remove cx16.callrom() just use callfar

This commit is contained in:
Irmen de Jong 2023-02-23 22:01:24 +01:00
parent 4641ac46e7
commit d282a2d846
8 changed files with 21 additions and 130 deletions

View File

@ -104,8 +104,7 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
"rrestore" to FSignature(false, emptyList(), null),
"rrestorex" to FSignature(false, emptyList(), null),
"memory" to FSignature(true, listOf(FParam("name", arrayOf(DataType.STR)), FParam("size", arrayOf(DataType.UWORD)), FParam("alignment", arrayOf(DataType.UWORD))), DataType.UWORD),
"callfar" to FSignature(false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
"callrom" to FSignature(false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
"callfar" to FSignature(false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), DataType.UWORD),
)
val InplaceModifyingBuiltinFunctions = setOf("rol", "ror", "rol2", "ror2", "sort", "reverse")

View File

@ -70,7 +70,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
"rrestorex" -> funcRrestoreX()
"cmp" -> funcCmp(fcall)
"callfar" -> funcCallFar(fcall)
"callrom" -> funcCallRom(fcall)
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
}
@ -132,101 +131,16 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
if(asmgen.options.compTarget.name != "cx16")
throw AssemblyError("callfar only works on cx16 target at this time")
val bank = fcall.args[0].asConstInteger()
val address = fcall.args[1].asConstInteger() ?: 0
val argAddrArg = fcall.args[2]
if(bank==null)
throw AssemblyError("callfar (jsrfar) bank has to be a constant")
if(fcall.args[1] !is PtNumber) {
assignAsmGen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.AY, false)
asmgen.out(" sta (+)+0 | sty (+)+1 ; store jsrfar address word")
}
if(argAddrArg.asConstInteger() == 0) {
asmgen.out("""
jsr cx16.jsrfar
+ .word ${address.toHex()}
.byte ${bank.toHex()}""")
} else {
when(argAddrArg) {
is PtAddressOf -> {
if(argAddrArg.identifier.type != DataType.UBYTE)
throw AssemblyError("callfar done with 'arg' pointer to variable that's not UBYTE")
asmgen.out("""
lda ${asmgen.asmVariableName(argAddrArg.identifier)}
jsr cx16.jsrfar
+ .word ${address.toHex()}
.byte ${bank.toHex()}
sta ${asmgen.asmVariableName(argAddrArg.identifier)}""")
}
is PtNumber -> {
asmgen.out("""
lda ${argAddrArg.number.toHex()}
jsr cx16.jsrfar
+ .word ${address.toHex()}
.byte ${bank.toHex()}
sta ${argAddrArg.number.toHex()}""")
}
else -> throw AssemblyError("callfar only accepts pointer-of a (ubyte) variable or constant memory address for the 'arg' parameter")
}
}
}
private fun funcCallRom(fcall: PtBuiltinFunctionCall) {
if(asmgen.options.compTarget.name != "cx16")
throw AssemblyError("callrom only works on cx16 target at this time")
val bank = fcall.args[0].asConstInteger()
val address = fcall.args[1].asConstInteger()
if(bank==null || address==null)
throw AssemblyError("callrom requires constant arguments")
if(address !in 0xc000..0xffff)
throw AssemblyError("callrom done on address outside of cx16 banked rom")
if(bank>=32)
throw AssemblyError("callrom bank must be <32")
val argAddrArg = fcall.args[2]
if(argAddrArg.asConstInteger() == 0) {
asmgen.out("""
lda $01
pha
lda #${bank}
sta $01
jsr ${address.toHex()}
pla
sta $01""")
} else {
when(argAddrArg) {
is PtAddressOf -> {
if(argAddrArg.identifier.type != DataType.UBYTE)
throw AssemblyError("callrom done with 'arg' pointer to variable that's not UBYTE")
asmgen.out("""
lda $01
pha
lda #${bank}
sta $01
lda ${asmgen.asmVariableName(argAddrArg.identifier)}
jsr ${address.toHex()}
sta ${asmgen.asmVariableName(argAddrArg.identifier)}
pla
sta $01""")
}
is PtNumber -> {
asmgen.out("""
lda $01
pha
lda #${bank}
sta $01
lda ${argAddrArg.number.toHex()}
jsr ${address.toHex()}
sta ${argAddrArg.number.toHex()}
pla
sta $01""")
}
else -> throw AssemblyError("callrom only accepts pointer-of a (ubyte) variable or constant memory address for the 'arg' parameter")
}
}
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.A) // bank
asmgen.out(" sta (++)+0")
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.AY) // jump address
asmgen.out(" sta (+)+0 | sty (+)+1")
asmgen.assignExpressionToRegister(fcall.args[2], RegisterOrPair.AY) // uword argument
asmgen.out("""
jsr cx16.jsrfar
+ .word 0
+ .byte 0""")
// note that by convention the values in A+Y registers are now the return value of the call.
}
private fun funcCmp(fcall: PtBuiltinFunctionCall) {

View File

@ -26,7 +26,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"rrestore",
"rrestorex" -> emptyList() // vm doesn't have registers to save/restore
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
"callrom" -> throw AssemblyError("callrom() is for cx16 target only")
"msb" -> funcMsb(call, resultRegister)
"lsb" -> funcLsb(call, resultRegister)
"memory" -> funcMemory(call, resultRegister)

View File

@ -903,31 +903,12 @@ memory(name, size, alignment)
The return value is just a simple uword address so it cannot be used as an array in your program.
You can only treat it as a pointer or use it in inline assembly.
callfar(bank, address, argumentaddress) ; NOTE: specific to cx16 target for now
Calls an assembly routine in another ram-bank on the Commander X16 (using the ``jsrfar`` routine)
The banked RAM is located in the address range $A000-$BFFF (8 kilobyte), but you can specify
any address in system ram (why this can be useful is explained at the end of this paragraph)
The third argument can be used to designate the memory address
of an argument for the routine; it will be loaded into the A register and will
receive the result value returned by the routine in the A register. If you leave this at zero,
no argument passing will be done.
If the routine requires different arguments or return values, ``callfar`` cannot be used
and you'll have to set up a call to ``jsrfar`` yourself to process this.
Note: the address can be a variable or other expression, which allows you to use ``callfar`` with bank 0 to do an indirect JSR to a subroutine
whose address can vary (jump table, etc. ``goto`` can do an indirect JMP to a variable address): ``callfar(0, &routine, &argument)``
This is not very efficient though, so maybe you should write a small piece of inline assembly for this instead.
callrom(bank, address, argumentaddress) ; NOTE: specific to cx16 target for now
Calls an assembly routine in another rom-bank on the Commander X16
The banked ROM is located in the address range $C000-$FFFF (16 kilobyte).
There are 32 banks (0 to 31).
The third argument can be used to designate the memory address
of an argument for the routine; it will be loaded into the A register and will
receive the result value returned by the routine in the A register. If you leave this at zero,
no argument passing will be done.
If the routine requires different arguments or return values, ``callrom`` cannot be used
and you'll have to set up a call in assembly code yourself that handles the banking and
argument/returnvalues.
callfar(bank, address, argumentword) -> uword ; NOTE: specific to cx16 target for now
Calls an assembly routine in another bank on the Commander X16 (using its ``jsrfar`` routine)
Be aware that ram OR rom bank may be changed depending on the address it jumps to!
The argumentword will be loaded into the A+Y registers before calling the routine.
The uword value that the routine returns in the A+Y registers, will be returned.
NOTE: this routine is very inefficient so don't use it to call often.
syscall(callnr), syscall1(callnr, arg), syscall2(callnr, arg1, arg2), syscall3(callnr, arg1, arg2, arg3)
Functions for doing a system call on targets that support this. Currently no actual target

View File

@ -787,8 +787,6 @@ to another piece of code that eventually returns).
If you jump to an address variable (uword), it is doing an 'indirect' jump: the jump will be done
to the address that's currently in the variable.
Note: to do an indirect *JSR* to a routine with a varying address, you can use the ``callfar`` builtin function
(which is not very efficient) or you have to write a small piece of inline assembly.
if statements

