romsub keyword is now extsub

This commit is contained in:
Irmen de Jong 2024-11-06 22:14:53 +01:00
parent c702c4a6df
commit 9864abd393
44 changed files with 501 additions and 504 deletions

View File

@ -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 -> {

View File

@ -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")
}
}
}

View File

@ -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}

View File

@ -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

View File

@ -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()

View File

@ -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
}

View File

@ -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: ----

View File

@ -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() {

View File

@ -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) {

View File

@ -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 {

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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() {

View File

@ -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 {

View File

@ -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() {

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -5,6 +5,6 @@ main {
}
stuff $1000 {
romsub $1000 = do_nothing()
extsub $1000 = do_nothing()
%asmbinary "do_nothing1.bin", 0
}

View File

@ -5,6 +5,6 @@ main {
}
stuff $1000 {
romsub $1000 = do_nothing()
extsub $1000 = do_nothing()
%asmbinary "subFolder/do_nothing2.bin", 0
}

View File

@ -5,6 +5,6 @@ main {
}
stuff $1000 {
romsub $1000 = do_nothing()
extsub $1000 = do_nothing()
%asmbinary "i_do_not_exist.bin", 0
}

View File

@ -5,6 +5,6 @@ main {
}
stuff $1000 {
romsub $1000 = do_nothing()
extsub $1000 = do_nothing()
%asmbinary "subFolder", 0
}

View File

@ -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} (")

View File

@ -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()

View File

@ -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.

View File

@ -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

View File

@ -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::

View File

@ -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 <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 <https://github.com/irmen/prog8/tree/master/examples/cx16/banking>`_ .
of the extsub with bank support, check out the `bank example code <https://github.com/irmen/prog8/tree/master/examples/cx16/banking>`_ .
Notice that the symbol for this routine in the assembly source code will still be defined as usual.

View File

@ -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?

View File

@ -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() {