home *** CD-ROM | disk | FTP | other *** search
- ; MATHLIB: a 16 Bit Arithmetic Package for Z80
- ; Sourced 26 Nov '80 by Trevor Marshall
- ; SYSOP, Thousand Oaks Tech RBBS
- ;
- ;
- MULTIPLY: ; 16 x 16 Bit multiplication
- ; (may be truncated to 16 x n bits)
- ;
- ;result (HL) = multiplicand (DE) x multiplier (BC)
- ;
- ; The multiplicand is in DE
- ; The multiplier is in BC
- ; The result will be in HL
- ; It overflows safely, but without indication
- ; Registers are destroyed
- ;
- ; Example: 5 x 3
- ; 101
- ; x 011
- ; ----------------
- ; 101 (Shifted LSBit=1)
- ; 101 (Shifted LSBit=1)
- ; 000 (Shifted LSBit=0,no add)
- ; ----------------
- ; 01111 (Result)
- ;
- ; Multiplier is in BC
- LD A,16 ; Loop count in A
- ;This count must be >= the number of bits used in BC
- ;
- LD HL,0 ;Clear result
- ;
- ZZMULT:
- ; is multiplier LSBit = 1 ?
- SRL B ;Right shift multiplier MSB
- ; 0 -> MSBit, LSBit -> Carry
- RR C ;Rotate right multiplier LSB
- ;Carry -> MSBit, LSBit -> Carry
- JR NC,ZZNOADD ;LSBit not 1, Dont add
- ;
- ; Could test for overflow by using this here:
- ; CCF ;Carry will be 1, C -> 0
- ; ADC HL,DE
- ; JR C,OVERFLOW.ROUTINE
- ; But will use the simpler
- ADD HL,DE ;LSBit = 1, so add multiplicand
- ; to (shifted) result
- ;
- ZZNOADD:
- ;Now we shift left the multiplicand
- SLA E ; 0 -> LSBit, MSBit -> Carry
- RL D ; Carry -> LSBit, MSBit -> Carry
- ;
- DEC A ;Loop cntr
- JR NZ,ZZMULT
- ;
- RET ; ***** DONE *****
- ;
- ;-------------------------------------------------------
- ;
- DIVIDE: ;16 Bit by 16 Bit Integer Division
- ;
- ; dividend (BC)
- ; result (BC) = --------------- + remainder (HL)
- ; divisor (DE)
- ;
- ; The dividend is in BC, and the result returns in BC
- ; The divisor is in DE
- ; After the division HL contains the remainder
- ;
- ; The divisor is successively subtracted from the high
- ; order bits of the dividend. After each subtraction
- ; the result is used instead of the initial dividend
- ; The result is increased by 1 each time.
- ; When the result of the subtraction is negative the
- ; partial result is restored by adding the divisor
- ; back to it.
- ; The result is simulataneously decremented by 1
- ;
- ;First check if divisor is 0
- LD A,D
- OR E
- JR Z,DIVIDE.BY.ZERO
- ; Dividend is in BC
- ;clear result
- LD HL,0
- ;loop counter
- LD A,16 ;DO NOT TRUNCATE
- ;
- ;Rotate Dividend left
- ;Carry has been zeroed by the OR E above
- ZZDIV1: RL C ;Carry -> LSBit, MSBit -> Carry
- RL B ;ditto
- ;Rotate Remainder left
- ADC HL,HL ;Never sets carry,
- ; ie RESETS carry
- ;Trial subtraction of divisor from result
- SBC HL,DE ;Carry -> 0 if no borrow
- ;Carry -> 1 if borrow
- JR NC,ZZPOS
- ;otherwise negative
- ADD HL,DE ;Restore dividend
- ZZPOS: CCF ;Calc Result Bit, Z80 carry peculiar
- DEC A ;Loop counter
- JR NZ,ZZDIV1 ;Loop for 16 Bits
- ;
- RL C ;Shift in last result bit
- RL B
- ; The result is in BC, the remainder in HL
- ;
- RET ; ***** DONE ****
- ;
- DIVIDE.BY.ZERO: LD BC,0FFFFH ;Infinity
- ; Output a diagnostic message if desired
- RET
- ;
-