View File

@ -14,10 +14,10 @@
<keywords keywords="&amp;;-&gt;;@;\$;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%ir;%launcher;%option;%output;%zeropage;%zpreserved;iso:;petscii:;sc:" />
<keywords3 keywords="@requirezp;@shared;@zp;bool;byte;const;float;str;ubyte;uword;void;word" />
<keywords4 keywords="abs;all;any;callfar;callrom;cmp;len;lsb;memory;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt16;swap;|&gt;" />
<keywords4 keywords="abs;all;any;callfar;cmp;len;lsb;memory;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt16;swap;|&gt;" />
</highlighting>
<extensionMap>
<mapping ext="p8" />
<mapping ext="prog8" />
</extensionMap>
</filetype>
</filetype>

View File

@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared requirezp</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%import&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved</Keywords>
<Keywords name="Keywords3">inline sub asmsub romsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat&#x000D;&#x000A;break return goto</Keywords>
<Keywords name="Keywords4">abs all any callfar callrom cmp len lsb lsl lsr memory mkword msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrt16 swap</Keywords>
<Keywords name="Keywords4">abs all any callfar cmp len lsb lsl lsr memory mkword msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrt16 swap</Keywords>
<Keywords name="Keywords5">true false&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords>

View File

@ -15,7 +15,7 @@ syn keyword prog8BuiltInFunc any all len reverse sort
" Miscellaneous functions
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex
syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof
syn keyword prog8BuiltInFunc swap memory callfar callrom
syn keyword prog8BuiltInFunc swap memory callfar
" c64/floats.p8