gbdk-2020 | GameBoy Development Kit |
| download: https://git.y1.nz/archives/gbdk.tar.gz | |
| README | Files | Log | Refs | LICENSE |
gbdk-lib/libc/asm/sm83/mul.s
1 ;--------------------------------------------------------------------------
2 ; mul.s
3 ;
4 ; Copyright (c) 2026, Phidias618
5 ;
6 ;--------------------------------------------------------------------------
7
8 .module mul
9 .area _CODE
10
11 .globl __mulsuchar
12 .globl __muluschar
13 .globl __mulschar
14 .globl __muluchar
15 .globl __mulint
16
17 ; operands with different sign
18
19 __muluschar:
20 ld b, a
21 ld a, e
22 ld e, b
23 __mulsuchar:
24 ; sign extends E while preserving A
25 ld l, #0
26 ld d, l
27 bit 7, e
28 jr z, .mul_acc_adel
29 dec d
30 jr .mul_acc_adel
31
32 __muluchar:
33 ld l, #0
34 ld d, l
35 jr .mul_acc_adel
36 __mulschar:
37 ; sign extends A into BC
38 ld c, a
39 add a
40 sbc a
41 ld b, a
42
43 ; sign extends E into DE
44 ld a, e
45 add a
46 sbc a
47 ld d, a
48 ; Fall through __mulint
49 __mulint:
50 ; computes BC * DE by using the following identity :
51 ; BC * DE = (B * E * 256) + (C * DE)
52
53 ; if D = 0 computes E * BC instead
54 ld a, d
55 OR a
56 jr z, shortcut_swap
57
58 ; computes B * E
59 xor a
60 sla b
61 jr nc, 0$
62 add e
63 0$:
64 ; skips the rest of the loop if either B = 0 or (B >= 128 and E = 0)
65 jr z, .mul_acc_cdea
66 .irp label, 1$, 2$, 3$, 4$, 5$, 6$, 7$
67 add a
68 sla b
69 jr nc, label
70 add e
71 label:
72 .endm
73 ; B * E is now stored in A
74
75 .mul_acc_cdea:
76 ; computes (C * DE) + (256 * A)
77 ld l, a
78 ld a, c
79 .mul_acc_adel:
80 ; computes (A * DE) + (256 * L)
81 .irp label, 0$, 1$, 2$, 3$, 4$, 5$, 6$, 7$
82 add hl, hl
83 add a
84 jr nc, label
85 add hl, de
86 label:
87 .endm
88 ld b, h
89 ld c, l
90 ret
91
92 shortcut_swap:
93 ld l, a ; a = 0
94 ld a, e
95 ld d, b
96 ld e, c
97 jr .mul_acc_adel
98
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.