mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 04:29:36 +00:00
call
now returns a word value
This commit is contained in:
parent
6cd392909c
commit
ad9eaeafeb
@ -133,7 +133,7 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
|||||||
"rrestore" to FSignature(false, emptyList(), null),
|
"rrestore" 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),
|
"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))), DataType.UWORD),
|
"callfar" to FSignature(false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), DataType.UWORD),
|
||||||
"call" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD))), null),
|
"call" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD))), DataType.UWORD),
|
||||||
)
|
)
|
||||||
|
|
||||||
val InplaceModifyingBuiltinFunctions = setOf("setlsb", "setmsb", "rol", "ror", "rol2", "ror2", "sort", "reverse")
|
val InplaceModifyingBuiltinFunctions = setOf("setlsb", "setmsb", "rol", "ror", "rol2", "ror2", "sort", "reverse")
|
||||||
|
@ -206,6 +206,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
sty (+)+2
|
sty (+)+2
|
||||||
+ jsr 0 ; modified""")
|
+ jsr 0 ; modified""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// note: the routine can return a word value (in AY)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
private fun funcCallFar(fcall: PtBuiltinFunctionCall, resultRegister: RegisterOrPair?) {
|
||||||
|
@ -77,7 +77,10 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
val addressTr = exprGen.translateExpression(call.args[0])
|
val addressTr = exprGen.translateExpression(call.args[0])
|
||||||
addToResult(result, addressTr, addressTr.resultReg, -1)
|
addToResult(result, addressTr, addressTr.resultReg, -1)
|
||||||
addInstr(result, IRInstruction(Opcode.CALLI, reg1 = addressTr.resultReg), null)
|
addInstr(result, IRInstruction(Opcode.CALLI, reg1 = addressTr.resultReg), null)
|
||||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
if(call.void)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||||
|
else
|
||||||
|
return ExpressionCodeResult(result, IRDataType.WORD, codeGen.registers.nextFree(), -1) // TODO actually the result is returned in CPU registers AY...
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcCallfar(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcCallfar(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
|
@ -64,7 +64,7 @@ verafx {
|
|||||||
|
|
||||||
sub copy(ubyte srcbank, uword srcaddr, ubyte tgtbank, uword tgtaddr, uword num_longwords) {
|
sub copy(ubyte srcbank, uword srcaddr, ubyte tgtbank, uword tgtaddr, uword num_longwords) {
|
||||||
; use cached 4-byte writes to quickly copy a portion of the video memory to somewhere else
|
; use cached 4-byte writes to quickly copy a portion of the video memory to somewhere else
|
||||||
; this routine is around 40-50% faster as a plain byte-by-byte copy
|
; this routine is about 50% faster as a plain byte-by-byte copy
|
||||||
cx16.VERA_CTRL = 1
|
cx16.VERA_CTRL = 1
|
||||||
cx16.VERA_ADDR_H = srcbank | %00010000 ; source: 1-byte increment
|
cx16.VERA_ADDR_H = srcbank | %00010000 ; source: 1-byte increment
|
||||||
cx16.VERA_ADDR_M = msb(srcaddr)
|
cx16.VERA_ADDR_M = msb(srcaddr)
|
||||||
|
@ -88,18 +88,17 @@ main {
|
|||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword func = 12345
|
uword func = 12345
|
||||||
call(func) ; ok
|
void call(func) ; ok
|
||||||
call(12345) ; ok
|
void call(12345) ; ok
|
||||||
cx16.r0 = call(func) ; error
|
cx16.r0 = call(func) ; ok
|
||||||
call(&start) ; error
|
void call(&start) ; error
|
||||||
call(start) ; error
|
void call(start) ; error
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
compileText(Cx16Target(), false, src, errors, false) shouldBe null
|
compileText(Cx16Target(), false, src, errors, false) shouldBe null
|
||||||
errors.errors.size shouldBe 3
|
errors.errors.size shouldBe 2
|
||||||
errors.errors[0] shouldContain ":7:19: assignment right hand side doesn't result in a value"
|
errors.errors[0] shouldContain "can't call this indirectly"
|
||||||
errors.errors[1] shouldContain "can't call this indirectly"
|
errors.errors[1] shouldContain "can't call this indirectly"
|
||||||
errors.errors[2] shouldContain "can't call this indirectly"
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -628,7 +628,7 @@ the emulators already support it).
|
|||||||
``copy``
|
``copy``
|
||||||
Very quickly copy a portion of the video memory to somewhere else in vram (4 bytes at a time)
|
Very quickly copy a portion of the video memory to somewhere else in vram (4 bytes at a time)
|
||||||
Sometimes this is also called "blitting".
|
Sometimes this is also called "blitting".
|
||||||
This routine is around 40-50% faster as a regular byte-by-byte copy.
|
This routine is about 50% faster as a regular byte-by-byte copy.
|
||||||
|
|
||||||
``transparency``
|
``transparency``
|
||||||
Enable or disable transparent writes (color 0 will be transparent if enabled).
|
Enable or disable transparent writes (color 0 will be transparent if enabled).
|
||||||
|
@ -966,12 +966,13 @@ memory (name, size, alignment)
|
|||||||
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.
|
||||||
|
|
||||||
call (address)
|
call (address) -> uword
|
||||||
Calls a subroutine given by its memory address. You cannot pass arguments and result values
|
Calls a subroutine given by its memory address. You cannot pass arguments directly,
|
||||||
directly, although it is ofcourse possible to do this via the global ``cx16.r0...`` registers for example.
|
although it is ofcourse possible to do this via the global ``cx16.r0...`` registers for example.
|
||||||
|
It is assumed the subroutine returns a word value (in AY), if it does not, just add void to the call to ignore the result value.
|
||||||
This function effectively creates an "indirect JSR" if you use it on a ``uword`` pointer variable.
|
This function effectively creates an "indirect JSR" if you use it on a ``uword`` pointer variable.
|
||||||
But because it doesn't handle bank switching
|
But because it doesn't handle bank switching etcetera by itself,
|
||||||
etcetera by itself, it is a lot faster than ``callfar``. And it works on other systems than just the Commander X16.
|
it is a lot faster than ``callfar``. And it works on other systems than just the Commander X16.
|
||||||
|
|
||||||
callfar (bank, address, argumentword) -> uword ; NOTE: specific to cx16 target for now
|
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)
|
Calls an assembly routine in another bank on the Commander X16 (using its ``JSRFAR`` routine)
|
||||||
|
@ -27,6 +27,7 @@ Compiler:
|
|||||||
- (need separate step in codegen and IR to write the "golden" variables)
|
- (need separate step in codegen and IR to write the "golden" variables)
|
||||||
|
|
||||||
- do we need (array)variable alignment tag instead of block alignment tag? You want to align the data, not the code in the block?
|
- do we need (array)variable alignment tag instead of block alignment tag? You want to align the data, not the code in the block?
|
||||||
|
- ir: proper code gen for the CALLI instruction and that it (optionally) returns a word value that needs to be assigned to a reg
|
||||||
- ir: getting it in shape for code generation
|
- ir: getting it in shape for code generation
|
||||||
- ir: related to the one above: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
|
- ir: related to the one above: block alignment doesn't translate well to variables in the block (the actual stuff that needs to be aligned in memory) but: need variable alignment tag instead of block alignment tag, really
|
||||||
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
- ir: idea: (but LLVM IR simply keeps the variables, so not a good idea then?...): replace all scalar variables by an allocated register. Keep a table of the variable to register mapping (including the datatype)
|
||||||
|
@ -1,51 +1,18 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import verafx
|
%zeropage basicsafe
|
||||||
%import diskio
|
|
||||||
%zeropage dontuse
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.uppercase()
|
uword function = &test
|
||||||
txt.print("abcdefghijklmnopqrstuvwxyz\n")
|
uword @shared derp = call(function)
|
||||||
txt.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ\n")
|
txt.print_uw(derp)
|
||||||
txt.print("0123456789!@#$%^&*()-=[]<>\n")
|
|
||||||
|
|
||||||
void diskio.vload_raw("fantasy.pf", 0, $4000)
|
|
||||||
; for cx16.r0 in $4000 to $4000+256*$0008 {
|
|
||||||
; cx16.vpoke(0, cx16.r0, %10101010)
|
|
||||||
; }
|
|
||||||
|
|
||||||
cbm.SETTIM(0,0,0)
|
|
||||||
repeat 1000 {
|
|
||||||
slowcopy(0, $4000, 1, $f000, 8*256/4)
|
|
||||||
}
|
|
||||||
txt.print("\nslow copy time: ")
|
|
||||||
txt.print_uw(cbm.RDTIM16())
|
|
||||||
txt.nl()
|
txt.nl()
|
||||||
sys.wait(60)
|
void call(function)
|
||||||
txt.lowercase()
|
|
||||||
sys.wait(120)
|
|
||||||
|
|
||||||
cbm.SETTIM(0,0,0)
|
|
||||||
repeat 1000 {
|
|
||||||
verafx.copy(0, $4000, 1, $f000, 8*256/4)
|
|
||||||
}
|
|
||||||
txt.print("verafx copy time: ")
|
|
||||||
txt.print_uw(cbm.RDTIM16())
|
|
||||||
txt.nl()
|
|
||||||
sys.wait(60)
|
|
||||||
; txt.uppercase()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub slowcopy(ubyte srcbank, uword srcaddr, ubyte tgtbank, uword tgtaddr, uword num_longwords) {
|
sub test() -> uword {
|
||||||
cx16.vaddr(srcbank, srcaddr, 0, 1)
|
txt.print("test\n")
|
||||||
cx16.vaddr(tgtbank, tgtaddr, 1, 1)
|
cx16.r0++
|
||||||
repeat num_longwords {
|
return 999
|
||||||
cx16.VERA_DATA1=cx16.VERA_DATA0
|
|
||||||
cx16.VERA_DATA1=cx16.VERA_DATA0
|
|
||||||
cx16.VERA_DATA1=cx16.VERA_DATA0
|
|
||||||
cx16.VERA_DATA1=cx16.VERA_DATA0
|
|
||||||
}
|
|
||||||
cx16.VERA_CTRL = 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user