mirror of
https://github.com/irmen/prog8.git
synced 2024-10-21 04:24:05 +00:00
added 'callfar' builtin function (for cx16 target) that uses jsrfar to call a routine in banked RAM
This commit is contained in:
parent
bf1b2066b6
commit
1170aed026
@ -518,11 +518,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
|
|
||||||
override fun visit(addressOf: AddressOf) {
|
override fun visit(addressOf: AddressOf) {
|
||||||
val variable=addressOf.identifier.targetVarDecl(program)
|
val variable=addressOf.identifier.targetVarDecl(program)
|
||||||
if(variable!=null
|
if(variable!=null && variable.type==VarDeclType.CONST)
|
||||||
&& variable.datatype !in ArrayDatatypes
|
|
||||||
&& variable.type!=VarDeclType.MEMORY
|
|
||||||
&& variable.struct == null
|
|
||||||
&& variable.datatype != DataType.STR && variable.datatype!=DataType.STRUCT)
|
|
||||||
errors.err("invalid pointer-of operand type", addressOf.position)
|
errors.err("invalid pointer-of operand type", addressOf.position)
|
||||||
super.visit(addressOf)
|
super.visit(addressOf)
|
||||||
}
|
}
|
||||||
|
@ -144,6 +144,7 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FSignature("rndf" , false, emptyList(), DataType.FLOAT),
|
FSignature("rndf" , false, emptyList(), DataType.FLOAT),
|
||||||
FSignature("memory" , true, listOf(FParam("name", setOf(DataType.STR)), FParam("size", setOf(DataType.UWORD))), DataType.UWORD),
|
FSignature("memory" , true, listOf(FParam("name", setOf(DataType.STR)), FParam("size", setOf(DataType.UWORD))), DataType.UWORD),
|
||||||
FSignature("swap" , false, listOf(FParam("first", NumericDatatypes), FParam("second", NumericDatatypes)), null),
|
FSignature("swap" , false, listOf(FParam("first", NumericDatatypes), FParam("second", NumericDatatypes)), null),
|
||||||
|
FSignature("callfar" , false, listOf(FParam("bank", setOf(DataType.UBYTE)), FParam("address", setOf(DataType.UWORD)), FParam("arg", setOf(DataType.UWORD))), null),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import prog8.ast.toHex
|
|||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.functions.FSignature
|
import prog8.compiler.functions.FSignature
|
||||||
import prog8.compiler.target.CpuType
|
import prog8.compiler.target.CpuType
|
||||||
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.*
|
import prog8.compiler.target.cpu6502.codegen.assignment.*
|
||||||
import prog8.compiler.target.subroutineFloatEvalResultVar2
|
import prog8.compiler.target.subroutineFloatEvalResultVar2
|
||||||
|
|
||||||
@ -65,10 +66,56 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
"pokew" -> funcPokeW(fcall)
|
"pokew" -> funcPokeW(fcall)
|
||||||
"poke" -> throw AssemblyError("poke() should have been replaced by @()")
|
"poke" -> throw AssemblyError("poke() should have been replaced by @()")
|
||||||
"cmp" -> funcCmp(fcall)
|
"cmp" -> funcCmp(fcall)
|
||||||
|
"callfar" -> funcCallFar(fcall)
|
||||||
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
|
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcCallFar(fcall: IFunctionCall) {
|
||||||
|
if(asmgen.options.compTarget !is Cx16Target)
|
||||||
|
throw AssemblyError("callfar only works on cx16 target at this time")
|
||||||
|
|
||||||
|
val bank = fcall.args[0].constValue(program)?.number?.toInt()
|
||||||
|
val address = fcall.args[1].constValue(program)?.number?.toInt()
|
||||||
|
if(bank==null || address==null)
|
||||||
|
throw AssemblyError("callfar (jsrfar) requires constant arguments")
|
||||||
|
|
||||||
|
if(address !in 0xa000..0xbfff)
|
||||||
|
throw AssemblyError("callfar done on address outside of cx16 banked ram")
|
||||||
|
if(bank==0)
|
||||||
|
throw AssemblyError("callfar done on bank 0 which is reserved for the kernal")
|
||||||
|
|
||||||
|
val argAddrArg = fcall.args[2]
|
||||||
|
if(argAddrArg.constValue(program)?.number == 0) {
|
||||||
|
asmgen.out("""
|
||||||
|
jsr cx16.jsrfar
|
||||||
|
.word ${address.toHex()}
|
||||||
|
.byte ${bank.toHex()}""")
|
||||||
|
} else {
|
||||||
|
when(argAddrArg) {
|
||||||
|
is AddressOf -> {
|
||||||
|
if(argAddrArg.identifier.targetVarDecl(program)?.datatype != 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 NumericLiteralValue -> {
|
||||||
|
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 funcCmp(fcall: IFunctionCall) {
|
private fun funcCmp(fcall: IFunctionCall) {
|
||||||
val arg1 = fcall.args[0]
|
val arg1 = fcall.args[0]
|
||||||
val arg2 = fcall.args[1]
|
val arg2 = fcall.args[1]
|
||||||
|
@ -897,6 +897,15 @@ memory(name, size)
|
|||||||
The return value is just a simple uword address so it cannot be used as an array in your program.
|
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.
|
You can only treat it as a pointer or use it in inline assembly.
|
||||||
|
|
||||||
|
callfar(bank, address, argumentaddress) ; NOTE: specific to cx16 compiler target for now
|
||||||
|
Calls an assembly routine in another ram-bank on the CommanderX16 (using the ``jsrfar`` routine)
|
||||||
|
The banked RAM is located in the address range $A000-$BFFF (8 kilobyte).
|
||||||
|
Notice that bank $00 is used by the Kernal and should not be used by user code.
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
Library routines
|
Library routines
|
||||||
----------------
|
----------------
|
||||||
|
@ -1,23 +1,30 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import string
|
%zeropage basicsafe
|
||||||
%zeropage dontuse
|
|
||||||
%import test_stack
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
uword zz = $4000
|
ubyte uu
|
||||||
|
cx16.rambank(1)
|
||||||
|
sys.memcopy(&banked.double, $a000, 100)
|
||||||
|
cx16.rambank(0)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
txt.print("hello")
|
uword ww
|
||||||
|
uu = 99
|
||||||
txt.print_uwhex(peekw(zz+2), true)
|
txt.print_ub(uu)
|
||||||
|
txt.nl()
|
||||||
@(zz+2) = lsb($ea31)
|
callfar($01, $a000, &uu)
|
||||||
@(zz+3) = msb($ea31)
|
txt.print_ub(uu)
|
||||||
pokew(zz+2, $ea32) ; TODO fix crash
|
}
|
||||||
zz = peekw(zz+2) ; TODO fix crash with asm
|
|
||||||
txt.print_uwhex(zz, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
banked {
|
||||||
|
asmsub double(ubyte number @A) -> ubyte @A {
|
||||||
|
%asm {{
|
||||||
|
asl a
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<keywords keywords="&;->;@;\$;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" />
|
<keywords keywords="&;->;@;\$;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;%launcher;%option;%output;%target;%zeropage;%zpreserved" />
|
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%launcher;%option;%output;%target;%zeropage;%zpreserved" />
|
||||||
<keywords3 keywords="byte;const;float;str;struct;ubyte;uword;void;word;zp" />
|
<keywords3 keywords="byte;const;float;str;struct;ubyte;uword;void;word;zp" />
|
||||||
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;ceil;cmp;cos;cos16;cos16u;cos8;cos8u;deg;fastrnd8;floor;len;ln;log2;lsb;lsl;lsr;max;memory;min;mkword;msb;offsetof;peek;peekw;poke;pokew;rad;reverse;rnd;rndf;rndw;rol;rol2;ror;ror2;round;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;sum;swap;tan" />
|
<keywords4 keywords="abs;acos;all;any;asin;atan;avg;callfar;ceil;cmp;cos;cos16;cos16u;cos8;cos8u;deg;fastrnd8;floor;len;ln;log2;lsb;lsl;lsr;max;memory;min;mkword;msb;offsetof;peek;peekw;poke;pokew;rad;reverse;rnd;rndf;rndw;rol;rol2;ror;ror2;round;sgn;sin;sin16;sin16u;sin8;sin8u;sizeof;sort;sqrt;sqrt16;sum;swap;tan" />
|
||||||
</highlighting>
|
</highlighting>
|
||||||
<extensionMap>
|
<extensionMap>
|
||||||
<mapping ext="p8" />
|
<mapping ext="p8" />
|
||||||
|
@ -17,7 +17,7 @@ syn keyword prog8BuiltInFunc any all len max min reverse sum sort
|
|||||||
" Miscellaneous functions
|
" Miscellaneous functions
|
||||||
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew rnd rndw
|
syn keyword prog8BuiltInFunc cmp lsb msb mkword peek peekw poke pokew rnd rndw
|
||||||
syn keyword prog8BuiltInFunc rndf fastrnd8 rol rol2 ror ror2 sizeof offsetof
|
syn keyword prog8BuiltInFunc rndf fastrnd8 rol rol2 ror ror2 sizeof offsetof
|
||||||
syn keyword prog8BuiltInFunc swap memory
|
syn keyword prog8BuiltInFunc swap memory callfar
|
||||||
|
|
||||||
|
|
||||||
" c64/floats.p8
|
" c64/floats.p8
|
||||||
|
Loading…
Reference in New Issue
Block a user