diff --git a/src/arch/z80/backend/runtime/core.py b/src/arch/z80/backend/runtime/core.py index dc5f3977d..8a8e944c5 100644 --- a/src/arch/z80/backend/runtime/core.py +++ b/src/arch/z80/backend/runtime/core.py @@ -226,7 +226,7 @@ class CoreLabels: CoreLabels.PISTORE_STR: "storestr.asm", CoreLabels.PISTORE_STR2: "storestr2.asm", CoreLabels.PLOADF: "ploadf.asm", - CoreLabels.POWF: "pow.asm", + CoreLabels.POWF: "math/pow.asm", CoreLabels.PSTOREF: "pstoref.asm", CoreLabels.PSTORE32: "pstore32.asm", CoreLabels.PSTORE_STR: "pstorestr.asm", diff --git a/src/lib/arch/zx48k/runtime/pow.asm b/src/lib/arch/zx48k/runtime/math/pow.asm similarity index 99% rename from src/lib/arch/zx48k/runtime/pow.asm rename to src/lib/arch/zx48k/runtime/math/pow.asm index 549dafb11..f6119c66d 100644 --- a/src/lib/arch/zx48k/runtime/pow.asm +++ b/src/lib/arch/zx48k/runtime/math/pow.asm @@ -32,4 +32,3 @@ __POW: ; Exponentiation ENDP pop namespace - diff --git a/src/lib/arch/zxnext/runtime/pow.asm b/src/lib/arch/zxnext/runtime/math/pow.asm similarity index 99% rename from src/lib/arch/zxnext/runtime/pow.asm rename to src/lib/arch/zxnext/runtime/math/pow.asm index 549dafb11..f6119c66d 100644 --- a/src/lib/arch/zxnext/runtime/pow.asm +++ b/src/lib/arch/zxnext/runtime/math/pow.asm @@ -32,4 +32,3 @@ __POW: ; Exponentiation ENDP pop namespace - diff --git a/tests/functional/arch/zx48k/addf.asm b/tests/functional/arch/zx48k/addf.asm new file mode 100644 index 000000000..74852efb3 --- /dev/null +++ b/tests/functional/arch/zx48k/addf.asm @@ -0,0 +1,181 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + 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, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + ld hl, _a + 4 + call .core.__FP_PUSH_REV + call .core.__ADDF + push bc + push de + push af + ld hl, _a + 4 + call .core.__FP_PUSH_REV + ld a, 082h + ld de, 00000h + ld bc, 00000h + call .core.__ADDF + push bc + push de + push af + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + call .core.__ADDF + call .core.__ADDF + ld hl, _a + call .core.__STOREF + 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/addf.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/stackf.asm" + ; ------------------------------------------------------------- + ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC + ; ------------------------------------------------------------- + push namespace core + __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) + __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) +__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out + call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK + exx + pop hl ; Caller-Caller return addr + exx + pop hl ; Caller return addr + pop af + pop de + pop bc + push hl ; Caller return addr + exx + push hl ; Caller-Caller return addr + exx + jp __FPSTACK_PUSH +__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/addf.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses A EDCB registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order AF DE BC (F not used). + ; + ; Uses CALLEE convention + ; ------------------------------------------------------------- + push namespace core +__ADDF: ; Addition + call __FPSTACK_PUSH2 + ; ------------- ROM ADD + rst 28h + defb 0fh ; ADD + defb 38h; ; END CALC + jp __FPSTACK_POP + pop namespace +#line 42 "arch/zx48k/addf.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 43 "arch/zx48k/addf.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/storef.asm" + push namespace core +__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de +__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' +__STOREF: ; Stores the given FP number in A EDCB at address HL + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace +#line 44 "arch/zx48k/addf.bas" + END diff --git a/tests/functional/arch/zx48k/addf.bas b/tests/functional/arch/zx48k/addf.bas new file mode 100644 index 000000000..782365537 --- /dev/null +++ b/tests/functional/arch/zx48k/addf.bas @@ -0,0 +1,3 @@ +REM another Float test +DIM a As Float +a = a + a + (a + 2 + a) diff --git a/tests/functional/arch/zx48k/fp_pow.asm b/tests/functional/arch/zx48k/fp_pow.asm new file mode 100644 index 000000000..95a7d2e4c --- /dev/null +++ b/tests/functional/arch/zx48k/fp_pow.asm @@ -0,0 +1,171 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + 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 +_x: + DEFB 00, 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, _x + 4 + call .core.__FP_PUSH_REV + ld a, 082h + ld de, 00020h + ld bc, 00000h + call .core.__POW + ld hl, _x + call .core.__STOREF + 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/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/stackf.asm" + ; ------------------------------------------------------------- + ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC + ; ------------------------------------------------------------- + push namespace core + __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) + __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) +__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out + call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK + exx + pop hl ; Caller-Caller return addr + exx + pop hl ; Caller return addr + pop af + pop de + pop bc + push hl ; Caller return addr + exx + push hl ; Caller-Caller return addr + exx + jp __FPSTACK_PUSH +__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses A EDCB registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order A DE BC. + ; + ; Uses CALLEE convention + ; +; Operands comes swapped: + ; 1 st parameter is the BASE (A ED CB) + ; 2 nd parameter (Top of the stack) is Exponent + ; ------------------------------------------------------------- + push namespace core +__POW: ; Exponentiation + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace +#line 25 "arch/zx48k/fp_pow.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 26 "arch/zx48k/fp_pow.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/storef.asm" + push namespace core +__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de +__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' +__STOREF: ; Stores the given FP number in A EDCB at address HL + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace +#line 27 "arch/zx48k/fp_pow.bas" + END diff --git a/tests/functional/arch/zx48k/fp_pow.bas b/tests/functional/arch/zx48k/fp_pow.bas new file mode 100644 index 000000000..1bb07f8f9 --- /dev/null +++ b/tests/functional/arch/zx48k/fp_pow.bas @@ -0,0 +1,3 @@ +DIM x as Float + +LET x = x ^ 2.5 diff --git a/tests/functional/arch/zx48k/mulf16.asm b/tests/functional/arch/zx48k/mulf16.asm new file mode 100644 index 000000000..57d1e2341 --- /dev/null +++ b/tests/functional/arch/zx48k/mulf16.asm @@ -0,0 +1,195 @@ + org 32768 +.core.__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + 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 e, h + ld d, 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 e, h + ld d, 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.__MULF16 + 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/mulf16.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/neg32.asm" + push namespace core +__ABS32: + bit 7, d + ret z +__NEG32: ; Negates DEHL (Two's complement) + ld a, l + cpl + ld l, a + ld a, h + cpl + ld h, a + ld a, e + cpl + ld e, a + ld a, d + cpl + ld d, a + inc l + ret nz + inc h + ret nz + inc de + ret + pop namespace +#line 2 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf16.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 3 "/zxbasic/src/lib/arch/zx48k/runtime/arith/mulf16.asm" + push namespace core +__MULF16: ; + ld a, d ; load sgn into a + ex af, af' ; saves it + call __ABS32 ; convert to positive + exx + pop hl ; Return address + pop de ; Low part + ex (sp), hl ; CALLEE caller convention; Now HL = Hight part, (SP) = Return address + ex de, hl ; D'E' = High part (B), H'L' = Low part (B) (must be in DE) + ex af, af' + xor d ; A register contains resulting sgn + ex af, af' + call __ABS32 ; convert to positive + call __MUL32_64START + ; rounding (was not included in zx81) +__ROUND_FIX: ; rounds a 64bit (32.32) fixed point number to 16.16 + ; result returned in dehl + ; input in h'l'hlb'c'ac + sla a ; result bit 47 to carry + exx + ld hl,0 ; ld does not change carry + adc hl,bc ; hl = hl + 0 + carry + push hl + exx + ld bc,0 + adc hl,bc ; hl = hl + 0 + carry + ex de, hl + pop hl ; rounded result in de.hl + ex af, af' ; recovers result sign + or a + jp m, __NEG32 ; if negative, negates it + ret + pop namespace +#line 48 "mulf16.bas" + END diff --git a/tests/functional/arch/zx48k/mulf16.bas b/tests/functional/arch/zx48k/mulf16.bas new file mode 100644 index 000000000..06cc5323c --- /dev/null +++ b/tests/functional/arch/zx48k/mulf16.bas @@ -0,0 +1,10 @@ +' TEST for Fixed + +DIM a as Fixed +DIM b as Fixed + +b = a * 0 +b = a * 1 +b = 0 * a +b = 1 * a +b = a * a diff --git a/tests/functional/arch/zx48k/read10.asm b/tests/functional/arch/zx48k/read10.asm index d0bfa7676..90c28a250 100644 --- a/tests/functional/arch/zx48k/read10.asm +++ b/tests/functional/arch/zx48k/read10.asm @@ -1119,6 +1119,32 @@ __REFRESH_TMP: ENDP pop namespace #line 117 "arch/zx48k/read10.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses A EDCB registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order A DE BC. + ; + ; Uses CALLEE convention + ; +; Operands comes swapped: + ; 1 st parameter is the BASE (A ED CB) + ; 2 nd parameter (Top of the stack) is Exponent + ; ------------------------------------------------------------- + push namespace core +__POW: ; Exponentiation + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace +#line 118 "arch/zx48k/read10.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" push namespace core SIN: ; Computes SIN using ROM FP-CALC @@ -1128,7 +1154,7 @@ SIN: ; Computes SIN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 118 "arch/zx48k/read10.bas" +#line 119 "arch/zx48k/read10.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" push namespace core TAN: ; Computes TAN using ROM FP-CALC @@ -1138,7 +1164,7 @@ TAN: ; Computes TAN using ROM FP-CALC defb 38h ; END CALC jp __FPSTACK_POP pop namespace -#line 119 "arch/zx48k/read10.bas" +#line 120 "arch/zx48k/read10.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/ploadf.asm" ; Parameter / Local var load ; A => Offset @@ -1179,32 +1205,6 @@ __PLOADF: add hl, de jp __LOADF pop namespace -#line 120 "arch/zx48k/read10.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" - ; ------------------------------------------------------------- - ; Floating point library using the FP ROM Calculator (ZX 48K) - ; All of them uses A EDCB registers as 1st paramter. - ; For binary operators, the 2n operator must be pushed into the - ; stack, in the order A DE BC. - ; - ; Uses CALLEE convention - ; -; Operands comes swapped: - ; 1 st parameter is the BASE (A ED CB) - ; 2 nd parameter (Top of the stack) is Exponent - ; ------------------------------------------------------------- - push namespace core -__POW: ; Exponentiation - PROC - call __FPSTACK_PUSH2 - ; ------------- ROM POW - rst 28h - defb 01h ; Exchange => 1, Base - defb 06h ; POW - defb 38h; ; END CALC - jp __FPSTACK_POP - ENDP - pop namespace #line 121 "arch/zx48k/read10.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm" diff --git a/tests/functional/arch/zx48k/read13.asm b/tests/functional/arch/zx48k/read13.asm index e8e3aafcc..2427b8e67 100644 --- a/tests/functional/arch/zx48k/read13.asm +++ b/tests/functional/arch/zx48k/read13.asm @@ -1546,27 +1546,7 @@ __ILOAD32: ret pop namespace #line 116 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" - push namespace core -SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 117 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" - push namespace core -TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 118 "arch/zx48k/read13.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) ; All of them uses A EDCB registers as 1st paramter. @@ -1591,6 +1571,26 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace +#line 117 "arch/zx48k/read13.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" + push namespace core +SIN: ; Computes SIN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace +#line 118 "arch/zx48k/read13.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" + push namespace core +TAN: ; Computes TAN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 119 "arch/zx48k/read13.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf16.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printnum.asm" diff --git a/tests/functional/arch/zx48k/read4.asm b/tests/functional/arch/zx48k/read4.asm index 03d5bef4a..72d4d2b52 100644 --- a/tests/functional/arch/zx48k/read4.asm +++ b/tests/functional/arch/zx48k/read4.asm @@ -551,27 +551,7 @@ __LOADSTR: ; __FASTCALL__ entry ret pop namespace #line 90 "arch/zx48k/read4.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" - push namespace core -SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 91 "arch/zx48k/read4.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" - push namespace core -TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 92 "arch/zx48k/read4.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) ; All of them uses A EDCB registers as 1st paramter. @@ -596,6 +576,26 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace +#line 91 "arch/zx48k/read4.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" + push namespace core +SIN: ; Computes SIN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace +#line 92 "arch/zx48k/read4.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" + push namespace core +TAN: ; Computes TAN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 93 "arch/zx48k/read4.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pushf.asm" ; Routine to push Float pointed by HL diff --git a/tests/functional/arch/zx48k/read5.asm b/tests/functional/arch/zx48k/read5.asm index 71b8f1f80..35ce4c0b1 100644 --- a/tests/functional/arch/zx48k/read5.asm +++ b/tests/functional/arch/zx48k/read5.asm @@ -1119,27 +1119,7 @@ __REFRESH_TMP: ENDP pop namespace #line 111 "arch/zx48k/read5.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" - push namespace core -SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 112 "arch/zx48k/read5.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" - push namespace core -TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 113 "arch/zx48k/read5.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) ; All of them uses A EDCB registers as 1st paramter. @@ -1164,6 +1144,26 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace +#line 112 "arch/zx48k/read5.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" + push namespace core +SIN: ; Computes SIN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace +#line 113 "arch/zx48k/read5.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" + push namespace core +TAN: ; Computes TAN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 114 "arch/zx48k/read5.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm" diff --git a/tests/functional/arch/zx48k/read8.asm b/tests/functional/arch/zx48k/read8.asm index 44934b41d..64f563a16 100644 --- a/tests/functional/arch/zx48k/read8.asm +++ b/tests/functional/arch/zx48k/read8.asm @@ -1136,27 +1136,7 @@ __REFRESH_TMP: ENDP pop namespace #line 102 "arch/zx48k/read8.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" - push namespace core -SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 103 "arch/zx48k/read8.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" - push namespace core -TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 104 "arch/zx48k/read8.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) ; All of them uses A EDCB registers as 1st paramter. @@ -1181,6 +1161,26 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace +#line 103 "arch/zx48k/read8.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" + push namespace core +SIN: ; Computes SIN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace +#line 104 "arch/zx48k/read8.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" + push namespace core +TAN: ; Computes TAN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 105 "arch/zx48k/read8.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm" diff --git a/tests/functional/arch/zx48k/read9.asm b/tests/functional/arch/zx48k/read9.asm index 7afc5c3c9..254b8460d 100644 --- a/tests/functional/arch/zx48k/read9.asm +++ b/tests/functional/arch/zx48k/read9.asm @@ -1336,27 +1336,7 @@ __LOADF: ; Loads a 40 bits FP number from address pointed by HL ret pop namespace #line 119 "arch/zx48k/read9.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" - push namespace core -SIN: ; Computes SIN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 1Fh - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 120 "arch/zx48k/read9.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" - push namespace core -TAN: ; Computes TAN using ROM FP-CALC - call __FPSTACK_PUSH - rst 28h ; ROM CALC - defb 21h ; TAN - defb 38h ; END CALC - jp __FPSTACK_POP - pop namespace -#line 121 "arch/zx48k/read9.bas" -#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/pow.asm" ; ------------------------------------------------------------- ; Floating point library using the FP ROM Calculator (ZX 48K) ; All of them uses A EDCB registers as 1st paramter. @@ -1381,6 +1361,26 @@ __POW: ; Exponentiation jp __FPSTACK_POP ENDP pop namespace +#line 120 "arch/zx48k/read9.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/sin.asm" + push namespace core +SIN: ; Computes SIN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 1Fh + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace +#line 121 "arch/zx48k/read9.bas" +#line 1 "/zxbasic/src/lib/arch/zx48k/runtime/math/tan.asm" + push namespace core +TAN: ; Computes TAN using ROM FP-CALC + call __FPSTACK_PUSH + rst 28h ; ROM CALC + defb 21h ; TAN + defb 38h ; END CALC + jp __FPSTACK_POP + pop namespace #line 122 "arch/zx48k/read9.bas" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printf.asm" #line 1 "/zxbasic/src/lib/arch/zx48k/runtime/printstr.asm" diff --git a/tests/functional/arch/zxnext/fp_pow.asm b/tests/functional/arch/zxnext/fp_pow.asm new file mode 100644 index 000000000..9cbfd742b --- /dev/null +++ b/tests/functional/arch/zxnext/fp_pow.asm @@ -0,0 +1,164 @@ + org 32768 +.core.__START_PROGRAM: + di + push iy + ld iy, 0x5C3A ; ZX Spectrum ROM variables address + ld hl, 0 + add hl, sp + ld (.core.__CALL_BACK__), hl + 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 +_x: + DEFB 00, 00, 00, 00, 00 +.core.ZXBASIC_USER_DATA_END: +.core.__MAIN_PROGRAM__: + ld hl, _x + 4 + call .core.__FP_PUSH_REV + ld a, 082h + ld de, 00020h + ld bc, 00000h + call .core.__POW + ld hl, _x + call .core.__STOREF + 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/pow.asm" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/stackf.asm" + ; ------------------------------------------------------------- + ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC + ; ------------------------------------------------------------- + push namespace core + __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) + __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) +__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out + call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK + exx + pop hl ; Caller-Caller return addr + exx + pop hl ; Caller return addr + pop af + pop de + pop bc + push hl ; Caller return addr + exx + push hl ; Caller-Caller return addr + exx + jp __FPSTACK_PUSH +__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH + pop namespace +#line 2 "/zxbasic/src/lib/arch/zxnext/runtime/pow.asm" + ; ------------------------------------------------------------- + ; Floating point library using the FP ROM Calculator (ZX 48K) + ; All of them uses A EDCB registers as 1st paramter. + ; For binary operators, the 2n operator must be pushed into the + ; stack, in the order A DE BC. + ; + ; Uses CALLEE convention + ; +; Operands comes swapped: + ; 1 st parameter is the BASE (A ED CB) + ; 2 nd parameter (Top of the stack) is Exponent + ; ------------------------------------------------------------- + push namespace core +__POW: ; Exponentiation + PROC + call __FPSTACK_PUSH2 + ; ------------- ROM POW + rst 28h + defb 01h ; Exchange => 1, Base + defb 06h ; POW + defb 38h; ; END CALC + jp __FPSTACK_POP + ENDP + pop namespace +#line 21 "arch/zxnext/fp_pow.bas" +#line 1 "/zxbasic/src/lib/arch/zxnext/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 22 "arch/zxnext/fp_pow.bas" +#line 1 "/zxbasic/src/lib/arch/zxnext/runtime/storef.asm" + push namespace core +__PISTOREF: ; Indect Stores a float (A, E, D, C, B) at location stored in memory, pointed by (IX + HL) + push de + ex de, hl ; DE <- HL + push ix + pop hl ; HL <- IX + add hl, de ; HL <- IX + HL + pop de +__ISTOREF: ; Load address at hl, and stores A,E,D,C,B registers at that address. Modifies A' register + ex af, af' + ld a, (hl) + inc hl + ld h, (hl) + ld l, a ; HL = (HL) + ex af, af' +__STOREF: ; Stores the given FP number in A EDCB at address HL + ld (hl), a + inc hl + ld (hl), e + inc hl + ld (hl), d + inc hl + ld (hl), c + inc hl + ld (hl), b + ret + pop namespace +#line 23 "arch/zxnext/fp_pow.bas" + END diff --git a/tests/functional/arch/zxnext/fp_pow.bas b/tests/functional/arch/zxnext/fp_pow.bas new file mode 100644 index 000000000..1bb07f8f9 --- /dev/null +++ b/tests/functional/arch/zxnext/fp_pow.bas @@ -0,0 +1,3 @@ +DIM x as Float + +LET x = x ^ 2.5