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