astvm almost complete

This commit is contained in:
Irmen de Jong 2019-07-10 16:06:11 +02:00
parent a59f7c75dc
commit d4b3e35bd2
7 changed files with 235 additions and 132 deletions

View File

@ -6,9 +6,7 @@ import prog8.ast.base.DataType
import prog8.ast.base.FatalAstException
import prog8.ast.base.initvarsSubName
import prog8.ast.base.printWarning
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.FunctionCall
import prog8.ast.expressions.TypecastExpression
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.functions.BuiltinFunctions
@ -292,4 +290,33 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
.sortWith(compareBy<WhenChoice, Int?>(nullsLast(), {it.values?.single()?.constValue(program)?.asIntegerValue}))
return super.visit(whenStatement)
}
override fun visit(memread: DirectMemoryRead): IExpression {
// make sure the memory address is an uword
val dt = memread.addressExpression.inferType(program)
if(dt!=DataType.UWORD) {
val literaladdr = memread.addressExpression as? LiteralValue
if(literaladdr!=null) {
memread.addressExpression = literaladdr.cast(DataType.UWORD)!!
} else {
memread.addressExpression = TypecastExpression(memread.addressExpression, DataType.UWORD, true, memread.addressExpression.position)
memread.addressExpression.parent = memread
}
}
return super.visit(memread)
}
override fun visit(memwrite: DirectMemoryWrite) {
val dt = memwrite.addressExpression.inferType(program)
if(dt!=DataType.UWORD) {
val literaladdr = memwrite.addressExpression as? LiteralValue
if(literaladdr!=null) {
memwrite.addressExpression = literaladdr.cast(DataType.UWORD)!!
} else {
memwrite.addressExpression = TypecastExpression(memwrite.addressExpression, DataType.UWORD, true, memwrite.addressExpression.position)
memwrite.addressExpression.parent = memwrite
}
}
super.visit(memwrite)
}
}

View File

