astvm can now more or less run all examples

This commit is contained in:
Irmen de Jong 2019-07-10 18:44:54 +02:00
parent d4b3e35bd2
commit 3d7a4bf81a
5 changed files with 86 additions and 32 deletions

View File

@ -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<Number>()
for(elt in array.withIndex()){
if(elt.value.integer!=null)
resultArray.add(elt.value.integer!!)
else {
println("ADDRESSOF ${elt.value}")
resultArray.add(0x8000)
}
else -> TODO("weird type on heap")
}
RuntimeValue(value.type, array = resultArray.toTypedArray(), heapId = heapId)
//RuntimeValue(value.type, array = array.map { it.integer!! }.toTypedArray(), heapId = heapId)
}
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

View File

@ -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<program ended>", 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<IExpression>) = args.map { evaluate(it, evalCtx) }
private fun performSyscall(sub: Subroutine, args: List<RuntimeValue>): List<RuntimeValue> {
if(!sub.isAsmSubroutine)
throw VmExecutionException("asmsub expected for syscall $sub")
val result = mutableListOf<RuntimeValue>()
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<Char>()
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")
}

View File

@ -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<lines.size-1) {
cursorX=0
cursorY++
}
}
}
private fun printTextSingleLine(text: String, lowercase: Boolean, inverseVideo: Boolean=false) {
for(clearx in cursorX until cursorX+text.length) {
g2d.clearRect(8*clearx, 8*y, 8, 8)
}
for(sc in Petscii.encodePetscii(text, lowercase)) {
setPetscii(cursorX, cursorY, sc, 1, inverseVideo)
cursorX++
if(cursorX>=(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
}

View File

@ -42,7 +42,7 @@
}
}
return ending(false)
return ending(false) ; @todo error
sub ending(ubyte success) {

View File

@ -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')
}
}