From 0b30ec51d18d978de9343c633e734447ee087a30 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 18 Jan 2026 11:32:34 +0000 Subject: [PATCH 1/2] fix: typo in mul32.asm runtime library --- src/lib/arch/zx48k/runtime/arith/mul32.asm | 3 - tests/functional/arch/zx48k/fact.asm | 1 - tests/functional/arch/zx48k/ltee9.asm | 1 - tests/functional/arch/zx48k/mul32.asm | 154 +++++++++++++++++++++ tests/functional/arch/zx48k/mul32.bas | 10 ++ tests/functional/arch/zx48k/mul32a.asm | 135 ++++++++++++++++++ tests/functional/arch/zx48k/mul32a.bas | 4 + tests/functional/arch/zx48k/mul32b.asm | 145 +++++++++++++++++++ tests/functional/arch/zx48k/mul32b.bas | 4 + tests/functional/arch/zx48k/mul32c.asm | 130 +++++++++++++++++ tests/functional/arch/zx48k/mul32c.bas | 3 + tests/functional/arch/zx48k/subrec.asm | 1 - 12 files changed, 585 insertions(+), 6 deletions(-) create mode 100644 tests/functional/arch/zx48k/mul32.asm create mode 100644 tests/functional/arch/zx48k/mul32.bas create mode 100644 tests/functional/arch/zx48k/mul32a.asm create mode 100644 tests/functional/arch/zx48k/mul32a.bas create mode 100644 tests/functional/arch/zx48k/mul32b.asm create mode 100644 tests/functional/arch/zx48k/mul32b.bas create mode 100644 tests/functional/arch/zx48k/mul32c.asm create mode 100644 tests/functional/arch/zx48k/mul32c.bas diff --git a/src/lib/arch/zx48k/runtime/arith/mul32.asm b/src/lib/arch/zx48k/runtime/arith/mul32.asm index fc6430221..641bc1efb 100644 --- a/src/lib/arch/zx48k/runtime/arith/mul32.asm +++ b/src/lib/arch/zx48k/runtime/arith/mul32.asm @@ -24,6 +24,3 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ret pop namespace - - -f diff --git a/tests/functional/arch/zx48k/fact.asm b/tests/functional/arch/zx48k/fact.asm index 2367e493a..e666c4249 100644 --- a/tests/functional/arch/zx48k/fact.asm +++ b/tests/functional/arch/zx48k/fact.asm @@ -185,7 +185,6 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ld l, c ret pop namespace - f #line 83 "arch/zx48k/fact.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm" ; SUB32 diff --git a/tests/functional/arch/zx48k/ltee9.asm b/tests/functional/arch/zx48k/ltee9.asm index f08516af1..f32f00449 100644 --- a/tests/functional/arch/zx48k/ltee9.asm +++ b/tests/functional/arch/zx48k/ltee9.asm @@ -277,7 +277,6 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ld l, c ret pop namespace - f #line 85 "arch/zx48k/ltee9.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm" ; SUB32 diff --git a/tests/functional/arch/zx48k/mul32.asm b/tests/functional/arch/zx48k/mul32.asm new file mode 100644 index 000000000..a2eb9a4fb --- /dev/null +++ b/tests/functional/arch/zx48k/mul32.asm @@ -0,0 +1,154 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_a: + DEFB 00, 00, 00, 00 +_b: + DEFB 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_a) + ld de, (_a + 2) + ld hl, 0 + ld d, h + ld e, l + ld (_b), hl + ld (_b + 2), de + ld hl, (_a) + ld de, (_a + 2) + ld (_b), hl + ld (_b + 2), de + ld hl, (_a) + ld de, (_a + 2) + ld hl, 0 + ld d, h + ld e, l + ld (_b), hl + ld (_b + 2), de + ld hl, (_a) + ld de, (_a + 2) + ld (_b), hl + ld (_b + 2), de + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__MUL32 + ld (_b), hl + ld (_b + 2), de + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm" +; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 + ; Used with permission. + ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') + ; 64bit result is returned in H'L'H L B'C'A C + push namespace core +__MUL32_64START: + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply +__LMUL: + xor a ; reset carry flag + ld h, a ; result bits 32..47 = 0 + ld l, a + exx + ld h, a ; result bits 48..63 = 0 + ld l, a + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART +__LMULLOOP: + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx +__LMULNOADD: + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l +__LMULSTART: + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START +__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace +#line 48 "arch/zx48k/mul32.bas" + END diff --git a/tests/functional/arch/zx48k/mul32.bas b/tests/functional/arch/zx48k/mul32.bas new file mode 100644 index 000000000..e72b22271 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32.bas @@ -0,0 +1,10 @@ +' TEST for ADD16 + +DIM a as ULong +DIM b as ULong + +b = a * 0 +b = a * 1 +b = 0 * a +b = 1 * a +b = a * a diff --git a/tests/functional/arch/zx48k/mul32a.asm b/tests/functional/arch/zx48k/mul32a.asm new file mode 100644 index 000000000..5777ebff5 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32a.asm @@ -0,0 +1,135 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_a: + DEFB 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__MUL32 + push de + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__MUL32 + ld (_a), hl + ld (_a + 2), de + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm" +; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 + ; Used with permission. + ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') + ; 64bit result is returned in H'L'H L B'C'A C + push namespace core +__MUL32_64START: + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply +__LMUL: + xor a ; reset carry flag + ld h, a ; result bits 32..47 = 0 + ld l, a + exx + ld h, a ; result bits 48..63 = 0 + ld l, a + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART +__LMULLOOP: + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx +__LMULNOADD: + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l +__LMULSTART: + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START +__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace +#line 31 "arch/zx48k/mul32a.bas" + END diff --git a/tests/functional/arch/zx48k/mul32a.bas b/tests/functional/arch/zx48k/mul32a.bas new file mode 100644 index 000000000..6e5a4b154 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32a.bas @@ -0,0 +1,4 @@ + +REM another MUL16 test +DIM a As Long +a = a * a * a diff --git a/tests/functional/arch/zx48k/mul32b.asm b/tests/functional/arch/zx48k/mul32b.asm new file mode 100644 index 000000000..ac6b32790 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32b.asm @@ -0,0 +1,145 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_a: + DEFB 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__MUL32 + push de + push hl + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld de, 0 + ld hl, 2 + call .core.__MUL32 + push de + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__MUL32 + call .core.__MUL32 + ld (_a), hl + ld (_a + 2), de + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm" +; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 + ; Used with permission. + ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') + ; 64bit result is returned in H'L'H L B'C'A C + push namespace core +__MUL32_64START: + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply +__LMUL: + xor a ; reset carry flag + ld h, a ; result bits 32..47 = 0 + ld l, a + exx + ld h, a ; result bits 48..63 = 0 + ld l, a + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART +__LMULLOOP: + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx +__LMULNOADD: + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l +__LMULSTART: + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START +__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace +#line 41 "arch/zx48k/mul32b.bas" + END diff --git a/tests/functional/arch/zx48k/mul32b.bas b/tests/functional/arch/zx48k/mul32b.bas new file mode 100644 index 000000000..be0b14e49 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32b.bas @@ -0,0 +1,4 @@ + +REM another ADD16 tests +DIM a As Long +a = a * a * (a * 2 * a) diff --git a/tests/functional/arch/zx48k/mul32c.asm b/tests/functional/arch/zx48k/mul32c.asm new file mode 100644 index 000000000..434009422 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32c.asm @@ -0,0 +1,130 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_a: + DEFB 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld de, 65535 + ld hl, 65535 + call .core.__MUL32 + ld (_a), hl + ld (_a + 2), de + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/_mul32.asm" +; Ripped from: http://www.andreadrian.de/oldcpu/z80_number_cruncher.html#moztocid784223 + ; Used with permission. + ; Multiplies 32x32 bit integer (DEHL x D'E'H'L') + ; 64bit result is returned in H'L'H L B'C'A C + push namespace core +__MUL32_64START: + push hl + exx + ld b, h + ld c, l ; BC = Low Part (A) + pop hl ; HL = Load Part (B) + ex de, hl ; DE = Low Part (B), HL = HightPart(A) (must be in B'C') + push hl + exx + pop bc ; B'C' = HightPart(A) + exx ; A = B'C'BC , B = D'E'DE + ; multiply routine 32 * 32bit = 64bit + ; h'l'hlb'c'ac = b'c'bc * d'e'de + ; needs register a, changes flags + ; + ; this routine was with tiny differences in the + ; sinclair zx81 rom for the mantissa multiply +__LMUL: + xor a ; reset carry flag + ld h, a ; result bits 32..47 = 0 + ld l, a + exx + ld h, a ; result bits 48..63 = 0 + ld l, a + exx + ld a,b ; mpr is b'c'ac + ld b,33 ; initialize loop counter + jp __LMULSTART +__LMULLOOP: + jr nc,__LMULNOADD ; JP is 2 cycles faster than JR. Since it's inside a LOOP + ; it can save up to 33 * 2 = 66 cycles + ; But JR if 3 cycles faster if JUMP not taken! + add hl,de ; result += mpd + exx + adc hl,de + exx +__LMULNOADD: + exx + rr h ; right shift upper + rr l ; 32bit of result + exx + rr h + rr l +__LMULSTART: + exx + rr b ; right shift mpr/ + rr c ; lower 32bit of result + exx + rra ; equivalent to rr a + rr c + djnz __LMULLOOP + ret ; result in h'l'hlb'c'ac + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mul32.asm" + push namespace core +__MUL32: + ; multiplies 32 bit un/signed integer. + ; First operand stored in DEHL, and 2nd onto stack + ; Lowest part of 2nd operand on top of the stack + ; returns the result in DE.HL + exx + pop hl ; Return ADDRESS + pop de ; Low part + ex (sp), hl ; CALLEE -> HL = High part + ex de, hl + call __MUL32_64START +__TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) + exx + push bc + exx + pop de + ld h, a + ld l, c + ret + pop namespace +#line 26 "arch/zx48k/mul32c.bas" + END diff --git a/tests/functional/arch/zx48k/mul32c.bas b/tests/functional/arch/zx48k/mul32c.bas new file mode 100644 index 000000000..43d6f9123 --- /dev/null +++ b/tests/functional/arch/zx48k/mul32c.bas @@ -0,0 +1,3 @@ +DIM a as Long + +a = -1 * a diff --git a/tests/functional/arch/zx48k/subrec.asm b/tests/functional/arch/zx48k/subrec.asm index a21e61db9..46a2cb3f7 100644 --- a/tests/functional/arch/zx48k/subrec.asm +++ b/tests/functional/arch/zx48k/subrec.asm @@ -201,7 +201,6 @@ __TO32BIT: ; Converts H'L'HLB'C'AC to DEHL (Discards H'L'HL) ld l, c ret pop namespace - f #line 94 "arch/zx48k/subrec.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/arith/sub32.asm" ; SUB32 From 5cac7640df8de061557df89baee61c3d3599ff07 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 18 Jan 2026 10:27:53 +0000 Subject: [PATCH 2/2] tests: add SGN tests for zxnext arch --- tests/functional/arch/zxnext/sgnf.asm | 78 +++++++++++++++++++++++++ tests/functional/arch/zxnext/sgnf.bas | 2 + tests/functional/arch/zxnext/sgnf16.asm | 76 ++++++++++++++++++++++++ tests/functional/arch/zxnext/sgnf16.bas | 2 + tests/functional/arch/zxnext/sgni16.asm | 73 +++++++++++++++++++++++ tests/functional/arch/zxnext/sgni16.bas | 2 + tests/functional/arch/zxnext/sgni32.asm | 76 ++++++++++++++++++++++++ tests/functional/arch/zxnext/sgni32.bas | 2 + tests/functional/arch/zxnext/sgni8.asm | 46 +++++++++++++++ tests/functional/arch/zxnext/sgni8.bas | 2 + tests/functional/arch/zxnext/sgnu16.asm | 46 +++++++++++++++ tests/functional/arch/zxnext/sgnu16.bas | 2 + tests/functional/arch/zxnext/sgnu32.asm | 51 ++++++++++++++++ tests/functional/arch/zxnext/sgnu32.bas | 2 + tests/functional/arch/zxnext/sgnu8.asm | 44 ++++++++++++++ tests/functional/arch/zxnext/sgnu8.bas | 2 + 16 files changed, 506 insertions(+) create mode 100644 tests/functional/arch/zxnext/sgnf.asm create mode 100644 tests/functional/arch/zxnext/sgnf.bas create mode 100644 tests/functional/arch/zxnext/sgnf16.asm create mode 100644 tests/functional/arch/zxnext/sgnf16.bas create mode 100644 tests/functional/arch/zxnext/sgni16.asm create mode 100644 tests/functional/arch/zxnext/sgni16.bas create mode 100644 tests/functional/arch/zxnext/sgni32.asm create mode 100644 tests/functional/arch/zxnext/sgni32.bas create mode 100644 tests/functional/arch/zxnext/sgni8.asm create mode 100644 tests/functional/arch/zxnext/sgni8.bas create mode 100644 tests/functional/arch/zxnext/sgnu16.asm create mode 100644 tests/functional/arch/zxnext/sgnu16.bas create mode 100644 tests/functional/arch/zxnext/sgnu32.asm create mode 100644 tests/functional/arch/zxnext/sgnu32.bas create mode 100644 tests/functional/arch/zxnext/sgnu8.asm create mode 100644 tests/functional/arch/zxnext/sgnu8.bas diff --git a/tests/functional/arch/zxnext/sgnf.asm b/tests/functional/arch/zxnext/sgnf.asm new file mode 100644 index 000000000..75d8446ff --- /dev/null +++ b/tests/functional/arch/zxnext/sgnf.asm @@ -0,0 +1,78 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 81h + DEFB 00h + DEFB 00h + DEFB 00h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, (_y) + ld de, (_y + 1) + ld bc, (_y + 3) + call .core.__SGNF + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgnf.asm" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgn.asm" + ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core + PROC + LOCAL __ENDSGN +__SGNF: + or b + or c + or d + or e + ret z + ld a, e + jr __ENDSGN +__SGNF16: +__SGNI32: + ld a, h + or l + or e + or d + ret z + ld a, d + jr __ENDSGN +__SGNI16: + ld a, h + or l + ret z + ld a, h +__ENDSGN: + or a + ld a, 1 + ret p + neg + ret + ENDP + pop namespace +#line 2 "/zxbasic/src/lib/arch/zxnext/runtime/sgnf.asm" +#line 18 "arch/zxnext/sgnf.bas" + END diff --git a/tests/functional/arch/zxnext/sgnf.bas b/tests/functional/arch/zxnext/sgnf.bas new file mode 100644 index 000000000..e652173d7 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnf.bas @@ -0,0 +1,2 @@ +dim y as Float=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgnf16.asm b/tests/functional/arch/zxnext/sgnf16.asm new file mode 100644 index 000000000..e7709c53e --- /dev/null +++ b/tests/functional/arch/zxnext/sgnf16.asm @@ -0,0 +1,76 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 00h + DEFB 00h + DEFB 01h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_y) + ld de, (_y + 2) + call .core.__SGNF16 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgnf16.asm" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgn.asm" + ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core + PROC + LOCAL __ENDSGN +__SGNF: + or b + or c + or d + or e + ret z + ld a, e + jr __ENDSGN +__SGNF16: +__SGNI32: + ld a, h + or l + or e + or d + ret z + ld a, d + jr __ENDSGN +__SGNI16: + ld a, h + or l + ret z + ld a, h +__ENDSGN: + or a + ld a, 1 + ret p + neg + ret + ENDP + pop namespace +#line 2 "/zxbasic/src/lib/arch/zxnext/runtime/sgnf16.asm" +#line 17 "arch/zxnext/sgnf16.bas" + END diff --git a/tests/functional/arch/zxnext/sgnf16.bas b/tests/functional/arch/zxnext/sgnf16.bas new file mode 100644 index 000000000..717a60512 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnf16.bas @@ -0,0 +1,2 @@ +dim y as Fixed=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgni16.asm b/tests/functional/arch/zxnext/sgni16.asm new file mode 100644 index 000000000..26f6608c6 --- /dev/null +++ b/tests/functional/arch/zxnext/sgni16.asm @@ -0,0 +1,73 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_y) + call .core.__SGNI16 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgni16.asm" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgn.asm" + ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core + PROC + LOCAL __ENDSGN +__SGNF: + or b + or c + or d + or e + ret z + ld a, e + jr __ENDSGN +__SGNF16: +__SGNI32: + ld a, h + or l + or e + or d + ret z + ld a, d + jr __ENDSGN +__SGNI16: + ld a, h + or l + ret z + ld a, h +__ENDSGN: + or a + ld a, 1 + ret p + neg + ret + ENDP + pop namespace +#line 2 "/zxbasic/src/lib/arch/zxnext/runtime/sgni16.asm" +#line 16 "arch/zxnext/sgni16.bas" + END diff --git a/tests/functional/arch/zxnext/sgni16.bas b/tests/functional/arch/zxnext/sgni16.bas new file mode 100644 index 000000000..ae9e6710d --- /dev/null +++ b/tests/functional/arch/zxnext/sgni16.bas @@ -0,0 +1,2 @@ +dim y as Integer=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgni32.asm b/tests/functional/arch/zxnext/sgni32.asm new file mode 100644 index 000000000..243567436 --- /dev/null +++ b/tests/functional/arch/zxnext/sgni32.asm @@ -0,0 +1,76 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h + DEFB 00h + DEFB 00h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_y) + ld de, (_y + 2) + call .core.__SGNI32 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgni32.asm" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgn.asm" + ; Returns SGN (SIGN) for 32, 16 and 8 bits signed integers, Fixed and FLOAT + push namespace core + PROC + LOCAL __ENDSGN +__SGNF: + or b + or c + or d + or e + ret z + ld a, e + jr __ENDSGN +__SGNF16: +__SGNI32: + ld a, h + or l + or e + or d + ret z + ld a, d + jr __ENDSGN +__SGNI16: + ld a, h + or l + ret z + ld a, h +__ENDSGN: + or a + ld a, 1 + ret p + neg + ret + ENDP + pop namespace +#line 2 "/zxbasic/src/lib/arch/zxnext/runtime/sgni32.asm" +#line 17 "arch/zxnext/sgni32.bas" + END diff --git a/tests/functional/arch/zxnext/sgni32.bas b/tests/functional/arch/zxnext/sgni32.bas new file mode 100644 index 000000000..8ae2f3c43 --- /dev/null +++ b/tests/functional/arch/zxnext/sgni32.bas @@ -0,0 +1,2 @@ +dim y as Long=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgni8.asm b/tests/functional/arch/zxnext/sgni8.asm new file mode 100644 index 000000000..28649be72 --- /dev/null +++ b/tests/functional/arch/zxnext/sgni8.asm @@ -0,0 +1,46 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, (_y) + call .core.__SGNI8 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgni8.asm" + ; Returns SGN (SIGN) for 8 bits signed integer + push namespace core +__SGNI8: + or a + ret z + ld a, 1 + ret p + neg + ret + pop namespace +#line 16 "arch/zxnext/sgni8.bas" + END diff --git a/tests/functional/arch/zxnext/sgni8.bas b/tests/functional/arch/zxnext/sgni8.bas new file mode 100644 index 000000000..ec06c5224 --- /dev/null +++ b/tests/functional/arch/zxnext/sgni8.bas @@ -0,0 +1,2 @@ +dim y as Byte=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgnu16.asm b/tests/functional/arch/zxnext/sgnu16.asm new file mode 100644 index 000000000..49b5132f6 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu16.asm @@ -0,0 +1,46 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_y) + call .core.__SGNU16 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgnu16.asm" + ; Returns SGN (SIGN) for 16 bits unsigned integer + push namespace core +__SGNU16: + ld a, h + or l + ret z + ld a, 1 + ret + pop namespace +#line 16 "arch/zxnext/sgnu16.bas" + END diff --git a/tests/functional/arch/zxnext/sgnu16.bas b/tests/functional/arch/zxnext/sgnu16.bas new file mode 100644 index 000000000..af1acc29c --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu16.bas @@ -0,0 +1,2 @@ +dim y as uInteger=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgnu32.asm b/tests/functional/arch/zxnext/sgnu32.asm new file mode 100644 index 000000000..5d9837438 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu32.asm @@ -0,0 +1,51 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h + DEFB 00h + DEFB 00h + DEFB 00h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, (_y) + ld de, (_y + 2) + call .core.__SGNU32 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgnu32.asm" + ; Returns SGN (SIGN) for 32 bits unsigned integer + push namespace core +__SGNU32: + ld a, h + or l + or d + or e + ret z + ld a, 1 + ret + pop namespace +#line 17 "arch/zxnext/sgnu32.bas" + END diff --git a/tests/functional/arch/zxnext/sgnu32.bas b/tests/functional/arch/zxnext/sgnu32.bas new file mode 100644 index 000000000..00bc09c8f --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu32.bas @@ -0,0 +1,2 @@ +dim y as uLong=1 +poke 0, sgn y diff --git a/tests/functional/arch/zxnext/sgnu8.asm b/tests/functional/arch/zxnext/sgnu8.asm new file mode 100644 index 000000000..f53b2fe57 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu8.asm @@ -0,0 +1,44 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld (.core.__CALL_BACK__), sp + ei + jp .core.__MAIN_PROGRAM__ +.core.__CALL_BACK__: + DEFW 0 +.core.ZXBASIC_USER_DATA: + ; Defines USER DATA Length in bytes +.core.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_END - .core.ZXBASIC_USER_DATA + .core.__LABEL__.ZXBASIC_USER_DATA_LEN EQU .core.ZXBASIC_USER_DATA_LEN + .core.__LABEL__.ZXBASIC_USER_DATA EQU .core.ZXBASIC_USER_DATA +_y: + DEFB 01h +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, (_y) + call .core.__SGNU8 + ld (0), a + ld hl, 0 + ld b, h + ld c, l +.core.__END_PROGRAM: + di + ld hl, (.core.__CALL_BACK__) + ld sp, hl + pop iy + ei + ret + ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/sgnu8.asm" + ; Returns SGN (SIGN) for 8 bits unsigned integera + push namespace core +__SGNU8: + or a + ret z + ld a, 1 + ret + pop namespace +#line 16 "arch/zxnext/sgnu8.bas" + END diff --git a/tests/functional/arch/zxnext/sgnu8.bas b/tests/functional/arch/zxnext/sgnu8.bas new file mode 100644 index 000000000..497869458 --- /dev/null +++ b/tests/functional/arch/zxnext/sgnu8.bas @@ -0,0 +1,2 @@ +dim y as uByte=1 +poke 0, sgn y