mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 03:54:27 +00:00
added direct memory access ("poke"/"peek")
This commit is contained in:
parent
75a57da44d
commit
500777bf78
@ -120,6 +120,7 @@ assign_target:
|
|||||||
| identifier
|
| identifier
|
||||||
| scoped_identifier
|
| scoped_identifier
|
||||||
| arrayindexed
|
| arrayindexed
|
||||||
|
| directmemory
|
||||||
;
|
;
|
||||||
|
|
||||||
postincrdecr : assign_target operator = ('++' | '--') ;
|
postincrdecr : assign_target operator = ('++' | '--') ;
|
||||||
@ -146,6 +147,7 @@ expression :
|
|||||||
| identifier
|
| identifier
|
||||||
| scoped_identifier
|
| scoped_identifier
|
||||||
| arrayindexed
|
| arrayindexed
|
||||||
|
| directmemory
|
||||||
| expression typecast
|
| expression typecast
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -157,6 +159,8 @@ arrayindexed :
|
|||||||
(identifier | scoped_identifier ) arrayspec
|
(identifier | scoped_identifier ) arrayspec
|
||||||
;
|
;
|
||||||
|
|
||||||
|
directmemory : '@' expression ;
|
||||||
|
|
||||||
|
|
||||||
functioncall :
|
functioncall :
|
||||||
(identifier | scoped_identifier) '(' expression_list? ')'
|
(identifier | scoped_identifier) '(' expression_list? ')'
|
||||||
|
21
compiler/examples/sprites.p8
Normal file
21
compiler/examples/sprites.p8
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
%import c64lib
|
||||||
|
%import c64utils
|
||||||
|
|
||||||
|
~ main {
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
|
||||||
|
c64.STROUT("balloon sprites!\n")
|
||||||
|
|
||||||
|
const uword SP0X = $d000 ; @todo "address-of" operator '&' so we can write &c64.SP0X
|
||||||
|
const uword SP0Y = $d001 ; @todo "address-of" operator '&' so we can write &c64.SP0Y
|
||||||
|
|
||||||
|
for ubyte i in 0 to 7 {
|
||||||
|
@(SP0X+i*2) = 30+i*30
|
||||||
|
@(SP0Y+i*2) = 100+i*10
|
||||||
|
}
|
||||||
|
|
||||||
|
c64.SPENA = 255 ; enable all sprites
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,95 +1,17 @@
|
|||||||
%import c64utils
|
%import c64utils
|
||||||
%option enable_floats
|
|
||||||
|
|
||||||
~ main {
|
~ main {
|
||||||
|
|
||||||
float[10] xcoor = [1,2,3,4,5,6,7,8,9.9,11.11 ]
|
|
||||||
float[10] ycoor = [11,22,33,44,55,66,77,88,99.9,111.11 ]
|
|
||||||
float[10] zcoor = [111,222,333,444,555,666,777,888,999.9,1001.11 ]
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
c64scr.print("\nxcoor:\n")
|
|
||||||
for float f1 in xcoor {
|
|
||||||
c64flt.print_f(f1)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
|
|
||||||
c64.CHROUT('\n')
|
uword vic = $d000
|
||||||
c64scr.print("ycoor:\n")
|
const uword cvic = $d000
|
||||||
for float f2 in ycoor {
|
|
||||||
c64flt.print_f(f2)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print("zcoor:\n")
|
|
||||||
for float f3 in zcoor {
|
|
||||||
c64flt.print_f(f3)
|
|
||||||
c64.CHROUT(',')
|
|
||||||
}
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
c64.CHROUT('X')
|
@(cvic+$20) = 7
|
||||||
c64scr.print_ub(X)
|
@(cvic+$21) = @(cvic+$20)
|
||||||
c64.CHROUT('\n')
|
|
||||||
float avgfx = avg(xcoor)
|
|
||||||
float avgfy = avg(ycoor)
|
|
||||||
float avgfz = avg(zcoor)
|
|
||||||
c64.CHROUT('X')
|
|
||||||
c64scr.print_ub(X)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
c64scr.print("avgfx=")
|
@(vic+$20) = 5
|
||||||
c64flt.print_f(avgfx)
|
@(vic+$21) = @(vic+$20)
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print("avgfy=")
|
|
||||||
c64flt.print_f(avgfy)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print("avgfz=")
|
|
||||||
c64flt.print_f(avgfz)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
separated2:
|
|
||||||
c64scr.print("\nseparated i=2\n")
|
|
||||||
c64scr.print(" x[2]=")
|
|
||||||
ubyte ii=2
|
|
||||||
c64flt.print_f(xcoor[ii])
|
|
||||||
|
|
||||||
c64scr.print(" y[2]=")
|
|
||||||
c64flt.print_f(ycoor[ii])
|
|
||||||
c64scr.print(" z[2]=")
|
|
||||||
c64flt.print_f(zcoor[ii])
|
|
||||||
|
|
||||||
separated3:
|
|
||||||
c64scr.print("\nseparated i=3\n")
|
|
||||||
ii=3
|
|
||||||
c64scr.print(" x[3]=")
|
|
||||||
c64flt.print_f(xcoor[ii])
|
|
||||||
c64scr.print(" y[3]=")
|
|
||||||
c64flt.print_f(ycoor[ii])
|
|
||||||
c64scr.print(" z[3]=")
|
|
||||||
c64flt.print_f(zcoor[ii])
|
|
||||||
|
|
||||||
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64.CHROUT('X')
|
|
||||||
c64scr.print_ub(X)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
avgfx = avg(xcoor)
|
|
||||||
avgfy = avg(ycoor)
|
|
||||||
avgfz = avg(zcoor)
|
|
||||||
c64.CHROUT('X')
|
|
||||||
c64scr.print_ub(X)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
c64scr.print("avgfx=")
|
|
||||||
c64flt.print_f(avgfx)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print("avgfy=")
|
|
||||||
c64flt.print_f(avgfy)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
c64scr.print("avgfz=")
|
|
||||||
c64flt.print_f(avgfz)
|
|
||||||
c64.CHROUT('\n')
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,6 +261,7 @@ interface IAstProcessor {
|
|||||||
fun process(assignTarget: AssignTarget): AssignTarget {
|
fun process(assignTarget: AssignTarget): AssignTarget {
|
||||||
assignTarget.arrayindexed?.process(this)
|
assignTarget.arrayindexed?.process(this)
|
||||||
assignTarget.identifier?.process(this)
|
assignTarget.identifier?.process(this)
|
||||||
|
assignTarget.memAddressExpression = assignTarget.memAddressExpression?.process(this)
|
||||||
return assignTarget
|
return assignTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,6 +274,11 @@ interface IAstProcessor {
|
|||||||
typecastExpression.expression = typecastExpression.expression.process(this)
|
typecastExpression.expression = typecastExpression.expression.process(this)
|
||||||
return typecastExpression
|
return typecastExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun process(directmemoryExpression: DirectMemoryExpression): IExpression {
|
||||||
|
directmemoryExpression.addressExpression = directmemoryExpression.addressExpression.process(this)
|
||||||
|
return directmemoryExpression
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -725,6 +731,7 @@ class VariableInitializationAssignment(target: AssignTarget, aug_op: String?, va
|
|||||||
data class AssignTarget(val register: Register?,
|
data class AssignTarget(val register: Register?,
|
||||||
val identifier: IdentifierReference?,
|
val identifier: IdentifierReference?,
|
||||||
val arrayindexed: ArrayIndexedExpression?,
|
val arrayindexed: ArrayIndexedExpression?,
|
||||||
|
var memAddressExpression: IExpression?,
|
||||||
override val position: Position) : Node {
|
override val position: Position) : Node {
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
@ -732,6 +739,7 @@ data class AssignTarget(val register: Register?,
|
|||||||
this.parent = parent
|
this.parent = parent
|
||||||
identifier?.linkParents(this)
|
identifier?.linkParents(this)
|
||||||
arrayindexed?.linkParents(this)
|
arrayindexed?.linkParents(this)
|
||||||
|
memAddressExpression?.linkParents(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun process(processor: IAstProcessor) = processor.process(this)
|
fun process(processor: IAstProcessor) = processor.process(this)
|
||||||
@ -739,9 +747,10 @@ data class AssignTarget(val register: Register?,
|
|||||||
companion object {
|
companion object {
|
||||||
fun fromExpr(expr: IExpression): AssignTarget {
|
fun fromExpr(expr: IExpression): AssignTarget {
|
||||||
return when (expr) {
|
return when (expr) {
|
||||||
is RegisterExpr -> AssignTarget(expr.register, null, null, expr.position)
|
is RegisterExpr -> AssignTarget(expr.register, null, null, null, expr.position)
|
||||||
is IdentifierReference -> AssignTarget(null, expr, null, expr.position)
|
is IdentifierReference -> AssignTarget(null, expr, null, null, expr.position)
|
||||||
is ArrayIndexedExpression -> AssignTarget(null, null, expr, expr.position)
|
is ArrayIndexedExpression -> AssignTarget(null, null, expr, null, expr.position)
|
||||||
|
is DirectMemoryExpression -> AssignTarget(null, null, null, expr, expr.position)
|
||||||
else -> throw FatalAstException("invalid expression object $expr")
|
else -> throw FatalAstException("invalid expression object $expr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -761,6 +770,10 @@ data class AssignTarget(val register: Register?,
|
|||||||
if(dt!=null)
|
if(dt!=null)
|
||||||
return dt
|
return dt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(memAddressExpression!=null)
|
||||||
|
return DataType.UBYTE
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -771,6 +784,8 @@ data class AssignTarget(val register: Register?,
|
|||||||
return identifier.nameInSource.last()
|
return identifier.nameInSource.last()
|
||||||
if(arrayindexed!=null)
|
if(arrayindexed!=null)
|
||||||
return arrayindexed.identifier!!.nameInSource.last()
|
return arrayindexed.identifier!!.nameInSource.last()
|
||||||
|
if(memAddressExpression is LiteralValue)
|
||||||
|
return (memAddressExpression as LiteralValue).asIntegerValue.toString()
|
||||||
return "???"
|
return "???"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1012,6 +1027,24 @@ class TypecastExpression(var expression: IExpression, var type: DataType, overri
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DirectMemoryExpression(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 "DirectMemory($addressExpression)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private data class NumericLiteral(val number: Number, val datatype: DataType)
|
private data class NumericLiteral(val number: Number, val datatype: DataType)
|
||||||
@ -1942,14 +1975,14 @@ private fun prog8Parser.Assign_targetContext.toAst() : AssignTarget {
|
|||||||
val register = register()?.toAst()
|
val register = register()?.toAst()
|
||||||
val identifier = identifier()
|
val identifier = identifier()
|
||||||
return when {
|
return when {
|
||||||
register!=null -> AssignTarget(register, null, null, toPosition())
|
register!=null -> AssignTarget(register, null, null, null, toPosition())
|
||||||
identifier!=null -> AssignTarget(null, identifier.toAst(), null, toPosition())
|
identifier!=null -> AssignTarget(null, identifier.toAst(), null, null, toPosition())
|
||||||
arrayindexed()!=null -> AssignTarget(null, null, arrayindexed().toAst(), toPosition())
|
arrayindexed()!=null -> AssignTarget(null, null, arrayindexed().toAst(), null, toPosition())
|
||||||
else -> AssignTarget(null, scoped_identifier()?.toAst(), null, toPosition())
|
directmemory()!=null -> AssignTarget(null, null, null, directmemory().expression().toAst(), toPosition())
|
||||||
|
else -> AssignTarget(null, scoped_identifier()?.toAst(), null, null, toPosition())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun prog8Parser.RegisterContext.toAst() = Register.valueOf(text.toUpperCase())
|
private fun prog8Parser.RegisterContext.toAst() = Register.valueOf(text.toUpperCase())
|
||||||
|
|
||||||
private fun prog8Parser.DatatypeContext.toAst() = DataType.valueOf(text.toUpperCase())
|
private fun prog8Parser.DatatypeContext.toAst() = DataType.valueOf(text.toUpperCase())
|
||||||
@ -2074,6 +2107,9 @@ private fun prog8Parser.ExpressionContext.toAst() : IExpression {
|
|||||||
if(typecast()!=null)
|
if(typecast()!=null)
|
||||||
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), toPosition())
|
return TypecastExpression(expression(0).toAst(), typecast().datatype().toAst(), toPosition())
|
||||||
|
|
||||||
|
if(directmemory()!=null)
|
||||||
|
return DirectMemoryExpression(directmemory().expression().toAst(), toPosition())
|
||||||
|
|
||||||
throw FatalAstException(text)
|
throw FatalAstException(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,6 +387,13 @@ class AstChecker(private val namespace: INameScope,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun processAssignmentTarget(assignment: Assignment, target: AssignTarget): Assignment {
|
private fun processAssignmentTarget(assignment: Assignment, target: AssignTarget): Assignment {
|
||||||
|
val memAddr = target.memAddressExpression?.constValue(namespace, heap)?.asIntegerValue
|
||||||
|
if(memAddr!=null) {
|
||||||
|
if(memAddr<0 || memAddr>=65536)
|
||||||
|
checkResult.add(ExpressionError("address out of range", target.position))
|
||||||
|
return assignment
|
||||||
|
}
|
||||||
|
|
||||||
if(target.identifier!=null) {
|
if(target.identifier!=null) {
|
||||||
val targetName = target.identifier.nameInSource
|
val targetName = target.identifier.nameInSource
|
||||||
val targetSymbol = namespace.lookup(targetName, assignment)
|
val targetSymbol = namespace.lookup(targetName, assignment)
|
||||||
|
@ -121,7 +121,7 @@ class StatementReorderer(private val namespace: INameScope, private val heap: He
|
|||||||
else
|
else
|
||||||
declvalue
|
declvalue
|
||||||
return VariableInitializationAssignment(
|
return VariableInitializationAssignment(
|
||||||
AssignTarget(null, IdentifierReference(decl.scopedname.split("."), decl.position), null, decl.position),
|
AssignTarget(null, IdentifierReference(decl.scopedname.split("."), decl.position), null, null, decl.position),
|
||||||
null,
|
null,
|
||||||
value,
|
value,
|
||||||
decl.position
|
decl.position
|
||||||
|
@ -580,6 +580,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
is ArrayIndexedExpression -> translate(expr, false)
|
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 RangeExpr -> throw CompilerException("it's not possible to just have a range expression that has to be translated")
|
||||||
is TypecastExpression -> translate(expr)
|
is TypecastExpression -> translate(expr)
|
||||||
|
is DirectMemoryExpression -> translate(expr)
|
||||||
else -> {
|
else -> {
|
||||||
val lv = expr.constValue(namespace, heap) ?: throw CompilerException("constant expression required, not $expr")
|
val lv = expr.constValue(namespace, heap) ?: throw CompilerException("constant expression required, not $expr")
|
||||||
when(lv.type) {
|
when(lv.type) {
|
||||||
@ -876,7 +877,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
} else {
|
} else {
|
||||||
when (arg.second.registerOrPair!!) {
|
when (arg.second.registerOrPair!!) {
|
||||||
A -> {
|
A -> {
|
||||||
val assign = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, arg.first, callPosition)
|
val assign = Assignment(listOf(AssignTarget(Register.A, null, null, null, callPosition)), null, arg.first, callPosition)
|
||||||
assign.linkParents(arguments[0].parent)
|
assign.linkParents(arguments[0].parent)
|
||||||
translate(assign)
|
translate(assign)
|
||||||
}
|
}
|
||||||
@ -885,12 +886,12 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
prog.instr(Opcode.RSAVEX)
|
prog.instr(Opcode.RSAVEX)
|
||||||
restoreX = true
|
restoreX = true
|
||||||
}
|
}
|
||||||
val assign = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, arg.first, callPosition)
|
val assign = Assignment(listOf(AssignTarget(Register.X, null, null, null, callPosition)), null, arg.first, callPosition)
|
||||||
assign.linkParents(arguments[0].parent)
|
assign.linkParents(arguments[0].parent)
|
||||||
translate(assign)
|
translate(assign)
|
||||||
}
|
}
|
||||||
Y -> {
|
Y -> {
|
||||||
val assign = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, arg.first, callPosition)
|
val assign = Assignment(listOf(AssignTarget(Register.Y, null, null, null, callPosition)), null, arg.first, callPosition)
|
||||||
assign.linkParents(arguments[0].parent)
|
assign.linkParents(arguments[0].parent)
|
||||||
translate(assign)
|
translate(assign)
|
||||||
}
|
}
|
||||||
@ -906,8 +907,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
valueA=arg.first
|
valueA=arg.first
|
||||||
valueX=LiteralValue.optimalInteger(0, callPosition)
|
valueX=LiteralValue.optimalInteger(0, callPosition)
|
||||||
val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, valueA, callPosition)
|
val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, null, callPosition)), null, valueA, callPosition)
|
||||||
val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, valueX, callPosition)
|
val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, null, callPosition)), null, valueX, callPosition)
|
||||||
assignA.linkParents(arguments[0].parent)
|
assignA.linkParents(arguments[0].parent)
|
||||||
assignX.linkParents(arguments[0].parent)
|
assignX.linkParents(arguments[0].parent)
|
||||||
translate(assignA)
|
translate(assignA)
|
||||||
@ -932,8 +933,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
valueA=arg.first
|
valueA=arg.first
|
||||||
valueY=LiteralValue.optimalInteger(0, callPosition)
|
valueY=LiteralValue.optimalInteger(0, callPosition)
|
||||||
val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, callPosition)), null, valueA, callPosition)
|
val assignA = Assignment(listOf(AssignTarget(Register.A, null, null, null, callPosition)), null, valueA, callPosition)
|
||||||
val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, valueY, callPosition)
|
val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, null, callPosition)), null, valueY, callPosition)
|
||||||
assignA.linkParents(arguments[0].parent)
|
assignA.linkParents(arguments[0].parent)
|
||||||
assignY.linkParents(arguments[0].parent)
|
assignY.linkParents(arguments[0].parent)
|
||||||
translate(assignA)
|
translate(assignA)
|
||||||
@ -962,8 +963,8 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
DataType.UBYTE -> {
|
DataType.UBYTE -> {
|
||||||
valueX=arg.first
|
valueX=arg.first
|
||||||
valueY=LiteralValue.optimalInteger(0, callPosition)
|
valueY=LiteralValue.optimalInteger(0, callPosition)
|
||||||
val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, callPosition)), null, valueX, callPosition)
|
val assignX = Assignment(listOf(AssignTarget(Register.X, null, null, null, callPosition)), null, valueX, callPosition)
|
||||||
val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, callPosition)), null, valueY, callPosition)
|
val assignY = Assignment(listOf(AssignTarget(Register.Y, null, null, null, callPosition)), null, valueY, callPosition)
|
||||||
assignX.linkParents(arguments[0].parent)
|
assignX.linkParents(arguments[0].parent)
|
||||||
assignY.linkParents(arguments[0].parent)
|
assignY.linkParents(arguments[0].parent)
|
||||||
translate(assignX)
|
translate(assignX)
|
||||||
@ -1481,6 +1482,17 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
assignTarget.register != null -> prog.instr(Opcode.POP_VAR_BYTE, callLabel = assignTarget.register.toString())
|
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.arrayindexed != null -> translate(assignTarget.arrayindexed, true) // write value to it
|
||||||
|
assignTarget.memAddressExpression != null -> {
|
||||||
|
val address = assignTarget.memAddressExpression?.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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> throw CompilerException("corrupt assigntarget $assignTarget")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1710,9 +1722,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
// loop starts here
|
// loop starts here
|
||||||
prog.label(loopLabel)
|
prog.label(loopLabel)
|
||||||
val assignTarget = if(loop.loopRegister!=null)
|
val assignTarget = if(loop.loopRegister!=null)
|
||||||
AssignTarget(loop.loopRegister, null, null, loop.position)
|
AssignTarget(loop.loopRegister, null, null, null, loop.position)
|
||||||
else
|
else
|
||||||
AssignTarget(null, loop.loopVar!!.copy(), null, loop.position)
|
AssignTarget(null, loop.loopVar!!.copy(), null, null, loop.position)
|
||||||
val arrayspec = ArraySpec(IdentifierReference(listOf(ForLoop.iteratorLoopcounterVarname), loop.position), loop.position)
|
val arrayspec = ArraySpec(IdentifierReference(listOf(ForLoop.iteratorLoopcounterVarname), loop.position), loop.position)
|
||||||
val assignLv = Assignment(
|
val assignLv = Assignment(
|
||||||
listOf(assignTarget), null,
|
listOf(assignTarget), null,
|
||||||
@ -1843,9 +1855,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
*/
|
*/
|
||||||
fun makeAssignmentTarget(): AssignTarget {
|
fun makeAssignmentTarget(): AssignTarget {
|
||||||
return if(varname!=null)
|
return if(varname!=null)
|
||||||
AssignTarget(null, IdentifierReference(varname, range.position), null, range.position)
|
AssignTarget(null, IdentifierReference(varname, range.position), null, null, range.position)
|
||||||
else
|
else
|
||||||
AssignTarget(register, null, null, range.position)
|
AssignTarget(register, null, null, null, range.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
val startAssignment = Assignment(listOf(makeAssignmentTarget()), null, range.from, range.position)
|
val startAssignment = Assignment(listOf(makeAssignmentTarget()), null, range.from, range.position)
|
||||||
@ -2071,4 +2083,15 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun translate(expr: DirectMemoryExpression) {
|
||||||
|
// for now, only a single memory location (ubyte) is read at a time.
|
||||||
|
val address = expr.addressExpression.constValue(namespace, heap)?.asIntegerValue
|
||||||
|
if(address!=null) {
|
||||||
|
prog.instr(Opcode.PUSH_MEM_UB, arg = Value(DataType.UWORD, address))
|
||||||
|
} else {
|
||||||
|
translate(expr.addressExpression)
|
||||||
|
prog.instr(Opcode.PUSH_MEMREAD)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ enum class Opcode {
|
|||||||
PUSH_MEM_W, // push word value from memory to stack
|
PUSH_MEM_W, // push word value from memory to stack
|
||||||
PUSH_MEM_UW, // push unsigned word value from memory to stack
|
PUSH_MEM_UW, // push unsigned word value from memory to stack
|
||||||
PUSH_MEM_FLOAT, // push float value from memory to stack
|
PUSH_MEM_FLOAT, // push float value from memory to stack
|
||||||
|
PUSH_MEMREAD, // push memory value from address that's on the stack
|
||||||
PUSH_VAR_BYTE, // push byte variable (ubyte, byte)
|
PUSH_VAR_BYTE, // push byte variable (ubyte, byte)
|
||||||
PUSH_VAR_WORD, // push word variable (uword, word)
|
PUSH_VAR_WORD, // push word variable (uword, word)
|
||||||
PUSH_VAR_FLOAT, // push float variable
|
PUSH_VAR_FLOAT, // push float variable
|
||||||
@ -27,6 +28,7 @@ enum class Opcode {
|
|||||||
POP_MEM_BYTE, // pop (u)byte value into destination memory address
|
POP_MEM_BYTE, // pop (u)byte value into destination memory address
|
||||||
POP_MEM_WORD, // pop (u)word value into destination memory address
|
POP_MEM_WORD, // pop (u)word value into destination memory address
|
||||||
POP_MEM_FLOAT, // pop float value into destination memory address
|
POP_MEM_FLOAT, // pop float value into destination memory address
|
||||||
|
POP_MEMWRITE, // pop address and byte stack and write the byte to the memory address
|
||||||
POP_VAR_BYTE, // pop (u)byte value into variable
|
POP_VAR_BYTE, // pop (u)byte value into variable
|
||||||
POP_VAR_WORD, // pop (u)word value into variable
|
POP_VAR_WORD, // pop (u)word value into variable
|
||||||
POP_VAR_FLOAT, // pop float value into variable
|
POP_VAR_FLOAT, // pop float value into variable
|
||||||
|
@ -493,6 +493,17 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
Opcode.PUSH_MEM_FLOAT -> {
|
Opcode.PUSH_MEM_FLOAT -> {
|
||||||
" lda #<${hexVal(ins)} | ldy #>${hexVal(ins)}| jsr prog8_lib.push_float"
|
" lda #<${hexVal(ins)} | ldy #>${hexVal(ins)}| jsr prog8_lib.push_float"
|
||||||
}
|
}
|
||||||
|
Opcode.PUSH_MEMREAD -> {
|
||||||
|
"""
|
||||||
|
lda ${(ESTACK_LO+1).toHex()},x
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
|
lda ${(ESTACK_HI+1).toHex()},x
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||||
|
ldy #0
|
||||||
|
lda (${C64Zeropage.SCRATCH_W1}),y
|
||||||
|
sta ${(ESTACK_LO+1).toHex()},x
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
Opcode.PUSH_REGAY_WORD -> {
|
Opcode.PUSH_REGAY_WORD -> {
|
||||||
" sta ${ESTACK_LO.toHex()},x | tya | sta ${ESTACK_HI.toHex()},x | dex "
|
" sta ${ESTACK_LO.toHex()},x | tya | sta ${ESTACK_HI.toHex()},x | dex "
|
||||||
@ -579,6 +590,20 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
Opcode.POP_MEM_FLOAT -> {
|
Opcode.POP_MEM_FLOAT -> {
|
||||||
" lda ${hexVal(ins)} | ldy ${hexValPlusOne(ins)} | jsr prog8_lib.pop_float"
|
" lda ${hexVal(ins)} | ldy ${hexValPlusOne(ins)} | jsr prog8_lib.pop_float"
|
||||||
}
|
}
|
||||||
|
Opcode.POP_MEMWRITE -> {
|
||||||
|
"""
|
||||||
|
inx
|
||||||
|
lda ${ESTACK_LO.toHex()},x
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1}
|
||||||
|
lda ${ESTACK_HI.toHex()},x
|
||||||
|
sta ${C64Zeropage.SCRATCH_W1+1}
|
||||||
|
inx
|
||||||
|
lda ${ESTACK_LO.toHex()},x
|
||||||
|
ldy #0
|
||||||
|
sta (${C64Zeropage.SCRATCH_W1}),y
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
|
||||||
Opcode.POP_VAR_BYTE -> {
|
Opcode.POP_VAR_BYTE -> {
|
||||||
when (ins.callLabel) {
|
when (ins.callLabel) {
|
||||||
"X" -> throw CompilerException("makes no sense to pop X, it's used as a stack pointer itself")
|
"X" -> throw CompilerException("makes no sense to pop X, it's used as a stack pointer itself")
|
||||||
@ -702,8 +727,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
Opcode.CAST_F_TO_B -> " jsr prog8_lib.stack_float2w"
|
Opcode.CAST_F_TO_B -> " jsr prog8_lib.stack_float2w"
|
||||||
Opcode.CAST_F_TO_UW -> " jsr prog8_lib.stack_float2uw"
|
Opcode.CAST_F_TO_UW -> " jsr prog8_lib.stack_float2uw"
|
||||||
Opcode.CAST_F_TO_W -> " jsr prog8_lib.stack_float2w"
|
Opcode.CAST_F_TO_W -> " jsr prog8_lib.stack_float2w"
|
||||||
Opcode.CAST_UB_TO_UW, Opcode.CAST_UB_TO_W -> " lda #0 | sta ${ESTACK_HI+1},x" // clear the msb
|
Opcode.CAST_UB_TO_UW, Opcode.CAST_UB_TO_W -> " lda #0 | sta ${(ESTACK_HI+1).toHex()},x" // clear the msb
|
||||||
Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " ${signExtendA("${ESTACK_HI+1},x")}" // sign extend the lsb @todo missing an lda???
|
Opcode.CAST_B_TO_UW, Opcode.CAST_B_TO_W -> " lda ${(ESTACK_LO+1)},x | ${signExtendA("${(ESTACK_HI+1).toHex()},x")}" // sign extend the lsb
|
||||||
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
|
Opcode.MSB -> " lda ${(ESTACK_HI+1).toHex()},x | sta ${(ESTACK_LO+1).toHex()},x"
|
||||||
|
|
||||||
Opcode.ADD_UB, Opcode.ADD_B -> {
|
Opcode.ADD_UB, Opcode.ADD_B -> {
|
||||||
|
@ -93,7 +93,7 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
|
|||||||
if(range.size(heap)==1) {
|
if(range.size(heap)==1) {
|
||||||
// for loop over a (constant) range of just a single value-- optimize the loop away
|
// for loop over a (constant) range of just a single value-- optimize the loop away
|
||||||
// loopvar/reg = range value , follow by block
|
// loopvar/reg = range value , follow by block
|
||||||
val assignment = Assignment(listOf(AssignTarget(forLoop.loopRegister, forLoop.loopVar, null, forLoop.position)), null, range.from, forLoop.position)
|
val assignment = Assignment(listOf(AssignTarget(forLoop.loopRegister, forLoop.loopVar, null, null, forLoop.position)), null, range.from, forLoop.position)
|
||||||
forLoop.body.statements.add(0, assignment)
|
forLoop.body.statements.add(0, assignment)
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
return forLoop.body
|
return forLoop.body
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Generated from ../antlr/prog8.g4 by ANTLR 4.7.2
|
// Generated from /home/irmen/Projects/prog8/compiler/antlr/prog8.g4 by ANTLR 4.7.2
|
||||||
package prog8.parser;
|
package prog8.parser;
|
||||||
import org.antlr.v4.runtime.Lexer;
|
import org.antlr.v4.runtime.Lexer;
|
||||||
import org.antlr.v4.runtime.CharStream;
|
import org.antlr.v4.runtime.CharStream;
|
||||||
@ -75,13 +75,13 @@ public class prog8Lexer extends Lexer {
|
|||||||
"'&='", "'|='", "'^='", "'%='", "'++'", "'--'", "'('", "')'", "'+'",
|
"'&='", "'|='", "'^='", "'%='", "'++'", "'--'", "'('", "')'", "'+'",
|
||||||
"'-'", "'**'", "'*'", "'/'", "'//'", "'%'", "'<'", "'>'", "'<='", "'>='",
|
"'-'", "'**'", "'*'", "'/'", "'//'", "'%'", "'<'", "'>'", "'<='", "'>='",
|
||||||
"'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'step'", "'and'", "'or'",
|
"'=='", "'!='", "'&'", "'^'", "'|'", "'to'", "'step'", "'and'", "'or'",
|
||||||
"'xor'", "'not'", "'as'", "'return'", "'break'", "'continue'", "'.'",
|
"'xor'", "'not'", "'as'", "'@'", "'return'", "'break'", "'continue'",
|
||||||
"'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'",
|
"'.'", "'A'", "'X'", "'Y'", "'AX'", "'AY'", "'XY'", "'Pc'", "'Pz'", "'Pn'",
|
||||||
"'Pv'", "'.w'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'{'",
|
"'Pv'", "'.w'", "'true'", "'false'", "'%asm'", "'sub'", "'->'", "'{'",
|
||||||
"'}'", "'asmsub'", "'clobbers'", "'@'", "'if'", "'else'", "'if_cs'",
|
"'}'", "'asmsub'", "'clobbers'", "'if'", "'else'", "'if_cs'", "'if_cc'",
|
||||||
"'if_cc'", "'if_eq'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'",
|
"'if_eq'", "'if_z'", "'if_ne'", "'if_nz'", "'if_pl'", "'if_pos'", "'if_mi'",
|
||||||
"'if_mi'", "'if_neg'", "'if_vs'", "'if_vc'", "'for'", "'in'", "'while'",
|
"'if_neg'", "'if_vs'", "'if_vc'", "'for'", "'in'", "'while'", "'repeat'",
|
||||||
"'repeat'", "'until'"
|
"'until'"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
private static final String[] _LITERAL_NAMES = makeLiteralNames();
|
||||||
@ -238,11 +238,11 @@ public class prog8Lexer extends Lexer {
|
|||||||
")\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"+
|
")\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"+
|
"\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?"+
|
"\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\3C\3C\3C\3C\3C\3D\3D\3D"+
|
"\3?\3?\3@\3@\3@\3@\3A\3A\3A\3A\3B\3B\3B\3C\3C\3D\3D\3D\3D\3D\3D\3D\3E"+
|
||||||
"\3D\3D\3D\3E\3E\3E\3E\3E\3E\3E\3E\3E\3F\3F\3G\3G\3H\3H\3I\3I\3J\3J\3J"+
|
"\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\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R"+
|
"\3K\3K\3L\3L\3L\3M\3M\3M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R\3R"+
|
||||||
"\3R\3R\3R\3S\3S\3S\3S\3S\3S\3T\3T\3T\3T\3T\3U\3U\3U\3U\3V\3V\3V\3W\3W"+
|
"\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\3Y\3Y\3Y\3Y\3Y\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3Z\3[\3[\3\\\3\\\3"+
|
"\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"+
|
"\\\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"+
|
"`\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"+
|
"d\3e\3e\3e\3e\3e\3e\3e\3f\3f\3f\3f\3f\3f\3g\3g\3g\3g\3g\3g\3g\3h\3h\3"+
|
||||||
@ -304,13 +304,13 @@ public class prog8Lexer extends Lexer {
|
|||||||
"\2\2k\u01ef\3\2\2\2m\u01f2\3\2\2\2o\u01f5\3\2\2\2q\u01f8\3\2\2\2s\u01fa"+
|
"\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}"+
|
"\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"+
|
"\u020a\3\2\2\2\177\u020d\3\2\2\2\u0081\u0211\3\2\2\2\u0083\u0215\3\2\2"+
|
||||||
"\2\u0085\u0218\3\2\2\2\u0087\u021f\3\2\2\2\u0089\u0225\3\2\2\2\u008b\u022e"+
|
"\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"+
|
"\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\u0239\3\2\2\2\u0097\u023c\3\2\2\2\u0099\u023f\3\2"+
|
"\u0236\3\2\2\2\u0095\u0238\3\2\2\2\u0097\u023b\3\2\2\2\u0099\u023e\3\2"+
|
||||||
"\2\2\u009b\u0242\3\2\2\2\u009d\u0245\3\2\2\2\u009f\u0248\3\2\2\2\u00a1"+
|
"\2\2\u009b\u0241\3\2\2\2\u009d\u0244\3\2\2\2\u009f\u0247\3\2\2\2\u00a1"+
|
||||||
"\u024b\3\2\2\2\u00a3\u024e\3\2\2\2\u00a5\u0253\3\2\2\2\u00a7\u0259\3\2"+
|
"\u024a\3\2\2\2\u00a3\u024d\3\2\2\2\u00a5\u0250\3\2\2\2\u00a7\u0255\3\2"+
|
||||||
"\2\2\u00a9\u025e\3\2\2\2\u00ab\u0262\3\2\2\2\u00ad\u0265\3\2\2\2\u00af"+
|
"\2\2\u00a9\u025b\3\2\2\2\u00ab\u0260\3\2\2\2\u00ad\u0264\3\2\2\2\u00af"+
|
||||||
"\u0267\3\2\2\2\u00b1\u0269\3\2\2\2\u00b3\u0270\3\2\2\2\u00b5\u0279\3\2"+
|
"\u0267\3\2\2\2\u00b1\u0269\3\2\2\2\u00b3\u026b\3\2\2\2\u00b5\u0272\3\2"+
|
||||||
"\2\2\u00b7\u027b\3\2\2\2\u00b9\u027e\3\2\2\2\u00bb\u0283\3\2\2\2\u00bd"+
|
"\2\2\u00b7\u027b\3\2\2\2\u00b9\u027e\3\2\2\2\u00bb\u0283\3\2\2\2\u00bd"+
|
||||||
"\u0289\3\2\2\2\u00bf\u028f\3\2\2\2\u00c1\u0295\3\2\2\2\u00c3\u029a\3\2"+
|
"\u0289\3\2\2\2\u00bf\u028f\3\2\2\2\u00c1\u0295\3\2\2\2\u00c3\u029a\3\2"+
|
||||||
"\2\2\u00c5\u02a0\3\2\2\2\u00c7\u02a6\3\2\2\2\u00c9\u02ac\3\2\2\2\u00cb"+
|
"\2\2\u00c5\u02a0\3\2\2\2\u00c7\u02a6\3\2\2\2\u00c9\u02ac\3\2\2\2\u00cb"+
|
||||||
@ -395,68 +395,68 @@ public class prog8Lexer extends Lexer {
|
|||||||
"\7z\2\2\u020e\u020f\7q\2\2\u020f\u0210\7t\2\2\u0210\u0080\3\2\2\2\u0211"+
|
"\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"+
|
"\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"+
|
"\2\u0215\u0216\7c\2\2\u0216\u0217\7u\2\2\u0217\u0084\3\2\2\2\u0218\u0219"+
|
||||||
"\7t\2\2\u0219\u021a\7g\2\2\u021a\u021b\7v\2\2\u021b\u021c\7w\2\2\u021c"+
|
"\7B\2\2\u0219\u0086\3\2\2\2\u021a\u021b\7t\2\2\u021b\u021c\7g\2\2\u021c"+
|
||||||
"\u021d\7t\2\2\u021d\u021e\7p\2\2\u021e\u0086\3\2\2\2\u021f\u0220\7d\2"+
|
"\u021d\7v\2\2\u021d\u021e\7w\2\2\u021e\u021f\7t\2\2\u021f\u0220\7p\2\2"+
|
||||||
"\2\u0220\u0221\7t\2\2\u0221\u0222\7g\2\2\u0222\u0223\7c\2\2\u0223\u0224"+
|
"\u0220\u0088\3\2\2\2\u0221\u0222\7d\2\2\u0222\u0223\7t\2\2\u0223\u0224"+
|
||||||
"\7m\2\2\u0224\u0088\3\2\2\2\u0225\u0226\7e\2\2\u0226\u0227\7q\2\2\u0227"+
|
"\7g\2\2\u0224\u0225\7c\2\2\u0225\u0226\7m\2\2\u0226\u008a\3\2\2\2\u0227"+
|
||||||
"\u0228\7p\2\2\u0228\u0229\7v\2\2\u0229\u022a\7k\2\2\u022a\u022b\7p\2\2"+
|
"\u0228\7e\2\2\u0228\u0229\7q\2\2\u0229\u022a\7p\2\2\u022a\u022b\7v\2\2"+
|
||||||
"\u022b\u022c\7w\2\2\u022c\u022d\7g\2\2\u022d\u008a\3\2\2\2\u022e\u022f"+
|
"\u022b\u022c\7k\2\2\u022c\u022d\7p\2\2\u022d\u022e\7w\2\2\u022e\u022f"+
|
||||||
"\7\60\2\2\u022f\u008c\3\2\2\2\u0230\u0231\7C\2\2\u0231\u008e\3\2\2\2\u0232"+
|
"\7g\2\2\u022f\u008c\3\2\2\2\u0230\u0231\7\60\2\2\u0231\u008e\3\2\2\2\u0232"+
|
||||||
"\u0233\7Z\2\2\u0233\u0090\3\2\2\2\u0234\u0235\7[\2\2\u0235\u0092\3\2\2"+
|
"\u0233\7C\2\2\u0233\u0090\3\2\2\2\u0234\u0235\7Z\2\2\u0235\u0092\3\2\2"+
|
||||||
"\2\u0236\u0237\7C\2\2\u0237\u0238\7Z\2\2\u0238\u0094\3\2\2\2\u0239\u023a"+
|
"\2\u0236\u0237\7[\2\2\u0237\u0094\3\2\2\2\u0238\u0239\7C\2\2\u0239\u023a"+
|
||||||
"\7C\2\2\u023a\u023b\7[\2\2\u023b\u0096\3\2\2\2\u023c\u023d\7Z\2\2\u023d"+
|
"\7Z\2\2\u023a\u0096\3\2\2\2\u023b\u023c\7C\2\2\u023c\u023d\7[\2\2\u023d"+
|
||||||
"\u023e\7[\2\2\u023e\u0098\3\2\2\2\u023f\u0240\7R\2\2\u0240\u0241\7e\2"+
|
"\u0098\3\2\2\2\u023e\u023f\7Z\2\2\u023f\u0240\7[\2\2\u0240\u009a\3\2\2"+
|
||||||
"\2\u0241\u009a\3\2\2\2\u0242\u0243\7R\2\2\u0243\u0244\7|\2\2\u0244\u009c"+
|
"\2\u0241\u0242\7R\2\2\u0242\u0243\7e\2\2\u0243\u009c\3\2\2\2\u0244\u0245"+
|
||||||
"\3\2\2\2\u0245\u0246\7R\2\2\u0246\u0247\7p\2\2\u0247\u009e\3\2\2\2\u0248"+
|
"\7R\2\2\u0245\u0246\7|\2\2\u0246\u009e\3\2\2\2\u0247\u0248\7R\2\2\u0248"+
|
||||||
"\u0249\7R\2\2\u0249\u024a\7x\2\2\u024a\u00a0\3\2\2\2\u024b\u024c\7\60"+
|
"\u0249\7p\2\2\u0249\u00a0\3\2\2\2\u024a\u024b\7R\2\2\u024b\u024c\7x\2"+
|
||||||
"\2\2\u024c\u024d\7y\2\2\u024d\u00a2\3\2\2\2\u024e\u024f\7v\2\2\u024f\u0250"+
|
"\2\u024c\u00a2\3\2\2\2\u024d\u024e\7\60\2\2\u024e\u024f\7y\2\2\u024f\u00a4"+
|
||||||
"\7t\2\2\u0250\u0251\7w\2\2\u0251\u0252\7g\2\2\u0252\u00a4\3\2\2\2\u0253"+
|
"\3\2\2\2\u0250\u0251\7v\2\2\u0251\u0252\7t\2\2\u0252\u0253\7w\2\2\u0253"+
|
||||||
"\u0254\7h\2\2\u0254\u0255\7c\2\2\u0255\u0256\7n\2\2\u0256\u0257\7u\2\2"+
|
"\u0254\7g\2\2\u0254\u00a6\3\2\2\2\u0255\u0256\7h\2\2\u0256\u0257\7c\2"+
|
||||||
"\u0257\u0258\7g\2\2\u0258\u00a6\3\2\2\2\u0259\u025a\7\'\2\2\u025a\u025b"+
|
"\2\u0257\u0258\7n\2\2\u0258\u0259\7u\2\2\u0259\u025a\7g\2\2\u025a\u00a8"+
|
||||||
"\7c\2\2\u025b\u025c\7u\2\2\u025c\u025d\7o\2\2\u025d\u00a8\3\2\2\2\u025e"+
|
"\3\2\2\2\u025b\u025c\7\'\2\2\u025c\u025d\7c\2\2\u025d\u025e\7u\2\2\u025e"+
|
||||||
"\u025f\7u\2\2\u025f\u0260\7w\2\2\u0260\u0261\7d\2\2\u0261\u00aa\3\2\2"+
|
"\u025f\7o\2\2\u025f\u00aa\3\2\2\2\u0260\u0261\7u\2\2\u0261\u0262\7w\2"+
|
||||||
"\2\u0262\u0263\7/\2\2\u0263\u0264\7@\2\2\u0264\u00ac\3\2\2\2\u0265\u0266"+
|
"\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\177\2\2\u0268\u00b0\3\2\2\2"+
|
"\7@\2\2\u0266\u00ae\3\2\2\2\u0267\u0268\7}\2\2\u0268\u00b0\3\2\2\2\u0269"+
|
||||||
"\u0269\u026a\7c\2\2\u026a\u026b\7u\2\2\u026b\u026c\7o\2\2\u026c\u026d"+
|
"\u026a\7\177\2\2\u026a\u00b2\3\2\2\2\u026b\u026c\7c\2\2\u026c\u026d\7"+
|
||||||
"\7u\2\2\u026d\u026e\7w\2\2\u026e\u026f\7d\2\2\u026f\u00b2\3\2\2\2\u0270"+
|
"u\2\2\u026d\u026e\7o\2\2\u026e\u026f\7u\2\2\u026f\u0270\7w\2\2\u0270\u0271"+
|
||||||
"\u0271\7e\2\2\u0271\u0272\7n\2\2\u0272\u0273\7q\2\2\u0273\u0274\7d\2\2"+
|
"\7d\2\2\u0271\u00b4\3\2\2\2\u0272\u0273\7e\2\2\u0273\u0274\7n\2\2\u0274"+
|
||||||
"\u0274\u0275\7d\2\2\u0275\u0276\7g\2\2\u0276\u0277\7t\2\2\u0277\u0278"+
|
"\u0275\7q\2\2\u0275\u0276\7d\2\2\u0276\u0277\7d\2\2\u0277\u0278\7g\2\2"+
|
||||||
"\7u\2\2\u0278\u00b4\3\2\2\2\u0279\u027a\7B\2\2\u027a\u00b6\3\2\2\2\u027b"+
|
"\u0278\u0279\7t\2\2\u0279\u027a\7u\2\2\u027a\u00b6\3\2\2\2\u027b\u027c"+
|
||||||
"\u027c\7k\2\2\u027c\u027d\7h\2\2\u027d\u00b8\3\2\2\2\u027e\u027f\7g\2"+
|
"\7k\2\2\u027c\u027d\7h\2\2\u027d\u00b8\3\2\2\2\u027e\u027f\7g\2\2\u027f"+
|
||||||
"\2\u027f\u0280\7n\2\2\u0280\u0281\7u\2\2\u0281\u0282\7g\2\2\u0282\u00ba"+
|
"\u0280\7n\2\2\u0280\u0281\7u\2\2\u0281\u0282\7g\2\2\u0282\u00ba\3\2\2"+
|
||||||
"\3\2\2\2\u0283\u0284\7k\2\2\u0284\u0285\7h\2\2\u0285\u0286\7a\2\2\u0286"+
|
"\2\u0283\u0284\7k\2\2\u0284\u0285\7h\2\2\u0285\u0286\7a\2\2\u0286\u0287"+
|
||||||
"\u0287\7e\2\2\u0287\u0288\7u\2\2\u0288\u00bc\3\2\2\2\u0289\u028a\7k\2"+
|
"\7e\2\2\u0287\u0288\7u\2\2\u0288\u00bc\3\2\2\2\u0289\u028a\7k\2\2\u028a"+
|
||||||
"\2\u028a\u028b\7h\2\2\u028b\u028c\7a\2\2\u028c\u028d\7e\2\2\u028d\u028e"+
|
"\u028b\7h\2\2\u028b\u028c\7a\2\2\u028c\u028d\7e\2\2\u028d\u028e\7e\2\2"+
|
||||||
"\7e\2\2\u028e\u00be\3\2\2\2\u028f\u0290\7k\2\2\u0290\u0291\7h\2\2\u0291"+
|
"\u028e\u00be\3\2\2\2\u028f\u0290\7k\2\2\u0290\u0291\7h\2\2\u0291\u0292"+
|
||||||
"\u0292\7a\2\2\u0292\u0293\7g\2\2\u0293\u0294\7s\2\2\u0294\u00c0\3\2\2"+
|
"\7a\2\2\u0292\u0293\7g\2\2\u0293\u0294\7s\2\2\u0294\u00c0\3\2\2\2\u0295"+
|
||||||
"\2\u0295\u0296\7k\2\2\u0296\u0297\7h\2\2\u0297\u0298\7a\2\2\u0298\u0299"+
|
"\u0296\7k\2\2\u0296\u0297\7h\2\2\u0297\u0298\7a\2\2\u0298\u0299\7|\2\2"+
|
||||||
"\7|\2\2\u0299\u00c2\3\2\2\2\u029a\u029b\7k\2\2\u029b\u029c\7h\2\2\u029c"+
|
"\u0299\u00c2\3\2\2\2\u029a\u029b\7k\2\2\u029b\u029c\7h\2\2\u029c\u029d"+
|
||||||
"\u029d\7a\2\2\u029d\u029e\7p\2\2\u029e\u029f\7g\2\2\u029f\u00c4\3\2\2"+
|
"\7a\2\2\u029d\u029e\7p\2\2\u029e\u029f\7g\2\2\u029f\u00c4\3\2\2\2\u02a0"+
|
||||||
"\2\u02a0\u02a1\7k\2\2\u02a1\u02a2\7h\2\2\u02a2\u02a3\7a\2\2\u02a3\u02a4"+
|
"\u02a1\7k\2\2\u02a1\u02a2\7h\2\2\u02a2\u02a3\7a\2\2\u02a3\u02a4\7p\2\2"+
|
||||||
"\7p\2\2\u02a4\u02a5\7|\2\2\u02a5\u00c6\3\2\2\2\u02a6\u02a7\7k\2\2\u02a7"+
|
"\u02a4\u02a5\7|\2\2\u02a5\u00c6\3\2\2\2\u02a6\u02a7\7k\2\2\u02a7\u02a8"+
|
||||||
"\u02a8\7h\2\2\u02a8\u02a9\7a\2\2\u02a9\u02aa\7r\2\2\u02aa\u02ab\7n\2\2"+
|
"\7h\2\2\u02a8\u02a9\7a\2\2\u02a9\u02aa\7r\2\2\u02aa\u02ab\7n\2\2\u02ab"+
|
||||||
"\u02ab\u00c8\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af"+
|
"\u00c8\3\2\2\2\u02ac\u02ad\7k\2\2\u02ad\u02ae\7h\2\2\u02ae\u02af\7a\2"+
|
||||||
"\7a\2\2\u02af\u02b0\7r\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7u\2\2\u02b2"+
|
"\2\u02af\u02b0\7r\2\2\u02b0\u02b1\7q\2\2\u02b1\u02b2\7u\2\2\u02b2\u00ca"+
|
||||||
"\u00ca\3\2\2\2\u02b3\u02b4\7k\2\2\u02b4\u02b5\7h\2\2\u02b5\u02b6\7a\2"+
|
"\3\2\2\2\u02b3\u02b4\7k\2\2\u02b4\u02b5\7h\2\2\u02b5\u02b6\7a\2\2\u02b6"+
|
||||||
"\2\u02b6\u02b7\7o\2\2\u02b7\u02b8\7k\2\2\u02b8\u00cc\3\2\2\2\u02b9\u02ba"+
|
"\u02b7\7o\2\2\u02b7\u02b8\7k\2\2\u02b8\u00cc\3\2\2\2\u02b9\u02ba\7k\2"+
|
||||||
"\7k\2\2\u02ba\u02bb\7h\2\2\u02bb\u02bc\7a\2\2\u02bc\u02bd\7p\2\2\u02bd"+
|
"\2\u02ba\u02bb\7h\2\2\u02bb\u02bc\7a\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be"+
|
||||||
"\u02be\7g\2\2\u02be\u02bf\7i\2\2\u02bf\u00ce\3\2\2\2\u02c0\u02c1\7k\2"+
|
"\7g\2\2\u02be\u02bf\7i\2\2\u02bf\u00ce\3\2\2\2\u02c0\u02c1\7k\2\2\u02c1"+
|
||||||
"\2\u02c1\u02c2\7h\2\2\u02c2\u02c3\7a\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5"+
|
"\u02c2\7h\2\2\u02c2\u02c3\7a\2\2\u02c3\u02c4\7x\2\2\u02c4\u02c5\7u\2\2"+
|
||||||
"\7u\2\2\u02c5\u00d0\3\2\2\2\u02c6\u02c7\7k\2\2\u02c7\u02c8\7h\2\2\u02c8"+
|
"\u02c5\u00d0\3\2\2\2\u02c6\u02c7\7k\2\2\u02c7\u02c8\7h\2\2\u02c8\u02c9"+
|
||||||
"\u02c9\7a\2\2\u02c9\u02ca\7x\2\2\u02ca\u02cb\7e\2\2\u02cb\u00d2\3\2\2"+
|
"\7a\2\2\u02c9\u02ca\7x\2\2\u02ca\u02cb\7e\2\2\u02cb\u00d2\3\2\2\2\u02cc"+
|
||||||
"\2\u02cc\u02cd\7h\2\2\u02cd\u02ce\7q\2\2\u02ce\u02cf\7t\2\2\u02cf\u00d4"+
|
"\u02cd\7h\2\2\u02cd\u02ce\7q\2\2\u02ce\u02cf\7t\2\2\u02cf\u00d4\3\2\2"+
|
||||||
"\3\2\2\2\u02d0\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u00d6\3\2\2\2\u02d3"+
|
"\2\u02d0\u02d1\7k\2\2\u02d1\u02d2\7p\2\2\u02d2\u00d6\3\2\2\2\u02d3\u02d4"+
|
||||||
"\u02d4\7y\2\2\u02d4\u02d5\7j\2\2\u02d5\u02d6\7k\2\2\u02d6\u02d7\7n\2\2"+
|
"\7y\2\2\u02d4\u02d5\7j\2\2\u02d5\u02d6\7k\2\2\u02d6\u02d7\7n\2\2\u02d7"+
|
||||||
"\u02d7\u02d8\7g\2\2\u02d8\u00d8\3\2\2\2\u02d9\u02da\7t\2\2\u02da\u02db"+
|
"\u02d8\7g\2\2\u02d8\u00d8\3\2\2\2\u02d9\u02da\7t\2\2\u02da\u02db\7g\2"+
|
||||||
"\7g\2\2\u02db\u02dc\7r\2\2\u02dc\u02dd\7g\2\2\u02dd\u02de\7c\2\2\u02de"+
|
"\2\u02db\u02dc\7r\2\2\u02dc\u02dd\7g\2\2\u02dd\u02de\7c\2\2\u02de\u02df"+
|
||||||
"\u02df\7v\2\2\u02df\u00da\3\2\2\2\u02e0\u02e1\7w\2\2\u02e1\u02e2\7p\2"+
|
"\7v\2\2\u02df\u00da\3\2\2\2\u02e0\u02e1\7w\2\2\u02e1\u02e2\7p\2\2\u02e2"+
|
||||||
"\2\u02e2\u02e3\7v\2\2\u02e3\u02e4\7k\2\2\u02e4\u02e5\7n\2\2\u02e5\u00dc"+
|
"\u02e3\7v\2\2\u02e3\u02e4\7k\2\2\u02e4\u02e5\7n\2\2\u02e5\u00dc\3\2\2"+
|
||||||
"\3\2\2\2\u02e6\u02ea\t\2\2\2\u02e7\u02e9\t\3\2\2\u02e8\u02e7\3\2\2\2\u02e9"+
|
"\2\u02e6\u02ea\t\2\2\2\u02e7\u02e9\t\3\2\2\u02e8\u02e7\3\2\2\2\u02e9\u02ec"+
|
||||||
"\u02ec\3\2\2\2\u02ea\u02e8\3\2\2\2\u02ea\u02eb\3\2\2\2\u02eb\u02ed\3\2"+
|
"\3\2\2\2\u02ea\u02e8\3\2\2\2\u02ea\u02eb\3\2\2\2\u02eb\u02ed\3\2\2\2\u02ec"+
|
||||||
"\2\2\u02ec\u02ea\3\2\2\2\u02ed\u02ee\5\u00dfp\2\u02ee\u02ef\3\2\2\2\u02ef"+
|
"\u02ea\3\2\2\2\u02ed\u02ee\5\u00dfp\2\u02ee\u02ef\3\2\2\2\u02ef\u02f0"+
|
||||||
"\u02f0\bo\2\2\u02f0\u00de\3\2\2\2\u02f1\u02f5\7=\2\2\u02f2\u02f4\n\2\2"+
|
"\bo\2\2\u02f0\u00de\3\2\2\2\u02f1\u02f5\7=\2\2\u02f2\u02f4\n\2\2\2\u02f3"+
|
||||||
"\2\u02f3\u02f2\3\2\2\2\u02f4\u02f7\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f5\u02f6"+
|
"\u02f2\3\2\2\2\u02f4\u02f7\3\2\2\2\u02f5\u02f3\3\2\2\2\u02f5\u02f6\3\2"+
|
||||||
"\3\2\2\2\u02f6\u02f8\3\2\2\2\u02f7\u02f5\3\2\2\2\u02f8\u02f9\bp\2\2\u02f9"+
|
"\2\2\u02f6\u02f8\3\2\2\2\u02f7\u02f5\3\2\2\2\u02f8\u02f9\bp\2\2\u02f9"+
|
||||||
"\u00e0\3\2\2\2\u02fa\u02fb\t\3\2\2\u02fb\u02fc\3\2\2\2\u02fc\u02fd\bq"+
|
"\u00e0\3\2\2\2\u02fa\u02fb\t\3\2\2\u02fb\u02fc\3\2\2\2\u02fc\u02fd\bq"+
|
||||||
"\3\2\u02fd\u00e2\3\2\2\2\u02fe\u0300\t\2\2\2\u02ff\u02fe\3\2\2\2\u0300"+
|
"\3\2\u02fd\u00e2\3\2\2\2\u02fe\u0300\t\2\2\2\u02ff\u02fe\3\2\2\2\u0300"+
|
||||||
"\u0301\3\2\2\2\u0301\u02ff\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u00e4\3\2"+
|
"\u0301\3\2\2\2\u0301\u02ff\3\2\2\2\u0301\u0302\3\2\2\2\u0302\u00e4\3\2"+
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -277,6 +277,11 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
val address = ins.arg!!.integerValue()
|
val address = ins.arg!!.integerValue()
|
||||||
evalstack.push(Value(DataType.FLOAT, mem.getFloat(address)))
|
evalstack.push(Value(DataType.FLOAT, mem.getFloat(address)))
|
||||||
}
|
}
|
||||||
|
Opcode.PUSH_MEMREAD -> {
|
||||||
|
val address = evalstack.pop()
|
||||||
|
checkDt(address, DataType.UWORD)
|
||||||
|
TODO("push_memread from $address")
|
||||||
|
}
|
||||||
Opcode.DISCARD_BYTE -> {
|
Opcode.DISCARD_BYTE -> {
|
||||||
val value = evalstack.pop()
|
val value = evalstack.pop()
|
||||||
checkDt(value, DataType.UBYTE)
|
checkDt(value, DataType.UBYTE)
|
||||||
@ -313,6 +318,13 @@ class StackVm(private var traceOutputFile: String?) {
|
|||||||
val address = ins.arg!!.integerValue()
|
val address = ins.arg!!.integerValue()
|
||||||
mem.setFloat(address, value.numericValue().toDouble())
|
mem.setFloat(address, value.numericValue().toDouble())
|
||||||
}
|
}
|
||||||
|
Opcode.POP_MEMWRITE -> {
|
||||||
|
val address = evalstack.pop()
|
||||||
|
checkDt(address, DataType.UWORD)
|
||||||
|
val value = evalstack.pop()
|
||||||
|
checkDt(value, DataType.UBYTE)
|
||||||
|
TODO("pop_memwrite $value to $address")
|
||||||
|
}
|
||||||
Opcode.ADD_UB -> {
|
Opcode.ADD_UB -> {
|
||||||
val (top, second) = evalstack.pop2()
|
val (top, second) = evalstack.pop2()
|
||||||
checkDt(top, DataType.UBYTE)
|
checkDt(top, DataType.UBYTE)
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/build" />
|
<excludeFolder url="file://$MODULE_DIR$/build" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="jdk" jdkName="Python 3.7" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -291,6 +291,24 @@ are banked in (and your code imports the ``c64lib.p8``)
|
|||||||
The largest 5-byte MFLPT float that can be stored is: **1.7014118345e+38** (negative: **-1.7014118345e+38**)
|
The largest 5-byte MFLPT float that can be stored is: **1.7014118345e+38** (negative: **-1.7014118345e+38**)
|
||||||
|
|
||||||
|
|
||||||
|
Converting types into other types
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Sometimes you need an unsigned word where you have an unsigned byte, or you need some other type conversion.
|
||||||
|
Many type conversions are possible by just writing ``as <type>`` at the end of an expression::
|
||||||
|
|
||||||
|
uword uw = $ea31
|
||||||
|
ubyte ub = uw as ubyte ; ub will be $31, identical to lsb(uw)
|
||||||
|
float f = uw as float ; f will be 59953, but this conversion can be omitted in this case
|
||||||
|
word w = uw as word ; w will be -5583 (simply reinterpret $ea31 as 2-complement negative number)
|
||||||
|
f = 56.777
|
||||||
|
ub = f as ubyte ; ub will be 56
|
||||||
|
|
||||||
|
Sometimes it is a straight 'type cast' where the value is simply interpreted as being of the other type,
|
||||||
|
sometimes an actual value conversion is done to convert it into the targe type.
|
||||||
|
Try to avoid type conversions as much as possible.
|
||||||
|
|
||||||
|
|
||||||
Initial values across multiple runs of the program
|
Initial values across multiple runs of the program
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -305,21 +323,6 @@ expected when the program is restarted.
|
|||||||
(This is an optimization choice to avoid having to store two copies of every string and array)
|
(This is an optimization choice to avoid having to store two copies of every string and array)
|
||||||
|
|
||||||
|
|
||||||
Indirect addressing and address-of
|
|
||||||
----------------------------------
|
|
||||||
|
|
||||||
The ``#`` operator is used to take the address of the symbol following it.
|
|
||||||
It can be used for example to work with the *address* of a memory mapped variable rather than
|
|
||||||
the value it holds. You could take the address of a string as well, but that is redundant:
|
|
||||||
the compiler already treats those as a value that you manipulate via its address.
|
|
||||||
For most other types this prefix is not supported and will result in a compilation error.
|
|
||||||
The resulting value is simply a 16 bit word.
|
|
||||||
|
|
||||||
.. todo::
|
|
||||||
This is not yet implemented.
|
|
||||||
Indirect addressing, Indirect addressing in jumps (jmp/jsr indirect)
|
|
||||||
|
|
||||||
|
|
||||||
Loops
|
Loops
|
||||||
-----
|
-----
|
||||||
|
|
||||||
@ -411,6 +414,19 @@ a fixed amount of memory which will not change.
|
|||||||
that there is a loss of precision. You can use builtin functions such as ``round`` and ``lsb`` to convert
|
that there is a loss of precision. You can use builtin functions such as ``round`` and ``lsb`` to convert
|
||||||
to a smaller datatype, or revert to integer arithmetic.
|
to a smaller datatype, or revert to integer arithmetic.
|
||||||
|
|
||||||
|
Direct access to memory locations
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Normally memory locations are accessed by a *memory mapped* name, such as ``c64.BGCOL0`` that is defined
|
||||||
|
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 = @$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
|
Expressions
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
@ -280,6 +280,12 @@ of something with an operand starting with 1 or 0, you'll have to add a space in
|
|||||||
**@todo pointers/addresses? (as opposed to normal WORDs)**
|
**@todo pointers/addresses? (as opposed to normal WORDs)**
|
||||||
|
|
||||||
|
|
||||||
|
Data type conversion
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Many type conversions are possible by just writing ``as <type>`` at the end of an expression,
|
||||||
|
for example ``ubyte ub = floatvalue as ubyte`` will convert the floating point value to an unsigned byte.
|
||||||
|
|
||||||
|
|
||||||
Memory mapped variables
|
Memory mapped variables
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
@ -290,6 +296,16 @@ should be the *memory address* where the value is located::
|
|||||||
memory byte BORDER = $d020
|
memory byte BORDER = $d020
|
||||||
|
|
||||||
|
|
||||||
|
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::
|
||||||
|
|
||||||
|
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
|
Constants
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
|
@ -30,6 +30,15 @@
|
|||||||
const uword Screen = $0400 ; default character screen matrix @todo matrix/array? needs to support array size > 255
|
const uword Screen = $0400 ; default character screen matrix @todo matrix/array? needs to support array size > 255
|
||||||
const uword Colors = $d800 ; character screen colors @todo matrix/array? needs to support array size > 255
|
const uword Colors = $d800 ; character screen colors @todo matrix/array? needs to support array size > 255
|
||||||
|
|
||||||
|
memory ubyte SPRPTR0 = 2040 ; default sprite pointers (store address of sprite / 64)
|
||||||
|
memory ubyte SPRPTR1 = 2041
|
||||||
|
memory ubyte SPRPTR2 = 2042
|
||||||
|
memory ubyte SPRPTR3 = 2043
|
||||||
|
memory ubyte SPRPTR4 = 2044
|
||||||
|
memory ubyte SPRPTR5 = 2045
|
||||||
|
memory ubyte SPRPTR6 = 2046
|
||||||
|
memory ubyte SPRPTR7 = 2047
|
||||||
|
|
||||||
|
|
||||||
; ---- VIC-II registers ----
|
; ---- VIC-II registers ----
|
||||||
|
|
||||||
|
@ -476,6 +476,7 @@ abs_f .proc
|
|||||||
|
|
||||||
add_w .proc
|
add_w .proc
|
||||||
; -- push word+word / uword+uword
|
; -- push word+word / uword+uword
|
||||||
|
; @todo INLINE THIS
|
||||||
inx
|
inx
|
||||||
clc
|
clc
|
||||||
lda ESTACK_LO,x
|
lda ESTACK_LO,x
|
||||||
@ -489,6 +490,7 @@ add_w .proc
|
|||||||
|
|
||||||
sub_w .proc
|
sub_w .proc
|
||||||
; -- push word-word
|
; -- push word-word
|
||||||
|
; @todo INLINE THIS
|
||||||
inx
|
inx
|
||||||
sec
|
sec
|
||||||
lda ESTACK_LO+1,x
|
lda ESTACK_LO+1,x
|
||||||
|
Loading…
Reference in New Issue
Block a user