IGNORED

# Square root routine in 21 decles

## Recommended Posts

Hi all,

I posted this to the Intellivision programming list, and Joe suggested that I post it here as well. It's basically a specialized version of the square root routine (it lacks the ability to specify additional fractional points in the answer).

What makes it interesting is that it fits in 21 decles making it a direct drop-in replacement for the EXEC's own square root replacement at \$1E23. In fact, its register compatible and you can do just that.

I'm not going to explain how everything works just yet… So if someone wants to pick it apart and give it a go, consider it a challenge. :-)

Enjoy!

Carl

```PROC	    SqRt
; Descr:  Returns the square root of R1 in R2.  Register and space
;		 compatible with the EXEC @ \$1E23. The 16-bit instructions
;		 below can easily be replaced with 10-bit equivalents:
;
;		 MVII    \$8000, R0  ->  SUBR    R0, R0
;		 ..					 RRC	 R0, 1
;		 MVII    \$FFFF, R5  ->  CLRR    R5
;		 ..					 DECR    R5
; Input:  R1  = Radicand or "PreDist"
; Output: R0  = \$0080 (NOT 0 or 1, like the EXEC)
;		 R2  = SqRt( R1 )
MVO@    R5, R6			  ; save RetAddr
MVII    \$8000, R0		   ; SquareBit = 1/2 * Bit^2, Count = 8
MOVR    R1, R2			  ; Radicand or "PreDist" in R2 for return
MVII    \$FFFF, R5		   ; Update = (Guess + Bit)^2 - 1
@@Cont:
SUBR    R0, R5			  ; Update -= 1/4 * Bit^2
SLLC    R2, 1			   ; was Remainder's MSB set ?
ADCR    R7				  ; if yes, skip CMPR & fall into "B1"
CMPR    R2, R5			  ; Update <= Remainder ?
BC	  @@B0			    ; no,  so set Result's current LSB = 0
@@B1:
SUBR    R5, R2			  ; Remainder -= ( Update - 1 )
ADDR    R0, R5			  ; -' Update += Bit^2
@@B0:
SLR	 R0, 1			   ; SquareBit >>= 1
BPL	 @@Cont			  ; if --Count == 0, handled final LSB
ANDI    \$00FF, R2		   ; isolate Result in bits 0-7
ENDP
```

Edited by Carl Mueller Jr
##### Share on other sites

Since AA bungled up Carl's formatting, here it is again, a little nicer:

```PROC        SqRt

; Descr:  Returns the square root of R1 in R2.  Register and space
;         compatible with the EXEC @ \$1E23. The 16-bit instructions
;         below can easily be replaced with 10-bit equivalents:
;
;         MVII    \$8000, R0  ->  SUBR    R0, R0
;         ..                     RRC     R0, 1
;         MVII    \$FFFF, R5  ->  CLRR    R5
;         ..                     DECR    R5

; Input:  R1  = Radicand or "PreDist"

; Output: R0  = \$0080 (NOT 0 or 1, like the EXEC)
;         R2  = SqRt( R1 )

MVO@    R5, R6              ; save RetAddr

MVII    \$8000, R0           ; SquareBit = 1/2 * Bit^2, Count = 8
MOVR    R1, R2              ; Radicand or "PreDist" in R2 for return
MVII    \$FFFF, R5           ; Update = (Guess + Bit)^2 - 1
@@Cont:
SUBR    R0, R5              ; Update -= 1/4 * Bit^2

SLLC    R2, 1               ; was Remainder's MSB set ?
ADCR    R7                  ; if yes, skip CMPR & fall into "B1"

CMPR    R2, R5              ; Update <= Remainder ?
BC      @@B0                ; no,  so set Result's current LSB = 0
@@B1:
SUBR    R5, R2              ; Remainder -= ( Update - 1 )

ADDR    R0, R5              ; -' Update += Bit^2
@@B0:
SLR     R0, 1               ; SquareBit >>= 1

BPL     @@Cont              ; if --Count == 0, handled final LSB

ANDI    \$00FF, R2           ; isolate Result in bits 0-7

ENDP
```

For whatever reason, the WYSIWYG editor likes to guess where tabs go, and gets it horribly wrong. This should be easier to follow.

And for those that aren't accustomed to seeing the raw instructions, MVO@ ..., R6 is PSHR, and MVI@ R6, ... is PULR. I won't give any hints, but I have a pretty good idea of how it all works. :-) I'll share my thoughts after the long weekend, to give people a chance to understand it on their own first.

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.