optimize (zp),y instructions for 65c02 to use (zp)

This commit is contained in:
Irmen de Jong 2021-01-15 18:46:23 +01:00
parent 46373717b6
commit 3dcef89a74
6 changed files with 114 additions and 57 deletions

View File

@ -526,19 +526,35 @@ internal class AsmGen(private val program: Program,
val sourceName = asmVariableName(pointervar)
val vardecl = pointervar.targetVarDecl(program.namespace)!!
val scopedName = vardecl.makeScopedName(vardecl.name)
return if(scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
Pair(true, sourceName)
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) {
return if (scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
out(" lda ($sourceName)")
Pair(true, sourceName)
} else {
out("""
lda $sourceName
ldy $sourceName+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
lda (P8ZP_SCRATCH_W1)""")
Pair(false, sourceName)
}
} else {
out("""
lda $sourceName
ldy $sourceName+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
lda (P8ZP_SCRATCH_W1),y""")
Pair(false, sourceName)
return if (scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
out(" ldy #0 | lda ($sourceName),y")
Pair(true, sourceName)
} else {
out("""
lda $sourceName
ldy $sourceName+1
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
lda (P8ZP_SCRATCH_W1),y""")
Pair(false, sourceName)
}
}
}
@ -546,20 +562,37 @@ internal class AsmGen(private val program: Program,
val sourceName = asmVariableName(pointervar)
val vardecl = pointervar.targetVarDecl(program.namespace)!!
val scopedName = vardecl.makeScopedName(vardecl.name)
if(scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
if(ldaInstructionArg!=null)
out(" lda $ldaInstructionArg")
out(" ldy #0 | sta ($sourceName),y")
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) {
if (scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
if (ldaInstructionArg != null)
out(" lda $ldaInstructionArg")
out(" sta ($sourceName)")
} else {
out("""
ldy $sourceName
sty P8ZP_SCRATCH_W2
ldy $sourceName+1
sty P8ZP_SCRATCH_W2+1
${if (ldaInstructionArg == null) "" else "lda $ldaInstructionArg"}
sta (P8ZP_SCRATCH_W2)""")
}
} else {
out("""
ldy $sourceName
sty P8ZP_SCRATCH_W2
ldy $sourceName+1
sty P8ZP_SCRATCH_W2+1
${if(ldaInstructionArg==null) "" else "lda $ldaInstructionArg"}
ldy #0
sta (P8ZP_SCRATCH_W2),y""")
if (scopedName in allocatedZeropageVariables) {
// pointervar is already in the zero page, no need to copy
if (ldaInstructionArg != null)
out(" lda $ldaInstructionArg")
out(" ldy #0 | sta ($sourceName),y")
} else {
out("""
ldy $sourceName
sty P8ZP_SCRATCH_W2
ldy $sourceName+1
sty P8ZP_SCRATCH_W2+1
${if (ldaInstructionArg == null) "" else "lda $ldaInstructionArg"}
ldy #0
sta (P8ZP_SCRATCH_W2),y""")
}
}
}

View File

@ -1472,10 +1472,18 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
}
else -> {
asmgen.assignExpressionToVariable(expr.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
if(pushResultOnEstack) {
asmgen.out(" dex | ldy #0 | lda (P8ZP_SCRATCH_W2),y | sta P8ESTACK_LO+1,x")
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02) {
if (pushResultOnEstack) {
asmgen.out(" dex | lda (P8ZP_SCRATCH_W2) | sta P8ESTACK_LO+1,x")
} else {
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
}
} else {
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y")
if (pushResultOnEstack) {
asmgen.out(" dex | ldy #0 | lda (P8ZP_SCRATCH_W2),y | sta P8ESTACK_LO+1,x")
} else {
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y")
}
}
}
}

View File

