1
2	SECTION	code_l_sdcc
3
4	PUBLIC	l_divu8
5	PUBLIC	l_modu8
6	PUBLIC	l_divu16
7	PUBLIC	l_modu16
8
9
10l_divu8:
11l_modu8:
12        ld      b,0x00
13        ld      d,b
14        ; Fall through to divu16
15
16l_divu16:
17l_modu16:
18        ;; Check for division by zero
19        ld      a,e
20        or      d
21        jr      NZ,divide      ; Branch if divisor is non-zero
22        ld      bc,0x00        ; Divide by zero error
23        ld      d,b
24        ld      e,c
25        scf                     ; Set carry, invalid result
26        ret
27divide:
28        ld      l,c             ; L = low byte of dividend/quotient
29        ld      h,b             ; H = high byte of dividend/quotient
30        ld      bc,0x00        ; BC = remainder
31        or      a               ; Clear carry to start
32        ld      a,16           ; 16 bits in dividend
33dvloop:
34        ;; Shift next bit of quotient into bit 0 of dividend
35        ;; Shift next MSB of dividend into LSB of remainder
36        ;; BC holds both dividend and quotient. While we shift a bit from
37        ;;  MSB of dividend, we shift next bit of quotient in from carry
38        ;; HL holds remainder
39        ;; Do a 32-bit left shift, shifting carry to L, L to H,
40        ;;  H to C, C to B
41        push    af              ; save number of bits remaining
42        rl      l               ; Carry (next bit of quotient) to bit 0
43        rl      h               ; Shift remaining bytes
44        rl      c
45        rl      b               ; Clears carry since BC was 0
46        ;; If remainder is >= divisor, next bit of quotient is 1. This
47        ;;  bit goes to carry
48        push    bc              ; Save current remainder
49        ld      a,c             ; Substract divisor from remainder
50        sbc     e
51        ld      c,a
52        ld      a,b
53        sbc     d
54        ld      b,a
55        ccf                     ; Complement borrow so 1 indicates a
56                                ;  successful substraction (this is the
57                                ;  next bit of quotient)
58        jr      C,drop         ; Jump if remainder is >= dividend
59        pop     bc              ; Otherwise, restore remainder
60        pop     af              ; recover # bits remaining, carry flag destroyed
61        dec     a
62        or      a               ; restore (clear) the carry flag
63        jr      NZ,dvloop
64        jr      nodrop
65drop:
66        inc     sp
67        inc     sp
68        pop     af              ; recover # bits remaining, carry flag destroyed
69        dec     a
70        scf                     ; restore (set) the carry flag
71        jr      NZ,dvloop
72        jr      nodrop
73nodrop:
74        ;; Shift last carry bit into quotient
75        ld      d,b             ; DE = remainder
76        ld      e,c
77        rl      l               ; Carry to L
78        ld      c,l             ; C = low byte of quotient
79        rl      h
80        ld      b,h             ; B = high byte of quotient
81        or      a               ; Clear carry, valid result
82        ret
83