diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index a92001446..d5b23a362 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -56,6 +56,7 @@ private fun compileMain(args: Array) { name = "c64" machine = C64MachineDefinition encodeString = { str -> Petscii.encodePetscii(str, true) } + decodeString = { bytes -> Petscii.decodePetscii(bytes, true) } asmGenerator = ::AsmGen } } diff --git a/compiler/src/prog8/compiler/target/CompilationTarget.kt b/compiler/src/prog8/compiler/target/CompilationTarget.kt index f14f85dfd..0c55a8eca 100644 --- a/compiler/src/prog8/compiler/target/CompilationTarget.kt +++ b/compiler/src/prog8/compiler/target/CompilationTarget.kt @@ -10,6 +10,7 @@ internal interface CompilationTarget { lateinit var name: String lateinit var machine: IMachineDefinition lateinit var encodeString: (str: String) -> List + lateinit var decodeString: (bytes: List) -> String lateinit var asmGenerator: (Program, Zeropage, CompilationOptions, Path) -> IAssemblyGenerator } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 190f74e31..5548ca1d5 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -206,7 +206,7 @@ internal class AsmGen(private val program: Program, return "$b0, $b1, $b2, $b3, $b4" } - private fun encodeStr(str: String): List { + private fun petscii(str: String): List { val bytes = Petscii.encodePetscii(str, true) return bytes.plus(0) } @@ -247,7 +247,7 @@ internal class AsmGen(private val program: Program, DataType.STRUCT -> {} // is flattened DataType.STR -> { val string = (decl.value as StringLiteralValue).value - outputStringvar(decl, encodeStr(string)) + outputStringvar(decl, petscii(string)) } DataType.ARRAY_UB -> { val data = makeArrayFillDataUnsigned(decl) @@ -331,7 +331,7 @@ internal class AsmGen(private val program: Program, // special treatment for string types: merge strings that are identical val encodedstringVars = normalVars .filter {it.datatype == DataType.STR } - .map { it to encodeStr((it.value as StringLiteralValue).value) } + .map { it to petscii((it.value as StringLiteralValue).value) } .groupBy({it.second}, {it.first}) for((encoded, variables) in encodedstringVars) { variables.dropLast(1).forEach { out(it.name) } diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index 8afc08e39..0ee7cf6ea 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -179,20 +179,21 @@ internal class StatementOptimizer(private val program: Program) : IAstModifyingV if(stringVar!=null) { val vardecl = stringVar.targetVarDecl(program.namespace)!! val string = vardecl.value!! as StringLiteralValue - val encodedString = CompilationTarget.encodeString(string.value) if(string.value.length==1) { + val firstCharEncoded = CompilationTarget.encodeString(string.value)[0] functionCallStatement.arglist.clear() - functionCallStatement.arglist.add(NumericLiteralValue.optimalInteger(encodedString[0].toInt(), functionCallStatement.position)) + functionCallStatement.arglist.add(NumericLiteralValue.optimalInteger(firstCharEncoded.toInt(), functionCallStatement.position)) functionCallStatement.target = IdentifierReference(listOf("c64", "CHROUT"), functionCallStatement.target.position) vardeclsToRemove.add(vardecl) optimizationsDone++ return functionCallStatement } else if(string.value.length==2) { + val firstTwoCharsEncoded = CompilationTarget.encodeString(string.value.take(2)) val scope = AnonymousScope(mutableListOf(), functionCallStatement.position) scope.statements.add(FunctionCallStatement(IdentifierReference(listOf("c64", "CHROUT"), functionCallStatement.target.position), - mutableListOf(NumericLiteralValue.optimalInteger(encodedString[0].toInt(), functionCallStatement.position)), functionCallStatement.position)) + mutableListOf(NumericLiteralValue.optimalInteger(firstTwoCharsEncoded[0].toInt(), functionCallStatement.position)), functionCallStatement.position)) scope.statements.add(FunctionCallStatement(IdentifierReference(listOf("c64", "CHROUT"), functionCallStatement.target.position), - mutableListOf(NumericLiteralValue.optimalInteger(encodedString[1].toInt(), functionCallStatement.position)), functionCallStatement.position)) + mutableListOf(NumericLiteralValue.optimalInteger(firstTwoCharsEncoded[1].toInt(), functionCallStatement.position)), functionCallStatement.position)) vardeclsToRemove.add(vardecl) optimizationsDone++ return scope diff --git a/compiler/src/prog8/vm/astvm/AstVm.kt b/compiler/src/prog8/vm/astvm/AstVm.kt index 5348a776d..3e010e3b6 100644 --- a/compiler/src/prog8/vm/astvm/AstVm.kt +++ b/compiler/src/prog8/vm/astvm/AstVm.kt @@ -735,7 +735,7 @@ class AstVm(val program: Program, compilationTarget: String) { break else { input.add(char) - dialog.canvas.printAscii(char) + dialog.canvas.printAsciiText(char.toString()) } } var inputStr = input.joinToString("") @@ -751,7 +751,7 @@ class AstVm(val program: Program, compilationTarget: String) { dialog.canvas.printAsciiText(args[0].floatval.toString()) } "c64.CHROUT" -> { - dialog.canvas.printAscii(args[0].byteval!!.toChar()) + dialog.canvas.printAsciiText(args[0].byteval!!.toChar().toString()) } "c64.CLEARSCR" -> { dialog.canvas.clearScreen(6) diff --git a/compiler/src/prog8/vm/astvm/Memory.kt b/compiler/src/prog8/vm/astvm/Memory.kt index 72a9a0147..f5220ce0f 100644 --- a/compiler/src/prog8/vm/astvm/Memory.kt +++ b/compiler/src/prog8/vm/astvm/Memory.kt @@ -1,7 +1,7 @@ package prog8.vm.astvm +import prog8.compiler.target.CompilationTarget import prog8.compiler.target.c64.C64MachineDefinition -import prog8.compiler.target.c64.Petscii import kotlin.math.abs class Memory(private val readObserver: (address: Int, value: Short) -> Short, @@ -94,23 +94,21 @@ class Memory(private val readObserver: (address: Int, value: Short) -> Short, } fun setString(address: Int, str: String) { - // lowercase PETSCII - val petscii = Petscii.encodePetscii(str, true) + val encoded = CompilationTarget.encodeString(str) var addr = address - for (c in petscii) setUByte(addr++, c) + for (c in encoded) setUByte(addr++, c) setUByte(addr, 0) } fun getString(strAddress: Int): String { - // lowercase PETSCII - val petscii = mutableListOf() + val encoded = mutableListOf() var addr = strAddress while(true) { val byte = getUByte(addr++) if(byte==0.toShort()) break - petscii.add(byte) + encoded.add(byte) } - return Petscii.decodePetscii(petscii, true) + return CompilationTarget.decodeString(encoded) } fun clear() { @@ -121,24 +119,4 @@ class Memory(private val readObserver: (address: Int, value: Short) -> Short, for(i in 0 until numbytes) setUByte(to+i, getUByte(from+i)) } - - fun getScreencodeString(strAddress: Int): String? { - // lowercase Screencodes - val screencodes = mutableListOf() - var addr = strAddress - while(true) { - val byte = getUByte(addr++) - if(byte==0.toShort()) break - screencodes.add(byte) - } - return Petscii.decodeScreencode(screencodes, true) - } - - fun setScreencodeString(address: Int, str: String) { - // lowercase screencodes - val screencodes = Petscii.encodeScreencode(str, true) - var addr = address - for (c in screencodes) setUByte(addr++, c) - setUByte(addr, 0) - } } diff --git a/compiler/src/prog8/vm/astvm/ScreenDialog.kt b/compiler/src/prog8/vm/astvm/ScreenDialog.kt index b1b042216..9eec6222c 100644 --- a/compiler/src/prog8/vm/astvm/ScreenDialog.kt +++ b/compiler/src/prog8/vm/astvm/ScreenDialog.kt @@ -6,7 +6,6 @@ import java.awt.* import java.awt.event.KeyEvent import java.awt.event.KeyListener import java.awt.image.BufferedImage -import java.io.CharConversionException import java.util.ArrayDeque import javax.swing.JFrame import javax.swing.JPanel @@ -66,20 +65,18 @@ class BitmapScreenPanel : KeyListener, JPanel() { fun printAsciiText(text: String) { val t2 = text.substringBefore(0.toChar()) - val lines = t2.split('\n') - for(line in lines.withIndex()) { - line.value.forEach { printAscii(it) } - if(line.index= (SCREENWIDTH / 8)) { cursorY++ @@ -100,31 +97,6 @@ class BitmapScreenPanel : KeyListener, JPanel() { } } - fun writeAsciiTextAt(x: Int, y: Int, text: String, color: Short) { - val colorIdx = (color % C64MachineDefinition.colorPalette.size).toShort() - var xx=x - for(clearx in xx until xx+text.length) { - g2d.clearRect(8*clearx, 8*y, 8, 8) - } - for(c in text) { - if(c=='\u0000') - break - setAsciiChar(xx++, y, c, colorIdx) - } - } - - fun setAsciiChar(x: Int, y: Int, char: Char, color: Short) { - g2d.clearRect(8*x, 8*y, 8, 8) - val colorIdx = (color % C64MachineDefinition.colorPalette.size).toShort() - val screencode = try { - Petscii.encodeScreencode(char.toString(), true)[0] - } catch (x: CharConversionException) { - '?'.toShort() - } - val coloredImage = C64MachineDefinition.Charset.getColoredChar(screencode, colorIdx) - g2d.drawImage(coloredImage, 8*x, 8*y , null) - } - fun setScreenChar(x: Int, y: Int, screencode: Short, color: Short) { g2d.clearRect(8*x, 8*y, 8, 8) val colorIdx = (color % C64MachineDefinition.colorPalette.size).toShort()