@ -123,7 +123,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
else -> {
assignExpressionToVariable(value.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, assign.target.scope)
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y")
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
else
asmgen.out(" ldy #0 | lda (P8ZP_SCRATCH_W2),y")
assignRegisterByte(assign.target, CpuRegister.A)
}
}
@ -1943,7 +1946,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
}
else -> {
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
asmgen.out(" ldy #0 | lda $ldaInstructionArg | sta (P8ZP_SCRATCH_W2),y")
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
asmgen.out(" lda $ldaInstructionArg | sta (P8ZP_SCRATCH_W2)")
else
asmgen.out(" lda $ldaInstructionArg | ldy #0 | sta (P8ZP_SCRATCH_W2),y")
}
}
}
@ -1969,7 +1975,10 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.saveRegisterStack(register, false)
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
asmgen.restoreRegisterStack(CpuRegister.A, false)
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
if (CompilationTarget.instance.machine.cpu == CpuType.CPU65c02)
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
else
asmgen.out(" ldy #0 | sta (P8ZP_SCRATCH_W2),y")
}
}
}

View File

@ -2,7 +2,6 @@
TODO
====
- use (zp) addressing mode on 65c02 specific code rather than ldy#0 / lda (zp),y
- optimize pointer access code @(pointer)? use a subroutine? macro? 65c02 vs 6502?
- can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50
- add a compiler option to generate a symbol listing at the end

View File

@ -12,7 +12,7 @@
main {
sub start() {
txt.print("\n65c02 file based assembler.\n\nfilename or enter for interactive: ")
txt.print("\nCommanderX16 65c02 file based assembler.\n\nfilename or enter for interactive: ")
str filename = "?" * 20
if txt.input_chars(filename)
@ -639,11 +639,10 @@ instructions {
phx
sta P8ZP_SCRATCH_W1
sty P8ZP_SCRATCH_W1+1
ldy #0
lda (P8ZP_SCRATCH_W1),y
lda (P8ZP_SCRATCH_W1)
and #$7f ; lowercase
pha
iny
ldy #1
lda (P8ZP_SCRATCH_W1),y
and #$7f ; lowercase
pha
@ -686,10 +685,9 @@ instructions {
;lda #13
;jsr c64.CHROUT
ldy #0
lda (P8ZP_SCRATCH_W2),y
lda (P8ZP_SCRATCH_W2)
beq _multi_addrmodes
iny
ldy #1
lda (P8ZP_SCRATCH_W2),y
cmp cx16.r5 ; check single possible addr.mode
bne _not_found
@ -707,12 +705,11 @@ _multi_addrmodes
lda (P8ZP_SCRATCH_W2),y ; check opcode for addr.mode
bne _valid
; opcode $00 usually means 'invalid' but for "brk" it is actually valid so check for "brk"
ldy #0
lda (P8ZP_SCRATCH_W1),y
lda (P8ZP_SCRATCH_W1)
and #$7f ; lowercase
cmp #'b'
bne _not_found
iny
ldy #1
lda (P8ZP_SCRATCH_W1),y
and #$7f ; lowercase
cmp #'r'

View File

@ -7,27 +7,38 @@ main {
sub start() {
str filename="?"*40
txt.print("> ")
ubyte il = txt.input_chars(filename)
txt.print_ub(il)
str name = "abcdef"
uword ptr = &name
ubyte cc
cc = @(ptr)
txt.chrout(cc)
txt.nl()
txt.print_ubhex(filename[0],1)
txt.print_ubhex(filename[1],1)
txt.print_ubhex(filename[2],1)
cc = @(ptr+1)
txt.chrout(cc)
txt.nl()
cc = @(ptr+2)
txt.chrout(cc)
txt.nl()
txt.print(filename)
txt.nl()
txt.print("> ")
il = txt.input_chars(filename)
txt.print_ub(il)
txt.chrout(@(ptr))
txt.chrout(@(ptr+1))
txt.chrout(@(ptr+2))
txt.nl()
txt.print_ubhex(filename[0],1)
txt.print_ubhex(filename[1],1)
txt.print_ubhex(filename[2],1)
@(ptr) = '1'
@(ptr+1) = '2'
@(ptr+2) = '3'
txt.print(name)
txt.nl()
txt.print(filename)
cc=0
@(ptr+cc) = 'a'
@(ptr+cc+1) = 'b'
@(ptr+cc+2) = 'c'
txt.print(name)
txt.nl()
}