mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
direct memory access and sprite fixes
This commit is contained in:
parent
c07bd8a4a8
commit
a319e6f9ec
@ -126,9 +126,8 @@ assign_target:
|
||||
postincrdecr : assign_target operator = ('++' | '--') ;
|
||||
|
||||
expression :
|
||||
'(' expression ')'
|
||||
| functioncall
|
||||
| prefix = ('+'|'-'|'~') expression
|
||||
functioncall
|
||||
| <assoc=right> prefix = ('+'|'-'|'~') expression
|
||||
| left = expression bop = '**' right = expression
|
||||
| left = expression bop = ('*' | '/' | '//' | '%' ) right = expression
|
||||
| left = expression bop = ('+' | '-' ) right = expression
|
||||
@ -149,6 +148,7 @@ expression :
|
||||
| arrayindexed
|
||||
| directmemory
|
||||
| expression typecast
|
||||
| '(' expression ')'
|
||||
;
|
||||
|
||||
|
||||
@ -159,7 +159,7 @@ arrayindexed :
|
||||
(identifier | scoped_identifier ) arrayspec
|
||||
;
|
||||
|
||||
directmemory : '@' expression ;
|
||||
directmemory : '@' '(' expression ')';
|
||||
|
||||
|
||||
functioncall :
|
||||
|
@ -3,27 +3,30 @@
|
||||
|
||||
~ main {
|
||||
|
||||
ubyte[63] balloonsprite = [ %00000000, %01111111, %00000000,
|
||||
%00000001, %11111111, %11000000,
|
||||
%00000011, %11111111, %11100000,
|
||||
%00000011, %11100011, %11100000,
|
||||
%00000111, %11011100, %11110000,
|
||||
%00000111, %11011101, %11110000,
|
||||
%00000111, %11011100, %11110000,
|
||||
%00000011, %11100011, %11100000,
|
||||
%00000011, %11111111, %11100000,
|
||||
%00000011, %11111111, %11100000,
|
||||
%00000010, %11111111, %10100000,
|
||||
%00000001, %01111111, %01000000,
|
||||
%00000001, %00111110, %01000000,
|
||||
%00000000, %10011100, %10000000,
|
||||
%00000000, %10011100, %10000000,
|
||||
%00000000, %01001001, %00000000,
|
||||
%00000000, %01001001, %00000000,
|
||||
%00000000, %00111110, %00000000,
|
||||
%00000000, %00111110, %00000000,
|
||||
%00000000, %00111110, %00000000,
|
||||
%00000000, %00011100, %00000000 ]
|
||||
const uword SP0X = $d000
|
||||
const uword SP0Y = $d001
|
||||
|
||||
ubyte[63] balloonsprite = [ %00000000,%01111111,%00000000,
|
||||
%00000001,%11111111,%11000000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000011,%11100011,%11100000,
|
||||
%00000111,%11011100,%11110000,
|
||||
%00000111,%11011101,%11110000,
|
||||
%00000111,%11011100,%11110000,
|
||||
%00000011,%11100011,%11100000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000011,%11111111,%11100000,
|
||||
%00000010,%11111111,%10100000,
|
||||
%00000001,%01111111,%01000000,
|
||||
%00000001,%00111110,%01000000,
|
||||
%00000000,%10011100,%10000000,
|
||||
%00000000,%10011100,%10000000,
|
||||
%00000000,%01001001,%00000000,
|
||||
%00000000,%01001001,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00111110,%00000000,
|
||||
%00000000,%00011100,%00000000 ]
|
||||
|
||||
const uword sprite_data_address = 13*64 ; // safe area inside the tape buffer
|
||||
|
||||
@ -34,7 +37,7 @@
|
||||
|
||||
; copy the ballon sprite data to the correct address and setup the sprite pointers
|
||||
; @todo make a memcopy function for this, that calls c64utils.memcopy
|
||||
for ubyte i in 0 to 62 {
|
||||
for ubyte i in 0 to 63 {
|
||||
;@(sprite_data_address+i) = @(balloonsprite+i) ; @todo nice error message
|
||||
@(sprite_data_address+i) = balloonsprite[i]
|
||||
}
|
||||
@ -48,23 +51,10 @@
|
||||
c64.SPRPTR6 = sprite_data_address//64
|
||||
c64.SPRPTR7 = sprite_data_address//64
|
||||
|
||||
c64.SP0X = 30+30*0
|
||||
c64.SP1X = 30+30*1
|
||||
c64.SP2X = 30+30*2
|
||||
c64.SP3X = 30+30*3
|
||||
c64.SP4X = 30+30*4
|
||||
c64.SP5X = 30+30*5
|
||||
c64.SP6X = 30+30*6
|
||||
c64.SP7X = 30+30*7
|
||||
|
||||
c64.SP0Y = 100+10*0
|
||||
c64.SP1Y = 100+10*1
|
||||
c64.SP2Y = 100+10*2
|
||||
c64.SP3Y = 100+10*3
|
||||
c64.SP4Y = 100+10*4
|
||||
c64.SP5Y = 100+10*5
|
||||
c64.SP6Y = 100+10*6
|
||||
c64.SP7Y = 100+10*7
|
||||
for ubyte i in 0 to 7 {
|
||||
@(SP0X+i*2) = 50+25*i
|
||||
@(SP0Y+i*2) = rnd()
|
||||
}
|
||||
|
||||
c64.SPENA = 255 ; enable all sprites
|
||||
}
|
||||
@ -72,30 +62,25 @@
|
||||
|
||||
|
||||
~ irq {
|
||||
|
||||
; @todo no longer auto-set this as irq handler. instead, add builtins functions activate_irqvec() / restore_irqvec()
|
||||
sub irq() {
|
||||
c64.SP0Y--
|
||||
c64.SP1Y--
|
||||
c64.SP2Y--
|
||||
c64.SP3Y--
|
||||
c64.SP4Y--
|
||||
c64.SP5Y--
|
||||
c64.SP6Y--
|
||||
c64.SP7Y--
|
||||
;return ; @todo return statements in the irqhandler should not do rts, but instead jmp c64.IRQDFRT
|
||||
; @todo also when including this return, the jmp c64.IRQDFRT at the end gets omitted.....:(
|
||||
c64.EXTCOL++
|
||||
for ubyte i in 0 to 7 {
|
||||
@(main.SP0Y+i+i)-- ; float up
|
||||
|
||||
|
||||
; const uword SP0X = $d000
|
||||
; for ubyte i in 0 to 7 {
|
||||
; @(SP0X+i*2) = @(SP0X+i*2) + 1 ; @todo this doesn't read (or write?) the correct values..
|
||||
; ubyte r = rnd()
|
||||
; if r>228
|
||||
; ; @(SP0X+i*2)++ ; @todo allow this
|
||||
; @(SP0X+i*2) = @(SP0X+i*2)+1
|
||||
; else {
|
||||
; if r<28
|
||||
; @(SP0X+i*2) = @(SP0X+i*2)-1
|
||||
; }
|
||||
; }
|
||||
; horizontal wobble effect
|
||||
ubyte r = rnd()
|
||||
if r>208
|
||||
@(main.SP0X+i+i)++
|
||||
else {
|
||||
; @todo if-else if -else syntax without curly braces
|
||||
if r<48
|
||||
@(main.SP0X+i+i)--
|
||||
}
|
||||
}
|
||||
c64.EXTCOL--
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,23 +3,15 @@
|
||||
~ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
A+=5
|
||||
|
||||
; @todo if-else if should compile ?:
|
||||
; if A>100
|
||||
; Y=2
|
||||
; else if A>20
|
||||
; Y=3
|
||||
|
||||
|
||||
; @($d020) = 5
|
||||
@($d020)++
|
||||
@($d021)--
|
||||
; @($d020)=(@$d020)+5
|
||||
@($d020)+=5
|
||||
; @($d021)=(@$d021)-5
|
||||
@($d021)-=5
|
||||
|
||||
ubyte i=0
|
||||
A= @($d020)
|
||||
A= @($d020+i)
|
||||
@($d020) = 0
|
||||
@($d020+i) = 0
|
||||
@($d020+i) = 1
|
||||
@($d020+i) = 2
|
||||
@($d020) = @($d020+i) + 1
|
||||
@($d020+i) = @($d020+i) + 1
|
||||
c64scr.print_ub(X)
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ interface IAstProcessor {
|
||||
fun process(assignTarget: AssignTarget): AssignTarget {
|
||||
assignTarget.arrayindexed?.process(this)
|
||||
assignTarget.identifier?.process(this)
|
||||
assignTarget.memAddressExpression = assignTarget.memAddressExpression?.process(this)
|
||||
assignTarget.memoryAddress?.process(this)
|
||||
return assignTarget
|
||||
}
|
||||
|
||||
@ -275,9 +275,14 @@ interface IAstProcessor {
|
||||
return typecastExpression
|
||||
}
|
||||
|
||||
fun process(directmemoryExpression: DirectMemoryExpression): IExpression {
|
||||
directmemoryExpression.addressExpression = directmemoryExpression.addressExpression.process(this)
|
||||
return directmemoryExpression
|
||||
fun process(memread: DirectMemoryRead): IExpression {
|
||||
memread.addressExpression = memread.addressExpression.process(this)
|
||||
return memread
|
||||
}
|
||||
|
||||
fun process(memwrite: DirectMemoryWrite): IExpression {
|
||||
memwrite.addressExpression = memwrite.addressExpression.process(this)
|
||||
return memwrite
|
||||
}
|
||||
}
|
||||
|
||||
@ -731,7 +736,7 @@ class VariableInitializationAssignment(target: AssignTarget, aug_op: String?, va
|
||||
data class AssignTarget(val register: Register?,
|
||||
val identifier: IdentifierReference?,
|
||||
val arrayindexed: ArrayIndexedExpression?,
|
||||
var memAddressExpression: IExpression?,
|
||||
var memoryAddress: DirectMemoryWrite?,
|
||||
override val position: Position) : Node {
|
||||
override lateinit var parent: Node
|
||||
|
||||
@ -739,7 +744,7 @@ data class AssignTarget(val register: Register?,
|
||||
this.parent = parent
|
||||
identifier?.linkParents(this)
|
||||
arrayindexed?.linkParents(this)
|
||||
memAddressExpression?.linkParents(this)
|
||||
memoryAddress?.linkParents(this)
|
||||
}
|
||||
|
||||
fun process(processor: IAstProcessor) = processor.process(this)
|
||||
@ -750,7 +755,8 @@ data class AssignTarget(val register: Register?,
|
||||
is RegisterExpr -> AssignTarget(expr.register, null, null, null, expr.position)
|
||||
is IdentifierReference -> AssignTarget(null, expr, null, null, expr.position)
|
||||
is ArrayIndexedExpression -> AssignTarget(null, null, expr, null, expr.position)
|
||||
is DirectMemoryExpression -> AssignTarget(null, null, null, expr, expr.position)
|
||||
is DirectMemoryRead -> AssignTarget(null, null, null, DirectMemoryWrite(expr.addressExpression, expr.position), expr.position)
|
||||
is DirectMemoryWrite -> AssignTarget(null, null, null, expr, expr.position)
|
||||
else -> throw FatalAstException("invalid expression object $expr")
|
||||
}
|
||||
}
|
||||
@ -771,7 +777,7 @@ data class AssignTarget(val register: Register?,
|
||||
return dt
|
||||
}
|
||||
|
||||
if(memAddressExpression!=null)
|
||||
if(memoryAddress!=null)
|
||||
return DataType.UBYTE
|
||||
|
||||
return null
|
||||
@ -784,8 +790,9 @@ data class AssignTarget(val register: Register?,
|
||||
return identifier.nameInSource.last()
|
||||
if(arrayindexed!=null)
|
||||
return arrayindexed.identifier!!.nameInSource.last()
|
||||
if(memAddressExpression is LiteralValue)
|
||||
return (memAddressExpression as LiteralValue).asIntegerValue.toString()
|
||||
val address = memoryAddress?.addressExpression
|
||||
if(address is LiteralValue)
|
||||
return address.asIntegerValue.toString()
|
||||
return "???"
|
||||
}
|
||||
}
|
||||
@ -1027,7 +1034,7 @@ class TypecastExpression(var expression: IExpression, var type: DataType, overri
|
||||
}
|
||||
|
||||
|
||||
class DirectMemoryExpression(var addressExpression: IExpression, override val position: Position) : IExpression {
|
||||
class DirectMemoryRead(var addressExpression: IExpression, override val position: Position) : IExpression {
|
||||
override lateinit var parent: Node
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
@ -1042,7 +1049,27 @@ class DirectMemoryExpression(var addressExpression: IExpression, override val po
|
||||
override fun constValue(namespace: INameScope, heap: HeapValues) = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "DirectMemory($addressExpression)"
|
||||
return "DirectMemoryRead($addressExpression)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DirectMemoryWrite(var addressExpression: IExpression, override val position: Position) : IExpression {
|
||||
override lateinit var parent: Node
|
||||
|
||||
override fun linkParents(parent: Node) {
|
||||
this.parent = parent
|
||||
this.addressExpression.linkParents(this)
|
||||
}
|
||||
|
||||
override fun process(processor: IAstProcessor) = processor.process(this)
|
||||
override fun referencesIdentifier(name: String) = false
|
||||
override fun resultingDatatype(namespace: INameScope, heap: HeapValues): DataType? = DataType.UBYTE
|
||||
override fun isIterable(namespace: INameScope, heap: HeapValues) = false
|
||||
override fun constValue(namespace: INameScope, heap: HeapValues) = null
|
||||
|
||||
override fun toString(): String {
|
||||
return "DirectMemoryWrite($addressExpression)"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1978,7 +2005,7 @@ private fun prog8Parser.Assign_targetContext.toAst() : AssignTarget {
|
||||
register!=null -> AssignTarget(register, null, null, null, toPosition())
|
||||
identifier!=null -> AssignTarget(null, identifier.toAst(), null, null, toPosition())
|
||||
arrayindexed()!=null -> AssignTarget(null, null, arrayindexed().toAst(), null, toPosition())
|
||||
directmemory()!=null -> AssignTarget(null, null, null, directmemory().expression().toAst(), toPosition())
|
||||
directmemory()!=null -> AssignTarget(null, null, null, DirectMemoryWrite(directmemory().expression().toAst(), toPosition()), toPosition())
|
||||
else -> AssignTarget(null, scoped_identifier()?.toAst(), null, null, toPosition())
|
||||
}
|
||||
}
|
||||
@ -2108,7 +2135,7 @@ private fun prog8Parser.ExpressionContext.toAst() : IExpression {
|
||||
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), toPosition())
|
||||
|
||||
if(directmemory()!=null)
|
||||
return DirectMemoryExpression(directmemory().expression().toAst(), toPosition())
|
||||
return DirectMemoryRead(directmemory().expression().toAst(), toPosition())
|
||||
|
||||
throw FatalAstException(text)
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
}
|
||||
|
||||
private fun processAssignmentTarget(assignment: Assignment, target: AssignTarget): Assignment {
|
||||
val memAddr = target.memAddressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||
val memAddr = target.memoryAddress?.addressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||
if(memAddr!=null) {
|
||||
if(memAddr<0 || memAddr>=65536)
|
||||
checkResult.add(ExpressionError("address out of range", target.position))
|
||||
@ -435,16 +435,16 @@ class AstChecker(private val namespace: INameScope,
|
||||
target.register != null -> RegisterExpr(target.register, target.position)
|
||||
target.identifier != null -> target.identifier
|
||||
target.arrayindexed != null -> target.arrayindexed
|
||||
target.memAddressExpression != null -> {
|
||||
// @addr += 4 --> @addr = @addr +4
|
||||
// TODO: make it so that it follows the others
|
||||
val memRead = DirectMemoryExpression(target.memAddressExpression!!, target.position)
|
||||
val expression = BinaryExpression(memRead, assignment.aug_op.substringBeforeLast('='), assignment.value, assignment.position)
|
||||
expression.linkParents(assignment.parent)
|
||||
val assignment2 = Assignment(listOf(target), null, expression, assignment.position)
|
||||
assignment2.linkParents(assignment.parent)
|
||||
return assignment2
|
||||
}
|
||||
target.memoryAddress != null -> target.memoryAddress!!
|
||||
// // @addr += 4 --> @addr = @addr +4
|
||||
// // TODO: make it so that it follows the others
|
||||
// val memRead = DirectMemoryRead(target.memoryAddress!!, target.position)
|
||||
// val expression = BinaryExpression(memRead, assignment.aug_op.substringBeforeLast('='), assignment.value, assignment.position)
|
||||
// expression.linkParents(assignment.parent)
|
||||
// val assignment2 = Assignment(listOf(target), null, expression, assignment.position)
|
||||
// assignment2.linkParents(assignment.parent)
|
||||
// return assignment2
|
||||
// }
|
||||
else -> throw FatalAstException("strange assignment")
|
||||
}
|
||||
|
||||
@ -827,7 +827,7 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(dt !in NumericDatatypes && dt !in ArrayDatatypes)
|
||||
checkResult.add(SyntaxError("can only increment or decrement a byte/float/word", postIncrDecr.position))
|
||||
}
|
||||
} else if(postIncrDecr.target.memAddressExpression != null) {
|
||||
} else if(postIncrDecr.target.memoryAddress != null) {
|
||||
// a memory location can always be ++/--
|
||||
}
|
||||
return super.process(postIncrDecr)
|
||||
|
@ -580,7 +580,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
is ArrayIndexedExpression -> translate(expr, false)
|
||||
is RangeExpr -> throw CompilerException("it's not possible to just have a range expression that has to be translated")
|
||||
is TypecastExpression -> translate(expr)
|
||||
is DirectMemoryExpression -> translate(expr)
|
||||
is DirectMemoryRead -> translate(expr)
|
||||
is DirectMemoryWrite -> translate(expr)
|
||||
else -> {
|
||||
val lv = expr.constValue(namespace, heap) ?: throw CompilerException("constant expression required, not $expr")
|
||||
when(lv.type) {
|
||||
@ -1273,15 +1274,19 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
"--" -> prog.instr(opcodeDecArrayindexedVar(variable.datatype), callLabel = variable.scopedname)
|
||||
}
|
||||
}
|
||||
stmt.target.memAddressExpression != null -> {
|
||||
val address = stmt.target.memAddressExpression!!.constValue(namespace, heap)?.asIntegerValue
|
||||
stmt.target.memoryAddress != null -> {
|
||||
val address = stmt.target.memoryAddress?.addressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||
if(address!=null) {
|
||||
when(stmt.operator) {
|
||||
"++" -> prog.instr(Opcode.INC_MEMORY, Value(DataType.UWORD, address))
|
||||
"--" -> prog.instr(Opcode.DEC_MEMORY, Value(DataType.UWORD, address))
|
||||
}
|
||||
} else {
|
||||
TODO("memory ++/-- ${stmt.target.memAddressExpression}")
|
||||
translate(stmt.target.memoryAddress!!.addressExpression)
|
||||
when(stmt.operator) {
|
||||
"++" -> prog.instr(Opcode.POP_INC_MEMORY)
|
||||
"--" -> prog.instr(Opcode.POP_DEC_MEMORY)
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw CompilerException("very strange postincrdecr ${stmt.target}")
|
||||
@ -1368,7 +1373,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
assignTarget.register != null -> prog.instr(Opcode.PUSH_VAR_BYTE, callLabel = assignTarget.register.toString())
|
||||
assignTarget.arrayindexed != null -> translate(assignTarget.arrayindexed, false)
|
||||
assignTarget.memAddressExpression != null -> {
|
||||
assignTarget.memoryAddress != null -> {
|
||||
TODO("translate aug assign on memory address $stmt")
|
||||
}
|
||||
}
|
||||
@ -1496,14 +1501,13 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
assignTarget.register != null -> prog.instr(Opcode.POP_VAR_BYTE, callLabel = assignTarget.register.toString())
|
||||
assignTarget.arrayindexed != null -> translate(assignTarget.arrayindexed, true) // write value to it
|
||||
assignTarget.memAddressExpression != null -> {
|
||||
val address = assignTarget.memAddressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||
assignTarget.memoryAddress != null -> {
|
||||
val address = assignTarget.memoryAddress?.addressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||
if(address!=null) {
|
||||
// const integer address given
|
||||
prog.instr(Opcode.POP_MEM_BYTE, arg=Value(DataType.UWORD, address))
|
||||
} else {
|
||||
translate(assignTarget.memAddressExpression!!)
|
||||
prog.instr(Opcode.POP_MEMWRITE)
|
||||
translate(assignTarget.memoryAddress!!)
|
||||
}
|
||||
}
|
||||
else -> throw CompilerException("corrupt assigntarget $assignTarget")
|
||||
@ -2097,15 +2101,26 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
||||
}
|
||||
}
|
||||
|
||||
private fun translate(expr: DirectMemoryExpression) {
|
||||
private fun translate(memread: DirectMemoryRead) {
|
||||
// for now, only a single memory location (ubyte) is read at a time.
|
||||
val address = expr.addressExpression.constValue(namespace, heap)?.asIntegerValue
|
||||
val address = memread.addressExpression.constValue(namespace, heap)?.asIntegerValue
|
||||
if(address!=null) {
|
||||
prog.instr(Opcode.PUSH_MEM_UB, arg = Value(DataType.UWORD, address))
|
||||
} else {
|
||||
translate(expr.addressExpression)
|
||||
translate(memread.addressExpression)
|
||||
prog.instr(Opcode.PUSH_MEMREAD)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translate(memwrite: DirectMemoryWrite) {
|
||||
// for now, only a single memory location (ubyte) is written at a time.
|
||||
val address = memwrite.addressExpression.constValue(namespace, heap)?.asIntegerValue
|
||||
if(address!=null) {
|
||||
prog.instr(Opcode.POP_MEM_BYTE, arg = Value(DataType.UWORD, address))
|
||||
} else {
|
||||
translate(memwrite.addressExpression)
|
||||
prog.instr(Opcode.POP_MEMWRITE)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -164,8 +164,10 @@ enum class Opcode {
|
||||
DEC_VAR_W,
|
||||
DEC_VAR_UW,
|
||||
DEC_VAR_F,
|
||||
INC_MEMORY,
|
||||
DEC_MEMORY,
|
||||
INC_MEMORY, // increment direct address
|
||||
DEC_MEMORY, // decrement direct address
|
||||
POP_INC_MEMORY, // increment address from stack
|
||||
POP_DEC_MEMORY, // decrement address from address
|
||||
|
||||
// comparisons
|
||||
// @todo the comparisons push the result back on the stack. Optimize this to work with just processor flags? This does mean you can no longer use a logical boolean result as a byte 0/1 value ?
|
||||
|
@ -496,11 +496,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
Opcode.PUSH_MEMREAD -> {
|
||||
"""
|
||||
lda ${(ESTACK_LO+1).toHex()},x
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
sta (+) +1
|
||||
lda ${(ESTACK_HI+1).toHex()},x
|
||||
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||
ldy #0
|
||||
lda (${C64Zeropage.SCRATCH_W1}),y
|
||||
sta (+) +2
|
||||
+ lda 65535 ; modified
|
||||
sta ${(ESTACK_LO+1).toHex()},x
|
||||
"""
|
||||
}
|
||||
@ -594,13 +593,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
"""
|
||||
inx
|
||||
lda ${ESTACK_LO.toHex()},x
|
||||
sta ${C64Zeropage.SCRATCH_W1}
|
||||
sta (+) +1
|
||||
lda ${ESTACK_HI.toHex()},x
|
||||
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||
sta (+) +2
|
||||
inx
|
||||
lda ${ESTACK_LO.toHex()},x
|
||||
ldy #0
|
||||
sta (${C64Zeropage.SCRATCH_W1}),y
|
||||
+ sta 65535 ; modified
|
||||
"""
|
||||
}
|
||||
|
||||
@ -637,6 +635,26 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
||||
jsr prog8_lib.inc_var_f
|
||||
"""
|
||||
}
|
||||
Opcode.POP_INC_MEMORY -> {
|
||||
"""
|
||||
inx
|
||||
lda ${ESTACK_LO.toHex()},x
|
||||
sta (+) +1
|
||||
lda ${ESTACK_HI.toHex()},x
|
||||
sta (+) +2
|
||||
+ inc 65535 ; modified
|
||||
"""
|
||||
}
|
||||
Opcode.POP_DEC_MEMORY -> {
|
||||
"""
|
||||
inx
|
||||
lda ${ESTACK_LO.toHex()},x
|
||||
sta (+) +1
|
||||
lda ${ESTACK_HI.toHex()},x
|
||||
sta (+) +2
|
||||
+ dec 65535 ; modified
|
||||
"""
|
||||
}
|
||||
Opcode.DEC_VAR_UB, Opcode.DEC_VAR_B -> {
|
||||
when (ins.callLabel) {
|
||||
"A" -> " sec | sbc #1"
|
||||
|
@ -72,11 +72,11 @@ public class prog8Lexer extends Lexer {
|
||||
"'%asmbinary'", "'%option'", "','", "'='", "'const'", "'memory'", "'ubyte'",
|
||||
"'byte'", "'uword'", "'word'", "'float'", "'str'", "'str_p'", "'str_s'",
|
||||
"'str_ps'", "'['", "']'", "'+='", "'-='", "'/='", "'//='", "'*='", "'**='",
|
||||
"'&='", "'|='", "'^='", "'%='", "'++'", "'--'", "'('", "')'", "'+'",
|
||||
"'-'", "'**'", "'*'", "'/'", "'//'", "'%'", "'<'", "'>'", "'<='", "'>='",
|
||||
"'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'step'", "'and'", "'or'",
|
||||
"'xor'", "'not'", "'as'", "'@'", "'return'", "'break'", "'continue'",
|
||||
"'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'",
|
||||
"'&='", "'|='", "'^='", "'%='", "'++'", "'--'", "'+'", "'-'", "'**'",
|
||||
"'*'", "'/'", "'//'", "'%'", "'<'", "'>'", "'<='", "'>='", "'=='", "'!='",
|
||||
"'&'", "'^'", "'|'", "'to'", "'step'", "'and'", "'or'", "'xor'", "'not'",
|
||||
"'('", "')'", "'as'", "'@'", "'return'", "'break'", "'continue'", "'.'",
|
||||
"'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'",
|
||||
"'Pv'", "'.w'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'{'",
|
||||
"'}'", "'asmsub'", "'clobbers'", "'if'", "'else'", "'if_cs'", "'if_cc'",
|
||||
"'if_eq'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'",
|
||||
@ -235,19 +235,19 @@ public class prog8Lexer extends Lexer {
|
||||
"\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34"+
|
||||
"\3\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3 \3 \3 \3!\3!\3!\3!\3\"\3\""+
|
||||
"\3\"\3#\3#\3#\3#\3$\3$\3$\3%\3%\3%\3&\3&\3&\3\'\3\'\3\'\3(\3(\3(\3)\3"+
|
||||
")\3)\3*\3*\3+\3+\3,\3,\3-\3-\3.\3.\3.\3/\3/\3\60\3\60\3\61\3\61\3\61\3"+
|
||||
"\62\3\62\3\63\3\63\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\3"+
|
||||
"\67\38\38\38\39\39\3:\3:\3;\3;\3<\3<\3<\3=\3=\3=\3=\3=\3>\3>\3>\3>\3?"+
|
||||
"\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E"+
|
||||
"\3E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3H\3H\3I\3I\3J\3J\3K"+
|
||||
"\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R\3R"+
|
||||
"\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W"+
|
||||
"\3X\3X\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3"+
|
||||
"\\\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3"+
|
||||
"`\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3d\3"+
|
||||
"d\3e\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3h\3h\3"+
|
||||
"h\3h\3h\3h\3i\3i\3i\3i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3l\3l\3l\3l\3l\3l\3"+
|
||||
"m\3m\3m\3m\3m\3m\3m\3n\3n\3n\3n\3n\3n\3o\3o\7o\u02e9\no\fo\16o\u02ec\13"+
|
||||
")\3)\3*\3*\3+\3+\3,\3,\3,\3-\3-\3.\3.\3/\3/\3/\3\60\3\60\3\61\3\61\3\62"+
|
||||
"\3\62\3\63\3\63\3\63\3\64\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67"+
|
||||
"\3\67\38\38\39\39\3:\3:\3:\3;\3;\3;\3;\3;\3<\3<\3<\3<\3=\3=\3=\3>\3>\3"+
|
||||
">\3>\3?\3?\3?\3?\3@\3@\3A\3A\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E\3"+
|
||||
"E\3E\3E\3E\3E\3F\3F\3F\3F\3F\3F\3F\3F\3F\3G\3G\3H\3H\3I\3I\3J\3J\3K\3"+
|
||||
"K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R\3R\3"+
|
||||
"S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3T\3U\3U\3U\3U\3U\3V\3V\3V\3V\3W\3W\3W\3"+
|
||||
"X\3X\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3[\3[\3[\3[\3[\3[\3[\3\\\3\\\3\\"+
|
||||
"\3]\3]\3]\3]\3]\3^\3^\3^\3^\3^\3^\3_\3_\3_\3_\3_\3_\3`\3`\3`\3`\3`\3`"+
|
||||
"\3a\3a\3a\3a\3a\3b\3b\3b\3b\3b\3b\3c\3c\3c\3c\3c\3c\3d\3d\3d\3d\3d\3d"+
|
||||
"\3e\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3h\3h\3h"+
|
||||
"\3h\3h\3h\3i\3i\3i\3i\3i\3i\3j\3j\3j\3j\3k\3k\3k\3l\3l\3l\3l\3l\3l\3m"+
|
||||
"\3m\3m\3m\3m\3m\3m\3n\3n\3n\3n\3n\3n\3o\3o\7o\u02e9\no\fo\16o\u02ec\13"+
|
||||
"o\3o\3o\3o\3o\3p\3p\7p\u02f4\np\fp\16p\u02f7\13p\3p\3p\3q\3q\3q\3q\3r"+
|
||||
"\6r\u0300\nr\rr\16r\u0301\3s\3s\7s\u0306\ns\fs\16s\u0309\13s\3t\3t\3t"+
|
||||
"\6t\u030e\nt\rt\16t\u030f\5t\u0312\nt\3u\3u\6u\u0316\nu\ru\16u\u0317\3"+
|
||||
@ -299,11 +299,11 @@ public class prog8Lexer extends Lexer {
|
||||
"\3\2\2\2=\u01b1\3\2\2\2?\u01b4\3\2\2\2A\u01b7\3\2\2\2C\u01bb\3\2\2\2E"+
|
||||
"\u01be\3\2\2\2G\u01c2\3\2\2\2I\u01c5\3\2\2\2K\u01c8\3\2\2\2M\u01cb\3\2"+
|
||||
"\2\2O\u01ce\3\2\2\2Q\u01d1\3\2\2\2S\u01d4\3\2\2\2U\u01d6\3\2\2\2W\u01d8"+
|
||||
"\3\2\2\2Y\u01da\3\2\2\2[\u01dc\3\2\2\2]\u01df\3\2\2\2_\u01e1\3\2\2\2a"+
|
||||
"\u01e3\3\2\2\2c\u01e6\3\2\2\2e\u01e8\3\2\2\2g\u01ea\3\2\2\2i\u01ec\3\2"+
|
||||
"\2\2k\u01ef\3\2\2\2m\u01f2\3\2\2\2o\u01f5\3\2\2\2q\u01f8\3\2\2\2s\u01fa"+
|
||||
"\3\2\2\2u\u01fc\3\2\2\2w\u01fe\3\2\2\2y\u0201\3\2\2\2{\u0206\3\2\2\2}"+
|
||||
"\u020a\3\2\2\2\177\u020d\3\2\2\2\u0081\u0211\3\2\2\2\u0083\u0215\3\2\2"+
|
||||
"\3\2\2\2Y\u01db\3\2\2\2[\u01dd\3\2\2\2]\u01df\3\2\2\2_\u01e2\3\2\2\2a"+
|
||||
"\u01e4\3\2\2\2c\u01e6\3\2\2\2e\u01e8\3\2\2\2g\u01eb\3\2\2\2i\u01ee\3\2"+
|
||||
"\2\2k\u01f1\3\2\2\2m\u01f4\3\2\2\2o\u01f6\3\2\2\2q\u01f8\3\2\2\2s\u01fa"+
|
||||
"\3\2\2\2u\u01fd\3\2\2\2w\u0202\3\2\2\2y\u0206\3\2\2\2{\u0209\3\2\2\2}"+
|
||||
"\u020d\3\2\2\2\177\u0211\3\2\2\2\u0081\u0213\3\2\2\2\u0083\u0215\3\2\2"+
|
||||
"\2\u0085\u0218\3\2\2\2\u0087\u021a\3\2\2\2\u0089\u0221\3\2\2\2\u008b\u0227"+
|
||||
"\3\2\2\2\u008d\u0230\3\2\2\2\u008f\u0232\3\2\2\2\u0091\u0234\3\2\2\2\u0093"+
|
||||
"\u0236\3\2\2\2\u0095\u0238\3\2\2\2\u0097\u023b\3\2\2\2\u0099\u023e\3\2"+
|
||||
@ -377,82 +377,82 @@ public class prog8Lexer extends Lexer {
|
||||
"\7~\2\2\u01c6\u01c7\7?\2\2\u01c7J\3\2\2\2\u01c8\u01c9\7`\2\2\u01c9\u01ca"+
|
||||
"\7?\2\2\u01caL\3\2\2\2\u01cb\u01cc\7\'\2\2\u01cc\u01cd\7?\2\2\u01cdN\3"+
|
||||
"\2\2\2\u01ce\u01cf\7-\2\2\u01cf\u01d0\7-\2\2\u01d0P\3\2\2\2\u01d1\u01d2"+
|
||||
"\7/\2\2\u01d2\u01d3\7/\2\2\u01d3R\3\2\2\2\u01d4\u01d5\7*\2\2\u01d5T\3"+
|
||||
"\2\2\2\u01d6\u01d7\7+\2\2\u01d7V\3\2\2\2\u01d8\u01d9\7-\2\2\u01d9X\3\2"+
|
||||
"\2\2\u01da\u01db\7/\2\2\u01dbZ\3\2\2\2\u01dc\u01dd\7,\2\2\u01dd\u01de"+
|
||||
"\7,\2\2\u01de\\\3\2\2\2\u01df\u01e0\7,\2\2\u01e0^\3\2\2\2\u01e1\u01e2"+
|
||||
"\7\61\2\2\u01e2`\3\2\2\2\u01e3\u01e4\7\61\2\2\u01e4\u01e5\7\61\2\2\u01e5"+
|
||||
"b\3\2\2\2\u01e6\u01e7\7\'\2\2\u01e7d\3\2\2\2\u01e8\u01e9\7>\2\2\u01e9"+
|
||||
"f\3\2\2\2\u01ea\u01eb\7@\2\2\u01ebh\3\2\2\2\u01ec\u01ed\7>\2\2\u01ed\u01ee"+
|
||||
"\7?\2\2\u01eej\3\2\2\2\u01ef\u01f0\7@\2\2\u01f0\u01f1\7?\2\2\u01f1l\3"+
|
||||
"\2\2\2\u01f2\u01f3\7?\2\2\u01f3\u01f4\7?\2\2\u01f4n\3\2\2\2\u01f5\u01f6"+
|
||||
"\7#\2\2\u01f6\u01f7\7?\2\2\u01f7p\3\2\2\2\u01f8\u01f9\7(\2\2\u01f9r\3"+
|
||||
"\2\2\2\u01fa\u01fb\7`\2\2\u01fbt\3\2\2\2\u01fc\u01fd\7~\2\2\u01fdv\3\2"+
|
||||
"\2\2\u01fe\u01ff\7v\2\2\u01ff\u0200\7q\2\2\u0200x\3\2\2\2\u0201\u0202"+
|
||||
"\7u\2\2\u0202\u0203\7v\2\2\u0203\u0204\7g\2\2\u0204\u0205\7r\2\2\u0205"+
|
||||
"z\3\2\2\2\u0206\u0207\7c\2\2\u0207\u0208\7p\2\2\u0208\u0209\7f\2\2\u0209"+
|
||||
"|\3\2\2\2\u020a\u020b\7q\2\2\u020b\u020c\7t\2\2\u020c~\3\2\2\2\u020d\u020e"+
|
||||
"\7z\2\2\u020e\u020f\7q\2\2\u020f\u0210\7t\2\2\u0210\u0080\3\2\2\2\u0211"+
|
||||
"\u0212\7p\2\2\u0212\u0213\7q\2\2\u0213\u0214\7v\2\2\u0214\u0082\3\2\2"+
|
||||
"\2\u0215\u0216\7c\2\2\u0216\u0217\7u\2\2\u0217\u0084\3\2\2\2\u0218\u0219"+
|
||||
"\7B\2\2\u0219\u0086\3\2\2\2\u021a\u021b\7t\2\2\u021b\u021c\7g\2\2\u021c"+
|
||||
"\u021d\7v\2\2\u021d\u021e\7w\2\2\u021e\u021f\7t\2\2\u021f\u0220\7p\2\2"+
|
||||
"\u0220\u0088\3\2\2\2\u0221\u0222\7d\2\2\u0222\u0223\7t\2\2\u0223\u0224"+
|
||||
"\7g\2\2\u0224\u0225\7c\2\2\u0225\u0226\7m\2\2\u0226\u008a\3\2\2\2\u0227"+
|
||||
"\u0228\7e\2\2\u0228\u0229\7q\2\2\u0229\u022a\7p\2\2\u022a\u022b\7v\2\2"+
|
||||
"\u022b\u022c\7k\2\2\u022c\u022d\7p\2\2\u022d\u022e\7w\2\2\u022e\u022f"+
|
||||
"\7g\2\2\u022f\u008c\3\2\2\2\u0230\u0231\7\60\2\2\u0231\u008e\3\2\2\2\u0232"+
|
||||
"\u0233\7C\2\2\u0233\u0090\3\2\2\2\u0234\u0235\7Z\2\2\u0235\u0092\3\2\2"+
|
||||
"\2\u0236\u0237\7[\2\2\u0237\u0094\3\2\2\2\u0238\u0239\7C\2\2\u0239\u023a"+
|
||||
"\7Z\2\2\u023a\u0096\3\2\2\2\u023b\u023c\7C\2\2\u023c\u023d\7[\2\2\u023d"+
|
||||
"\u0098\3\2\2\2\u023e\u023f\7Z\2\2\u023f\u0240\7[\2\2\u0240\u009a\3\2\2"+
|
||||
"\2\u0241\u0242\7R\2\2\u0242\u0243\7e\2\2\u0243\u009c\3\2\2\2\u0244\u0245"+
|
||||
"\7R\2\2\u0245\u0246\7|\2\2\u0246\u009e\3\2\2\2\u0247\u0248\7R\2\2\u0248"+
|
||||
"\u0249\7p\2\2\u0249\u00a0\3\2\2\2\u024a\u024b\7R\2\2\u024b\u024c\7x\2"+
|
||||
"\2\u024c\u00a2\3\2\2\2\u024d\u024e\7\60\2\2\u024e\u024f\7y\2\2\u024f\u00a4"+
|
||||
"\3\2\2\2\u0250\u0251\7v\2\2\u0251\u0252\7t\2\2\u0252\u0253\7w\2\2\u0253"+
|
||||
"\u0254\7g\2\2\u0254\u00a6\3\2\2\2\u0255\u0256\7h\2\2\u0256\u0257\7c\2"+
|
||||
"\2\u0257\u0258\7n\2\2\u0258\u0259\7u\2\2\u0259\u025a\7g\2\2\u025a\u00a8"+
|
||||
"\3\2\2\2\u025b\u025c\7\'\2\2\u025c\u025d\7c\2\2\u025d\u025e\7u\2\2\u025e"+
|
||||
"\u025f\7o\2\2\u025f\u00aa\3\2\2\2\u0260\u0261\7u\2\2\u0261\u0262\7w\2"+
|
||||
"\2\u0262\u0263\7d\2\2\u0263\u00ac\3\2\2\2\u0264\u0265\7/\2\2\u0265\u0266"+
|
||||
"\7@\2\2\u0266\u00ae\3\2\2\2\u0267\u0268\7}\2\2\u0268\u00b0\3\2\2\2\u0269"+
|
||||
"\u026a\7\177\2\2\u026a\u00b2\3\2\2\2\u026b\u026c\7c\2\2\u026c\u026d\7"+
|
||||
"u\2\2\u026d\u026e\7o\2\2\u026e\u026f\7u\2\2\u026f\u0270\7w\2\2\u0270\u0271"+
|
||||
"\7d\2\2\u0271\u00b4\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7n\2\2\u0274"+
|
||||
"\u0275\7q\2\2\u0275\u0276\7d\2\2\u0276\u0277\7d\2\2\u0277\u0278\7g\2\2"+
|
||||
"\u0278\u0279\7t\2\2\u0279\u027a\7u\2\2\u027a\u00b6\3\2\2\2\u027b\u027c"+
|
||||
"\7k\2\2\u027c\u027d\7h\2\2\u027d\u00b8\3\2\2\2\u027e\u027f\7g\2\2\u027f"+
|
||||
"\u0280\7n\2\2\u0280\u0281\7u\2\2\u0281\u0282\7g\2\2\u0282\u00ba\3\2\2"+
|
||||
"\2\u0283\u0284\7k\2\2\u0284\u0285\7h\2\2\u0285\u0286\7a\2\2\u0286\u0287"+
|
||||
"\7e\2\2\u0287\u0288\7u\2\2\u0288\u00bc\3\2\2\2\u0289\u028a\7k\2\2\u028a"+
|
||||
"\u028b\7h\2\2\u028b\u028c\7a\2\2\u028c\u028d\7e\2\2\u028d\u028e\7e\2\2"+
|
||||
"\u028e\u00be\3\2\2\2\u028f\u0290\7k\2\2\u0290\u0291\7h\2\2\u0291\u0292"+
|
||||
"\7a\2\2\u0292\u0293\7g\2\2\u0293\u0294\7s\2\2\u0294\u00c0\3\2\2\2\u0295"+
|
||||
"\u0296\7k\2\2\u0296\u0297\7h\2\2\u0297\u0298\7a\2\2\u0298\u0299\7|\2\2"+
|
||||
"\u0299\u00c2\3\2\2\2\u029a\u029b\7k\2\2\u029b\u029c\7h\2\2\u029c\u029d"+
|
||||
"\7a\2\2\u029d\u029e\7p\2\2\u029e\u029f\7g\2\2\u029f\u00c4\3\2\2\2\u02a0"+
|
||||
"\u02a1\7k\2\2\u02a1\u02a2\7h\2\2\u02a2\u02a3\7a\2\2\u02a3\u02a4\7p\2\2"+
|
||||
"\u02a4\u02a5\7|\2\2\u02a5\u00c6\3\2\2\2\u02a6\u02a7\7k\2\2\u02a7\u02a8"+
|
||||
"\7h\2\2\u02a8\u02a9\7a\2\2\u02a9\u02aa\7r\2\2\u02aa\u02ab\7n\2\2\u02ab"+
|
||||
"\u00c8\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af\7a\2"+
|
||||
"\2\u02af\u02b0\7r\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7u\2\2\u02b2\u00ca"+
|
||||
"\3\2\2\2\u02b3\u02b4\7k\2\2\u02b4\u02b5\7h\2\2\u02b5\u02b6\7a\2\2\u02b6"+
|
||||
"\u02b7\7o\2\2\u02b7\u02b8\7k\2\2\u02b8\u00cc\3\2\2\2\u02b9\u02ba\7k\2"+
|
||||
"\2\u02ba\u02bb\7h\2\2\u02bb\u02bc\7a\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be"+
|
||||
"\7g\2\2\u02be\u02bf\7i\2\2\u02bf\u00ce\3\2\2\2\u02c0\u02c1\7k\2\2\u02c1"+
|
||||
"\u02c2\7h\2\2\u02c2\u02c3\7a\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5\7u\2\2"+
|
||||
"\u02c5\u00d0\3\2\2\2\u02c6\u02c7\7k\2\2\u02c7\u02c8\7h\2\2\u02c8\u02c9"+
|
||||
"\7a\2\2\u02c9\u02ca\7x\2\2\u02ca\u02cb\7e\2\2\u02cb\u00d2\3\2\2\2\u02cc"+
|
||||
"\u02cd\7h\2\2\u02cd\u02ce\7q\2\2\u02ce\u02cf\7t\2\2\u02cf\u00d4\3\2\2"+
|
||||
"\2\u02d0\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u00d6\3\2\2\2\u02d3\u02d4"+
|
||||
"\7y\2\2\u02d4\u02d5\7j\2\2\u02d5\u02d6\7k\2\2\u02d6\u02d7\7n\2\2\u02d7"+
|
||||
"\u02d8\7g\2\2\u02d8\u00d8\3\2\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7g\2"+
|
||||
"\2\u02db\u02dc\7r\2\2\u02dc\u02dd\7g\2\2\u02dd\u02de\7c\2\2\u02de\u02df"+
|
||||
"\7v\2\2\u02df\u00da\3\2\2\2\u02e0\u02e1\7w\2\2\u02e1\u02e2\7p\2\2\u02e2"+
|
||||
"\u02e3\7v\2\2\u02e3\u02e4\7k\2\2\u02e4\u02e5\7n\2\2\u02e5\u00dc\3\2\2"+
|
||||
"\2\u02e6\u02ea\t\2\2\2\u02e7\u02e9\t\3\2\2\u02e8\u02e7\3\2\2\2\u02e9\u02ec"+
|
||||
"\3\2\2\2\u02ea\u02e8\3\2\2\2\u02ea\u02eb\3\2\2\2\u02eb\u02ed\3\2\2\2\u02ec"+
|
||||
"\7/\2\2\u01d2\u01d3\7/\2\2\u01d3R\3\2\2\2\u01d4\u01d5\7-\2\2\u01d5T\3"+
|
||||
"\2\2\2\u01d6\u01d7\7/\2\2\u01d7V\3\2\2\2\u01d8\u01d9\7,\2\2\u01d9\u01da"+
|
||||
"\7,\2\2\u01daX\3\2\2\2\u01db\u01dc\7,\2\2\u01dcZ\3\2\2\2\u01dd\u01de\7"+
|
||||
"\61\2\2\u01de\\\3\2\2\2\u01df\u01e0\7\61\2\2\u01e0\u01e1\7\61\2\2\u01e1"+
|
||||
"^\3\2\2\2\u01e2\u01e3\7\'\2\2\u01e3`\3\2\2\2\u01e4\u01e5\7>\2\2\u01e5"+
|
||||
"b\3\2\2\2\u01e6\u01e7\7@\2\2\u01e7d\3\2\2\2\u01e8\u01e9\7>\2\2\u01e9\u01ea"+
|
||||
"\7?\2\2\u01eaf\3\2\2\2\u01eb\u01ec\7@\2\2\u01ec\u01ed\7?\2\2\u01edh\3"+
|
||||
"\2\2\2\u01ee\u01ef\7?\2\2\u01ef\u01f0\7?\2\2\u01f0j\3\2\2\2\u01f1\u01f2"+
|
||||
"\7#\2\2\u01f2\u01f3\7?\2\2\u01f3l\3\2\2\2\u01f4\u01f5\7(\2\2\u01f5n\3"+
|
||||
"\2\2\2\u01f6\u01f7\7`\2\2\u01f7p\3\2\2\2\u01f8\u01f9\7~\2\2\u01f9r\3\2"+
|
||||
"\2\2\u01fa\u01fb\7v\2\2\u01fb\u01fc\7q\2\2\u01fct\3\2\2\2\u01fd\u01fe"+
|
||||
"\7u\2\2\u01fe\u01ff\7v\2\2\u01ff\u0200\7g\2\2\u0200\u0201\7r\2\2\u0201"+
|
||||
"v\3\2\2\2\u0202\u0203\7c\2\2\u0203\u0204\7p\2\2\u0204\u0205\7f\2\2\u0205"+
|
||||
"x\3\2\2\2\u0206\u0207\7q\2\2\u0207\u0208\7t\2\2\u0208z\3\2\2\2\u0209\u020a"+
|
||||
"\7z\2\2\u020a\u020b\7q\2\2\u020b\u020c\7t\2\2\u020c|\3\2\2\2\u020d\u020e"+
|
||||
"\7p\2\2\u020e\u020f\7q\2\2\u020f\u0210\7v\2\2\u0210~\3\2\2\2\u0211\u0212"+
|
||||
"\7*\2\2\u0212\u0080\3\2\2\2\u0213\u0214\7+\2\2\u0214\u0082\3\2\2\2\u0215"+
|
||||
"\u0216\7c\2\2\u0216\u0217\7u\2\2\u0217\u0084\3\2\2\2\u0218\u0219\7B\2"+
|
||||
"\2\u0219\u0086\3\2\2\2\u021a\u021b\7t\2\2\u021b\u021c\7g\2\2\u021c\u021d"+
|
||||
"\7v\2\2\u021d\u021e\7w\2\2\u021e\u021f\7t\2\2\u021f\u0220\7p\2\2\u0220"+
|
||||
"\u0088\3\2\2\2\u0221\u0222\7d\2\2\u0222\u0223\7t\2\2\u0223\u0224\7g\2"+
|
||||
"\2\u0224\u0225\7c\2\2\u0225\u0226\7m\2\2\u0226\u008a\3\2\2\2\u0227\u0228"+
|
||||
"\7e\2\2\u0228\u0229\7q\2\2\u0229\u022a\7p\2\2\u022a\u022b\7v\2\2\u022b"+
|
||||
"\u022c\7k\2\2\u022c\u022d\7p\2\2\u022d\u022e\7w\2\2\u022e\u022f\7g\2\2"+
|
||||
"\u022f\u008c\3\2\2\2\u0230\u0231\7\60\2\2\u0231\u008e\3\2\2\2\u0232\u0233"+
|
||||
"\7C\2\2\u0233\u0090\3\2\2\2\u0234\u0235\7Z\2\2\u0235\u0092\3\2\2\2\u0236"+
|
||||
"\u0237\7[\2\2\u0237\u0094\3\2\2\2\u0238\u0239\7C\2\2\u0239\u023a\7Z\2"+
|
||||
"\2\u023a\u0096\3\2\2\2\u023b\u023c\7C\2\2\u023c\u023d\7[\2\2\u023d\u0098"+
|
||||
"\3\2\2\2\u023e\u023f\7Z\2\2\u023f\u0240\7[\2\2\u0240\u009a\3\2\2\2\u0241"+
|
||||
"\u0242\7R\2\2\u0242\u0243\7e\2\2\u0243\u009c\3\2\2\2\u0244\u0245\7R\2"+
|
||||
"\2\u0245\u0246\7|\2\2\u0246\u009e\3\2\2\2\u0247\u0248\7R\2\2\u0248\u0249"+
|
||||
"\7p\2\2\u0249\u00a0\3\2\2\2\u024a\u024b\7R\2\2\u024b\u024c\7x\2\2\u024c"+
|
||||
"\u00a2\3\2\2\2\u024d\u024e\7\60\2\2\u024e\u024f\7y\2\2\u024f\u00a4\3\2"+
|
||||
"\2\2\u0250\u0251\7v\2\2\u0251\u0252\7t\2\2\u0252\u0253\7w\2\2\u0253\u0254"+
|
||||
"\7g\2\2\u0254\u00a6\3\2\2\2\u0255\u0256\7h\2\2\u0256\u0257\7c\2\2\u0257"+
|
||||
"\u0258\7n\2\2\u0258\u0259\7u\2\2\u0259\u025a\7g\2\2\u025a\u00a8\3\2\2"+
|
||||
"\2\u025b\u025c\7\'\2\2\u025c\u025d\7c\2\2\u025d\u025e\7u\2\2\u025e\u025f"+
|
||||
"\7o\2\2\u025f\u00aa\3\2\2\2\u0260\u0261\7u\2\2\u0261\u0262\7w\2\2\u0262"+
|
||||
"\u0263\7d\2\2\u0263\u00ac\3\2\2\2\u0264\u0265\7/\2\2\u0265\u0266\7@\2"+
|
||||
"\2\u0266\u00ae\3\2\2\2\u0267\u0268\7}\2\2\u0268\u00b0\3\2\2\2\u0269\u026a"+
|
||||
"\7\177\2\2\u026a\u00b2\3\2\2\2\u026b\u026c\7c\2\2\u026c\u026d\7u\2\2\u026d"+
|
||||
"\u026e\7o\2\2\u026e\u026f\7u\2\2\u026f\u0270\7w\2\2\u0270\u0271\7d\2\2"+
|
||||
"\u0271\u00b4\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7n\2\2\u0274\u0275"+
|
||||
"\7q\2\2\u0275\u0276\7d\2\2\u0276\u0277\7d\2\2\u0277\u0278\7g\2\2\u0278"+
|
||||
"\u0279\7t\2\2\u0279\u027a\7u\2\2\u027a\u00b6\3\2\2\2\u027b\u027c\7k\2"+
|
||||
"\2\u027c\u027d\7h\2\2\u027d\u00b8\3\2\2\2\u027e\u027f\7g\2\2\u027f\u0280"+
|
||||
"\7n\2\2\u0280\u0281\7u\2\2\u0281\u0282\7g\2\2\u0282\u00ba\3\2\2\2\u0283"+
|
||||
"\u0284\7k\2\2\u0284\u0285\7h\2\2\u0285\u0286\7a\2\2\u0286\u0287\7e\2\2"+
|
||||
"\u0287\u0288\7u\2\2\u0288\u00bc\3\2\2\2\u0289\u028a\7k\2\2\u028a\u028b"+
|
||||
"\7h\2\2\u028b\u028c\7a\2\2\u028c\u028d\7e\2\2\u028d\u028e\7e\2\2\u028e"+
|
||||
"\u00be\3\2\2\2\u028f\u0290\7k\2\2\u0290\u0291\7h\2\2\u0291\u0292\7a\2"+
|
||||
"\2\u0292\u0293\7g\2\2\u0293\u0294\7s\2\2\u0294\u00c0\3\2\2\2\u0295\u0296"+
|
||||
"\7k\2\2\u0296\u0297\7h\2\2\u0297\u0298\7a\2\2\u0298\u0299\7|\2\2\u0299"+
|
||||
"\u00c2\3\2\2\2\u029a\u029b\7k\2\2\u029b\u029c\7h\2\2\u029c\u029d\7a\2"+
|
||||
"\2\u029d\u029e\7p\2\2\u029e\u029f\7g\2\2\u029f\u00c4\3\2\2\2\u02a0\u02a1"+
|
||||
"\7k\2\2\u02a1\u02a2\7h\2\2\u02a2\u02a3\7a\2\2\u02a3\u02a4\7p\2\2\u02a4"+
|
||||
"\u02a5\7|\2\2\u02a5\u00c6\3\2\2\2\u02a6\u02a7\7k\2\2\u02a7\u02a8\7h\2"+
|
||||
"\2\u02a8\u02a9\7a\2\2\u02a9\u02aa\7r\2\2\u02aa\u02ab\7n\2\2\u02ab\u00c8"+
|
||||
"\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af\7a\2\2\u02af"+
|
||||
"\u02b0\7r\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7u\2\2\u02b2\u00ca\3\2\2"+
|
||||
"\2\u02b3\u02b4\7k\2\2\u02b4\u02b5\7h\2\2\u02b5\u02b6\7a\2\2\u02b6\u02b7"+
|
||||
"\7o\2\2\u02b7\u02b8\7k\2\2\u02b8\u00cc\3\2\2\2\u02b9\u02ba\7k\2\2\u02ba"+
|
||||
"\u02bb\7h\2\2\u02bb\u02bc\7a\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be\7g\2\2"+
|
||||
"\u02be\u02bf\7i\2\2\u02bf\u00ce\3\2\2\2\u02c0\u02c1\7k\2\2\u02c1\u02c2"+
|
||||
"\7h\2\2\u02c2\u02c3\7a\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5\7u\2\2\u02c5"+
|
||||
"\u00d0\3\2\2\2\u02c6\u02c7\7k\2\2\u02c7\u02c8\7h\2\2\u02c8\u02c9\7a\2"+
|
||||
"\2\u02c9\u02ca\7x\2\2\u02ca\u02cb\7e\2\2\u02cb\u00d2\3\2\2\2\u02cc\u02cd"+
|
||||
"\7h\2\2\u02cd\u02ce\7q\2\2\u02ce\u02cf\7t\2\2\u02cf\u00d4\3\2\2\2\u02d0"+
|
||||
"\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u00d6\3\2\2\2\u02d3\u02d4\7y\2"+
|
||||
"\2\u02d4\u02d5\7j\2\2\u02d5\u02d6\7k\2\2\u02d6\u02d7\7n\2\2\u02d7\u02d8"+
|
||||
"\7g\2\2\u02d8\u00d8\3\2\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7g\2\2\u02db"+
|
||||
"\u02dc\7r\2\2\u02dc\u02dd\7g\2\2\u02dd\u02de\7c\2\2\u02de\u02df\7v\2\2"+
|
||||
"\u02df\u00da\3\2\2\2\u02e0\u02e1\7w\2\2\u02e1\u02e2\7p\2\2\u02e2\u02e3"+
|
||||
"\7v\2\2\u02e3\u02e4\7k\2\2\u02e4\u02e5\7n\2\2\u02e5\u00dc\3\2\2\2\u02e6"+
|
||||
"\u02ea\t\2\2\2\u02e7\u02e9\t\3\2\2\u02e8\u02e7\3\2\2\2\u02e9\u02ec\3\2"+
|
||||
"\2\2\u02ea\u02e8\3\2\2\2\u02ea\u02eb\3\2\2\2\u02eb\u02ed\3\2\2\2\u02ec"+
|
||||
"\u02ea\3\2\2\2\u02ed\u02ee\5\u00dfp\2\u02ee\u02ef\3\2\2\2\u02ef\u02f0"+
|
||||
"\bo\2\2\u02f0\u00de\3\2\2\2\u02f1\u02f5\7=\2\2\u02f2\u02f4\n\2\2\2\u02f3"+
|
||||
"\u02f2\3\2\2\2\u02f4\u02f7\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f5\u02f6\3\2"+
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -325,6 +325,16 @@ class StackVm(private var traceOutputFile: String?) {
|
||||
checkDt(value, DataType.UBYTE)
|
||||
TODO("pop_memwrite $value to $address")
|
||||
}
|
||||
Opcode.POP_INC_MEMORY -> {
|
||||
val address = evalstack.pop()
|
||||
checkDt(address, DataType.UWORD)
|
||||
TODO("pop_inc_memory $address")
|
||||
}
|
||||
Opcode.POP_DEC_MEMORY -> {
|
||||
val address = evalstack.pop()
|
||||
checkDt(address, DataType.UWORD)
|
||||
TODO("pop_dec_memory $address")
|
||||
}
|
||||
Opcode.ADD_UB -> {
|
||||
val (top, second) = evalstack.pop2()
|
||||
checkDt(top, DataType.UBYTE)
|
||||
|
@ -421,11 +421,11 @@ Normally memory locations are accessed by a *memory mapped* name, such as ``c64.
|
||||
as the memory mapped address $d021.
|
||||
|
||||
If you want to access a memory location directly (by using the address itself), without defining
|
||||
a memory mapped location, you can do so by prefixing the address with ``@``::
|
||||
a memory mapped location, you can do so by enclosing the address in ``@(...)``::
|
||||
|
||||
A = @$d020 ; set the A register to the current c64 screen border color ("peek(53280)")
|
||||
@$d020 = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
@(vic+$20) = 6 ; you can also use expressions to 'calculate' the address
|
||||
A = @($d020) ; set the A register to the current c64 screen border color ("peek(53280)")
|
||||
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
@(vic+$20) = 6 ; you can also use expressions to 'calculate' the address
|
||||
|
||||
|
||||
Expressions
|
||||
|
@ -300,11 +300,11 @@ should be the *memory address* where the value is located::
|
||||
Direct access to memory locations
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Instead of defining a memory mapped name for a specific memory location, you can also
|
||||
directly access the memory. Prefix a numeric expression or literal by ``@`` to do that::
|
||||
directly access the memory. Enclose a numeric expression or literal with ``@(...)`` to do that::
|
||||
|
||||
A = @$d020 ; set the A register to the current c64 screen border color ("peek(53280)")
|
||||
@$d020 = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
@(vic+$20) = 6 ; a dynamic expression to 'calculate' the address
|
||||
A = @($d020) ; set the A register to the current c64 screen border color ("peek(53280)")
|
||||
@($d020) = 0 ; set the c64 screen border to black ("poke 53280,0")
|
||||
@(vic+$20) = 6 ; a dynamic expression to 'calculate' the address
|
||||
|
||||
|
||||
Constants
|
||||
|
Loading…
x
Reference in New Issue
Block a user