more split array stuff for 6502

This commit is contained in:
Irmen de Jong 2023-05-27 14:43:09 +02:00
parent c94e292176
commit 3ac9036c79
16 changed files with 250 additions and 81 deletions

View File

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

View File

@ -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")

View File

@ -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

View File

@ -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")

View File

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

View File

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

View File

@ -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 -> {

View File

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

View File

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

View File

@ -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")

View File

@ -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()

View File

@ -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"),

View File

@ -13,11 +13,11 @@
</options>
<keywords keywords="&amp;;-&gt;;@;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;|&gt;" />
</highlighting>
<extensionMap>
<mapping ext="p8" />
<mapping ext="prog8" />
</extensionMap>
</filetype>
</filetype>

View File

@ -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&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared requirezp</Keywords>
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared split requirezp</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%import&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved</Keywords>
<Keywords name="Keywords3">inline sub asmsub romsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;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>

View File

@ -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

View File

@ -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())