source: buchla-68k/lib700/uldiv.s@ 6dbed52

Last change on this file since 6dbed52 was 4cfe69a, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Use .ds and .dc pseudo-ops. Generate debug symbols.

  • Property mode set to 100644
File size: 2.5 KB
RevLine 
[4f508e6]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| ------------------------------------------------------------------------------
[f40a309]19 .text
[4f508e6]20
[f40a309]21 .xdef _uldiv,_uldivr
[4f508e6]22
23DIVIDEND = 8
24DIVISOR = 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
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
[f40a309]52 .page
[4f508e6]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
[f40a309]91 .bss
92 .even
[4f508e6]93
[4cfe69a]94_uldivr: .ds.l 1
[4f508e6]95
[f40a309]96 .end
Note: See TracBrowser for help on using the repository browser.