@ -88,7 +88,7 @@ fun compileProgram(filepath: Path,
programAst.checkValid(compilerOptions) // check if final tree is valid
programAst.checkRecursion() // check if there are recursive subroutine calls
// printAst(programAst)
printAst(programAst)
// namespace.debugPrint()
if(generateVmCode) {

View File

@ -553,10 +553,22 @@ open class RuntimeValue(val type: DataType, num: Number?=null, val str: String?=
}
DataType.UWORD -> {
when (targetType) {
DataType.BYTE -> RuntimeValue(DataType.BYTE, integerValue())
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue())
DataType.BYTE -> {
val v=integerValue()
if(v<128)
RuntimeValue(DataType.BYTE, v)
else
RuntimeValue(DataType.BYTE, v-256)
}
DataType.UBYTE -> RuntimeValue(DataType.UBYTE, integerValue() and 255)
DataType.UWORD -> this
DataType.WORD -> RuntimeValue(DataType.WORD, integerValue())
DataType.WORD -> {
val v=integerValue()
if(v<32768)
RuntimeValue(DataType.WORD, v)
else
RuntimeValue(DataType.WORD, v-65536)
}
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, numericValue())
else -> throw ArithmeticException("invalid type cast from $type to $targetType")
}

View File

@ -6,6 +6,7 @@ import prog8.ast.base.initvarsSubName
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.LiteralValue
import prog8.ast.statements.*
import prog8.compiler.target.c64.Mflpt5
import prog8.vm.RuntimeValue
import prog8.vm.RuntimeValueRange
import prog8.compiler.target.c64.Petscii
@ -136,8 +137,10 @@ class AstVm(val program: Program) {
init {
// observe the jiffyclock
// observe the jiffyclock and screen matrix
mem.observe(0xa0, 0xa1, 0xa2)
for(i in 1024..2023)
mem.observe(i)
dialog.requestFocusInWindow()
@ -166,6 +169,11 @@ class AstVm(val program: Program) {
val jiffies = (time_hi.toInt() shl 16) + (time_mid.toInt() shl 8) + time_lo
rtcOffset = bootTime - (jiffies*1000/60)
}
if(address in 1024..2023) {
// write to the screen matrix
val scraddr = address-1024
dialog.canvas.setChar(scraddr % 40, scraddr / 40, value, 1)
}
return value
}
@ -235,7 +243,11 @@ class AstVm(val program: Program) {
if(statusflags.irqd)
return // interrupt is disabled
val jiffies = min((timeStamp-rtcOffset)*60/1000, 24*3600*60-1)
var jiffies = (timeStamp-rtcOffset)*60/1000
if(jiffies>24*3600*60-1) {
jiffies = 0
rtcOffset = timeStamp
}
// update the C-64 60hz jiffy clock in the ZP addresses:
mem.setUByte_DMA(0x00a0, (jiffies ushr 16).toShort())
mem.setUByte_DMA(0x00a1, (jiffies ushr 8 and 255).toShort())
@ -252,7 +264,10 @@ class AstVm(val program: Program) {
internal fun executeSubroutine(sub: Subroutine, arguments: List<RuntimeValue>, startlabel: Label?=null): List<RuntimeValue> {
assert(!sub.isAsmSubroutine)
if(sub.isAsmSubroutine) {
return performSyscall(sub, arguments)
}
if (sub.statements.isEmpty())
throw VmTerminationException("scope contains no statements: $sub")
if (arguments.size != sub.parameters.size)
@ -352,19 +367,49 @@ class AstVm(val program: Program) {
stmt.target.identifier != null -> {
val ident = stmt.definingScope().lookup(stmt.target.identifier!!.nameInSource, stmt) as VarDecl
val identScope = ident.definingScope()
var value = runtimeVariables.get(identScope, ident.name)
value = when {
stmt.operator == "++" -> value.add(RuntimeValue(value.type, 1))
stmt.operator == "--" -> value.sub(RuntimeValue(value.type, 1))
else -> throw VmExecutionException("strange postincdec operator $stmt")
when(ident.type){
VarDeclType.VAR -> {
var value = runtimeVariables.get(identScope, ident.name)
value = when {
stmt.operator == "++" -> value.add(RuntimeValue(value.type, 1))
stmt.operator == "--" -> value.sub(RuntimeValue(value.type, 1))
else -> throw VmExecutionException("strange postincdec operator $stmt")
}
runtimeVariables.set(identScope, ident.name, value)
}
VarDeclType.MEMORY -> {
val addr=ident.value!!.constValue(program)!!.asIntegerValue!!
val newval = when {
stmt.operator == "++" -> mem.getUByte(addr)+1 and 255
stmt.operator == "--" -> mem.getUByte(addr)-1 and 255
else -> throw VmExecutionException("strange postincdec operator $stmt")
}
mem.setUByte(addr,newval.toShort())
}
VarDeclType.CONST -> throw VmExecutionException("can't be const")
}
runtimeVariables.set(identScope, ident.name, value)
}
stmt.target.memoryAddress != null -> {
TODO("postincrdecr memory $stmt")
val addr = evaluate(stmt.target.memoryAddress!!.addressExpression, evalCtx).integerValue()
val newval = when {
stmt.operator == "++" -> mem.getUByte(addr)+1 and 255
stmt.operator == "--" -> mem.getUByte(addr)-1 and 255
else -> throw VmExecutionException("strange postincdec operator $stmt")
}
mem.setUByte(addr,newval.toShort())
}
stmt.target.arrayindexed != null -> {
TODO("postincrdecr array $stmt")
val arrayvar = stmt.target.arrayindexed!!.identifier.targetVarDecl(program.namespace)!!
val arrayvalue = runtimeVariables.get(arrayvar.definingScope(), arrayvar.name)
val elementType = stmt.target.arrayindexed!!.inferType(program)!!
val index = evaluate(stmt.target.arrayindexed!!.arrayspec.index, evalCtx).integerValue()
var value = RuntimeValue(elementType, arrayvalue.array!![index].toInt())
when {
stmt.operator == "++" -> value=value.inc()
stmt.operator == "--" -> value=value.dec()
else -> throw VmExecutionException("strange postincdec operator $stmt")
}
arrayvalue.array[index] = value.numericValue()
}
stmt.target.register != null -> {
var value = runtimeVariables.get(program.namespace, stmt.target.register!!.name)
@ -504,7 +549,7 @@ class AstVm(val program: Program) {
DataType.FLOAT -> mem.setFloat(address, value.floatval!!)
DataType.STR -> mem.setString(address, value.str!!)
DataType.STR_S -> mem.setScreencodeString(address, value.str!!)
else -> TODO("set memvar $decl")
else -> throw VmExecutionException("weird memaddress type $decl")
}
} else
runtimeVariables.set(decl.definingScope(), decl.name, value)
@ -514,46 +559,62 @@ class AstVm(val program: Program) {
evalCtx.mem.setUByte(address, value.byteval!!)
}
target.arrayindexed != null -> {
val array = evaluate(target.arrayindexed.identifier, evalCtx)
val index = evaluate(target.arrayindexed.arrayspec.index, evalCtx)
when (array.type) {
DataType.ARRAY_UB -> {
if (value.type != DataType.UBYTE)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
val vardecl = target.arrayindexed.identifier.targetVarDecl(program.namespace)!!
if(vardecl.type==VarDeclType.VAR) {
val array = evaluate(target.arrayindexed.identifier, evalCtx)
val index = evaluate(target.arrayindexed.arrayspec.index, evalCtx)
when (array.type) {
DataType.ARRAY_UB -> {
if (value.type != DataType.UBYTE)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_B -> {
if (value.type != DataType.BYTE)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_UW -> {
if (value.type != DataType.UWORD)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_W -> {
if (value.type != DataType.WORD)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_F -> {
if (value.type != DataType.FLOAT)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.STR, DataType.STR_S -> {
if (value.type !in ByteDatatypes)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
else -> throw VmExecutionException("strange array type ${array.type}")
}
DataType.ARRAY_B -> {
if (value.type != DataType.BYTE)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
if (array.type in ArrayDatatypes)
array.array!![index.integerValue()] = value.numericValue()
else if (array.type in StringDatatypes) {
val indexInt = index.integerValue()
val newchr = Petscii.decodePetscii(listOf(value.numericValue().toShort()), true)
val newstr = array.str!!.replaceRange(indexInt, indexInt + 1, newchr)
val ident = contextStmt.definingScope().lookup(target.arrayindexed.identifier.nameInSource, contextStmt) as? VarDecl
?: throw VmExecutionException("can't find assignment target ${target.identifier}")
val identScope = ident.definingScope()
program.heap.update(array.heapId!!, newstr)
runtimeVariables.set(identScope, ident.name, RuntimeValue(array.type, str = newstr, heapId = array.heapId))
}
DataType.ARRAY_UW -> {
if (value.type != DataType.UWORD)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_W -> {
if (value.type != DataType.WORD)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.ARRAY_F -> {
if (value.type != DataType.FLOAT)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
DataType.STR, DataType.STR_S -> {
if (value.type !in ByteDatatypes)
throw VmExecutionException("new value is of different datatype ${value.type} for $array")
}
else -> throw VmExecutionException("strange array type ${array.type}")
}
if (array.type in ArrayDatatypes)
array.array!![index.integerValue()] = value.numericValue()
else if (array.type in StringDatatypes) {
val indexInt = index.integerValue()
val newchr = Petscii.decodePetscii(listOf(value.numericValue().toShort()), true)
val newstr = array.str!!.replaceRange(indexInt, indexInt + 1, newchr)
val ident = contextStmt.definingScope().lookup(target.arrayindexed.identifier.nameInSource, contextStmt) as? VarDecl
?: throw VmExecutionException("can't find assignment target ${target.identifier}")
val identScope = ident.definingScope()
program.heap.update(array.heapId!!, newstr)
runtimeVariables.set(identScope, ident.name, RuntimeValue(array.type, str = newstr, heapId = array.heapId))
else {
val address = (vardecl.value as LiteralValue).asIntegerValue!!
val index = evaluate(target.arrayindexed.arrayspec.index, evalCtx).integerValue()
val elementType = target.arrayindexed.inferType(program)!!
when(elementType) {
DataType.UBYTE -> mem.setUByte(address+index, value.byteval!!)
DataType.BYTE -> mem.setSByte(address+index, value.byteval!!)
DataType.UWORD -> mem.setUWord(address+index*2, value.wordval!!)
DataType.WORD -> mem.setSWord(address+index*2, value.wordval!!)
DataType.FLOAT -> mem.setFloat(address+index*Mflpt5.MemorySize, value.floatval!!)
else -> throw VmExecutionException("strange array elt type $elementType")
}
}
}
target.register != null -> {
@ -572,54 +633,57 @@ class AstVm(val program: Program) {
private fun evaluate(args: List<IExpression>) = args.map { evaluate(it, evalCtx) }
private fun performSyscall(sub: Subroutine, args: List<RuntimeValue>) {
assert(sub.isAsmSubroutine)
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" -> {
// if the argument is an UWORD, consider it to be the "address" of the string (=heapId)
if (args[0].wordval != null) {
val str = program.heap.get(args[0].wordval!!).str!!
dialog.canvas.printText(str, 1, true)
dialog.canvas.printText(str, true)
} else
dialog.canvas.printText(args[0].str!!, 1, true)
dialog.canvas.printText(args[0].str!!, true)
}
"c64scr.print_ub" -> {
dialog.canvas.printText(args[0].byteval!!.toString(), 1, true)
dialog.canvas.printText(args[0].byteval!!.toString(), true)
}
"c64scr.print_ub0" -> {
dialog.canvas.printText("%03d".format(args[0].byteval!!), 1, true)
dialog.canvas.printText("%03d".format(args[0].byteval!!), true)
}
"c64scr.print_b" -> {
dialog.canvas.printText(args[0].byteval!!.toString(), 1, true)
dialog.canvas.printText(args[0].byteval!!.toString(), true)
}
"c64scr.print_uw" -> {
dialog.canvas.printText(args[0].wordval!!.toString(), 1, true)
dialog.canvas.printText(args[0].wordval!!.toString(), true)
}
"c64scr.print_uw0" -> {
dialog.canvas.printText("%05d".format(args[0].wordval!!), 1, true)
dialog.canvas.printText("%05d".format(args[0].wordval!!), true)
}
"c64scr.print_w" -> {
dialog.canvas.printText(args[0].wordval!!.toString(), 1, true)
dialog.canvas.printText(args[0].wordval!!.toString(), true)
}
"c64scr.print_ubhex" -> {
val prefix = if (args[0].asBoolean) "$" else ""
val number = args[1].byteval!!
dialog.canvas.printText("$prefix${number.toString(16).padStart(2, '0')}", 1, true)
dialog.canvas.printText("$prefix${number.toString(16).padStart(2, '0')}", true)
}
"c64scr.print_uwhex" -> {
val prefix = if (args[0].asBoolean) "$" else ""
val number = args[1].wordval!!
dialog.canvas.printText("$prefix${number.toString(16).padStart(4, '0')}", 1, true)
dialog.canvas.printText("$prefix${number.toString(16).padStart(4, '0')}", true)
}
"c64scr.print_uwbin" -> {
val prefix = if (args[0].asBoolean) "%" else ""
val number = args[1].wordval!!
dialog.canvas.printText("$prefix${number.toString(2).padStart(16, '0')}", 1, true)
dialog.canvas.printText("$prefix${number.toString(2).padStart(16, '0')}", true)
}
"c64scr.print_ubbin" -> {
val prefix = if (args[0].asBoolean) "%" else ""
val number = args[1].byteval!!
dialog.canvas.printText("$prefix${number.toString(2).padStart(8, '0')}", 1, true)
dialog.canvas.printText("$prefix${number.toString(2).padStart(8, '0')}", true)
}
"c64scr.clear_screenchars" -> {
dialog.canvas.clearScreen(6)
@ -633,14 +697,26 @@ class AstVm(val program: Program) {
"c64scr.plot" -> {
dialog.canvas.setCursorPos(args[0].integerValue(), args[1].integerValue())
}
"c64flt.print_f" -> {
dialog.canvas.printText(args[0].floatval.toString(), true)
}
"c64.CHROUT" -> {
dialog.canvas.printPetscii(args[0].byteval!!)
}
"c64flt.print_f" -> {
dialog.canvas.printText(args[0].floatval.toString(), 1, true)
"c64.CLEARSCR" -> {
dialog.canvas.clearScreen(6)
}
"c64.CHRIN" -> {
while(dialog.keyboardBuffer.isEmpty()) {
Thread.sleep(10)
}
val char=dialog.keyboardBuffer.pop()
result.add(RuntimeValue(DataType.UBYTE, char.toShort()))
}
else -> TODO("syscall ${sub.scopedname} $sub")
}
return result
}
private fun performBuiltinFunction(name: String, args: List<RuntimeValue>, statusflags: StatusFlags): RuntimeValue? {
@ -716,7 +792,7 @@ class AstVm(val program: Program) {
DataType.UWORD -> args[0]
DataType.WORD -> RuntimeValue(DataType.UWORD, abs(args[0].numericValue().toDouble()))
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, abs(args[0].numericValue().toDouble()))
else -> TODO("strange abs type")
else -> throw VmExecutionException("strange abs type ${args[0]}")
}
}
"max" -> {
@ -739,7 +815,7 @@ class AstVm(val program: Program) {
DataType.UWORD -> RuntimeValue(DataType.UWORD, sum)
DataType.WORD -> RuntimeValue(DataType.WORD, sum)
DataType.FLOAT -> RuntimeValue(DataType.FLOAT, sum)
else -> TODO("weird sum type")
else -> throw VmExecutionException("weird sum type ${args[0]}")
}
}
"any" -> {

View File

@ -7,6 +7,7 @@ import java.awt.*
import java.awt.event.KeyEvent
import java.awt.event.KeyListener
import java.awt.image.BufferedImage
import java.util.*
import javax.swing.JFrame
import javax.swing.JPanel
import javax.swing.Timer
@ -18,6 +19,7 @@ class BitmapScreenPanel : KeyListener, JPanel() {
private val g2d = image.graphics as Graphics2D
private var cursorX: Int=0
private var cursorY: Int=0
val keyboardBuffer: Deque<Char> = LinkedList<Char>()
init {
val size = Dimension(image.width * SCALING, image.height * SCALING)
@ -30,14 +32,14 @@ class BitmapScreenPanel : KeyListener, JPanel() {
addKeyListener(this)
}
override fun keyTyped(p0: KeyEvent?) {}
override fun keyTyped(p0: KeyEvent) {
keyboardBuffer.add(p0.keyChar)
}
override fun keyPressed(p0: KeyEvent?) {
println("pressed: $p0.k")
override fun keyPressed(p0: KeyEvent) {
}
override fun keyReleased(p0: KeyEvent?) {
println("released: $p0")
}
override fun paint(graphics: Graphics?) {
@ -61,23 +63,25 @@ class BitmapScreenPanel : KeyListener, JPanel() {
g2d.color = Colors.palette[color % Colors.palette.size]
g2d.drawLine(x1, y1, x2, y2)
}
fun printText(text: String, color: Short, lowercase: Boolean, inverseVideo: Boolean=false) {
fun printText(text: String, lowercase: Boolean, inverseVideo: Boolean=false) {
val t2 = text.substringBefore(0.toChar())
val lines = t2.split('\n')
for(line in lines.withIndex()) {
printTextSingleLine(line.value, color, lowercase, inverseVideo)
printTextSingleLine(line.value, lowercase, inverseVideo)
if(line.index<lines.size-1) {
cursorX=0
cursorY++
}
}
}
private fun printTextSingleLine(text: String, color: Short, lowercase: Boolean, inverseVideo: Boolean=false) {
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, color, inverseVideo)
setPetscii(cursorX, cursorY, sc, 1, inverseVideo)
cursorX++
if(cursorX>=(SCREENWIDTH /8)) {
cursorY++
@ -100,6 +104,19 @@ class BitmapScreenPanel : KeyListener, JPanel() {
}
}
fun writeTextAt(x: Int, y: Int, text: String, color: Short, lowercase: Boolean, inverseVideo: Boolean=false) {
val colorIdx = (color % Colors.palette.size).toShort()
var xx=x
for(clearx in xx until xx+text.length) {
g2d.clearRect(8*clearx, 8*y, 8, 8)
}
for(sc in Petscii.encodePetscii(text, lowercase)) {
if(sc==0.toShort())
break
setPetscii(xx++, y, sc, colorIdx, inverseVideo)
}
}
fun setPetscii(x: Int, y: Int, petscii: Short, color: Short, inverseVideo: Boolean) {
g2d.clearRect(8*x, 8*y, 8, 8)
val colorIdx = (color % Colors.palette.size).toShort()
@ -124,20 +141,6 @@ class BitmapScreenPanel : KeyListener, JPanel() {
return Pair(cursorX, cursorY)
}
fun writeText(x: Int, y: Int, text: String, color: Short, lowercase: Boolean, inverseVideo: Boolean=false) {
val colorIdx = (color % Colors.palette.size).toShort()
var xx=x
for(clearx in xx until xx+text.length) {
g2d.clearRect(8*clearx, 8*y, 8, 8)
}
for(sc in Petscii.encodePetscii(text, lowercase)) {
if(sc==0.toShort())
break
setPetscii(xx++, y, sc, colorIdx, inverseVideo)
}
}
companion object {
const val SCREENWIDTH = 320
const val SCREENHEIGHT = 200
@ -148,6 +151,7 @@ class BitmapScreenPanel : KeyListener, JPanel() {
class ScreenDialog(title: String) : JFrame(title) {
val canvas = BitmapScreenPanel()
val keyboardBuffer = canvas.keyboardBuffer
init {
val borderWidth = 16

View File

@ -2027,7 +2027,7 @@ class StackVm(private var traceOutputFile: String?) {
val color = evalstack.pop()
val (cy, cx) = evalstack.pop2()
val text = heap.get(textPtr)
canvas?.writeText(cx.integerValue(), cy.integerValue(), text.str!!, color.integerValue().toShort(), true)
canvas?.writeTextAt(cx.integerValue(), cy.integerValue(), text.str!!, color.integerValue().toShort(), true)
}
Syscall.FUNC_RND -> evalstack.push(RuntimeValue(DataType.UBYTE, rnd.nextInt() and 255))
Syscall.FUNC_RNDW -> evalstack.push(RuntimeValue(DataType.UWORD, rnd.nextInt() and 65535))
@ -2309,54 +2309,54 @@ class StackVm(private var traceOutputFile: String?) {
Syscall.SYSASM_c64scr_print -> {
val straddr = variables.getValue("A").integerValue() + 256*variables.getValue("Y").integerValue()
val str = heap.get(straddr).str!!
canvas?.printText(str, 1, true)
canvas?.printText(str, true)
}
Syscall.SYSASM_c64scr_print_ub -> {
val num = variables.getValue("A").integerValue()
canvas?.printText(num.toString(), 1, true)
canvas?.printText(num.toString(), true)
}
Syscall.SYSASM_c64scr_print_ub0 -> {
val num = variables.getValue("A").integerValue()
canvas?.printText("%03d".format(num), 1, true)
canvas?.printText("%03d".format(num), true)
}
Syscall.SYSASM_c64scr_print_b -> {
val num = variables.getValue("A").integerValue()
if(num<=127)
canvas?.printText(num.toString(), 1, true)
canvas?.printText(num.toString(), true)
else
canvas?.printText("-${256-num}", 1, true)
canvas?.printText("-${256-num}", true)
}
Syscall.SYSASM_c64scr_print_uw -> {
val lo = variables.getValue("A").integerValue()
val hi = variables.getValue("Y").integerValue()
val number = lo+256*hi
canvas?.printText(number.toString(), 1, true)
canvas?.printText(number.toString(), true)
}
Syscall.SYSASM_c64scr_print_uw0 -> {
val lo = variables.getValue("A").integerValue()
val hi = variables.getValue("Y").integerValue()
val number = lo+256*hi
canvas?.printText("%05d".format(number), 1, true)
canvas?.printText("%05d".format(number), true)
}
Syscall.SYSASM_c64scr_print_uwhex -> {
val prefix = if(this.P_carry) "$" else ""
val lo = variables.getValue("A").integerValue()
val hi = variables.getValue("Y").integerValue()
val number = lo+256*hi
canvas?.printText("$prefix${number.toString(16).padStart(4, '0')}", 1, true)
canvas?.printText("$prefix${number.toString(16).padStart(4, '0')}", true)
}
Syscall.SYSASM_c64scr_print_w -> {
val lo = variables.getValue("A").integerValue()
val hi = variables.getValue("Y").integerValue()
val number = lo+256*hi
if(number<=32767)
canvas?.printText(number.toString(), 1, true)
canvas?.printText(number.toString(), true)
else
canvas?.printText("-${65536-number}", 1, true)
canvas?.printText("-${65536-number}", true)
}
Syscall.SYSASM_c64flt_print_f -> {
val number = variables.getValue("c64flt.print_f.value").numericValue()
canvas?.printText(number.toString(), 1, true)
canvas?.printText(number.toString(), true)
}
Syscall.SYSASM_c64scr_setcc -> {
val x = variables.getValue("c64scr.setcc.column").integerValue()

View File

@ -1,33 +1,17 @@
%import c64utils
%zeropage basicsafe
%import c64flt
~ main {
sub start() {
ubyte xx=99
ubyte yy=99
ubyte aa=99
rsave()
c64flt.GETADR()
rrestore()
c64scr.print_ub(yy)
c64.CHROUT(',')
c64scr.print_ub(aa)
c64.CHROUT('\n')
rsave()
c64utils.ubyte2hex($9c)
rrestore()
c64scr.print_ub(aa)
c64.CHROUT(',')
c64scr.print_ub(yy)
c64.CHROUT('\n')
; rsave()
; A,Y=c64flt.FOUT() ; @ todo accept A,Y for AY response
; rrestore()
while true {
c64scr.print_ub(c64.TIME_HI)
c64.CHROUT(':')
c64scr.print_ub(c64.TIME_MID)
c64.CHROUT(':')
c64scr.print_ub(c64.TIME_LO)
c64.CHROUT('\n')
}
}
}