This commit is contained in:
Irmen de Jong 2018-10-18 02:14:13 +02:00
parent bcedb5f5e3
commit c01114db9f
3 changed files with 128 additions and 48 deletions

View File

@ -5,29 +5,7 @@
sub start() { sub start() {
const ubyte screen_color = 9 c64utils.init_system()
const ubyte border_color = 2
const ubyte cursor_color = 7
ubyte ubb
uword uww
byte color
byte color2
AX=XY
uww=XY
AY=uww
A++
X++
AY++
A = ~X
A = not Y
ubb = ~ubb
uww = ~uww
color2 = ~color
uww = not uww
return return

View File

@ -73,11 +73,28 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
} }
private fun symname(scoped: String, block: IntermediateProgram.ProgramBlock): String { private fun symname(scoped: String, block: IntermediateProgram.ProgramBlock): String {
val name = if (scoped.startsWith("${block.shortname}.")) scoped.substring(block.shortname.length+1) else scoped if(' ' in scoped)
val validName = name.replace("<<<", "prog8_").replace(">>>", "") return scoped
if(validName=="-")
val blockLocal: Boolean
var name = if (scoped.startsWith("${block.shortname}.")) {
blockLocal = true
scoped.substring(block.shortname.length+1)
} else {
blockLocal = false
scoped
}
name = name.replace("<<<", "prog8_").replace(">>>", "")
if(name=="-")
return "-" return "-"
return validName.replace("-", "").replace(".", "_") if(blockLocal)
name = name.replace(".", "_")
else {
val parts = name.split(".", limit=2)
if(parts.size>1)
name = "${parts[0]}.${parts[1].replace(".", "_")}"
}
return name.replace("-", "")
} }
@ -311,6 +328,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tdex") out("\tdex")
} }
private fun pushByteY() {
out("\ttya")
out("\tsta ${ESTACK_LO.toHex()},x")
out("\tdex")
}
private fun replaceByteA() { private fun replaceByteA() {
out("\tsta ${(ESTACK_LO+1).toHex()},x") out("\tsta ${(ESTACK_LO+1).toHex()},x")
} }
@ -388,6 +411,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tlda ${ESTACK_LO.toHex()},x") out("\tlda ${ESTACK_LO.toHex()},x")
} }
private fun popByteY() {
// for operations that remove a value from the stack
out("\tinx")
out("\tldy ${ESTACK_LO.toHex()},x")
}
private fun peekByteA() { private fun peekByteA() {
// for operations that modify a value on the stack // for operations that modify a value on the stack
out("\tlda ${(ESTACK_LO+1).toHex()},x") out("\tlda ${(ESTACK_LO+1).toHex()},x")
@ -435,8 +464,9 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
Opcode.CLC -> out("\tclc") Opcode.CLC -> out("\tclc")
Opcode.SEI -> out("\tsei") Opcode.SEI -> out("\tsei")
Opcode.CLI -> out("\tcli") Opcode.CLI -> out("\tcli")
Opcode.RETURN -> out("\trts") // todo is return really this simple?
Opcode.JUMP -> out("\tjmp ${ins.callLabel}") Opcode.JUMP -> out("\tjmp ${ins.callLabel}")
Opcode.CALL -> out("\tjsr ${ins.callLabel}")
Opcode.RETURN -> out("\trts") // todo is return really this simple?
Opcode.B2UB -> {} // is a no-op, just carry on with the byte as-is 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.UB2B -> {} // is a no-op, just carry on with the byte as-is
Opcode.RSAVE -> out("\tphp\n\tpha\n\ttxa\n\tpha\n\ttya\n\tpha") Opcode.RSAVE -> out("\tphp\n\tpha\n\ttxa\n\tpha\n\ttya\n\tpha")
@ -573,8 +603,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
return 1 // skip 1 return 1 // skip 1
} }
// byte from variable onto stack // byte from variable onto stack
TODO("can be register") when(ins.callLabel) {
pushVarByte(ins.callLabel!!) "A" -> pushByteA()
"X" -> throw CompilerException("makes no sense to push X it's used as a stack pointer itself")
"Y" -> pushByteY()
else -> pushVarByte(ins.callLabel!!)
}
} }
Opcode.PUSH_WORD -> { Opcode.PUSH_WORD -> {
val nextIns = block.getIns(insIdx+1) val nextIns = block.getIns(insIdx+1)
@ -649,8 +683,12 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
return 1 // skip 1 return 1 // skip 1
} }
// word from memory onto stack // word from memory onto stack
TODO("can be register") when(ins.callLabel) {
pushVarWord(ins.callLabel!!) "AX" -> TODO()
"AY" -> TODO()
"XY" -> TODO()
else -> pushVarWord(ins.callLabel!!)
}
} }
Opcode.PUSH_FLOAT -> { Opcode.PUSH_FLOAT -> {
val nextIns = block.getIns(insIdx+1) val nextIns = block.getIns(insIdx+1)
@ -702,12 +740,43 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
pushFloat(ins.arg!!.integerValue().toHex()) pushFloat(ins.arg!!.integerValue().toHex())
} }
Opcode.INC_VAR_UB, Opcode.INC_VAR_B -> { Opcode.INC_VAR_UB, Opcode.INC_VAR_B -> {
TODO("can be register") when(ins.callLabel) {
out("\tinc ${ins.callLabel}") "A" -> out("\tclc\n\tadc #1")
"X" -> out("\tinx")
"Y" -> out("\tiny")
else -> out("\tinc ${ins.callLabel}")
}
}
Opcode.INC_VAR_UW -> {
when(ins.callLabel) {
"AX" -> {
out("\tclc\n\tadc #1")
out("\tbne +")
out("\tinx")
out("+")
}
"AY" -> {
out("\tclc\n\tadc #1")
out("\tbne +")
out("\tiny")
out("+")
}
"XY" -> {
out("\tinx")
out("\tbne +")
out("\tiny")
out("+")
}
else -> TODO("inc_var_uw $ins")
}
} }
Opcode.DEC_VAR_UB, Opcode.DEC_VAR_B -> { Opcode.DEC_VAR_UB, Opcode.DEC_VAR_B -> {
TODO("can be register") when(ins.callLabel) {
out("\tdec ${ins.callLabel}") "A" -> out("\tsec\n\tsbc #1")
"X" -> out("\tdex")
"Y" -> out("\tdey")
else -> out("\tdec ${ins.callLabel}")
}
} }
Opcode.ADD_UB, Opcode.ADD_B -> { Opcode.ADD_UB, Opcode.ADD_B -> {
peekByte2A() peekByte2A()
@ -726,16 +795,51 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tsta ${ins.arg!!.integerValue().toHex()}") out("\tsta ${ins.arg!!.integerValue().toHex()}")
} }
Opcode.POP_VAR_BYTE -> { Opcode.POP_VAR_BYTE -> {
when(ins.callLabel) {
"A" -> popByteA()
"X" -> throw CompilerException("makes no sense to pop X it's used as a stack pointer itself")
"Y" -> popByteY()
else -> {
popByteA() popByteA()
TODO("can be register")
out("\tsta ${ins.callLabel}") out("\tsta ${ins.callLabel}")
} }
}
}
Opcode.POP_VAR_WORD -> { Opcode.POP_VAR_WORD -> {
when(ins.callLabel) {
"AX" -> throw CompilerException("makes no sense to pop X it's used as a stack pointer itself")
"AY" -> TODO()
"XY" -> throw CompilerException("makes no sense to pop X it's used as a stack pointer itself")
else -> {
popWordAY() popWordAY()
TODO("can be register")
out("\tsta ${ins.callLabel}") out("\tsta ${ins.callLabel}")
out("\tsty ${ins.callLabel}+1") out("\tsty ${ins.callLabel}+1")
} }
}
}
Opcode.DEC_VAR_UW -> {
when(ins.callLabel) {
"AX" -> {
out("\tcmp #0")
out("\tbne +")
out("\tdex")
out("+\tsec\n\tsbc #1")
}
"AY" -> {
out("\tcmp #0")
out("\tbne +")
out("\tdey")
out("+\tsec\n\tsbc #1")
}
"XY" -> {
out("\ttxa")
out("\tbne +")
out("\tdey")
out("+\tdex")
}
else -> TODO("dec_var_uw $ins")
}
}
Opcode.NEG_B -> { Opcode.NEG_B -> {
peekByteA() peekByteA()
out("\teor #\$ff") out("\teor #\$ff")
@ -761,7 +865,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tlda #0") out("\tlda #0")
out("\tbeq ++") out("\tbeq ++")
out("+\tlda #1") out("+\tlda #1")
out("++") out("+")
replaceByteA() replaceByteA()
} }
Opcode.NOT_WORD -> { Opcode.NOT_WORD -> {
@ -771,7 +875,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
out("\tlda #0") out("\tlda #0")
out("\tbeq ++") out("\tbeq ++")
out("+\tlda #1") out("+\tlda #1")
out("++\tsta ${(ESTACK_LO+1).toHex()},x") out("+\tsta ${(ESTACK_LO+1).toHex()},x")
out("\tsta ${(ESTACK_HI+1).toHex()},x") out("\tsta ${(ESTACK_HI+1).toHex()},x")
} }
@ -783,10 +887,8 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// Opcode.POP_VAR_FLOAT -> TODO() // Opcode.POP_VAR_FLOAT -> TODO()
// Opcode.COPY_VAR_FLOAT -> TODO() // Opcode.COPY_VAR_FLOAT -> TODO()
// Opcode.INC_VAR_W -> TODO() // Opcode.INC_VAR_W -> TODO()
// Opcode.INC_VAR_UW -> TODO()
// Opcode.INC_VAR_F -> TODO() // Opcode.INC_VAR_F -> TODO()
// Opcode.DEC_VAR_W -> TODO() // Opcode.DEC_VAR_W -> TODO()
// Opcode.DEC_VAR_UW -> TODO()
// Opcode.DEC_VAR_F -> TODO() // Opcode.DEC_VAR_F -> TODO()
// Opcode.ADD_UW -> TODO() // Opcode.ADD_UW -> TODO()
// Opcode.ADD_W -> TODO() // Opcode.ADD_W -> TODO()
@ -916,7 +1018,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// Opcode.BNZ -> TODO() // Opcode.BNZ -> TODO()
// Opcode.BNEG -> TODO() // Opcode.BNEG -> TODO()
// Opcode.BPOS -> TODO() // Opcode.BPOS -> TODO()
// Opcode.CALL -> TODO()
// Opcode.SYSCALL -> TODO() // Opcode.SYSCALL -> TODO()
// Opcode.BREAKPOINT -> TODO() // Opcode.BREAKPOINT -> TODO()
} }

View File

@ -18,6 +18,7 @@ asmsub init_system () -> clobbers(A,X,Y) -> () {
; This means that the BASIC, KERNAL and CHARGEN ROMs are banked in, ; This means that the BASIC, KERNAL and CHARGEN ROMs are banked in,
; the VIC, SID and CIA chips are reset, screen is cleared, and the default IRQ is set. ; the VIC, SID and CIA chips are reset, screen is cleared, and the default IRQ is set.
; Also a different color scheme is chosen to identify ourselves a little. ; Also a different color scheme is chosen to identify ourselves a little.
; All three registers set to 0, status flags cleared.
%asm {{ %asm {{
sei sei
cld cld