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 { when {
iterations == 0 -> {} iterations == 0 -> {}
iterations <= 255 -> { iterations <= 255 -> {
out(""" out(" lda #${iterations}")
lda #${iterations} repeatByteCountInA(counterLabel, repeatLabel, endLabel, stmt.body)
sta $counterLabel
$repeatLabel lda $counterLabel
beq $endLabel
dec $counterLabel
""")
translate(stmt.body)
out("""
jmp $repeatLabel
$counterLabel .byte 0
$endLabel""")
} }
else -> { else -> {
out(""" out(" lda #<${iterations} | ldy #>${iterations}")
lda #<${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 sta $counterLabel
lda #>${iterations} sty $counterLabel+1
sta $counterLabel+1
$repeatLabel lda $counterLabel $repeatLabel lda $counterLabel
bne + bne +
lda $counterLabel+1 lda $counterLabel+1
@ -723,24 +754,25 @@ $repeatLabel lda $counterLabel
dec $counterLabel+1 dec $counterLabel+1
+ dec $counterLabel + dec $counterLabel
""") """)
translate(stmt.body) translate(body)
out(""" out("""
jmp $repeatLabel jmp $repeatLabel
$counterLabel .word 0 $counterLabel .word 0
$endLabel""") $endLabel""")
} }
}
}
is IdentifierReference -> {
TODO("iterations ${stmt.iterations}")
}
else -> {
TODO("repeat loop with iterations ${stmt.iterations}")
}
}
loopEndLabels.pop() private fun repeatByteCountInA(counterLabel: String, repeatLabel: String, endLabel: String, body: AnonymousScope) {
loopContinueLabels.pop() // 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) { private fun translate(stmt: WhileLoop) {

View File

@ -9,5 +9,38 @@ main {
sub start() { 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() { sub start() {
graphics.enable_bitmap_mode() graphics.enable_bitmap_mode()
turtle.init() turtle.init()
; turtle.pu()
repeat 100 { ; turtle.pos(150, 110)
while c64.RASTER { ; turtle.pd()
}
}
ubyte i ubyte i
for i in 0 to 100 { for i in 0 to 100 {