mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
asmassignment can now use arbitrary source symbols; optimized byte-word sign extesion with this to not use stack anymore
This commit is contained in:
parent
73524e01a6
commit
c15fd75df7
@ -220,7 +220,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir:
|
||||
programAst.processAstBeforeAsmGeneration(errors)
|
||||
errors.handle()
|
||||
|
||||
// printAst(programAst)
|
||||
printAst(programAst) // TODO
|
||||
|
||||
CompilationTarget.instance.machine.initializeZeropage(compilerOptions)
|
||||
val assembly = CompilationTarget.instance.asmGenerator(
|
||||
|
@ -194,11 +194,10 @@ internal class AsmGen(private val program: Program,
|
||||
}
|
||||
|
||||
private fun assignInitialValueToVar(decl: VarDecl, variableName: List<String>) {
|
||||
val variable = IdentifierReference(variableName, decl.position)
|
||||
variable.linkParents(decl.parent)
|
||||
val asmName = asmVariableName(variableName)
|
||||
val asgn = AsmAssignment(
|
||||
AsmAssignSource.fromAstSource(decl.value!!, program),
|
||||
AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, decl.datatype, decl.definingSubroutine(), variable = variable),
|
||||
AsmAssignSource.fromAstSource(decl.value!!, program, this),
|
||||
AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, decl.datatype, decl.definingSubroutine(), variableAsmName = asmName),
|
||||
false, decl.position)
|
||||
assignmentAsmGen.translateNormalAssignment(asgn)
|
||||
}
|
||||
@ -496,6 +495,12 @@ internal class AsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
internal fun asmSymbolName(name: String) = fixNameSymbols(name)
|
||||
internal fun asmVariableName(name: String) = fixNameSymbols(name)
|
||||
internal fun asmSymbolName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
||||
internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
||||
|
||||
|
||||
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): Pair<Boolean, String> {
|
||||
// returns if the pointer is already on the ZP itself or not (in the latter case SCRATCH_W1 is used as intermediary)
|
||||
val sourceName = asmVariableName(pointervar)
|
||||
@ -538,8 +543,7 @@ internal class AsmGen(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
internal fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
||||
|
||||
private fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
||||
|
||||
private val saveRegisterLabels = Stack<String>()
|
||||
|
||||
|
@ -498,7 +498,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
// all other types of swap() calls are done via the evaluation stack
|
||||
fun targetFromExpr(expr: Expression, datatype: DataType): AsmAssignTarget {
|
||||
return when (expr) {
|
||||
is IdentifierReference -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, datatype, expr.definingSubroutine(), variable=expr)
|
||||
is IdentifierReference -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, datatype, expr.definingSubroutine(), variableAsmName = asmgen.asmVariableName(expr))
|
||||
is ArrayIndexedExpression -> AsmAssignTarget(TargetStorageKind.ARRAY, program, asmgen, datatype, expr.definingSubroutine(), array = expr)
|
||||
is DirectMemoryRead -> AsmAssignTarget(TargetStorageKind.MEMORY, program, asmgen, datatype, expr.definingSubroutine(), memory = DirectMemoryWrite(expr.addressExpression, expr.position))
|
||||
else -> throw AssemblyError("invalid expression object $expr")
|
||||
@ -509,12 +509,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.translateExpression(second)
|
||||
val datatype = first.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
val assignFirst = AsmAssignment(
|
||||
AsmAssignSource(SourceStorageKind.STACK, program, datatype),
|
||||
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, datatype),
|
||||
targetFromExpr(first, datatype),
|
||||
false, first.position
|
||||
)
|
||||
val assignSecond = AsmAssignment(
|
||||
AsmAssignSource(SourceStorageKind.STACK, program, datatype),
|
||||
AsmAssignSource(SourceStorageKind.STACK, program, asmgen, datatype),
|
||||
targetFromExpr(second, datatype),
|
||||
false, second.position
|
||||
)
|
||||
|
@ -610,8 +610,8 @@ $endLabel""")
|
||||
}
|
||||
|
||||
private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) {
|
||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine(), variable=stmt.loopVar)
|
||||
val src = AsmAssignSource.fromAstSource(range.from, program).adjustSignedUnsigned(target)
|
||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), stmt.definingSubroutine(), variableAsmName=asmgen.asmVariableName(stmt.loopVar))
|
||||
val src = AsmAssignSource.fromAstSource(range.from, program, asmgen).adjustSignedUnsigned(target)
|
||||
val assign = AsmAssignment(src, target, false, range.position)
|
||||
asmgen.translateNormalAssignment(assign)
|
||||
}
|
||||
|
@ -155,11 +155,9 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
if(!isArgumentTypeCompatible(valueDt, parameter.value.type))
|
||||
throw AssemblyError("argument type incompatible")
|
||||
|
||||
val scopedParamVar = (sub.scopedname+"."+parameter.value.name).split(".")
|
||||
val identifier = IdentifierReference(scopedParamVar, sub.position)
|
||||
identifier.linkParents(value.parent)
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, parameter.value.type, sub, variable = identifier)
|
||||
val source = AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(tgt)
|
||||
val varName = asmgen.asmVariableName(sub.scopedname+"."+parameter.value.name)
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, parameter.value.type, sub, variableAsmName = varName)
|
||||
val source = AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(tgt)
|
||||
val asgn = AsmAssignment(source, tgt, false, Position.DUMMY)
|
||||
asmgen.translateNormalAssignment(asgn)
|
||||
}
|
||||
@ -234,23 +232,25 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
||||
// via register or register pair
|
||||
val target = AsmAssignTarget.fromRegisters(register!!, sub, program, asmgen)
|
||||
if(requiredDt largerThan valueDt) {
|
||||
// TODO we need to sign extend the source, do this via stack (slow)
|
||||
println("warning: slow stack evaluation used for sign-extend: into $requiredDt at ${value.position}")
|
||||
asmgen.translateExpression(value)
|
||||
asmgen.signExtendStackLsb(valueDt)
|
||||
val src = AsmAssignSource(SourceStorageKind.STACK, program, valueDt)
|
||||
// we need to sign extend the source, do this via temporary word variable
|
||||
val scratchVar = asmgen.asmVariableName("P8ZP_SCRATCH_W1")
|
||||
val scratchTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, DataType.UBYTE, sub, scratchVar)
|
||||
val source = AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||
asmgen.translateNormalAssignment(AsmAssignment(source, scratchTarget, false, value.position))
|
||||
asmgen.signExtendVariableLsb(scratchVar, valueDt)
|
||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, DataType.UWORD, scratchVar)
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||
}
|
||||
else {
|
||||
val src = if(valueDt in PassByReferenceDatatypes) {
|
||||
if(value is IdentifierReference) {
|
||||
val addr = AddressOf(value, Position.DUMMY)
|
||||
AsmAssignSource.fromAstSource(addr, program).adjustSignedUnsigned(target)
|
||||
AsmAssignSource.fromAstSource(addr, program, asmgen).adjustSignedUnsigned(target)
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(target)
|
||||
AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target)
|
||||
}
|
||||
} else {
|
||||
AsmAssignSource.fromAstSource(value, program).adjustSignedUnsigned(target)
|
||||
AsmAssignSource.fromAstSource(value, program, asmgen).adjustSignedUnsigned(target)
|
||||
}
|
||||
asmgen.translateNormalAssignment(AsmAssignment(src, target, false, Position.DUMMY))
|
||||
}
|
||||
|
@ -31,11 +31,11 @@ internal enum class SourceStorageKind {
|
||||
}
|
||||
|
||||
internal class AsmAssignTarget(val kind: TargetStorageKind,
|
||||
program: Program,
|
||||
asmgen: AsmGen,
|
||||
private val program: Program,
|
||||
private val asmgen: AsmGen,
|
||||
val datatype: DataType,
|
||||
val scope: Subroutine?,
|
||||
val variable: IdentifierReference? = null,
|
||||
private val variableAsmName: String? = null,
|
||||
val array: ArrayIndexedExpression? = null,
|
||||
val memory: DirectMemoryWrite? = null,
|
||||
val register: RegisterOrPair? = null,
|
||||
@ -44,19 +44,15 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
|
||||
{
|
||||
val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0}
|
||||
val constArrayIndexValue by lazy { array?.arrayspec?.constIndex() }
|
||||
val vardecl by lazy { variable!!.targetVarDecl(program.namespace)!! }
|
||||
val asmVarname by lazy {
|
||||
if(variable!=null)
|
||||
asmgen.asmVariableName(variable)
|
||||
val asmVarname: String
|
||||
get() = if(array==null)
|
||||
variableAsmName!!
|
||||
else
|
||||
asmgen.asmVariableName(array!!.identifier)
|
||||
}
|
||||
asmgen.asmVariableName(array.identifier)
|
||||
|
||||
lateinit var origAssign: AsmAssignment
|
||||
|
||||
init {
|
||||
if(variable!=null && vardecl.type == VarDeclType.CONST)
|
||||
throw AssemblyError("can't assign to a constant")
|
||||
if(register!=null && datatype !in IntegerDatatypes)
|
||||
throw AssemblyError("register must be integer type")
|
||||
}
|
||||
@ -65,7 +61,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
|
||||
fun fromAstAssignment(assign: Assignment, program: Program, asmgen: AsmGen): AsmAssignTarget = with(assign.target) {
|
||||
val dt = inferType(program, assign).typeOrElse(DataType.STRUCT)
|
||||
when {
|
||||
identifier != null -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, assign.definingSubroutine(), variable=identifier, origAstTarget = this)
|
||||
identifier != null -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, assign.definingSubroutine(), variableAsmName = asmgen.asmVariableName(identifier!!), origAstTarget = this)
|
||||
arrayindexed != null -> AsmAssignTarget(TargetStorageKind.ARRAY, program, asmgen, dt, assign.definingSubroutine(), array = arrayindexed, origAstTarget = this)
|
||||
memoryAddress != null -> AsmAssignTarget(TargetStorageKind.MEMORY, program, asmgen, dt, assign.definingSubroutine(), memory = memoryAddress, origAstTarget = this)
|
||||
else -> throw AssemblyError("weird target")
|
||||
@ -86,8 +82,9 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
|
||||
|
||||
internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
private val program: Program,
|
||||
private val asmgen: AsmGen,
|
||||
val datatype: DataType,
|
||||
val variable: IdentifierReference? = null,
|
||||
private val variableAsmName: String? = null,
|
||||
val array: ArrayIndexedExpression? = null,
|
||||
val memory: DirectMemoryRead? = null,
|
||||
val register: CpuRegister? = null,
|
||||
@ -97,28 +94,33 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
{
|
||||
val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0}
|
||||
val constArrayIndexValue by lazy { array?.arrayspec?.constIndex() }
|
||||
val vardecl by lazy { variable?.targetVarDecl(program.namespace)!! }
|
||||
|
||||
val asmVarname: String
|
||||
get() = if(array==null)
|
||||
variableAsmName!!
|
||||
else
|
||||
asmgen.asmVariableName(array.identifier)
|
||||
|
||||
companion object {
|
||||
fun fromAstSource(value: Expression, program: Program): AsmAssignSource {
|
||||
fun fromAstSource(value: Expression, program: Program, asmgen: AsmGen): AsmAssignSource {
|
||||
val cv = value.constValue(program)
|
||||
if(cv!=null)
|
||||
return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, cv.type, number = cv)
|
||||
return AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, cv.type, number = cv)
|
||||
|
||||
return when(value) {
|
||||
is NumericLiteralValue -> AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, value.type, number = cv)
|
||||
is NumericLiteralValue -> AsmAssignSource(SourceStorageKind.LITERALNUMBER, program, asmgen, value.type, number = cv)
|
||||
is StringLiteralValue -> throw AssemblyError("string literal value should not occur anymore for asm generation")
|
||||
is ArrayLiteralValue -> throw AssemblyError("array literal value should not occur anymore for asm generation")
|
||||
is IdentifierReference -> {
|
||||
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
AsmAssignSource(SourceStorageKind.VARIABLE, program, dt, variable = value)
|
||||
AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, dt, variableAsmName = asmgen.asmVariableName(value))
|
||||
}
|
||||
is DirectMemoryRead -> {
|
||||
AsmAssignSource(SourceStorageKind.MEMORY, program, DataType.UBYTE, memory = value)
|
||||
AsmAssignSource(SourceStorageKind.MEMORY, program, asmgen, DataType.UBYTE, memory = value)
|
||||
}
|
||||
is ArrayIndexedExpression -> {
|
||||
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
AsmAssignSource(SourceStorageKind.ARRAY, program, dt, array = value)
|
||||
AsmAssignSource(SourceStorageKind.ARRAY, program, asmgen, dt, array = value)
|
||||
}
|
||||
else -> {
|
||||
if(value is FunctionCall) {
|
||||
@ -138,7 +140,7 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
RegisterOrPair.AY,
|
||||
RegisterOrPair.XY -> DataType.UWORD
|
||||
}
|
||||
return AsmAssignSource(SourceStorageKind.EXPRESSION, program, dt, expression = value)
|
||||
return AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, dt, expression = value)
|
||||
}
|
||||
else -> throw AssemblyError("can't translate multiple return values in assignment")
|
||||
}
|
||||
@ -146,24 +148,14 @@ internal class AsmAssignSource(val kind: SourceStorageKind,
|
||||
}
|
||||
|
||||
val dt = value.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
return AsmAssignSource(SourceStorageKind.EXPRESSION, program, dt, expression = value)
|
||||
return AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, dt, expression = value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAstValue(): Expression = when(kind) {
|
||||
SourceStorageKind.LITERALNUMBER -> number!!
|
||||
SourceStorageKind.VARIABLE -> variable!!
|
||||
SourceStorageKind.ARRAY -> array!!
|
||||
SourceStorageKind.MEMORY -> memory!!
|
||||
SourceStorageKind.EXPRESSION -> expression!!
|
||||
SourceStorageKind.REGISTER -> throw AssemblyError("cannot get a register source as Ast node")
|
||||
SourceStorageKind.STACK -> throw AssemblyError("cannot get a stack source as Ast node")
|
||||
}
|
||||
|
||||
fun withAdjustedDt(newType: DataType) =
|
||||
AsmAssignSource(kind, program, newType, variable, array, memory, register, number, expression)
|
||||
AsmAssignSource(kind, program, asmgen, newType, variableAsmName, array, memory, register, number, expression)
|
||||
|
||||
fun adjustSignedUnsigned(target: AsmAssignTarget): AsmAssignSource {
|
||||
// allow some signed/unsigned relaxations
|
||||
|
@ -18,7 +18,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
|
||||
fun translate(assignment: Assignment) {
|
||||
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
||||
val source = AsmAssignSource.fromAstSource(assignment.value, program).adjustSignedUnsigned(target)
|
||||
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
|
||||
|
||||
val assign = AsmAssignment(source, target, assignment.isAugmentable, assignment.position)
|
||||
target.origAssign = assign
|
||||
@ -43,13 +43,16 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
SourceStorageKind.VARIABLE -> {
|
||||
// simple case: assign from another variable
|
||||
val variable = assign.source.variable!!
|
||||
val variable = assign.source.asmVarname!!
|
||||
when (assign.target.datatype) {
|
||||
DataType.UBYTE, DataType.BYTE -> assignVariableByte(assign.target, variable)
|
||||
DataType.UWORD, DataType.WORD -> assignVariableWord(assign.target, variable)
|
||||
DataType.FLOAT -> assignVariableFloat(assign.target, variable)
|
||||
DataType.STR -> assignVariableString(assign.target, variable)
|
||||
in PassByReferenceDatatypes -> assignAddressOf(assign.target, variable)
|
||||
in PassByReferenceDatatypes -> {
|
||||
// TODO what about when the name is a struct? name.firstStructVarName(program.namespace)
|
||||
assignAddressOf(assign.target, variable)
|
||||
}
|
||||
else -> throw AssemblyError("unsupported assignment target type ${assign.target.datatype}")
|
||||
}
|
||||
}
|
||||
@ -117,7 +120,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
SourceStorageKind.EXPRESSION -> {
|
||||
val value = assign.source.expression!!
|
||||
when(value) {
|
||||
is AddressOf -> assignAddressOf(assign.target, value.identifier)
|
||||
is AddressOf -> {
|
||||
val sourceName = value.identifier.firstStructVarName(program.namespace) ?: asmgen.asmVariableName(value.identifier)
|
||||
assignAddressOf(assign.target, sourceName)
|
||||
}
|
||||
is NumericLiteralValue -> throw AssemblyError("source kind should have been literalnumber")
|
||||
is IdentifierReference -> throw AssemblyError("source kind should have been variable")
|
||||
is ArrayIndexedExpression -> throw AssemblyError("source kind should have been array")
|
||||
@ -349,9 +355,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignAddressOf(target: AsmAssignTarget, name: IdentifierReference) {
|
||||
val sourceName = name.firstStructVarName(program.namespace) ?: asmgen.fixNameSymbols(name.nameInSource.joinToString("."))
|
||||
|
||||
private fun assignAddressOf(target: AsmAssignTarget, sourceName: String) {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.out("""
|
||||
@ -376,19 +380,17 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
TargetStorageKind.STACK -> {
|
||||
val srcname = asmgen.asmVariableName(name)
|
||||
asmgen.out("""
|
||||
lda #<$srcname
|
||||
lda #<$sourceName
|
||||
sta P8ESTACK_LO,x
|
||||
lda #>$srcname
|
||||
lda #>$sourceName
|
||||
sta P8ESTACK_HI,x
|
||||
dex""")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignVariableString(target: AsmAssignTarget, variable: IdentifierReference) {
|
||||
val sourceName = asmgen.asmVariableName(variable)
|
||||
private fun assignVariableString(target: AsmAssignTarget, sourceName: String) {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
when(target.datatype) {
|
||||
@ -425,8 +427,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignVariableWord(target: AsmAssignTarget, variable: IdentifierReference) {
|
||||
val sourceName = asmgen.asmVariableName(variable)
|
||||
private fun assignVariableWord(target: AsmAssignTarget, sourceName: String) {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.out("""
|
||||
@ -529,8 +530,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignVariableFloat(target: AsmAssignTarget, variable: IdentifierReference) {
|
||||
val sourceName = asmgen.asmVariableName(variable)
|
||||
private fun assignVariableFloat(target: AsmAssignTarget, sourceName: String) {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.out("""
|
||||
@ -564,8 +564,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
||||
}
|
||||
}
|
||||
|
||||
private fun assignVariableByte(target: AsmAssignTarget, variable: IdentifierReference) {
|
||||
val sourceName = asmgen.asmVariableName(variable)
|
||||
private fun assignVariableByte(target: AsmAssignTarget, sourceName: String) {
|
||||
when(target.kind) {
|
||||
TargetStorageKind.VARIABLE -> {
|
||||
asmgen.out("""
|
||||
|
@ -7,16 +7,17 @@
|
||||
; even in Vice in warp mode (700% speed on my machine) it's slow, but you can see progress
|
||||
|
||||
; Note: this program is compatible with C64 and CX16.
|
||||
; TODO why is there a weird black column on the right part on CX16?
|
||||
|
||||
main {
|
||||
const ubyte width = 255
|
||||
const uword width = 320
|
||||
const ubyte height = 200
|
||||
const ubyte max_iter = 16
|
||||
|
||||
sub start() {
|
||||
graphics.enable_bitmap_mode()
|
||||
|
||||
ubyte pixelx
|
||||
uword pixelx
|
||||
ubyte pixely
|
||||
|
||||
for pixely in 0 to height-1 {
|
||||
|
@ -7,29 +7,9 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
print_10s(1)
|
||||
txt.chrout('\n')
|
||||
print_10s(123)
|
||||
txt.chrout('\n')
|
||||
print_10s(54321)
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
|
||||
ubyte ww
|
||||
ww=1
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
ww=123
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
ww=255
|
||||
print_10s(ww)
|
||||
txt.chrout('\n')
|
||||
|
||||
txt.print("\nCommands are:\n"+
|
||||
"buy jump inf cash\n" +
|
||||
"sell teleport market hold\n" +
|
||||
"fuel galhyp local quit\n")
|
||||
ubyte xx
|
||||
ubyte yy
|
||||
regx(xx)
|
||||
|
||||
; str name = "irmen de jong"
|
||||
; uword strptr = &name
|
||||
@ -49,6 +29,14 @@ main {
|
||||
|
||||
}
|
||||
|
||||
asmsub regx(uword value @AX) {
|
||||
%asm {{
|
||||
|
||||
nop
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub print_10s(uword value @AY) clobbers(A, X, Y) {
|
||||
%asm {{
|
||||
jsr conv.uword2decimal
|
||||
|
@ -25,6 +25,8 @@ main {
|
||||
|
||||
repeat {
|
||||
str input = "????????"
|
||||
txt.print("\nCash: ")
|
||||
util.print_10s(ship.cash)
|
||||
txt.print("\nCommand (?=help): ")
|
||||
ubyte num_chars = txt.input_chars(input)
|
||||
txt.chrout('\n')
|
||||
@ -59,19 +61,19 @@ trader {
|
||||
ubyte num_chars
|
||||
|
||||
sub do_jump() {
|
||||
txt.print("\nTODO JUMP\n")
|
||||
txt.print("\nTODO JUMP\n") ; TODO
|
||||
}
|
||||
|
||||
sub do_teleport() {
|
||||
txt.print("\nTODO TELEPORT\n")
|
||||
txt.print("\nTODO TELEPORT\n") ; TODO
|
||||
}
|
||||
|
||||
sub do_buy() {
|
||||
txt.print("\nTODO BUY\n")
|
||||
txt.print("\nTODO BUY\n") ; TODO
|
||||
}
|
||||
|
||||
sub do_sell() {
|
||||
txt.print("\nTODO SELL\n")
|
||||
txt.print("\nTODO SELL\n") ; TODO
|
||||
}
|
||||
|
||||
sub do_fuel() {
|
||||
@ -88,7 +90,7 @@ trader {
|
||||
}
|
||||
|
||||
sub do_hold() {
|
||||
txt.print("\nCheat! TODO adjust cargo hold size\n")
|
||||
txt.print("\nCheat! TODO adjust cargo hold size\n") ; TODO
|
||||
}
|
||||
|
||||
sub do_next_galaxy() {
|
||||
@ -101,7 +103,7 @@ trader {
|
||||
txt.print("\nSystem name (empty=current): ")
|
||||
num_chars = txt.input_chars(input)
|
||||
if num_chars {
|
||||
txt.print("\nTODO INFO\n")
|
||||
txt.print("\nTODO INFO\n") ; TODO
|
||||
} else {
|
||||
planet.display(false)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user