92e0ceba34f13775946193b327f8f1ef5d7a4a5d
[fw/sdcc] / device / lib / z80 / mul.s
1         ;; Originally from GBDK by Pascal Felber.
2         
3         .area   _CODE
4
5 __mulschar_rr_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_rr_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_rr_s::
31 __mulsint_rr_s::
32 __muluint_rr_s::
33         ld      hl,#2
34         add     hl,sp
35         
36         ld      e,(hl)
37         inc     hl
38         ld      d,(hl)
39         inc     hl
40         ld      a,(hl)
41         inc     hl
42         ld      h,(hl)
43         ld      l,a
44
45         ;; Fall through
46         
47 __muluchar_rr_hds::
48 __mulsint_rr_hds::
49 __muluint_rr_hds::
50         ;; Parameters:
51         ;;      HL, DE (left, right irrelivent)
52         ;; Must preserve BC
53         ld      b,h
54         ld      c,l
55         
56         ;; 16-bit multiplication
57         ;; 
58         ;; Entry conditions
59         ;;   BC = multiplicand
60         ;;   DE = multiplier
61         ;; 
62         ;; Exit conditions
63         ;;   DE = less significant word of product
64         ;;
65         ;; Register used: AF,BC,DE,HL
66 .mul16:
67 .mulu16:
68         LD      HL,#0x00        ; Product = 0
69         LD      A,#15           ; Count = bit length - 1
70         ;; Shift-and-add algorithm
71         ;; If MSB of multiplier is 1, add multiplicand to partial product
72         ;; Shift partial product, multiplier left 1 bit
73 .mlp:
74         SLA     E               ; Shift multiplier left 1 bit
75         RL      D
76         jp      NC,.mlp1        ; Jump if MSB of multiplier = 0
77         ADD     HL,BC           ; Add multiplicand to partial product
78 .mlp1:
79         ADD     HL,HL           ; Shift partial product left
80         DEC     A
81         jp      NZ,.mlp         ; Continue until count = 0
82         ;; Add multiplicand one last time if MSB of multiplier is 1
83         BIT     7,D             ; Get MSB of multiplier
84         JR      Z,.mend         ; Exit if MSB of multiplier is 0
85         ADD     HL,BC           ; Add multiplicand to product
86 .mend:
87                                 ; HL = result
88         ret
89