diff --git a/compiler/src/prog8/vm/RuntimeValue.kt b/compiler/src/prog8/vm/RuntimeValue.kt index 58c8691ee..4ce740125 100644 --- a/compiler/src/prog8/vm/RuntimeValue.kt +++ b/compiler/src/prog8/vm/RuntimeValue.kt @@ -26,7 +26,7 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= in NumericDatatypes -> RuntimeValue(literalValue.type, num = literalValue.asNumericValue!!) in StringDatatypes -> from(literalValue.heapId!!, heap) in ArrayDatatypes -> from(literalValue.heapId!!, heap) - else -> TODO("type") + else -> throw IllegalArgumentException("weird source value $literalValue") } } @@ -40,11 +40,19 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= RuntimeValue(value.type, array = value.doubleArray!!.toList().toTypedArray(), heapId = heapId) } else { val array = value.array!! - if (array.any { it.addressOf != null }) - TODO("addressof values") - RuntimeValue(value.type, array = array.map { it.integer!! }.toTypedArray(), heapId = heapId) + val resultArray = mutableListOf() + for(elt in array.withIndex()){ + if(elt.value.integer!=null) + resultArray.add(elt.value.integer!!) + else { + println("ADDRESSOF ${elt.value}") + resultArray.add(0x8000) + } + } + RuntimeValue(value.type, array = resultArray.toTypedArray(), heapId = heapId) + //RuntimeValue(value.type, array = array.map { it.integer!! }.toTypedArray(), heapId = heapId) } - else -> TODO("weird type on heap") + else -> throw IllegalArgumentException("weird value type on heap $value") } } @@ -114,7 +122,7 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= in ArrayDatatypes -> LiteralValue(type, arrayvalue = array?.map { LiteralValue.optimalNumeric(it, Position("", 0, 0, 0)) }?.toTypedArray(), position = Position("", 0, 0, 0)) - else -> TODO("strange type") + else -> throw IllegalArgumentException("weird source value $this") } } @@ -575,7 +583,13 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?= } DataType.WORD -> { when (targetType) { - DataType.BYTE -> RuntimeValue(DataType.BYTE, integerValue() and 255) + DataType.BYTE -> { + val v = integerValue() and 255 + if(v<128) + RuntimeValue(DataType.BYTE, v) + else + RuntimeValue(DataType.BYTE, v-256) + } DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 65535) DataType.UWORD -> RuntimeValue(DataType.UWORD, integerValue()) DataType.WORD -> this diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 15498e40b..6b14da1fa 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -11,6 +11,7 @@ import prog8.vm.RuntimeValue import prog8.vm.RuntimeValueRange import prog8.compiler.target.c64.Petscii import java.awt.EventQueue +import java.io.CharConversionException import java.util.* import kotlin.NoSuchElementException import kotlin.concurrent.fixedRateTimer @@ -228,6 +229,7 @@ class AstVm(val program: Program) { } } } + dialog.canvas.printText("\n", true) println("PROGRAM EXITED!") dialog.title = "PROGRAM EXITED" } catch (tx: VmTerminationException) { @@ -634,9 +636,6 @@ class AstVm(val program: Program) { private fun evaluate(args: List) = args.map { evaluate(it, evalCtx) } private fun performSyscall(sub: Subroutine, args: List): List { - if(!sub.isAsmSubroutine) - throw VmExecutionException("asmsub expected for syscall $sub") - val result = mutableListOf() when (sub.scopedname) { "c64scr.print" -> { @@ -697,6 +696,32 @@ class AstVm(val program: Program) { "c64scr.plot" -> { dialog.canvas.setCursorPos(args[0].integerValue(), args[1].integerValue()) } + "c64scr.input_chars" -> { + val input=mutableListOf() + for(i in 0 until 80) { + while(dialog.keyboardBuffer.isEmpty()) { + Thread.sleep(10) + } + val char=dialog.keyboardBuffer.pop() + if(char=='\n') + break + else { + input.add(char) + val printChar = try { + Petscii.encodePetscii("" + char, true).first() + } catch (cv: CharConversionException) { + 0x3f.toShort() + } + dialog.canvas.printPetscii(printChar) + } + } + val inputStr = input.joinToString("") + val heapId = args[0].wordval!! + val origStr = program.heap.get(heapId).str!! + val paddedStr=inputStr.padEnd(origStr.length+1, '\u0000').substring(0, origStr.length) + program.heap.update(heapId, paddedStr) + result.add(RuntimeValue(DataType.UBYTE, paddedStr.indexOf('\u0000'))) + } "c64flt.print_f" -> { dialog.canvas.printText(args[0].floatval.toString(), true) } @@ -713,6 +738,12 @@ class AstVm(val program: Program) { val char=dialog.keyboardBuffer.pop() result.add(RuntimeValue(DataType.UBYTE, char.toShort())) } + "c64utils.str2uword" -> { + val heapId = args[0].wordval!! + val argString = program.heap.get(heapId).str!! + val numericpart = argString.takeWhile { it.isDigit() } + result.add(RuntimeValue(DataType.UWORD, numericpart.toInt() and 65535)) + } else -> TODO("syscall ${sub.scopedname} $sub") } diff --git a/compiler/src/prog8/vm/astvm/ScreenDialog.kt b/compiler/src/prog8/vm/astvm/ScreenDialog.kt index 7aa6cd138..94a4679ec 100644 --- a/compiler/src/prog8/vm/astvm/ScreenDialog.kt +++ b/compiler/src/prog8/vm/astvm/ScreenDialog.kt @@ -68,24 +68,10 @@ class BitmapScreenPanel : KeyListener, JPanel() { val t2 = text.substringBefore(0.toChar()) val lines = t2.split('\n') for(line in lines.withIndex()) { - printTextSingleLine(line.value, lowercase, inverseVideo) + val petscii = Petscii.encodePetscii(line.value, lowercase) + petscii.forEach { printPetscii(it, inverseVideo) } if(line.index=(SCREENWIDTH /8)) { - cursorY++ - cursorX=0 + printPetscii(13) // newline } } } @@ -102,6 +88,18 @@ class BitmapScreenPanel : KeyListener, JPanel() { cursorX = 0 } } + while(cursorY>=(SCREENHEIGHT/8)) { + // scroll the screen up because the cursor went past the last line + Thread.sleep(10) + val screen = image.copy() + val graphics = image.graphics as Graphics2D + graphics.drawImage(screen, 0, -8, null) + val color = graphics.color + graphics.color = Colors.palette[6] + graphics.fillRect(0, 24*8, SCREENWIDTH, 25*8) + graphics.color=color + cursorY-- + } } fun writeTextAt(x: Int, y: Int, text: String, color: Short, lowercase: Boolean, inverseVideo: Boolean=false) { @@ -201,3 +199,12 @@ class ScreenDialog(title: String) : JFrame(title) { repaintTimer.start() } } + + +private fun BufferedImage.copy(): BufferedImage { + val bcopy = BufferedImage(this.width, this.height, this.type) + val g = bcopy.graphics + g.drawImage(this, 0, 0, null) + g.dispose() + return bcopy +} diff --git a/examples/numbergame.p8 b/examples/numbergame.p8 index f980cc05d..68cef5c6e 100644 --- a/examples/numbergame.p8 +++ b/examples/numbergame.p8 @@ -42,7 +42,7 @@ } } - return ending(false) + return ending(false) ; @todo error sub ending(ubyte success) { diff --git a/examples/test.p8 b/examples/test.p8 index a48559000..590cb1cd8 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,12 +4,14 @@ ~ main { sub start() { + str naam = " " + while true { - c64scr.print_ub(c64.TIME_HI) + c64scr.print("naam: ") + ubyte length = c64scr.input_chars(naam) + c64scr.print_ub(length) c64.CHROUT(':') - c64scr.print_ub(c64.TIME_MID) - c64.CHROUT(':') - c64scr.print_ub(c64.TIME_LO) + c64scr.print(naam) c64.CHROUT('\n') } }