diff --git a/src/arch/z80/visitor/translator_inst_visitor.py b/src/arch/z80/visitor/translator_inst_visitor.py index d0a0d0ab4..bb4336b4c 100644 --- a/src/arch/z80/visitor/translator_inst_visitor.py +++ b/src/arch/z80/visitor/translator_inst_visitor.py @@ -244,4 +244,4 @@ def ic_varx(self, name: str, type_: TYPE | sym.BASICTYPE, default_value: list) - self.emit("varx", name, self.TSUFFIX(type_), default_value) def ic_xor(self, type_: TYPE | sym.BASICTYPE, t, t1, t2) -> None: - self.emit("xor" + self.TSUFFIX(type_), t, t1, t2) + self.emit(f"xor{self._no_bool(type_)}", t, t1, t2) diff --git a/tests/functional/arch/zx48k/and16.asm b/tests/functional/arch/zx48k/and16.asm index 9af2a346c..b14ea39ec 100644 --- a/tests/functional/arch/zx48k/and16.asm +++ b/tests/functional/arch/zx48k/and16.asm @@ -47,6 +47,23 @@ _b: ld de, (_a) ld hl, (_a) call .core.__AND16 + sub 1 + sbc a, a + inc a + ld (_b), a + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + push af + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + ld h, a + pop af + or a + jr z, .LABEL.__LABEL0 + ld a, h +.LABEL.__LABEL0: sub 1 sbc a, a inc a @@ -80,5 +97,16 @@ __AND16: or e ret pop namespace -#line 44 "arch/zx48k/and16.bas" +#line 61 "arch/zx48k/and16.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 62 "arch/zx48k/and16.bas" END diff --git a/tests/functional/arch/zx48k/and16.bas b/tests/functional/arch/zx48k/and16.bas index 81e47d603..b18383260 100644 --- a/tests/functional/arch/zx48k/and16.bas +++ b/tests/functional/arch/zx48k/and16.bas @@ -8,3 +8,5 @@ b = a AND 1 b = 0 AND a b = 1 AND a b = a AND a +b = (a = a) AND (a = a) + diff --git a/tests/functional/arch/zx48k/and32.asm b/tests/functional/arch/zx48k/and32.asm index 9492290cd..6be51625f 100644 --- a/tests/functional/arch/zx48k/and32.asm +++ b/tests/functional/arch/zx48k/and32.asm @@ -57,6 +57,31 @@ _b: ld hl, (_a) ld de, (_a + 2) call .core.__AND32 + sub 1 + sbc a, a + inc a + ld (_b), a + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + push af + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + ld h, a + pop af + or a + jr z, .LABEL.__LABEL0 + ld a, h +.LABEL.__LABEL0: sub 1 sbc a, a inc a @@ -98,5 +123,31 @@ __AND32: #line 28 "/zxbasic/src/lib/arch/zx48k/runtime/bool/and32.asm" ret pop namespace -#line 54 "arch/zx48k/and32.bas" +#line 79 "arch/zx48k/and32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 80 "arch/zx48k/and32.bas" END diff --git a/tests/functional/arch/zx48k/and32.bas b/tests/functional/arch/zx48k/and32.bas index 3524e58c5..0b09b7d9d 100644 --- a/tests/functional/arch/zx48k/and32.bas +++ b/tests/functional/arch/zx48k/and32.bas @@ -8,3 +8,5 @@ b = a AND 1 b = 0 AND a b = 1 AND a b = a AND a +b = (a = a) AND (a = a) + diff --git a/tests/functional/arch/zx48k/and8.asm b/tests/functional/arch/zx48k/and8.asm index 5c22c95b6..cfa95d399 100644 --- a/tests/functional/arch/zx48k/and8.asm +++ b/tests/functional/arch/zx48k/and8.asm @@ -46,6 +46,27 @@ _b: jr z, .LABEL.__LABEL0 ld a, h .LABEL.__LABEL0: + sub 1 + sbc a, a + inc a + ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + ld h, a + pop af + or a + jr z, .LABEL.__LABEL1 + ld a, h +.LABEL.__LABEL1: sub 1 sbc a, a inc a diff --git a/tests/functional/arch/zx48k/and8.bas b/tests/functional/arch/zx48k/and8.bas index 751fff5e8..b9a501ea3 100644 --- a/tests/functional/arch/zx48k/and8.bas +++ b/tests/functional/arch/zx48k/and8.bas @@ -8,3 +8,5 @@ b = a AND 1 b = 0 AND a b = 1 AND a b = a AND a +b = (a = a) AND (a = a) + diff --git a/tests/functional/arch/zx48k/andf.asm b/tests/functional/arch/zx48k/andf.asm index 9b4bb70b8..3f7431c52 100644 --- a/tests/functional/arch/zx48k/andf.asm +++ b/tests/functional/arch/zx48k/andf.asm @@ -67,6 +67,29 @@ _b: call .core.__FP_PUSH_REV call .core.__ANDF ld (_b), a + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + push af + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + ld h, a + pop af + or a + jr z, .LABEL.__LABEL0 + ld a, h +.LABEL.__LABEL0: + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -311,7 +334,28 @@ __ANDF: ; A & B call __FPSTACK_POP jp __FTOU8 ; Convert to 8 bits pop namespace -#line 60 "arch/zx48k/andf.bas" +#line 83 "arch/zx48k/andf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eqf.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses C EDHL registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order BC DE HL (B not used). + ; + ; Uses CALLEE convention + ; ------------------------------------------------------------- + push namespace core +__EQF: ; A = B + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace +#line 84 "arch/zx48k/andf.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last @@ -339,5 +383,5 @@ __FP_PUSH_REV: exx ret pop namespace -#line 61 "arch/zx48k/andf.bas" +#line 85 "arch/zx48k/andf.bas" END diff --git a/tests/functional/arch/zx48k/andf.bas b/tests/functional/arch/zx48k/andf.bas index 4e6a0412a..e8cfba7e6 100644 --- a/tests/functional/arch/zx48k/andf.bas +++ b/tests/functional/arch/zx48k/andf.bas @@ -8,3 +8,5 @@ b = a AND 1 b = 0 AND a b = 1 AND a b = a AND a +b = (a = a) AND (a = a) + diff --git a/tests/functional/arch/zx48k/not16.asm b/tests/functional/arch/zx48k/not16.asm index a8ce1bb36..43d4624d3 100644 --- a/tests/functional/arch/zx48k/not16.asm +++ b/tests/functional/arch/zx48k/not16.asm @@ -35,6 +35,13 @@ _b: sbc a, a neg ld (_b), a + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + sub 1 + sbc a, a + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -50,4 +57,15 @@ _b: ei ret ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 35 "arch/zx48k/not16.bas" END diff --git a/tests/functional/arch/zx48k/not16.bas b/tests/functional/arch/zx48k/not16.bas index c159772a1..5156b63e8 100644 --- a/tests/functional/arch/zx48k/not16.bas +++ b/tests/functional/arch/zx48k/not16.bas @@ -6,3 +6,5 @@ DIM b as Ubyte b = NOT 0 b = NOT 1 b = NOT a +b = NOT (a = a) + diff --git a/tests/functional/arch/zx48k/not32.asm b/tests/functional/arch/zx48k/not32.asm index 3b1c355e5..c8cd68010 100644 --- a/tests/functional/arch/zx48k/not32.asm +++ b/tests/functional/arch/zx48k/not32.asm @@ -33,6 +33,17 @@ _b: call .core.__NOT32 neg ld (_b), a + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + sub 1 + sbc a, a + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -62,5 +73,31 @@ __NOT32: ; A = ¬A sbc a, a; Gives 0 if not carry, FF otherwise ret pop namespace -#line 26 "arch/zx48k/not32.bas" +#line 37 "arch/zx48k/not32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 38 "arch/zx48k/not32.bas" END diff --git a/tests/functional/arch/zx48k/not32.bas b/tests/functional/arch/zx48k/not32.bas index 3988e8fa6..41609f7ec 100644 --- a/tests/functional/arch/zx48k/not32.bas +++ b/tests/functional/arch/zx48k/not32.bas @@ -6,3 +6,5 @@ DIM b as Ubyte b = NOT 0 b = NOT 1 b = NOT a +b = NOT (a = a) + diff --git a/tests/functional/arch/zx48k/not8.asm b/tests/functional/arch/zx48k/not8.asm index d210a9448..64b8c3a21 100644 --- a/tests/functional/arch/zx48k/not8.asm +++ b/tests/functional/arch/zx48k/not8.asm @@ -33,6 +33,13 @@ _b: sbc a, a neg ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l diff --git a/tests/functional/arch/zx48k/not8.bas b/tests/functional/arch/zx48k/not8.bas index dc59750cf..1fe37e044 100644 --- a/tests/functional/arch/zx48k/not8.bas +++ b/tests/functional/arch/zx48k/not8.bas @@ -1,4 +1,4 @@ -' TEST for Booleand NOT 8 bits + ' TEST for Booleand NOT 8 bits DIM a as Ubyte DIM b as Ubyte @@ -6,3 +6,5 @@ DIM b as Ubyte b = NOT 0 b = NOT 1 b = NOT a +b = NOT (a = a) + diff --git a/tests/functional/arch/zx48k/notf.asm b/tests/functional/arch/zx48k/notf.asm index 9a9b32b64..9896a22ef 100644 --- a/tests/functional/arch/zx48k/notf.asm +++ b/tests/functional/arch/zx48k/notf.asm @@ -33,6 +33,16 @@ _b: ld bc, (_a + 3) call .core.__NOTF ld (_b), a + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + sub 1 + sbc a, a + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -277,5 +287,54 @@ __NOTF: ; A = ¬A call __FPSTACK_POP jp __FTOU8 ; Convert to 8 bits pop namespace -#line 26 "arch/zx48k/notf.bas" +#line 36 "arch/zx48k/notf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eqf.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses C EDHL registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order BC DE HL (B not used). + ; + ; Uses CALLEE convention + ; ------------------------------------------------------------- + push namespace core +__EQF: ; A = B + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace +#line 37 "arch/zx48k/notf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pushf.asm" + ; Routine to push Float pointed by HL + ; Into the stack. Notice that the hl points to the last + ; byte of the FP number. + ; Uses H'L' B'C' and D'E' to preserve ABCDEHL registers + push namespace core +__FP_PUSH_REV: + push hl + exx + pop hl + pop bc ; Return Address + ld d, (hl) + dec hl + ld e, (hl) + dec hl + push de + ld d, (hl) + dec hl + ld e, (hl) + dec hl + push de + ld d, (hl) + push de + push bc ; Return Address + exx + ret + pop namespace +#line 38 "arch/zx48k/notf.bas" END diff --git a/tests/functional/arch/zx48k/notf.bas b/tests/functional/arch/zx48k/notf.bas index 7cd58d2dd..627154d5c 100644 --- a/tests/functional/arch/zx48k/notf.bas +++ b/tests/functional/arch/zx48k/notf.bas @@ -6,3 +6,5 @@ DIM b as Ubyte b = NOT 0 b = NOT 1 b = NOT a +b = NOT (a = a) + diff --git a/tests/functional/arch/zx48k/or16.asm b/tests/functional/arch/zx48k/or16.asm index 87d920547..60f13ecfd 100644 --- a/tests/functional/arch/zx48k/or16.asm +++ b/tests/functional/arch/zx48k/or16.asm @@ -60,6 +60,19 @@ _b: sbc a, a inc a ld (_b), a + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + push af + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + pop de + or d + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -75,4 +88,15 @@ _b: ei ret ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 66 "arch/zx48k/or16.bas" END diff --git a/tests/functional/arch/zx48k/or16.bas b/tests/functional/arch/zx48k/or16.bas index 9edf73937..a55c10cd0 100644 --- a/tests/functional/arch/zx48k/or16.bas +++ b/tests/functional/arch/zx48k/or16.bas @@ -8,3 +8,5 @@ b = a OR 1 b = 0 OR a b = 1 OR a b = a OR a +b = (a = a) OR (a = a) + diff --git a/tests/functional/arch/zx48k/or32.asm b/tests/functional/arch/zx48k/or32.asm index e80338794..87a90095c 100644 --- a/tests/functional/arch/zx48k/or32.asm +++ b/tests/functional/arch/zx48k/or32.asm @@ -79,6 +79,27 @@ _b: sbc a, a inc a ld (_b), a + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + push af + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + pop de + or d + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -113,5 +134,31 @@ __OR32: ; Performs logical operation A AND B #line 26 "/zxbasic/src/lib/arch/zx48k/runtime/bool/or32.asm" ret pop namespace -#line 72 "arch/zx48k/or32.bas" +#line 93 "arch/zx48k/or32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 94 "arch/zx48k/or32.bas" END diff --git a/tests/functional/arch/zx48k/or32.bas b/tests/functional/arch/zx48k/or32.bas index 29bbed044..defda4ed6 100644 --- a/tests/functional/arch/zx48k/or32.bas +++ b/tests/functional/arch/zx48k/or32.bas @@ -8,3 +8,5 @@ b = a OR 1 b = 0 OR a b = 1 OR a b = a OR a +b = (a = a) OR (a = a) + diff --git a/tests/functional/arch/zx48k/or8.asm b/tests/functional/arch/zx48k/or8.asm index e7c92e3da..005dec10c 100644 --- a/tests/functional/arch/zx48k/or8.asm +++ b/tests/functional/arch/zx48k/or8.asm @@ -53,6 +53,23 @@ _b: sbc a, a inc a ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + pop de + or d + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l diff --git a/tests/functional/arch/zx48k/or8.bas b/tests/functional/arch/zx48k/or8.bas index 174eb888f..10f6cdda9 100644 --- a/tests/functional/arch/zx48k/or8.bas +++ b/tests/functional/arch/zx48k/or8.bas @@ -8,3 +8,5 @@ b = a OR 1 b = 0 OR a b = 1 OR a b = a OR a +b = (a = a) OR (a = a) + diff --git a/tests/functional/arch/zx48k/orf.asm b/tests/functional/arch/zx48k/orf.asm index 62ffed9a0..7e2cd31f2 100644 --- a/tests/functional/arch/zx48k/orf.asm +++ b/tests/functional/arch/zx48k/orf.asm @@ -67,6 +67,25 @@ _b: call .core.__FP_PUSH_REV call .core.__ORF ld (_b), a + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + push af + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + pop de + or d + sub 1 + sbc a, a + inc a + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -311,7 +330,28 @@ __ORF: ; A | B call __FPSTACK_POP jp __FTOU8 ; Convert to 32 bits pop namespace -#line 60 "arch/zx48k/orf.bas" +#line 79 "arch/zx48k/orf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eqf.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses C EDHL registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order BC DE HL (B not used). + ; + ; Uses CALLEE convention + ; ------------------------------------------------------------- + push namespace core +__EQF: ; A = B + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace +#line 80 "arch/zx48k/orf.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last @@ -339,5 +379,5 @@ __FP_PUSH_REV: exx ret pop namespace -#line 61 "arch/zx48k/orf.bas" +#line 81 "arch/zx48k/orf.bas" END diff --git a/tests/functional/arch/zx48k/orf.bas b/tests/functional/arch/zx48k/orf.bas index 222c86f96..a40166965 100644 --- a/tests/functional/arch/zx48k/orf.bas +++ b/tests/functional/arch/zx48k/orf.bas @@ -8,3 +8,5 @@ b = a OR 1 b = 0 OR a b = 1 OR a b = a OR a +b = (a = a) OR (a = a) + diff --git a/tests/functional/arch/zx48k/xor16.asm b/tests/functional/arch/zx48k/xor16.asm index 32701f831..c10e1ba1c 100644 --- a/tests/functional/arch/zx48k/xor16.asm +++ b/tests/functional/arch/zx48k/xor16.asm @@ -57,6 +57,18 @@ _b: call .core.__XOR16 neg ld (_b), a + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + push af + ld de, (_a) + ld hl, (_a) + call .core.__EQ16 + ld h, a + pop af + call .core.__XOR8 + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -98,5 +110,16 @@ __XOR8: ret pop namespace #line 4 "/zxbasic/src/lib/arch/zx48k/runtime/bool/xor16.asm" -#line 50 "arch/zx48k/xor16.bas" +#line 62 "arch/zx48k/xor16.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq16.asm" + push namespace core +__EQ16: ; Test if 16bit values HL == DE + ; Returns result in A: 0 = False, FF = True + xor a ; Reset carry flag + sbc hl, de + ret nz + inc a + ret + pop namespace +#line 64 "arch/zx48k/xor16.bas" END diff --git a/tests/functional/arch/zx48k/xor16.bas b/tests/functional/arch/zx48k/xor16.bas index a3b37e27f..e4fe648bb 100644 --- a/tests/functional/arch/zx48k/xor16.bas +++ b/tests/functional/arch/zx48k/xor16.bas @@ -8,3 +8,5 @@ b = a XOR 1 b = 0 XOR a b = 1 XOR a b = a XOR a +b = (a = a) XOR (a = a) + diff --git a/tests/functional/arch/zx48k/xor32.asm b/tests/functional/arch/zx48k/xor32.asm index ae23a362d..1647e8f05 100644 --- a/tests/functional/arch/zx48k/xor32.asm +++ b/tests/functional/arch/zx48k/xor32.asm @@ -69,6 +69,26 @@ _b: call .core.__XOR32 neg ld (_b), a + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + push af + ld hl, (_a + 2) + push hl + ld hl, (_a) + push hl + ld hl, (_a) + ld de, (_a + 2) + call .core.__EQ32 + ld h, a + pop af + call .core.__XOR8 + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -130,5 +150,31 @@ __XOR32: ld h, c jp __XOR8 pop namespace -#line 62 "arch/zx48k/xor32.bas" +#line 82 "arch/zx48k/xor32.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eq32.asm" + push namespace core +__EQ32: ; Test if 32bit value HLDE equals top of the stack + ; Returns result in A: 0 = False, FF = True + exx + pop bc ; Return address + exx + xor a ; Reset carry flag + pop bc + sbc hl, bc ; Low part + ex de, hl + pop bc + sbc hl, bc ; High part + exx + push bc ; CALLEE + exx + ld a, h + or l + or d + or e ; a = 0 and Z flag set only if HLDE = 0 + ld a, 1 + ret z + xor a + ret + pop namespace +#line 84 "arch/zx48k/xor32.bas" END diff --git a/tests/functional/arch/zx48k/xor32.bas b/tests/functional/arch/zx48k/xor32.bas index 2d263946e..ee8b6d322 100644 --- a/tests/functional/arch/zx48k/xor32.bas +++ b/tests/functional/arch/zx48k/xor32.bas @@ -8,3 +8,5 @@ b = a XOR 1 b = 0 XOR a b = 1 XOR a b = a XOR a +b = (a = a) XOR (a = a) + diff --git a/tests/functional/arch/zx48k/xor8.asm b/tests/functional/arch/zx48k/xor8.asm index 1cf54ce1b..1a2dc1900 100644 --- a/tests/functional/arch/zx48k/xor8.asm +++ b/tests/functional/arch/zx48k/xor8.asm @@ -49,6 +49,22 @@ _b: call .core.__XOR8 neg ld (_b), a + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + push af + ld hl, (_a - 1) + ld a, (_a) + sub h + sub 1 + sbc a, a + ld h, a + pop af + call .core.__XOR8 + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -87,5 +103,5 @@ __XOR8: xor l ret pop namespace -#line 42 "arch/zx48k/xor8.bas" +#line 58 "arch/zx48k/xor8.bas" END diff --git a/tests/functional/arch/zx48k/xor8.bas b/tests/functional/arch/zx48k/xor8.bas index b7bae25c6..ed9fb24f5 100644 --- a/tests/functional/arch/zx48k/xor8.bas +++ b/tests/functional/arch/zx48k/xor8.bas @@ -8,3 +8,5 @@ b = a XOR 1 b = 0 XOR a b = 1 XOR a b = a XOR a +b = (a = a) XOR (a = a) + diff --git a/tests/functional/arch/zx48k/xorf.asm b/tests/functional/arch/zx48k/xorf.asm index b49887c24..575df3e5e 100644 --- a/tests/functional/arch/zx48k/xorf.asm +++ b/tests/functional/arch/zx48k/xorf.asm @@ -67,6 +67,24 @@ _b: call .core.__FP_PUSH_REV call .core.__XORF ld (_b), a + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + push af + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__EQF + ld h, a + pop af + call .core.__XOR8 + neg + ld (_b), a ld hl, 0 ld b, h ld c, l @@ -82,6 +100,30 @@ _b: ei ret ;; --- end of user code --- +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bool/xor8.asm" +; vim:ts=4:et: + ; FASTCALL boolean xor 8 version. + ; result in Accumulator (0 False, not 0 True) +; __FASTCALL__ version (operands: A, H) + ; Performs 8bit xor 8bit and returns the boolean + push namespace core +__XOR16: + ld a, h + or l + ld h, a + ld a, d + or e +__XOR8: + sub 1 + sbc a, a + ld l, a ; l = 00h or FFh + ld a, h + sub 1 + sbc a, a ; a = 00h or FFh + xor l + ret + pop namespace +#line 78 "arch/zx48k/xorf.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/bool/xorf.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/u32tofreg.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" @@ -321,7 +363,28 @@ __XORF: ; A XOR B call __FPSTACK_POP jp __FTOU8 ; Convert to 8 bits pop namespace -#line 60 "arch/zx48k/xorf.bas" +#line 79 "arch/zx48k/xorf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/cmp/eqf.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses C EDHL registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order BC DE HL (B not used). + ; + ; Uses CALLEE convention + ; ------------------------------------------------------------- + push namespace core +__EQF: ; A = B + call __FPSTACK_PUSH2 + ; ------------- ROM NOS-EQL + ld b, 0Eh ; For comparison operators, OP must be in B also + rst 28h + defb 0Eh + defb 38h; ; END CALC + call __FPSTACK_POP + jp __FTOU8 ; Convert to 8 bits + pop namespace +#line 80 "arch/zx48k/xorf.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pushf.asm" ; Routine to push Float pointed by HL ; Into the stack. Notice that the hl points to the last @@ -349,5 +412,5 @@ __FP_PUSH_REV: exx ret pop namespace -#line 61 "arch/zx48k/xorf.bas" +#line 81 "arch/zx48k/xorf.bas" END diff --git a/tests/functional/arch/zx48k/xorf.bas b/tests/functional/arch/zx48k/xorf.bas index 5b191f2a5..67755b71e 100644 --- a/tests/functional/arch/zx48k/xorf.bas +++ b/tests/functional/arch/zx48k/xorf.bas @@ -8,3 +8,5 @@ b = a XOR 1 b = 0 XOR a b = 1 XOR a b = a XOR a +b = (a = a) XOR (a = a) + diff --git a/tests/runtime/check_test.py b/tests/runtime/check_test.py index 0c4a92402..d3572ef19 100755 --- a/tests/runtime/check_test.py +++ b/tests/runtime/check_test.py @@ -26,8 +26,12 @@ def on_breakpoint(self): self.stop() def run_test(self, tape_filename, ram_filename): - # Auto-load the tape. - self._load_file(tape_filename) + # Autoload the tape. + try: + self._load_file(tape_filename) + except FileNotFoundError: + print(f"Tape file '{tape_filename}' not found") + sys.exit(1) # Catch the end of test. self.set_breakpoint(8) @@ -42,6 +46,7 @@ def run_test(self, tape_filename, ram_filename): screen = self.read(0x4000, 6 * 1024 + 768) # Compare it with the etalon screenshot. + with open(ram_filename, "rb") as f: if screen != f.read(): print("FAIL")