home *** CD-ROM | disk | FTP | other *** search
- ; MATHLIB: a 16 Bit Arithmetic Package for 6805
- ; Sourced Feb '81 by Trevor Marshall
- ; SYSOP, Thousand Oaks, Tech RBBS
- ;
- ;MULTIPLY: 16 x 16 Bit multiplication
- ;
- ; RESULT,RESULT+1 = MPLICAND,MPLICAND+1
- ; x MPLIER,MPLIER+1
- ; MPLIER, MPLICAND may be destroyed
- ;COUNT: DS 1 ;loop counter
- ;RESULT: DS 2
- ;MPLICAND DS 2
- ;MPLIER DS 2
- ;
- ; Example: 5 x 3
- ; 101
- ; x 011
- ; ----------------
- ; 101 (Shifted LSBit=1)
- ; 101 (Shifted LSBit=1)
- ; 000 (Shifted LSBit=0,no add)
- ; ----------------
- ; 01111 (Result)
- ;
- MULTIPLY: LDA #16 ;initialize count
- STA COUNT
- CLR RESULT+1 ;and result
- CLR RESULT
- ;
- ; is multiplier LSBit = 1 ?
- ZZMULT: SHR MPLIER ;right shift multIplier MSB
- ; ; 0 -> MSBit, LSBit -> Carry
- RRC MPLIER+1 ;shift right multiplier LSB
- ; ;Carry-> MSBit, LSBit -> Carry
- BNC ZZNOADD ;LSBit not 1, don't add
- ;
- ; Could test for overflow here:
- ; (.Z80) CCF ;Carry will be 1, C -> 0
- ; ADC HL,DE
- ; JR C,OVERFLOW.ROUTINE
- ; But will add without carry
- LDA MPLICAND+1 ;LSBit=1, so add multiplicand
- ; ;to (shifted) result
- ADD RESULT+1
- STA RESULT+1
- LDA MPLICAND
- ADC RESULT
- STA RESULT
- ;
- ZZNOADD: SHL MPLICAND+1 ; 0 -> LSBit, MSBit -> Carry
- RLC MPLICAND ;Carry -> LSBit, MSBit -> Carry
- DEC COUNT
- BNZ ZZMULT
- RET ; ***** DONE *****
- ;
- ;
- ;
- ;DIVIDE: ;16 Bit by 16 Bit Integer Division
- ;
- ; (DIVIDEND,DIVIDEND+1)
- ; DIVIDEND,DIVIDEND+1 =----------------------- + REM,REM+1
- ; (DIVISOR,DIVISOR+1)
- ; The dividend & divisor are stored in memory with
- ; the MSByte first
- ; Their location is via EQU statements
- ;COUNTER: EQU $39 ;A scratch location for loop count
- ;DIVIDEND: EQU $3A ;2 locs at top of user RAM
- ;RESULT: EQU $ ;Result replaces dividend
- ;DIVISOR: EQU $3C ; "
- ;REM: EQU $3E ; "
- ;
- ; 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
- DIVIDE: LDA DIVISOR
- XOR DIVISOR+1
- BZ DIVBY0
- ;clear result
- CLRA
- STA REM
- STA REM+1
- ;loop counter
- LDA #16
- STA COUNTER
- ;
- ;Rotate Dividend left
- CLRC
- ZZDIV1: RLC DIVIDEND+1
- RLC DIVIDEND
- ;Rotate Remainder left and collect carry result
- RLC REM+1
- RLC REM
- LDA REM+1
- SUB DIVISOR+1
- STA REM+1 ;Modify to reflect result
- LDA REM
- SBC DIVISOR
- STA REM ; "
- BNC ZZPOS
- ;otherwise negative
- LDA REM+1 ;Restore dividend
- ADD DIVISOR+1
- STA REM+1
- LDA REM
- ADC DIVISOR
- STA REM
- ZZPOS: BNC ZZPOS1 ;If carry is clear set it
- CLRC ;if set, clear it
- BR ZZPOS2 ;Thus complement the carry
- ZZPOS1: SETC
- ZZPOS2: DEC COUNTER
- BNZ ZZDIV1
- RLC DIVIDEND+1 ;Shift in last result bit
- RLC DIVIDEND
- RET ; ***** DONE ****
- ;
- DIVBY0 LDA $FF ;infinity
- STA DIVIDEND+1
- STA DIVIDEND
- ; Output a diagnostic message if desired
- RET
- ;
-