mirror of
https://github.com/irmen/prog8.git
synced 2024-07-24 22:29:15 +00:00
6502 start
This commit is contained in:
parent
b7d8f026f4
commit
b52120139c
@ -16,6 +16,16 @@ sub start() {
|
|||||||
word wv2
|
word wv2
|
||||||
uword uwv2
|
uword uwv2
|
||||||
|
|
||||||
|
X=X
|
||||||
|
X=X
|
||||||
|
Y=Y
|
||||||
|
X=A
|
||||||
|
A=Y
|
||||||
|
A=ubvar
|
||||||
|
AX=XY
|
||||||
|
XY=XY
|
||||||
|
AY=uwvar
|
||||||
|
XY=uwvar
|
||||||
|
|
||||||
bv2 = ub2b(ubvar)
|
bv2 = ub2b(ubvar)
|
||||||
ubv2 = b2ub(bvar)
|
ubv2 = b2ub(bvar)
|
||||||
|
@ -42,6 +42,8 @@ fun main(args: Array<String>) {
|
|||||||
as? Directive)?.args?.single()?.name?.toUpperCase()
|
as? Directive)?.args?.single()?.name?.toUpperCase()
|
||||||
val launcherType = (moduleAst.statements.singleOrNull { it is Directive && it.directive=="%launcher"}
|
val launcherType = (moduleAst.statements.singleOrNull { it is Directive && it.directive=="%launcher"}
|
||||||
as? Directive)?.args?.single()?.name?.toUpperCase()
|
as? Directive)?.args?.single()?.name?.toUpperCase()
|
||||||
|
moduleAst.loadAddress = (moduleAst.statements.singleOrNull { it is Directive && it.directive=="%address"}
|
||||||
|
as? Directive)?.args?.single()?.int ?: 0
|
||||||
val zpoption: String? = (moduleAst.statements.singleOrNull { it is Directive && it.directive=="%zeropage"}
|
val zpoption: String? = (moduleAst.statements.singleOrNull { it is Directive && it.directive=="%zeropage"}
|
||||||
as? Directive)?.args?.single()?.name?.toUpperCase()
|
as? Directive)?.args?.single()?.name?.toUpperCase()
|
||||||
val zpType: ZeropageType =
|
val zpType: ZeropageType =
|
||||||
|
@ -421,6 +421,8 @@ class Module(override val name: String,
|
|||||||
this.parent=parent
|
this.parent=parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var loadAddress: Int = 0 // can be set with the %address directive
|
||||||
|
|
||||||
fun linkParents() {
|
fun linkParents() {
|
||||||
parent = ParentSentinel
|
parent = ParentSentinel
|
||||||
statements.forEach {it.linkParents(this)}
|
statements.forEach {it.linkParents(this)}
|
||||||
|
@ -159,7 +159,7 @@ class Compiler(private val options: CompilationOptions) {
|
|||||||
println("\nCreating stackVM code...")
|
println("\nCreating stackVM code...")
|
||||||
|
|
||||||
val namespace = module.definingScope()
|
val namespace = module.definingScope()
|
||||||
val program = IntermediateProgram(module.name, heap)
|
val program = IntermediateProgram(module.name, module.loadAddress, heap)
|
||||||
|
|
||||||
val translator = StatementTranslator(program, namespace, heap)
|
val translator = StatementTranslator(program, namespace, heap)
|
||||||
translator.process(module)
|
translator.process(module)
|
||||||
@ -178,7 +178,7 @@ private class StatementTranslator(private val prog: IntermediateProgram,
|
|||||||
val continueStmtLabelStack : Stack<String> = Stack()
|
val continueStmtLabelStack : Stack<String> = Stack()
|
||||||
|
|
||||||
override fun process(block: Block): IStatement {
|
override fun process(block: Block): IStatement {
|
||||||
prog.newBlock(block.scopedname, block.address)
|
prog.newBlock(block.scopedname, block.name, block.address)
|
||||||
processVariables(block)
|
processVariables(block)
|
||||||
prog.label(block.scopedname)
|
prog.label(block.scopedname)
|
||||||
prog.line(block.position)
|
prog.line(block.position)
|
||||||
|
@ -9,9 +9,9 @@ import prog8.compiler.HeapValues
|
|||||||
import java.io.PrintStream
|
import java.io.PrintStream
|
||||||
|
|
||||||
|
|
||||||
class IntermediateProgram(val name: String, val heap: HeapValues) {
|
class IntermediateProgram(val name: String, var loadAddress: Int, val heap: HeapValues) {
|
||||||
|
|
||||||
private class ProgramBlock(val scopedname: String, val address: Int?) {
|
class ProgramBlock(val scopedname: String, val shortname: String, var address: Int?) {
|
||||||
val instructions = mutableListOf<Instruction>()
|
val instructions = mutableListOf<Instruction>()
|
||||||
val variables = mutableMapOf<String, Value>()
|
val variables = mutableMapOf<String, Value>()
|
||||||
val labels = mutableMapOf<String, Instruction>()
|
val labels = mutableMapOf<String, Instruction>()
|
||||||
@ -20,10 +20,16 @@ class IntermediateProgram(val name: String, val heap: HeapValues) {
|
|||||||
get() { return variables.size }
|
get() { return variables.size }
|
||||||
val numInstructions: Int
|
val numInstructions: Int
|
||||||
get() { return instructions.filter { it.opcode!= Opcode.LINE }.size }
|
get() { return instructions.filter { it.opcode!= Opcode.LINE }.size }
|
||||||
|
|
||||||
|
fun getIns(idx: Int): Instruction {
|
||||||
|
if(idx>=0 && idx <instructions.size)
|
||||||
|
return instructions[idx]
|
||||||
|
return Instruction(Opcode.NOP)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val blocks = mutableListOf<ProgramBlock>()
|
val blocks = mutableListOf<ProgramBlock>()
|
||||||
private val memory = mutableMapOf<Int, List<Value>>()
|
val memory = mutableMapOf<Int, List<Value>>()
|
||||||
private lateinit var currentBlock: ProgramBlock
|
private lateinit var currentBlock: ProgramBlock
|
||||||
|
|
||||||
val numVariables: Int
|
val numVariables: Int
|
||||||
@ -273,8 +279,8 @@ class IntermediateProgram(val name: String, val heap: HeapValues) {
|
|||||||
currentBlock.instructions.add(Instruction(Opcode.LINE, callLabel = "${position.line} ${position.file}"))
|
currentBlock.instructions.add(Instruction(Opcode.LINE, callLabel = "${position.line} ${position.file}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun newBlock(scopedname: String, address: Int?) {
|
fun newBlock(scopedname: String, shortname: String, address: Int?) {
|
||||||
currentBlock = ProgramBlock(scopedname, address)
|
currentBlock = ProgramBlock(scopedname, shortname, address)
|
||||||
blocks.add(currentBlock)
|
blocks.add(currentBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,15 +1,371 @@
|
|||||||
package prog8.compiler.target.c64
|
package prog8.compiler.target.c64
|
||||||
|
|
||||||
import prog8.compiler.CompilationOptions
|
import prog8.compiler.CompilationOptions
|
||||||
|
import prog8.compiler.LauncherType
|
||||||
|
import prog8.compiler.OutputType
|
||||||
|
import prog8.compiler.intermediate.Instruction
|
||||||
import prog8.compiler.intermediate.IntermediateProgram
|
import prog8.compiler.intermediate.IntermediateProgram
|
||||||
|
import prog8.compiler.intermediate.LabelInstr
|
||||||
|
import prog8.compiler.intermediate.Opcode
|
||||||
|
import prog8.compiler.toHex
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
class AssemblyError(msg: String) : RuntimeException(msg)
|
||||||
|
|
||||||
|
|
||||||
class AsmGen(val options: CompilationOptions) {
|
class AsmGen(val options: CompilationOptions) {
|
||||||
fun compileToAssembly(program: IntermediateProgram): AssemblyProgram {
|
fun compileToAssembly(program: IntermediateProgram): AssemblyProgram {
|
||||||
println("\nGenerating assembly code from intermediate code... ")
|
println("\nGenerating assembly code from intermediate code... ")
|
||||||
// todo generate 6502 assembly
|
// todo generate 6502 assembly
|
||||||
|
val out = File("${program.name}.asm").printWriter()
|
||||||
|
out.use {
|
||||||
|
header(out::println, program)
|
||||||
|
for(block in program.blocks)
|
||||||
|
block2asm(out::println, block)
|
||||||
|
}
|
||||||
|
|
||||||
return AssemblyProgram(program.name)
|
return AssemblyProgram(program.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun header(out: (String)->Unit, program: IntermediateProgram) {
|
||||||
|
val ourName = this.javaClass.name
|
||||||
|
out("; 6502 assembly code for '${program.name}'")
|
||||||
|
out("; generated by $ourName on ${Date()}")
|
||||||
|
out("; assembler syntax is for the 64tasm cross-assembler")
|
||||||
|
out("; output options: output=${options.output} launcher=${options.launcher} zp=${options.zeropage}")
|
||||||
|
out("\n.cpu '6502'\n.enc 'none'\n")
|
||||||
|
|
||||||
|
if(program.loadAddress==0) // fix load address
|
||||||
|
program.loadAddress = if(options.launcher==LauncherType.BASIC) BASIC_LOAD_ADDRESS else RAW_LOAD_ADDRESS
|
||||||
|
|
||||||
|
when {
|
||||||
|
options.launcher == LauncherType.BASIC -> {
|
||||||
|
if (program.loadAddress != 0x0801)
|
||||||
|
throw AssemblyError("BASIC output must have load address $0801")
|
||||||
|
out("; ---- basic program with sys call ----")
|
||||||
|
out("* = ${program.loadAddress.toHex()}")
|
||||||
|
val year = Calendar.getInstance().get(Calendar.YEAR)
|
||||||
|
out("\t.word (+), $year")
|
||||||
|
out("\t.null $9e, format(' %d ', _prog8_entrypoint), $3a, $8f, ' prog8 by idj'")
|
||||||
|
out("+\t.word 0")
|
||||||
|
out("_prog8_entrypoint\t; assembly code starts here\n")
|
||||||
|
}
|
||||||
|
options.output == OutputType.PRG -> {
|
||||||
|
out("; ---- program without sys call ----")
|
||||||
|
out("* = ${program.loadAddress.toHex()}\n")
|
||||||
|
}
|
||||||
|
options.output == OutputType.RAW -> {
|
||||||
|
out("; ---- raw assembler program ----")
|
||||||
|
out("* = ${program.loadAddress.toHex()}\n")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call the init methods of each block and then jump to the main.start entrypoint
|
||||||
|
out("\t; initialize all blocks(reset vars)")
|
||||||
|
// todo zeropage if it's there
|
||||||
|
for(block in program.blocks)
|
||||||
|
out("\tjsr ${block.scopedname}._prog8_init")
|
||||||
|
out("\tjmp main.start\t; jump to program entrypoint")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun block2asm(out: (String)->Unit, block: IntermediateProgram.ProgramBlock) {
|
||||||
|
out("\n; ---- block: '${block.shortname}' ----")
|
||||||
|
if(block.address!=null) {
|
||||||
|
out(".cerror * > ${block.address?.toHex()}, 'block address overlaps by ', *-${block.address?.toHex()},' bytes'")
|
||||||
|
out("* = ${block.address?.toHex()}")
|
||||||
|
}
|
||||||
|
out("${block.shortname}\t.proc\n")
|
||||||
|
|
||||||
|
// init the variables
|
||||||
|
out("_prog8_init\t; (re)set vars to initial values")
|
||||||
|
// todo init vars
|
||||||
|
|
||||||
|
var skip = 0
|
||||||
|
for(ins in block.instructions.withIndex()) {
|
||||||
|
if(skip==0)
|
||||||
|
skip = ins2asm(out, ins.index, ins.value, block)
|
||||||
|
else
|
||||||
|
skip--
|
||||||
|
}
|
||||||
|
out("\n\t.pend\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
private val registerStrings = setOf("A", "X", "Y", "AX", "AY", "XY")
|
||||||
|
|
||||||
|
private fun ins2asm(out: (String) -> Unit, insIdx: Int, ins: Instruction, block: IntermediateProgram.ProgramBlock): Int {
|
||||||
|
if(ins is LabelInstr) {
|
||||||
|
if(ins.name==block.shortname)
|
||||||
|
return 0
|
||||||
|
if(ins.name.startsWith("${block.shortname}."))
|
||||||
|
out(ins.name.substring(block.shortname.length+1))
|
||||||
|
else
|
||||||
|
out(ins.name)
|
||||||
|
out("\trts") // todo weg
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
when(ins.opcode) {
|
||||||
|
Opcode.LINE -> out("\t; src line: ${ins.callLabel}")
|
||||||
|
Opcode.NOP -> out("\tnop") // shouldn't be present anymore though
|
||||||
|
Opcode.SEC -> out("\tsec")
|
||||||
|
Opcode.CLC -> out("\tclc")
|
||||||
|
Opcode.SEI -> out("\tsei")
|
||||||
|
Opcode.CLI -> out("\tcli")
|
||||||
|
Opcode.TERMINATE -> out("\tbrk\t; terminate!")
|
||||||
|
Opcode.B2UB -> {} // is a no-op, just carry on with the byte as-is
|
||||||
|
Opcode.UB2B -> {} // is a no-op, just carry on with the byte as-is
|
||||||
|
Opcode.PUSH_BYTE -> {
|
||||||
|
// check if we load a register (X, Y) with constant value
|
||||||
|
val nextIns = block.getIns(insIdx+1)
|
||||||
|
if(nextIns.opcode==Opcode.POP_VAR_BYTE && nextIns.callLabel in registerStrings) {
|
||||||
|
out("\tld${nextIns.callLabel!!.toLowerCase()} #${ins.arg!!.integerValue().toHex()}")
|
||||||
|
return 1 // skip 1
|
||||||
|
}
|
||||||
|
// todo push_byte
|
||||||
|
}
|
||||||
|
Opcode.PUSH_WORD -> {
|
||||||
|
// check if we load a register (AX, AY, XY) with constant value
|
||||||
|
val nextIns = block.getIns(insIdx+1)
|
||||||
|
if(nextIns.opcode==Opcode.POP_VAR_WORD && nextIns.callLabel in registerStrings) {
|
||||||
|
val regs = nextIns.callLabel!!.toLowerCase()
|
||||||
|
val value = ins.arg!!.integerValue().toHex()
|
||||||
|
out("\tld${regs[0]} #<$value")
|
||||||
|
out("\tld${regs[1]} #>$value")
|
||||||
|
return 1 // skip 1
|
||||||
|
}
|
||||||
|
// todo push_word
|
||||||
|
}
|
||||||
|
Opcode.COPY_VAR_BYTE -> {
|
||||||
|
if(ins.callLabel2 in registerStrings) {
|
||||||
|
if(ins.callLabel in registerStrings) {
|
||||||
|
// copying register -> register
|
||||||
|
when {
|
||||||
|
ins.callLabel == "A" -> out("\tta${ins.callLabel2!!.toLowerCase()}")
|
||||||
|
ins.callLabel == "X" -> if (ins.callLabel2 == "Y") {
|
||||||
|
// 6502 doesn't have txy
|
||||||
|
out("\ttxa\n\ttay")
|
||||||
|
} else out("\ttxa")
|
||||||
|
ins.callLabel == "Y" -> if (ins.callLabel2 == "X") {
|
||||||
|
// 6502 doesn't have tyx
|
||||||
|
out("\ttya\n\ttax")
|
||||||
|
} else out("\ttya")
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// todo copy_var_byte
|
||||||
|
}
|
||||||
|
Opcode.COPY_VAR_WORD -> {
|
||||||
|
if(ins.callLabel2 in registerStrings) {
|
||||||
|
if(ins.callLabel in registerStrings) {
|
||||||
|
// copying registerpair -> registerpair
|
||||||
|
when {
|
||||||
|
ins.callLabel == "AX" -> when (ins.callLabel2) {
|
||||||
|
"AY" -> out("\ttxy")
|
||||||
|
"XY" -> out("\tpha\n\ttxa\n\ttay\n\tpla\n\ttax")
|
||||||
|
}
|
||||||
|
ins.callLabel == "AY" -> when (ins.callLabel2) {
|
||||||
|
"AX" -> out("\tpha\n\ttya\n\ttax\n\tpla")
|
||||||
|
"XY" -> out("\ttax")
|
||||||
|
}
|
||||||
|
ins.callLabel == "XY" -> when (ins.callLabel2) {
|
||||||
|
"AX" -> out("\ttxa\n\tpha\n\ttya\n\ttax\n\tpla")
|
||||||
|
"AY" -> out("\ttxa")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// todo copy_var_byte
|
||||||
|
}
|
||||||
|
else-> {}
|
||||||
|
// Opcode.PUSH_FLOAT -> TODO()
|
||||||
|
// Opcode.PUSH_MEM_B -> TODO()
|
||||||
|
// Opcode.PUSH_MEM_UB -> TODO()
|
||||||
|
// Opcode.PUSH_MEM_W -> TODO()
|
||||||
|
// Opcode.PUSH_MEM_UW -> TODO()
|
||||||
|
// Opcode.PUSH_MEM_FLOAT -> TODO()
|
||||||
|
// Opcode.PUSH_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.PUSH_VAR_WORD -> TODO()
|
||||||
|
// Opcode.PUSH_VAR_FLOAT -> TODO()
|
||||||
|
// Opcode.DISCARD_BYTE -> TODO()
|
||||||
|
// Opcode.DISCARD_WORD -> TODO()
|
||||||
|
// Opcode.DISCARD_FLOAT -> TODO()
|
||||||
|
// Opcode.POP_MEM_B -> TODO()
|
||||||
|
// Opcode.POP_MEM_UB -> TODO()
|
||||||
|
// Opcode.POP_MEM_W -> TODO()
|
||||||
|
// Opcode.POP_MEM_UW -> TODO()
|
||||||
|
// Opcode.POP_MEM_FLOAT -> TODO()
|
||||||
|
// Opcode.POP_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.POP_VAR_WORD -> TODO()
|
||||||
|
// Opcode.POP_VAR_FLOAT -> TODO()
|
||||||
|
// Opcode.COPY_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.COPY_VAR_WORD -> TODO()
|
||||||
|
// Opcode.COPY_VAR_FLOAT -> TODO()
|
||||||
|
// Opcode.ADD_UB -> TODO()
|
||||||
|
// Opcode.ADD_B -> TODO()
|
||||||
|
// Opcode.ADD_UW -> TODO()
|
||||||
|
// Opcode.ADD_W -> TODO()
|
||||||
|
// Opcode.ADD_F -> TODO()
|
||||||
|
// Opcode.SUB_UB -> TODO()
|
||||||
|
// Opcode.SUB_B -> TODO()
|
||||||
|
// Opcode.SUB_UW -> TODO()
|
||||||
|
// Opcode.SUB_W -> TODO()
|
||||||
|
// Opcode.SUB_F -> TODO()
|
||||||
|
// Opcode.MUL_UB -> TODO()
|
||||||
|
// Opcode.MUL_B -> TODO()
|
||||||
|
// Opcode.MUL_UW -> TODO()
|
||||||
|
// Opcode.MUL_W -> TODO()
|
||||||
|
// Opcode.MUL_F -> TODO()
|
||||||
|
// Opcode.DIV_UB -> TODO()
|
||||||
|
// Opcode.DIV_B -> TODO()
|
||||||
|
// Opcode.DIV_UW -> TODO()
|
||||||
|
// Opcode.DIV_W -> TODO()
|
||||||
|
// Opcode.DIV_F -> TODO()
|
||||||
|
// Opcode.FLOORDIV_UB -> TODO()
|
||||||
|
// Opcode.FLOORDIV_B -> TODO()
|
||||||
|
// Opcode.FLOORDIV_UW -> TODO()
|
||||||
|
// Opcode.FLOORDIV_W -> TODO()
|
||||||
|
// Opcode.FLOORDIV_F -> TODO()
|
||||||
|
// Opcode.REMAINDER_UB -> TODO()
|
||||||
|
// Opcode.REMAINDER_B -> TODO()
|
||||||
|
// Opcode.REMAINDER_UW -> TODO()
|
||||||
|
// Opcode.REMAINDER_W -> TODO()
|
||||||
|
// Opcode.REMAINDER_F -> TODO()
|
||||||
|
// Opcode.POW_UB -> TODO()
|
||||||
|
// Opcode.POW_B -> TODO()
|
||||||
|
// Opcode.POW_UW -> TODO()
|
||||||
|
// Opcode.POW_W -> TODO()
|
||||||
|
// Opcode.POW_F -> TODO()
|
||||||
|
// Opcode.NEG_B -> TODO()
|
||||||
|
// Opcode.NEG_W -> TODO()
|
||||||
|
// Opcode.NEG_F -> TODO()
|
||||||
|
// Opcode.SHL_BYTE -> TODO()
|
||||||
|
// Opcode.SHL_WORD -> TODO()
|
||||||
|
// Opcode.SHL_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.SHL_MEM_WORD -> TODO()
|
||||||
|
// Opcode.SHL_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.SHL_VAR_WORD -> TODO()
|
||||||
|
// Opcode.SHR_BYTE -> TODO()
|
||||||
|
// Opcode.SHR_WORD -> TODO()
|
||||||
|
// Opcode.SHR_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.SHR_MEM_WORD -> TODO()
|
||||||
|
// Opcode.SHR_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.SHR_VAR_WORD -> TODO()
|
||||||
|
// Opcode.ROL_BYTE -> TODO()
|
||||||
|
// Opcode.ROL_WORD -> TODO()
|
||||||
|
// Opcode.ROL_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.ROL_MEM_WORD -> TODO()
|
||||||
|
// Opcode.ROL_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.ROL_VAR_WORD -> TODO()
|
||||||
|
// Opcode.ROR_BYTE -> TODO()
|
||||||
|
// Opcode.ROR_WORD -> TODO()
|
||||||
|
// Opcode.ROR_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.ROR_MEM_WORD -> TODO()
|
||||||
|
// Opcode.ROR_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.ROR_VAR_WORD -> TODO()
|
||||||
|
// Opcode.ROL2_BYTE -> TODO()
|
||||||
|
// Opcode.ROL2_WORD -> TODO()
|
||||||
|
// Opcode.ROL2_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.ROL2_MEM_WORD -> TODO()
|
||||||
|
// Opcode.ROL2_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.ROL2_VAR_WORD -> TODO()
|
||||||
|
// Opcode.ROR2_BYTE -> TODO()
|
||||||
|
// Opcode.ROR2_WORD -> TODO()
|
||||||
|
// Opcode.ROR2_MEM_BYTE -> TODO()
|
||||||
|
// Opcode.ROR2_MEM_WORD -> TODO()
|
||||||
|
// Opcode.ROR2_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.ROR2_VAR_WORD -> TODO()
|
||||||
|
// Opcode.BITAND_BYTE -> TODO()
|
||||||
|
// Opcode.BITAND_WORD -> TODO()
|
||||||
|
// Opcode.BITOR_BYTE -> TODO()
|
||||||
|
// Opcode.BITOR_WORD -> TODO()
|
||||||
|
// Opcode.BITXOR_BYTE -> TODO()
|
||||||
|
// Opcode.BITXOR_WORD -> TODO()
|
||||||
|
// Opcode.INV_BYTE -> TODO()
|
||||||
|
// Opcode.INV_WORD -> TODO()
|
||||||
|
// Opcode.LSB -> TODO()
|
||||||
|
// Opcode.MSB -> TODO()
|
||||||
|
// Opcode.B2WORD -> TODO()
|
||||||
|
// Opcode.UB2UWORD -> TODO()
|
||||||
|
// Opcode.MSB2WORD -> TODO()
|
||||||
|
// Opcode.B2FLOAT -> TODO()
|
||||||
|
// Opcode.UB2FLOAT -> TODO()
|
||||||
|
// Opcode.W2FLOAT -> TODO()
|
||||||
|
// Opcode.UW2FLOAT -> TODO()
|
||||||
|
// Opcode.AND_BYTE -> TODO()
|
||||||
|
// Opcode.AND_WORD -> TODO()
|
||||||
|
// Opcode.OR_BYTE -> TODO()
|
||||||
|
// Opcode.OR_WORD -> TODO()
|
||||||
|
// Opcode.XOR_BYTE -> TODO()
|
||||||
|
// Opcode.XOR_WORD -> TODO()
|
||||||
|
// Opcode.NOT_BYTE -> TODO()
|
||||||
|
// Opcode.NOT_WORD -> TODO()
|
||||||
|
// Opcode.INC_B -> TODO()
|
||||||
|
// Opcode.INC_UB -> TODO()
|
||||||
|
// Opcode.INC_W -> TODO()
|
||||||
|
// Opcode.INC_UW -> TODO()
|
||||||
|
// Opcode.INC_F -> TODO()
|
||||||
|
// Opcode.INC_VAR_B -> TODO()
|
||||||
|
// Opcode.INC_VAR_UB -> TODO()
|
||||||
|
// Opcode.INC_VAR_W -> TODO()
|
||||||
|
// Opcode.INC_VAR_UW -> TODO()
|
||||||
|
// Opcode.INC_VAR_F -> TODO()
|
||||||
|
// Opcode.DEC_B -> TODO()
|
||||||
|
// Opcode.DEC_UB -> TODO()
|
||||||
|
// Opcode.DEC_W -> TODO()
|
||||||
|
// Opcode.DEC_UW -> TODO()
|
||||||
|
// Opcode.DEC_F -> TODO()
|
||||||
|
// Opcode.DEC_VAR_B -> TODO()
|
||||||
|
// Opcode.DEC_VAR_UB -> TODO()
|
||||||
|
// Opcode.DEC_VAR_W -> TODO()
|
||||||
|
// Opcode.DEC_VAR_UW -> TODO()
|
||||||
|
// Opcode.DEC_VAR_F -> TODO()
|
||||||
|
// Opcode.LESS_B -> TODO()
|
||||||
|
// Opcode.LESS_UB -> TODO()
|
||||||
|
// Opcode.LESS_W -> TODO()
|
||||||
|
// Opcode.LESS_UW -> TODO()
|
||||||
|
// Opcode.LESS_F -> TODO()
|
||||||
|
// Opcode.GREATER_B -> TODO()
|
||||||
|
// Opcode.GREATER_UB -> TODO()
|
||||||
|
// Opcode.GREATER_W -> TODO()
|
||||||
|
// Opcode.GREATER_UW -> TODO()
|
||||||
|
// Opcode.GREATER_F -> TODO()
|
||||||
|
// Opcode.LESSEQ_B -> TODO()
|
||||||
|
// Opcode.LESSEQ_UB -> TODO()
|
||||||
|
// Opcode.LESSEQ_W -> TODO()
|
||||||
|
// Opcode.LESSEQ_UW -> TODO()
|
||||||
|
// Opcode.LESSEQ_F -> TODO()
|
||||||
|
// Opcode.GREATEREQ_B -> TODO()
|
||||||
|
// Opcode.GREATEREQ_UB -> TODO()
|
||||||
|
// Opcode.GREATEREQ_W -> TODO()
|
||||||
|
// Opcode.GREATEREQ_UW -> TODO()
|
||||||
|
// Opcode.GREATEREQ_F -> TODO()
|
||||||
|
// Opcode.EQUAL_BYTE -> TODO()
|
||||||
|
// Opcode.EQUAL_WORD -> TODO()
|
||||||
|
// Opcode.EQUAL_F -> TODO()
|
||||||
|
// Opcode.NOTEQUAL_BYTE -> TODO()
|
||||||
|
// Opcode.NOTEQUAL_WORD -> TODO()
|
||||||
|
// Opcode.NOTEQUAL_F -> TODO()
|
||||||
|
// Opcode.READ_INDEXED_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.READ_INDEXED_VAR_WORD -> TODO()
|
||||||
|
// Opcode.READ_INDEXED_VAR_FLOAT -> TODO()
|
||||||
|
// Opcode.WRITE_INDEXED_VAR_BYTE -> TODO()
|
||||||
|
// Opcode.WRITE_INDEXED_VAR_WORD -> TODO()
|
||||||
|
// Opcode.WRITE_INDEXED_VAR_FLOAT -> TODO()
|
||||||
|
// Opcode.JUMP -> TODO()
|
||||||
|
// Opcode.BCS -> TODO()
|
||||||
|
// Opcode.BCC -> TODO()
|
||||||
|
// Opcode.BZ -> TODO()
|
||||||
|
// Opcode.BNZ -> TODO()
|
||||||
|
// Opcode.BNEG -> TODO()
|
||||||
|
// Opcode.BPOS -> TODO()
|
||||||
|
// Opcode.CALL -> TODO()
|
||||||
|
// Opcode.RETURN -> TODO()
|
||||||
|
// Opcode.SYSCALL -> TODO()
|
||||||
|
// Opcode.BREAKPOINT -> TODO()
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -12,6 +12,9 @@ import kotlin.math.pow
|
|||||||
const val FLOAT_MAX_POSITIVE = 1.7014118345e+38
|
const val FLOAT_MAX_POSITIVE = 1.7014118345e+38
|
||||||
const val FLOAT_MAX_NEGATIVE = -1.7014118345e+38
|
const val FLOAT_MAX_NEGATIVE = -1.7014118345e+38
|
||||||
|
|
||||||
|
const val BASIC_LOAD_ADDRESS = 0x0801
|
||||||
|
const val RAW_LOAD_ADDRESS = 0xc000
|
||||||
|
|
||||||
|
|
||||||
class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ Directives
|
|||||||
- default for ``raw`` output is ``$c000``
|
- default for ``raw`` output is ``$c000``
|
||||||
- default for ``prg`` output is ``$0801``
|
- default for ``prg`` output is ``$0801``
|
||||||
- cannot be changed if you select ``prg`` with a ``basic`` launcher;
|
- cannot be changed if you select ``prg`` with a ``basic`` launcher;
|
||||||
then it is always ``$081d`` (immediately after the BASIC program), and the BASIC program itself is always at ``$0801``.
|
then it is always ``$081e`` (immediately after the BASIC program), and the BASIC program itself is always at ``$0801``.
|
||||||
This is because the C64 expects BASIC programs to start at this address.
|
This is because the C64 expects BASIC programs to start at this address.
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user