mirror of
https://github.com/irmen/prog8.git
synced 2024-11-23 07:32:10 +00:00
made the ZP and compilation target more generic
This commit is contained in:
parent
5da9379c37
commit
8d8c066447
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
|
|
||||||
c64 {
|
c64 {
|
||||||
|
; TODO get rid of those:
|
||||||
const uword ESTACK_LO = $ce00 ; evaluation stack (lsb)
|
const uword ESTACK_LO = $ce00 ; evaluation stack (lsb)
|
||||||
const uword ESTACK_HI = $cf00 ; evaluation stack (msb)
|
const uword ESTACK_HI = $cf00 ; evaluation stack (msb)
|
||||||
&ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP
|
&ubyte SCRATCH_ZPB1 = $02 ; scratch byte 1 in ZP
|
||||||
|
@ -4,14 +4,25 @@ import prog8.compiler.CompilationOptions
|
|||||||
import prog8.compiler.Zeropage
|
import prog8.compiler.Zeropage
|
||||||
|
|
||||||
|
|
||||||
|
interface IMachineFloat {
|
||||||
|
fun toDouble(): Double
|
||||||
|
fun makeFloatFillAsm(): String
|
||||||
|
}
|
||||||
|
|
||||||
interface IMachineDefinition {
|
interface IMachineDefinition {
|
||||||
val FLOAT_MAX_NEGATIVE: Double
|
val FLOAT_MAX_NEGATIVE: Double
|
||||||
val FLOAT_MAX_POSITIVE: Double
|
val FLOAT_MAX_POSITIVE: Double
|
||||||
val FLOAT_MEM_SIZE: Int
|
val FLOAT_MEM_SIZE: Int
|
||||||
val POINTER_MEM_SIZE: Int
|
val POINTER_MEM_SIZE: Int
|
||||||
|
val ESTACK_LO: Int
|
||||||
|
val ESTACK_HI: Int
|
||||||
|
val BASIC_LOAD_ADDRESS : Int
|
||||||
|
val RAW_LOAD_ADDRESS : Int
|
||||||
|
|
||||||
val opcodeNames: Set<String>
|
val opcodeNames: Set<String>
|
||||||
var zeropage: Zeropage
|
var zeropage: Zeropage
|
||||||
|
|
||||||
fun initializeZeropage(compilerOptions: CompilationOptions)
|
fun initializeZeropage(compilerOptions: CompilationOptions)
|
||||||
|
fun getFloat(num: Number): IMachineFloat
|
||||||
|
fun getFloatRomConst(number: Double): String?
|
||||||
}
|
}
|
||||||
|
@ -5,31 +5,62 @@ import prog8.compiler.CompilerException
|
|||||||
import prog8.compiler.Zeropage
|
import prog8.compiler.Zeropage
|
||||||
import prog8.compiler.ZeropageType
|
import prog8.compiler.ZeropageType
|
||||||
import prog8.compiler.target.IMachineDefinition
|
import prog8.compiler.target.IMachineDefinition
|
||||||
|
import prog8.compiler.target.IMachineFloat
|
||||||
|
import java.math.RoundingMode
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
object C64MachineDefinition: IMachineDefinition {
|
internal object C64MachineDefinition: IMachineDefinition {
|
||||||
|
|
||||||
// 5-byte cbm MFLPT format limitations:
|
// 5-byte cbm MFLPT format limitations:
|
||||||
override val FLOAT_MAX_POSITIVE = 1.7014118345e+38 // bytes: 255,127,255,255,255
|
override val FLOAT_MAX_POSITIVE = 1.7014118345e+38 // bytes: 255,127,255,255,255
|
||||||
override val FLOAT_MAX_NEGATIVE = -1.7014118345e+38 // bytes: 255,255,255,255,255
|
override val FLOAT_MAX_NEGATIVE = -1.7014118345e+38 // bytes: 255,255,255,255,255
|
||||||
override val FLOAT_MEM_SIZE = 5
|
override val FLOAT_MEM_SIZE = 5
|
||||||
override val POINTER_MEM_SIZE = 2
|
override val POINTER_MEM_SIZE = 2
|
||||||
const val BASIC_LOAD_ADDRESS = 0x0801
|
override val BASIC_LOAD_ADDRESS = 0x0801
|
||||||
const val RAW_LOAD_ADDRESS = 0xc000
|
override val RAW_LOAD_ADDRESS = 0xc000
|
||||||
|
|
||||||
// the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations)
|
// the 2*256 byte evaluation stack (on which bytes, words, and even floats are stored during calculations)
|
||||||
// and some heavily used string constants derived from the two values above
|
// and some heavily used string constants derived from the two values above
|
||||||
const val ESTACK_LO_VALUE = 0xce00 // $ce00-$ceff inclusive
|
override val ESTACK_LO = 0xce00 // $ce00-$ceff inclusive
|
||||||
const val ESTACK_HI_VALUE = 0xcf00 // $cf00-$cfff inclusive
|
override val ESTACK_HI = 0xcf00 // $ce00-$ceff inclusive
|
||||||
const val ESTACK_LO_HEX = "\$ce00"
|
|
||||||
const val ESTACK_LO_PLUS1_HEX = "\$ce01"
|
|
||||||
const val ESTACK_LO_PLUS2_HEX = "\$ce02"
|
|
||||||
const val ESTACK_HI_HEX = "\$cf00"
|
|
||||||
const val ESTACK_HI_PLUS1_HEX = "\$cf01"
|
|
||||||
const val ESTACK_HI_PLUS2_HEX = "\$cf02"
|
|
||||||
|
|
||||||
override lateinit var zeropage: Zeropage
|
override lateinit var zeropage: Zeropage
|
||||||
|
override fun getFloat(num: Number) = Mflpt5.fromNumber(num)
|
||||||
|
|
||||||
|
override fun getFloatRomConst(number: Double): String? {
|
||||||
|
// try to match the ROM float constants to save memory
|
||||||
|
val mflpt5 = Mflpt5.fromNumber(number)
|
||||||
|
val floatbytes = shortArrayOf(mflpt5.b0, mflpt5.b1, mflpt5.b2, mflpt5.b3, mflpt5.b4)
|
||||||
|
when {
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x00, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_ZERO"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x82, 0x49, 0x0f, 0xda, 0xa1)) -> return "c64flt.FL_PIVAL"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x90, 0x80, 0x00, 0x00, 0x00)) -> return "c64flt.FL_N32768"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x81, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FONE"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x80, 0x35, 0x04, 0xf3, 0x34)) -> return "c64flt.FL_SQRHLF"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x81, 0x35, 0x04, 0xf3, 0x34)) -> return "c64flt.FL_SQRTWO"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x80, 0x80, 0x00, 0x00, 0x00)) -> return "c64flt.FL_NEGHLF"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x80, 0x31, 0x72, 0x17, 0xf8)) -> return "c64flt.FL_LOG2"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x84, 0x20, 0x00, 0x00, 0x00)) -> return "c64flt.FL_TENC"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x9e, 0x6e, 0x6b, 0x28, 0x00)) -> return "c64flt.FL_NZMIL"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x80, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FHALF"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x81, 0x38, 0xaa, 0x3b, 0x29)) -> return "c64flt.FL_LOGEB2"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x81, 0x49, 0x0f, 0xda, 0xa2)) -> return "c64flt.FL_PIHALF"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x83, 0x49, 0x0f, 0xda, 0xa2)) -> return "c64flt.FL_TWOPI"
|
||||||
|
floatbytes.contentEquals(shortArrayOf(0x7f, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FR4"
|
||||||
|
else -> {
|
||||||
|
// attempt to correct for a few rounding issues
|
||||||
|
when (number.toBigDecimal().setScale(10, RoundingMode.HALF_DOWN).toDouble()) {
|
||||||
|
3.1415926536 -> return "c64flt.FL_PIVAL"
|
||||||
|
1.4142135624 -> return "c64flt.FL_SQRTWO"
|
||||||
|
0.7071067812 -> return "c64flt.FL_SQRHLF"
|
||||||
|
0.6931471806 -> return "c64flt.FL_LOG2"
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
||||||
zeropage = C64Zeropage(compilerOptions)
|
zeropage = C64Zeropage(compilerOptions)
|
||||||
@ -47,16 +78,7 @@ object C64MachineDefinition: IMachineDefinition {
|
|||||||
"sta", "stx", "sty", "tas", "tax", "tay", "tsx", "txa", "txs", "tya", "xaa")
|
"sta", "stx", "sty", "tas", "tax", "tay", "tsx", "txa", "txs", "tya", "xaa")
|
||||||
|
|
||||||
|
|
||||||
class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
internal class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
|
|
||||||
companion object {
|
|
||||||
// TODO get rid of these static constants, use the properties from the Zeropage base class instead
|
|
||||||
const val SCRATCH_B1 = 0x02
|
|
||||||
const val SCRATCH_REG = 0x03 // temp storage for a register
|
|
||||||
const val SCRATCH_REG_X = 0xfa // temp storage for register X (the evaluation stack pointer)
|
|
||||||
const val SCRATCH_W1 = 0xfb // $fb+$fc
|
|
||||||
const val SCRATCH_W2 = 0xfd // $fd+$fe
|
|
||||||
}
|
|
||||||
|
|
||||||
override val SCRATCH_B1 = 0x02 // temp storage for a single byte
|
override val SCRATCH_B1 = 0x02 // temp storage for a single byte
|
||||||
override val SCRATCH_REG = 0x03 // temp storage for a register
|
override val SCRATCH_REG = 0x03 // temp storage for a register
|
||||||
@ -130,8 +152,7 @@ object C64MachineDefinition: IMachineDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, val b4: Short): IMachineFloat {
|
||||||
data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, val b4: Short) {
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val zero = Mflpt5(0, 0, 0, 0, 0)
|
val zero = Mflpt5(0, 0, 0, 0, 0)
|
||||||
@ -178,7 +199,7 @@ object C64MachineDefinition: IMachineDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toDouble(): Double {
|
override fun toDouble(): Double {
|
||||||
if (this == zero) return 0.0
|
if (this == zero) return 0.0
|
||||||
val exp = b0 - 128
|
val exp = b0 - 128
|
||||||
val sign = (b1.toInt() and 0x80) > 0
|
val sign = (b1.toInt() and 0x80) > 0
|
||||||
@ -186,5 +207,14 @@ object C64MachineDefinition: IMachineDefinition {
|
|||||||
val result = number.toDouble() * (2.0).pow(exp) / 0x100000000
|
val result = number.toDouble() * (2.0).pow(exp) / 0x100000000
|
||||||
return if (sign) -result else result
|
return if (sign) -result else result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun makeFloatFillAsm(): String {
|
||||||
|
val b0 = "$" + b0.toString(16).padStart(2, '0')
|
||||||
|
val b1 = "$" + b1.toString(16).padStart(2, '0')
|
||||||
|
val b2 = "$" + b2.toString(16).padStart(2, '0')
|
||||||
|
val b3 = "$" + b3.toString(16).padStart(2, '0')
|
||||||
|
val b4 = "$" + b4.toString(16).padStart(2, '0')
|
||||||
|
return "$b0, $b1, $b2, $b3, $b4"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,11 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.*
|
import prog8.compiler.*
|
||||||
|
import prog8.compiler.target.CompilationTarget
|
||||||
import prog8.compiler.target.IAssemblyGenerator
|
import prog8.compiler.target.IAssemblyGenerator
|
||||||
import prog8.compiler.target.IAssemblyProgram
|
import prog8.compiler.target.IAssemblyProgram
|
||||||
import prog8.compiler.target.c64.AssemblyProgram
|
import prog8.compiler.target.c64.AssemblyProgram
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition
|
import prog8.compiler.target.c64.C64MachineDefinition
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.Petscii
|
import prog8.compiler.target.c64.Petscii
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
||||||
@ -91,7 +89,17 @@ internal class AsmGen(private val program: Program,
|
|||||||
program.actualLoadAddress = program.definedLoadAddress
|
program.actualLoadAddress = program.definedLoadAddress
|
||||||
if (program.actualLoadAddress == 0) // fix load address
|
if (program.actualLoadAddress == 0) // fix load address
|
||||||
program.actualLoadAddress = if (options.launcher == LauncherType.BASIC)
|
program.actualLoadAddress = if (options.launcher == LauncherType.BASIC)
|
||||||
C64MachineDefinition.BASIC_LOAD_ADDRESS else C64MachineDefinition.RAW_LOAD_ADDRESS
|
CompilationTarget.machine.BASIC_LOAD_ADDRESS else CompilationTarget.machine.RAW_LOAD_ADDRESS
|
||||||
|
|
||||||
|
// the global prog8 variables needed
|
||||||
|
val zp = CompilationTarget.machine.zeropage
|
||||||
|
out("P8ZP_SCRATCH_B1 = ${zp.SCRATCH_B1}")
|
||||||
|
out("P8ZP_SCRATCH_REG = ${zp.SCRATCH_REG}")
|
||||||
|
out("P8ZP_SCRATCH_REG_X = ${zp.SCRATCH_REG_X}")
|
||||||
|
out("P8ZP_SCRATCH_W1 = ${zp.SCRATCH_W1} ; word")
|
||||||
|
out("P8ZP_SCRATCH_W2 = ${zp.SCRATCH_W2} ; word")
|
||||||
|
out("P8ESTACK_LO = ${CompilationTarget.machine.ESTACK_LO.toHex()}")
|
||||||
|
out("P8ESTACK_HI = ${CompilationTarget.machine.ESTACK_HI.toHex()}")
|
||||||
|
|
||||||
when {
|
when {
|
||||||
options.launcher == LauncherType.BASIC -> {
|
options.launcher == LauncherType.BASIC -> {
|
||||||
@ -154,8 +162,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
// the global list of all floating point constants for the whole program
|
// the global list of all floating point constants for the whole program
|
||||||
out("; global float constants")
|
out("; global float constants")
|
||||||
for (flt in globalFloatConsts) {
|
for (flt in globalFloatConsts) {
|
||||||
val mflpt5 = C64MachineDefinition.Mflpt5.fromNumber(flt.key)
|
val floatFill = CompilationTarget.machine.getFloat(flt.key).makeFloatFillAsm()
|
||||||
val floatFill = makeFloatFill(mflpt5)
|
|
||||||
val floatvalue = flt.key
|
val floatvalue = flt.key
|
||||||
out("${flt.value}\t.byte $floatFill ; float $floatvalue")
|
out("${flt.value}\t.byte $floatFill ; float $floatvalue")
|
||||||
}
|
}
|
||||||
@ -229,15 +236,6 @@ internal class AsmGen(private val program: Program,
|
|||||||
} else assemblyLines.add(fragment)
|
} else assemblyLines.add(fragment)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun makeFloatFill(flt: C64MachineDefinition.Mflpt5): String {
|
|
||||||
val b0 = "$" + flt.b0.toString(16).padStart(2, '0')
|
|
||||||
val b1 = "$" + flt.b1.toString(16).padStart(2, '0')
|
|
||||||
val b2 = "$" + flt.b2.toString(16).padStart(2, '0')
|
|
||||||
val b3 = "$" + flt.b3.toString(16).padStart(2, '0')
|
|
||||||
val b4 = "$" + flt.b4.toString(16).padStart(2, '0')
|
|
||||||
return "$b0, $b1, $b2, $b3, $b4"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun encode(str: String, altEncoding: Boolean): List<Short> {
|
private fun encode(str: String, altEncoding: Boolean): List<Short> {
|
||||||
val bytes = if(altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
val bytes = if(altEncoding) Petscii.encodeScreencode(str, true) else Petscii.encodePetscii(str, true)
|
||||||
return bytes.plus(0)
|
return bytes.plus(0)
|
||||||
@ -333,7 +331,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
val floatFills = array.map {
|
val floatFills = array.map {
|
||||||
val number = (it as NumericLiteralValue).number
|
val number = (it as NumericLiteralValue).number
|
||||||
makeFloatFill(C64MachineDefinition.Mflpt5.fromNumber(number))
|
CompilationTarget.machine.getFloat(number).makeFloatFillAsm()
|
||||||
}
|
}
|
||||||
out(decl.name)
|
out(decl.name)
|
||||||
for (f in array.zip(floatFills))
|
for (f in array.zip(floatFills))
|
||||||
@ -466,45 +464,17 @@ internal class AsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun getFloatConst(number: Double): String {
|
internal fun getFloatAsmConst(number: Double): String {
|
||||||
// try to match the ROM float constants to save memory
|
var asmName = CompilationTarget.machine.getFloatRomConst(number)
|
||||||
val mflpt5 = C64MachineDefinition.Mflpt5.fromNumber(number)
|
if(asmName.isNullOrEmpty()) {
|
||||||
val floatbytes = shortArrayOf(mflpt5.b0, mflpt5.b1, mflpt5.b2, mflpt5.b3, mflpt5.b4)
|
|
||||||
when {
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x00, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_ZERO"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x82, 0x49, 0x0f, 0xda, 0xa1)) -> return "c64flt.FL_PIVAL"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x90, 0x80, 0x00, 0x00, 0x00)) -> return "c64flt.FL_N32768"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x81, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FONE"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x80, 0x35, 0x04, 0xf3, 0x34)) -> return "c64flt.FL_SQRHLF"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x81, 0x35, 0x04, 0xf3, 0x34)) -> return "c64flt.FL_SQRTWO"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x80, 0x80, 0x00, 0x00, 0x00)) -> return "c64flt.FL_NEGHLF"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x80, 0x31, 0x72, 0x17, 0xf8)) -> return "c64flt.FL_LOG2"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x84, 0x20, 0x00, 0x00, 0x00)) -> return "c64flt.FL_TENC"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x9e, 0x6e, 0x6b, 0x28, 0x00)) -> return "c64flt.FL_NZMIL"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x80, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FHALF"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x81, 0x38, 0xaa, 0x3b, 0x29)) -> return "c64flt.FL_LOGEB2"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x81, 0x49, 0x0f, 0xda, 0xa2)) -> return "c64flt.FL_PIHALF"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x83, 0x49, 0x0f, 0xda, 0xa2)) -> return "c64flt.FL_TWOPI"
|
|
||||||
floatbytes.contentEquals(shortArrayOf(0x7f, 0x00, 0x00, 0x00, 0x00)) -> return "c64flt.FL_FR4"
|
|
||||||
else -> {
|
|
||||||
// attempt to correct for a few rounding issues
|
|
||||||
when (number.toBigDecimal().setScale(10, RoundingMode.HALF_DOWN).toDouble()) {
|
|
||||||
3.1415926536 -> return "c64flt.FL_PIVAL"
|
|
||||||
1.4142135624 -> return "c64flt.FL_SQRTWO"
|
|
||||||
0.7071067812 -> return "c64flt.FL_SQRHLF"
|
|
||||||
0.6931471806 -> return "c64flt.FL_LOG2"
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no ROM float const for this value, create our own
|
// no ROM float const for this value, create our own
|
||||||
val name = globalFloatConsts[number]
|
asmName = globalFloatConsts[number]
|
||||||
if(name!=null)
|
if(asmName==null) {
|
||||||
return name
|
asmName = "prog8_float_const_${globalFloatConsts.size}"
|
||||||
val newName = "prog8_float_const_${globalFloatConsts.size}"
|
globalFloatConsts[number] = asmName
|
||||||
globalFloatConsts[number] = newName
|
|
||||||
return newName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return asmName
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun asmIdentifierName(identifier: IdentifierReference): String {
|
internal fun asmIdentifierName(identifier: IdentifierReference): String {
|
||||||
@ -529,10 +499,10 @@ internal class AsmGen(private val program: Program,
|
|||||||
out("""
|
out("""
|
||||||
lda $sourceName
|
lda $sourceName
|
||||||
ldy $sourceName+1
|
ldy $sourceName+1
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (${C64Zeropage.SCRATCH_W1}),y""")
|
lda (P8ZP_SCRATCH_W1),y""")
|
||||||
return Pair(false, sourceName)
|
return Pair(false, sourceName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -549,12 +519,12 @@ internal class AsmGen(private val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
out("""
|
out("""
|
||||||
ldy $sourceName
|
ldy $sourceName
|
||||||
sty ${C64Zeropage.SCRATCH_W2}
|
sty P8ZP_SCRATCH_W2
|
||||||
ldy $sourceName+1
|
ldy $sourceName+1
|
||||||
sty ${C64Zeropage.SCRATCH_W2 + 1}
|
sty P8ZP_SCRATCH_W2+1
|
||||||
${if(ldaInstructionArg==null) "" else "lda $ldaInstructionArg"}
|
${if(ldaInstructionArg==null) "" else "lda $ldaInstructionArg"}
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
sta (P8ZP_SCRATCH_W2),y""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -680,14 +650,14 @@ internal class AsmGen(private val program: Program,
|
|||||||
else {
|
else {
|
||||||
expressionsAsmGen.translateExpression(index)
|
expressionsAsmGen.translateExpression(index)
|
||||||
out("""
|
out("""
|
||||||
inc $ESTACK_LO_HEX,x
|
inc P8ESTACK_LO,x
|
||||||
bne +
|
bne +
|
||||||
inc $ESTACK_HI_HEX,x
|
inc P8ESTACK_HI,x
|
||||||
+""")
|
+""")
|
||||||
when(register) {
|
when(register) {
|
||||||
CpuRegister.A -> out(" inx | lda $ESTACK_LO_HEX,x")
|
CpuRegister.A -> out(" inx | lda P8ESTACK_LO,x")
|
||||||
CpuRegister.X -> throw AssemblyError("can't use X here")
|
CpuRegister.X -> throw AssemblyError("can't use X here")
|
||||||
CpuRegister.Y -> out(" inx | ldy $ESTACK_LO_HEX,x")
|
CpuRegister.Y -> out(" inx | ldy P8ESTACK_LO,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -723,9 +693,9 @@ internal class AsmGen(private val program: Program,
|
|||||||
else {
|
else {
|
||||||
expressionsAsmGen.translateExpression(index)
|
expressionsAsmGen.translateExpression(index)
|
||||||
when(register) {
|
when(register) {
|
||||||
CpuRegister.A -> out(" inx | lda $ESTACK_LO_HEX,x")
|
CpuRegister.A -> out(" inx | lda P8ESTACK_LO,x")
|
||||||
CpuRegister.X -> throw AssemblyError("can't use X here")
|
CpuRegister.X -> throw AssemblyError("can't use X here")
|
||||||
CpuRegister.Y -> out(" inx | ldy $ESTACK_LO_HEX,x")
|
CpuRegister.Y -> out(" inx | ldy P8ESTACK_LO,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -808,8 +778,8 @@ internal class AsmGen(private val program: Program,
|
|||||||
|
|
||||||
private fun translateTestStack(dataType: DataType) {
|
private fun translateTestStack(dataType: DataType) {
|
||||||
when(dataType) {
|
when(dataType) {
|
||||||
in ByteDatatypes -> out(" inx | lda $ESTACK_LO_HEX,x")
|
in ByteDatatypes -> out(" inx | lda P8ESTACK_LO,x")
|
||||||
in WordDatatypes -> out(" inx | lda $ESTACK_LO_HEX,x | ora $ESTACK_HI_HEX,x")
|
in WordDatatypes -> out(" inx | lda P8ESTACK_LO,x | ora P8ESTACK_HI,x")
|
||||||
DataType.FLOAT -> throw AssemblyError("conditional value should be an integer (boolean)")
|
DataType.FLOAT -> throw AssemblyError("conditional value should be an integer (boolean)")
|
||||||
else -> throw AssemblyError("non-numerical dt")
|
else -> throw AssemblyError("non-numerical dt")
|
||||||
}
|
}
|
||||||
@ -864,11 +834,11 @@ internal class AsmGen(private val program: Program,
|
|||||||
val dt = stmt.iterations!!.inferType(program).typeOrElse(DataType.STRUCT)
|
val dt = stmt.iterations!!.inferType(program).typeOrElse(DataType.STRUCT)
|
||||||
when (dt) {
|
when (dt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
out(" inx | lda ${ESTACK_LO_HEX},x")
|
out(" inx | lda P8ESTACK_LO,x")
|
||||||
repeatByteCountInA(null, repeatLabel, endLabel, stmt.body)
|
repeatByteCountInA(null, repeatLabel, endLabel, stmt.body)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
out(" inx | lda ${ESTACK_LO_HEX},x | ldy ${ESTACK_HI_HEX},x")
|
out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x")
|
||||||
repeatWordCountInAY(null, repeatLabel, endLabel, stmt.body)
|
repeatWordCountInAY(null, repeatLabel, endLabel, stmt.body)
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid loop expression datatype $dt")
|
else -> throw AssemblyError("invalid loop expression datatype $dt")
|
||||||
@ -940,13 +910,13 @@ $counterVar .byte 0""")
|
|||||||
if(!conditionDt.isKnown)
|
if(!conditionDt.isKnown)
|
||||||
throw AssemblyError("unknown condition dt")
|
throw AssemblyError("unknown condition dt")
|
||||||
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
||||||
out(" inx | lda $ESTACK_LO_HEX,x | beq $endLabel")
|
out(" inx | lda P8ESTACK_LO,x | beq $endLabel")
|
||||||
} else {
|
} else {
|
||||||
out("""
|
out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
bne +
|
bne +
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
beq $endLabel
|
beq $endLabel
|
||||||
+ """)
|
+ """)
|
||||||
}
|
}
|
||||||
@ -967,13 +937,13 @@ $counterVar .byte 0""")
|
|||||||
if(!conditionDt.isKnown)
|
if(!conditionDt.isKnown)
|
||||||
throw AssemblyError("unknown condition dt")
|
throw AssemblyError("unknown condition dt")
|
||||||
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes) {
|
||||||
out(" inx | lda $ESTACK_LO_HEX,x | beq $repeatLabel")
|
out(" inx | lda P8ESTACK_LO,x | beq $repeatLabel")
|
||||||
} else {
|
} else {
|
||||||
out("""
|
out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
bne +
|
bne +
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
beq $repeatLabel
|
beq $repeatLabel
|
||||||
+ """)
|
+ """)
|
||||||
}
|
}
|
||||||
@ -989,9 +959,9 @@ $counterVar .byte 0""")
|
|||||||
if(!conditionDt.isKnown)
|
if(!conditionDt.isKnown)
|
||||||
throw AssemblyError("unknown condition dt")
|
throw AssemblyError("unknown condition dt")
|
||||||
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes)
|
if(conditionDt.typeOrElse(DataType.BYTE) in ByteDatatypes)
|
||||||
out(" inx | lda $ESTACK_LO_HEX,x")
|
out(" inx | lda P8ESTACK_LO,x")
|
||||||
else
|
else
|
||||||
out(" inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x")
|
out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x")
|
||||||
for(choice in stmt.choices) {
|
for(choice in stmt.choices) {
|
||||||
val choiceLabel = makeLabel("choice")
|
val choiceLabel = makeLabel("choice")
|
||||||
if(choice.values==null) {
|
if(choice.values==null) {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package prog8.compiler.target.c64.codegen
|
package prog8.compiler.target.c64.codegen
|
||||||
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|
||||||
|
|
||||||
|
|
||||||
// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations
|
// note: see https://wiki.nesdev.com/w/index.php/6502_assembly_optimisations
|
||||||
|
|
||||||
@ -87,10 +84,10 @@ private fun optimizeCmpSequence(linesByFour: List<List<IndexedValue<String>>>):
|
|||||||
// the repeated lda can be removed
|
// the repeated lda can be removed
|
||||||
val mods = mutableListOf<Modification>()
|
val mods = mutableListOf<Modification>()
|
||||||
for(lines in linesByFour) {
|
for(lines in linesByFour) {
|
||||||
if(lines[0].value.trim()=="lda $ESTACK_LO_PLUS1_HEX,x" &&
|
if(lines[0].value.trim()=="lda P8ESTACK_LO+1,x" &&
|
||||||
lines[1].value.trim().startsWith("cmp ") &&
|
lines[1].value.trim().startsWith("cmp ") &&
|
||||||
lines[2].value.trim().startsWith("beq ") &&
|
lines[2].value.trim().startsWith("beq ") &&
|
||||||
lines[3].value.trim()=="lda $ESTACK_LO_PLUS1_HEX,x") {
|
lines[3].value.trim()=="lda P8ESTACK_LO+1,x") {
|
||||||
mods.add(Modification(lines[3].index, true, null)) // remove the second lda
|
mods.add(Modification(lines[3].index, true, null)) // remove the second lda
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,10 +99,10 @@ private fun optimizeUselessStackByteWrites(linesByFour: List<List<IndexedValue<S
|
|||||||
// this is a lot harder for word values because the instruction sequence varies.
|
// this is a lot harder for word values because the instruction sequence varies.
|
||||||
val mods = mutableListOf<Modification>()
|
val mods = mutableListOf<Modification>()
|
||||||
for(lines in linesByFour) {
|
for(lines in linesByFour) {
|
||||||
if(lines[0].value.trim()=="sta $ESTACK_LO_HEX,x" &&
|
if(lines[0].value.trim()=="sta P8ESTACK_LO,x" &&
|
||||||
lines[1].value.trim()=="dex" &&
|
lines[1].value.trim()=="dex" &&
|
||||||
lines[2].value.trim()=="inx" &&
|
lines[2].value.trim()=="inx" &&
|
||||||
lines[3].value.trim()=="lda $ESTACK_LO_HEX,x") {
|
lines[3].value.trim()=="lda P8ESTACK_LO,x") {
|
||||||
mods.add(Modification(lines[1].index, true, null))
|
mods.add(Modification(lines[1].index, true, null))
|
||||||
mods.add(Modification(lines[2].index, true, null))
|
mods.add(Modification(lines[2].index, true, null))
|
||||||
mods.add(Modification(lines[3].index, true, null))
|
mods.add(Modification(lines[3].index, true, null))
|
||||||
|
@ -6,15 +6,6 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.FunctionCallStatement
|
import prog8.ast.statements.FunctionCallStatement
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind
|
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
import prog8.functions.FSignature
|
import prog8.functions.FSignature
|
||||||
|
|
||||||
@ -60,7 +51,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
"rsave" -> {
|
"rsave" -> {
|
||||||
// save cpu status flag and all registers A, X, Y.
|
// save cpu status flag and all registers A, X, Y.
|
||||||
// see http://6502.org/tutorials/register_preservation.html
|
// see http://6502.org/tutorials/register_preservation.html
|
||||||
asmgen.out(" php | sta ${C64Zeropage.SCRATCH_REG} | pha | txa | pha | tya | pha | lda ${C64Zeropage.SCRATCH_REG}")
|
asmgen.out(" php | sta P8ZP_SCRATCH_REG | pha | txa | pha | tya | pha | lda P8ZP_SCRATCH_REG")
|
||||||
}
|
}
|
||||||
"rrestore" -> {
|
"rrestore" -> {
|
||||||
// restore all registers and cpu status flag
|
// restore all registers and cpu status flag
|
||||||
@ -88,8 +79,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$varName
|
lda #<$varName
|
||||||
ldy #>$varName
|
ldy #>$varName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$numElements
|
lda #$numElements
|
||||||
jsr prog8_lib.reverse_b
|
jsr prog8_lib.reverse_b
|
||||||
""")
|
""")
|
||||||
@ -98,8 +89,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$varName
|
lda #<$varName
|
||||||
ldy #>$varName
|
ldy #>$varName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$numElements
|
lda #$numElements
|
||||||
jsr prog8_lib.reverse_w
|
jsr prog8_lib.reverse_w
|
||||||
""")
|
""")
|
||||||
@ -108,8 +99,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$varName
|
lda #<$varName
|
||||||
ldy #>$varName
|
ldy #>$varName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$numElements
|
lda #$numElements
|
||||||
jsr prog8_lib.reverse_f
|
jsr prog8_lib.reverse_f
|
||||||
""")
|
""")
|
||||||
@ -130,10 +121,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$varName
|
lda #<$varName
|
||||||
ldy #>$varName
|
ldy #>$varName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$numElements
|
lda #$numElements
|
||||||
sta ${C64Zeropage.SCRATCH_B1}
|
sta P8ZP_SCRATCH_B1
|
||||||
""")
|
""")
|
||||||
asmgen.out(if (decl.datatype == DataType.ARRAY_UB) " jsr prog8_lib.sort_ub" else " jsr prog8_lib.sort_b")
|
asmgen.out(if (decl.datatype == DataType.ARRAY_UB) " jsr prog8_lib.sort_ub" else " jsr prog8_lib.sort_b")
|
||||||
}
|
}
|
||||||
@ -141,10 +132,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$varName
|
lda #<$varName
|
||||||
ldy #>$varName
|
ldy #>$varName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1 + 1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #$numElements
|
lda #$numElements
|
||||||
sta ${C64Zeropage.SCRATCH_B1}
|
sta P8ZP_SCRATCH_B1
|
||||||
""")
|
""")
|
||||||
asmgen.out(if (decl.datatype == DataType.ARRAY_UW) " jsr prog8_lib.sort_uw" else " jsr prog8_lib.sort_w")
|
asmgen.out(if (decl.datatype == DataType.ARRAY_UW) " jsr prog8_lib.sort_uw" else " jsr prog8_lib.sort_w")
|
||||||
}
|
}
|
||||||
@ -219,9 +210,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.translateExpression(what.addressExpression)
|
asmgen.translateExpression(what.addressExpression)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta (+) + 1
|
sta (+) + 1
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta (+) + 2
|
sta (+) + 2
|
||||||
+ ror ${'$'}ffff ; modified
|
+ ror ${'$'}ffff ; modified
|
||||||
""")
|
""")
|
||||||
@ -316,9 +307,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
asmgen.translateExpression(what.addressExpression)
|
asmgen.translateExpression(what.addressExpression)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta (+) + 1
|
sta (+) + 1
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta (+) + 2
|
sta (+) + 2
|
||||||
+ rol ${'$'}ffff ; modified
|
+ rol ${'$'}ffff ; modified
|
||||||
""")
|
""")
|
||||||
@ -397,7 +388,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
lda #<$name
|
lda #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr prog8_lib.strlen
|
jsr prog8_lib.strlen
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,13 +419,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if(dt.istype(DataType.FLOAT)) {
|
if(dt.istype(DataType.FLOAT)) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$firstName
|
lda #<$firstName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
lda #>$firstName
|
lda #>$firstName
|
||||||
sta ${C64Zeropage.SCRATCH_W1+1}
|
sta P8ZP_SCRATCH_W1+1
|
||||||
lda #<$secondName
|
lda #<$secondName
|
||||||
sta ${C64Zeropage.SCRATCH_W2}
|
sta P8ZP_SCRATCH_W2
|
||||||
lda #>$secondName
|
lda #>$secondName
|
||||||
sta ${C64Zeropage.SCRATCH_W2+1}
|
sta P8ZP_SCRATCH_W2+1
|
||||||
jsr c64flt.swap_floats
|
jsr c64flt.swap_floats
|
||||||
""")
|
""")
|
||||||
return
|
return
|
||||||
@ -460,7 +451,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
// trick: push the args in reverse order (msb first, lsb second) this saves some instructions
|
// trick: push the args in reverse order (msb first, lsb second) this saves some instructions
|
||||||
asmgen.translateExpression(fcall.args[1])
|
asmgen.translateExpression(fcall.args[1])
|
||||||
asmgen.translateExpression(fcall.args[0])
|
asmgen.translateExpression(fcall.args[0])
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta $ESTACK_HI_PLUS1_HEX,x")
|
asmgen.out(" inx | lda P8ESTACK_LO,x | sta P8ESTACK_HI+1,x")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcMsb(fcall: IFunctionCall) {
|
private fun funcMsb(fcall: IFunctionCall) {
|
||||||
@ -471,10 +462,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
throw AssemblyError("msb(const) should have been const-folded away")
|
throw AssemblyError("msb(const) should have been const-folded away")
|
||||||
if (arg is IdentifierReference) {
|
if (arg is IdentifierReference) {
|
||||||
val sourceName = asmgen.asmIdentifierName(arg)
|
val sourceName = asmgen.asmIdentifierName(arg)
|
||||||
asmgen.out(" lda $sourceName+1 | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $sourceName+1 | sta P8ESTACK_LO,x | dex")
|
||||||
} else {
|
} else {
|
||||||
asmgen.translateExpression(arg)
|
asmgen.translateExpression(arg)
|
||||||
asmgen.out(" lda $ESTACK_HI_PLUS1_HEX,x | sta $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" lda P8ESTACK_HI+1,x | sta P8ESTACK_LO+1,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,7 +477,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
throw AssemblyError("lsb(const) should have been const-folded away")
|
throw AssemblyError("lsb(const) should have been const-folded away")
|
||||||
if (arg is IdentifierReference) {
|
if (arg is IdentifierReference) {
|
||||||
val sourceName = asmgen.asmIdentifierName(arg)
|
val sourceName = asmgen.asmIdentifierName(arg)
|
||||||
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $sourceName | sta P8ESTACK_LO,x | dex")
|
||||||
} else {
|
} else {
|
||||||
asmgen.translateExpression(arg)
|
asmgen.translateExpression(arg)
|
||||||
// just ignore any high-byte
|
// just ignore any high-byte
|
||||||
@ -499,12 +490,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
val size = arg.targetVarDecl(program.namespace)!!.arraysize!!.constIndex()!!
|
val size = arg.targetVarDecl(program.namespace)!!.arraysize!!.constIndex()!!
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$identifierName
|
lda #<$identifierName
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
lda #>$identifierName
|
lda #>$identifierName
|
||||||
sta $ESTACK_HI_HEX,x
|
sta P8ESTACK_HI,x
|
||||||
dex
|
dex
|
||||||
lda #$size
|
lda #$size
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex
|
dex
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,6 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS2_HEX
|
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
import prog8.functions.BuiltinFunctions
|
import prog8.functions.BuiltinFunctions
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
@ -46,20 +40,20 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
// result value in cpu or status registers, put it on the stack
|
// result value in cpu or status registers, put it on the stack
|
||||||
if (reg.registerOrPair != null) {
|
if (reg.registerOrPair != null) {
|
||||||
when (reg.registerOrPair) {
|
when (reg.registerOrPair) {
|
||||||
RegisterOrPair.A -> asmgen.out(" sta $ESTACK_LO_HEX,x | dex")
|
RegisterOrPair.A -> asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
RegisterOrPair.Y -> asmgen.out(" tya | sta $ESTACK_LO_HEX,x | dex")
|
RegisterOrPair.Y -> asmgen.out(" tya | sta P8ESTACK_LO,x | dex")
|
||||||
RegisterOrPair.AY -> asmgen.out(" sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex")
|
RegisterOrPair.AY -> asmgen.out(" sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex")
|
||||||
RegisterOrPair.X -> {
|
RegisterOrPair.X -> {
|
||||||
// return value in X register has been discarded, just push a zero
|
// return value in X register has been discarded, just push a zero
|
||||||
asmgen.out(" lda #0 | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda #0 | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
RegisterOrPair.AX -> {
|
RegisterOrPair.AX -> {
|
||||||
// return value in X register has been discarded, just push a zero in this place
|
// return value in X register has been discarded, just push a zero in this place
|
||||||
asmgen.out(" sta $ESTACK_LO_HEX,x | lda #0 | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | lda #0 | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
RegisterOrPair.XY -> {
|
RegisterOrPair.XY -> {
|
||||||
// return value in X register has been discarded, just push a zero in this place
|
// return value in X register has been discarded, just push a zero in this place
|
||||||
asmgen.out(" lda #0 | sta $ESTACK_LO_HEX,x | tya | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda #0 | sta P8ESTACK_LO,x | tya | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +69,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
when(expr.type) {
|
when(expr.type) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {}
|
DataType.UBYTE, DataType.BYTE -> {}
|
||||||
DataType.UWORD, DataType.WORD -> asmgen.out(" lda #0 | sta $ESTACK_HI_PLUS1_HEX,x")
|
DataType.UWORD, DataType.WORD -> asmgen.out(" lda #0 | sta P8ESTACK_HI+1,x")
|
||||||
DataType.FLOAT -> asmgen.out(" jsr c64flt.stack_ub2float")
|
DataType.FLOAT -> asmgen.out(" jsr c64flt.stack_ub2float")
|
||||||
in PassByReferenceDatatypes -> throw AssemblyError("cannot cast to a pass-by-reference datatype")
|
in PassByReferenceDatatypes -> throw AssemblyError("cannot cast to a pass-by-reference datatype")
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
@ -87,11 +81,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
// sign extend
|
// sign extend
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
ora #$7f
|
ora #$7f
|
||||||
bmi +
|
bmi +
|
||||||
lda #0
|
lda #0
|
||||||
+ sta $ESTACK_HI_PLUS1_HEX,x""")
|
+ sta P8ESTACK_HI+1,x""")
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> asmgen.out(" jsr c64flt.stack_b2float")
|
DataType.FLOAT -> asmgen.out(" jsr c64flt.stack_b2float")
|
||||||
in PassByReferenceDatatypes -> throw AssemblyError("cannot cast to a pass-by-reference datatype")
|
in PassByReferenceDatatypes -> throw AssemblyError("cannot cast to a pass-by-reference datatype")
|
||||||
@ -134,40 +128,40 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
|
|
||||||
private fun translateExpression(expr: AddressOf) {
|
private fun translateExpression(expr: AddressOf) {
|
||||||
val name = asmgen.asmIdentifierName(expr.identifier)
|
val name = asmgen.asmIdentifierName(expr.identifier)
|
||||||
asmgen.out(" lda #<$name | sta $ESTACK_LO_HEX,x | lda #>$name | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda #<$name | sta P8ESTACK_LO,x | lda #>$name | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExpression(expr: DirectMemoryRead) {
|
private fun translateExpression(expr: DirectMemoryRead) {
|
||||||
when(expr.addressExpression) {
|
when(expr.addressExpression) {
|
||||||
is NumericLiteralValue -> {
|
is NumericLiteralValue -> {
|
||||||
val address = (expr.addressExpression as NumericLiteralValue).number.toInt()
|
val address = (expr.addressExpression as NumericLiteralValue).number.toInt()
|
||||||
asmgen.out(" lda ${address.toHex()} | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda ${address.toHex()} | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
is IdentifierReference -> {
|
is IdentifierReference -> {
|
||||||
// the identifier is a pointer variable, so read the value from the address in it
|
// the identifier is a pointer variable, so read the value from the address in it
|
||||||
asmgen.loadByteFromPointerIntoA(expr.addressExpression as IdentifierReference)
|
asmgen.loadByteFromPointerIntoA(expr.addressExpression as IdentifierReference)
|
||||||
asmgen.out(" sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
translateExpression(expr.addressExpression)
|
translateExpression(expr.addressExpression)
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack")
|
||||||
asmgen.out(" sta $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" sta P8ESTACK_LO+1,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExpression(expr: NumericLiteralValue) {
|
private fun translateExpression(expr: NumericLiteralValue) {
|
||||||
when(expr.type) {
|
when(expr.type) {
|
||||||
DataType.UBYTE, DataType.BYTE -> asmgen.out(" lda #${expr.number.toHex()} | sta $ESTACK_LO_HEX,x | dex")
|
DataType.UBYTE, DataType.BYTE -> asmgen.out(" lda #${expr.number.toHex()} | sta P8ESTACK_LO,x | dex")
|
||||||
DataType.UWORD, DataType.WORD -> asmgen.out("""
|
DataType.UWORD, DataType.WORD -> asmgen.out("""
|
||||||
lda #<${expr.number.toHex()}
|
lda #<${expr.number.toHex()}
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
lda #>${expr.number.toHex()}
|
lda #>${expr.number.toHex()}
|
||||||
sta $ESTACK_HI_HEX,x
|
sta P8ESTACK_HI,x
|
||||||
dex
|
dex
|
||||||
""")
|
""")
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
val floatConst = asmgen.getFloatConst(expr.number.toDouble())
|
val floatConst = asmgen.getFloatAsmConst(expr.number.toDouble())
|
||||||
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
@ -178,16 +172,16 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
val varname = asmgen.asmIdentifierName(expr)
|
val varname = asmgen.asmIdentifierName(expr)
|
||||||
when(expr.inferType(program).typeOrElse(DataType.STRUCT)) {
|
when(expr.inferType(program).typeOrElse(DataType.STRUCT)) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
asmgen.out(" lda $varname | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $varname | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
asmgen.out(" lda $varname | sta $ESTACK_LO_HEX,x | lda $varname+1 | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $varname | sta P8ESTACK_LO,x | lda $varname+1 | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.out(" lda #<$varname | ldy #>$varname| jsr c64flt.push_float")
|
asmgen.out(" lda #<$varname | ldy #>$varname| jsr c64flt.push_float")
|
||||||
}
|
}
|
||||||
in IterableDatatypes -> {
|
in IterableDatatypes -> {
|
||||||
asmgen.out(" lda #<$varname | sta $ESTACK_LO_HEX,x | lda #>$varname | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda #<$varname | sta P8ESTACK_LO,x | lda #>$varname | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("stack push weird variable type $expr")
|
else -> throw AssemblyError("stack push weird variable type $expr")
|
||||||
}
|
}
|
||||||
@ -213,20 +207,20 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
when (leftDt) {
|
when (leftDt) {
|
||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
if (amount <= 2)
|
if (amount <= 2)
|
||||||
repeat(amount) { asmgen.out(" lsr $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(amount) { asmgen.out(" lsr P8ESTACK_LO+1,x") }
|
||||||
else {
|
else {
|
||||||
asmgen.out(" lda $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" lda P8ESTACK_LO+1,x")
|
||||||
repeat(amount) { asmgen.out(" lsr a") }
|
repeat(amount) { asmgen.out(" lsr a") }
|
||||||
asmgen.out(" sta $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" sta P8ESTACK_LO+1,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
if (amount <= 2)
|
if (amount <= 2)
|
||||||
repeat(amount) { asmgen.out(" lda $ESTACK_LO_PLUS1_HEX,x | asl a | ror $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(amount) { asmgen.out(" lda P8ESTACK_LO+1,x | asl a | ror P8ESTACK_LO+1,x") }
|
||||||
else {
|
else {
|
||||||
asmgen.out(" lda $ESTACK_LO_PLUS1_HEX,x | sta ${C64Zeropage.SCRATCH_B1}")
|
asmgen.out(" lda P8ESTACK_LO+1,x | sta P8ZP_SCRATCH_B1")
|
||||||
repeat(amount) { asmgen.out(" asl a | ror ${C64Zeropage.SCRATCH_B1} | lda ${C64Zeropage.SCRATCH_B1}") }
|
repeat(amount) { asmgen.out(" asl a | ror P8ZP_SCRATCH_B1 | lda P8ZP_SCRATCH_B1") }
|
||||||
asmgen.out(" sta $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" sta P8ESTACK_LO+1,x")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.UWORD -> {
|
DataType.UWORD -> {
|
||||||
@ -236,7 +230,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
left -= 7
|
left -= 7
|
||||||
}
|
}
|
||||||
if (left in 0..2)
|
if (left in 0..2)
|
||||||
repeat(left) { asmgen.out(" lsr $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(left) { asmgen.out(" lsr P8ESTACK_HI+1,x | ror P8ESTACK_LO+1,x") }
|
||||||
else
|
else
|
||||||
asmgen.out(" jsr math.shift_right_uw_$left")
|
asmgen.out(" jsr math.shift_right_uw_$left")
|
||||||
}
|
}
|
||||||
@ -247,7 +241,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
left -= 7
|
left -= 7
|
||||||
}
|
}
|
||||||
if (left in 0..2)
|
if (left in 0..2)
|
||||||
repeat(left) { asmgen.out(" lda $ESTACK_HI_PLUS1_HEX,x | asl a | ror $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(left) { asmgen.out(" lda P8ESTACK_HI+1,x | asl a | ror P8ESTACK_HI+1,x | ror P8ESTACK_LO+1,x") }
|
||||||
else
|
else
|
||||||
asmgen.out(" jsr math.shift_right_w_$left")
|
asmgen.out(" jsr math.shift_right_w_$left")
|
||||||
}
|
}
|
||||||
@ -262,11 +256,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
if(amount!=null) {
|
if(amount!=null) {
|
||||||
if (leftDt in ByteDatatypes) {
|
if (leftDt in ByteDatatypes) {
|
||||||
if (amount <= 2)
|
if (amount <= 2)
|
||||||
repeat(amount) { asmgen.out(" asl $ESTACK_LO_PLUS1_HEX,x") }
|
repeat(amount) { asmgen.out(" asl P8ESTACK_LO+1,x") }
|
||||||
else {
|
else {
|
||||||
asmgen.out(" lda $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" lda P8ESTACK_LO+1,x")
|
||||||
repeat(amount) { asmgen.out(" asl a") }
|
repeat(amount) { asmgen.out(" asl a") }
|
||||||
asmgen.out(" sta $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" sta P8ESTACK_LO+1,x")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var left = amount
|
var left = amount
|
||||||
@ -275,7 +269,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
left -= 7
|
left -= 7
|
||||||
}
|
}
|
||||||
if (left in 0..2)
|
if (left in 0..2)
|
||||||
repeat(left) { asmgen.out(" asl $ESTACK_LO_PLUS1_HEX,x | rol $ESTACK_HI_PLUS1_HEX,x") }
|
repeat(left) { asmgen.out(" asl P8ESTACK_LO+1,x | rol P8ESTACK_HI+1,x") }
|
||||||
else
|
else
|
||||||
asmgen.out(" jsr math.shift_left_w_$left")
|
asmgen.out(" jsr math.shift_left_w_$left")
|
||||||
}
|
}
|
||||||
@ -365,9 +359,9 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
when(type) {
|
when(type) {
|
||||||
in ByteDatatypes ->
|
in ByteDatatypes ->
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
eor #255
|
eor #255
|
||||||
sta $ESTACK_LO_PLUS1_HEX,x
|
sta P8ESTACK_LO+1,x
|
||||||
""")
|
""")
|
||||||
in WordDatatypes -> asmgen.out(" jsr prog8_lib.inv_word")
|
in WordDatatypes -> asmgen.out(" jsr prog8_lib.inv_word")
|
||||||
else -> throw AssemblyError("weird type")
|
else -> throw AssemblyError("weird type")
|
||||||
@ -392,10 +386,10 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
val indexValue = index.number.toInt() * elementDt.memorySize()
|
val indexValue = index.number.toInt() * elementDt.memorySize()
|
||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta $ESTACK_LO_HEX,x | lda $arrayVarName+$indexValue+1 | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | lda $arrayVarName+$indexValue+1 | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr c64flt.push_float")
|
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr c64flt.push_float")
|
||||||
@ -406,11 +400,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | lda $arrayVarName+1,y | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | lda $arrayVarName+1,y | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(arrayExpr, elementDt, CpuRegister.A)
|
||||||
@ -439,18 +433,18 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
asmgen.out(" jsr prog8_lib.remainder_ub")
|
asmgen.out(" jsr prog8_lib.remainder_ub")
|
||||||
}
|
}
|
||||||
"+" -> asmgen.out("""
|
"+" -> asmgen.out("""
|
||||||
lda $ESTACK_LO_PLUS2_HEX,x
|
lda P8ESTACK_LO+2,x
|
||||||
clc
|
clc
|
||||||
adc $ESTACK_LO_PLUS1_HEX,x
|
adc P8ESTACK_LO+1,x
|
||||||
inx
|
inx
|
||||||
sta $ESTACK_LO_PLUS1_HEX,x
|
sta P8ESTACK_LO+1,x
|
||||||
""")
|
""")
|
||||||
"-" -> asmgen.out("""
|
"-" -> asmgen.out("""
|
||||||
lda $ESTACK_LO_PLUS2_HEX,x
|
lda P8ESTACK_LO+2,x
|
||||||
sec
|
sec
|
||||||
sbc $ESTACK_LO_PLUS1_HEX,x
|
sbc P8ESTACK_LO+1,x
|
||||||
inx
|
inx
|
||||||
sta $ESTACK_LO_PLUS1_HEX,x
|
sta P8ESTACK_LO+1,x
|
||||||
""")
|
""")
|
||||||
"<<" -> asmgen.out(" jsr prog8_lib.shiftleft_b")
|
"<<" -> asmgen.out(" jsr prog8_lib.shiftleft_b")
|
||||||
">>" -> asmgen.out(" jsr prog8_lib.shiftright_b")
|
">>" -> asmgen.out(" jsr prog8_lib.shiftright_b")
|
||||||
|
@ -4,13 +4,8 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.DataType
|
import prog8.ast.base.DataType
|
||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.expressions.RangeExpr
|
import prog8.ast.expressions.RangeExpr
|
||||||
import prog8.ast.statements.AssignTarget
|
|
||||||
import prog8.ast.statements.Assignment
|
|
||||||
import prog8.ast.statements.ForLoop
|
import prog8.ast.statements.ForLoop
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget
|
||||||
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
|
import prog8.compiler.target.c64.codegen.assignment.AsmAssignment
|
||||||
@ -60,9 +55,9 @@ internal class ForLoopsAsmGen(private val program: Program, private val asmgen:
|
|||||||
asmgen.translateExpression(range.from)
|
asmgen.translateExpression(range.from)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta $varname
|
sta $varname
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
@ -84,9 +79,9 @@ $endLabel inx""")
|
|||||||
asmgen.translateExpression(range.from)
|
asmgen.translateExpression(range.from)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta $varname
|
sta $varname
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
@ -122,9 +117,9 @@ $endLabel inx""")
|
|||||||
assignLoopvar(stmt, range)
|
assignLoopvar(stmt, range)
|
||||||
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
val varname = asmgen.asmIdentifierName(stmt.loopVar)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $ESTACK_HI_PLUS1_HEX,x
|
lda P8ESTACK_HI+1,x
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
sta $modifiedLabel2+1
|
sta $modifiedLabel2+1
|
||||||
$loopLabel""")
|
$loopLabel""")
|
||||||
asmgen.translate(stmt.body)
|
asmgen.translate(stmt.body)
|
||||||
@ -158,9 +153,9 @@ $modifiedLabel2 cmp #0 ; modified
|
|||||||
// (u)words, step >= 2
|
// (u)words, step >= 2
|
||||||
asmgen.translateExpression(range.to)
|
asmgen.translateExpression(range.to)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $ESTACK_HI_PLUS1_HEX,x
|
lda P8ESTACK_HI+1,x
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
sta $modifiedLabel2+1
|
sta $modifiedLabel2+1
|
||||||
""")
|
""")
|
||||||
assignLoopvar(stmt, range)
|
assignLoopvar(stmt, range)
|
||||||
@ -209,9 +204,9 @@ $endLabel inx""")
|
|||||||
// (u)words, step <= -2
|
// (u)words, step <= -2
|
||||||
asmgen.translateExpression(range.to)
|
asmgen.translateExpression(range.to)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $ESTACK_HI_PLUS1_HEX,x
|
lda P8ESTACK_HI+1,x
|
||||||
sta $modifiedLabel+1
|
sta $modifiedLabel+1
|
||||||
lda $ESTACK_LO_PLUS1_HEX,x
|
lda P8ESTACK_LO+1,x
|
||||||
sta $modifiedLabel2+1
|
sta $modifiedLabel2+1
|
||||||
""")
|
""")
|
||||||
assignLoopvar(stmt, range)
|
assignLoopvar(stmt, range)
|
||||||
|
@ -7,7 +7,6 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.statements.SubroutineParameter
|
import prog8.ast.statements.SubroutineParameter
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.codegen.assignment.*
|
import prog8.compiler.target.c64.codegen.assignment.*
|
||||||
|
|
||||||
|
|
||||||
@ -72,7 +71,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
pha
|
pha
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
beq +
|
beq +
|
||||||
sec
|
sec
|
||||||
bcs ++
|
bcs ++
|
||||||
@ -156,7 +155,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
pha
|
pha
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
beq +
|
beq +
|
||||||
sec
|
sec
|
||||||
bcs ++
|
bcs ++
|
||||||
|
@ -6,9 +6,6 @@ import prog8.ast.expressions.IdentifierReference
|
|||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.PostIncrDecr
|
import prog8.ast.statements.PostIncrDecr
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
|
|
||||||
|
|
||||||
@ -59,9 +56,9 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
|||||||
asmgen.translateExpression(addressExpr)
|
asmgen.translateExpression(addressExpr)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta (+) + 1
|
sta (+) + 1
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta (+) + 2
|
sta (+) + 2
|
||||||
""")
|
""")
|
||||||
if(incr)
|
if(incr)
|
||||||
@ -100,7 +97,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
||||||
asmgen.out(" stx ${C64Zeropage.SCRATCH_REG_X} | tax")
|
asmgen.out(" stx P8ZP_SCRATCH_REG_X | tax")
|
||||||
when(elementDt) {
|
when(elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||||
@ -127,7 +124,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg
|
|||||||
}
|
}
|
||||||
else -> throw AssemblyError("weird array elt dt")
|
else -> throw AssemblyError("weird array elt dt")
|
||||||
}
|
}
|
||||||
asmgen.out(" ldx ${C64Zeropage.SCRATCH_REG_X}")
|
asmgen.out(" ldx P8ZP_SCRATCH_REG_X")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,6 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX
|
|
||||||
import prog8.compiler.target.c64.codegen.AsmGen
|
import prog8.compiler.target.c64.codegen.AsmGen
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
|
|
||||||
@ -62,9 +59,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val indexValue = index.number.toInt() * elementDt.memorySize()
|
val indexValue = index.number.toInt() * elementDt.memorySize()
|
||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes ->
|
in ByteDatatypes ->
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | dex")
|
||||||
in WordDatatypes ->
|
in WordDatatypes ->
|
||||||
asmgen.out(" lda $arrayVarName+$indexValue | sta $ESTACK_LO_HEX,x | lda $arrayVarName+$indexValue+1 | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName+$indexValue | sta P8ESTACK_LO,x | lda $arrayVarName+$indexValue+1 | sta P8ESTACK_HI,x | dex")
|
||||||
DataType.FLOAT ->
|
DataType.FLOAT ->
|
||||||
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr c64flt.push_float")
|
asmgen.out(" lda #<$arrayVarName+$indexValue | ldy #>$arrayVarName+$indexValue | jsr c64flt.push_float")
|
||||||
else ->
|
else ->
|
||||||
@ -74,11 +71,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||||
asmgen.out(" lda $arrayVarName,y | sta $ESTACK_LO_HEX,x | lda $arrayVarName+1,y | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $arrayVarName,y | sta P8ESTACK_LO,x | lda $arrayVarName+1,y | sta P8ESTACK_HI,x | dex")
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.A)
|
||||||
@ -167,14 +164,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
when (target.datatype) {
|
when (target.datatype) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname}")
|
asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname}")
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta ${target.asmVarname}
|
sta ${target.asmVarname}
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta ${target.asmVarname}+1
|
sta ${target.asmVarname}+1
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -190,7 +187,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
TargetStorageKind.MEMORY -> {
|
TargetStorageKind.MEMORY -> {
|
||||||
asmgen.out(" inx")
|
asmgen.out(" inx")
|
||||||
storeByteViaRegisterAInMemoryAddress("$ESTACK_LO_HEX,x", target.memory!!)
|
storeByteViaRegisterAInMemoryAddress("P8ESTACK_LO,x", target.memory!!)
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> {
|
TargetStorageKind.ARRAY -> {
|
||||||
val index = target.array!!.arrayspec.index
|
val index = target.array!!.arrayspec.index
|
||||||
@ -199,14 +196,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val scaledIdx = target.constArrayIndexValue!! * target.datatype.memorySize()
|
val scaledIdx = target.constArrayIndexValue!! * target.datatype.memorySize()
|
||||||
when(target.datatype) {
|
when(target.datatype) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname}+$scaledIdx")
|
asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname}+$scaledIdx")
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta ${target.asmVarname}+$scaledIdx
|
sta ${target.asmVarname}+$scaledIdx
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta ${target.asmVarname}+$scaledIdx+1
|
sta ${target.asmVarname}+$scaledIdx+1
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -224,15 +221,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when(target.datatype) {
|
when(target.datatype) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x | sta ${target.asmVarname},y")
|
asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname},y")
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.Y)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta ${target.asmVarname},y
|
sta ${target.asmVarname},y
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta ${target.asmVarname}+1,y
|
sta ${target.asmVarname}+1,y
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -251,7 +248,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
asmgen.out(" inx | lda P8ESTACK_LO,x")
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,16 +257,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
when (target.datatype) {
|
when (target.datatype) {
|
||||||
DataType.UBYTE, DataType.BYTE -> {
|
DataType.UBYTE, DataType.BYTE -> {
|
||||||
when(target.register!!) {
|
when(target.register!!) {
|
||||||
RegisterOrPair.A -> asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
RegisterOrPair.A -> asmgen.out(" inx | lda P8ESTACK_LO,x")
|
||||||
RegisterOrPair.X -> throw AssemblyError("can't use X here")
|
RegisterOrPair.X -> throw AssemblyError("can't use X here")
|
||||||
RegisterOrPair.Y -> asmgen.out(" inx | ldy $ESTACK_LO_HEX,x")
|
RegisterOrPair.Y -> asmgen.out(" inx | ldy P8ESTACK_LO,x")
|
||||||
else -> throw AssemblyError("can't assign byte to register pair word")
|
else -> throw AssemblyError("can't assign byte to register pair word")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> {
|
DataType.UWORD, DataType.WORD, in PassByReferenceDatatypes -> {
|
||||||
when(target.register!!) {
|
when(target.register!!) {
|
||||||
RegisterOrPair.AX -> throw AssemblyError("can't use X here")
|
RegisterOrPair.AX -> throw AssemblyError("can't use X here")
|
||||||
RegisterOrPair.AY-> asmgen.out(" inx | lda $ESTACK_LO_HEX,x | ldy $ESTACK_HI_HEX,x")
|
RegisterOrPair.AY-> asmgen.out(" inx | lda P8ESTACK_LO,x | ldy P8ESTACK_HI,x")
|
||||||
RegisterOrPair.XY-> throw AssemblyError("can't use X here")
|
RegisterOrPair.XY-> throw AssemblyError("can't use X here")
|
||||||
else -> throw AssemblyError("can't assign word to single byte register")
|
else -> throw AssemblyError("can't assign word to single byte register")
|
||||||
}
|
}
|
||||||
@ -322,9 +319,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
val srcname = asmgen.asmIdentifierName(name)
|
val srcname = asmgen.asmIdentifierName(name)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$srcname
|
lda #<$srcname
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
lda #>$srcname
|
lda #>$srcname
|
||||||
sta $ESTACK_HI_HEX,x
|
sta P8ESTACK_HI,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -365,8 +362,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<$sourceName
|
lda #<$sourceName
|
||||||
ldy #>$sourceName
|
ldy #>$sourceName
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
lda #<${target.asmVarname}+$scaledIdx
|
lda #<${target.asmVarname}+$scaledIdx
|
||||||
ldy #>${target.asmVarname}+$scaledIdx
|
ldy #>${target.asmVarname}+$scaledIdx
|
||||||
jsr c64flt.copy_float
|
jsr c64flt.copy_float
|
||||||
@ -394,9 +391,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.A)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array, target.datatype, CpuRegister.A)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldy #<$sourceName
|
ldy #<$sourceName
|
||||||
sty ${C64Zeropage.SCRATCH_W1}
|
sty P8ZP_SCRATCH_W1
|
||||||
ldy #>$sourceName
|
ldy #>$sourceName
|
||||||
sty ${C64Zeropage.SCRATCH_W1+1}
|
sty P8ZP_SCRATCH_W1+1
|
||||||
ldy #>${target.asmVarname}
|
ldy #>${target.asmVarname}
|
||||||
clc
|
clc
|
||||||
adc #<${target.asmVarname}
|
adc #<${target.asmVarname}
|
||||||
@ -408,9 +405,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | lda $sourceName+1 | sta $ESTACK_HI_HEX,x | dex")
|
asmgen.out(" lda $sourceName | sta P8ESTACK_LO,x | lda $sourceName+1 | sta P8ESTACK_HI,x | dex")
|
||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
asmgen.out(" inx | lda P8ESTACK_LO,x")
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -426,9 +423,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #$sourceName
|
lda #$sourceName
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
lda #$sourceName+1
|
lda #$sourceName+1
|
||||||
sta $ESTACK_HI_HEX,x
|
sta P8ESTACK_HI,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,9 +490,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
|
asmgen.out(" lda $sourceName | sta ${target.asmVarname},y")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
asmgen.out(" lda $sourceName | sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" lda $sourceName | sta P8ESTACK_LO,x | dex")
|
||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out(" inx | lda $ESTACK_LO_HEX,x")
|
asmgen.out(" inx | lda P8ESTACK_LO,x")
|
||||||
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
popAndWriteArrayvalueWithUnscaledIndexA(target.datatype, target.asmVarname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -513,7 +510,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #$sourceName
|
lda #$sourceName
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -552,15 +549,15 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.restoreRegister(register)
|
asmgen.restoreRegister(register)
|
||||||
when (register) {
|
when (register) {
|
||||||
CpuRegister.A -> asmgen.out(" sta ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.A -> asmgen.out(" sta P8ZP_SCRATCH_B1")
|
||||||
CpuRegister.X -> asmgen.out(" stx ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.X -> asmgen.out(" stx P8ZP_SCRATCH_B1")
|
||||||
CpuRegister.Y -> asmgen.out(" sty ${C64Zeropage.SCRATCH_B1}")
|
CpuRegister.Y -> asmgen.out(" sty P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
tay
|
tay
|
||||||
lda ${C64Zeropage.SCRATCH_B1}
|
lda P8ZP_SCRATCH_B1
|
||||||
sta ${target.asmVarname},y
|
sta ${target.asmVarname},y
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -590,9 +587,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
when(register) {
|
when(register) {
|
||||||
CpuRegister.A -> asmgen.out(" sta $ESTACK_LO_HEX,x | dex")
|
CpuRegister.A -> asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
CpuRegister.X -> throw AssemblyError("can't use X here")
|
CpuRegister.X -> throw AssemblyError("can't use X here")
|
||||||
CpuRegister.Y -> asmgen.out(" tya | sta $ESTACK_LO_HEX,x | dex")
|
CpuRegister.Y -> asmgen.out(" tya | sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -631,7 +628,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
asl a
|
asl a
|
||||||
tay
|
tay
|
||||||
lda #<${word.toHex()}
|
lda #<${word.toHex()}
|
||||||
@ -651,9 +648,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<${word.toHex()}
|
lda #<${word.toHex()}
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
lda #>${word.toHex()}
|
lda #>${word.toHex()}
|
||||||
sta $ESTACK_HI_HEX,x
|
sta P8ESTACK_HI,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -682,7 +679,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
ldy $ESTACK_LO_HEX,x
|
ldy P8ESTACK_LO,x
|
||||||
lda #${byte.toHex()}
|
lda #${byte.toHex()}
|
||||||
sta ${target.asmVarname},y
|
sta ${target.asmVarname},y
|
||||||
""")
|
""")
|
||||||
@ -698,7 +695,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #${byte.toHex()}
|
lda #${byte.toHex()}
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -740,9 +737,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<${target.asmVarname}
|
lda #<${target.asmVarname}
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
lda #>${target.asmVarname}
|
lda #>${target.asmVarname}
|
||||||
sta ${C64Zeropage.SCRATCH_W1 + 1}
|
sta P8ZP_SCRATCH_W1+1
|
||||||
jsr c64flt.set_0_array_float
|
jsr c64flt.set_0_array_float
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -750,13 +747,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
|
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
|
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
|
||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
val floatConst = asmgen.getFloatConst(float)
|
val floatConst = asmgen.getFloatAsmConst(float)
|
||||||
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// non-zero value
|
// non-zero value
|
||||||
val constFloat = asmgen.getFloatConst(float)
|
val constFloat = asmgen.getFloatAsmConst(float)
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -799,13 +796,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(index)
|
asmgen.translateExpression(index)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda #<${constFloat}
|
lda #<${constFloat}
|
||||||
sta ${C64Zeropage.SCRATCH_W1}
|
sta P8ZP_SCRATCH_W1
|
||||||
lda #>${constFloat}
|
lda #>${constFloat}
|
||||||
sta ${C64Zeropage.SCRATCH_W1 + 1}
|
sta P8ZP_SCRATCH_W1+1
|
||||||
lda #<${arrayVarName}
|
lda #<${arrayVarName}
|
||||||
sta ${C64Zeropage.SCRATCH_W2}
|
sta P8ZP_SCRATCH_W2
|
||||||
lda #>${arrayVarName}
|
lda #>${arrayVarName}
|
||||||
sta ${C64Zeropage.SCRATCH_W2 + 1}
|
sta P8ZP_SCRATCH_W2+1
|
||||||
jsr c64flt.set_array_float
|
jsr c64flt.set_array_float
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
@ -813,7 +810,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
|
TargetStorageKind.MEMORY -> throw AssemblyError("can't assign float to memory byte")
|
||||||
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
|
TargetStorageKind.REGISTER -> throw AssemblyError("can't assign float to register")
|
||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
val floatConst = asmgen.getFloatConst(float)
|
val floatConst = asmgen.getFloatAsmConst(float)
|
||||||
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
asmgen.out(" lda #<$floatConst | ldy #>$floatConst | jsr c64flt.push_float")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -844,7 +841,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda ${address.toHex()}
|
lda ${address.toHex()}
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex""")
|
dex""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -872,7 +869,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> {
|
TargetStorageKind.STACK -> {
|
||||||
asmgen.loadByteFromPointerIntoA(identifier)
|
asmgen.loadByteFromPointerIntoA(identifier)
|
||||||
asmgen.out(" sta $ESTACK_LO_HEX,x | dex")
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -892,13 +889,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.translateExpression(addressExpr)
|
asmgen.translateExpression(addressExpr)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
lda $ESTACK_LO_HEX,x
|
lda P8ESTACK_LO,x
|
||||||
sta ${C64Zeropage.SCRATCH_W2}
|
sta P8ZP_SCRATCH_W2
|
||||||
lda $ESTACK_HI_HEX,x
|
lda P8ESTACK_HI,x
|
||||||
sta ${C64Zeropage.SCRATCH_W2+1}
|
sta P8ZP_SCRATCH_W2+1
|
||||||
lda $ldaInstructionArg
|
lda $ldaInstructionArg
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
sta (P8ZP_SCRATCH_W2),y""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,12 +923,12 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
asmgen.restoreRegister(CpuRegister.A)
|
asmgen.restoreRegister(CpuRegister.A)
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
inx
|
inx
|
||||||
ldy $ESTACK_LO_HEX,x
|
ldy P8ESTACK_LO,x
|
||||||
sty ${C64Zeropage.SCRATCH_W2}
|
sty P8ZP_SCRATCH_W2
|
||||||
ldy $ESTACK_HI_HEX,x
|
ldy P8ESTACK_HI,x
|
||||||
sty ${C64Zeropage.SCRATCH_W2+1}
|
sty P8ZP_SCRATCH_W2+1
|
||||||
ldy #0
|
ldy #0
|
||||||
sta (${C64Zeropage.SCRATCH_W2}),y""")
|
sta (P8ZP_SCRATCH_W2),y""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -939,13 +936,13 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
private fun popAndWriteArrayvalueWithUnscaledIndexA(elementDt: DataType, asmArrayvarname: String) {
|
private fun popAndWriteArrayvalueWithUnscaledIndexA(elementDt: DataType, asmArrayvarname: String) {
|
||||||
when (elementDt) {
|
when (elementDt) {
|
||||||
in ByteDatatypes ->
|
in ByteDatatypes ->
|
||||||
asmgen.out(" tay | inx | lda $ESTACK_LO_HEX,x | sta $asmArrayvarname,y")
|
asmgen.out(" tay | inx | lda P8ESTACK_LO,x | sta $asmArrayvarname,y")
|
||||||
in WordDatatypes ->
|
in WordDatatypes ->
|
||||||
asmgen.out(" asl a | tay | inx | lda $ESTACK_LO_HEX,x | sta $asmArrayvarname,y | lda $ESTACK_HI_HEX,x | sta $asmArrayvarname+1,y")
|
asmgen.out(" asl a | tay | inx | lda P8ESTACK_LO,x | sta $asmArrayvarname,y | lda P8ESTACK_HI,x | sta $asmArrayvarname+1,y")
|
||||||
DataType.FLOAT ->
|
DataType.FLOAT ->
|
||||||
// scaling * 5 is done in the subroutine that's called
|
// scaling * 5 is done in the subroutine that's called
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
sta $ESTACK_LO_HEX,x
|
sta P8ESTACK_LO,x
|
||||||
dex
|
dex
|
||||||
lda #<$asmArrayvarname
|
lda #<$asmArrayvarname
|
||||||
ldy #>$asmArrayvarname
|
ldy #>$asmArrayvarname
|
||||||
|
@ -4,9 +4,7 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.AssemblyError
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
import prog8.compiler.target.CompilationTarget
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX
|
|
||||||
import prog8.compiler.target.c64.codegen.AsmGen
|
import prog8.compiler.target.c64.codegen.AsmGen
|
||||||
import prog8.compiler.toHex
|
import prog8.compiler.toHex
|
||||||
|
|
||||||
@ -194,18 +192,19 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
println("warning: slow stack evaluation used (1): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO optimize...
|
println("warning: slow stack evaluation used (1): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO optimize...
|
||||||
asmgen.translateExpression(memory.addressExpression)
|
asmgen.translateExpression(memory.addressExpression)
|
||||||
// TODO buggy?:
|
// TODO buggy?:
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta ${C64Zeropage.SCRATCH_B1}")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
|
||||||
|
val zp = CompilationTarget.machine.zeropage
|
||||||
when {
|
when {
|
||||||
valueLv != null -> inplaceModification_byte_litval_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, valueLv.toInt())
|
valueLv != null -> inplaceModification_byte_litval_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, valueLv.toInt())
|
||||||
ident != null -> inplaceModification_byte_variable_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, ident)
|
ident != null -> inplaceModification_byte_variable_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, ident)
|
||||||
// TODO more specialized code for types such as memory read etc.
|
// TODO more specialized code for types such as memory read etc.
|
||||||
value is TypecastExpression -> {
|
value is TypecastExpression -> {
|
||||||
if (tryRemoveRedundantCast(value, target, operator)) return
|
if (tryRemoveRedundantCast(value, target, operator)) return
|
||||||
inplaceModification_byte_value_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
inplaceModification_byte_value_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
||||||
}
|
}
|
||||||
else -> inplaceModification_byte_value_to_variable(C64Zeropage.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
else -> inplaceModification_byte_value_to_variable(zp.SCRATCH_B1.toHex(), DataType.UBYTE, operator, value)
|
||||||
}
|
}
|
||||||
asmgen.out(" lda ${C64Zeropage.SCRATCH_B1} | jsr prog8_lib.write_byte_to_address_on_stack | inx")
|
asmgen.out(" lda P8ZP_SCRATCH_B1 | jsr prog8_lib.write_byte_to_address_on_stack | inx")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,27 +239,27 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"+" -> {
|
"+" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
jsr c64flt.pop_float_fac1
|
jsr c64flt.pop_float_fac1
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<$name
|
lda #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.FADD
|
jsr c64flt.FADD
|
||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
jsr c64flt.pop_float_fac1
|
jsr c64flt.pop_float_fac1
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<$name
|
lda #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.FSUB
|
jsr c64flt.FSUB
|
||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
@ -290,7 +289,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"-" -> TODO("-")
|
"-" -> TODO("-")
|
||||||
"*" -> {
|
"*" -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<$name
|
lda #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVFM
|
jsr c64flt.MOVFM
|
||||||
@ -300,7 +299,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"/" -> TODO("div")
|
"/" -> TODO("div")
|
||||||
@ -310,14 +309,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
private fun inplaceModification_float_litval_to_variable(name: String, operator: String, value: Double) {
|
||||||
val constValueName = asmgen.getFloatConst(value)
|
val constValueName = asmgen.getFloatAsmConst(value)
|
||||||
when (operator) {
|
when (operator) {
|
||||||
"**" -> TODO("pow")
|
"**" -> TODO("pow")
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if (value == 0.0)
|
if (value == 0.0)
|
||||||
return
|
return
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<$name
|
lda #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVFM
|
jsr c64flt.MOVFM
|
||||||
@ -327,14 +326,14 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if (value == 0.0)
|
if (value == 0.0)
|
||||||
return
|
return
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<$constValueName
|
lda #<$constValueName
|
||||||
ldy #>$constValueName
|
ldy #>$constValueName
|
||||||
jsr c64flt.MOVFM
|
jsr c64flt.MOVFM
|
||||||
@ -344,7 +343,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
"*" -> TODO("mul")
|
"*" -> TODO("mul")
|
||||||
@ -369,19 +368,19 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> {
|
"+" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" clc | adc $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" clc | adc P8ESTACK_LO+1,x")
|
||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" sec | sbc $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" sec | sbc P8ESTACK_LO+1,x")
|
||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
@ -395,27 +394,27 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
">>" -> TODO("ubyte lsr")
|
">>" -> TODO("ubyte lsr")
|
||||||
"&" -> {
|
"&" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" and $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" and P8ESTACK_LO+1,x")
|
||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"^" -> {
|
"^" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" xor $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" xor P8ESTACK_LO+1,x")
|
||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"|" -> {
|
"|" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
asmgen.out(" ora $ESTACK_LO_PLUS1_HEX,x")
|
asmgen.out(" ora P8ESTACK_LO+1,x")
|
||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -432,7 +431,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -440,7 +439,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
@ -458,7 +457,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"^" -> {
|
"^" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -466,7 +465,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"|" -> {
|
"|" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -474,7 +473,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -489,7 +488,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -497,7 +496,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> {
|
"/" -> {
|
||||||
@ -521,7 +520,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
@ -531,7 +530,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&" -> {
|
"&" -> {
|
||||||
@ -540,7 +539,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"^" -> {
|
"^" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -548,7 +547,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
"|" -> {
|
"|" -> {
|
||||||
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
val (ptrOnZp, sourceName) = asmgen.loadByteFromPointerIntoA(pointervar)
|
||||||
@ -556,7 +555,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -782,7 +781,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"+" -> asmgen.out("""
|
"+" -> asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
clc
|
clc
|
||||||
adc $ESTACK_LO_PLUS1_HEX,x
|
adc P8ESTACK_LO+1,x
|
||||||
sta $name
|
sta $name
|
||||||
bcc +
|
bcc +
|
||||||
inc $name+1
|
inc $name+1
|
||||||
@ -790,7 +789,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
"-" -> asmgen.out("""
|
"-" -> asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
sec
|
sec
|
||||||
sbc $ESTACK_LO_PLUS1_HEX,x
|
sbc P8ESTACK_LO+1,x
|
||||||
sta $name
|
sta $name
|
||||||
bcs +
|
bcs +
|
||||||
dec $name+1
|
dec $name+1
|
||||||
@ -846,8 +845,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// the value is a proper 16-bit word, so use both bytes of it.
|
// the value is a proper 16-bit word, so use both bytes of it.
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | adc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"+" -> asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name | lda $name+1 | adc P8ESTACK_HI+1,x | sta $name+1")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | sbc $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"-" -> asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name | lda $name+1 | sbc P8ESTACK_HI+1,x | sta $name+1")
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
"%" -> {
|
"%" -> {
|
||||||
@ -857,9 +856,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
// asmgen.out(" jsr prog8_lib.remainder_ub")
|
||||||
}
|
}
|
||||||
"<<", ">>" -> throw AssemblyError("shift by a word value not supported, max is a byte")
|
"<<", ">>" -> throw AssemblyError("shift by a word value not supported, max is a byte")
|
||||||
"&" -> asmgen.out(" lda $name | and $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | and $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"&" -> asmgen.out(" lda $name | and P8ESTACK_LO+1,x | sta $name | lda $name+1 | and P8ESTACK_HI+1,x | sta $name+1")
|
||||||
"^" -> asmgen.out(" lda $name | xor $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | xor $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"^" -> asmgen.out(" lda $name | xor P8ESTACK_LO+1,x | sta $name | lda $name+1 | xor P8ESTACK_HI+1,x | sta $name+1")
|
||||||
"|" -> asmgen.out(" lda $name | ora $ESTACK_LO_PLUS1_HEX,x | sta $name | lda $name+1 | ora $ESTACK_HI_PLUS1_HEX,x | sta $name+1")
|
"|" -> asmgen.out(" lda $name | ora P8ESTACK_LO+1,x | sta $name | lda $name+1 | ora P8ESTACK_HI+1,x | sta $name+1")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -878,8 +877,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.translateExpression(value)
|
asmgen.translateExpression(value)
|
||||||
when (operator) {
|
when (operator) {
|
||||||
// note: ** (power) operator requires floats.
|
// note: ** (power) operator requires floats.
|
||||||
"+" -> asmgen.out(" lda $name | clc | adc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"+" -> asmgen.out(" lda $name | clc | adc P8ESTACK_LO+1,x | sta $name")
|
||||||
"-" -> asmgen.out(" lda $name | sec | sbc $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"-" -> asmgen.out(" lda $name | sec | sbc P8ESTACK_LO+1,x | sta $name")
|
||||||
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
"*" -> TODO("mul")// asmgen.out(" jsr prog8_lib.mul_byte") // the optimized routines should have been checked earlier
|
||||||
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
"/" -> TODO("div")// asmgen.out(if(types==DataType.UBYTE) " jsr prog8_lib.idiv_ub" else " jsr prog8_lib.idiv_b")
|
||||||
"%" -> {
|
"%" -> {
|
||||||
@ -923,9 +922,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"&" -> asmgen.out(" lda $name | and $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"&" -> asmgen.out(" lda $name | and P8ESTACK_LO+1,x | sta $name")
|
||||||
"^" -> asmgen.out(" lda $name | xor $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"^" -> asmgen.out(" lda $name | xor P8ESTACK_LO+1,x | sta $name")
|
||||||
"|" -> asmgen.out(" lda $name | ora $ESTACK_LO_PLUS1_HEX,x | sta $name")
|
"|" -> asmgen.out(" lda $name | ora P8ESTACK_LO+1,x | sta $name")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
asmgen.out(" inx")
|
asmgen.out(" inx")
|
||||||
@ -1063,7 +1062,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, target.datatype, CpuRegister.Y, true)
|
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, target.datatype, CpuRegister.Y, true)
|
||||||
asmgen.out(" lda #0 | sta ${target.asmVarname},y")
|
asmgen.out(" lda #0 | sta ${target.asmVarname},y")
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> asmgen.out(" lda #0 | sta $ESTACK_HI_PLUS1_HEX,x")
|
TargetStorageKind.STACK -> asmgen.out(" lda #0 | sta P8ESTACK_HI+1,x")
|
||||||
else -> throw AssemblyError("weird target")
|
else -> throw AssemblyError("weird target")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1121,7 +1120,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
println("warning: slow stack evaluation used (6): ${mem.addressExpression::class.simpleName} at ${mem.addressExpression.position}") // TODO
|
println("warning: slow stack evaluation used (6): ${mem.addressExpression::class.simpleName} at ${mem.addressExpression.position}") // TODO
|
||||||
@ -1192,7 +1191,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
if(ptrOnZp)
|
if(ptrOnZp)
|
||||||
asmgen.out(" sta ($sourceName),y")
|
asmgen.out(" sta ($sourceName),y")
|
||||||
else
|
else
|
||||||
asmgen.out(" sta (${C64Zeropage.SCRATCH_W1}),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
println("warning: slow stack evaluation used (7): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO
|
println("warning: slow stack evaluation used (7): ${memory.addressExpression::class.simpleName} at ${memory.addressExpression.position}") // TODO
|
||||||
@ -1272,7 +1271,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
TargetStorageKind.VARIABLE -> {
|
TargetStorageKind.VARIABLE -> {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
stx ${C64Zeropage.SCRATCH_REG_X}
|
stx P8ZP_SCRATCH_REG_X
|
||||||
lda #<${target.asmVarname}
|
lda #<${target.asmVarname}
|
||||||
ldy #>${target.asmVarname}
|
ldy #>${target.asmVarname}
|
||||||
jsr c64flt.MOVFM
|
jsr c64flt.MOVFM
|
||||||
@ -1280,7 +1279,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
ldx #<${target.asmVarname}
|
ldx #<${target.asmVarname}
|
||||||
ldy #>${target.asmVarname}
|
ldy #>${target.asmVarname}
|
||||||
jsr c64flt.MOVMF
|
jsr c64flt.MOVMF
|
||||||
ldx ${C64Zeropage.SCRATCH_REG_X}
|
ldx P8ZP_SCRATCH_REG_X
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
|
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
|
||||||
|
@ -123,7 +123,7 @@ class TestCompiler {
|
|||||||
|
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class TestZeropage {
|
class TestC64Zeropage {
|
||||||
|
|
||||||
private val errors = ErrorReporter()
|
private val errors = ErrorReporter()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user