0 Members and 1 Guest are viewing this topic.
Well I am almost positive that using my algorithm would require the use of RAM, even if you used all the shadow registers, too.
0→A 0→D ;This is where the result will go 0→C ;This is a carry For(B,1,12) ;12 is half the number of input bits D+D→D ;We want to shift D left D+D+1→C ;The difference of consecutive squares? A<<E ;rotate E left, then rotate the carry into A A<<E ;In z80, "rlc e \ rla" If A>=C ;If A is greater than or equal to C D+1→D A-C→A End;You will need an input (24 bits in the above example);You will need an output (12 bits in the above example);You will need a counter (4 bits in the above example);You will need an accumulator (24 bits in the above example);You will need a carry (13 bits in the above example);;You will need at least (77 bits in the above example)
;===============================================================sqrtE:;===============================================================;Input:; E is the value to find the square root of;Outputs:; A is E-D^2; B is 0; D is the result; E is not changed; HL is not changed;Destroys:; C=2D+1 if D is even, 2D-1 if D is odd xor a ;1 4 4 ld d,a ;1 4 4 ld c,a ;1 4 4 ld b,4 ;2 7 7sqrtELoop: rlc d ;2 8 32 ld c,d ;1 4 16 scf ;1 4 16 rl c ;2 8 32 rlc e ;2 8 32 rla ;1 4 16 rlc e ;2 8 32 rla ;1 4 16 cp c ;1 4 16 jr c,$+4 ;4 12|15 48+3x inc d ;-- -- -- sub c ;-- -- -- djnz sqrtELoop ;2 13|8 47 ret ;1 10 10
cp d ;1 4 4 jr c,$+3 ;3 12|11 12|11 inc d ;-- -- --
multBCDbyEHL: ld a, b ld b, c ld c, d ld d, amultDBCbyEHL: push de push hl ld ix, $8000 ld (ix), l xor a ld h, a ld l, a call do8Bits ld (ix+1), a pop af ld (ix), a push de ld a, (ix+1) call do8Bits ld (ix+1), a pop af ;least sig number ex de, hl ex (sp), hl ;D and 2nd least sig in for new number ld (ix), l pop hl ;D and 2nd least sig push af ;least sig number push hl ;2nd least sig number ex de, hl ld a, (ix+1) call do8Bits ld b, a ld c, h ld d, l pop hl ld a, l pop hl ld h, a ret ;####;input: DBC = 1 number; AHL = running number; (ix) = to multiply by;output: AHLE = output; E is done; DBC = 1 numberdo8Bits: ld (ix+1), 8loop: srl (ix) jr nc, skip add hl, bc adc a, dskip: rra rr h rr l rr e dec (ix+1) jr nz, loop ret
; ahl = sqrt(hldebc) push bc ; ld c,ixl pop ix ; ld b,ixh push de ld c,l ld a,h ld hl,0 ld b,h ld e,l ld d,h ld (iy+asm_Flag1),d ld (iy+asm_Flag2),24Loop: cp $40 push af sbc hl,de ld a,b sbc a,(iy+asm_Flag1) jr c,Restore ld b,a pop af sub $40 scf jr SkipRestore: pop af adc hl,de or aSkip: rl e rl d rl (iy+asm_Flag1) add ix,ix ex (sp),hl adc hl,hl ex (sp),hl rl c rla adc hl,hl rl b add ix,ix ex (sp),hl adc hl,hl ex (sp),hl rl c rla adc hl,hl rl b dec (iy+asm_Flag2) jr nz,Loop pop hl ld a,(iy+asm_Flag1) ret
; dea = sqrt(hldebc) di push bc ; ld c,ixl pop ix ; ld b,ixh ld bc,$40 ld a,l ld l,h ld h,b exx ld de,0 ld l,e ld h,d ld b,24 or aLoop: exx sbc hl,bc exx sbc hl,de jr nc,Skip exx add hl,bc exx adc hl,deSkip: exx ccf rl b exx rl e rl d exx add ix,ix rl e rl d rla adc hl,hl exx adc hl,hl exx add ix,ix rl e rl d rla adc hl,hl exx adc hl,hl djnz Loop exx ld a,b exx ei ret
B/2→A ;start with anything, reallyFor(C,1,12(A+B/A)/2→AEnd
432 x27-----
1100010111010111
;D*E xor a ;This is the accumulator ld b,8 ;this is the counterMultLoop: add a,a ;this is to rotate the accumulator left. Use rlca, too rlc e ;This puts the next bit in E in the carry jr nc,$+3 ;If the bit in E was not 1, you add 0 (so don't add!) add a,d ;1*D=D, so add D. Binary makes math easy. djnz MultLoop ret
Hey, jacobly, I tested both of your multiplication routines and it doesn't seem like they're doing the same thing... I've tried both of them in my program but they have different results.
// Multiply a times btemp = 0repeat for each bit in a temp <<= 1 if (high bit of a set) temp += b a <<= 1return temp// Divide a by btemp = 0repeat for each bit in a temp <<= 1 temp += high bit of a a <<= 1 if (temp >= b) temp -= b set low bit of areturn a// Sqrt atemp = 0b = 0repeat for every 2 bits in a temp += high 2 bits of a a <<= 2 test = b << 2 + 1 b <<= 1 if (temp >= test) temp -= test set low bit of breturn b// Sqrt a, sometimes better with multiple-of-a-byte registerstemp = high byte of aa <<= 8b = 0repeat for every 2 bits in a test = b << 8 + 0x40 b <<= 1 if (temp >= test) temp -= test set low bit of b temp += high 2 bits of a a <<= 2return b
333x471----1) 4*333 +Acc = 1332 Acc*10= 133202) 7*333 +Acc = 15651 Acc*10= 1565103) 1*333 +Acc = 156843
00100110x11011001---------------1) 1x00100110 +Acc = 00100110 Acc*2= 010011002) 1x00100110 +Acc = 01001100+00100110=01110010 Acc*2= 111001003) 0x00100110 +Acc = 11100100 Acc*2= 1110010004) 1x00100110 +Acc = 111101110 Acc*2= 11110111005) 1x00100110 +Acc = 10000000010 Acc*2= 1000000001006) 0x00100110 +Acc = 100000000100 Acc*2= 10000000010007) 0x00100110 +Acc = 1000000001000 Acc*2= 100000000100008) 1x00100110 +Acc = 10000000110110