A85: Oops
[Prev][Next][Index][Thread]
A85: Oops
Oops, forgot to attach math32.inc...
here it is.
-Humberto Yeverino Jr.
"I kick ass for the Lord."
***********************************************************
Home Page:
http://www.engr.csufresno.edu/~humberto/Home.html
Ti Page:
http://www.engr.csufresno.edu/~humberto/tex.html
z80 Source Page:
http://www.engr.csufresno.edu/~humberto/z80source.html
Official Tyrant Home Page:
http://www.engr.csufresno.edu/~humberto/tyrant.html
E-mail:
humberto@engr.csufresno.edu
***********************************************************
;New 32-bit Math routines for the z80
;by Humberto Yeverino Jr.
;August 22, 1998
;*** Last updated August 27, 1998 ***
;Questions, bugs... complements,
;e-mail: humberto@engr.csufresno.edu
;TI WebPage: www.engr.csufresno.edu/~humberto/tex.html
;You are free to modify them and use them as you wish.
;be careful though, some routines rely on others.
;the shift routines could be smaller but mul32 and div32 use them
;a lot so I optimized for speed.
;If you find a way to optimize one of these routines e-mail me so I
;can update the file. You will of course get credit.
;NOTE:
;To use these routines you must define 5 areas of memory
;three 4 byte chunks named RegA, RegB, and RegC to be used as registers.
;one 11 byte chunk named StringSpace for creating strings from RegA
;REMEMBER: you don't have to leave this space reserved. Just remember that
;these areas will be written over when you use routines.
;For example, wherever you define StringSpace should be a place for all
;sort s of temorary data.
;Here are all the routines included and what they do.
;ld8A, ld8B, ld8C
;load a register into RegA, RegB, or RegC
;destroys b and hl
;There are a lot of ld instructions but they are cheap on space.
;NOT ALL INSTRUCTIONS ARE IN THIS FILE.
;If you want to add another (ld32C for instance) you'll have to write it
;yourself. (but it's really easy)
;Just make sure you add it to this file, that way it will be faster & smaller
;But if you want to rewrite the IntString routine so that it creates a
;differnt format of string you might want to e-mail me.
;Later I will probably post different IntString routines on my z80 rouine
;page.
;LOAD---------------------------------------------------
;ld8A, ld8B, ld8C
;load register a into RegA/RegB/RegC
;destroys hl and b
;ld16A, ld16B, ld16C
;load register hl into RegA, RegB, or RegC
;detroys hl and b
;ld32
;copies memory from hl to de
;detroys b
;ld32A, ld32B
;copies memory from hl to RegA, RegB
;destroys bc, de and hl
;ld32AB, ld32AC, ld32BA, ld32BC
;load RegA with RegB/RegC, load RegB with RegA/RegC
;destroys bc, de and hl
;ADD---------------------------------------------------
;add32
;(hl):=(hl)+(de)
;destroys a, b, de and hl
;adc32
;same as add32 only adds carry flag also
;no register routines are supported for this one because it's likely you
;will never use it. But it takes up no space so..
;add32A, add32C (you get the idea)
;RegA=RegA+(de)
;destroys a, b, de and hl
;add32AB, add32CB
;RegA=RegA+RegB
;destroys a, b, de and hl
;SUB---------------------------------------------------
;sub32
;(hl):=(hl)-(de)
;destroys a, b, de and hl
;sbc32
;same as sub32 accept with carry
;sub32A
;RegA=RegA-(de)
;destroys a, b, de and hl
;sub32AB
;RegA=RegA-RegB
;destroys a, b, de and hl
;CP----------------------------------------------------
;cp32
;compares (hl) to (de)
;destroys a, b, de and hl
;cp32A, cp32B
;compares RegA to (de)
;destroys a, b, de and hl
;cp32AB, cp32AC, cp32BA, cp32BC
;compare RegA to RegB ect.
;destroys a, b, de and hl
;ALL of the shift instructions shift in the carry flag.
;SR----------------------------------------------------
;sr32
;shift (hl) right
;destroys hl
;sr32A, sr32B sr32C
;shift RegA right ect.
;destroys hl
;SL----------------------------------------------------
;sl32
;shift (hl) left
;destroys hl
;sl32A, sl32B, sl32C
;shift RegA left ect.
;destroys hl
;CLEARREG----------------------------------------------
;ClearReg
;sets (hl) to 0
;destroys b and hl
;ClearRegA, ClearRegB, ClearRegC
;sets RegA to 0 ect.
;destroys b and hl
;MUL & DIV---------------------------------------------
;mul32
;RegC=RegA*RegB
;destroys a, b, de and hl
;div32
;RegC=RegA/RegB, RegA=Remainder, RegB preserved
;destroys a, bc, de and hl
;INT TO STRING-----------------------------------------
;IntString32
;convert 32-bit int in RegA to a string.
;hl->string
;RegC=0, RegA destroyed, RegB preserved.
;destroys a, bc and de
ld8A:
call ClearRegA
ld (RegA),a
ret
ld8B: ;Required for InString32
call ClearRegB
ld (RegB),a
ret
ld8C:
call ClearRegC
ld (RegC),a
ret
ld16A:
ld (RegA),hl
ld hl,0
ld (RegA+2),hl
ret
ld16B:
ld (RegB),hl
ld hl,0
ld (RegB+2),hl
ret
ld16C:
ld (RegC),hl
ld hl,0
ld (RegC+2),hl
ret
;63 bytes for all ld32 routins
ld32AB:
ld hl,RegB
ld32A: ;Total 9 bytes
ld de,RegA ;3
ld32:
ld bc,4 ;3
ldir ;2
ret ;1
ld32AC: ;Required for IntString32
ld hl,RegC
jr ld32A
ld32B:
ld de,RegB
jr ld32
ld32BA:
ld hl,RegA
jr ld32B
ld32BC:
ld hl,RegC
jr ld32B
add32AB: ;Total 16 bytes
ld de,RegB ;3
add32A:
ld hl,RegA ;3
add32:
or a
adc32:
ld b,4 ;2
add32Loop:
ld a,(de) ;1
adc a,(hl) ;1
ld (hl),a ;1
inc hl ;1
inc de ;1
djnz add32Loop ;2
ret ;1
add32C: ;Total 8 bytes
ld hl,RegC ;3
jr add32
add32CB: ;Required for mul32
ld de,RegB ;3
jr add32C
sub32AB: ;Required for div32
;IN = RegA, RegB
;OUT = RegA=RegA-RegB
ld hl,RegB ;3
sub32A:
ld de,RegA ;3
sub32: ;Total 10 bytes
or a
sbc32:
ld b,4 ;2
sub32Loop:
ld a,(de) ;1
sbc a,(hl) ;1
ld (de),a ;1
inc de ;1
inc hl ;1
djnz sub32Loop ;2
ret ;1
cp32AB: ;Required for div32
ld hl,RegB+3
cp32A:
ld de,RegA+3
cp32:
ld b,4
cp32Loop:
ld a,(de)
cp (hl) ;(hl)-(de) c-hl<hl, nc-hl>=de, z-hl=de, nz-hl!=de
ret nz ;(hl)!=(de) then done
dec hl
dec de ;try next bytes
djnz cp32Loop
cp32Done:
ret
cp32AC:
ld hl,RegC+3
jr cp32A
cp32B:
ld de,RegB+3
jr cp32
cp32BA:
ld hl,RegA+3
jr cp32B
cp32BC: ;Required for div32
ld hl,RegC+3
jr cp32B
sr32A: ;15 98 Required for mul32
ld hl,RegA+3 ;3 10
sr32: ;12 88
rr (hl) ;2 15
dec hl ;1 6
rr (hl) ;2 15
dec hl ;1 6
rr (hl) ;2 15
dec hl ;1 6
rr (hl) ;2 15
ret ;1 10
sr32B: ;5 110 Required for div32
ld hl,RegB+3
jr sr32
sr32C:
ld hl,RegC+3
jr sr32
sl32A: ;15 98 (hl):=(hl)*2
ld hl,RegA
sl32: ;12 88
rl (hl) ;2 15 rotate
inc hl ;1 6 next byte
rl (hl)
inc hl
rl (hl)
inc hl
rl (hl)
ret
sl32B: ;5 110 Required for mul32 and div32
ld hl,RegB ;3 10
jr sl32 ;2 12
sl32C: ;Required for div32
ld hl,RegC
jr sl32
ClearRegA: ;Total 11 bytes
ld hl,RegA ;3
ClearReg: ;Total 8 bytes
ld b,4 ;2
ClearRegLoop:
ld (hl),0 ;2
inc hl ;1
djnz ClearRegLoop ;2
ret ;1
ClearRegB:
ld hl,RegB
jr ClearReg
ClearRegC: ;Required for mul32
ld hl,RegC
jr ClearReg
mul32:
call ClearRegC
ld b,32
mul32Loop:
push bc
call sr32A ;3 push least sig bit of RegA into carry
jr nc,mul32NoAdd ;2 if carry=0 goto NoAdd
call add32CB ;3 RegC=RegC+RegB
mul32NoAdd:
call sl32B ;3 RegB=RegB*2
pop bc
djnz mul32Loop
ret
div32: ;Total 38 bytes Required for IntString32
call ClearRegC
call cp32BC
ret z ;check if b=0
ld c,1 ;2
or a ;1 carry=0
div32Loop:
ld a,(RegB+3) ;3 13
bit 7,a ;2 8 Test Most sig bit of RegB
jr nz,div32Loop2 ;2 7 if it's 1 goto div32Ready else
inc c ;1 4 inc c
call sl32B ;3 127 shift RegB left
jr div32Loop ;2 12 loop time=171
div32Loop2:
call cp32AB ;3
jr c,div32NoSub ;2 if RegA<RegB goto div32NoSub else
call sub32AB ;3 RegA=RegA-RegB
div32NoSub:
ccf ;1
call sl32C ;3 left shift a 1 into RegC
call sr32B ;3 RegB=RegB/2 ;1
dec c
jr nz,div32Loop2 ;2
call sl32B ;Restore RegB
ret ;1
IntString32:
ld a,10
call ld8B ;load 10 into RegB
ld b,a ;number of digits
ld hl,StringSpace+10
ld (hl),0 ;for 0 terminated string
IntString32Loop:
push bc ;save b
dec hl ;previous byte
push hl ;save hl BC:HL
call div32 ;divide RegA by 10
ld a,(RegA) ;put answer in a
add a,48 ;add offset
call ld32AC ;load RegC into RegA
pop hl
pop bc ;get pointer & b
ld (hl),a ;load char into pointer
djnz IntString32Loop
;get rid of preceding zeros
ld a,48
ld b,9 ;do at most 9 moves
IntStrnLoop2:
cp (hl)
ret nz
inc hl
djnz IntStrnLoop2
ret