title Integer Square Root name('SQRT') ; Integer Square Root in Assembler ; Base upon the article "Tiny BASIC Square Root Routine" ; ("Microcomputing", February 1980) entry sqrt cseg ; ; HL:=SQRT(HL) ; sqrt: ld (Value),hl ; Save entry value ex de,hl ld hl,1 or a sbc hl,de jr c,sqrt1 ld hl,1 ; Return 1 if value 0..1 ret sqrt1: ld hl,182 call divide inc hl inc hl ld (Work1),hl ; Start approximation ld hl,0 ld (Work2),hl sqrt2: ; Start of loop ld de,(Value) ld hl,(Work1) push hl call divide pop de add hl,de srl h rr l ld (Work3),hl ; Go on with approximation ex de,hl ld hl,(Work1) or a sbc hl,de ld a,1 jr z,sqrt4 ld de,(Work2) or a sbc hl,de ld a,1 jr z,sqrt4 xor a sqrt4: ld (Work4),a or a jr nz,sqrt3 ld hl,(Work3) ld de,(Work1) or a sbc hl,de ld (Work2),hl ld hl,(Work3) ld (Work1),hl sqrt3: ld a,(Work4) or a jr z,sqrt2 ; End of loop ld de,(Work1) ld hl,(Work3) or a sbc hl,de ex de,hl ; Determine result ret ; ; ------------------------------------------------------------ ; ; DIV - courtesy of Borland (TURBO PASCAL 3.0) ; Divide signed integers ; ENTRY Reg DE holds dividend ; Reg HL holds divisor ; EXIT Reg HL holds quotient ; Reg DE holds remainder ; divide: ld a,h xor d ; Calculate sign push af call abs ; Make both numbers positive ex de,hl call abs ex de,hl ld b,h ; Copy divisor ld c,l xor a ld h,a ; Clear result ld l,a ld a,17 ; Set bit count divloop: adc hl,hl ; Perform division sbc hl,bc jr nc,divNC add hl,bc scf divNC: ccf rl e rl d dec a ; Test done jr nz,divloop ; Nope, loop on ex de,hl pop af ; Get resulting sign ret p jr negate ; Negate result ; ; ABS - courtesy of Borland (TURBO PASCAL 3.0) ; ENTRY Reg HL holds signed integer ; EXIT Reg HL holds positive integer ; abs: bit 7,h ; Test sign ret z ; Already positive negate: ld a,h ; Build one's complement cpl ld h,a ld a,l cpl ld l,a inc hl ; Fix for two's complement ret dseg Value: ds 2 Work1: ds 2 Work2: ds 2 Work3: ds 2 Work4: ds 1 end