Changeset 4f508e6 in buchla-68k for lib700/uldiv.s
- Timestamp:
- 07/01/2017 02:34:46 PM (7 years ago)
- Branches:
- master
- Children:
- 08e1da1
- Parents:
- f40a309
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lib700/uldiv.s
rf40a309 r4f508e6 1 *------------------------------------------------------------------------------2 *uldiv.s -- unsigned long division, with remainder3 *Version 2 -- 1987-06-08 -- D.N. Lynx Crowe4 *Lifted from the Alcyon C library by disassembly so I could fix a bug -5 *_uldivr must be in the bss segment so the code will work in PROM.6 * 7 *long8 *uldiv(dividnd, divisor)9 *long dividnd, divisor;10 * 11 *extern long uldivr;12 * 13 *Divides 'dividnd' by 'divisor', treating both as unsigned14 *long integers. Returns the quotient and leaves the15 *remainder in 'uldivr'. Produces a divide check on division16 * by zero, with $80000000 returned for both quotient and17 *remainder.18 *------------------------------------------------------------------------------1 | ------------------------------------------------------------------------------ 2 | uldiv.s -- unsigned long division, with remainder 3 | Version 2 -- 1987-06-08 -- D.N. Lynx Crowe 4 | Lifted from the Alcyon C library by disassembly so I could fix a bug - 5 | _uldivr must be in the bss segment so the code will work in PROM. 6 7 | long 8 | uldiv(dividnd, divisor) 9 | long dividnd, divisor; 10 11 | extern long uldivr; 12 13 | Divides 'dividnd' by 'divisor', treating both as unsigned 14 | long integers. Returns the quotient and leaves the 15 | remainder in 'uldivr'. Produces a divide check on division 16 | by zero, with 0x80000000 returned for both quotient and 17 | remainder. 18 | ------------------------------------------------------------------------------ 19 19 .text 20 * 20 21 21 .xdef _uldiv,_uldivr 22 * 23 DIVIDEND .equ824 DIVISOR .equ1225 * 26 _uldiv: link a6,#0 *Link stack frames27 movem.l d3-d7,-(a7) *Save registers28 move.l DIVIDEND(a6),d7 *d7 = DIVIDEND29 move.l DIVISOR(a6),d6 *d6 = DIVISOR30 tst.l d6 *Divide by zero ?31 bne notdzero *Jump if not32 * 33 move.l # $80000000,_uldivr *Force error result34 move.l # $80000000,d0 *... by dividing35 divu #0,d0 *... by zero36 bra ulexit *... then exit37 * 38 notdzero: cmp.l d7,d6 *Divide underflow ?39 bls notunflo *Jump if not40 * 41 move.l d7,_uldivr *Remainder = dividend42 clr.l d0 *Quotient = 043 bra ulexit *Exit44 * 45 notunflo: cmp.l d6,d7 *Is dividend = divisor ?46 bne startdiv *Go start dividing if not47 * 48 moveq.l #1,d5 *Quotient = 149 clr.l d7 *Remainder = 050 bra setreslt *Go set result51 * 22 23 DIVIDEND = 8 24 DIVISOR = 12 25 26 _uldiv: link a6,#0 | Link stack frames 27 movem.l d3-d7,-(a7) | Save registers 28 move.l DIVIDEND(a6),d7 | d7 = DIVIDEND 29 move.l DIVISOR(a6),d6 | d6 = DIVISOR 30 tst.l d6 | Divide by zero ? 31 bne notdzero | Jump if not 32 33 move.l #0x80000000,_uldivr | Force error result 34 move.l #0x80000000,d0 | ... by dividing 35 divu #0,d0 | ... by zero 36 bra ulexit | ... then exit 37 38 notdzero: cmp.l d7,d6 | Divide underflow ? 39 bls notunflo | Jump if not 40 41 move.l d7,_uldivr | Remainder = dividend 42 clr.l d0 | Quotient = 0 43 bra ulexit | Exit 44 45 notunflo: cmp.l d6,d7 | Is dividend = divisor ? 46 bne startdiv | Go start dividing if not 47 48 moveq.l #1,d5 | Quotient = 1 49 clr.l d7 | Remainder = 0 50 bra setreslt | Go set result 51 52 52 .page 53 * 54 startdiv: moveq.l #1,d4 *Set result bit in d455 * 56 divloop1: cmp.l d6,d7 *Divisor aligned OK ?57 bcs divloop2 *Jump if so58 * 59 move.l d6,d0 *Can we align things better ?60 asl.l #1,d0 *...61 cmp.l d0,d6 *...62 bhi divloop2 *Jump if not63 * 64 asl.l #1,d6 *Shift the divisor65 asl.l #1,d4 *Shift the result bit66 bra divloop1 *Loop for next bit67 * 68 divloop2: clr.l d5 *Clear quotient69 * 70 divloop3: tst.l d4 *More bits to do ?71 beq setreslt *Go set result if not72 * 73 cmp.l d6,d7 *Can we subtract ?74 bcs divloop4 *Jump if not75 * 76 or.l d4,d5 *Set a bit in the quotient77 sub.l d6,d7 *Subtract divisor from dividend78 * 79 divloop4: lsr.l #1,d4 *Shift the result bit80 lsr.l #1,d6 *Shift the divisor81 bra divloop3 *Loop for next bit82 * 83 setreslt: move.l d7,_uldivr *Store remainder84 move.l d5,d0 *Put quotient in d085 * 86 ulexit: tst.l (a7)+ *Discard top of stack87 movem.l (a7)+,d4-d7 *Restore registers88 unlk a6 *Unlink stack frames89 rts *Return to caller90 * 53 54 startdiv: moveq.l #1,d4 | Set result bit in d4 55 56 divloop1: cmp.l d6,d7 | Divisor aligned OK ? 57 bcs divloop2 | Jump if so 58 59 move.l d6,d0 | Can we align things better ? 60 asl.l #1,d0 | ... 61 cmp.l d0,d6 | ... 62 bhi divloop2 | Jump if not 63 64 asl.l #1,d6 | Shift the divisor 65 asl.l #1,d4 | Shift the result bit 66 bra divloop1 | Loop for next bit 67 68 divloop2: clr.l d5 | Clear quotient 69 70 divloop3: tst.l d4 | More bits to do ? 71 beq setreslt | Go set result if not 72 73 cmp.l d6,d7 | Can we subtract ? 74 bcs divloop4 | Jump if not 75 76 or.l d4,d5 | Set a bit in the quotient 77 sub.l d6,d7 | Subtract divisor from dividend 78 79 divloop4: lsr.l #1,d4 | Shift the result bit 80 lsr.l #1,d6 | Shift the divisor 81 bra divloop3 | Loop for next bit 82 83 setreslt: move.l d7,_uldivr | Store remainder 84 move.l d5,d0 | Put quotient in d0 85 86 ulexit: tst.l (a7)+ | Discard top of stack 87 movem.l (a7)+,d4-d7 | Restore registers 88 unlk a6 | Unlink stack frames 89 rts | Return to caller 90 91 91 .bss 92 92 .even 93 * 93 94 94 _uldivr: ds.l 1 95 * 95 96 96 .end
Note:
See TracChangeset
for help on using the changeset viewer.