* Optimised many of the library functions
[fw/sdcc] / device / lib / z80 / mul.s
1         ;; Originally from GBDK by Pascal Felber.
2         
3         .area   _CODE
4
5 __mulschar_rrx_s::
6         ld      hl,#2
7         add     hl,sp
8
9         ld      e,(hl)
10         inc     hl
11         ld      l,(hl)                
12
13         ;; Fall through
14 __mulschar_rrx_hds::
15         ;; Need to sign extend before going in.
16         ld      c,l
17         
18         ld      a,l
19         rla
20         sbc     a,a
21         ld      b,a
22
23         ld      a,e
24         rla
25         sbc     a,a
26         ld      d,a
27
28         jp      .mul16
29
30 __muluchar_rrx_s::
31         ld      hl,#2
32         add     hl,sp
33
34         ld      e,(hl)
35
36         inc     hl
37         ld      c,(hl)                
38
39         ;; Clear the top
40         xor     a
41         ld      d,a
42         ld      b,a
43         
44         jp      .mulu16
45         
46 __mulsint_rrx_s::
47 __muluint_rrx_s::
48         ld      hl,#2
49         add     hl,sp
50         
51         ld      e,(hl)
52         inc     hl
53         ld      d,(hl)
54         inc     hl
55         ld      a,(hl)
56         inc     hl
57         ld      h,(hl)
58         ld      l,a
59
60         ;; Fall through
61         
62 __muluchar_rrx_hds::
63 __mulsint_rrx_hds::
64 __muluint_rrx_hds::
65         ;; Parameters:
66         ;;      HL, DE (left, right irrelivent)
67         ld      b,h
68         ld      c,l
69         
70         ;; 16-bit multiplication
71         ;; 
72         ;; Entry conditions
73         ;;   BC = multiplicand
74         ;;   DE = multiplier
75         ;; 
76         ;; Exit conditions
77         ;;   DE = less significant word of product
78         ;;
79         ;; Register used: AF,BC,DE,HL
80 .mul16:
81 .mulu16:
82         LD      HL,#0x00        ; Product = 0
83         LD      A,#15           ; Count = bit length - 1
84         ;; Shift-and-add algorithm
85         ;; If MSB of multiplier is 1, add multiplicand to partial product
86         ;; Shift partial product, multiplier left 1 bit
87 .mlp:
88         SLA     E               ; Shift multiplier left 1 bit
89         RL      D
90         jp      NC,.mlp1        ; Jump if MSB of multiplier = 0
91         ADD     HL,BC           ; Add multiplicand to partial product
92 .mlp1:
93         ADD     HL,HL           ; Shift partial product left
94         DEC     A
95         jp      NZ,.mlp         ; Continue until count = 0
96         ;; Add multiplicand one last time if MSB of multiplier is 1
97         BIT     7,D             ; Get MSB of multiplier
98         JR      Z,.mend         ; Exit if MSB of multiplier is 0
99         ADD     HL,BC           ; Add multiplicand to product
100 .mend:
101                                 ; HL = result
102         ret
103