mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
more split array stuff for 6502
This commit is contained in:
parent
c94e292176
commit
3ac9036c79
@ -368,7 +368,10 @@ class AsmGen6502Internal (
|
||||
val reg = register.toString().lowercase()
|
||||
val indexnum = expr.index.asConstInteger()
|
||||
if (indexnum != null) {
|
||||
val indexValue = indexnum * options.compTarget.memorySize(elementDt) + if (addOneExtra) 1 else 0
|
||||
val indexValue = if(expr.splitWords)
|
||||
indexnum + if (addOneExtra) 1 else 0
|
||||
else
|
||||
indexnum * options.compTarget.memorySize(elementDt) + if (addOneExtra) 1 else 0
|
||||
out(" ld$reg #$indexValue")
|
||||
return
|
||||
}
|
||||
@ -378,8 +381,23 @@ class AsmGen6502Internal (
|
||||
|
||||
val indexName = asmVariableName(indexVar)
|
||||
|
||||
if(expr.splitWords)
|
||||
TODO("split word access ${expr.position}")
|
||||
if(expr.splitWords) {
|
||||
if(addOneExtra) {
|
||||
out(" ldy $indexName | iny")
|
||||
when (register) {
|
||||
CpuRegister.A -> out(" tya")
|
||||
CpuRegister.X -> out(" txy")
|
||||
CpuRegister.Y -> {}
|
||||
}
|
||||
} else {
|
||||
when (register) {
|
||||
CpuRegister.A -> out(" lda $indexName")
|
||||
CpuRegister.X -> out(" ldx $indexName")
|
||||
CpuRegister.Y -> out(" ldy $indexName")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (addOneExtra) {
|
||||
// add 1 to the result
|
||||
@ -389,15 +407,13 @@ class AsmGen6502Internal (
|
||||
when (register) {
|
||||
CpuRegister.A -> out(" tya")
|
||||
CpuRegister.X -> out(" tyx")
|
||||
CpuRegister.Y -> {
|
||||
}
|
||||
CpuRegister.Y -> {}
|
||||
}
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
out(" lda $indexName | sec | rol a")
|
||||
when (register) {
|
||||
CpuRegister.A -> {
|
||||
}
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> out(" tax")
|
||||
CpuRegister.Y -> out(" tay")
|
||||
}
|
||||
@ -413,8 +429,7 @@ class AsmGen6502Internal (
|
||||
adc $indexName"""
|
||||
)
|
||||
when (register) {
|
||||
CpuRegister.A -> {
|
||||
}
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> out(" tax")
|
||||
CpuRegister.Y -> out(" tay")
|
||||
}
|
||||
@ -427,8 +442,7 @@ class AsmGen6502Internal (
|
||||
in WordDatatypes -> {
|
||||
out(" lda $indexName | asl a")
|
||||
when (register) {
|
||||
CpuRegister.A -> {
|
||||
}
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> out(" tax")
|
||||
CpuRegister.Y -> out(" tay")
|
||||
}
|
||||
@ -444,8 +458,7 @@ class AsmGen6502Internal (
|
||||
adc $indexName"""
|
||||
)
|
||||
when (register) {
|
||||
CpuRegister.A -> {
|
||||
}
|
||||
CpuRegister.A -> {}
|
||||
CpuRegister.X -> out(" tax")
|
||||
CpuRegister.Y -> out(" tay")
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(what.splitWords)
|
||||
TODO("splitwords ${what.position}")
|
||||
TODO("ror2 split words ${what.position}")
|
||||
translateRolRorArrayArgs(what.variable, what, "ror2", 'w')
|
||||
asmgen.out(" jsr prog8_lib.ror2_array_uw")
|
||||
}
|
||||
@ -494,7 +494,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(what.splitWords)
|
||||
TODO("splitwords ${what.position}")
|
||||
TODO("ror split words ${what.position}")
|
||||
translateRolRorArrayArgs(what.variable, what, "ror", 'w')
|
||||
asmgen.out(" jsr prog8_lib.ror_array_uw")
|
||||
}
|
||||
@ -538,7 +538,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(what.splitWords)
|
||||
TODO("splitwords ${what.position}")
|
||||
TODO("rol2 split words ${what.position}")
|
||||
translateRolRorArrayArgs(what.variable, what, "rol2", 'w')
|
||||
asmgen.out(" jsr prog8_lib.rol2_array_uw")
|
||||
}
|
||||
@ -599,7 +599,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
when (what) {
|
||||
is PtArrayIndexer -> {
|
||||
if(what.splitWords)
|
||||
TODO("splitwords ${what.position}")
|
||||
TODO("rol split words ${what.position}")
|
||||
translateRolRorArrayArgs(what.variable, what, "rol", 'w')
|
||||
asmgen.out(" jsr prog8_lib.rol_array_uw")
|
||||
}
|
||||
@ -616,7 +616,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
|
||||
private fun translateRolRorArrayArgs(arrayvar: PtIdentifier, indexer: PtArrayIndexer, operation: String, dt: Char) {
|
||||
if(indexer.splitWords)
|
||||
TODO("split word access ${indexer.position}")
|
||||
TODO("rol/ror split words access ${indexer.position}")
|
||||
if(arrayvar.type==DataType.UWORD) {
|
||||
if(dt!='b')
|
||||
throw AssemblyError("non-array var indexing requires bytes dt")
|
||||
|
@ -238,7 +238,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" lda #<$varname | ldy #>$varname| jsr floats.push_float")
|
||||
}
|
||||
in SplitWordArrayTypes -> {
|
||||
TODO("split $varname")
|
||||
throw AssemblyError("can't push address of split-word array ${expr.position}")
|
||||
}
|
||||
in IterableDatatypes -> {
|
||||
asmgen.out(" lda #<$varname | sta P8ESTACK_LO,x | lda #>$varname | sta P8ESTACK_HI,x | dex")
|
||||
@ -748,7 +748,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
||||
val arrayVarName = asmgen.asmVariableName(arrayExpr.variable)
|
||||
|
||||
if(arrayExpr.splitWords)
|
||||
TODO("split word access ${arrayExpr.position}")
|
||||
TODO("split words ${arrayExpr.position}")
|
||||
|
||||
if(arrayExpr.variable.type==DataType.UWORD) {
|
||||
// indexing a pointer var instead of a real array or string
|
||||
|
@ -441,7 +441,7 @@ $loopLabel sty $indexVar
|
||||
// allocate index var on ZP if possible
|
||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||
result.fold(
|
||||
success = { (address,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||
success = { (address,_,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||
failure = { asmgen.out("$indexVar .byte 0") }
|
||||
)
|
||||
} else {
|
||||
@ -449,13 +449,44 @@ $loopLabel sty $indexVar
|
||||
}
|
||||
asmgen.out(endLabel)
|
||||
}
|
||||
DataType.ARRAY_UW_SPLIT -> {
|
||||
asmgen.out("; TODO iterate over split uword array")
|
||||
// TODO("iterate over split uword array")
|
||||
}
|
||||
DataType.ARRAY_W_SPLIT -> {
|
||||
asmgen.out("; TODO iterate over split word array")
|
||||
// TODO("iterate over split word array")
|
||||
DataType.ARRAY_UW_SPLIT, DataType.ARRAY_W_SPLIT -> {
|
||||
numElements!!
|
||||
val indexVar = asmgen.makeLabel("for_index")
|
||||
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
||||
asmgen.out("""
|
||||
ldy #0
|
||||
$loopLabel sty $indexVar
|
||||
lda ${iterableName}_lsb,y
|
||||
sta $loopvarName
|
||||
lda ${iterableName}_msb,y
|
||||
sta $loopvarName+1""")
|
||||
asmgen.translate(stmt.statements)
|
||||
if(numElements<=255u) {
|
||||
asmgen.out("""
|
||||
ldy $indexVar
|
||||
iny
|
||||
cpy #$numElements
|
||||
beq $endLabel
|
||||
bne $loopLabel""")
|
||||
} else {
|
||||
// length is 256
|
||||
asmgen.out("""
|
||||
ldy $indexVar
|
||||
iny
|
||||
bne $loopLabel
|
||||
beq $endLabel""")
|
||||
}
|
||||
if(numElements>=16u) {
|
||||
// allocate index var on ZP if possible
|
||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||
result.fold(
|
||||
success = { (address,_,_)-> asmgen.out("""$indexVar = $address ; auto zp UBYTE""") },
|
||||
failure = { asmgen.out("$indexVar .byte 0") }
|
||||
)
|
||||
} else {
|
||||
asmgen.out("$indexVar .byte 0")
|
||||
}
|
||||
asmgen.out(endLabel)
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
throw AssemblyError("for loop with floating point variables is not supported")
|
||||
|
@ -65,6 +65,31 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
val asmArrayvarname = asmgen.asmVariableName(targetArrayIdx.variable)
|
||||
val elementDt = targetArrayIdx.type
|
||||
val constIndex = targetArrayIdx.index.asConstInteger()
|
||||
if(targetArrayIdx.splitWords) {
|
||||
if(constIndex!=null) {
|
||||
if(incr)
|
||||
asmgen.out(" inc ${asmArrayvarname}_lsb+$constIndex | bne + | inc ${asmArrayvarname}_msb+$constIndex |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda ${asmArrayvarname}_lsb+$constIndex
|
||||
bne +
|
||||
dec ${asmArrayvarname}_msb+$constIndex
|
||||
+ dec ${asmArrayvarname}_lsb+$constIndex""")
|
||||
} else {
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, scope!!)
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.X)
|
||||
if(incr)
|
||||
asmgen.out(" inc ${asmArrayvarname}_lsb,x | bne + | inc ${asmArrayvarname}_msb,x |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda ${asmArrayvarname}_lsb,x
|
||||
bne +
|
||||
dec ${asmArrayvarname}_msb,x
|
||||
+ dec ${asmArrayvarname}_lsb,x""")
|
||||
asmgen.restoreRegisterLocal(CpuRegister.X)
|
||||
}
|
||||
return
|
||||
}
|
||||
if(constIndex!=null) {
|
||||
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
||||
when(elementDt) {
|
||||
@ -74,11 +99,10 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
asmgen.out(" inc $asmArrayvarname+$indexValue | bne + | inc $asmArrayvarname+$indexValue+1 |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda $asmArrayvarname+$indexValue
|
||||
bne +
|
||||
dec $asmArrayvarname+$indexValue+1
|
||||
+ dec $asmArrayvarname+$indexValue
|
||||
""")
|
||||
lda $asmArrayvarname+$indexValue
|
||||
bne +
|
||||
dec $asmArrayvarname+$indexValue+1
|
||||
+ dec $asmArrayvarname+$indexValue""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out(" lda #<($asmArrayvarname+$indexValue) | ldy #>($asmArrayvarname+$indexValue)")
|
||||
@ -89,9 +113,8 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
}
|
||||
else
|
||||
{
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.A)
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, scope!!)
|
||||
asmgen.out(" tax")
|
||||
asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, elementDt, CpuRegister.X)
|
||||
when(elementDt) {
|
||||
in ByteDatatypes -> {
|
||||
asmgen.out(if(incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x")
|
||||
@ -101,20 +124,20 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as
|
||||
asmgen.out(" inc $asmArrayvarname,x | bne + | inc $asmArrayvarname+1,x |+")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda $asmArrayvarname,x
|
||||
bne +
|
||||
dec $asmArrayvarname+1,x
|
||||
lda $asmArrayvarname,x
|
||||
bne +
|
||||
dec $asmArrayvarname+1,x
|
||||
+ dec $asmArrayvarname,x
|
||||
""")
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
asmgen.out("""
|
||||
ldy #>$asmArrayvarname
|
||||
clc
|
||||
adc #<$asmArrayvarname
|
||||
bcc +
|
||||
iny
|
||||
+ jsr floats.inc_var_f""")
|
||||
ldy #>$asmArrayvarname
|
||||
clc
|
||||
adc #<$asmArrayvarname
|
||||
bcc +
|
||||
iny
|
||||
+ jsr floats.inc_var_f""")
|
||||
}
|
||||
else -> throw AssemblyError("weird array elt dt")
|
||||
}
|
||||
|
@ -629,11 +629,15 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
DataType.ARRAY_UW_SPLIT -> {
|
||||
val data = makeArrayFillDataUnsigned(dt, value, orNumberOfZeros)
|
||||
// TODO("gen split uword array $data")
|
||||
asmgen.out("_array_$varname := ${data.joinToString()}")
|
||||
asmgen.out("${varname}_lsb\t.byte <_array_$varname")
|
||||
asmgen.out("${varname}_msb\t.byte >_array_$varname")
|
||||
}
|
||||
DataType.ARRAY_W_SPLIT -> {
|
||||
val data = makeArrayFillDataSigned(dt, value, orNumberOfZeros)
|
||||
// TODO("gen split word array $data")
|
||||
asmgen.out("_array_$varname := ${data.joinToString()}")
|
||||
asmgen.out("${varname}_lsb\t.byte <_array_$varname")
|
||||
asmgen.out("${varname}_msb\t.byte >_array_$varname")
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
||||
@ -730,7 +734,7 @@ internal class ProgramAndVarsGen(
|
||||
val number = it.number!!.toInt()
|
||||
"$" + number.toString(16).padStart(4, '0')
|
||||
}
|
||||
in SplitWordArrayTypes -> array.map {
|
||||
DataType.ARRAY_W, DataType.ARRAY_W_SPLIT -> array.map {
|
||||
val number = it.number!!.toInt()
|
||||
val hexnum = number.absoluteValue.toString(16).padStart(4, '0')
|
||||
if(number>=0)
|
||||
|
@ -172,8 +172,6 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
AsmAssignSource(SourceStorageKind.MEMORY, program, asmgen, DataType.UBYTE, memory = value)
|
||||
}
|
||||
is PtArrayIndexer -> {
|
||||
if(value.splitWords)
|
||||
TODO("splitwords ${value.position}")
|
||||
AsmAssignSource(SourceStorageKind.ARRAY, program, asmgen, value.type, array = value)
|
||||
}
|
||||
is PtBuiltinFunctionCall -> {
|
||||
|
@ -80,6 +80,20 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
val constIndex = value.index.asConstInteger()
|
||||
|
||||
if(value.splitWords) {
|
||||
require(elementDt in WordDatatypes)
|
||||
if(constIndex!=null) {
|
||||
asmgen.out(" lda ${arrayVarName}_lsb+$constIndex | ldy ${arrayVarName}_msb+$constIndex")
|
||||
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
} else {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(value, elementDt, CpuRegister.Y)
|
||||
asmgen.out(" lda ${arrayVarName}_lsb,y | pha | lda ${arrayVarName}_msb,y | tay | pla")
|
||||
assignRegisterpairWord(assign.target, RegisterOrPair.AY)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (constIndex!=null) {
|
||||
// constant array index value
|
||||
val indexValue = constIndex * program.memsizer.memorySize(elementDt)
|
||||
@ -1455,6 +1469,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
// return
|
||||
// }
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign type casted byte into split words ${target.position}")
|
||||
// byte to word, just assign to registers first, then assign into array
|
||||
assignExpressionToRegister(value, RegisterOrPair.AY, targetDt==DataType.WORD)
|
||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||
@ -1851,6 +1867,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" inx | lda P8ESTACK_LO,x | sta ${target.asmVarname}+$scaledIdx")
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign word stack value into split words ${target.position}")
|
||||
asmgen.out("""
|
||||
inx
|
||||
lda P8ESTACK_LO,x
|
||||
@ -2054,6 +2072,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
target.array!!
|
||||
if(target.array.splitWords)
|
||||
TODO("assign var into split words ${target.position}")
|
||||
if(target.constArrayIndexValue!=null) {
|
||||
val scaledIdx = target.constArrayIndexValue!! * program.memsizer.memorySize(target.datatype).toUInt()
|
||||
when(target.datatype) {
|
||||
@ -2348,6 +2368,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
""")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(wordtarget.array!!.splitWords)
|
||||
TODO("assign byte into split words ${wordtarget.position}")
|
||||
if (wordtarget.constArrayIndexValue!=null) {
|
||||
val scaledIdx = wordtarget.constArrayIndexValue!! * 2u
|
||||
asmgen.out(" lda $sourceName")
|
||||
@ -2356,7 +2378,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
else {
|
||||
asmgen.saveRegisterLocal(CpuRegister.X, wordtarget.scope!!)
|
||||
asmgen.loadScaledArrayIndexIntoRegister(wordtarget.array!!, wordtarget.datatype, CpuRegister.X)
|
||||
asmgen.loadScaledArrayIndexIntoRegister(wordtarget.array, wordtarget.datatype, CpuRegister.X)
|
||||
asmgen.out(" lda $sourceName")
|
||||
asmgen.signExtendAYlsb(DataType.BYTE)
|
||||
asmgen.out(" sta ${wordtarget.asmVarname},x | inx | tya | sta ${wordtarget.asmVarname},x")
|
||||
@ -2698,6 +2720,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(target.array!!.splitWords)
|
||||
TODO("assign register pair into split words ${target.position}")
|
||||
if (target.constArrayIndexValue!=null) {
|
||||
val idx = target.constArrayIndexValue!! * 2u
|
||||
when (regs) {
|
||||
@ -2723,7 +2747,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
RegisterOrPair.XY -> asmgen.out(" txa | pha | tya | pha")
|
||||
else -> throw AssemblyError("expected reg pair")
|
||||
}
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y, true)
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array, DataType.UWORD, CpuRegister.Y, true)
|
||||
asmgen.out("""
|
||||
pla
|
||||
sta ${target.asmVarname},y
|
||||
@ -2833,11 +2857,16 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y)
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
sta ${target.asmVarname},y
|
||||
sta ${target.asmVarname}+1,y
|
||||
""")
|
||||
if(target.array.splitWords)
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
sta ${target.asmVarname}_lsb,y
|
||||
sta ${target.asmVarname}_msb,y""")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda #0
|
||||
sta ${target.asmVarname},y
|
||||
sta ${target.asmVarname}+1,y""")
|
||||
}
|
||||
TargetStorageKind.REGISTER -> {
|
||||
when(target.register!!) {
|
||||
@ -2885,12 +2914,18 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
asmgen.loadScaledArrayIndexIntoRegister(target.array!!, DataType.UWORD, CpuRegister.Y)
|
||||
asmgen.out("""
|
||||
lda #<${word.toHex()}
|
||||
sta ${target.asmVarname},y
|
||||
lda #>${word.toHex()}
|
||||
sta ${target.asmVarname}+1,y
|
||||
""")
|
||||
if(target.array.splitWords)
|
||||
asmgen.out("""
|
||||
lda #<${word.toHex()}
|
||||
sta ${target.asmVarname}_lsb,y
|
||||
lda #>${word.toHex()}
|
||||
sta ${target.asmVarname}_msb,y""")
|
||||
else
|
||||
asmgen.out("""
|
||||
lda #<${word.toHex()}
|
||||
sta ${target.asmVarname},y
|
||||
lda #>${word.toHex()}
|
||||
sta ${target.asmVarname}+1,y""")
|
||||
}
|
||||
TargetStorageKind.REGISTER -> {
|
||||
when(target.register!!) {
|
||||
@ -3272,6 +3307,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" lda #0 | sta ${wordtarget.asmVarname}+1")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(wordtarget.array!!.splitWords)
|
||||
TODO("assign mem byte into split words ${wordtarget.position}")
|
||||
asmgen.out(" lda ${address.toHex()} | ldy #0")
|
||||
assignRegisterpairWord(wordtarget, RegisterOrPair.AY)
|
||||
}
|
||||
@ -3301,6 +3338,8 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" lda #0 | sta ${wordtarget.asmVarname}+1")
|
||||
}
|
||||
TargetStorageKind.ARRAY -> {
|
||||
if(wordtarget.array!!.splitWords)
|
||||
TODO("assign mem byte into split words ${wordtarget.position}")
|
||||
asmgen.loadByteFromPointerIntoA(identifier)
|
||||
asmgen.out(" ldy #0")
|
||||
assignRegisterpairWord(wordtarget, RegisterOrPair.AY)
|
||||
|
@ -193,6 +193,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
TargetStorageKind.ARRAY -> {
|
||||
val indexNum = target.array!!.index as? PtNumber
|
||||
val indexVar = target.array.index as? PtIdentifier
|
||||
if(target.array.splitWords)
|
||||
TODO("in-place assign split words ${target.position}")
|
||||
when {
|
||||
indexNum!=null -> {
|
||||
val targetVarName = "${target.asmVarname} + ${indexNum.number.toInt()*program.memsizer.memorySize(target.datatype)}"
|
||||
|
@ -1369,20 +1369,20 @@ class IRCodeGen(
|
||||
private fun translate(postIncrDecr: PtPostIncrDecr): IRCodeChunks {
|
||||
val operationMem: Opcode
|
||||
val operationRegister: Opcode
|
||||
val array = postIncrDecr.target.array
|
||||
when(postIncrDecr.operator) {
|
||||
"++" -> {
|
||||
operationMem = Opcode.INCM
|
||||
operationMem = if(array?.splitWords==true) Opcode.INCMSPLIT else Opcode.INCM
|
||||
operationRegister = Opcode.INC
|
||||
}
|
||||
"--" -> {
|
||||
operationMem = Opcode.DECM
|
||||
operationMem = if(array?.splitWords==true) Opcode.DECMSPLIT else Opcode.DECM
|
||||
operationRegister = Opcode.DEC
|
||||
}
|
||||
else -> throw AssemblyError("weird operator")
|
||||
}
|
||||
val ident = postIncrDecr.target.identifier
|
||||
val memory = postIncrDecr.target.memory
|
||||
val array = postIncrDecr.target.array
|
||||
val irDt = irType(postIncrDecr.target.type)
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
if(ident!=null) {
|
||||
@ -1405,18 +1405,35 @@ class IRCodeGen(
|
||||
val variable = array.variable.name
|
||||
val itemsize = program.memsizer.memorySize(array.type)
|
||||
val fixedIndex = constIntValue(array.index)
|
||||
if(fixedIndex!=null) {
|
||||
val offset = fixedIndex*itemsize
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), null)
|
||||
if(array.splitWords) {
|
||||
val iterable = symbolTable.flat.getValue(array.variable.name) as StStaticVariable
|
||||
val arrayLength = iterable.length!!
|
||||
if(fixedIndex!=null) {
|
||||
addInstr(result, IRInstruction(operationMem, irDt, immediate = arrayLength, labelSymbol="$variable+$fixedIndex"), null)
|
||||
} else {
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
val incReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOADXSPLIT, irDt, reg1=incReg, reg2=indexTr.resultReg, immediate = arrayLength, labelSymbol=variable)
|
||||
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
chunk += IRInstruction(Opcode.STOREXSPLIT, irDt, reg1=incReg, reg2=indexTr.resultReg, immediate = arrayLength, labelSymbol=variable)
|
||||
result += chunk
|
||||
}
|
||||
} else {
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
val incReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
result += chunk
|
||||
if(fixedIndex!=null) {
|
||||
val offset = fixedIndex*itemsize
|
||||
addInstr(result, IRInstruction(operationMem, irDt, labelSymbol="$variable+$offset"), null)
|
||||
} else {
|
||||
val indexTr = expressionEval.translateExpression(array.index)
|
||||
addToResult(result, indexTr, indexTr.resultReg, -1)
|
||||
val chunk = IRCodeChunk(null, null)
|
||||
val incReg = registers.nextFree()
|
||||
chunk += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
chunk += IRInstruction(operationRegister, irDt, reg1=incReg)
|
||||
chunk += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable)
|
||||
result += chunk
|
||||
}
|
||||
}
|
||||
} else
|
||||
throw AssemblyError("weird assigntarget")
|
||||
|
@ -74,7 +74,12 @@ main {
|
||||
txt.nl()
|
||||
|
||||
split_uwords[1]++
|
||||
split_words[1]--
|
||||
split_words[1]++
|
||||
|
||||
print_arrays()
|
||||
txt.nl()
|
||||
split_uwords[1] |= 4095
|
||||
split_words[1] |= 127
|
||||
|
||||
print_arrays()
|
||||
txt.nl()
|
||||
|
@ -121,8 +121,10 @@ exts reg1 - reg1 = signed extension of reg1 (b
|
||||
ext reg1 - reg1 = unsigned extension of reg1 (which in practice just means clearing the MSB / MSW) (ext.w not yet implemented as we don't have longs yet)
|
||||
inc reg1 - reg1 = reg1+1
|
||||
incm address - memory at address += 1
|
||||
incmsplit arraylen, address - memory at address += 1 (in lsb/msb split word array)
|
||||
dec reg1 - reg1 = reg1-1
|
||||
decm address - memory at address -= 1
|
||||
decmsplit arraylen, address - memory at address -= 1 (in lsb/msb split word array)
|
||||
neg reg1 - reg1 = sign negation of reg1
|
||||
negm address - sign negate memory at address
|
||||
addr reg1, reg2 - reg1 += reg2
|
||||
@ -293,8 +295,10 @@ enum class Opcode {
|
||||
|
||||
INC,
|
||||
INCM,
|
||||
INCMSPLIT,
|
||||
DEC,
|
||||
DECM,
|
||||
DECMSPLIT,
|
||||
NEG,
|
||||
NEGM,
|
||||
ADDR,
|
||||
@ -571,8 +575,10 @@ val instructionFormats = mutableMapOf(
|
||||
Opcode.SGES to InstructionFormat.from("BW,<>r1,<r2"),
|
||||
Opcode.INC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.INCM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.INCMSPLIT to InstructionFormat.from("W,<i,<>a"),
|
||||
Opcode.DEC to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.DECM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.DECMSPLIT to InstructionFormat.from("W,<i,<>a"),
|
||||
Opcode.NEG to InstructionFormat.from("BW,<>r1 | F,<>fr1"),
|
||||
Opcode.NEGM to InstructionFormat.from("BW,<>a | F,<>a"),
|
||||
Opcode.ADDR to InstructionFormat.from("BW,<>r1,<r2 | F,<>fr1,<fr2"),
|
||||
|
@ -13,11 +13,11 @@
|
||||
</options>
|
||||
<keywords keywords="&;->;@;and;as;asmsub;break;clobbers;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
|
||||
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%import;%ir;%launcher;%option;%output;%zeropage;%zpreserved;iso:;petscii:;sc:" />
|
||||
<keywords3 keywords="@requirezp;@shared;@zp;bool;byte;const;float;str;ubyte;uword;void;word" />
|
||||
<keywords3 keywords="@requirezp;@shared;@split;@zp;bool;byte;const;float;str;ubyte;uword;void;word" />
|
||||
<keywords4 keywords="abs;all;any;callfar;callram;callrom;clamp;cmp;divmod;len;lsb;max;memory;min;mkword;msb;peek;peekw;poke;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;sgn;sizeof;sort;sqrt;sqrt16;swap;|>" />
|
||||
</highlighting>
|
||||
<extensionMap>
|
||||
<mapping ext="p8" />
|
||||
<mapping ext="prog8" />
|
||||
</extensionMap>
|
||||
</filetype>
|
||||
</filetype>
|
||||
|
@ -24,7 +24,7 @@
|
||||
<Keywords name="Folders in comment, open"></Keywords>
|
||||
<Keywords name="Folders in comment, middle"></Keywords>
|
||||
<Keywords name="Folders in comment, close"></Keywords>
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
word uword
float
zp shared requirezp</Keywords>
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
word uword
float
zp shared split requirezp</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%ir
%asmbinary
%asminclude
%breakpoint
%import
%launcher
%option
%output
%zeropage
%zpreserved</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub romsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat unroll
break return goto</Keywords>
|
||||
<Keywords name="Keywords4">abs all any callfar clamp cmp divmod len lsb lsl lsr memory mkword min max msb peek peekw poke pokew push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 sgn sizeof sort sqrtw swap</Keywords>
|
||||
|
@ -43,7 +43,7 @@ syn region prog8ArrayType matchgroup=prog8Type
|
||||
\ start="\<\%(u\?byte\|u\?word\|float\|str\|bool\)\[" end="\]"
|
||||
\ transparent
|
||||
syn keyword prog8StorageClass const
|
||||
syn match prog8StorageClass "\(^\|\s\)\(@zp\|@shared\|@requirezp\)\>"
|
||||
syn match prog8StorageClass "\(^\|\s\)\(@zp\|@shared\|@split\|@requirezp\)\>"
|
||||
|
||||
syn region prog8Block start="{" end="}" transparent
|
||||
syn region prog8Expression start="(" end=")" transparent
|
||||
|
@ -223,8 +223,10 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
Opcode.SGES -> InsSGES(ins)
|
||||
Opcode.INC -> InsINC(ins)
|
||||
Opcode.INCM -> InsINCM(ins)
|
||||
Opcode.INCMSPLIT -> InsINCMSPLIT(ins)
|
||||
Opcode.DEC -> InsDEC(ins)
|
||||
Opcode.DECM -> InsDECM(ins)
|
||||
Opcode.DECMSPLIT -> InsDECMSPLIT(ins)
|
||||
Opcode.NEG -> InsNEG(ins)
|
||||
Opcode.NEGM -> InsNEGM(ins)
|
||||
Opcode.ADDR -> InsADDR(ins)
|
||||
@ -919,6 +921,20 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsINCMSPLIT(i: IRInstruction) {
|
||||
val address = i.address!!
|
||||
var lsb = memory.getUB(address).toInt()
|
||||
var msb = memory.getUB(address+i.immediate!!).toInt()
|
||||
lsb++
|
||||
if(lsb>255) {
|
||||
lsb = 0
|
||||
msb++
|
||||
}
|
||||
memory.setUB(address, lsb.toUByte())
|
||||
memory.setUB(address+i.immediate!!, msb.toUByte())
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsDEC(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, (registers.getUB(i.reg1!!)-1u).toUByte())
|
||||
@ -937,6 +953,21 @@ class VirtualMachine(irProgram: IRProgram) {
|
||||
nextPc()
|
||||
}
|
||||
|
||||
private fun InsDECMSPLIT(i: IRInstruction) {
|
||||
val address = i.address!!
|
||||
var lsb = memory.getUB(address).toInt()
|
||||
var msb = memory.getUB(address+i.immediate!!).toInt()
|
||||
lsb--
|
||||
if(lsb<0) {
|
||||
lsb = 255
|
||||
msb--
|
||||
}
|
||||
memory.setUB(address, lsb.toUByte())
|
||||
memory.setUB(address+i.immediate!!, msb.toUByte())
|
||||
nextPc()
|
||||
|
||||
}
|
||||
|
||||
private fun InsNEG(i: IRInstruction) {
|
||||
when(i.type!!) {
|
||||
IRDataType.BYTE -> registers.setUB(i.reg1!!, (-registers.getUB(i.reg1!!).toInt()).toUByte())
|
||||
|
Loading…
x
Reference in New Issue
Block a user