60hz irq implemented in stackvm

This commit is contained in:
Irmen de Jong 2018-09-27 22:45:57 +02:00
parent 99d63b13a8
commit 7f28f8be11
6 changed files with 220 additions and 124 deletions

13
compiler/examples/irq.p8 Normal file
View File

@ -0,0 +1,13 @@
~ main {
sub start() -> () {
byte jiffyclockHi = $a0
byte jiffyclockMid = $a1
byte jiffyclockLo = $a2
_vm_gfx_pixel(2,2,jiffyclockHi)
_vm_gfx_pixel(4,2,jiffyclockMid)
_vm_gfx_pixel(6,2,jiffyclockLo)
}
}

View File

@ -17,9 +17,11 @@ fun main(args: Array<String>) {
} }
val program = Program.load(args.first()) val program = Program.load(args.first())
//val irqProgram = Program("irq", mutableListOf(), emptyMap(), emptyMap(), emptyMap())
val irqProgram = Program.load("irq_stackvm.txt")
val vm = StackVm(traceOutputFile = null) val vm = StackVm(traceOutputFile = null)
val dialog = ScreenDialog() val dialog = ScreenDialog()
vm.load(program, dialog.canvas) vm.load(program, irqProgram, dialog.canvas)
EventQueue.invokeLater { EventQueue.invokeLater {
dialog.pack() dialog.pack()
dialog.isVisible = true dialog.isVisible = true
@ -36,6 +38,10 @@ fun main(args: Array<String>) {
(a.source as Timer).stop() (a.source as Timer).stop()
} }
} }
val irqTimer = Timer(1000/60) { a -> vm.irq(a.`when`) }
programTimer.start() programTimer.start()
irqTimer.start()
} }
} }

View File

@ -0,0 +1,64 @@
package prog8.stackvm
import prog8.compiler.target.c64.Mflpt5
import prog8.compiler.target.c64.Petscii
class Memory {
private val mem = ShortArray(65536) // shorts because byte is signed and we store values 0..255
fun getByte(address: Int): Short {
return mem[address]
}
fun setByte(address: Int, value: Short) {
if(value<0 || value>255) throw VmExecutionException("byte value not 0..255")
mem[address] = value
}
fun getWord(address: Int): Int {
return mem[address] + 256*mem[address+1]
}
fun setWord(address: Int, value: Int) {
if(value<0 || value>65535) throw VmExecutionException("word value not 0..65535")
mem[address] = value.and(255).toShort()
mem[address+1] = (value / 256).toShort()
}
fun setFloat(address: Int, value: Double) {
val mflpt5 = Mflpt5.fromNumber(value)
mem[address] = mflpt5.b0
mem[address+1] = mflpt5.b1
mem[address+2] = mflpt5.b2
mem[address+3] = mflpt5.b3
mem[address+4] = mflpt5.b4
}
fun getFloat(address: Int): Double {
return Mflpt5(mem[address], mem[address + 1], mem[address + 2], mem[address + 3], mem[address + 4]).toDouble()
}
fun setString(address: Int, str: String) {
// lowercase PETSCII
val petscii = Petscii.encodePetscii(str, true)
var addr = address
for (c in petscii) mem[addr++] = c
mem[addr] = 0
}
fun getString(strAddress: Int): String {
// lowercase PETSCII
val petscii = mutableListOf<Short>()
var addr = strAddress
while(true) {
val byte = mem[addr++]
if(byte==0.toShort()) break
petscii.add(byte)
}
return Petscii.decodePetscii(petscii, true)
}
fun clear() {
for(i in 0..65535) mem[i]=0
}
}

View File

