Carl Mueller Jr Posted May 25, 2012 Share Posted May 25, 2012 (edited) 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 ; -. 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 MVI@ R6, R7 ; return to SqRt's caller ENDP Edited May 25, 2012 by Carl Mueller Jr 1 Quote Link to comment Share on other sites More sharing options...
intvnut Posted May 26, 2012 Share Posted May 26, 2012 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 ; -. 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 MVI@ R6, R7 ; return to SqRt's caller 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.