From 86cc2f1075293d473cae91ce6b8f436b43bff3b5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 2 May 2022 20:16:45 +0200 Subject: [PATCH] vm: implementing more fp instructions --- .../src/prog8/codegen/virtual/CodeGen.kt | 14 +- .../prog8/codegen/virtual/ExpressionGen.kt | 132 +++++++++++------- compiler/res/prog8lib/virtual/conv.p8 | 55 ++++++-- compiler/res/prog8lib/virtual/floats.p8 | 19 +-- docs/source/todo.rst | 8 +- examples/test.p8 | 96 +++++++++---- virtualmachine/src/prog8/vm/Instructions.kt | 32 ++++- virtualmachine/src/prog8/vm/SysCalls.kt | 18 ++- 8 files changed, 259 insertions(+), 115 deletions(-) diff --git a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt index 53c21a0c6..adbd61625 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/CodeGen.kt @@ -380,10 +380,22 @@ class CodeGen(internal val program: PtProgram, return code } + internal fun multiplyByConstFloat(fpReg: Int, factor: Float): VmCodeChunk { + val code = VmCodeChunk() + if(factor==1f) + return code + if(factor==0f) { + code += VmCodeInstruction(Opcode.LOAD, VmDataType.FLOAT, fpReg1 = fpReg, fpValue = 0f) + } else { + val factorReg = vmRegisters.nextFreeFloat() + code += VmCodeInstruction(Opcode.MUL, VmDataType.FLOAT, fpReg1 = fpReg, fpReg2 = fpReg, fpReg3 = factorReg) + } + return code + } + internal val powersOfTwo = (0..16).map { 2.0.pow(it.toDouble()).toInt() } internal fun multiplyByConst(dt: VmDataType, reg: Int, factor: Int): VmCodeChunk { - // TODO support floating-point factors val code = VmCodeChunk() if(factor==1) return code diff --git a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt index 759ed38c5..4f4143338 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/ExpressionGen.kt @@ -62,7 +62,7 @@ internal class ExpressionGen(private val codeGen: CodeGen) { is PtTypeCast -> code += translate(expr, resultRegister) is PtPrefix -> code += translate(expr, resultRegister) is PtArrayIndexer -> code += translate(expr, resultRegister) - is PtBinaryExpression -> code += translate(expr, resultRegister) + is PtBinaryExpression -> code += translate(expr, resultRegister, resultFpRegister) is PtBuiltinFunctionCall -> code += codeGen.translateBuiltinFunc(expr, resultRegister) is PtFunctionCall -> code += translate(expr, resultRegister, resultFpRegister) is PtContainmentCheck -> code += translate(expr, resultRegister, resultFpRegister) @@ -269,13 +269,13 @@ internal class ExpressionGen(private val codeGen: CodeGen) { return code } - private fun translate(binExpr: PtBinaryExpression, resultRegister: Int): VmCodeChunk { + private fun translate(binExpr: PtBinaryExpression, resultRegister: Int, resultFpRegister: Int): VmCodeChunk { val vmDt = codeGen.vmType(binExpr.left.type) val signed = binExpr.left.type in SignedDatatypes return when(binExpr.operator) { "+" -> operatorPlus(binExpr, vmDt, resultRegister) "-" -> operatorMinus(binExpr, vmDt, resultRegister) - "*" -> operatorMultiply(binExpr, vmDt, resultRegister) + "*" -> operatorMultiply(binExpr, vmDt, resultRegister, resultFpRegister ) "/" -> operatorDivide(binExpr, vmDt, resultRegister) "%" -> operatorModulo(binExpr, vmDt, resultRegister) "|", "or" -> operatorOr(binExpr, vmDt, resultRegister) @@ -398,6 +398,8 @@ internal class ExpressionGen(private val codeGen: CodeGen) { } private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { + if(vmDt==VmDataType.FLOAT) + throw IllegalArgumentException("floating-point modulo not supported") val code = VmCodeChunk() val leftResultReg = codeGen.vmRegisters.nextFree() val rightResultReg = codeGen.vmRegisters.nextFree() @@ -410,74 +412,104 @@ internal class ExpressionGen(private val codeGen: CodeGen) { private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() val constFactorRight = binExpr.right as? PtNumber - if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { - code += translateExpression(binExpr.left, resultRegister, -1) - val factor = constFactorRight.number.toInt() - code += codeGen.divideByConst(vmDt, resultRegister, factor) + if(vmDt==VmDataType.FLOAT) { + TODO("div float") } else { - val leftResultReg = codeGen.vmRegisters.nextFree() - val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, -1) - code += translateExpression(binExpr.right, rightResultReg, -1) - code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { + code += translateExpression(binExpr.left, resultRegister, -1) + val factor = constFactorRight.number.toInt() + code += codeGen.divideByConst(vmDt, resultRegister, factor) + } else { + val leftResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.vmRegisters.nextFree() + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) + code += VmCodeInstruction(Opcode.DIV, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + } } return code } - private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { + private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int, resultFpRegister: Int): VmCodeChunk { val code = VmCodeChunk() val constFactorLeft = binExpr.left as? PtNumber val constFactorRight = binExpr.right as? PtNumber - if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) { - code += translateExpression(binExpr.right, resultRegister, -1) - val factor = constFactorLeft.number.toInt() - code += codeGen.multiplyByConst(vmDt, resultRegister, factor) - } else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { - code += translateExpression(binExpr.left, resultRegister, -1) - val factor = constFactorRight.number.toInt() - code += codeGen.multiplyByConst(vmDt, resultRegister, factor) + if(vmDt==VmDataType.FLOAT) { + if(constFactorLeft!=null) { + code += translateExpression(binExpr.right, -1, resultFpRegister) + val factor = constFactorLeft.number.toFloat() + code += codeGen.multiplyByConstFloat(resultFpRegister, factor) + } else if(constFactorRight!=null) { + code += translateExpression(binExpr.left, -1, resultFpRegister) + val factor = constFactorRight.number.toFloat() + code += codeGen.multiplyByConstFloat(resultFpRegister, factor) + } else { + val leftResultFpReg = codeGen.vmRegisters.nextFreeFloat() + val rightResultFpReg = codeGen.vmRegisters.nextFreeFloat() + code += translateExpression(binExpr.left, -1, leftResultFpReg) + code += translateExpression(binExpr.right, -1, rightResultFpReg) + code += VmCodeInstruction(Opcode.MUL, vmDt, fpReg1 = resultFpRegister, reg2=leftResultFpReg, reg3=rightResultFpReg) + } } else { - val leftResultReg = codeGen.vmRegisters.nextFree() - val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, -1) - code += translateExpression(binExpr.right, rightResultReg, -1) - code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + if(constFactorLeft!=null && constFactorLeft.type!=DataType.FLOAT) { + code += translateExpression(binExpr.right, resultRegister, -1) + val factor = constFactorLeft.number.toInt() + code += codeGen.multiplyByConst(vmDt, resultRegister, factor) + } else if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) { + code += translateExpression(binExpr.left, resultRegister, -1) + val factor = constFactorRight.number.toInt() + code += codeGen.multiplyByConst(vmDt, resultRegister, factor) + } else { + val leftResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.vmRegisters.nextFree() + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) + code += VmCodeInstruction(Opcode.MUL, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + } } return code } private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - if((binExpr.right as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.left, resultRegister, -1) - code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister) - } - else { - val leftResultReg = codeGen.vmRegisters.nextFree() - val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, -1) - code += translateExpression(binExpr.right, rightResultReg, -1) - code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + if(vmDt==VmDataType.FLOAT) { + TODO("minus float") + } else { + if((binExpr.right as? PtNumber)?.number==1.0) { + code += translateExpression(binExpr.left, resultRegister, -1) + code += VmCodeInstruction(Opcode.DEC, vmDt, reg1=resultRegister) + } + else { + val leftResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.vmRegisters.nextFree() + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) + code += VmCodeInstruction(Opcode.SUB, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + } } return code } private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: VmDataType, resultRegister: Int): VmCodeChunk { val code = VmCodeChunk() - if((binExpr.left as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.right, resultRegister, -1) - code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) - } - else if((binExpr.right as? PtNumber)?.number==1.0) { - code += translateExpression(binExpr.left, resultRegister, -1) - code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) - } - else { - val leftResultReg = codeGen.vmRegisters.nextFree() - val rightResultReg = codeGen.vmRegisters.nextFree() - code += translateExpression(binExpr.left, leftResultReg, -1) - code += translateExpression(binExpr.right, rightResultReg, -1) - code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + if(vmDt==VmDataType.FLOAT) { + TODO("plus float") + } else { + if((binExpr.left as? PtNumber)?.number==1.0) { + code += translateExpression(binExpr.right, resultRegister, -1) + code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) + } + else if((binExpr.right as? PtNumber)?.number==1.0) { + code += translateExpression(binExpr.left, resultRegister, -1) + code += VmCodeInstruction(Opcode.INC, vmDt, reg1=resultRegister) + } + else { + val leftResultReg = codeGen.vmRegisters.nextFree() + val rightResultReg = codeGen.vmRegisters.nextFree() + code += translateExpression(binExpr.left, leftResultReg, -1) + code += translateExpression(binExpr.right, rightResultReg, -1) + code += VmCodeInstruction(Opcode.ADD, vmDt, reg1=resultRegister, reg2=leftResultReg, reg3=rightResultReg) + } } return code } diff --git a/compiler/res/prog8lib/virtual/conv.p8 b/compiler/res/prog8lib/virtual/conv.p8 index b3e829741..b1ddaa17c 100644 --- a/compiler/res/prog8lib/virtual/conv.p8 +++ b/compiler/res/prog8lib/virtual/conv.p8 @@ -184,47 +184,76 @@ sub str2ubyte(str string) -> ubyte { ; -- returns in A the unsigned byte value of the string number argument in AY ; the number may NOT be preceded by a + sign and may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) - ; TODO - return 0 + return str2uword(string) as ubyte } sub str2byte(str string) -> byte { ; -- returns in A the signed byte value of the string number argument in AY ; the number may be preceded by a + or - sign but may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) - ; TODO - return 0 + return str2word(string) as byte } sub str2uword(str string) -> uword { ; -- returns the unsigned word value of the string number argument in AY ; the number may NOT be preceded by a + sign and may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) - ; TODO - return 0 + %asm {{ + loadm.w r0, {conv.str2uword.string} + syscall 11 + return + }} } sub str2word(str string) -> word { ; -- returns the signed word value of the string number argument in AY ; the number may be preceded by a + or - sign but may NOT contain spaces ; (any non-digit character will terminate the number string that is parsed) - ; TODO - return 0 + %asm {{ + loadm.w r0, {conv.str2word.string} + syscall 12 + return + }} } sub hex2uword(str string) -> uword { ; -- hexadecimal string (with or without '$') to uword. - ; string may be in petscii or c64-screencode encoding. ; stops parsing at the first character that's not a hex digit (except leading $) - ; TODO - return 0 + ; TODO fix this result + uword result + ubyte char + if @(string)=='$' + string++ + repeat { + char = @(string) + if char==0 + return result + result <<= 4 + if char>='0' and char<='9' + result |= char-'0' + else + result |= char-'a'+10 + string++ + } } sub bin2uword(str string) -> uword { ; -- binary string (with or without '%') to uword. ; stops parsing at the first character that's not a 0 or 1. (except leading %) - ; TODO - return 0 + ; TODO fix this result + uword result + ubyte char + if @(string)=='%' + string++ + repeat { + char = @(string) + if char==0 + return result + result <<= 1 + if char=='1' + result |= 1 + string++ + } } } diff --git a/compiler/res/prog8lib/virtual/floats.p8 b/compiler/res/prog8lib/virtual/floats.p8 index db1c9985d..865c4f1d1 100644 --- a/compiler/res/prog8lib/virtual/floats.p8 +++ b/compiler/res/prog8lib/virtual/floats.p8 @@ -19,17 +19,15 @@ sub print_f(float value) { } sub pow(float value, float power) -> float { - ; TODO fpow.f instruction %asm {{ loadm.f fr0,{floats.pow.value} loadm.f fr1,{floats.pow.power} - fpow.f fr0,fr0 + fpow.f fr0,fr0,fr1 return }} } sub fabs(float value) -> float { - ; TODO fabs.f instruction %asm {{ loadm.f fr0,{floats.fabs.value} fabs.f fr0,fr0 @@ -38,7 +36,6 @@ sub fabs(float value) -> float { } sub sin(float angle) -> float { - ; TODO fsin.f instruction %asm {{ loadm.f fr0,{floats.sin.angle} fsin.f fr0,fr0 @@ -47,7 +44,6 @@ sub sin(float angle) -> float { } sub cos(float angle) -> float { - ; TODO fcos.f instruction %asm {{ loadm.f fr0,{floats.cos.angle} fcos.f fr0,fr0 @@ -56,7 +52,6 @@ sub cos(float angle) -> float { } sub tan(float value) -> float { - ; TODO ftan.f instruction %asm {{ loadm.f fr0,{floats.tan.value} ftan.f fr0,fr0 @@ -65,7 +60,6 @@ sub tan(float value) -> float { } sub atan(float value) -> float { - ; TODO fatan.f instruction %asm {{ loadm.f fr0,{floats.atan.value} fatan.f fr0,fr0 @@ -74,7 +68,6 @@ sub atan(float value) -> float { } sub ln(float value) -> float { - ; TODO fln.f instruction %asm {{ loadm.f fr0,{floats.ln.value} fln.f fr0,fr0 @@ -83,16 +76,14 @@ sub ln(float value) -> float { } sub log2(float value) -> float { - ; TODO flog2.f instruction %asm {{ loadm.f fr0,{floats.log2.value} - flog2.f fr0,fr0 + flog.f fr0,fr0 return }} } sub sqrt(float value) -> float { - ; TODO fsqrt.f instruction %asm {{ loadm.f fr0,{floats.sqrt.value} fsqrt.f fr0,fr0 @@ -111,7 +102,6 @@ sub deg(float angle) -> float { } sub round(float value) -> float { - ; TODO fround.f instruction %asm {{ loadm.f fr0,{floats.round.value} fround.f fr0,fr0 @@ -120,7 +110,6 @@ sub round(float value) -> float { } sub floor(float value) -> float { - ; TODO ffloor.f instruction %asm {{ loadm.f fr0,{floats.floor.value} ffloor.f fr0,fr0 @@ -130,7 +119,6 @@ sub floor(float value) -> float { sub ceil(float value) -> float { ; -- ceil: tr = int(f); if tr==f -> return else return tr+1 - ; TODO fceil.f instruction %asm {{ loadm.f fr0,{floats.ceil.value} fceil.f fr0,fr0 @@ -139,9 +127,8 @@ sub ceil(float value) -> float { } sub rndf() -> float { - ; TODO frnd.f instruction %asm {{ - frnd.f fr0 + rnd.f fr0 return }} } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index cfbc06681..7961a9b64 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,12 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- vm: fix fp reg out of bounds -- vm: implement missing floating point functions +- vm: fix if @(string)=='$' string++ not working on ea31 +- vm: fix conv hex2uword and bin2uword +- vm: implement float div, minus, plus +- vm: implement float type casts to integer types +- vm: implement float any, all, reverse, sort +- vm: fix test fp calc result being 0 - 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. - allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type diff --git a/examples/test.p8 b/examples/test.p8 index 8fbf35c66..47c58a1aa 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,15 +8,61 @@ main { sub start() { - float fl = 500.0 - txt.print("rad 180 = ") - floats.print_f(floats.rad(180.0)) - txt.print("rad 360 = ") - floats.print_f(floats.rad(360.0)) - txt.print("deg 2 = ") - floats.print_f(floats.deg(2.0)) - txt.print("deg pi = ") - floats.print_f(floats.deg(floats.PI)) + + ubyte ub = conv.str2ubyte("234") + txt.print_ub(ub) + txt.nl() + byte sb = conv.str2byte("-123") + txt.print_b(sb) + txt.nl() + uword uw = conv.str2uword("54321") + txt.print_uw(uw) + txt.nl() + word sw = conv.str2word("-12345") + txt.print_w(sw) + txt.nl() + txt.nl() + + ; TODO fix hex2uword and bin2uword + uw = conv.hex2uword("0") + txt.print_uw(uw) + txt.nl() + uw = conv.hex2uword("1") + txt.print_uw(uw) + txt.nl() + uw = conv.hex2uword("a") + txt.print_uw(uw) + txt.nl() + uw = conv.bin2uword("0") + txt.print_uw(uw) + txt.nl() + uw = conv.bin2uword("1") + txt.print_uw(uw) + txt.nl() + txt.nl() + + uw = conv.hex2uword("$ea31") + txt.print_uw(uw) + txt.nl() + uw = conv.hex2uword("ea31") + txt.print_uw(uw) + txt.nl() + uw = conv.bin2uword("%100000111011101") + txt.print_uw(uw) + txt.nl() + uw = conv.bin2uword("100000111011101") + txt.print_uw(uw) + txt.nl() + +; float fl = 500.0 +; txt.print("rad 180 = ") +; floats.print_f(floats.rad(180.0)) +; txt.print("rad 360 = ") +; floats.print_f(floats.rad(360.0)) +; txt.print("deg 2 = ") +; floats.print_f(floats.deg(2.0)) +; txt.print("deg pi = ") +; floats.print_f(floats.deg(floats.PI)) sys.exit(42) ; floats.print_f(-42.42) ; float f1 = 1.2345 @@ -58,21 +104,21 @@ main { ; "deg", "round", "floor", "ceil", "rndf" ; a "pixelshader": - sys.gfx_enable(0) ; enable lo res screen - ubyte shifter - - repeat { - uword xx - uword yy = 0 - repeat 240 { - xx = 0 - repeat 320 { - sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) - xx++ - } - yy++ - } - shifter+=4 - } +; sys.gfx_enable(0) ; enable lo res screen +; ubyte shifter +; +; repeat { +; uword xx +; uword yy = 0 +; repeat 240 { +; xx = 0 +; repeat 320 { +; sys.gfx_plot(xx, yy, xx*yy + shifter as ubyte) +; xx++ +; } +; yy++ +; } +; shifter+=4 +; } } } diff --git a/virtualmachine/src/prog8/vm/Instructions.kt b/virtualmachine/src/prog8/vm/Instructions.kt index 6564d6982..72e08b0a1 100644 --- a/virtualmachine/src/prog8/vm/Instructions.kt +++ b/virtualmachine/src/prog8/vm/Instructions.kt @@ -18,8 +18,6 @@ a few fp conversion instructions to *only* LOAD AND STORE instructions have a possible memory operand, all other instructions use only registers or immediate value. - TODO all floating point arithmethic functions as fp-instructions. - LOAD/STORE ---------- All have type b or w or f. @@ -130,8 +128,8 @@ rol reg1 - rotate reg1 left by 1bits, not us roxl reg1 - rotate reg1 left by 1bits, using carry, + set Carry to shifted bit -FLOATING POINT CONVERSIONS --------------------------- +FLOATING POINT CONVERSIONS AND FUNCTIONS +---------------------------------------- ffromub fpreg1, reg1 - fpreg1 = reg1 from usigned byte ffromsb fpreg1, reg1 - fpreg1 = reg1 from signed byte ffromuw fpreg1, reg1 - fpreg1 = reg1 from unsigned word @@ -140,6 +138,8 @@ ftoub reg1, fpreg1 - reg1 = fpreg1 as unsigned byte ftosb reg1, fpreg1 - reg1 = fpreg1 as signed byte ftouw reg1, fpreg1 - reg1 = fpreg1 as unsigned word ftosw reg1, fpreg1 - reg1 = fpreg1 as signed word +fpow fpreg1, fpreg2, fpreg3 - fpreg1 = fpreg2 to the power of fpreg3 +fabs fpreg1, fpreg2 - fpreg1 = abs(fpreg2) MISC @@ -248,6 +248,18 @@ enum class Opcode { FTOSB, FTOUW, FTOSW, + FPOW, + FABS, + FSIN, + FCOS, + FTAN, + FATAN, + FLN, + FLOG, + FSQRT, + FROUND, + FFLOOR, + FCEIL, CLC, SEC, @@ -512,6 +524,18 @@ val instructionFormats = mutableMapOf( Opcode.FTOSB to InstructionFormat.from("F,r1,fr1"), Opcode.FTOUW to InstructionFormat.from("F,r1,fr1"), Opcode.FTOSW to InstructionFormat.from("F,r1,fr1"), + Opcode.FPOW to InstructionFormat.from("F,fr1,fr2,fr3"), + Opcode.FABS to InstructionFormat.from("F,fr1,fr2"), + Opcode.FSIN to InstructionFormat.from("F,fr1,fr2"), + Opcode.FCOS to InstructionFormat.from("F,fr1,fr2"), + Opcode.FTAN to InstructionFormat.from("F,fr1,fr2"), + Opcode.FATAN to InstructionFormat.from("F,fr1,fr2"), + Opcode.FLN to InstructionFormat.from("F,fr1,fr2"), + Opcode.FLOG to InstructionFormat.from("F,fr1,fr2"), + Opcode.FSQRT to InstructionFormat.from("F,fr1,fr2"), + Opcode.FROUND to InstructionFormat.from("F,fr1,fr2"), + Opcode.FFLOOR to InstructionFormat.from("F,fr1,fr2"), + Opcode.FCEIL to InstructionFormat.from("F,fr1,fr2"), Opcode.MSIG to InstructionFormat.from("BW,r1,r2"), Opcode.PUSH to InstructionFormat.from("BW,r1"), diff --git a/virtualmachine/src/prog8/vm/SysCalls.kt b/virtualmachine/src/prog8/vm/SysCalls.kt index f2d6ba1e9..b149f0a59 100644 --- a/virtualmachine/src/prog8/vm/SysCalls.kt +++ b/virtualmachine/src/prog8/vm/SysCalls.kt @@ -16,8 +16,8 @@ SYSCALLS: 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 = -12 = +11 = decimal string to word (unsigned) +12 = decimal string to word (signed) 13 = wait ; wait certain amount of jiffies (1/60 sec) 14 = waitvsync ; wait on vsync 15 = sort_ubyte array @@ -55,8 +55,8 @@ enum class Syscall { GFX_ENABLE, GFX_CLEAR, GFX_PLOT, - UNUSED_1, - UNUSED_2, + STR_TO_UWORD, + STR_TO_WORD, WAIT, WAITVSYNC, SORT_UBYTE, @@ -301,6 +301,16 @@ object SysCalls { val value = vm.registers.getFloat(0) print(value) } + Syscall.STR_TO_UWORD -> { + val stringAddr = vm.registers.getUW(0) + val string = vm.memory.getString(stringAddr.toInt()) + vm.registers.setUW(0, string.toUShort()) + } + Syscall.STR_TO_WORD -> { + val stringAddr = vm.registers.getUW(0) + val string = vm.memory.getString(stringAddr.toInt()) + vm.registers.setSW(0, string.toShort()) + } else -> TODO("syscall ${call.name}") } }