mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
remove syscall() builtin functions
vm code can do this via inline assembly
This commit is contained in:
parent
0ee790969d
commit
b32641db87
@ -119,7 +119,6 @@ internal class BuiltinFunctionsAsmGen(private val program: Program,
|
|||||||
"cmp" -> funcCmp(fcall)
|
"cmp" -> funcCmp(fcall)
|
||||||
"callfar" -> funcCallFar(fcall)
|
"callfar" -> funcCallFar(fcall)
|
||||||
"callrom" -> funcCallRom(fcall)
|
"callrom" -> funcCallRom(fcall)
|
||||||
"syscall", "syscall1", "syscall2", "syscall3", "syscall1fp" -> throw AssemblyError("6502 assembly target doesn't use syscall function interface")
|
|
||||||
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
|
else -> throw AssemblyError("missing asmgen for builtin func ${func.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import prog8.code.ast.*
|
|||||||
import prog8.code.core.ArrayToElementTypes
|
import prog8.code.core.ArrayToElementTypes
|
||||||
import prog8.code.core.AssemblyError
|
import prog8.code.core.AssemblyError
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.WordDatatypes
|
|
||||||
import prog8.vm.Opcode
|
import prog8.vm.Opcode
|
||||||
import prog8.vm.Syscall
|
import prog8.vm.Syscall
|
||||||
import prog8.vm.VmDataType
|
import prog8.vm.VmDataType
|
||||||
@ -32,11 +31,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
"rndw" -> funcRndw(resultRegister)
|
"rndw" -> funcRndw(resultRegister)
|
||||||
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
|
"callfar" -> throw AssemblyError("callfar() is for cx16 target only")
|
||||||
"callrom" -> throw AssemblyError("callrom() is for cx16 target only")
|
"callrom" -> throw AssemblyError("callrom() is for cx16 target only")
|
||||||
"syscall" -> funcSyscall(call)
|
|
||||||
"syscall1" -> funcSyscall1(call)
|
|
||||||
"syscall2" -> funcSyscall2(call)
|
|
||||||
"syscall3" -> funcSyscall3(call)
|
|
||||||
"syscall1fp" -> funcSyscall1fp(call)
|
|
||||||
"msb" -> funcMsb(call, resultRegister)
|
"msb" -> funcMsb(call, resultRegister)
|
||||||
"lsb" -> funcLsb(call, resultRegister)
|
"lsb" -> funcLsb(call, resultRegister)
|
||||||
"memory" -> funcMemory(call, resultRegister)
|
"memory" -> funcMemory(call, resultRegister)
|
||||||
@ -350,60 +344,6 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcSyscall(call: PtBuiltinFunctionCall): VmCodeChunk {
|
|
||||||
val code = VmCodeChunk()
|
|
||||||
val vExpr = call.args.single() as PtNumber
|
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value=vExpr.number.toInt())
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSyscall1(call: PtBuiltinFunctionCall): VmCodeChunk {
|
|
||||||
val code = VmCodeChunk()
|
|
||||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
|
||||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSyscall1fp(call: PtBuiltinFunctionCall): VmCodeChunk {
|
|
||||||
val code = VmCodeChunk()
|
|
||||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
|
||||||
code += exprGen.translateExpression(call.args[1], -1, 0)
|
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSyscall2(call: PtBuiltinFunctionCall): VmCodeChunk {
|
|
||||||
val code = VmCodeChunk()
|
|
||||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 1)
|
|
||||||
while(codeGen.vmRegisters.peekNext()<2) {
|
|
||||||
codeGen.vmRegisters.nextFree()
|
|
||||||
}
|
|
||||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
|
||||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
|
||||||
code += exprGen.translateExpression(call.args[2], 1, -1)
|
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
|
||||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1)
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcSyscall3(call: PtBuiltinFunctionCall): VmCodeChunk {
|
|
||||||
val code = VmCodeChunk()
|
|
||||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 1)
|
|
||||||
code += VmCodeInstruction(Opcode.PUSH, VmDataType.WORD, reg1 = 2)
|
|
||||||
while(codeGen.vmRegisters.peekNext()<3) {
|
|
||||||
codeGen.vmRegisters.nextFree()
|
|
||||||
}
|
|
||||||
val callNr = (call.args[0] as PtNumber).number.toInt()
|
|
||||||
code += exprGen.translateExpression(call.args[1], 0, -1)
|
|
||||||
code += exprGen.translateExpression(call.args[2], 1, -1)
|
|
||||||
code += exprGen.translateExpression(call.args[3], 2, -1)
|
|
||||||
code += VmCodeInstruction(Opcode.SYSCALL, value=callNr)
|
|
||||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 2)
|
|
||||||
code += VmCodeInstruction(Opcode.POP, VmDataType.WORD, reg1 = 1)
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
private fun funcRolRor2(opcode: Opcode, call: PtBuiltinFunctionCall, resultRegister: Int): VmCodeChunk {
|
||||||
val vmDt = codeGen.vmType(call.args[0].type)
|
val vmDt = codeGen.vmType(call.args[0].type)
|
||||||
val code = VmCodeChunk()
|
val code = VmCodeChunk()
|
||||||
|
@ -19,84 +19,130 @@ sub print_f(float value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub pow(float value, float power) -> float {
|
sub pow(float value, float power) -> float {
|
||||||
; TODO
|
; TODO fpow.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.pow.value}
|
||||||
|
loadm.f fr1,{floats.pow.power}
|
||||||
|
fpow.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub fabs(float value) -> float {
|
sub fabs(float value) -> float {
|
||||||
; TODO
|
; TODO fabs.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.fabs.value}
|
||||||
|
fabs.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub sin(float angle) -> float {
|
sub sin(float angle) -> float {
|
||||||
; TODO sin.f instruction
|
; TODO fsin.f instruction
|
||||||
%asm {{
|
%asm {{
|
||||||
loadm.f fr0,{floats.sin.angle}
|
loadm.f fr0,{floats.sin.angle}
|
||||||
sin.f fr0,fr0
|
fsin.f fr0,fr0
|
||||||
return
|
return
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub cos(float angle) -> float {
|
sub cos(float angle) -> float {
|
||||||
; TODO
|
; TODO fcos.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.cos.angle}
|
||||||
|
fcos.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub tan(float value) -> float {
|
sub tan(float value) -> float {
|
||||||
; TODO
|
; TODO ftan.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.tan.value}
|
||||||
|
ftan.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub atan(float value) -> float {
|
sub atan(float value) -> float {
|
||||||
; TODO
|
; TODO fatan.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.atan.value}
|
||||||
|
fatan.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ln(float value) -> float {
|
sub ln(float value) -> float {
|
||||||
; TODO
|
; TODO fln.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.ln.value}
|
||||||
|
fln.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub log2(float value) -> float {
|
sub log2(float value) -> float {
|
||||||
; TODO
|
; TODO flog2.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.log2.value}
|
||||||
|
flog2.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub sqrt(float value) -> float {
|
sub sqrt(float value) -> float {
|
||||||
; TODO
|
; TODO fsqrt.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.sqrt.value}
|
||||||
|
fsqrt.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rad(float angle) -> float {
|
sub rad(float angle) -> float {
|
||||||
; -- convert degrees to radians (d * pi / 180)
|
; -- convert degrees to radians (d * pi / 180)
|
||||||
; TODO
|
return angle * PI / 180.0
|
||||||
return -42.42
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub deg(float angle) -> float {
|
sub deg(float angle) -> float {
|
||||||
; -- convert radians to degrees (d * (1/ pi * 180))
|
; -- convert radians to degrees (d * (1/ pi * 180))
|
||||||
; TODO
|
return angle * 180.0 / PI
|
||||||
return -42.42
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub round(float value) -> float {
|
sub round(float value) -> float {
|
||||||
; TODO
|
; TODO fround.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.round.value}
|
||||||
|
fround.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub floor(float value) -> float {
|
sub floor(float value) -> float {
|
||||||
; TODO
|
; TODO ffloor.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.floor.value}
|
||||||
|
ffloor.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ceil(float value) -> float {
|
sub ceil(float value) -> float {
|
||||||
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
; -- ceil: tr = int(f); if tr==f -> return else return tr+1
|
||||||
; TODO
|
; TODO fceil.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
loadm.f fr0,{floats.ceil.value}
|
||||||
|
fceil.f fr0,fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub rndf() -> float {
|
sub rndf() -> float {
|
||||||
; TODO
|
; TODO frnd.f instruction
|
||||||
return -42.42
|
%asm {{
|
||||||
|
frnd.f fr0
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,74 +8,26 @@ sys {
|
|||||||
|
|
||||||
const ubyte target = 255 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL, 255 = virtual
|
const ubyte target = 255 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL, 255 = virtual
|
||||||
|
|
||||||
; Syscalls table, taken from Syscall enumeration
|
|
||||||
; 0 = reset ; resets system
|
|
||||||
; 1 = exit ; stops program and returns statuscode from r0.w
|
|
||||||
; 2 = print_c ; print single character
|
|
||||||
; 3 = print_s ; print 0-terminated string from memory
|
|
||||||
; 4 = print_u8 ; print unsigned int byte
|
|
||||||
; 5 = print_u16 ; print unsigned int word
|
|
||||||
; 6 = input ; reads a line of text entered by the user, r0.w = memory buffer, r1.b = maxlength (0-255, 0=unlimited). Zero-terminates the string. Returns length in r0.w
|
|
||||||
; 7 = sleep ; sleep amount of milliseconds
|
|
||||||
; 8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
|
||||||
; 9 = gfx_clear ; clear graphics window with shade in r0.b
|
|
||||||
; 10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
|
||||||
; 11 = set_carry status flag
|
|
||||||
; 12 = clear_carry status flag
|
|
||||||
; 13 = wait ; wait certain amount of jiffies (1/60 sec)
|
|
||||||
; 14 = waitvsync ; wait on vsync
|
|
||||||
; 15 = sort_ubyte array
|
|
||||||
; 16 = sort_byte array
|
|
||||||
; 17 = sort_uword array
|
|
||||||
; 18 = sort_word array
|
|
||||||
; 19 = max_ubyte array
|
|
||||||
; 20 = max_byte array
|
|
||||||
; 21 = max_uword array
|
|
||||||
; 22 = max_word array
|
|
||||||
; 23 = min_ubyte array
|
|
||||||
; 24 = min_byte array
|
|
||||||
; 25 = min_uword array
|
|
||||||
; 26 = min_word array
|
|
||||||
; 27 = sum_byte array
|
|
||||||
; 28 = sum_word array
|
|
||||||
; 29 = any_byte array
|
|
||||||
; 30 = any_word array
|
|
||||||
; 31 = all_byte array
|
|
||||||
; 32 = all_word array
|
|
||||||
; 33 = reverse_bytes array
|
|
||||||
; 34 = reverse_words array
|
|
||||||
; 35 = printf (float arg in fpReg0)
|
|
||||||
const ubyte SC_RESET = 0
|
|
||||||
const ubyte SC_EXIT = 1
|
|
||||||
const ubyte SC_PRINT_C = 2
|
|
||||||
const ubyte SC_PRINT_S = 3
|
|
||||||
const ubyte SC_PRINT_U8 = 4
|
|
||||||
const ubyte SC_PRINT_U16 = 5
|
|
||||||
const ubyte SC_INPUT = 6
|
|
||||||
const ubyte SC_SLEEP = 7
|
|
||||||
const ubyte SC_GFX_ENABLE = 8
|
|
||||||
const ubyte SC_GFX_CLEAR = 9
|
|
||||||
const ubyte SC_GFX_PLOT = 10
|
|
||||||
const ubyte SC_SET_CARRY = 11
|
|
||||||
const ubyte SC_CLEAR_CARRY = 12
|
|
||||||
const ubyte SC_WAIT = 13
|
|
||||||
const ubyte SC_WAITVSYNC = 14
|
|
||||||
const ubyte SC_PRINTF = 35
|
|
||||||
|
|
||||||
|
|
||||||
sub reset_system() {
|
sub reset_system() {
|
||||||
; Soft-reset the system back to initial power-on Basic prompt.
|
; Soft-reset the system back to initial power-on Basic prompt.
|
||||||
void syscall(SC_RESET)
|
%asm {{
|
||||||
|
syscall 0
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub wait(uword jiffies) {
|
sub wait(uword jiffies) {
|
||||||
; --- wait approximately the given number of jiffies (1/60th seconds)
|
; --- wait approximately the given number of jiffies (1/60th seconds)
|
||||||
void syscall1(SC_WAIT, jiffies)
|
%asm {{
|
||||||
|
loadm.w r0, {sys.wait.jiffies}
|
||||||
|
syscall 13
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub waitvsync() {
|
sub waitvsync() {
|
||||||
; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling.
|
; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling.
|
||||||
void syscall(SC_WAITVSYNC)
|
%asm {{
|
||||||
|
syscall 14
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub internal_stringcopy(uword source, uword target) {
|
sub internal_stringcopy(uword source, uword target) {
|
||||||
@ -112,15 +64,39 @@ sys {
|
|||||||
|
|
||||||
sub exit(ubyte returnvalue) {
|
sub exit(ubyte returnvalue) {
|
||||||
; -- immediately exit the program with a return code in the A register
|
; -- immediately exit the program with a return code in the A register
|
||||||
void syscall1(SC_EXIT, returnvalue)
|
%asm {{
|
||||||
}
|
loadm.b r0,{sys.exit.returnvalue}
|
||||||
|
syscall 1
|
||||||
sub clear_carry() {
|
}}
|
||||||
void syscall(SC_CLEAR_CARRY)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub set_carry() {
|
sub set_carry() {
|
||||||
void syscall(SC_SET_CARRY)
|
%asm {{
|
||||||
|
sec
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub clear_carry() {
|
||||||
|
%asm {{
|
||||||
|
clc
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub gfx_enable(ubyte mode) {
|
||||||
|
%asm {{
|
||||||
|
loadm.b r0, {sys.gfx_enable.mode}
|
||||||
|
syscall 8
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub gfx_plot(uword xx, uword yy, ubyte color) {
|
||||||
|
%asm {{
|
||||||
|
loadm.w r0, {sys.gfx_plot.xx}
|
||||||
|
loadm.w r1, {sys.gfx_plot.yy}
|
||||||
|
loadm.b r2, {sys.gfx_plot.color}
|
||||||
|
syscall 10
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,11 @@
|
|||||||
txt {
|
txt {
|
||||||
|
|
||||||
sub clear_screen() {
|
sub clear_screen() {
|
||||||
void syscall1(3, "\x1b[2J\x1B[H")
|
str @shared sequence = "\x1b[2J\x1B[H"
|
||||||
|
%asm {{
|
||||||
|
load.w r0, {txt.clear_screen.sequence}
|
||||||
|
syscall 3
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub nl() {
|
sub nl() {
|
||||||
@ -27,11 +31,17 @@ sub uppercase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub chrout(ubyte char) {
|
sub chrout(ubyte char) {
|
||||||
void syscall1(2, char)
|
%asm {{
|
||||||
|
loadm.b r0, {txt.chrout.char}
|
||||||
|
syscall 2
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub print (str text) {
|
sub print (str text) {
|
||||||
void syscall1(3, text)
|
%asm {{
|
||||||
|
loadm.w r0, {txt.print.text}
|
||||||
|
syscall 3
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub print_ub0 (ubyte value) {
|
sub print_ub0 (ubyte value) {
|
||||||
@ -105,7 +115,11 @@ sub print_w (word value) {
|
|||||||
sub input_chars (uword buffer) -> ubyte {
|
sub input_chars (uword buffer) -> ubyte {
|
||||||
; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well)
|
; ---- Input a string (max. 80 chars) from the keyboard. Returns length of input. (string is terminated with a 0 byte as well)
|
||||||
; It assumes the keyboard is selected as I/O channel!
|
; It assumes the keyboard is selected as I/O channel!
|
||||||
return syscall1(6, buffer)
|
%asm {{
|
||||||
|
loadm.w r0,{txt.input_chars.buffer}
|
||||||
|
syscall 6
|
||||||
|
return
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -123,11 +123,6 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
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", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
FSignature("callfar" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||||
FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||||
FSignature("syscall" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE))), DataType.UWORD, null),
|
|
||||||
FSignature("syscall1" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
|
||||||
FSignature("syscall1fp" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.FLOAT))), DataType.FLOAT, null),
|
|
||||||
FSignature("syscall2" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
|
||||||
FSignature("syscall3" , false, listOf(FParam("callnr", arrayOf(DataType.UBYTE)), FParam("arg1", arrayOf(DataType.UWORD)), FParam("arg2", arrayOf(DataType.UWORD)), FParam("arg3", arrayOf(DataType.UWORD))), DataType.UWORD, null),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- vm: get rid of the syscall() functions in prog8 via inline assembly
|
- vm: fix fp reg out of bounds
|
||||||
- vm: implement missing floating point functions
|
- vm: implement missing floating point functions
|
||||||
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
|
- vm: get rid of intermediate floats.xxx() functions somehow, instead generate the float instructions directly?
|
||||||
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
|
- pipe operator: allow non-unary function calls in the pipe that specify the other argument(s) in the calls.
|
||||||
|
@ -8,14 +8,23 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.print("float tests: ")
|
float fl = 500.0
|
||||||
floats.print_f(-42.42)
|
txt.print("rad 180 = ")
|
||||||
float f1 = 1.2345
|
floats.print_f(floats.rad(180.0))
|
||||||
float f2 = -9.99
|
txt.print("rad 360 = ")
|
||||||
float f3
|
floats.print_f(floats.rad(360.0))
|
||||||
f3 = floats.sin(f3)
|
txt.print("deg 2 = ")
|
||||||
floats.print_f(f3)
|
floats.print_f(floats.deg(2.0))
|
||||||
txt.nl()
|
txt.print("deg pi = ")
|
||||||
|
floats.print_f(floats.deg(floats.PI))
|
||||||
|
sys.exit(42)
|
||||||
|
; floats.print_f(-42.42)
|
||||||
|
; float f1 = 1.2345
|
||||||
|
; float f2 = -9.99
|
||||||
|
; float f3
|
||||||
|
; f3 = floats.sin(f3)
|
||||||
|
; floats.print_f(f3)
|
||||||
|
; txt.nl()
|
||||||
|
|
||||||
; float f1 = 1.555
|
; float f1 = 1.555
|
||||||
; floats.print_f(floats.sin(f1))
|
; floats.print_f(floats.sin(f1))
|
||||||
@ -49,23 +58,21 @@ main {
|
|||||||
; "deg", "round", "floor", "ceil", "rndf"
|
; "deg", "round", "floor", "ceil", "rndf"
|
||||||
|
|
||||||
; a "pixelshader":
|
; a "pixelshader":
|
||||||
; void syscall1(8, 0) ; enable lo res creen
|
sys.gfx_enable(0) ; enable lo res screen
|
||||||
; ubyte shifter
|
ubyte shifter
|
||||||
;
|
|
||||||
; ; pokemon(1,0)
|
repeat {
|
||||||
;
|
uword xx
|
||||||
; repeat {
|
uword yy = 0
|
||||||
; uword xx
|
repeat 240 {
|
||||||
; uword yy = 0
|
xx = 0
|
||||||
; repeat 240 {
|
repeat 320 {
|
||||||
; xx = 0
|
sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte)
|
||||||
; repeat 320 {
|
xx++
|
||||||
; syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel
|
}
|
||||||
; xx++
|
yy++
|
||||||
; }
|
}
|
||||||
; yy++
|
shifter+=4
|
||||||
; }
|
}
|
||||||
; shifter+=4
|
|
||||||
; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ SYSCALLS:
|
|||||||
8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
8 = gfx_enable ; enable graphics window r0.b = 0 -> lores 320x240, r0.b = 1 -> hires 640x480
|
||||||
9 = gfx_clear ; clear graphics window with shade in r0.b
|
9 = gfx_clear ; clear graphics window with shade in r0.b
|
||||||
10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
10 = gfx_plot ; plot pixel in graphics window, r0.w/r1.w contain X and Y coordinates, r2.b contains brightness
|
||||||
11 = set_carry status flag
|
11 = <unused 1>
|
||||||
12 = clear_carry status flag
|
12 = <unused 2>
|
||||||
13 = wait ; wait certain amount of jiffies (1/60 sec)
|
13 = wait ; wait certain amount of jiffies (1/60 sec)
|
||||||
14 = waitvsync ; wait on vsync
|
14 = waitvsync ; wait on vsync
|
||||||
15 = sort_ubyte array
|
15 = sort_ubyte array
|
||||||
@ -55,8 +55,8 @@ enum class Syscall {
|
|||||||
GFX_ENABLE,
|
GFX_ENABLE,
|
||||||
GFX_CLEAR,
|
GFX_CLEAR,
|
||||||
GFX_PLOT,
|
GFX_PLOT,
|
||||||
SET_CARRY,
|
UNUSED_1,
|
||||||
CLEAR_CARRY,
|
UNUSED_2,
|
||||||
WAIT,
|
WAIT,
|
||||||
WAITVSYNC,
|
WAITVSYNC,
|
||||||
SORT_UBYTE,
|
SORT_UBYTE,
|
||||||
@ -297,8 +297,6 @@ object SysCalls {
|
|||||||
else
|
else
|
||||||
vm.registers.setUB(0, 0u)
|
vm.registers.setUB(0, 0u)
|
||||||
}
|
}
|
||||||
Syscall.SET_CARRY -> vm.statusCarry = true
|
|
||||||
Syscall.CLEAR_CARRY -> vm.statusCarry = false
|
|
||||||
Syscall.PRINT_F -> {
|
Syscall.PRINT_F -> {
|
||||||
val value = vm.registers.getFloat(0)
|
val value = vm.registers.getFloat(0)
|
||||||
print(value)
|
print(value)
|
||||||
|
@ -61,11 +61,13 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
registers.reset()
|
registers.reset()
|
||||||
memory.reset()
|
// memory.reset()
|
||||||
pc = 0
|
pc = 0
|
||||||
stepCount = 0
|
stepCount = 0
|
||||||
callStack.clear()
|
callStack.clear()
|
||||||
statusCarry = false
|
statusCarry = false
|
||||||
|
statusNegative = false
|
||||||
|
statusZero = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun exit() {
|
fun exit() {
|
||||||
@ -168,6 +170,8 @@ class VirtualMachine(val memory: Memory, program: List<Instruction>) {
|
|||||||
Opcode.PUSH -> InsPUSH(ins)
|
Opcode.PUSH -> InsPUSH(ins)
|
||||||
Opcode.POP -> InsPOP(ins)
|
Opcode.POP -> InsPOP(ins)
|
||||||
Opcode.BREAKPOINT -> InsBREAKPOINT()
|
Opcode.BREAKPOINT -> InsBREAKPOINT()
|
||||||
|
Opcode.CLC -> { statusCarry = false; pc++ }
|
||||||
|
Opcode.SEC -> { statusCarry = true; pc++ }
|
||||||
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
|
else -> throw IllegalArgumentException("invalid opcode ${ins.opcode}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user