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