diff --git a/codeCore/src/prog8/code/ast/AstPrinter.kt b/codeCore/src/prog8/code/ast/AstPrinter.kt index 75b97a559..1fbaaf82c 100644 --- a/codeCore/src/prog8/code/ast/AstPrinter.kt +++ b/codeCore/src/prog8/code/ast/AstPrinter.kt @@ -95,7 +95,7 @@ fun printAst(root: PtNode, skipLibraries: Boolean, output: (text: String) -> Uni val bank = if(node.address.constbank!=null) "@bank ${node.address.constbank}" else if(node.address.varbank!=null) "@bank ${node.address.varbank?.name}" else "" - str + "romsub $bank ${node.address.address.toHex()} = ${node.name}($params) $clobbers $returns" + str + "extsub $bank ${node.address.address.toHex()} = ${node.name}($params) $clobbers $returns" } } is PtBlock -> { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt index 96b69bc33..b9459c109 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/IfElseAsmGen.kt @@ -141,7 +141,7 @@ internal class IfElseAsmGen(private val program: PtProgram, if(fcall!=null && fcall.type==DataType.BOOL) { val extsub = st.lookup(fcall.name) as? StExtSub if(extsub!=null && extsub.returns.any { it.register.statusflag!=null }) { - throw AssemblyError("if romsub() that returns a status register boolean should have been changed into a Conditional branch such as if_cc") + throw AssemblyError("if extsub() returning a status register boolean should have been changed into a Conditional branch such as if_cc") } } } diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index 5a09d92a2..6bff7ed4b 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -774,7 +774,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { fcallArgs = FunctionCallArgs(argRegisters, returnRegisters) ) } - else TODO("romsub with banked address got called ${callTarget.name}") + else TODO("extsub with banked address got called ${callTarget.name}") } addInstr(result, call, null) val resultRegs = returnRegisters.filter{it.dt!=IRDataType.FLOAT}.map{it.registerNum} diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 4ebced472..1cc153b0f 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -1701,9 +1701,9 @@ class IRCodeGen( } is PtAsmSub -> { if(child.address!=null) { - // romsub. No codegen needed: calls to this are jumping straight to the address. + // extmsub. No codegen needed: calls to this are jumping straight to the address. require(child.children.isEmpty()) { - "romsub should be empty at ${child.position}" + "extsub should be empty at ${child.position}" } } else { // regular asmsub diff --git a/codeGenIntermediate/test/TestVmCodeGen.kt b/codeGenIntermediate/test/TestVmCodeGen.kt index f869ad4d8..b35fbf5bd 100644 --- a/codeGenIntermediate/test/TestVmCodeGen.kt +++ b/codeGenIntermediate/test/TestVmCodeGen.kt @@ -523,9 +523,9 @@ class TestVmCodeGen: FunSpec({ irChunks.size shouldBe 1 } - test("romsub allowed in ir-codegen") { + test("extsub allowed in ir-codegen") { //main { -// romsub $5000 = routine() +// extsub $5000 = routine() // // sub start() { // routine() diff --git a/compiler/res/prog8lib/atari/syslib.p8 b/compiler/res/prog8lib/atari/syslib.p8 index 6bcb6d805..b0779f0f4 100644 --- a/compiler/res/prog8lib/atari/syslib.p8 +++ b/compiler/res/prog8lib/atari/syslib.p8 @@ -12,9 +12,9 @@ atari { &uword COLCRS = 85 &ubyte ROWCRS = 84 - romsub $F24A = getchar() -> ubyte @A - romsub $F2B0 = outchar(ubyte character @ A) - romsub $F2FD = waitkey() -> ubyte @A + extsub $F24A = getchar() -> ubyte @A + extsub $F2B0 = outchar(ubyte character @ A) + extsub $F2FD = waitkey() -> ubyte @A } diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index b36c75390..710d37b3c 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -56,49 +56,49 @@ cbm { ; CLEARSCR -> use txt.clear_screen ; HOMECRSR -> use txt.home or txt.plot -romsub $FA65 = IRQDFRT() clobbers(A,X,Y) ; default IRQ routine -romsub $FF33 = IRQDFEND() clobbers(A,X,Y) ; default IRQ end/cleanup +extsub $FA65 = IRQDFRT() clobbers(A,X,Y) ; default IRQ routine +extsub $FF33 = IRQDFEND() clobbers(A,X,Y) ; default IRQ end/cleanup -romsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip -romsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, SID, IRQ) -romsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, tape buffer, screen -romsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors -romsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table -romsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag -romsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN -romsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK -romsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set top of memory pointer -romsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer -romsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard -romsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus -romsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus -romsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus -romsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK -romsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN -romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN -romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK -romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) -romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters -romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters -romsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file -romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file -romsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel -romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel -romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices -romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. -romsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character -romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device -romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device -romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock -romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 -romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files -romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! -romsub $FFED = SCRORG() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! -romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. -romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices +extsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip +extsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, SID, IRQ) +extsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, tape buffer, screen +extsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors +extsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table +extsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag +extsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN +extsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK +extsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set top of memory pointer +extsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer +extsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard +extsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus +extsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus +extsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus +extsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK +extsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN +extsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN +extsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK +extsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) +extsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters +extsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters +extsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file +extsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file +extsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel +extsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel +extsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices +extsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. +extsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character +extsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device +extsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device +extsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock +extsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) +extsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 +extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 +extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files +extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock +extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! +extsub $FFED = SCRORG() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. +extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices ; ---- end of C64 compatible ROM kernal routines ---- @@ -319,7 +319,7 @@ c128 { ; TODO c128 a bunch of kernal routines are missing here that are specific to the c128 -romsub $FF6E = JSRFAR() +extsub $FF6E = JSRFAR() ; ---- C128 specific system utility routines: ---- diff --git a/compiler/res/prog8lib/c128/textio.p8 b/compiler/res/prog8lib/c128/textio.p8 index bc089f81c..7e836d8e1 100644 --- a/compiler/res/prog8lib/c128/textio.p8 +++ b/compiler/res/prog8lib/c128/textio.p8 @@ -13,7 +13,7 @@ txt { const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 -romsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. +extsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. sub clear_screen() { diff --git a/compiler/res/prog8lib/c64/floats.p8 b/compiler/res/prog8lib/c64/floats.p8 index c1a548007..80f1dbcc7 100644 --- a/compiler/res/prog8lib/c64/floats.p8 +++ b/compiler/res/prog8lib/c64/floats.p8 @@ -15,21 +15,21 @@ floats { ; note: fac1/2 might get clobbered even if not mentioned in the function's name. ; note: for subtraction and division, the left operand is in fac2, the right operand in fac1. -romsub $bba2 = MOVFM(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac1 -romsub $bba6 = FREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac1 -romsub $ba8c = CONUPK(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac2 -romsub $ba90 = FAREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac2 -romsub $bbfc = MOVFA() clobbers(A,X) ; copy fac2 to fac1 -romsub $bc0c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded the least significant bit) -romsub $bc0f = MOVEF() clobbers(A,X) ; copy fac1 to fac2 -romsub $bbd4 = MOVMF(uword mflpt @ XY) clobbers(A,Y) ; store fac1 to memory X/Y as 5-byte mflpt +extsub $bba2 = MOVFM(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac1 +extsub $bba6 = FREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac1 +extsub $ba8c = CONUPK(uword mflpt @ AY) clobbers(A,Y) ; load mflpt value from memory in A/Y into fac2 +extsub $ba90 = FAREADMEM() clobbers(A,Y) ; load mflpt value from memory in $22/$23 into fac2 +extsub $bbfc = MOVFA() clobbers(A,X) ; copy fac2 to fac1 +extsub $bc0c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded the least significant bit) +extsub $bc0f = MOVEF() clobbers(A,X) ; copy fac1 to fac2 +extsub $bbd4 = MOVMF(uword mflpt @ XY) clobbers(A,Y) ; store fac1 to memory X/Y as 5-byte mflpt ; fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15) ; (tip: use floats.GETADRAY to get A/Y output; lo/hi switched to normal little endian order) -romsub $b7f7 = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A +extsub $b7f7 = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A -romsub $bc9b = QINT() clobbers(A,X,Y) ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST. -romsub $b1bf = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY) +extsub $bc9b = QINT() clobbers(A,X,Y) ; fac1 -> 4-byte signed integer in 98-101 ($62-$65), with the MSB FIRST. +extsub $b1bf = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 100-101 ($64-$65) MSB FIRST. (might throw ILLEGAL QUANTITY) ; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1 ; (tip: use floats.GIVAYFAY to use A/Y input; lo/hi switched to normal order) @@ -37,47 +37,47 @@ romsub $b1bf = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 100-101 ; there is also floats.FREADS32 that reads from 98-101 ($62-$65) MSB FIRST ; there is also floats.FREADUS32 that reads from 98-101 ($62-$65) MSB FIRST ; there is also floats.FREAD{S,U}24AXY that read (un)signed int24 into fac1 from A/X/Y (lo/mid/hi bytes) -romsub $b391 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) +extsub $b391 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) -romsub $b3a2 = FREADUY(ubyte value @ Y) clobbers(A,X,Y) ; 8 bit unsigned Y -> float in fac1 -romsub $bc3c = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 -romsub $b7b5 = FREADSTR(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $22/23 must point to string, A=string length. Also see parse() -romsub $aabc = FPRINTLN() clobbers(A,X,Y) ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well) -romsub $bddd = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY ($0100) +extsub $b3a2 = FREADUY(ubyte value @ Y) clobbers(A,X,Y) ; 8 bit unsigned Y -> float in fac1 +extsub $bc3c = FREADSA(byte value @ A) clobbers(A,X,Y) ; 8 bit signed A -> float in fac1 +extsub $b7b5 = FREADSTR(ubyte length @ A) clobbers(A,X,Y) ; str -> fac1, $22/23 must point to string, A=string length. Also see parse() +extsub $aabc = FPRINTLN() clobbers(A,X,Y) ; print string of fac1, on one line (= with newline) destroys fac1. (consider FOUT + STROUT as well) +extsub $bddd = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY ($0100) -romsub $b849 = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for integer rounding- call this before INT -romsub $bae2 = MUL10() clobbers(A,X,Y) ; fac1 *= 10 -romsub $bafe = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! You have to fix sign manually! -romsub $bc5b = 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 +extsub $b849 = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for integer rounding- call this before INT +extsub $bae2 = MUL10() clobbers(A,X,Y) ; fac1 *= 10 +extsub $bafe = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! You have to fix sign manually! +extsub $bc5b = 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 $b86a = FADDT() clobbers(A,X,Y) ; fac1 += fac2 -romsub $b867 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y -romsub $b853 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands -romsub $b850 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 -romsub $ba2b = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 -romsub $ba28 = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y -romsub $bb12 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands -romsub $bb0f = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 -romsub $bf7b = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 -romsub $bf78 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** mflpt from A/Y -romsub $bd7e = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A +extsub $b86a = FADDT() clobbers(A,X,Y) ; fac1 += fac2 +extsub $b867 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y +extsub $b853 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands +extsub $b850 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 +extsub $ba2b = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 +extsub $ba28 = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y +extsub $bb12 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands +extsub $bb0f = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 +extsub $bf7b = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 +extsub $bf78 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** mflpt from A/Y +extsub $bd7e = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A -romsub $aed4 = NOTOP() clobbers(A,X,Y) ; fac1 = NOT(fac1) -romsub $bccc = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to integer round instead of trunc -romsub $b9ea = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) -romsub $bc39 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) -romsub $bc2b = SIGN() -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive -romsub $bc58 = ABS() ; fac1 = ABS(fac1) -romsub $bf71 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) -romsub $bf74 = SQRA() clobbers(A,X,Y) ; fac1 = SQRT(fac2) -romsub $bfed = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) -romsub $bfb4 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) -romsub $b8d7 = NORMAL() clobbers(A) ; normalize FAC1 -romsub $e097 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator -romsub $e264 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) -romsub $e26b = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) -romsub $e2b4 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) -romsub $e30e = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) +extsub $aed4 = NOTOP() clobbers(A,X,Y) ; fac1 = NOT(fac1) +extsub $bccc = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to integer round instead of trunc +extsub $b9ea = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) +extsub $bc39 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) +extsub $bc2b = SIGN() -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive +extsub $bc58 = ABS() ; fac1 = ABS(fac1) +extsub $bf71 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) +extsub $bf74 = SQRA() clobbers(A,X,Y) ; fac1 = SQRT(fac2) +extsub $bfed = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) +extsub $bfb4 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) +extsub $b8d7 = NORMAL() clobbers(A) ; normalize FAC1 +extsub $e097 = RND() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator +extsub $e264 = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) +extsub $e26b = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) +extsub $e2b4 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) +extsub $e30e = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) asmsub FREADS32() clobbers(A,X,Y) { diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 300ab469b..c3c3142ac 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -57,50 +57,50 @@ cbm { ; ---- CBM ROM kernal routines (C64 addresses) ---- -romsub $AB1E = STROUT(uword strptr @ AY) clobbers(A, X, Y) ; print null-terminated string (use txt.print instead) -romsub $E544 = CLEARSCR() clobbers(A,X,Y) ; clear the screen -romsub $E566 = HOMECRSR() clobbers(A,X,Y) ; cursor to top left of screen -romsub $EA31 = IRQDFRT() clobbers(A,X,Y) ; default IRQ routine -romsub $EA81 = IRQDFEND() clobbers(A,X,Y) ; default IRQ end/cleanup -romsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip -romsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, SID, IRQ) -romsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, tape buffer, screen -romsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors -romsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table -romsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag -romsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN -romsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK -romsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set top of memory pointer -romsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer -romsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard -romsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus -romsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus -romsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus -romsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK -romsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN -romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN -romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK -romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) -romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters -romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters -romsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file -romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file -romsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel -romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel -romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices -romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. -romsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character -romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device -romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device -romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock -romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 -romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files -romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) -romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. -romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices +extsub $AB1E = STROUT(uword strptr @ AY) clobbers(A, X, Y) ; print null-terminated string (use txt.print instead) +extsub $E544 = CLEARSCR() clobbers(A,X,Y) ; clear the screen +extsub $E566 = HOMECRSR() clobbers(A,X,Y) ; cursor to top left of screen +extsub $EA31 = IRQDFRT() clobbers(A,X,Y) ; default IRQ routine +extsub $EA81 = IRQDFEND() clobbers(A,X,Y) ; default IRQ end/cleanup +extsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip +extsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, SID, IRQ) +extsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, tape buffer, screen +extsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors +extsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table +extsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag +extsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN +extsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK +extsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set top of memory pointer +extsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer +extsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard +extsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus +extsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus +extsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus +extsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK +extsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN +extsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN +extsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK +extsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) +extsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters +extsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters +extsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file +extsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file +extsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel +extsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel +extsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices +extsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. +extsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character +extsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device +extsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device +extsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock +extsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) +extsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 +extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 +extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files +extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock +extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. +extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices inline asmsub STOP2() clobbers(X,A) -> bool @Pz { diff --git a/compiler/res/prog8lib/c64/textio.p8 b/compiler/res/prog8lib/c64/textio.p8 index 5e186aae1..d531c761c 100644 --- a/compiler/res/prog8lib/c64/textio.p8 +++ b/compiler/res/prog8lib/c64/textio.p8 @@ -13,7 +13,7 @@ txt { const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 -romsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. +extsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. sub clear_screen() { chrout(147) diff --git a/compiler/res/prog8lib/cx16/floats.p8 b/compiler/res/prog8lib/cx16/floats.p8 index f5e32e4c8..df07b2331 100644 --- a/compiler/res/prog8lib/cx16/floats.p8 +++ b/compiler/res/prog8lib/cx16/floats.p8 @@ -14,67 +14,67 @@ floats { ; note: fac1/2 might get clobbered even if not mentioned in the function's name. ; note: for subtraction and division, the left operand is in fac2, the right operand in fac1. -romsub $fe00 = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 'facmo' and 'faclo', MSB FIRST. (might throw ILLEGAL QUANTITY) See "basic.sym" kernal symbol file for their memory locations. +extsub $fe00 = AYINT() clobbers(A,X,Y) ; fac1-> signed word in 'facmo' and 'faclo', MSB FIRST. (might throw ILLEGAL QUANTITY) See "basic.sym" kernal symbol file for their memory locations. ; GIVAYF: signed word in Y/A (note different lsb/msb order) -> float in fac1 ; there is also floats.GIVUAYFAY - unsigned word in A/Y (lo/hi) to fac1 ; (tip: use GIVAYFAY to use A/Y input; lo/hi switched to normal order) -romsub $fe03 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) +extsub $fe03 = GIVAYF(ubyte lo @ Y, ubyte hi @ A) clobbers(A,X,Y) -romsub $fe06 = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY -romsub $fe09 = VAL_1(uword string @XY, ubyte length @A) clobbers(A,X,Y) -> float @FAC1 ; convert ASCII string in XY and length in A, to floating point in FAC1. WARNING: only implemented in ROM 47+. Safer to use floats.parse() instead. +extsub $fe06 = FOUT() clobbers(X) -> uword @ AY ; fac1 -> string, address returned in AY +extsub $fe09 = VAL_1(uword string @XY, ubyte length @A) clobbers(A,X,Y) -> float @FAC1 ; convert ASCII string in XY and length in A, to floating point in FAC1. WARNING: only implemented in ROM 47+. Safer to use floats.parse() instead. ; GETADR: fac1 -> unsigned word in Y/A (might throw ILLEGAL QUANTITY) (result also in $14/15) ; (tip: use GETADRAY to get A/Y output; lo/hi switched to normal little endian order) -romsub $fe0c = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A -romsub $fe0f = FLOATC() clobbers(A,X,Y) ; convert address to floating point +extsub $fe0c = GETADR() clobbers(X) -> ubyte @ Y, ubyte @ A +extsub $fe0f = FLOATC() clobbers(A,X,Y) ; convert address to floating point -romsub $fe12 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 -romsub $fe15 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands -romsub $fe18 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y -romsub $fe1b = FADDT() clobbers(A,X,Y) ; fac1 += fac2 -romsub $fe1e = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y -romsub $fe21 = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 -romsub $fe24 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 -romsub $fe27 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands -romsub $fe2a = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) -romsub $fe2d = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to integer round instead of trunc -romsub $fe30 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) -romsub $fe33 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) -romsub $fe36 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** float in A/Y -romsub $fe39 = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 -romsub $fe3c = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) -romsub $fe3f = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) -romsub $fe42 = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) -romsub $fe45 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) -romsub $fe48 = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) -romsub $fe4b = ROUND() clobbers(A,X,Y) ; round least significant bit of fac1 -romsub $fe4e = ABS() clobbers(A,X,Y) ; fac1 = ABS(fac1) -romsub $fe51 = SIGN() clobbers(X,Y) -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive -romsub $fe54 = 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 $fe57 = RND_0() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator NOTE: incompatible with C64's RND routine -romsub $fe57 = RND() clobbers(A,X,Y) ; alias for RND_0 -romsub $fe5a = CONUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac2 -romsub $fe5d = ROMUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in current bank in A/Y into fac2 -romsub $fe60 = MOVFRM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 (use MOVFM instead) -romsub $fe63 = MOVFM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 -romsub $fe66 = MOVMF(uword mflpt @ XY) clobbers(A,X,Y) ; store fac1 to memory X/Y as 5-byte mflpt -romsub $fe69 = MOVFA() clobbers(A,X) ; copy fac2 to fac1 -romsub $fe6c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded the least significant bit) +extsub $fe12 = FSUB(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt from A/Y - fac1 +extsub $fe15 = FSUBT() clobbers(A,X,Y) ; fac1 = fac2-fac1 mind the order of the operands +extsub $fe18 = FADD(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 += mflpt value from A/Y +extsub $fe1b = FADDT() clobbers(A,X,Y) ; fac1 += fac2 +extsub $fe1e = FMULT(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 *= mflpt value from A/Y +extsub $fe21 = FMULTT() clobbers(A,X,Y) ; fac1 *= fac2 +extsub $fe24 = FDIV(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = mflpt in A/Y / fac1 +extsub $fe27 = FDIVT() clobbers(A,X,Y) ; fac1 = fac2/fac1 mind the order of the operands +extsub $fe2a = LOG() clobbers(A,X,Y) ; fac1 = LN(fac1) (natural log) +extsub $fe2d = INT() clobbers(A,X,Y) ; INT() truncates, use FADDH first to integer round instead of trunc +extsub $fe30 = SQR() clobbers(A,X,Y) ; fac1 = SQRT(fac1) +extsub $fe33 = NEGOP() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) +extsub $fe36 = FPWR(uword mflpt @ AY) clobbers(A,X,Y) ; fac1 = fac2 ** float in A/Y +extsub $fe39 = FPWRT() clobbers(A,X,Y) ; fac1 = fac2 ** fac1 +extsub $fe3c = EXP() clobbers(A,X,Y) ; fac1 = EXP(fac1) (e ** fac1) +extsub $fe3f = COS() clobbers(A,X,Y) ; fac1 = COS(fac1) +extsub $fe42 = SIN() clobbers(A,X,Y) ; fac1 = SIN(fac1) +extsub $fe45 = TAN() clobbers(A,X,Y) ; fac1 = TAN(fac1) +extsub $fe48 = ATN() clobbers(A,X,Y) ; fac1 = ATN(fac1) +extsub $fe4b = ROUND() clobbers(A,X,Y) ; round least significant bit of fac1 +extsub $fe4e = ABS() clobbers(A,X,Y) ; fac1 = ABS(fac1) +extsub $fe51 = SIGN() clobbers(X,Y) -> ubyte @ A ; SIGN(fac1) to A, $ff, $0, $1 for negative, zero, positive +extsub $fe54 = 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 +extsub $fe57 = RND_0() clobbers(A,X,Y) ; fac1 = RND(fac1) float random number generator NOTE: incompatible with C64's RND routine +extsub $fe57 = RND() clobbers(A,X,Y) ; alias for RND_0 +extsub $fe5a = CONUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac2 +extsub $fe5d = ROMUPK(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in current bank in A/Y into fac2 +extsub $fe60 = MOVFRM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 (use MOVFM instead) +extsub $fe63 = MOVFM(uword mflpt @ AY) clobbers(A,X,Y) ; load mflpt value from memory in A/Y into fac1 +extsub $fe66 = MOVMF(uword mflpt @ XY) clobbers(A,X,Y) ; store fac1 to memory X/Y as 5-byte mflpt +extsub $fe69 = MOVFA() clobbers(A,X) ; copy fac2 to fac1 +extsub $fe6c = MOVAF() clobbers(A,X) ; copy fac1 to fac2 (rounded the least significant bit) ; X16 additions -romsub $fe6f = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for integer rounding- call this before INT -romsub $fe72 = ZEROFC() clobbers(A,X,Y) ; fac1 = 0 -romsub $fe75 = NORMAL() clobbers(A,X,Y) ; normalize fac1 -romsub $fe78 = NEGFAC() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) (doesn't work, juse use NEGOP() instead!) -romsub $fe7b = MUL10() clobbers(A,X,Y) ; fac1 *= 10 -romsub $fe7e = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! Have to restore sign manually! -romsub $fe81 = MOVEF() clobbers(A,X) ; copy fac1 to fac2 -romsub $fe84 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) -romsub $fe87 = FLOAT() clobbers(A,X,Y) ; FAC = (s8).A -romsub $fe8a = FLOATS() clobbers(A,X,Y) ; FAC = (s16)facho+1:facho -romsub $fe8d = QINT() clobbers(A,X,Y) ; facho:facho+1:facho+2:facho+3 = u32(FAC) -romsub $fe90 = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A +extsub $fe6f = FADDH() clobbers(A,X,Y) ; fac1 += 0.5, for integer rounding- call this before INT +extsub $fe72 = ZEROFC() clobbers(A,X,Y) ; fac1 = 0 +extsub $fe75 = NORMAL() clobbers(A,X,Y) ; normalize fac1 +extsub $fe78 = NEGFAC() clobbers(A) ; switch the sign of fac1 (fac1 = -fac1) (doesn't work, juse use NEGOP() instead!) +extsub $fe7b = MUL10() clobbers(A,X,Y) ; fac1 *= 10 +extsub $fe7e = DIV10() clobbers(A,X,Y) ; fac1 /= 10 , CAUTION: result is always positive! Have to restore sign manually! +extsub $fe81 = MOVEF() clobbers(A,X) ; copy fac1 to fac2 +extsub $fe84 = SGN() clobbers(A,X,Y) ; fac1 = SGN(fac1), result of SIGN (-1, 0 or 1) +extsub $fe87 = FLOAT() clobbers(A,X,Y) ; FAC = (s8).A +extsub $fe8a = FLOATS() clobbers(A,X,Y) ; FAC = (s16)facho+1:facho +extsub $fe8d = QINT() clobbers(A,X,Y) ; facho:facho+1:facho+2:facho+3 = u32(FAC) +extsub $fe90 = FINLOG(byte value @A) clobbers (A, X, Y) ; fac1 += signed byte in A diff --git a/compiler/res/prog8lib/cx16/graphics.p8 b/compiler/res/prog8lib/cx16/graphics.p8 index 8fb802781..f25cce812 100644 --- a/compiler/res/prog8lib/cx16/graphics.p8 +++ b/compiler/res/prog8lib/cx16/graphics.p8 @@ -15,7 +15,7 @@ graphics { %option ignore_unused - romsub $feff = FB_cursor_position2() clobbers(A,X,Y) ; alias for the normal FB_cursor_position() call but reuses existing r0 and r1 + extsub $feff = FB_cursor_position2() clobbers(A,X,Y) ; alias for the normal FB_cursor_position() call but reuses existing r0 and r1 const uword WIDTH = 320 const ubyte HEIGHT = 240 diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index caea5b638..10eb5900f 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -44,45 +44,45 @@ cbm { ; CLEARSCR -> use txt.clear_screen ; HOMECRSR -> use txt.home or txt.plot -romsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip, including resetting to the default color palette. Note: also sets the video mode back to VGA -romsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, IRQ, ...) -romsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, screen -romsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors -romsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table -romsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag -romsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN -romsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK -romsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY, ubyte @A ; read/set top of memory pointer. NOTE: on the Cx16 also returns the number of RAM memory banks in A! Also see cx16.numbanks() -romsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer -romsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard, also called kbd_scan -romsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus -romsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus -romsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus -romsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK -romsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN -romsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN -romsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK -romsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) -romsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters -romsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters -romsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file -romsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file -romsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel -romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel -romsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices -romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. -romsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character -romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device -romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) clobbers (X, Y) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device. See also BSAVE -romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock -romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (in little endian order: A=lo,X=mid,Y=high) , however use RDTIM_safe() instead -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 -romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files -romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) -romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Also see txt.plot -romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices +extsub $FF81 = CINT() clobbers(A,X,Y) ; (alias: SCINIT) initialize screen editor and video chip, including resetting to the default color palette. Note: also sets the video mode back to VGA +extsub $FF84 = IOINIT() clobbers(A, X) ; initialize I/O devices (CIA, IRQ, ...) +extsub $FF87 = RAMTAS() clobbers(A,X,Y) ; initialize RAM, screen +extsub $FF8A = RESTOR() clobbers(A,X,Y) ; restore default I/O vectors +extsub $FF8D = VECTOR(uword userptr @ XY, bool dir @ Pc) clobbers(A,Y) ; read/set I/O vector table +extsub $FF90 = SETMSG(ubyte value @ A) ; set Kernal message control flag +extsub $FF93 = SECOND(ubyte address @ A) clobbers(A) ; (alias: LSTNSA) send secondary address after LISTEN +extsub $FF96 = TKSA(ubyte address @ A) clobbers(A) ; (alias: TALKSA) send secondary address after TALK +extsub $FF99 = MEMTOP(uword address @ XY, bool dir @ Pc) -> uword @ XY, ubyte @A ; read/set top of memory pointer. NOTE: on the Cx16 also returns the number of RAM memory banks in A! Also see cx16.numbanks() +extsub $FF9C = MEMBOT(uword address @ XY, bool dir @ Pc) -> uword @ XY ; read/set bottom of memory pointer +extsub $FF9F = SCNKEY() clobbers(A,X,Y) ; scan the keyboard, also called kbd_scan +extsub $FFA2 = SETTMO(ubyte timeout @ A) ; set time-out flag for IEEE bus +extsub $FFA5 = ACPTR() -> ubyte @ A ; (alias: IECIN) input byte from serial bus +extsub $FFA8 = CIOUT(ubyte databyte @ A) ; (alias: IECOUT) output byte to serial bus +extsub $FFAB = UNTLK() clobbers(A) ; command serial bus device to UNTALK +extsub $FFAE = UNLSN() clobbers(A) ; command serial bus device to UNLISTEN +extsub $FFB1 = LISTEN(ubyte device @ A) clobbers(A) ; command serial bus device to LISTEN +extsub $FFB4 = TALK(ubyte device @ A) clobbers(A) ; command serial bus device to TALK +extsub $FFB7 = READST() -> ubyte @ A ; read I/O status word (use CLEARST to reset it to 0) +extsub $FFBA = SETLFS(ubyte logical @ A, ubyte device @ X, ubyte secondary @ Y) ; set logical file parameters +extsub $FFBD = SETNAM(ubyte namelen @ A, str filename @ XY) ; set filename parameters +extsub $FFC0 = OPEN() clobbers(X,Y) -> bool @Pc, ubyte @A ; (via 794 ($31A)) open a logical file +extsub $FFC3 = CLOSE(ubyte logical @ A) clobbers(A,X,Y) ; (via 796 ($31C)) close a logical file +extsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; (via 798 ($31E)) define an input channel +extsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; (via 800 ($320)) define an output channel +extsub $FFCC = CLRCHN() clobbers(A,X) ; (via 802 ($322)) restore default devices +extsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; (via 804 ($324)) input a character (for keyboard, read a whole line from the screen) A=byte read. +extsub $FFD2 = CHROUT(ubyte character @ A) ; (via 806 ($326)) output a character +extsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A, uword @ XY ; (via 816 ($330)) load from device +extsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) clobbers (X, Y) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device. See also BSAVE +extsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock +extsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (in little endian order: A=lo,X=mid,Y=high) , however use RDTIM_safe() instead +extsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 +extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 +extsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files +extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock +extsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) +extsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Also see txt.plot +extsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices ; ---- utility @@ -394,152 +394,152 @@ cx16 { ; ---- Commander X-16 additions on top of C64 kernal routines ---- ; spelling of the names is taken from the Commander X-16 rom sources -romsub $ff4a = CLOSE_ALL(ubyte device @A) clobbers(A,X,Y) -romsub $ff59 = LKUPLA(ubyte la @A) clobbers(A,X,Y) -romsub $ff5c = LKUPSA(ubyte sa @Y) clobbers(A,X,Y) -romsub $ff5f = screen_mode(ubyte mode @A, bool getCurrent @Pc) -> ubyte @A, ubyte @X, ubyte @Y, bool @Pc ; also see SCREEN or get_screen_mode() -romsub $ff62 = screen_set_charset(ubyte charset @A, uword charsetptr @XY) clobbers(A,X,Y) -romsub $ff6e = JSRFAR() ; following word = address to call, byte after that=rom/ram bank it is in -romsub $ff74 = fetch(ubyte zp_startaddr @A, ubyte bank @X, ubyte index @Y) clobbers(X) -> ubyte @A -romsub $ff77 = stash(ubyte data @A, ubyte bank @X, ubyte index @Y) clobbers(X) ; note: The the zero page address containing the base address is passed in stavec ($03B2) -romsub $ff7d = PRIMM() +extsub $ff4a = CLOSE_ALL(ubyte device @A) clobbers(A,X,Y) +extsub $ff59 = LKUPLA(ubyte la @A) clobbers(A,X,Y) +extsub $ff5c = LKUPSA(ubyte sa @Y) clobbers(A,X,Y) +extsub $ff5f = screen_mode(ubyte mode @A, bool getCurrent @Pc) -> ubyte @A, ubyte @X, ubyte @Y, bool @Pc ; also see SCREEN or get_screen_mode() +extsub $ff62 = screen_set_charset(ubyte charset @A, uword charsetptr @XY) clobbers(A,X,Y) +extsub $ff6e = JSRFAR() ; following word = address to call, byte after that=rom/ram bank it is in +extsub $ff74 = fetch(ubyte zp_startaddr @A, ubyte bank @X, ubyte index @Y) clobbers(X) -> ubyte @A +extsub $ff77 = stash(ubyte data @A, ubyte bank @X, ubyte index @Y) clobbers(X) ; note: The the zero page address containing the base address is passed in stavec ($03B2) +extsub $ff7d = PRIMM() ; high level graphics & fonts -romsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y) -romsub $ff23 = GRAPH_clear() clobbers(A,X,Y) -romsub $ff26 = GRAPH_set_window(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y) -romsub $ff29 = GRAPH_set_colors(ubyte stroke @A, ubyte fill @X, ubyte background @Y) clobbers (A,X,Y) -romsub $ff2c = GRAPH_draw_line(uword x1 @R0, uword y1 @R1, uword x2 @R2, uword y2 @R3) clobbers(A,X,Y) -romsub $ff2f = GRAPH_draw_rect(uword x @R0, uword y @R1, uword width @R2, uword height @R3, uword cornerradius @R4, bool fill @Pc) clobbers(A,X,Y) -romsub $ff32 = GRAPH_move_rect(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword width @R4, uword height @R5) clobbers(A,X,Y) -romsub $ff35 = GRAPH_draw_oval(uword x @R0, uword y @R1, uword width @R2, uword height @R3, bool fill @Pc) clobbers(A,X,Y) -romsub $ff38 = GRAPH_draw_image(uword x @R0, uword y @R1, uword ptr @R2, uword width @R3, uword height @R4) clobbers(A,X,Y) -romsub $ff3b = GRAPH_set_font(uword fontptr @R0) clobbers(A,X,Y) -romsub $ff3e = GRAPH_get_char_size(ubyte baseline @A, ubyte width @X, ubyte height_or_style @Y, bool is_control @Pc) clobbers(A,X,Y) -romsub $ff41 = GRAPH_put_char(uword x @R0, uword y @R1, ubyte character @A) clobbers(A,X,Y) -romsub $ff41 = GRAPH_put_next_char(ubyte character @A) clobbers(A,X,Y) ; alias for the routine above that doesn't reset the position of the initial character +extsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y) +extsub $ff23 = GRAPH_clear() clobbers(A,X,Y) +extsub $ff26 = GRAPH_set_window(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y) +extsub $ff29 = GRAPH_set_colors(ubyte stroke @A, ubyte fill @X, ubyte background @Y) clobbers (A,X,Y) +extsub $ff2c = GRAPH_draw_line(uword x1 @R0, uword y1 @R1, uword x2 @R2, uword y2 @R3) clobbers(A,X,Y) +extsub $ff2f = GRAPH_draw_rect(uword x @R0, uword y @R1, uword width @R2, uword height @R3, uword cornerradius @R4, bool fill @Pc) clobbers(A,X,Y) +extsub $ff32 = GRAPH_move_rect(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword width @R4, uword height @R5) clobbers(A,X,Y) +extsub $ff35 = GRAPH_draw_oval(uword x @R0, uword y @R1, uword width @R2, uword height @R3, bool fill @Pc) clobbers(A,X,Y) +extsub $ff38 = GRAPH_draw_image(uword x @R0, uword y @R1, uword ptr @R2, uword width @R3, uword height @R4) clobbers(A,X,Y) +extsub $ff3b = GRAPH_set_font(uword fontptr @R0) clobbers(A,X,Y) +extsub $ff3e = GRAPH_get_char_size(ubyte baseline @A, ubyte width @X, ubyte height_or_style @Y, bool is_control @Pc) clobbers(A,X,Y) +extsub $ff41 = GRAPH_put_char(uword x @R0, uword y @R1, ubyte character @A) clobbers(A,X,Y) +extsub $ff41 = GRAPH_put_next_char(ubyte character @A) clobbers(A,X,Y) ; alias for the routine above that doesn't reset the position of the initial character ; framebuffer -romsub $fef6 = FB_init() clobbers(A,X,Y) -romsub $fef9 = FB_get_info() clobbers(X,Y) -> byte @A, uword @R0, uword @R1 ; width=r0, height=r1 -romsub $fefc = FB_set_palette(uword pointer @R0, ubyte index @A, ubyte colorcount @X) clobbers(A,X,Y) -romsub $feff = FB_cursor_position(uword x @R0, uword y @R1) clobbers(A,X,Y) -romsub $ff02 = FB_cursor_next_line(uword x @R0) clobbers(A,X,Y) -romsub $ff05 = FB_get_pixel() clobbers(X,Y) -> ubyte @A -romsub $ff08 = FB_get_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) -romsub $ff0b = FB_set_pixel(ubyte color @A) clobbers(A,X,Y) -romsub $ff0e = FB_set_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) -romsub $ff11 = FB_set_8_pixels(ubyte pattern @A, ubyte color @X) clobbers(A,X,Y) -romsub $ff14 = FB_set_8_pixels_opaque(ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) -romsub $ff17 = FB_fill_pixels(uword count @R0, uword pstep @R1, ubyte color @A) clobbers(A,X,Y) -romsub $ff1a = FB_filter_pixels(uword pointer @ R0, uword count @R1) clobbers(A,X,Y) -romsub $ff1d = FB_move_pixels(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword count @R4) clobbers(A,X,Y) +extsub $fef6 = FB_init() clobbers(A,X,Y) +extsub $fef9 = FB_get_info() clobbers(X,Y) -> byte @A, uword @R0, uword @R1 ; width=r0, height=r1 +extsub $fefc = FB_set_palette(uword pointer @R0, ubyte index @A, ubyte colorcount @X) clobbers(A,X,Y) +extsub $feff = FB_cursor_position(uword x @R0, uword y @R1) clobbers(A,X,Y) +extsub $ff02 = FB_cursor_next_line(uword x @R0) clobbers(A,X,Y) +extsub $ff05 = FB_get_pixel() clobbers(X,Y) -> ubyte @A +extsub $ff08 = FB_get_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) +extsub $ff0b = FB_set_pixel(ubyte color @A) clobbers(A,X,Y) +extsub $ff0e = FB_set_pixels(uword pointer @R0, uword count @R1) clobbers(A,X,Y) +extsub $ff11 = FB_set_8_pixels(ubyte pattern @A, ubyte color @X) clobbers(A,X,Y) +extsub $ff14 = FB_set_8_pixels_opaque(ubyte pattern @R0, ubyte mask @A, ubyte color1 @X, ubyte color2 @Y) clobbers(A,X,Y) +extsub $ff17 = FB_fill_pixels(uword count @R0, uword pstep @R1, ubyte color @A) clobbers(A,X,Y) +extsub $ff1a = FB_filter_pixels(uword pointer @ R0, uword count @R1) clobbers(A,X,Y) +extsub $ff1d = FB_move_pixels(uword sx @R0, uword sy @R1, uword tx @R2, uword ty @R3, uword count @R4) clobbers(A,X,Y) ; misc -romsub $fec6 = i2c_read_byte(ubyte device @X, ubyte offset @Y) clobbers (X,Y) -> ubyte @A, bool @Pc -romsub $fec9 = i2c_write_byte(ubyte device @X, ubyte offset @Y, ubyte data @A) clobbers (A,X,Y) -> bool @Pc -romsub $feb4 = i2c_batch_read(ubyte device @X, uword buffer @R0, uword length @R1, bool advance @Pc) clobbers(A,Y) -> bool @Pc -romsub $feb7 = i2c_batch_write(ubyte device @X, uword buffer @R0, uword length @R1, bool advance @Pc) clobbers(A,Y) -> bool @Pc +extsub $fec6 = i2c_read_byte(ubyte device @X, ubyte offset @Y) clobbers (X,Y) -> ubyte @A, bool @Pc +extsub $fec9 = i2c_write_byte(ubyte device @X, ubyte offset @Y, ubyte data @A) clobbers (A,X,Y) -> bool @Pc +extsub $feb4 = i2c_batch_read(ubyte device @X, uword buffer @R0, uword length @R1, bool advance @Pc) clobbers(A,Y) -> bool @Pc +extsub $feb7 = i2c_batch_write(ubyte device @X, uword buffer @R0, uword length @R1, bool advance @Pc) clobbers(A,Y) -> bool @Pc -romsub $fef0 = sprite_set_image(uword pixels @R0, uword mask @R1, ubyte bpp @R2, ubyte number @A, ubyte width @X, ubyte height @Y, bool apply_mask @Pc) clobbers(A,X,Y) -> bool @Pc -romsub $fef3 = sprite_set_position(uword x @R0, uword y @R1, ubyte number @A) clobbers(A,X,Y) -romsub $fee4 = memory_fill(uword address @R0, uword num_bytes @R1, ubyte value @A) clobbers(A,X,Y) -romsub $fee7 = memory_copy(uword source @R0, uword target @R1, uword num_bytes @R2) clobbers(A,X,Y) -romsub $feea = memory_crc(uword address @R0, uword num_bytes @R1) clobbers(A,X,Y) -> uword @R2 -romsub $feed = memory_decompress(uword input @R0, uword output @R1) clobbers(A,X,Y) -> uword @R1 ; last address +1 is result in R1 -romsub $fedb = console_init(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y) -romsub $fede = console_put_char(ubyte character @A, bool wrapping @Pc) clobbers(A,X,Y) -romsub $fee1 = console_get_char() clobbers(X,Y) -> ubyte @A -romsub $fed8 = console_put_image(uword pointer @R0, uword width @R1, uword height @R2) clobbers(A,X,Y) -romsub $fed5 = console_set_paging_message(uword msgptr @R0) clobbers(A,X,Y) -romsub $fecf = entropy_get() -> ubyte @A, ubyte @X, ubyte @Y -;; romsub $fea8 = extapi16(ubyte callnumber @A) clobbers (A,X,Y) ; not useful yet because is for 65816 cpu -romsub $feab = extapi(ubyte callnumber @A) clobbers (A,X,Y) -romsub $fecc = monitor() clobbers(A,X,Y) +extsub $fef0 = sprite_set_image(uword pixels @R0, uword mask @R1, ubyte bpp @R2, ubyte number @A, ubyte width @X, ubyte height @Y, bool apply_mask @Pc) clobbers(A,X,Y) -> bool @Pc +extsub $fef3 = sprite_set_position(uword x @R0, uword y @R1, ubyte number @A) clobbers(A,X,Y) +extsub $fee4 = memory_fill(uword address @R0, uword num_bytes @R1, ubyte value @A) clobbers(A,X,Y) +extsub $fee7 = memory_copy(uword source @R0, uword target @R1, uword num_bytes @R2) clobbers(A,X,Y) +extsub $feea = memory_crc(uword address @R0, uword num_bytes @R1) clobbers(A,X,Y) -> uword @R2 +extsub $feed = memory_decompress(uword input @R0, uword output @R1) clobbers(A,X,Y) -> uword @R1 ; last address +1 is result in R1 +extsub $fedb = console_init(uword x @R0, uword y @R1, uword width @R2, uword height @R3) clobbers(A,X,Y) +extsub $fede = console_put_char(ubyte character @A, bool wrapping @Pc) clobbers(A,X,Y) +extsub $fee1 = console_get_char() clobbers(X,Y) -> ubyte @A +extsub $fed8 = console_put_image(uword pointer @R0, uword width @R1, uword height @R2) clobbers(A,X,Y) +extsub $fed5 = console_set_paging_message(uword msgptr @R0) clobbers(A,X,Y) +extsub $fecf = entropy_get() -> ubyte @A, ubyte @X, ubyte @Y +;; extsub $fea8 = extapi16(ubyte callnumber @A) clobbers (A,X,Y) ; not useful yet because is for 65816 cpu +extsub $feab = extapi(ubyte callnumber @A) clobbers (A,X,Y) +extsub $fecc = monitor() clobbers(A,X,Y) -romsub $ff44 = MACPTR(ubyte length @A, uword buffer @XY, bool dontAdvance @Pc) clobbers(A) -> bool @Pc, uword @XY -romsub $feb1 = MCIOUT(ubyte length @A, uword buffer @XY, bool dontAdvance @Pc) clobbers(A) -> bool @Pc, uword @XY -romsub $FEBA = BSAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) clobbers (X, Y) -> bool @ Pc, ubyte @ A ; like cbm.SAVE, but omits the 2-byte prg header -romsub $ff47 = enter_basic(bool cold_or_warm @Pc) clobbers(A,X,Y) -romsub $ff4d = clock_set_date_time(uword yearmonth @R0, uword dayhours @R1, uword minsecs @R2, uword jiffiesweekday @R3) clobbers(A, X, Y) -romsub $ff50 = clock_get_date_time() clobbers(A, X, Y) -> uword @R0, uword @R1, uword @R2, uword @R3 ; result registers see clock_set_date_time() +extsub $ff44 = MACPTR(ubyte length @A, uword buffer @XY, bool dontAdvance @Pc) clobbers(A) -> bool @Pc, uword @XY +extsub $feb1 = MCIOUT(ubyte length @A, uword buffer @XY, bool dontAdvance @Pc) clobbers(A) -> bool @Pc, uword @XY +extsub $FEBA = BSAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) clobbers (X, Y) -> bool @ Pc, ubyte @ A ; like cbm.SAVE, but omits the 2-byte prg header +extsub $ff47 = enter_basic(bool cold_or_warm @Pc) clobbers(A,X,Y) +extsub $ff4d = clock_set_date_time(uword yearmonth @R0, uword dayhours @R1, uword minsecs @R2, uword jiffiesweekday @R3) clobbers(A, X, Y) +extsub $ff50 = clock_get_date_time() clobbers(A, X, Y) -> uword @R0, uword @R1, uword @R2, uword @R3 ; result registers see clock_set_date_time() ; keyboard, mouse, joystick ; note: also see the cbm.kbdbuf_clear() helper routine -romsub $febd = kbdbuf_peek() -> ubyte @A, ubyte @X ; key in A, queue length in X -romsub $fec0 = kbdbuf_get_modifiers() -> ubyte @A -romsub $fec3 = kbdbuf_put(ubyte key @A) clobbers(X) -romsub $fed2 = keymap(uword identifier @XY, bool read @Pc) -> bool @Pc -romsub $ff68 = mouse_config(byte shape @A, ubyte resX @X, ubyte resY @Y) clobbers (A, X, Y) -romsub $ff6b = mouse_get(ubyte zdataptr @X) -> ubyte @A, byte @X ; use mouse_pos() instead -romsub $ff71 = mouse_scan() clobbers(A, X, Y) -romsub $ff53 = joystick_scan() clobbers(A, X, Y) -romsub $ff56 = joystick_get(ubyte joynr @A) -> uword @AX, bool @Y ; note: everything is inverted +extsub $febd = kbdbuf_peek() -> ubyte @A, ubyte @X ; key in A, queue length in X +extsub $fec0 = kbdbuf_get_modifiers() -> ubyte @A +extsub $fec3 = kbdbuf_put(ubyte key @A) clobbers(X) +extsub $fed2 = keymap(uword identifier @XY, bool read @Pc) -> bool @Pc +extsub $ff68 = mouse_config(byte shape @A, ubyte resX @X, ubyte resY @Y) clobbers (A, X, Y) +extsub $ff6b = mouse_get(ubyte zdataptr @X) -> ubyte @A, byte @X ; use mouse_pos() instead +extsub $ff71 = mouse_scan() clobbers(A, X, Y) +extsub $ff53 = joystick_scan() clobbers(A, X, Y) +extsub $ff56 = joystick_get(ubyte joynr @A) -> uword @AX, bool @Y ; note: everything is inverted ; X16Edit (rom bank 13/14 but you ideally should use the routine search_x16edit() to search for the correct bank) -romsub $C000 = x16edit_default() clobbers(A,X,Y) -romsub $C003 = x16edit_loadfile(ubyte firstbank @X, ubyte lastbank @Y, str filename @R0, ubyte filenameLength @R1) clobbers(A,X,Y) -romsub $C006 = x16edit_loadfile_options(ubyte firstbank @X, ubyte lastbank @Y, str filename @R0, +extsub $C000 = x16edit_default() clobbers(A,X,Y) +extsub $C003 = x16edit_loadfile(ubyte firstbank @X, ubyte lastbank @Y, str filename @R0, ubyte filenameLength @R1) clobbers(A,X,Y) +extsub $C006 = x16edit_loadfile_options(ubyte firstbank @X, ubyte lastbank @Y, str filename @R0, uword filenameLengthAndOptions @R1, uword tabstopAndWordwrap @R2, uword disknumberAndColors @R3, uword headerAndStatusColors @R4) clobbers(A,X,Y) ; Audio (rom bank 10) -romsub @bank 10 $C09F = audio_init() clobbers(A,X,Y) -> bool @Pc ; (re)initialize both vera PSG and YM audio chips -romsub @bank 10 $C000 = bas_fmfreq(ubyte channel @A, uword freq @XY, bool noretrigger @Pc) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C003 = bas_fmnote(ubyte channel @A, ubyte note @X, ubyte fracsemitone @Y, bool noretrigger @Pc) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C006 = bas_fmplaystring(ubyte length @A, str string @XY) clobbers(A,X,Y) -romsub @bank 10 $C009 = bas_fmvib(ubyte speed @A, ubyte depth @X) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C00C = bas_playstringvoice(ubyte channel @A) clobbers(Y) -romsub @bank 10 $C00F = bas_psgfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C012 = bas_psgnote(ubyte voice @A, ubyte note @X, ubyte fracsemitone @Y) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C015 = bas_psgwav(ubyte voice @A, ubyte waveform @X) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C018 = bas_psgplaystring(ubyte length @A, str string @XY) clobbers(A,X,Y) -romsub @bank 10 $C08D = bas_fmchordstring(ubyte length @A, str string @XY) clobbers(A,X,Y) -romsub @bank 10 $C090 = bas_psgchordstring(ubyte length @A, str string @XY) clobbers(A,X,Y) -romsub @bank 10 $C01B = notecon_bas2fm(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C01E = notecon_bas2midi(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C021 = notecon_bas2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc -romsub @bank 10 $C024 = notecon_fm2bas(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C027 = notecon_fm2midi(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C02A = notecon_fm2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc -romsub @bank 10 $C02D = notecon_freq2bas(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C030 = notecon_freq2fm(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C033 = notecon_freq2midi(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C036 = notecon_freq2psg(uword freqHz @XY) clobbers(A) -> uword @XY, bool @Pc -romsub @bank 10 $C039 = notecon_midi2bas(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C03C = notecon_midi2fm(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc -romsub @bank 10 $C03F = notecon_midi2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc -romsub @bank 10 $C042 = notecon_psg2bas(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C045 = notecon_psg2fm(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C048 = notecon_psg2midi(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc -romsub @bank 10 $C04B = psg_init() clobbers(A,X,Y) ; (re)init Vera PSG -romsub @bank 10 $C04E = psg_playfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) -romsub @bank 10 $C051 = psg_read(ubyte offset @X, bool cookedVol @Pc) clobbers(Y) -> ubyte @A -romsub @bank 10 $C054 = psg_setatten(ubyte voice @A, ubyte attenuation @X) clobbers(A,X,Y) -romsub @bank 10 $C057 = psg_setfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) -romsub @bank 10 $C05A = psg_setpan(ubyte voice @A, ubyte panning @X) clobbers(A,X,Y) -romsub @bank 10 $C05D = psg_setvol(ubyte voice @A, ubyte volume @X) clobbers(A,X,Y) -romsub @bank 10 $C060 = psg_write(ubyte value @A, ubyte offset @X) clobbers(Y) -romsub @bank 10 $C0A2 = psg_write_fast(ubyte value @A, ubyte offset @X) clobbers(Y) -romsub @bank 10 $C093 = psg_getatten(ubyte voice @A) clobbers(Y) -> ubyte @X -romsub @bank 10 $C096 = psg_getpan(ubyte voice @A) clobbers(Y) -> ubyte @X -romsub @bank 10 $C063 = ym_init() clobbers(A,X,Y) -> bool @Pc ; (re)init YM chip -romsub @bank 10 $C066 = ym_loaddefpatches() clobbers(A,X,Y) -> bool @Pc ; load default YM patches -romsub @bank 10 $C069 = ym_loadpatch(ubyte channel @A, uword patchOrAddress @XY, bool what @Pc) clobbers(A,X,Y) -romsub @bank 10 $C06C = ym_loadpatchlfn(ubyte channel @A, ubyte lfn @X) clobbers(X,Y) -> ubyte @A, bool @Pc -romsub @bank 10 $C06F = ym_playdrum(ubyte channel @A, ubyte note @X) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C072 = ym_playnote(ubyte channel @A, ubyte kc @X, ubyte kf @Y, bool notrigger @Pc) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C075 = ym_setatten(ubyte channel @A, ubyte attenuation @X) clobbers(Y) -> bool @Pc -romsub @bank 10 $C078 = ym_setdrum(ubyte channel @A, ubyte note @X) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C07B = ym_setnote(ubyte channel @A, ubyte kc @X, ubyte kf @Y) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C07E = ym_setpan(ubyte channel @A, ubyte panning @X) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C081 = ym_read(ubyte register @X, bool cooked @Pc) clobbers(Y) -> ubyte @A, bool @Pc -romsub @bank 10 $C084 = ym_release(ubyte channel @A) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C087 = ym_trigger(ubyte channel @A, bool noRelease @Pc) clobbers(A,X,Y) -> bool @Pc -romsub @bank 10 $C08A = ym_write(ubyte value @A, ubyte register @X) clobbers(Y) -> bool @Pc -romsub @bank 10 $C099 = ym_getatten(ubyte channel @A) clobbers(Y) -> ubyte @X -romsub @bank 10 $C09C = ym_getpan(ubyte channel @A) clobbers(Y) -> ubyte @X -romsub @bank 10 $C0A5 = ym_get_chip_type() clobbers(X) -> ubyte @A +extsub @bank 10 $C09F = audio_init() clobbers(A,X,Y) -> bool @Pc ; (re)initialize both vera PSG and YM audio chips +extsub @bank 10 $C000 = bas_fmfreq(ubyte channel @A, uword freq @XY, bool noretrigger @Pc) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C003 = bas_fmnote(ubyte channel @A, ubyte note @X, ubyte fracsemitone @Y, bool noretrigger @Pc) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C006 = bas_fmplaystring(ubyte length @A, str string @XY) clobbers(A,X,Y) +extsub @bank 10 $C009 = bas_fmvib(ubyte speed @A, ubyte depth @X) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C00C = bas_playstringvoice(ubyte channel @A) clobbers(Y) +extsub @bank 10 $C00F = bas_psgfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C012 = bas_psgnote(ubyte voice @A, ubyte note @X, ubyte fracsemitone @Y) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C015 = bas_psgwav(ubyte voice @A, ubyte waveform @X) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C018 = bas_psgplaystring(ubyte length @A, str string @XY) clobbers(A,X,Y) +extsub @bank 10 $C08D = bas_fmchordstring(ubyte length @A, str string @XY) clobbers(A,X,Y) +extsub @bank 10 $C090 = bas_psgchordstring(ubyte length @A, str string @XY) clobbers(A,X,Y) +extsub @bank 10 $C01B = notecon_bas2fm(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C01E = notecon_bas2midi(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C021 = notecon_bas2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc +extsub @bank 10 $C024 = notecon_fm2bas(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C027 = notecon_fm2midi(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C02A = notecon_fm2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc +extsub @bank 10 $C02D = notecon_freq2bas(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C030 = notecon_freq2fm(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C033 = notecon_freq2midi(uword freqHz @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C036 = notecon_freq2psg(uword freqHz @XY) clobbers(A) -> uword @XY, bool @Pc +extsub @bank 10 $C039 = notecon_midi2bas(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C03C = notecon_midi2fm(ubyte note @X) clobbers(A) -> ubyte @X, bool @Pc +extsub @bank 10 $C03F = notecon_midi2psg(ubyte note @X, ubyte fracsemitone @Y) clobbers(A) -> uword @XY, bool @Pc +extsub @bank 10 $C042 = notecon_psg2bas(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C045 = notecon_psg2fm(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C048 = notecon_psg2midi(uword freq @XY) clobbers(A) -> ubyte @X, ubyte @Y, bool @Pc +extsub @bank 10 $C04B = psg_init() clobbers(A,X,Y) ; (re)init Vera PSG +extsub @bank 10 $C04E = psg_playfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) +extsub @bank 10 $C051 = psg_read(ubyte offset @X, bool cookedVol @Pc) clobbers(Y) -> ubyte @A +extsub @bank 10 $C054 = psg_setatten(ubyte voice @A, ubyte attenuation @X) clobbers(A,X,Y) +extsub @bank 10 $C057 = psg_setfreq(ubyte voice @A, uword freq @XY) clobbers(A,X,Y) +extsub @bank 10 $C05A = psg_setpan(ubyte voice @A, ubyte panning @X) clobbers(A,X,Y) +extsub @bank 10 $C05D = psg_setvol(ubyte voice @A, ubyte volume @X) clobbers(A,X,Y) +extsub @bank 10 $C060 = psg_write(ubyte value @A, ubyte offset @X) clobbers(Y) +extsub @bank 10 $C0A2 = psg_write_fast(ubyte value @A, ubyte offset @X) clobbers(Y) +extsub @bank 10 $C093 = psg_getatten(ubyte voice @A) clobbers(Y) -> ubyte @X +extsub @bank 10 $C096 = psg_getpan(ubyte voice @A) clobbers(Y) -> ubyte @X +extsub @bank 10 $C063 = ym_init() clobbers(A,X,Y) -> bool @Pc ; (re)init YM chip +extsub @bank 10 $C066 = ym_loaddefpatches() clobbers(A,X,Y) -> bool @Pc ; load default YM patches +extsub @bank 10 $C069 = ym_loadpatch(ubyte channel @A, uword patchOrAddress @XY, bool what @Pc) clobbers(A,X,Y) +extsub @bank 10 $C06C = ym_loadpatchlfn(ubyte channel @A, ubyte lfn @X) clobbers(X,Y) -> ubyte @A, bool @Pc +extsub @bank 10 $C06F = ym_playdrum(ubyte channel @A, ubyte note @X) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C072 = ym_playnote(ubyte channel @A, ubyte kc @X, ubyte kf @Y, bool notrigger @Pc) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C075 = ym_setatten(ubyte channel @A, ubyte attenuation @X) clobbers(Y) -> bool @Pc +extsub @bank 10 $C078 = ym_setdrum(ubyte channel @A, ubyte note @X) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C07B = ym_setnote(ubyte channel @A, ubyte kc @X, ubyte kf @Y) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C07E = ym_setpan(ubyte channel @A, ubyte panning @X) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C081 = ym_read(ubyte register @X, bool cooked @Pc) clobbers(Y) -> ubyte @A, bool @Pc +extsub @bank 10 $C084 = ym_release(ubyte channel @A) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C087 = ym_trigger(ubyte channel @A, bool noRelease @Pc) clobbers(A,X,Y) -> bool @Pc +extsub @bank 10 $C08A = ym_write(ubyte value @A, ubyte register @X) clobbers(Y) -> bool @Pc +extsub @bank 10 $C099 = ym_getatten(ubyte channel @A) clobbers(Y) -> ubyte @X +extsub @bank 10 $C09C = ym_getpan(ubyte channel @A) clobbers(Y) -> ubyte @X +extsub @bank 10 $C0A5 = ym_get_chip_type() clobbers(X) -> ubyte @A ; extapi call numbers const ubyte EXTAPI_clear_status = $01 diff --git a/compiler/res/prog8lib/cx16/textio.p8 b/compiler/res/prog8lib/cx16/textio.p8 index 32e81a692..c5d66eb5b 100644 --- a/compiler/res/prog8lib/cx16/textio.p8 +++ b/compiler/res/prog8lib/cx16/textio.p8 @@ -16,7 +16,7 @@ const ubyte DEFAULT_HEIGHT = 60 const ubyte VERA_TEXTMATRIX_BANK = 1 const uword VERA_TEXTMATRIX_ADDR = $b000 -romsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. +extsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. sub clear_screen() { diff --git a/compiler/res/prog8lib/pet32/syslib.p8 b/compiler/res/prog8lib/pet32/syslib.p8 index 152ecc5d9..059050363 100644 --- a/compiler/res/prog8lib/pet32/syslib.p8 +++ b/compiler/res/prog8lib/pet32/syslib.p8 @@ -24,15 +24,15 @@ cbm { const uword Screen = $8000 ; to have this as an array[40*25] the compiler would have to support array size > 255 -romsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; define an input channel -romsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; define an output channel -romsub $FFCC = CLRCHN() clobbers(A,X) ; restore default devices -romsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; input a character (for keyboard, read a whole line from the screen) A=byte read. -romsub $FFD2 = CHROUT(ubyte character @ A) ; output a character -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; get a character also see GETIN2 -romsub $FFE7 = CLALL() clobbers(A,X) ; close all files -romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock +extsub $FFC6 = CHKIN(ubyte logical @ X) clobbers(A,X) -> bool @Pc ; define an input channel +extsub $FFC9 = CHKOUT(ubyte logical @ X) clobbers(A,X) ; define an output channel +extsub $FFCC = CLRCHN() clobbers(A,X) ; restore default devices +extsub $FFCF = CHRIN() clobbers(X, Y) -> ubyte @ A ; input a character (for keyboard, read a whole line from the screen) A=byte read. +extsub $FFD2 = CHROUT(ubyte character @ A) ; output a character +extsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; check the STOP key (and some others in A) also see STOP2 +extsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; get a character also see GETIN2 +extsub $FFE7 = CLALL() clobbers(A,X) ; close all files +extsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock inline asmsub STOP2() clobbers(X,A) -> bool @Pz { diff --git a/compiler/res/prog8lib/pet32/textio.p8 b/compiler/res/prog8lib/pet32/textio.p8 index 2f144e934..c3ddd17b3 100644 --- a/compiler/res/prog8lib/pet32/textio.p8 +++ b/compiler/res/prog8lib/pet32/textio.p8 @@ -12,7 +12,7 @@ txt { const ubyte DEFAULT_WIDTH = 40 const ubyte DEFAULT_HEIGHT = 25 -romsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. +extsub $FFD2 = chrout(ubyte character @ A) ; for consistency. You can also use cbm.CHROUT directly ofcourse. Note: takes a PETSCII encoded character. sub clear_screen() { diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index d7b52f74a..3d055692b 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -388,7 +388,7 @@ internal class AstChecker(private val program: Program, err("bank variable must be ubyte") } if(subroutine.inline && subroutine.asmAddress!=null) - throw FatalAstException("romsub cannot be inline") + throw FatalAstException("extsub cannot be inline") super.visit(subroutine) diff --git a/compiler/test/TestCompilerOnCharLit.kt b/compiler/test/TestCompilerOnCharLit.kt index e33747727..a3cb37922 100644 --- a/compiler/test/TestCompilerOnCharLit.kt +++ b/compiler/test/TestCompilerOnCharLit.kt @@ -38,7 +38,7 @@ class TestCompilerOnCharLit: FunSpec({ val platform = Cx16Target() val result = compileText(platform, false, """ main { - romsub ${"$"}FFD2 = chrout(ubyte ch @ A) + extsub ${"$"}FFD2 = chrout(ubyte ch @ A) sub start() { chrout('\n') } @@ -61,7 +61,7 @@ class TestCompilerOnCharLit: FunSpec({ val platform = Cx16Target() val result = compileText(platform, false, """ main { - romsub ${"$"}FFD2 = chrout(ubyte ch @ A) + extsub ${"$"}FFD2 = chrout(ubyte ch @ A) sub start() { ubyte ch = '\n' chrout(ch) @@ -96,7 +96,7 @@ class TestCompilerOnCharLit: FunSpec({ val platform = Cx16Target() val result = compileText(platform, false, """ main { - romsub ${"$"}FFD2 = chrout(ubyte ch @ A) + extsub ${"$"}FFD2 = chrout(ubyte ch @ A) sub start() { const ubyte ch = '\n' chrout(ch) diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 404663052..b71709c25 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -1035,9 +1035,9 @@ main { %option no_sysinit main { - romsub ${'$'}2000 = func1() clobbers(X) -> ubyte @A, word @R0, byte @R1 - romsub ${'$'}3000 = func2() clobbers(X) -> ubyte @A, uword @R0, uword @R1 - romsub ${'$'}4000 = func3() clobbers(X) -> ubyte @R0 + extsub ${'$'}2000 = func1() clobbers(X) -> ubyte @A, word @R0, byte @R1 + extsub ${'$'}3000 = func2() clobbers(X) -> ubyte @A, uword @R0, uword @R1 + extsub ${'$'}4000 = func3() clobbers(X) -> ubyte @R0 sub start() { bool flag diff --git a/compiler/test/ast/TestSubroutines.kt b/compiler/test/ast/TestSubroutines.kt index 67b5ded91..77fed8dda 100644 --- a/compiler/test/ast/TestSubroutines.kt +++ b/compiler/test/ast/TestSubroutines.kt @@ -184,9 +184,9 @@ main { void, void, void = test3() } - romsub ${'$'}8000 = test(ubyte arg @A) -> bool @Pc - romsub ${'$'}8002 = test2(uword arg @AY, uword arg2 @R1, bool flag @Pc, byte value @X) -> ubyte @A, bool @Pc - romsub ${'$'}8003 = test3() -> uword @R1, bool @Pc, ubyte @X + extsub ${'$'}8000 = test(ubyte arg @A) -> bool @Pc + extsub ${'$'}8002 = test2(uword arg @AY, uword arg2 @R1, bool flag @Pc, byte value @X) -> ubyte @A, bool @Pc + extsub ${'$'}8003 = test3() -> uword @R1, bool @Pc, ubyte @X }""" compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index 1914295e5..7ea21ae48 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -618,8 +618,8 @@ main { test("void assignment is invalid") { val src=""" main { - romsub $2000 = multi() -> ubyte @A, ubyte @Y - romsub $3000 = single() -> ubyte @A + extsub $2000 = multi() -> ubyte @A, ubyte @Y + extsub $3000 = single() -> ubyte @A sub start() { void, void = multi() ; ok diff --git a/compiler/test/codegeneration/TestVariousCodeGen.kt b/compiler/test/codegeneration/TestVariousCodeGen.kt index 01aad8fcf..59740a45d 100644 --- a/compiler/test/codegeneration/TestVariousCodeGen.kt +++ b/compiler/test/codegeneration/TestVariousCodeGen.kt @@ -451,7 +451,7 @@ main { test("multiple status flags return values from asmsub") { val src=""" main { - romsub 5000 = carryAndNegativeAndByteAndWord() -> bool @Pc, bool @Pn, ubyte @X, uword @AY + extsub 5000 = carryAndNegativeAndByteAndWord() -> bool @Pc, bool @Pn, ubyte @X, uword @AY sub start() { ubyte @shared x diff --git a/compiler/test/fixtures/asmBinaryFromSameFolder.p8 b/compiler/test/fixtures/asmBinaryFromSameFolder.p8 index d48a8c6b0..1c8233c05 100644 --- a/compiler/test/fixtures/asmBinaryFromSameFolder.p8 +++ b/compiler/test/fixtures/asmBinaryFromSameFolder.p8 @@ -5,6 +5,6 @@ main { } stuff $1000 { - romsub $1000 = do_nothing() + extsub $1000 = do_nothing() %asmbinary "do_nothing1.bin", 0 } \ No newline at end of file diff --git a/compiler/test/fixtures/asmBinaryFromSubFolder.p8 b/compiler/test/fixtures/asmBinaryFromSubFolder.p8 index 5b48b7892..6bbf14de6 100644 --- a/compiler/test/fixtures/asmBinaryFromSubFolder.p8 +++ b/compiler/test/fixtures/asmBinaryFromSubFolder.p8 @@ -5,6 +5,6 @@ main { } stuff $1000 { - romsub $1000 = do_nothing() + extsub $1000 = do_nothing() %asmbinary "subFolder/do_nothing2.bin", 0 } \ No newline at end of file diff --git a/compiler/test/fixtures/asmBinaryNonExisting.p8 b/compiler/test/fixtures/asmBinaryNonExisting.p8 index 2ff4e2f46..170d86442 100644 --- a/compiler/test/fixtures/asmBinaryNonExisting.p8 +++ b/compiler/test/fixtures/asmBinaryNonExisting.p8 @@ -5,6 +5,6 @@ main { } stuff $1000 { - romsub $1000 = do_nothing() + extsub $1000 = do_nothing() %asmbinary "i_do_not_exist.bin", 0 } \ No newline at end of file diff --git a/compiler/test/fixtures/asmBinaryNonReadable.p8 b/compiler/test/fixtures/asmBinaryNonReadable.p8 index 3b7f63bfc..1fc4c2de2 100644 --- a/compiler/test/fixtures/asmBinaryNonReadable.p8 +++ b/compiler/test/fixtures/asmBinaryNonReadable.p8 @@ -5,6 +5,6 @@ main { } stuff $1000 { - romsub $1000 = do_nothing() + extsub $1000 = do_nothing() %asmbinary "subFolder", 0 } \ No newline at end of file diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index 08b8c10c3..873237e1f 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -184,7 +184,7 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: val bank = if(subroutine.asmAddress.constbank!=null) "@bank ${subroutine.asmAddress.constbank}" else if(subroutine.asmAddress.varbank!=null) "@bank ${subroutine.asmAddress.varbank?.nameInSource?.joinToString(".")}" else "" - output("romsub $bank ${subroutine.asmAddress.address.toHex()} = ${subroutine.name} (") + output("extsub $bank ${subroutine.asmAddress.address.toHex()} = ${subroutine.name} (") } else output("asmsub ${subroutine.name} (") diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index 3c8bcb18d..2838283d6 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -1,6 +1,7 @@ package prog8.ast.antlr import org.antlr.v4.runtime.ParserRuleContext +import org.antlr.v4.runtime.tree.ErrorNodeImpl import org.antlr.v4.runtime.tree.TerminalNode import prog8.ast.base.FatalAstException import prog8.ast.base.SyntaxError @@ -78,7 +79,7 @@ private fun SubroutinedeclarationContext.toAst() : Subroutine { return when { subroutine()!=null -> subroutine().toAst() asmsubroutine()!=null -> asmsubroutine().toAst() - romsubroutine()!=null -> romsubroutine().toAst() + extsubroutine()!=null -> extsubroutine().toAst() else -> throw FatalAstException("weird subroutine decl $this") } } @@ -175,7 +176,9 @@ private fun AsmsubroutineContext.toAst(): Subroutine { subdecl.asmClobbers, null, true, inline, false, statements, toPosition()) } -private fun RomsubroutineContext.toAst(): Subroutine { +private fun ExtsubroutineContext.toAst(): Subroutine { + if(this.text.startsWith("romsub")) + println("INFO ${toPosition().toClickableStr()} 'romsub' keyword is deprecated, change to 'extsub'") // TODO eventually, remove this 'romsub' support altogether val subdecl = asmsub_decl().toAst() val constbank = constbank?.toAst()?.number?.toUInt()?.toUByte() val varbank = varbank?.toAst() diff --git a/docs/source/comparing.rst b/docs/source/comparing.rst index 20862272b..f4736f45a 100644 --- a/docs/source/comparing.rst +++ b/docs/source/comparing.rst @@ -26,7 +26,7 @@ No linker --------- - Even though your programs can consist of many separate module files, the compiler always outputs a single program file. There is no separate linker step. Currently, it's not easily possible to integrate object files created elsewhere. If the object file has a fixed load location and fixed entrypoints, - it can be loaded explicitly and accessed easily using romsub definitions though. + it can be loaded explicitly and accessed easily using extsub definitions though. - The prog8 compiler is self-contained in a single jar file. You do need 1 external tool namely 64tass, which performs the assembler step. @@ -79,7 +79,7 @@ Pointers Foreign function interface (external/ROM calls) ----------------------------------------------- -- You can use the ``romsub`` keyword to define the call signature of foreign functions (usually ROM routines, hence the name) in a natural way. +- You can use the ``extsub`` keyword to define the call signature of foreign functions (ROM routines or external routines elsewhere in RAM) in a natural way. Calling those generates code that is as efficient or even more efficient as calling regular subroutines. No additional stubs are needed. You can even specify the memory bank the routine is in and the compiler takes care of bank switching when calling it. diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 27c421058..20f722bb5 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -805,7 +805,7 @@ Subroutines are parts of the code that can be repeatedly invoked using a subrout Their definition, using the ``sub`` statement, includes the specification of the required parameters and return value. Subroutines can be defined in a Block, but also nested inside another subroutine. Everything is scoped accordingly. With ``asmsub`` you can define a low-level subroutine that is implemented directly in assembly and takes parameters -directly in registers. Finally with ``romsub`` you can define an external subroutine that's implemented outside +directly in registers. Finally with ``extsub`` you can define an external subroutine that's implemented outside of the program (for instance, a ROM routine, or a routine in a library loaded elsewhere in RAM). Trivial ``asmsub`` routines can be tagged as ``inline`` to tell the compiler to copy their code diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 7223a9a40..4f288e1f9 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -723,7 +723,7 @@ Otherwise the compiler will warn you about discarding the result of the call. Multiple return values ^^^^^^^^^^^^^^^^^^^^^^ Normal subroutines can only return zero or one return values. -However, the special ``asmsub`` routines (implemented in assembly code) or ``romsub`` routines +However, the special ``asmsub`` routines (implemented in assembly code) or ``extsub`` routines (referencing an external routine in ROM or elsewhere in RAM) can return more than one return value. For example a status in the carry bit and a number in A, or a 16-bit value in A/Y registers and some more values in R0 and R1. In all of these cases, you have to "multi assign" all return values of the subroutine call to something. @@ -786,7 +786,7 @@ External subroutines External subroutines are usually defined by compiler library files, with the following syntax:: - romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) clobbers() + extsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) clobbers() -> bool @Pc, ubyte @ A, ubyte @ X, ubyte @ Y This defines the ``LOAD`` subroutine at memory address $FFD5, taking arguments in all three registers A, X and Y, @@ -794,14 +794,9 @@ and returning stuff in several registers as well. The ``clobbers`` clause is use what CPU registers are clobbered by the call instead of being unchanged or returning a meaningful result value. **Banks:** it is possible to declare a non-standard ROM or RAM bank that the routine is living in, with ``@bank`` like this: -``romsub @bank 10 $C09F = audio_init()`` to define a routine at $C09F in bank 10. You can also specify a variable for the bank. +``extsub @bank 10 $C09F = audio_init()`` to define a routine at $C09F in bank 10. You can also specify a variable for the bank. See :ref:`banking` for more information. -.. note:: - ``romsub`` is most often used to define ROM subroutines. But contrary to what the name may suggest, - it can also define an external subroutine elsewhere in normal RAM. It simply states the address - and signature of the subroutine; it doesn't care if the routine is in ROM or RAM address space. - User-written subroutines in the program source code itself, implemented purely in assembly and which have an assembly calling convention (i.e. the parameters are strictly passed via cpu registers), are defined with ``asmsub`` like this:: diff --git a/docs/source/technical.rst b/docs/source/technical.rst index c10ff2ee1..32913e7df 100644 --- a/docs/source/technical.rst +++ b/docs/source/technical.rst @@ -46,16 +46,16 @@ Calling a subroutine in another memory bank can be done by using the ``callfar`` When you are using the routines above, you are doing explicit manual banks control. However, Prog8 also provides something more sophisticated than this, when dealing with banked subroutines: -External subroutines defined with ``romsub`` can have a non-standard ROM or RAM bank specified as well. +External subroutines defined with ``extsub`` can have a non-standard ROM or RAM bank specified as well. The compiler will then transparently change a call to this routine so that the correct bank is activated automatically before the normal jump to the subroutine (and switched back on return). The programmer doesn't have to bother anymore with setting/resetting the banks manually, or having the program crash because the routine is called in the wrong bank! You define such a routine by adding ``@bank `` -to the romsub subroutine definition. This specifies the bank number where the subroutine is located in. +to the extsub subroutine definition. This specifies the bank number where the subroutine is located in. You can use a constant bank number 0-255, or a ubyte variable to make it dynamic:: - romsub @bank 10 $C09F = audio_init() - romsub @bank banknr $A000 = first_hiram_routine() + extsub @bank 10 $C09F = audio_init() + extsub @bank banknr $A000 = first_hiram_routine() When you then call this routine in your program as usual, the compiler will no longer generate a simple JSR instruction to the routine. Instead it will generate a piece of code that automatically switches the ROM or RAM bank to the @@ -67,7 +67,7 @@ On the Commodore 64 some custom code is also emitted that toggle the banks, reta Other compilation targets don't have banking or prog8 doesn't yet support automatic bank selection on them. There's a "banking" example for the Commander X16 that shows a possible application -of the romsub with bank support, check out the `bank example code `_ . +of the extsub with bank support, check out the `bank example code `_ . Notice that the symbol for this routine in the assembly source code will still be defined as usual. diff --git a/docs/source/todo.rst b/docs/source/todo.rst index bd28fb5a0..13eb6bf98 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,8 +1,6 @@ TODO ==== -rename 'romsub' to 'extsub' ? keep romsub as alias? - for releasenotes: gfx2.width and gfx2.height got renamed as gfx_lores.WIDTH/HEIGHT or gfx_hires4.WIDTH/HEIGTH constants. Screen mode routines also renamed. regenerate symbol dump files @@ -18,6 +16,7 @@ Maybe this routine can be made more intelligent. See usesOtherRegistersWhileEva Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ +- remove 'extsub' as a recognised alternative for 'extsub' - Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions - Does it make codegen easier if everything is an expression? Start with the PtProgram ast , get rid of the statements there -> expressions that have Void data type - Can we support signed % (remainder) somehow? diff --git a/examples/cx16/banking/program.p8 b/examples/cx16/banking/program.p8 index 6a32653f9..4b19b1a94 100644 --- a/examples/cx16/banking/program.p8 +++ b/examples/cx16/banking/program.p8 @@ -5,9 +5,9 @@ %zeropage basicsafe main { - romsub @bank 4 $A000 = lib_routine1(ubyte value @A) clobbers(X) -> uword @AY - romsub @bank 5 $A000 = lib_routine2(ubyte value @A) clobbers(X) -> uword @AY - romsub @bank 10 $C09F = audio_init() -> bool @A + extsub @bank 4 $A000 = lib_routine1(ubyte value @A) clobbers(X) -> uword @AY + extsub @bank 5 $A000 = lib_routine2(ubyte value @A) clobbers(X) -> uword @AY + extsub @bank 10 $C09F = audio_init() -> bool @A sub start() { diff --git a/examples/cx16/vtui/testvtui.p8 b/examples/cx16/vtui/testvtui.p8 index 8597f6405..2a3c99373 100644 --- a/examples/cx16/vtui/testvtui.p8 +++ b/examples/cx16/vtui/testvtui.p8 @@ -122,28 +122,28 @@ vtui $1000 { ; NOTE: base address $1000 here must be the same as the block's memory address, for obvious reasons! ; The routines below are for VTUI 1.0 - romsub $1000 = initialize() clobbers(A, X, Y) - romsub $1002 = screen_set(ubyte mode @A) clobbers(A, X, Y) - romsub $1005 = set_bank(bool bank1 @Pc) clobbers(A) - romsub $1008 = set_stride(ubyte stride @A) clobbers(A) - romsub $100b = set_decr(bool incrdecr @Pc) clobbers(A) - romsub $100e = clr_scr(ubyte char @A, ubyte colors @X) clobbers(Y) - romsub $1011 = gotoxy(ubyte column @A, ubyte row @Y) - romsub $1014 = plot_char(ubyte char @A, ubyte colors @X) - romsub $1017 = scan_char() -> ubyte @A, ubyte @X - romsub $101a = hline(ubyte char @A, ubyte length @Y, ubyte colors @X) clobbers(A) - romsub $101d = vline(ubyte char @A, ubyte height @Y, ubyte colors @X) clobbers(A) - romsub $1020 = print_str(str txtstring @R0, ubyte length @Y, ubyte colors @X, ubyte convertchars @A) clobbers(A, Y) - romsub $1023 = fill_box(ubyte char @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(A, Y) - romsub $1026 = pet2scr(ubyte char @A) -> ubyte @A - romsub $1029 = scr2pet(ubyte char @A) -> ubyte @A - romsub $102c = border(ubyte mode @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(Y) ; NOTE: mode 6 means 'custom' characters taken from r3 - r6 - romsub $102f = save_rect(ubyte ramtype @A, bool vbank1 @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y) - romsub $1032 = rest_rect(ubyte ramtype @A, bool vbank1 @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y) - romsub $1035 = input_str(uword buffer @R0, ubyte buflen @Y, ubyte colors @X) clobbers (A) -> ubyte @Y ; Y=length of input - romsub $1038 = get_bank() clobbers (A) -> bool @Pc - romsub $103b = get_stride() -> ubyte @A - romsub $103e = get_decr() clobbers (A) -> bool @Pc + extsub $1000 = initialize() clobbers(A, X, Y) + extsub $1002 = screen_set(ubyte mode @A) clobbers(A, X, Y) + extsub $1005 = set_bank(bool bank1 @Pc) clobbers(A) + extsub $1008 = set_stride(ubyte stride @A) clobbers(A) + extsub $100b = set_decr(bool incrdecr @Pc) clobbers(A) + extsub $100e = clr_scr(ubyte char @A, ubyte colors @X) clobbers(Y) + extsub $1011 = gotoxy(ubyte column @A, ubyte row @Y) + extsub $1014 = plot_char(ubyte char @A, ubyte colors @X) + extsub $1017 = scan_char() -> ubyte @A, ubyte @X + extsub $101a = hline(ubyte char @A, ubyte length @Y, ubyte colors @X) clobbers(A) + extsub $101d = vline(ubyte char @A, ubyte height @Y, ubyte colors @X) clobbers(A) + extsub $1020 = print_str(str txtstring @R0, ubyte length @Y, ubyte colors @X, ubyte convertchars @A) clobbers(A, Y) + extsub $1023 = fill_box(ubyte char @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(A, Y) + extsub $1026 = pet2scr(ubyte char @A) -> ubyte @A + extsub $1029 = scr2pet(ubyte char @A) -> ubyte @A + extsub $102c = border(ubyte mode @A, ubyte width @R1, ubyte height @R2, ubyte colors @X) clobbers(Y) ; NOTE: mode 6 means 'custom' characters taken from r3 - r6 + extsub $102f = save_rect(ubyte ramtype @A, bool vbank1 @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y) + extsub $1032 = rest_rect(ubyte ramtype @A, bool vbank1 @Pc, uword address @R0, ubyte width @R1, ubyte height @R2) clobbers(A, X, Y) + extsub $1035 = input_str(uword buffer @R0, ubyte buflen @Y, ubyte colors @X) clobbers (A) -> ubyte @Y ; Y=length of input + extsub $1038 = get_bank() clobbers (A) -> bool @Pc + extsub $103b = get_stride() -> ubyte @A + extsub $103e = get_decr() clobbers (A) -> bool @Pc ; -- helper function to do string length counting for you internally, and turn the convertchars flag into a boolean again asmsub print_str2(str txtstring @R0, ubyte colors @X, bool convertchars @Pc) clobbers(A, Y) { diff --git a/examples/cx16/zsmkit/zsmkit_high.p8 b/examples/cx16/zsmkit/zsmkit_high.p8 index 7140b1b36..9ee184b70 100644 --- a/examples/cx16/zsmkit/zsmkit_high.p8 +++ b/examples/cx16/zsmkit/zsmkit_high.p8 @@ -1,35 +1,35 @@ -; romsubs for zsmkit loaded at $8c00 +; extubs for zsmkit loaded at $8c00 zsmkit { - romsub $8C00 = zsm_init_engine(ubyte bank @A) clobbers(A, X, Y) - romsub $8C03 = zsm_tick(ubyte type @A) clobbers(A, X, Y) + extsub $8C00 = zsm_init_engine(ubyte bank @A) clobbers(A, X, Y) + extsub $8C03 = zsm_tick(ubyte type @A) clobbers(A, X, Y) - romsub $8C06 = zsm_play(ubyte prio @X) clobbers(A, X, Y) - romsub $8C09 = zsm_stop(ubyte prio @X) clobbers(A, X, Y) - romsub $8C0C = zsm_rewind(ubyte prio @X) clobbers(A, X, Y) - romsub $8C0F = zsm_close(ubyte prio @X) clobbers(A, X, Y) - romsub $8C12 = zsm_fill_buffers() clobbers(A, X, Y) - romsub $8C15 = zsm_setlfs(ubyte prio @X, ubyte lfn_sa @A, ubyte device @Y) clobbers(A, X, Y) - romsub $8C18 = zsm_setfile(ubyte prio @X, str filename @AY) clobbers(A, X, Y) - romsub $8C1B = zsm_loadpcm(ubyte prio @X, uword data_ptr @AY) clobbers(X) -> uword @AY - romsub $8C1E = zsm_setmem(ubyte prio @X, uword data_ptr @AY) clobbers(A, X, Y) - romsub $8C21 = zsm_setatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) - romsub $8C24 = zsm_setcb(ubyte prio @X, uword func_ptr @AY) clobbers(A, X, Y) - romsub $8C27 = zsm_clearcb(ubyte prio @X) clobbers(A, X, Y) - romsub $8C2A = zsm_getstate(ubyte prio @X) clobbers(X) -> bool @Pc, bool @Pz, uword @AY - romsub $8C2D = zsm_setrate(ubyte prio @X, uword rate @AY) clobbers(A, X, Y) - romsub $8C30 = zsm_getrate(ubyte prio @X) clobbers() -> uword @AY - romsub $8C33 = zsm_setloop(ubyte prio @X, bool loop @Pc) clobbers(A, X, Y) - romsub $8C36 = zsm_opmatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) - romsub $8C39 = zsm_psgatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) - romsub $8C3C = zsm_pcmatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) - romsub $8C3F = zsm_set_int_rate(ubyte value @A, ubyte frac @Y) clobbers(A, X, Y) + extsub $8C06 = zsm_play(ubyte prio @X) clobbers(A, X, Y) + extsub $8C09 = zsm_stop(ubyte prio @X) clobbers(A, X, Y) + extsub $8C0C = zsm_rewind(ubyte prio @X) clobbers(A, X, Y) + extsub $8C0F = zsm_close(ubyte prio @X) clobbers(A, X, Y) + extsub $8C12 = zsm_fill_buffers() clobbers(A, X, Y) + extsub $8C15 = zsm_setlfs(ubyte prio @X, ubyte lfn_sa @A, ubyte device @Y) clobbers(A, X, Y) + extsub $8C18 = zsm_setfile(ubyte prio @X, str filename @AY) clobbers(A, X, Y) + extsub $8C1B = zsm_loadpcm(ubyte prio @X, uword data_ptr @AY) clobbers(X) -> uword @AY + extsub $8C1E = zsm_setmem(ubyte prio @X, uword data_ptr @AY) clobbers(A, X, Y) + extsub $8C21 = zsm_setatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) + extsub $8C24 = zsm_setcb(ubyte prio @X, uword func_ptr @AY) clobbers(A, X, Y) + extsub $8C27 = zsm_clearcb(ubyte prio @X) clobbers(A, X, Y) + extsub $8C2A = zsm_getstate(ubyte prio @X) clobbers(X) -> bool @Pc, bool @Pz, uword @AY + extsub $8C2D = zsm_setrate(ubyte prio @X, uword rate @AY) clobbers(A, X, Y) + extsub $8C30 = zsm_getrate(ubyte prio @X) clobbers() -> uword @AY + extsub $8C33 = zsm_setloop(ubyte prio @X, bool loop @Pc) clobbers(A, X, Y) + extsub $8C36 = zsm_opmatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) + extsub $8C39 = zsm_psgatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) + extsub $8C3C = zsm_pcmatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) + extsub $8C3F = zsm_set_int_rate(ubyte value @A, ubyte frac @Y) clobbers(A, X, Y) - romsub $8C4B = zcm_setmem(ubyte slot @X, uword data_ptr @AY) clobbers(A) - romsub $8C4E = zcm_play(ubyte slot @X, ubyte volume @A) clobbers(A, X) - romsub $8C51 = zcm_stop() clobbers(A) + extsub $8C4B = zcm_setmem(ubyte slot @X, uword data_ptr @AY) clobbers(A) + extsub $8C4E = zcm_play(ubyte slot @X, ubyte volume @A) clobbers(A, X) + extsub $8C51 = zcm_stop() clobbers(A) - romsub $8C54 = zsmkit_setisr() clobbers(A) - romsub $8C57 = zsmkit_clearisr() clobbers(A) + extsub $8C54 = zsmkit_setisr() clobbers(A) + extsub $8C57 = zsmkit_clearisr() clobbers(A) } diff --git a/examples/cx16/zsmkit/zsmkit_low.p8 b/examples/cx16/zsmkit/zsmkit_low.p8 index 34e5df1ce..8b99c20d1 100644 --- a/examples/cx16/zsmkit/zsmkit_low.p8 +++ b/examples/cx16/zsmkit/zsmkit_low.p8 @@ -1,35 +1,35 @@ -; romsubs for zsmkit loaded at $0830 +; extsubs for zsmkit loaded at $0830 zsmkit { - romsub $0830 = zsm_init_engine(ubyte bank @A) clobbers(A, X, Y) - romsub $0833 = zsm_tick(ubyte type @A) clobbers(A, X, Y) + extsub $0830 = zsm_init_engine(ubyte bank @A) clobbers(A, X, Y) + extsub $0833 = zsm_tick(ubyte type @A) clobbers(A, X, Y) - romsub $0836 = zsm_play(ubyte prio @X) clobbers(A, X, Y) - romsub $0839 = zsm_stop(ubyte prio @X) clobbers(A, X, Y) - romsub $083c = zsm_rewind(ubyte prio @X) clobbers(A, X, Y) - romsub $083f = zsm_close(ubyte prio @X) clobbers(A, X, Y) - romsub $0842 = zsm_fill_buffers() clobbers(A, X, Y) - romsub $0845 = zsm_setlfs(ubyte prio @X, ubyte lfn_sa @A, ubyte device @Y) clobbers(A, X, Y) - romsub $0848 = zsm_setfile(ubyte prio @X, str filename @AY) clobbers(A, X, Y) - romsub $084b = zsm_loadpcm(ubyte prio @X, uword data_ptr @AY) clobbers(X) -> uword @AY - romsub $084e = zsm_setmem(ubyte prio @X, uword data_ptr @AY) clobbers(A, X, Y) - romsub $0851 = zsm_setatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) - romsub $0854 = zsm_setcb(ubyte prio @X, uword func_ptr @AY) clobbers(A, X, Y) - romsub $0857 = zsm_clearcb(ubyte prio @X) clobbers(A, X, Y) - romsub $085A = zsm_getstate(ubyte prio @X) clobbers(X) -> bool @Pc, bool @Pz, uword @AY - romsub $085D = zsm_setrate(ubyte prio @X, uword rate @AY) clobbers(A, X, Y) - romsub $0860 = zsm_getrate(ubyte prio @X) clobbers() -> uword @AY - romsub $0863 = zsm_setloop(ubyte prio @X, bool loop @Pc) clobbers(A, X, Y) - romsub $0866 = zsm_opmatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) - romsub $0869 = zsm_psgatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) - romsub $086C = zsm_pcmatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) - romsub $086F = zsm_set_int_rate(ubyte value @A, ubyte frac @Y) clobbers(A, X, Y) + extsub $0836 = zsm_play(ubyte prio @X) clobbers(A, X, Y) + extsub $0839 = zsm_stop(ubyte prio @X) clobbers(A, X, Y) + extsub $083c = zsm_rewind(ubyte prio @X) clobbers(A, X, Y) + extsub $083f = zsm_close(ubyte prio @X) clobbers(A, X, Y) + extsub $0842 = zsm_fill_buffers() clobbers(A, X, Y) + extsub $0845 = zsm_setlfs(ubyte prio @X, ubyte lfn_sa @A, ubyte device @Y) clobbers(A, X, Y) + extsub $0848 = zsm_setfile(ubyte prio @X, str filename @AY) clobbers(A, X, Y) + extsub $084b = zsm_loadpcm(ubyte prio @X, uword data_ptr @AY) clobbers(X) -> uword @AY + extsub $084e = zsm_setmem(ubyte prio @X, uword data_ptr @AY) clobbers(A, X, Y) + extsub $0851 = zsm_setatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) + extsub $0854 = zsm_setcb(ubyte prio @X, uword func_ptr @AY) clobbers(A, X, Y) + extsub $0857 = zsm_clearcb(ubyte prio @X) clobbers(A, X, Y) + extsub $085A = zsm_getstate(ubyte prio @X) clobbers(X) -> bool @Pc, bool @Pz, uword @AY + extsub $085D = zsm_setrate(ubyte prio @X, uword rate @AY) clobbers(A, X, Y) + extsub $0860 = zsm_getrate(ubyte prio @X) clobbers() -> uword @AY + extsub $0863 = zsm_setloop(ubyte prio @X, bool loop @Pc) clobbers(A, X, Y) + extsub $0866 = zsm_opmatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) + extsub $0869 = zsm_psgatten(ubyte prio @X, ubyte channel @Y, ubyte value @A) clobbers(A, X, Y) + extsub $086C = zsm_pcmatten(ubyte prio @X, ubyte value @A) clobbers(A, X, Y) + extsub $086F = zsm_set_int_rate(ubyte value @A, ubyte frac @Y) clobbers(A, X, Y) - romsub $087B = zcm_setmem(ubyte slot @X, uword data_ptr @AY) clobbers(A) - romsub $087E = zcm_play(ubyte slot @X, ubyte volume @A) clobbers(A, X) - romsub $0881 = zcm_stop() clobbers(A) + extsub $087B = zcm_setmem(ubyte slot @X, uword data_ptr @AY) clobbers(A) + extsub $087E = zcm_play(ubyte slot @X, ubyte volume @A) clobbers(A, X) + extsub $0881 = zcm_stop() clobbers(A) - romsub $0884 = zsmkit_setisr() clobbers(A) - romsub $0887 = zsmkit_clearisr() clobbers(A) + extsub $0884 = zsmkit_setisr() clobbers(A) + extsub $0887 = zsmkit_clearisr() clobbers(A) } diff --git a/examples/test.p8 b/examples/test.p8 index 9bcc27d11..44682cbce 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,7 +5,7 @@ main { ubyte bank - romsub @bank bank $a000 = routine_in_hiram(uword arg @AY) -> uword @AY + extsub @bank bank $a000 = routine_in_hiram(uword arg @AY) -> uword @AY sub start() { ; copy the routine into hiram bank 8 diff --git a/parser/antlr/Prog8ANTLR.g4 b/parser/antlr/Prog8ANTLR.g4 index aac97d63c..0d6c42cee 100644 --- a/parser/antlr/Prog8ANTLR.g4 +++ b/parser/antlr/Prog8ANTLR.g4 @@ -136,7 +136,7 @@ variabledeclaration : subroutinedeclaration : subroutine | asmsubroutine - | romsubroutine + | extsubroutine ; alias: 'alias' identifier '=' scoped_identifier ; @@ -293,8 +293,8 @@ asmsubroutine : inline? 'asmsub' asmsub_decl EOL? (statement_block EOL?) ; -romsubroutine : - 'romsub' ('@bank' (constbank=integerliteral | varbank=scoped_identifier))? address=integerliteral '=' asmsub_decl +extsubroutine : + ('romsub' | 'extsub') ('@bank' (constbank=integerliteral | varbank=scoped_identifier))? address=integerliteral '=' asmsub_decl ; asmsub_decl : identifier '(' asmsub_params? ')' asmsub_clobbers? asmsub_returns? ; diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml index 432d67853..6a14834c2 100644 --- a/syntax-files/IDEA/Prog8.xml +++ b/syntax-files/IDEA/Prog8.xml @@ -11,7 +11,7 @@