mirror of
https://github.com/irmen/prog8.git
synced 2024-10-18 01:24:51 +00:00
don't clobber A when trying to save X at functioncall
This commit is contained in:
parent
35aebbc209
commit
97b9c8f320
@ -552,55 +552,60 @@ 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
|
internal fun fixNameSymbols(name: String) = name.replace("<", "prog8_").replace(">", "") // take care of the autogenerated invalid (anon) label names
|
||||||
|
|
||||||
internal fun saveRegister(register: CpuRegister, forFuncCall: Boolean = false, dontClobberA: Boolean = false) {
|
|
||||||
|
private val saveRegisterLabels = Stack<String>();
|
||||||
|
|
||||||
|
internal fun saveRegister(register: CpuRegister, forFuncCall: Boolean = false) {
|
||||||
when(register) {
|
when(register) {
|
||||||
CpuRegister.A -> out(" pha")
|
CpuRegister.A -> out(" pha")
|
||||||
CpuRegister.X -> {
|
CpuRegister.X -> {
|
||||||
// TODO get rid of REG_X altogheter! replace with sta _save | txa | pha | lda _save
|
// TODO get rid of REG_X altogether!
|
||||||
when {
|
when {
|
||||||
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phx")
|
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phx")
|
||||||
forFuncCall -> {
|
forFuncCall -> {
|
||||||
if(dontClobberA)
|
val save = makeLabel("saveX")
|
||||||
out(" sta P8ZP_SCRATCH_REG | txa | pha | lda P8ZP_SCRATCH_REG")
|
saveRegisterLabels.push(save)
|
||||||
else
|
out("""
|
||||||
out(" txa | pha")
|
stx $save
|
||||||
|
jmp +
|
||||||
|
$save .byte 0
|
||||||
|
+""")
|
||||||
}
|
}
|
||||||
else -> out(" stx P8ZP_SCRATCH_REG_X")
|
else -> out(" stx P8ZP_SCRATCH_REG_X")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CpuRegister.Y -> {
|
CpuRegister.Y -> {
|
||||||
when {
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" phy")
|
||||||
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" phy")
|
else {
|
||||||
dontClobberA -> out(" sta P8ZP_SCRATCH_REG | tya | pha | lda P8ZP_SCRATCH_REG")
|
val save = makeLabel("saveY")
|
||||||
else -> out(" tya | pha")
|
out("""
|
||||||
|
sty $save
|
||||||
|
jmp +
|
||||||
|
$save .byte 0
|
||||||
|
+""")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun restoreRegister(register: CpuRegister, forFuncCall: Boolean = false, dontClobberA: Boolean=false) {
|
internal fun restoreRegister(register: CpuRegister, forFuncCall: Boolean = false) {
|
||||||
when(register) {
|
when(register) {
|
||||||
CpuRegister.A -> {
|
CpuRegister.A -> out(" pla")
|
||||||
require(!dontClobberA)
|
|
||||||
out(" pla")
|
|
||||||
}
|
|
||||||
CpuRegister.X -> {
|
CpuRegister.X -> {
|
||||||
when {
|
when {
|
||||||
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" plx")
|
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" plx")
|
||||||
forFuncCall -> {
|
forFuncCall -> {
|
||||||
if(dontClobberA)
|
val save = saveRegisterLabels.pop()
|
||||||
out(" sta P8ZP_SCRATCH_REG | pla | tax | lda P8ZP_SCRATCH_REG")
|
out(" ldx $save")
|
||||||
else
|
|
||||||
out(" pla | tax")
|
|
||||||
}
|
}
|
||||||
else -> out(" ldx P8ZP_SCRATCH_REG_X")
|
else -> out(" ldx P8ZP_SCRATCH_REG_X")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CpuRegister.Y -> {
|
CpuRegister.Y -> {
|
||||||
when {
|
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) out(" ply")
|
||||||
CompilationTarget.instance.machine.cpu == CpuType.CPU65c02 -> out(" ply")
|
else {
|
||||||
dontClobberA -> out(" sta P8ZP_SCRATCH_REG | pla | tay | lda P8ZP_SCRATCH_REG")
|
val save = saveRegisterLabels.pop()
|
||||||
else -> out(" pla | tay")
|
out(" ldy $save")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
|
val sub = stmt.target.targetSubroutine(program.namespace) ?: throw AssemblyError("undefined subroutine ${stmt.target}")
|
||||||
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam()
|
val saveX = CpuRegister.X in sub.asmClobbers || sub.regXasResult() || sub.regXasParam()
|
||||||
if(saveX)
|
if(saveX)
|
||||||
asmgen.saveRegister(CpuRegister.X, forFuncCall = true, dontClobberA = false) // we only save X for now (required! is the eval stack pointer), screw A and Y...
|
asmgen.saveRegister(CpuRegister.X, forFuncCall = true)
|
||||||
|
|
||||||
val subName = asmgen.asmSymbolName(stmt.target)
|
val subName = asmgen.asmSymbolName(stmt.target)
|
||||||
if(stmt.args.isNotEmpty()) {
|
if(stmt.args.isNotEmpty()) {
|
||||||
@ -58,7 +58,7 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
asmgen.out(" jsr $subName")
|
asmgen.out(" jsr $subName")
|
||||||
|
|
||||||
if(saveX)
|
if(saveX)
|
||||||
asmgen.restoreRegister(CpuRegister.X, forFuncCall = true, dontClobberA = false)
|
asmgen.restoreRegister(CpuRegister.X, forFuncCall = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) {
|
private fun registerArgsViaStackEvaluation(stmt: IFunctionCall, sub: Subroutine) {
|
||||||
|
@ -248,7 +248,6 @@ waitkey:
|
|||||||
c64.CHROUT('K')
|
c64.CHROUT('K')
|
||||||
|
|
||||||
while c64.GETIN()!=133 {
|
while c64.GETIN()!=133 {
|
||||||
; TODO FIX THIS, DOESN'T TRIGGER ANYMORE ON F1
|
|
||||||
; endless loop until user presses F1 to restart the game
|
; endless loop until user presses F1 to restart the game
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
%target cx16
|
%import c64textio
|
||||||
%import cx16textio
|
|
||||||
;%import c64flt
|
;%import c64flt
|
||||||
;%option enable_floats
|
;%option enable_floats
|
||||||
; %zeropage kernalsafe
|
; %zeropage kernalsafe
|
||||||
|
Loading…
Reference in New Issue
Block a user