From ae648b8a0a4fa2cf478e21c0a0af38c483a28d5d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 23 Dec 2020 01:55:15 +0100 Subject: [PATCH] subroutines can now be defined even within regular code and will not disrupt the generated code anymore (they are moved to the end of their scope by the compiler) --- .../ast/processing/StatementReorderer.kt | 8 + compiler/src/prog8/compiler/Main.kt | 2 +- examples/cx16/gfx2.p8 | 207 ++++++++++++++++++ examples/test.p8 | 195 ++--------------- 4 files changed, 231 insertions(+), 181 deletions(-) create mode 100644 examples/cx16/gfx2.p8 diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index e148634cb..5d2742017 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -69,6 +69,14 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte ) } } + + val subs = subroutine.statements.filterIsInstance() + if(subs.isNotEmpty()) { + // all subroutines defined within this subroutine are moved to the end + return subs.map { IAstModification.Remove(it, subroutine) } + + subs.map { IAstModification.InsertLast(it, subroutine) } + } + return noModifications } diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index c96fe45a3..76f30d600 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -223,7 +223,7 @@ private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir: programAst.processAstBeforeAsmGeneration(errors) errors.handle() - // printAst(programAst) + printAst(programAst) CompilationTarget.instance.machine.initializeZeropage(compilerOptions) val assembly = CompilationTarget.instance.asmGenerator( diff --git a/examples/cx16/gfx2.p8 b/examples/cx16/gfx2.p8 new file mode 100644 index 000000000..065a27ce0 --- /dev/null +++ b/examples/cx16/gfx2.p8 @@ -0,0 +1,207 @@ +%import textio +%import diskio +%import floats +%import graphics +%import test_stack +%zeropage basicsafe +%option no_sysinit + +main { + + sub start () { + + gfx2.set_mode(128) + gfx2.clear_screen() + + uword offset + ubyte angle + uword x + uword y + when gfx2.active_mode { + 0, 1 -> { + for offset in 0 to 90 step 3 { + for angle in 0 to 255 { + x = $0008+sin8u(angle)/2 + y = $0008+cos8u(angle)/2 + gfx2.plot(x+offset*2,y+offset, lsb(x+y)) + } + } + } + 128 -> { + for offset in 0 to 190 step 6 { + for angle in 0 to 255 { + x = $0008+sin8u(angle) + y = $0008+cos8u(angle) + gfx2.plot(x+offset*2,y+offset, 1) + } + } + } + } + } +} + +gfx2 { + + ubyte active_mode = 255 + uword width = 0 + uword height = 0 + ubyte bpp = 0 + + sub set_mode(ubyte mode) { + ; mode 0 = bitmap 320 x 240 x 1c monochrome + ; mode 1 = bitmap 320 x 240 x 256c + ; mode 128 = bitmap 640 x 480 x 1c monochrome + ; ...other modes? + + when mode { + 0 -> { + ; 320 x 240 x 1c + cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 + cx16.VERA_DC_HSCALE = 64 + cx16.VERA_DC_VSCALE = 64 + cx16.VERA_L1_CONFIG = %00000100 + cx16.VERA_L1_MAPBASE = 0 + cx16.VERA_L1_TILEBASE = 0 + width = 320 + height = 240 + bpp = 1 + } + 1 -> { + ; 320 x 240 x 256c + cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 + cx16.VERA_DC_HSCALE = 64 + cx16.VERA_DC_VSCALE = 64 + cx16.VERA_L1_CONFIG = %00000111 + cx16.VERA_L1_MAPBASE = 0 + cx16.VERA_L1_TILEBASE = 0 + width = 320 + height = 240 + bpp = 8 + } + 128 -> { + ; 640 x 480 x 1c + cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 + cx16.VERA_DC_HSCALE = 128 + cx16.VERA_DC_VSCALE = 128 + cx16.VERA_L1_CONFIG = %00000100 + cx16.VERA_L1_MAPBASE = 0 + cx16.VERA_L1_TILEBASE = %00000001 + width = 640 + height = 480 + bpp = 1 + } + } + active_mode = mode + } + + sub clear_screen() { + when active_mode { + 0 -> { + ; 320 x 240 x 1c + cx16.VERA_CTRL = 0 + cx16.VERA_ADDR_H = %00010000 + cx16.VERA_ADDR_M = 0 + cx16.VERA_ADDR_L = 0 + repeat 240/2/8 + cs_innerloop640() + } + 1 -> { + ; 320 x 240 x 256c + cx16.VERA_CTRL = 0 + cx16.VERA_ADDR_H = %00010000 + cx16.VERA_ADDR_M = 0 + cx16.VERA_ADDR_L = 0 + repeat 240/2 + cs_innerloop640() + } + 128 -> { + ; 640 x 480 x 1c + cx16.VERA_CTRL = 0 + cx16.VERA_ADDR_H = %00010000 + cx16.VERA_ADDR_M = 0 + cx16.VERA_ADDR_L = 0 + repeat 480/8 + cs_innerloop640() + } + } + } + + sub plot(uword x, uword y, ubyte color) { + ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1] + when active_mode { + 0 -> { + cx16.vpoke_or(0, y*(320/8) + x/8, bits[lsb(x)&7]) ; TODO !?!? if the &7 remains, the code at the '128' label is wrong!!! if changed or removed, the code at 128 works fine! + } + 1 -> { + void addr_mul_320_add_24(y, x) ; 24 bits result is in r0 and r1L + cx16.vpoke(lsb(cx16.r1), cx16.r0, color) + } + 128 -> { + cx16.vpoke_or(0, y*(640/8) + x/8, bits[lsb(x)&7]) + } + } + return + + + asmsub addr_mul_320_add_24(uword address @R0, uword value @AY) -> uword @R0, ubyte @R1 { + %asm {{ + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda cx16.r0 + sta P8ZP_SCRATCH_B1 + lda cx16.r0+1 + sta cx16.r1 + sta P8ZP_SCRATCH_REG + lda cx16.r0 + asl a + rol P8ZP_SCRATCH_REG + asl a + rol P8ZP_SCRATCH_REG + asl a + rol P8ZP_SCRATCH_REG + asl a + rol P8ZP_SCRATCH_REG + asl a + rol P8ZP_SCRATCH_REG + asl a + rol P8ZP_SCRATCH_REG + sta cx16.r0 + lda P8ZP_SCRATCH_B1 + clc + adc P8ZP_SCRATCH_REG + sta cx16.r0+1 + bcc + + inc cx16.r1 ++ ; now add the value to this 24-bits number + lda cx16.r0 + clc + adc P8ZP_SCRATCH_W1 + sta cx16.r0 + lda cx16.r0+1 + adc P8ZP_SCRATCH_W1+1 + sta cx16.r0+1 + bcc + + inc cx16.r1 ++ lda cx16.r1 + rts + }} + } + } + + asmsub cs_innerloop640() { + %asm {{ + ldy #80 +- stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + stz cx16.VERA_DATA0 + dey + bne - + rts + }} + } +} diff --git a/examples/test.p8 b/examples/test.p8 index 24181abaf..878d107f2 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,188 +8,23 @@ main { -; uword adres -; ubyte adreshi - - sub start () { - txt.print("hello\n") + ubyte value = 100 + ubyte add = 1 - gfx2.set_mode(128) - gfx2.clear_screen() - - uword offset - ubyte angle - uword x - uword y - when gfx2.active_mode { - 0 -> { - for offset in 0 to 90 step 3 { - for angle in 0 to 255 { - x = $0008+sin8u(angle)/2 - y = $0008+cos8u(angle)/2 - gfx2.plot(x+offset*2,y+offset, lsb(x+y)) - } - } - } - 128 -> { - for offset in 0 to 190 step 6 { - for angle in 0 to 255 { - x = $0008+sin8u(angle) - y = $0008+cos8u(angle) - gfx2.plot(x+offset*2,y+offset, 1) - } - } - } - } - } -} - -gfx2 { - - ubyte active_mode = 255 - uword width = 0 - uword height = 0 - ubyte bpp = 0 - - sub set_mode(ubyte mode) { - ; mode 0 = bitmap 320 x 240 x 256c - ; mode 128 = bitmap 640 x 480 x 1c monochrome - ; ... - - when mode { - 0 -> { - ; 320 x 240 x 256c - cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 - cx16.VERA_DC_HSCALE = 64 - cx16.VERA_DC_VSCALE = 64 - cx16.VERA_L1_CONFIG = %00000111 - cx16.VERA_L1_MAPBASE = 0 - cx16.VERA_L1_TILEBASE = 0 - width = 320 - height = 240 - bpp = 8 - } - 128 -> { - ; 640 x 480 x 1c - cx16.VERA_DC_VIDEO = (cx16.VERA_DC_VIDEO & %11001111) | %00100000 ; enable only layer 1 - cx16.VERA_DC_HSCALE = 128 - cx16.VERA_DC_VSCALE = 128 - cx16.VERA_L1_CONFIG = %00000100 - cx16.VERA_L1_MAPBASE = 0 - cx16.VERA_L1_TILEBASE = %00000001 - width = 640 - height = 480 - bpp = 1 - } - } - active_mode = mode - } - - sub clear_screen() { - when active_mode { - 0 -> { - ; 320 x 240 x 256c - cx16.VERA_CTRL = 0 - cx16.VERA_ADDR_H = %00010000 - cx16.VERA_ADDR_M = 0 - cx16.VERA_ADDR_L = 0 - repeat 240/4 - cs_innerloop1280() - } - 128 -> { - ; 640 x 480 x 1c - cx16.VERA_CTRL = 0 - cx16.VERA_ADDR_H = %00010000 - cx16.VERA_ADDR_M = 0 - cx16.VERA_ADDR_L = 0 - repeat 480/16 - cs_innerloop1280() - } - } - } - - asmsub cs_innerloop1280() { - %asm {{ - ldy #160 -- stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - stz cx16.VERA_DATA0 - dey - bne - - rts - }} - } - - - sub plot(uword x, uword y, ubyte color) { - uword addr - ubyte addrhi - - when active_mode { - 0 -> { - addr = y - addr_mul_24_320() - addr_add_word_24(x) - cx16.vpoke(addrhi, addr, color) - } - 128 -> { - ubyte[8] bits = [128, 64, 32, 16, 8, 4, 2, 1] - cx16.vpoke_or(0, y*(640/8) + x/8, bits[lsb(x)&7]) - } - } - - - ; TODO when subs are in front of real code, they generate in place and fuck up the code. Move them to the bottom? - asmsub addr_mul_24_320() { - ; addr = addr * 256 + addr * 64, bits 16-23 into addrhi - %asm {{ - lda addr - sta P8ZP_SCRATCH_B1 - lda addr+1 - sta addrhi - sta P8ZP_SCRATCH_REG - lda addr - asl a - rol P8ZP_SCRATCH_REG - asl a - rol P8ZP_SCRATCH_REG - asl a - rol P8ZP_SCRATCH_REG - asl a - rol P8ZP_SCRATCH_REG - asl a - rol P8ZP_SCRATCH_REG - asl a - rol P8ZP_SCRATCH_REG - sta addr - lda P8ZP_SCRATCH_B1 - clc - adc P8ZP_SCRATCH_REG - sta addr+1 - bcc + - inc addrhi - + rts - }} - } - - asmsub addr_add_word_24(uword w @ AY) { - %asm {{ - clc - adc addr - sta addr - tya - adc addr+1 - sta addr+1 - bcc + - inc addrhi -+ rts - }} + sub dinges() { + value+=add } + + sub dinges2() { + value+=add + } + + txt.print_ub(value) + txt.chrout('\n') + dinges() + dinges2() + txt.print_ub(value) + txt.chrout('\n') } }