From 64c85b9617a167ff011ce18fe1d5aedbc2eeecde Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 5 Apr 2021 21:45:39 +0200 Subject: [PATCH] fix cx16 rom v39 float changes --- compiler/res/prog8lib/cx16/floats.p8 | 61 +++++++++++++------------ compiler/res/prog8lib/cx16/syslib.p8 | 4 +- compiler/src/prog8/compiler/Compiler.kt | 2 +- docs/source/index.rst | 2 + docs/source/programming.rst | 4 ++ docs/source/todo.rst | 4 ++ examples/cx16/highresbitmap.p8 | 2 +- examples/test.p8 | 47 ++++++++++--------- 8 files changed, 71 insertions(+), 55 deletions(-) diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index 2c84649d9..8fd286a4b 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -8,7 +8,9 @@ %option enable_floats floats { - ; ---- this block contains C-64 floating point related functions ---- + ; ---- this block contains C-64 compatible floating point related functions ---- + ; the addresses are from cx16 V39 emulator and roms! they won't work on older versions. + const float PI = 3.141592653589793 const float TWOPI = 6.283185307179586 @@ -40,39 +42,38 @@ romsub $fe12 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt valu romsub $fe15 = FADDT() clobbers(A,X,Y) ; fac1 += fac2 romsub $fe1b = ZEROFC() clobbers(A,X,Y) ; fac1 = 0 romsub $fe1e = NORMAL() clobbers(A,X,Y) ; normalize fac1 (?) +romsub $fe21 = NEGFAC() clobbers(A,X,Y) ; fac1 = -fac1 romsub $fe24 = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) romsub $fe27 = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y romsub $fe2a = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 -romsub $fe33 = CONUPK(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac2 -romsub $fe36 = MUL10() clobbers(A,X,Y) ; fac1 *= 10 -romsub $fe3c = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! -romsub $fe3f = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 (remainder in fac2) -romsub $fe42 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands +romsub $fe30 = CONUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac2 +romsub $fe33 = MUL10() clobbers(A,X,Y) ; fac1 *= 10 +romsub $fe36 = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! +romsub $fe39 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 (remainder in fac2) +romsub $fe3c = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 (remainder in fac2) mind the order of the operands -romsub $fe48 = MOVFM(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac1 -romsub $fe4b = MOVMF(uword mflpt @ XY) clobbers(A,Y) ; store fac1 to memory X/Y as 5-byte mflpt -romsub $fe4e = MOVFA() clobbers(A,X) ; copy fac2 to fac1 -romsub $fe51 = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded) -romsub $fe54 = MOVEF() clobbers(A,X) ; copy fac1 to fac2 -romsub $fe5a = SIGN() -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive -romsub $fe5d = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) -romsub $fe60 = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 -romsub $fe6c = ABS() ; fac1 = ABS(fac1) -romsub $fe6f = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than -romsub $fe78 = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc -romsub $fe7e = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A -romsub $fe81 = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY -romsub $fe8a = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) -romsub $fe8d = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 -; note: there is no FPWR() on the Cx16 -romsub $fe93 = NEGOP() clobbers(A) ; switch the sign of fac1 -romsub $fe96 = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) -romsub $fe9f = RND2(byte value @A) clobbers(A,X,Y) ; fac1 = RND(A) float random number generator -romsub $fea2 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator -romsub $fea5 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) -romsub $fea8 = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) -romsub $feab = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) -romsub $feae = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) +romsub $fe42 = MOVFM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 +romsub $fe45 = MOVMF(uword mflpt @ XY) clobbers(A,X,Y) ; store fac1 to memory X/Y as 5-byte mflpt +romsub $fe48 = MOVFA() clobbers(A,X) ; copy fac2 to fac1 +romsub $fe4b = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded) +romsub $fe4e = MOVEF() clobbers(A,X) ; copy fac1 to fac2 +romsub $fe54 = SIGN() clobbers(X,Y) -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive +romsub $fe57 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) +romsub $fe5a = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 +romsub $fe66 = ABS() clobbers(A,X,Y) ; fac1 = ABS(fac1) +romsub $fe69 = FCOMP(uword mflpt @ AY) clobbers(X,Y) -> ubyte @ A ; A = compare fac1 to mflpt in A/Y, 0=equal 1=fac1 is greater, 255=fac1 is less than +romsub $fe72 = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to round instead of trunc +romsub $fe78 = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A +romsub $fe7b = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY +romsub $fe81 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) +romsub $fe84 = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 +romsub $fe8a = NEGOP() clobbers(A,X,Y) ; fac1 = -fac1-1 +romsub $fe8d = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) +romsub $fe96 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator +romsub $fe99 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) +romsub $fe9c = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) +romsub $fe9f = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) +romsub $fea2 = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) asmsub GIVUAYFAY (uword value @ AY) clobbers(A,X,Y) { diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 9527e7dcb..0fecb24fa 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -503,9 +503,9 @@ asmsub init_system() { %asm {{ sei cld - stz $01 ; select rom bank 0 (enable kernal) lda #$80 sta VERA_CTRL + stz $01 ; select rom bank 0 (enable kernal) jsr c64.IOINIT jsr c64.RESTOR jsr c64.CINT @@ -517,6 +517,8 @@ asmsub init_system() { jsr c64.CHROUT lda #147 ; clear screen jsr c64.CHROUT + ldx #4 + stx $01 ; select rom bank 4 (enable basic again) lda #0 tax tay diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 09c660748..b94bc6ea3 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -214,7 +214,7 @@ private fun determineCompilationOptions(program: Program, compTarget: ICompilati } if (zpType==ZeropageType.FLOATSAFE && compTarget.name == Cx16Target.name) { - System.err.println("Warning: Cx16 target must use zp option basicsafe instead of floatsafe") + System.err.println("Warning: cx16 target must use zp option basicsafe instead of floatsafe") zpType = ZeropageType.BASICSAFE } diff --git a/docs/source/index.rst b/docs/source/index.rst index 83a73eeed..7e51a9bba 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -148,6 +148,8 @@ For MacOS you can use the Homebrew system to install a recent version of OpenJDK Finally: an **emulator** (or a real machine ofcourse) to test and run your programs on. In C64 mode, thhe compiler assumes the presence of the `Vice emulator `_. If you're targeting the CommanderX16 instead, there's the `x16emu `_. +Make sure you use cx16 emulator and roms **V39 or newer**! Starting from version 6.5, prog8 targets that system version. +Your program may work on V38 but that will only be by luck. .. important:: **Building the compiler itself:** (*Only needed if you have not downloaded a pre-built 'fat-jar'*) diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 1b37ce048..a6d6ff313 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -233,6 +233,10 @@ to worry about this yourself) The largest 5-byte MFLPT float that can be stored is: **1.7014118345e+38** (negative: **-1.7014118345e+38**) +.. note:: + On the Commander X16, to use floating point operations, ROM bank 4 has to be enabled (BASIC). + Importing the ``floats`` library will do this for you if needed. + Arrays ^^^^^^ diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 80b226d18..15ede19d3 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,10 @@ TODO ==== +- make the floats lib set rombank 4 on cx16 and set sysinit back to rombank 0 (kernal only) +- make sure rombank is back to 4 on cx16 when program exits back to basic +- check use of float NEGOP vs NEGFAC for cx16 + - allow inlining of subroutines with params - optimize several inner loops in gfx2 - hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine) diff --git a/examples/cx16/highresbitmap.p8 b/examples/cx16/highresbitmap.p8 index 83b0d969e..49d042e60 100644 --- a/examples/cx16/highresbitmap.p8 +++ b/examples/cx16/highresbitmap.p8 @@ -2,7 +2,7 @@ %import gfx2 %import floats %import textio -%zeropage basicsafe +%zeropage dontuse main { diff --git a/examples/test.p8 b/examples/test.p8 index 228e21405..2b79458ce 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,33 +1,36 @@ -%zeropage basicsafe +%import textio +%import floats +%zeropage dontuse main { sub start() { - - ubyte[6] array = [ 1,2,3, -; Comment here - 4,5,6 ] - - ubyte zz = len(array) - - ubyte foobar - empty2() + float f1 = 9.9999 + float f2 = 8.8888 + float f3 = 0.1111 %asm {{ - lda foobar + phx + ldy #f1 + jsr $FE42 + jsr $FE7B + plx }} - } + f3=cos(f3) - sub nix() { - } + floats.print_f(f1) + txt.nl() + floats.print_f(f2) + txt.nl() + floats.print_f(f3) + txt.nl() + f3 = cos(f3) + floats.print_f(f3) + + txt.print("ok!\n") + + sys.wait(2*60) - sub empty2() { - } -} - -derp { - sub nix2() { - ubyte zz - zz++ } }