Skip to content

Commit 863a56d

Browse files
authored
Merge pull request #1037 from boriel-basic/fix/typo_in_mul32_asm
Fix/typo in mul32 asm
2 parents 9a88079 + 5cac764 commit 863a56d

28 files changed

Lines changed: 1091 additions & 6 deletions

src/lib/arch/zx48k/runtime/arith/mul32.asm

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,3 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
2424
ret
2525

2626
pop namespace
27-
28-
29-
f

tests/functional/arch/zx48k/fact.asm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,6 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
185185
ld l, c
186186
ret
187187
pop namespace
188-
f
189188
#line 83 "arch/zx48k/fact.bas"
190189
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm"
191190
; SUB32

tests/functional/arch/zx48k/ltee9.asm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,6 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
277277
ld l, c
278278
ret
279279
pop namespace
280-
f
281280
#line 85 "arch/zx48k/ltee9.bas"
282281
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm"
283282
; SUB32
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld (.core.__CALL_BACK__), sp
10+
ei
11+
jp .core.__MAIN_PROGRAM__
12+
.core.__CALL_BACK__:
13+
DEFW 0
14+
.core.ZXBASIC_USER_DATA:
15+
; Defines USER DATA Length in bytes
16+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
17+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
18+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
19+
_a:
20+
DEFB 00, 00, 00, 00
21+
_b:
22+
DEFB 00, 00, 00, 00
23+
.core.ZXBASIC_USER_DATA_END:
24+
.core.__MAIN_PROGRAM__:
25+
ld hl, (_a)
26+
ld de, (_a + 2)
27+
ld hl, 0
28+
ld d, h
29+
ld e, l
30+
ld (_b), hl
31+
ld (_b + 2), de
32+
ld hl, (_a)
33+
ld de, (_a + 2)
34+
ld (_b), hl
35+
ld (_b + 2), de
36+
ld hl, (_a)
37+
ld de, (_a + 2)
38+
ld hl, 0
39+
ld d, h
40+
ld e, l
41+
ld (_b), hl
42+
ld (_b + 2), de
43+
ld hl, (_a)
44+
ld de, (_a + 2)
45+
ld (_b), hl
46+
ld (_b + 2), de
47+
ld hl, (_a + 2)
48+
push hl
49+
ld hl, (_a)
50+
push hl
51+
ld hl, (_a)
52+
ld de, (_a + 2)
53+
call .core.__MUL32
54+
ld (_b), hl
55+
ld (_b + 2), de
56+
ld hl, 0
57+
ld b, h
58+
ld c, l
59+
.core.__END_PROGRAM:
60+
di
61+
ld hl, (.core.__CALL_BACK__)
62+
ld sp, hl
63+
exx
64+
pop hl
65+
exx
66+
pop iy
67+
pop ix
68+
ei
69+
ret
70+
;; --- end of user code ---
71+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm"
72+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm"
73+
; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223
74+
; Used with permission.
75+
; Multiplies 32x32 bit integer (DEHL x D'E'H'L')
76+
; 64bit result is returned in H'L'H L B'C'A C
77+
push namespace core
78+
__MUL32_64START:
79+
push hl
80+
exx
81+
ld b, h
82+
ld c, l ; BC = Low Part (A)
83+
pop hl ; HL = Load Part (B)
84+
ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C')
85+
push hl
86+
exx
87+
pop bc ; B'C' = HightPart(A)
88+
exx ; A = B'C'BC , B = D'E'DE
89+
; multiply routine 32 * 32bit = 64bit
90+
; h'l'hlb'c'ac = b'c'bc * d'e'de
91+
; needs register a, changes flags
92+
;
93+
; this routine was with tiny differences in the
94+
; sinclair zx81 rom for the mantissa multiply
95+
__LMUL:
96+
xor a ; reset carry flag
97+
ld h, a ; result bits 32..47 = 0
98+
ld l, a
99+
exx
100+
ld h, a ; result bits 48..63 = 0
101+
ld l, a
102+
exx
103+
ld a,b ; mpr is b'c'ac
104+
ld b,33 ; initialize loop counter
105+
jp __LMULSTART
106+
__LMULLOOP:
107+
jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP
108+
; it can save up to 33 * 2 = 66 cycles
109+
; But JR if 3 cycles faster if JUMP not taken!
110+
add hl,de ; result += mpd
111+
exx
112+
adc hl,de
113+
exx
114+
__LMULNOADD:
115+
exx
116+
rr h ; right shift upper
117+
rr l ; 32bit of result
118+
exx
119+
rr h
120+
rr l
121+
__LMULSTART:
122+
exx
123+
rr b ; right shift mpr/
124+
rr c ; lower 32bit of result
125+
exx
126+
rra ; equivalent to rr a
127+
rr c
128+
djnz __LMULLOOP
129+
ret ; result in h'l'hlb'c'ac
130+
pop namespace
131+
#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm"
132+
push namespace core
133+
__MUL32:
134+
; multiplies 32 bit un/signed integer.
135+
; First operand stored in DEHL, and 2nd onto stack
136+
; Lowest part of 2nd operand on top of the stack
137+
; returns the result in DE.HL
138+
exx
139+
pop hl ; Return ADDRESS
140+
pop de ; Low part
141+
ex (sp), hl ; CALLEE -> HL = High part
142+
ex de, hl
143+
call __MUL32_64START
144+
__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
145+
exx
146+
push bc
147+
exx
148+
pop de
149+
ld h, a
150+
ld l, c
151+
ret
152+
pop namespace
153+
#line 48 "arch/zx48k/mul32.bas"
154+
END
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
' TEST for ADD16
2+
3+
DIM a as ULong
4+
DIM b as ULong
5+
6+
b = a * 0
7+
b = a * 1
8+
b = 0 * a
9+
b = 1 * a
10+
b = a * a
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
org 32768
2+
.core.__START_PROGRAM:
3+
di
4+
push ix
5+
push iy
6+
exx
7+
push hl
8+
exx
9+
ld (.core.__CALL_BACK__), sp
10+
ei
11+
jp .core.__MAIN_PROGRAM__
12+
.core.__CALL_BACK__:
13+
DEFW 0
14+
.core.ZXBASIC_USER_DATA:
15+
; Defines USER DATA Length in bytes
16+
.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA
17+
.core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN
18+
.core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA
19+
_a:
20+
DEFB 00, 00, 00, 00
21+
.core.ZXBASIC_USER_DATA_END:
22+
.core.__MAIN_PROGRAM__:
23+
ld hl, (_a + 2)
24+
push hl
25+
ld hl, (_a)
26+
push hl
27+
ld hl, (_a)
28+
ld de, (_a + 2)
29+
call .core.__MUL32
30+
push de
31+
push hl
32+
ld hl, (_a)
33+
ld de, (_a + 2)
34+
call .core.__MUL32
35+
ld (_a), hl
36+
ld (_a + 2), de
37+
ld hl, 0
38+
ld b, h
39+
ld c, l
40+
.core.__END_PROGRAM:
41+
di
42+
ld hl, (.core.__CALL_BACK__)
43+
ld sp, hl
44+
exx
45+
pop hl
46+
exx
47+
pop iy
48+
pop ix
49+
ei
50+
ret
51+
;; --- end of user code ---
52+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm"
53+
#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm"
54+
; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223
55+
; Used with permission.
56+
; Multiplies 32x32 bit integer (DEHL x D'E'H'L')
57+
; 64bit result is returned in H'L'H L B'C'A C
58+
push namespace core
59+
__MUL32_64START:
60+
push hl
61+
exx
62+
ld b, h
63+
ld c, l ; BC = Low Part (A)
64+
pop hl ; HL = Load Part (B)
65+
ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C')
66+
push hl
67+
exx
68+
pop bc ; B'C' = HightPart(A)
69+
exx ; A = B'C'BC , B = D'E'DE
70+
; multiply routine 32 * 32bit = 64bit
71+
; h'l'hlb'c'ac = b'c'bc * d'e'de
72+
; needs register a, changes flags
73+
;
74+
; this routine was with tiny differences in the
75+
; sinclair zx81 rom for the mantissa multiply
76+
__LMUL:
77+
xor a ; reset carry flag
78+
ld h, a ; result bits 32..47 = 0
79+
ld l, a
80+
exx
81+
ld h, a ; result bits 48..63 = 0
82+
ld l, a
83+
exx
84+
ld a,b ; mpr is b'c'ac
85+
ld b,33 ; initialize loop counter
86+
jp __LMULSTART
87+
__LMULLOOP:
88+
jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP
89+
; it can save up to 33 * 2 = 66 cycles
90+
; But JR if 3 cycles faster if JUMP not taken!
91+
add hl,de ; result += mpd
92+
exx
93+
adc hl,de
94+
exx
95+
__LMULNOADD:
96+
exx
97+
rr h ; right shift upper
98+
rr l ; 32bit of result
99+
exx
100+
rr h
101+
rr l
102+
__LMULSTART:
103+
exx
104+
rr b ; right shift mpr/
105+
rr c ; lower 32bit of result
106+
exx
107+
rra ; equivalent to rr a
108+
rr c
109+
djnz __LMULLOOP
110+
ret ; result in h'l'hlb'c'ac
111+
pop namespace
112+
#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm"
113+
push namespace core
114+
__MUL32:
115+
; multiplies 32 bit un/signed integer.
116+
; First operand stored in DEHL, and 2nd onto stack
117+
; Lowest part of 2nd operand on top of the stack
118+
; returns the result in DE.HL
119+
exx
120+
pop hl ; Return ADDRESS
121+
pop de ; Low part
122+
ex (sp), hl ; CALLEE -> HL = High part
123+
ex de, hl
124+
call __MUL32_64START
125+
__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL)
126+
exx
127+
push bc
128+
exx
129+
pop de
130+
ld h, a
131+
ld l, c
132+
ret
133+
pop namespace
134+
#line 31 "arch/zx48k/mul32a.bas"
135+
END
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
REM another MUL16 test
3+
DIM a As Long
4+
a = a * a * a

0 commit comments

Comments
 (0)