* Improved the pop params code
[fw/sdcc] / device / lib / z80 / mul.s
1         ;; Originally from GBDK by Pascal Felber.
2         
3         .area   _CODE
4 __mulschar::    
5 __muluchar::
6         push    de
7         push    bc
8         push    ix
9         ld      ix,#0
10         add     ix,sp
11
12         ld      c,8(ix)
13         ld      e,9(ix)
14         call    .mulu8
15         
16         pop     ix
17         pop     bc
18         pop     de
19         ret
20
21 __mulsint::
22 __muluint::
23         push    de
24         push    bc
25         push    ix
26         ld      ix,#0
27         add     ix,sp
28
29         ld      c,8(ix)
30         ld      b,9(ix)
31         ld      e,10(ix)
32         ld      d,11(ix)
33         call    .mulu16
34         
35         pop     ix
36         pop     bc
37         pop     de
38         ret
39                 
40 .mul8:
41 .mulu8:
42         LD      B,#0x00         ; Sign extend is not necessary with mul
43         LD      D,B
44         ; Fall through
45         
46         ;; 16-bit multiplication
47         ;; 
48         ;; Entry conditions
49         ;;   BC = multiplicand
50         ;;   DE = multiplier
51         ;; 
52         ;; Exit conditions
53         ;;   DE = less significant word of product
54         ;;
55         ;; Register used: AF,BC,DE,HL
56 .mul16:
57 .mulu16:
58         LD      HL,#0x00        ; Product = 0
59         LD      A,#15           ; Count = bit length - 1
60         ;; Shift-and-add algorithm
61         ;; If MSB of multiplier is 1, add multiplicand to partial product
62         ;; Shift partial product, multiplier left 1 bit
63 .mlp:
64         SLA     E               ; Shift multiplier left 1 bit
65         RL      D
66         JR      NC,.mlp1        ; Jump if MSB of multiplier = 0
67         ADD     HL,BC           ; Add multiplicand to partial product
68 .mlp1:
69         ADD     HL,HL           ; Shift partial product left
70         DEC     A
71         JR      NZ,.mlp         ; Continue until count = 0
72         ;; Add multiplicand one last time if MSB of multiplier is 1
73         BIT     7,D             ; Get MSB of multiplier
74         JR      Z,.mend         ; Exit if MSB of multiplier is 0
75         ADD     HL,BC           ; Add multiplicand to product
76 .mend:
77         RET                     ; HL = result
78