finalize repeat asmgen

This commit is contained in:
Irmen de Jong 2020-07-26 01:32:27 +02:00
parent af8279a9b9
commit 3c55719bf1
3 changed files with 99 additions and 36 deletions

View File

@ -695,25 +695,56 @@ internal class AsmGen(private val program: Program,
when {
iterations == 0 -> {}
iterations <= 255 -> {
out("""
lda #${iterations}
sta $counterLabel
$repeatLabel lda $counterLabel
beq $endLabel
dec $counterLabel
""")
translate(stmt.body)
out("""
jmp $repeatLabel
$counterLabel .byte 0
$endLabel""")
out(" lda #${iterations}")
repeatByteCountInA(counterLabel, repeatLabel, endLabel, stmt.body)
}
else -> {
out("""
lda #<${iterations}
out(" lda #<${iterations} | ldy #>${iterations}")
repeatWordCountInAY(counterLabel, repeatLabel, endLabel, stmt.body)
}
}
}
is IdentifierReference -> {
val vardecl = (stmt.iterations as IdentifierReference).targetStatement(program.namespace) as VarDecl
val name = asmIdentifierName(stmt.iterations as IdentifierReference)
when(vardecl.datatype) {
DataType.UBYTE, DataType.BYTE -> {
out(" lda $name")
repeatByteCountInA(counterLabel, repeatLabel, endLabel, stmt.body)
}
DataType.UWORD, DataType.WORD -> {
out(" lda $name | ldy $name+1")
repeatWordCountInAY(counterLabel, repeatLabel, endLabel, stmt.body)
}
else -> throw AssemblyError("invalid loop variable datatype $vardecl")
}
}
else -> {
translateExpression(stmt.iterations!!)
val dt = stmt.iterations!!.inferType(program).typeOrElse(DataType.STRUCT)
when (dt) {
in ByteDatatypes -> {
out(" inx | lda ${ESTACK_LO_HEX},x")
repeatByteCountInA(counterLabel, repeatLabel, endLabel, stmt.body)
}
in WordDatatypes -> {
out(" inx | lda ${ESTACK_LO_HEX},x | ldy ${ESTACK_HI_HEX},x")
repeatWordCountInAY(counterLabel, repeatLabel, endLabel, stmt.body)
}
else -> throw AssemblyError("invalid loop expression datatype $dt")
}
}
}
loopEndLabels.pop()
loopContinueLabels.pop()
}
private fun repeatWordCountInAY(counterLabel: String, repeatLabel: String, endLabel: String, body: AnonymousScope) {
// note: A/Y must have been loaded with the number of iterations already!
out("""
sta $counterLabel
lda #>${iterations}
sta $counterLabel+1
sty $counterLabel+1
$repeatLabel lda $counterLabel
bne +
lda $counterLabel+1
@ -723,24 +754,25 @@ $repeatLabel lda $counterLabel
dec $counterLabel+1
+ dec $counterLabel
""")
translate(stmt.body)
out("""
translate(body)
out("""
jmp $repeatLabel
$counterLabel .word 0
$endLabel""")
}
}
}
is IdentifierReference -> {
TODO("iterations ${stmt.iterations}")
}
else -> {
TODO("repeat loop with iterations ${stmt.iterations}")
}
}
}
loopEndLabels.pop()
loopContinueLabels.pop()
private fun repeatByteCountInA(counterLabel: String, repeatLabel: String, endLabel: String, body: AnonymousScope) {
// note: A must have been loaded with the number of iterations already!
out("""
sta $counterLabel
$repeatLabel lda $counterLabel
beq $endLabel
dec $counterLabel""")
translate(body)
out("""
jmp $repeatLabel
$counterLabel .byte 0
$endLabel""")
}
private fun translate(stmt: WhileLoop) {

View File

@ -9,5 +9,38 @@ main {
sub start() {
}
repeat 10 {
c64.CHROUT('*')
}
c64.CHROUT('\n')
ubyte ub = 9
repeat ub {
c64.CHROUT('*')
}
c64.CHROUT('\n')
repeat 320 {
c64.CHROUT('+')
}
c64.CHROUT('\n')
uword uw = 320
repeat uw {
c64.CHROUT('-')
}
c64.CHROUT('\n')
ub = 7
repeat ub+2 {
c64.CHROUT('*')
}
c64.CHROUT('\n')
uw = 318
repeat uw+2 {
c64.CHROUT('*')
}
c64.CHROUT('\n')
}
}

View File

@ -10,11 +10,9 @@ main {
sub start() {
graphics.enable_bitmap_mode()
turtle.init()
repeat 100 {
while c64.RASTER {
}
}
; turtle.pu()
; turtle.pos(150, 110)
; turtle.pd()
ubyte i
for i in 0 to 100 {