diff --git a/examples/test.p8 b/examples/test.p8 index 97c9fb201..9cd4dff0a 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -47,23 +47,23 @@ main { ; "deg", "round", "floor", "ceil", "rndf" ; a "pixelshader": - void syscall1(8, 0) ; enable lo res creen - ubyte shifter - - ; pokemon(1,0) - - repeat { - uword xx - uword yy = 0 - repeat 240 { - xx = 0 - repeat 320 { - syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel - xx++ - } - yy++ - } - shifter+=4 - } +; void syscall1(8, 0) ; enable lo res creen +; ubyte shifter +; +; ; pokemon(1,0) +; +; repeat { +; uword xx +; uword yy = 0 +; repeat 240 { +; xx = 0 +; repeat 320 { +; syscall3(10, xx, yy, xx*yy + shifter) ; plot pixel +; xx++ +; } +; yy++ +; } +; shifter+=4 +; } } } diff --git a/virtualmachine/src/prog8/vm/VirtualMachine.kt b/virtualmachine/src/prog8/vm/VirtualMachine.kt index 1a4c12ba3..ace3df34c 100644 --- a/virtualmachine/src/prog8/vm/VirtualMachine.kt +++ b/virtualmachine/src/prog8/vm/VirtualMachine.kt @@ -650,39 +650,43 @@ class VirtualMachine(val memory: Memory, program: List) { private fun InsADD(i: Instruction) { when(i.type!!) { - VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!, i.reg3!!, null) - VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!, i.reg3!!, null) + VmDataType.BYTE -> arithByte("+", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.WORD -> arithWord("+", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.FLOAT -> arithFloat("+", i.fpReg1!!, i.fpReg2!!, i.fpReg3!!) } pc++ } private fun InsSUB(i: Instruction) { when(i.type!!) { - VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!, i.reg3!!, null) - VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!, i.reg3!!, null) + VmDataType.BYTE -> arithByte("-", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.WORD -> arithWord("-", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.FLOAT -> arithFloat("-", i.fpReg1!!, i.fpReg2!!, i.fpReg3!!) } pc++ } private fun InsMUL(i: Instruction) { when(i.type!!) { - VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!, i.reg3!!, null) - VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!, i.reg3!!, null) + VmDataType.BYTE -> arithByte("*", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.WORD -> arithWord("*", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.FLOAT -> arithFloat("*", i.fpReg1!!, i.fpReg2!!, i.fpReg3!!) } pc++ } private fun InsDIV(i: Instruction) { when(i.type!!) { - VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!, i.reg3!!, null) - VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!, i.reg3!!, null) + VmDataType.BYTE -> arithByte("/", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.WORD -> arithWord("/", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.FLOAT -> arithFloat("/", i.fpReg1!!, i.fpReg2!!, i.fpReg3!!) } pc++ } private fun InsMOD(i: Instruction) { when(i.type!!) { - VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!, i.reg3!!, null) - VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!, i.reg3!!, null) + VmDataType.BYTE -> arithByte("%", i.reg1!!, i.reg2!!, i.reg3!!) + VmDataType.WORD -> arithWord("%", i.reg1!!, i.reg2!!, i.reg3!!) VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } pc++ @@ -692,6 +696,7 @@ class VirtualMachine(val memory: Memory, program: List) { when(i.type!!) { VmDataType.BYTE -> registers.setSB(i.reg1!!, registers.getSB(i.reg2!!).toInt().sign.toByte()) VmDataType.WORD -> registers.setSW(i.reg1!!, registers.getSW(i.reg2!!).toInt().sign.toShort()) + VmDataType.FLOAT -> registers.setFloat(i.fpReg1!!, registers.getFloat(i.fpReg2!!).sign) } pc++ } @@ -729,9 +734,7 @@ class VirtualMachine(val memory: Memory, program: List) { comparison = reg1.toInt() - reg2.toInt() statusNegative = (comparison and 0x8000)==0x8000 } - VmDataType.FLOAT -> { - TODO("CMP float") - } + VmDataType.FLOAT -> throw IllegalArgumentException("invalid float type for this instruction $i") } if(comparison==0){ statusZero = true @@ -746,9 +749,9 @@ class VirtualMachine(val memory: Memory, program: List) { pc++ } - private fun arithByte(operator: String, reg1: Int, reg2: Int, reg3: Int?, value: UByte?) { + private fun arithByte(operator: String, reg1: Int, reg2: Int, reg3: Int) { val left = registers.getUB(reg2) - val right = value ?: registers.getUB(reg3!!) + val right = registers.getUB(reg3) val result = when(operator) { "+" -> left + right "-" -> left - right @@ -766,9 +769,9 @@ class VirtualMachine(val memory: Memory, program: List) { registers.setUB(reg1, result.toUByte()) } - private fun arithWord(operator: String, reg1: Int, reg2: Int, reg3: Int?, value: UShort?) { + private fun arithWord(operator: String, reg1: Int, reg2: Int, reg3: Int) { val left = registers.getUW(reg2) - val right = value ?: registers.getUW(reg3!!) + val right = registers.getUW(reg3) val result = when(operator) { "+" -> left + right "-" -> left - right @@ -786,6 +789,25 @@ class VirtualMachine(val memory: Memory, program: List) { registers.setUW(reg1, result.toUShort()) } + private fun arithFloat(operator: String, fpReg1: Int, fpReg2: Int, fpReg3: Int) { + val left = registers.getFloat(fpReg2) + val right = registers.getFloat(fpReg3) + val result = when(operator) { + "+" -> left + right + "-" -> left - right + "*" -> left * right + "/" -> { + if(right==0f) Float.MAX_VALUE + else left / right + } + "%" -> { + if(right==0f) Float.MAX_VALUE + else left % right + } + else -> throw IllegalArgumentException("operator word $operator") + } + registers.setFloat(fpReg1, result) + } private fun InsEXT(i: Instruction) { when(i.type!!){