@ -45,7 +45,7 @@ class BitmapScreenPanel : JPanel() {
companion object { companion object {
const val SCREENWIDTH = 320 const val SCREENWIDTH = 320
const val SCREENHEIGHT = 256 const val SCREENHEIGHT = 200
const val SCALING = 3 const val SCALING = 3
val palette = listOf( // this is Pepto's Commodore-64 palette http://www.pepto.de/projects/colorvic/ val palette = listOf( // this is Pepto's Commodore-64 palette http://www.pepto.de/projects/colorvic/
Color(0x000000), // 0 = black Color(0x000000), // 0 = black

View File

@ -1,7 +1,6 @@
package prog8.stackvm package prog8.stackvm
import prog8.ast.DataType import prog8.ast.DataType
import prog8.compiler.target.c64.Mflpt5
import prog8.compiler.target.c64.Petscii import prog8.compiler.target.c64.Petscii
import java.io.File import java.io.File
import java.io.PrintStream import java.io.PrintStream
@ -165,66 +164,6 @@ enum class Syscall(val callNr: Short) {
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL, ROR, ROL2, ROR2, and FLT)! // some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL, ROR, ROL2, ROR2, and FLT)!
} }
class Memory {
private val mem = ShortArray(65536) // shorts because byte is signed and we store values 0..255
fun getByte(address: Int): Short {
return mem[address]
}
fun setByte(address: Int, value: Short) {
if(value<0 || value>255) throw VmExecutionException("byte value not 0..255")
mem[address] = value
}
fun getWord(address: Int): Int {
return mem[address] + 256*mem[address+1]
}
fun setWord(address: Int, value: Int) {
if(value<0 || value>65535) throw VmExecutionException("word value not 0..65535")
mem[address] = value.and(255).toShort()
mem[address+1] = (value / 256).toShort()
}
fun setFloat(address: Int, value: Double) {
val mflpt5 = Mflpt5.fromNumber(value)
mem[address] = mflpt5.b0
mem[address+1] = mflpt5.b1
mem[address+2] = mflpt5.b2
mem[address+3] = mflpt5.b3
mem[address+4] = mflpt5.b4
}
fun getFloat(address: Int): Double {
return Mflpt5(mem[address], mem[address+1], mem[address+2], mem[address+3], mem[address+4]).toDouble()
}
fun setString(address: Int, str: String) {
// lowercase PETSCII
val petscii = Petscii.encodePetscii(str, true)
var addr = address
for (c in petscii) mem[addr++] = c
mem[addr] = 0
}
fun getString(strAddress: Int): String {
// lowercase PETSCII
val petscii = mutableListOf<Short>()
var addr = strAddress
while(true) {
val byte = mem[addr++]
if(byte==0.toShort()) break
petscii.add(byte)
}
return Petscii.decodePetscii(petscii, true)
}
fun clear() {
for(i in 0..65535) mem[i]=0
}
}
class Value(val type: DataType, numericvalue: Number?, val stringvalue: String?=null, val arrayvalue: IntArray?=null) { class Value(val type: DataType, numericvalue: Number?, val stringvalue: String?=null, val arrayvalue: IntArray?=null) {
private var byteval: Short? = null private var byteval: Short? = null
@ -912,10 +851,6 @@ class Program (val name: String,
class StackVm(val traceOutputFile: String?) { class StackVm(val traceOutputFile: String?) {
val mem = Memory() val mem = Memory()
val evalstack = MyStack<Value>() // evaluation stack
val callstack = MyStack<Instruction>() // subroutine call stack
var sourceLine = "" // meta info about current line in source file
private set
var P_carry: Boolean = false var P_carry: Boolean = false
private set private set
var P_irqd: Boolean = false var P_irqd: Boolean = false
@ -923,22 +858,39 @@ class StackVm(val traceOutputFile: String?) {
var variables = mutableMapOf<String, Value>() // all variables (set of all vars used by all blocks/subroutines) key = their fully scoped name var variables = mutableMapOf<String, Value>() // all variables (set of all vars used by all blocks/subroutines) key = their fully scoped name
private set private set
private var program = listOf<Instruction>() private var program = listOf<Instruction>()
private var irqProgram = listOf<Instruction>()
var evalstack = MyStack<Value>()
private set
var callstack = MyStack<Instruction>()
private set
private var traceOutput = if(traceOutputFile!=null) PrintStream(File(traceOutputFile), "utf-8") else null private var traceOutput = if(traceOutputFile!=null) PrintStream(File(traceOutputFile), "utf-8") else null
private lateinit var currentIns: Instruction
private var canvas: BitmapScreenPanel? = null private var canvas: BitmapScreenPanel? = null
private val rnd = Random() private val rnd = Random()
private val bootTime = System.currentTimeMillis()
private lateinit var currentIns: Instruction
var sourceLine: String = ""
private set
fun load(program: Program, canvas: BitmapScreenPanel?) { fun load(program: Program, irqProgram: Program?, canvas: BitmapScreenPanel?) {
this.program = program.program this.program = program.program
this.irqProgram = irqProgram?.program ?: mutableListOf(Instruction(Opcode.NOP))
this.canvas = canvas this.canvas = canvas
variables = program.variables.toMutableMap() variables = program.variables.toMutableMap()
if(this.variables.contains("A") || irqCurrentVariables = irqProgram?.variables?.toMutableMap() ?: mutableMapOf()
if(variables.contains("A") ||
variables.contains("X") || variables.contains("X") ||
variables.contains("Y") || variables.contains("Y") ||
variables.contains("XY") || variables.contains("XY") ||
variables.contains("AX") || variables.contains("AX") ||
variables.contains("AY")) variables.contains("AY"))
throw VmExecutionException("program contains variable(s) for the reserved registers A,X,...") throw VmExecutionException("program contains variable(s) for the reserved registers A,X,...")
if(irqCurrentVariables.contains("A") ||
irqCurrentVariables.contains("X") ||
irqCurrentVariables.contains("Y") ||
irqCurrentVariables.contains("XY") ||
irqCurrentVariables.contains("AX") ||
irqCurrentVariables.contains("AY"))
throw VmExecutionException("irqProgram contains variable(s) for the reserved registers A,X,...")
// define the 'registers' // define the 'registers'
variables["A"] = Value(DataType.BYTE, 0) variables["A"] = Value(DataType.BYTE, 0)
variables["X"] = Value(DataType.BYTE, 0) variables["X"] = Value(DataType.BYTE, 0)
@ -946,14 +898,24 @@ class StackVm(val traceOutputFile: String?) {
variables["AX"] = Value(DataType.WORD, 0) variables["AX"] = Value(DataType.WORD, 0)
variables["AY"] = Value(DataType.WORD, 0) variables["AY"] = Value(DataType.WORD, 0)
variables["XY"] = Value(DataType.WORD, 0) variables["XY"] = Value(DataType.WORD, 0)
irqCurrentVariables["A"] = Value(DataType.BYTE, 0)
irqCurrentVariables["X"] = Value(DataType.BYTE, 0)
irqCurrentVariables["Y"] = Value(DataType.BYTE, 0)
irqCurrentVariables["AX"] = Value(DataType.WORD, 0)
irqCurrentVariables["AY"] = Value(DataType.WORD, 0)
irqCurrentVariables["XY"] = Value(DataType.WORD, 0)
initMemory(program.memory) initMemory(program.memory)
evalstack.clear() evalstack.clear()
callstack.clear() callstack.clear()
irqEvalStack.clear()
irqCallStack.clear()
P_carry = false P_carry = false
P_irqd = false P_irqd = false
sourceLine = "" sourceLine = ""
irqCurrentLine = ""
currentIns = this.program[0] currentIns = this.program[0]
irqCurrentIns = this.irqProgram[0]
} }
fun step(instructionCount: Int = 10000) { fun step(instructionCount: Int = 10000) {
@ -1568,4 +1530,55 @@ class StackVm(val traceOutputFile: String?) {
return ins.next return ins.next
} }
fun irq(timestamp: Long) {
// 60hz IRQ handling
if(P_irqd)
return // interrupt is disabled
P_irqd=true
swapIrqExecutionContexts(true)
val jiffies = min((timestamp-bootTime)*60/1000, 24*3600*60-1)
// update the C-64 60hz jiffy clock in the ZP addresses:
mem.setByte(0x00a0, (jiffies ushr 16).toShort())
mem.setByte(0x00a1, (jiffies ushr 8 and 255).toShort())
mem.setByte(0x00a2, (jiffies and 255).toShort())
try {
// execute the irq routine
this.step(Int.MAX_VALUE)
} catch(vmt: VmTerminationException) {
// irq routine ended
}
if(evalstack.isNotEmpty())
throw VmExecutionException("irq: eval stack is not empty at exit from irq program")
if(callstack.isNotEmpty())
throw VmExecutionException("irq: call stack is not empty at exit from irq program")
swapIrqExecutionContexts(false)
P_irqd=false
}
private lateinit var irqCurrentIns: Instruction
private var irqCurrentVariables = mutableMapOf<String, Value>()
private var irqCurrentLine: String = ""
private var irqEvalStack = MyStack<Value>()
private var irqCallStack = MyStack<Instruction>()
private var irqCarry = false
private fun swapIrqExecutionContexts(startingIrq: Boolean) {
irqCarry = P_carry.also { P_carry = irqCarry }
irqProgram = program.also { program = irqProgram }
irqCurrentIns = currentIns.also { currentIns = irqCurrentIns }
irqCurrentVariables = variables.also {variables = irqCurrentVariables }
irqCurrentLine = sourceLine.also { sourceLine = irqCurrentLine }
irqEvalStack = evalstack.also { evalstack = irqEvalStack }
irqCallStack = callstack.also { callstack = irqCallStack }
if(startingIrq) {
currentIns = program.first()
sourceLine = ""
P_carry = false
}
}
} }

View File

@ -50,7 +50,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testInitAndNop() { fun testInitAndNop() {
val ins = mutableListOf(Instruction(Opcode.NOP)) val ins = mutableListOf(Instruction(Opcode.NOP))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertEquals(6, vm.variables.size) assertEquals(6, vm.variables.size)
assertTrue(vm.variables.containsKey("XY")) assertTrue(vm.variables.containsKey("XY"))
assertTrue(vm.variables.containsKey("A")) assertTrue(vm.variables.containsKey("A"))
@ -65,7 +65,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testBreakpoint() { fun testBreakpoint() {
val ins = mutableListOf(Instruction(Opcode.BREAKPOINT)) val ins = mutableListOf(Instruction(Opcode.BREAKPOINT))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertFailsWith<VmBreakpointException> { assertFailsWith<VmBreakpointException> {
vm.step() vm.step()
} }
@ -76,7 +76,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testLine() { fun testLine() {
val ins = mutableListOf(Instruction(Opcode.LINE, Value(DataType.STR, null, "line 99"))) val ins = mutableListOf(Instruction(Opcode.LINE, Value(DataType.STR, null, "line 99")))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(1) vm.step(1)
assertEquals("line 99", vm.sourceLine) assertEquals("line 99", vm.sourceLine)
@ -85,7 +85,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testSECandSEIandCLCandCLI() { fun testSECandSEIandCLCandCLI() {
val ins = mutableListOf(Instruction(Opcode.SEC), Instruction(Opcode.SEI), Instruction(Opcode.CLC), Instruction(Opcode.CLI)) val ins = mutableListOf(Instruction(Opcode.SEC), Instruction(Opcode.SEI), Instruction(Opcode.CLC), Instruction(Opcode.CLI))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
assertFalse(vm.P_irqd) assertFalse(vm.P_irqd)
vm.step(1) vm.step(1)
@ -105,7 +105,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testPush() { fun testPush() {
val ins = mutableListOf(Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999))) val ins = mutableListOf(Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999)))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(1) vm.step(1)
assertEquals(1, vm.evalstack.size) assertEquals(1, vm.evalstack.size)
@ -122,7 +122,7 @@ class TestStackVmOpcodes {
val mem=mapOf(0x2000 to listOf(Value(DataType.WORD, 0x42ea)), val mem=mapOf(0x2000 to listOf(Value(DataType.WORD, 0x42ea)),
0x3000 to listOf(Value(DataType.WORD, 0x42ea)), 0x3000 to listOf(Value(DataType.WORD, 0x42ea)),
0x4000 to listOf(Value(DataType.FLOAT, 42.25))) 0x4000 to listOf(Value(DataType.FLOAT, 42.25)))
vm.load(makeProg(ins, mem=mem), null) vm.load(makeProg(ins, mem=mem), null, null)
assertEquals(0xea, vm.mem.getByte(0x2000)) assertEquals(0xea, vm.mem.getByte(0x2000))
assertEquals(0x42, vm.mem.getByte(0x2001)) assertEquals(0x42, vm.mem.getByte(0x2001))
assertEquals(0xea, vm.mem.getByte(0x3000)) assertEquals(0xea, vm.mem.getByte(0x3000))
@ -141,7 +141,7 @@ class TestStackVmOpcodes {
@Test @Test
fun testPushVar() { fun testPushVar() {
val ins = mutableListOf(Instruction(Opcode.PUSH_VAR, Value(DataType.STR, null, "varname"))) val ins = mutableListOf(Instruction(Opcode.PUSH_VAR, Value(DataType.STR, null, "varname")))
vm.load(makeProg(ins, mapOf("varname" to Value(DataType.FLOAT, 42.999))), null) vm.load(makeProg(ins, mapOf("varname" to Value(DataType.FLOAT, 42.999))), null, null)
assertEquals(7, vm.variables.size) assertEquals(7, vm.variables.size)
assertTrue(vm.variables.containsKey("varname")) assertTrue(vm.variables.containsKey("varname"))
assertTrue(vm.variables.containsKey("XY")) assertTrue(vm.variables.containsKey("XY"))
@ -159,7 +159,7 @@ class TestStackVmOpcodes {
val ins = mutableListOf( val ins = mutableListOf(
Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999)), Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999)),
Instruction(Opcode.DUP)) Instruction(Opcode.DUP))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(2) vm.step(2)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -174,7 +174,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.WORD, 9999)), Instruction(Opcode.PUSH, Value(DataType.WORD, 9999)),
Instruction(Opcode.SWAP) Instruction(Opcode.SWAP)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(3) vm.step(3)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -188,7 +188,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999)), Instruction(Opcode.PUSH, Value(DataType.FLOAT, 42.999)),
Instruction(Opcode.PUSH, Value(DataType.FLOAT, 3.1415)), Instruction(Opcode.PUSH, Value(DataType.FLOAT, 3.1415)),
Instruction(Opcode.DISCARD)) Instruction(Opcode.DISCARD))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(2) vm.step(2)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -204,7 +204,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.WORD, 222)), Instruction(Opcode.PUSH, Value(DataType.WORD, 222)),
Instruction(Opcode.PUSH, Value(DataType.WORD, 333)), Instruction(Opcode.PUSH, Value(DataType.WORD, 333)),
Instruction(Opcode.ARRAY, Value(DataType.WORD, 2))) Instruction(Opcode.ARRAY, Value(DataType.WORD, 2)))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(4) vm.step(4)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -218,7 +218,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.BYTE, 22)), Instruction(Opcode.PUSH, Value(DataType.BYTE, 22)),
Instruction(Opcode.PUSH, Value(DataType.BYTE, 33)), Instruction(Opcode.PUSH, Value(DataType.BYTE, 33)),
Instruction(Opcode.ARRAY, Value(DataType.WORD, 2))) Instruction(Opcode.ARRAY, Value(DataType.WORD, 2)))
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(4) vm.step(4)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -232,7 +232,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.WORD, 222)), Instruction(Opcode.PUSH, Value(DataType.WORD, 222)),
Instruction(Opcode.PUSH, Value(DataType.FLOAT, 333.33)), Instruction(Opcode.PUSH, Value(DataType.FLOAT, 333.33)),
Instruction(Opcode.ARRAY, Value(DataType.WORD, 2))) Instruction(Opcode.ARRAY, Value(DataType.WORD, 2)))
vm.load(makeProg(ins3), null) vm.load(makeProg(ins3), null, null)
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
vm.step(4) vm.step(4)
} }
@ -247,7 +247,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x2000)), Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x2000)),
Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x3000)), Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x3000)),
Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x4000))) Instruction(Opcode.POP_MEM, Value(DataType.WORD, 0x4000)))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertEquals(0, vm.mem.getWord(0x2000)) assertEquals(0, vm.mem.getWord(0x2000))
assertEquals(0, vm.mem.getWord(0x3000)) assertEquals(0, vm.mem.getWord(0x3000))
assertEquals(0.0, vm.mem.getFloat(0x4000)) assertEquals(0.0, vm.mem.getFloat(0x4000))
@ -274,7 +274,7 @@ class TestStackVmOpcodes {
"var2" to Value(DataType.WORD, 0), "var2" to Value(DataType.WORD, 0),
"var3" to Value(DataType.FLOAT, 0) "var3" to Value(DataType.FLOAT, 0)
) )
vm.load(makeProg(ins, vars), null) vm.load(makeProg(ins, vars), null, null)
assertEquals(9, vm.variables.size) assertEquals(9, vm.variables.size)
vm.step(6) vm.step(6)
assertEquals(Value(DataType.BYTE, 123), vm.variables["var1"]) assertEquals(Value(DataType.BYTE, 123), vm.variables["var1"])
@ -287,7 +287,7 @@ class TestStackVmOpcodes {
val vars2 = mapOf( val vars2 = mapOf(
"var1" to Value(DataType.BYTE, 0) "var1" to Value(DataType.BYTE, 0)
) )
vm.load(makeProg(ins2, vars2), null) vm.load(makeProg(ins2, vars2), null, null)
assertEquals(7, vm.variables.size) assertEquals(7, vm.variables.size)
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
vm.step(2) vm.step(2)
@ -597,7 +597,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.NEG), Instruction(Opcode.NEG),
Instruction(Opcode.NEG) Instruction(Opcode.NEG)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(2) vm.step(2)
assertEquals(1, vm.evalstack.size) assertEquals(1, vm.evalstack.size)
@ -610,7 +610,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.WORD, 1234)), Instruction(Opcode.PUSH, Value(DataType.WORD, 1234)),
Instruction(Opcode.NEG) Instruction(Opcode.NEG)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.WORD, 64302), vm.evalstack.pop()) assertEquals(Value(DataType.WORD, 64302), vm.evalstack.pop())
@ -618,7 +618,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.BYTE, 12)), Instruction(Opcode.PUSH, Value(DataType.BYTE, 12)),
Instruction(Opcode.NEG) Instruction(Opcode.NEG)
) )
vm.load(makeProg(ins3), null) vm.load(makeProg(ins3), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.BYTE, 244), vm.evalstack.pop()) assertEquals(Value(DataType.BYTE, 244), vm.evalstack.pop())
} }
@ -632,7 +632,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.INV), Instruction(Opcode.INV),
Instruction(Opcode.INV) Instruction(Opcode.INV)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertThat(vm.evalstack, empty()) assertThat(vm.evalstack, empty())
vm.step(3) vm.step(3)
assertEquals(2, vm.evalstack.size) assertEquals(2, vm.evalstack.size)
@ -645,7 +645,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.FLOAT, 1234.33)), Instruction(Opcode.PUSH, Value(DataType.FLOAT, 1234.33)),
Instruction(Opcode.INV) Instruction(Opcode.INV)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
vm.step(2) vm.step(2)
} }
@ -661,7 +661,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.LSB), Instruction(Opcode.LSB),
Instruction(Opcode.LSB) Instruction(Opcode.LSB)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(4) vm.step(4)
assertEquals(Value(DataType.BYTE, 0x31), vm.evalstack.pop()) assertEquals(Value(DataType.BYTE, 0x31), vm.evalstack.pop())
vm.step(1) vm.step(1)
@ -681,7 +681,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.MSB), Instruction(Opcode.MSB),
Instruction(Opcode.MSB) Instruction(Opcode.MSB)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(4) vm.step(4)
assertEquals(Value(DataType.BYTE, 0xea), vm.evalstack.pop()) assertEquals(Value(DataType.BYTE, 0xea), vm.evalstack.pop())
vm.step(1) vm.step(1)
@ -699,7 +699,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.B2WORD), Instruction(Opcode.B2WORD),
Instruction(Opcode.B2WORD) Instruction(Opcode.B2WORD)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.WORD, 0x0045), vm.evalstack.pop()) assertEquals(Value(DataType.WORD, 0x0045), vm.evalstack.pop())
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
@ -715,7 +715,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.MSB2WORD), Instruction(Opcode.MSB2WORD),
Instruction(Opcode.MSB2WORD) Instruction(Opcode.MSB2WORD)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.WORD, 0x4500), vm.evalstack.pop()) assertEquals(Value(DataType.WORD, 0x4500), vm.evalstack.pop())
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
@ -731,7 +731,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.B2FLOAT), Instruction(Opcode.B2FLOAT),
Instruction(Opcode.B2FLOAT) Instruction(Opcode.B2FLOAT)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.FLOAT, 123.0), vm.evalstack.pop()) assertEquals(Value(DataType.FLOAT, 123.0), vm.evalstack.pop())
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
@ -747,7 +747,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.W2FLOAT), Instruction(Opcode.W2FLOAT),
Instruction(Opcode.W2FLOAT) Instruction(Opcode.W2FLOAT)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.FLOAT, 12345.0), vm.evalstack.pop()) assertEquals(Value(DataType.FLOAT, 12345.0), vm.evalstack.pop())
assertFailsWith<VmExecutionException> { assertFailsWith<VmExecutionException> {
@ -765,7 +765,7 @@ class TestStackVmOpcodes {
) )
val mem=mapOf(0x2000 to listOf(Value(DataType.BYTE, 100), Value(DataType.BYTE, 255)), val mem=mapOf(0x2000 to listOf(Value(DataType.BYTE, 100), Value(DataType.BYTE, 255)),
0x3000 to listOf(Value(DataType.WORD, 0x42ea), Value(DataType.WORD, 0xffff))) 0x3000 to listOf(Value(DataType.WORD, 0x42ea), Value(DataType.WORD, 0xffff)))
vm.load(makeProg(ins, mem=mem), null) vm.load(makeProg(ins, mem=mem), null, null)
vm.step(4) vm.step(4)
assertEquals(101, vm.mem.getByte(0x2000)) assertEquals(101, vm.mem.getByte(0x2000))
assertEquals(0, vm.mem.getByte(0x2001)) assertEquals(0, vm.mem.getByte(0x2001))
@ -782,7 +782,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.INC_VAR, Value(DataType.STR, null, "var2"))) Instruction(Opcode.INC_VAR, Value(DataType.STR, null, "var2")))
val vars = mapOf("var1" to Value(DataType.WORD, 65534), val vars = mapOf("var1" to Value(DataType.WORD, 65534),
"var2" to Value(DataType.BYTE, 254)) "var2" to Value(DataType.BYTE, 254))
vm.load(makeProg(ins, vars = vars), null) vm.load(makeProg(ins, vars = vars), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.WORD, 65535), vm.variables["var1"]) assertEquals(Value(DataType.WORD, 65535), vm.variables["var1"])
assertEquals(Value(DataType.BYTE, 255), vm.variables["var2"]) assertEquals(Value(DataType.BYTE, 255), vm.variables["var2"])
@ -800,7 +800,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.DEC_VAR, Value(DataType.STR, null, "var2"))) Instruction(Opcode.DEC_VAR, Value(DataType.STR, null, "var2")))
val vars = mapOf("var1" to Value(DataType.WORD,1), val vars = mapOf("var1" to Value(DataType.WORD,1),
"var2" to Value(DataType.BYTE, 1)) "var2" to Value(DataType.BYTE, 1))
vm.load(makeProg(ins, vars = vars), null) vm.load(makeProg(ins, vars = vars), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.WORD, 0), vm.variables["var1"]) assertEquals(Value(DataType.WORD, 0), vm.variables["var1"])
assertEquals(Value(DataType.BYTE, 0), vm.variables["var2"]) assertEquals(Value(DataType.BYTE, 0), vm.variables["var2"])
@ -819,7 +819,7 @@ class TestStackVmOpcodes {
) )
val mem=mapOf(0x2000 to listOf(Value(DataType.BYTE, 100), Value(DataType.BYTE, 0)), val mem=mapOf(0x2000 to listOf(Value(DataType.BYTE, 100), Value(DataType.BYTE, 0)),
0x3000 to listOf(Value(DataType.WORD, 0x42ea), Value(DataType.WORD, 0))) 0x3000 to listOf(Value(DataType.WORD, 0x42ea), Value(DataType.WORD, 0)))
vm.load(makeProg(ins, mem=mem), null) vm.load(makeProg(ins, mem=mem), null, null)
vm.step(4) vm.step(4)
assertEquals(99, vm.mem.getByte(0x2000)) assertEquals(99, vm.mem.getByte(0x2000))
assertEquals(255, vm.mem.getByte(0x2001)) assertEquals(255, vm.mem.getByte(0x2001))
@ -838,7 +838,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.PUSH, Value(DataType.WORD, 25544)), Instruction(Opcode.PUSH, Value(DataType.WORD, 25544)),
Instruction(Opcode.SYSCALL, Value(DataType.BYTE, Syscall.FUNC_SIN.callNr)) Instruction(Opcode.SYSCALL, Value(DataType.BYTE, Syscall.FUNC_SIN.callNr))
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(4) vm.step(4)
val rndb1 = vm.evalstack.pop() val rndb1 = vm.evalstack.pop()
@ -1047,7 +1047,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(3) vm.step(3)
@ -1067,7 +1067,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
@ -1088,7 +1088,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(3) vm.step(3)
@ -1108,7 +1108,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(3) vm.step(3)
@ -1130,7 +1130,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(2) vm.step(2)
@ -1152,7 +1152,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
vm.step(3) vm.step(3)
@ -1169,7 +1169,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2"))) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string2")))
val labels = mapOf("label" to ins.last()) // points to the second LINE instruction val labels = mapOf("label" to ins.last()) // points to the second LINE instruction
vm.load(makeProg(ins, labels=labels), null) vm.load(makeProg(ins, labels=labels), null, null)
vm.step(2) vm.step(2)
assertEquals("string2", vm.sourceLine) assertEquals("string2", vm.sourceLine)
assertEquals(0, vm.callstack.size) assertEquals(0, vm.callstack.size)
@ -1184,7 +1184,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.TERMINATE), Instruction(Opcode.TERMINATE),
Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string1")) Instruction(Opcode.LINE, Value(DataType.STR, null, stringvalue = "string1"))
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
assertFailsWith<VmTerminationException> { assertFailsWith<VmTerminationException> {
vm.step(1) vm.step(1)
} }
@ -1208,7 +1208,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.RETURN) Instruction(Opcode.RETURN)
) )
val labels = mapOf("label" to ins[3]) // points to the LINE instruction val labels = mapOf("label" to ins[3]) // points to the LINE instruction
vm.load(makeProg(ins, labels = labels), null) vm.load(makeProg(ins, labels = labels), null, null)
vm.step(1) vm.step(1)
assertEquals("", vm.sourceLine) assertEquals("", vm.sourceLine)
assertEquals(1, vm.callstack.size) assertEquals(1, vm.callstack.size)
@ -1244,7 +1244,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.DISCARD), Instruction(Opcode.DISCARD),
Instruction(Opcode.SHR) // error Instruction(Opcode.SHR) // error
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(6) vm.step(6)
assertEquals(Value(DataType.BYTE, 124), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 124), vm.evalstack.peek())
vm.step(2) vm.step(2)
@ -1282,7 +1282,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.DISCARD), Instruction(Opcode.DISCARD),
Instruction(Opcode.SHL) // error Instruction(Opcode.SHL) // error
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(6) vm.step(6)
assertEquals(Value(DataType.BYTE, 242), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 242), vm.evalstack.peek())
vm.step(2) vm.step(2)
@ -1313,7 +1313,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROR), // 0b00100110 c=1 Instruction(Opcode.ROR), // 0b00100110 c=1
Instruction(Opcode.ROR) // 0b10010011 c=0 (original value after 9 rors) Instruction(Opcode.ROR) // 0b10010011 c=0 (original value after 9 rors)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.BYTE, 0b01001001), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 0b01001001), vm.evalstack.peek())
assertTrue(vm.P_carry) assertTrue(vm.P_carry)
@ -1351,7 +1351,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROR), Instruction(Opcode.ROR),
Instruction(Opcode.ROR) // 0b1001001100001101 c=0 (original value after 17 rors) Instruction(Opcode.ROR) // 0b1001001100001101 c=0 (original value after 17 rors)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.WORD, 0b0100100110000110), vm.evalstack.peek()) assertEquals(Value(DataType.WORD, 0b0100100110000110), vm.evalstack.peek())
assertTrue(vm.P_carry) assertTrue(vm.P_carry)
@ -1378,7 +1378,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROL), // 0b01001001 c=1 Instruction(Opcode.ROL), // 0b01001001 c=1
Instruction(Opcode.ROL) // 0b10010011 c=0 (original value after 9 rors) Instruction(Opcode.ROL) // 0b10010011 c=0 (original value after 9 rors)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.BYTE, 0b00100110), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 0b00100110), vm.evalstack.peek())
assertTrue(vm.P_carry) assertTrue(vm.P_carry)
@ -1416,7 +1416,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROL), Instruction(Opcode.ROL),
Instruction(Opcode.ROL) // 0b1001001100001101 c=0 (original value after 17 rors) Instruction(Opcode.ROL) // 0b1001001100001101 c=0 (original value after 17 rors)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
vm.step(3) vm.step(3)
assertEquals(Value(DataType.WORD, 0b0010011000011010), vm.evalstack.peek()) assertEquals(Value(DataType.WORD, 0b0010011000011010), vm.evalstack.peek())
assertTrue(vm.P_carry) assertTrue(vm.P_carry)
@ -1442,7 +1442,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROR2), Instruction(Opcode.ROR2),
Instruction(Opcode.ROR2) // 0b10010011 (original value after 8 rors) Instruction(Opcode.ROR2) // 0b10010011 (original value after 8 rors)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.BYTE, 0b11001001), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 0b11001001), vm.evalstack.peek())
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
@ -1472,7 +1472,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROR2), Instruction(Opcode.ROR2),
Instruction(Opcode.ROR2) // 0b1001001100001101 (original value after 16 rors) Instruction(Opcode.ROR2) // 0b1001001100001101 (original value after 16 rors)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.WORD, 0b1100100110000110), vm.evalstack.peek()) assertEquals(Value(DataType.WORD, 0b1100100110000110), vm.evalstack.peek())
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
@ -1496,7 +1496,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROL2), Instruction(Opcode.ROL2),
Instruction(Opcode.ROL2) // 0b10010011 (original value after 8 rols) Instruction(Opcode.ROL2) // 0b10010011 (original value after 8 rols)
) )
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.BYTE, 0b00100111), vm.evalstack.peek()) assertEquals(Value(DataType.BYTE, 0b00100111), vm.evalstack.peek())
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
@ -1524,7 +1524,7 @@ class TestStackVmOpcodes {
Instruction(Opcode.ROL2), Instruction(Opcode.ROL2),
Instruction(Opcode.ROL2) // 0b1001001100001101 (original value after 16 rols) Instruction(Opcode.ROL2) // 0b1001001100001101 (original value after 16 rols)
) )
vm.load(makeProg(ins2), null) vm.load(makeProg(ins2), null, null)
vm.step(2) vm.step(2)
assertEquals(Value(DataType.WORD, 0b0010011000011011), vm.evalstack.peek()) assertEquals(Value(DataType.WORD, 0b0010011000011011), vm.evalstack.peek())
assertFalse(vm.P_carry) assertFalse(vm.P_carry)
@ -1544,7 +1544,7 @@ class TestStackVmOpcodes {
ins.add(Instruction(Opcode.PUSH, vars.next())) ins.add(Instruction(Opcode.PUSH, vars.next()))
ins.add(Instruction(operator)) ins.add(Instruction(operator))
} }
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
for(expectedValue in expected) { for(expectedValue in expected) {
vm.step(3) vm.step(3)
assertEquals(Value(DataType.BYTE, expectedValue), vm.evalstack.pop()) assertEquals(Value(DataType.BYTE, expectedValue), vm.evalstack.pop())
@ -1558,7 +1558,7 @@ class TestStackVmOpcodes {
ins.add(Instruction(Opcode.PUSH, value)) ins.add(Instruction(Opcode.PUSH, value))
for (i in 1 until values.size) for (i in 1 until values.size)
ins.add(Instruction(operator)) ins.add(Instruction(operator))
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(values.size) vm.step(values.size)
assertEquals(values.size, vm.evalstack.size) assertEquals(values.size, vm.evalstack.size)
for (expectedVal in expected) { for (expectedVal in expected) {
@ -1579,7 +1579,7 @@ class TestStackVmOpcodes {
ins.add(Instruction(operator)) ins.add(Instruction(operator))
ins.add(Instruction(Opcode.DISCARD)) ins.add(Instruction(Opcode.DISCARD))
} }
vm.load(makeProg(ins), null) vm.load(makeProg(ins), null, null)
vm.step(values.size) vm.step(values.size)
assertEquals(values.size, vm.evalstack.size) assertEquals(values.size, vm.evalstack.size)
for (expectedVal in expected) { for (expectedVal in expected) {