source: buchla-68k/orig/CLIBRARY/ULDIV.S@ 73dd55f

Last change on this file since 73dd55f was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 8 years ago

Imported original source code.

  • Property mode set to 100755
File size: 2.6 KB
Line 
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 $80000000 returned for both quotient and
17* remainder.
18* ------------------------------------------------------------------------------
19 .text
20*
21 .xdef _uldiv,_uldivr
22*
23DIVIDEND .equ 8
24DIVISOR .equ 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 #$80000000,_uldivr * Force error result
34 move.l #$80000000,d0 * ... by dividing
35 divu #0,d0 * ... by zero
36 bra ulexit * ... then exit
37*
38notdzero: 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*
45notunflo: 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 .page
53*
54startdiv: moveq.l #1,d4 * Set result bit in d4
55*
56divloop1: 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*
68divloop2: clr.l d5 * Clear quotient
69*
70divloop3: 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*
79divloop4: lsr.l #1,d4 * Shift the result bit
80 lsr.l #1,d6 * Shift the divisor
81 bra divloop3 * Loop for next bit
82*
83setreslt: move.l d7,_uldivr * Store remainder
84 move.l d5,d0 * Put quotient in d0
85*
86ulexit: 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 .bss
92 .even
93*
94_uldivr: ds.l 1
95*
96 .end
Note: See TracBrowser for help on using the repository browser.