diff --git a/compiler/res/prog8lib/diskio.p8 b/compiler/res/prog8lib/diskio.p8 index 5342fd5eb..4130739fc 100644 --- a/compiler/res/prog8lib/diskio.p8 +++ b/compiler/res/prog8lib/diskio.p8 @@ -73,21 +73,18 @@ io_error: sub list_files(ubyte drivenumber, uword pattern, ubyte suffixmatch, uword name_ptrs, ubyte max_names) -> ubyte { ; -- fill the array 'name_ptrs' with (pointers to) the names of the files requested. - ubyte[256] names_buffer - ubyte[256] names_buffer1 ; to store a bit more names - ; TODO names_buffer = memory("filenames", 512) - uword buf_ptr = &names_buffer - names_buffer1[0] = 0 ; TODO force array to exist + uword names_buffer = memory("filenames", 512) + uword buffer_start = names_buffer ubyte files_found = 0 if lf_start_list(drivenumber, pattern, suffixmatch) { while lf_next_entry() { - @(name_ptrs) = lsb(buf_ptr) + @(name_ptrs) = lsb(names_buffer) name_ptrs++ - @(name_ptrs) = msb(buf_ptr) + @(name_ptrs) = msb(names_buffer) name_ptrs++ - buf_ptr += strcopy(diskio.list_filename, buf_ptr) + 1 + names_buffer += strcopy(diskio.list_filename, names_buffer) + 1 files_found++ - if buf_ptr - &names_buffer > (len(names_buffer) + len(names_buffer1) - 18) + if names_buffer - buffer_start > 512-18 break if files_found == max_names break diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index ffc785049..0a5f2801d 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -697,7 +697,6 @@ class AsmGenInfo { var usedRegsaveY = false var usedFloatEvalResultVar1 = false var usedFloatEvalResultVar2 = false - val removals = mutableListOf() class ArrayIndexerInfo(val name: String, val replaces: ArrayIndex) } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 4d01c448e..2d075d110 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -51,6 +51,7 @@ internal class AsmGen(private val program: Program, internal val loopEndLabels = ArrayDeque() private val blockLevelVarInits = mutableMapOf>() internal val slabs = mutableMapOf() + internal val removals = mutableListOf>() override fun compileToAssembly(): IAssemblyProgram { assemblyLines.clear() @@ -64,6 +65,12 @@ internal class AsmGen(private val program: Program, throw AssemblyError("first block should be 'main'") for(b in program.allBlocks()) block2asm(b) + + for(removal in removals.toList()) { + removal.second.remove(removal.first) + removals.remove(removal) + } + slaballocations() footer() @@ -845,10 +852,12 @@ internal class AsmGen(private val program: Program, out("; statements") sub.statements.forEach{ translate(it) } - for(stmt in sub.asmGenInfo.removals) { - sub.remove(stmt) + for(removal in removals.toList()) { + if(removal.second==sub) { + removal.second.remove(removal.first) + removals.remove(removal) + } } - sub.asmGenInfo.removals.clear() out("; variables") out("; register saves") diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 2ba1136e0..0a957fca2 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -35,25 +35,25 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val if(discardResult && resultToStack) throw AssemblyError("cannot both discard the result AND put it onto stack") - val scope = (fcall as Node).definingSubroutine()!! + val sscope = (fcall as Node).definingSubroutine() when (func.name) { "msb" -> funcMsb(fcall, resultToStack) "lsb" -> funcLsb(fcall, resultToStack) "mkword" -> funcMkword(fcall, resultToStack) - "abs" -> funcAbs(fcall, func, resultToStack, scope) + "abs" -> funcAbs(fcall, func, resultToStack, sscope) "swap" -> funcSwap(fcall) "min", "max" -> funcMinMax(fcall, func, resultToStack) "sum" -> funcSum(fcall, resultToStack) "any", "all" -> funcAnyAll(fcall, func, resultToStack) "sin8", "sin8u", "sin16", "sin16u", - "cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, scope) - "sgn" -> funcSgn(fcall, func, resultToStack, scope) + "cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, sscope) + "sgn" -> funcSgn(fcall, func, resultToStack, sscope) "sin", "cos", "tan", "atan", "ln", "log2", "sqrt", "rad", "deg", "round", "floor", "ceil", - "rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, scope) + "rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, sscope) "rnd", "rndw" -> funcRnd(func, resultToStack) - "sqrt16" -> funcSqrt16(fcall, func, resultToStack, scope) + "sqrt16" -> funcSqrt16(fcall, func, resultToStack, sscope) "rol" -> funcRol(fcall) "rol2" -> funcRol2(fcall) "ror" -> funcRor(fcall) @@ -80,21 +80,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val "clear_irqd" -> asmgen.out(" cli") "set_irqd" -> asmgen.out(" sei") "strlen" -> funcStrlen(fcall, resultToStack) - "strcmp" -> funcStrcmp(fcall, func, resultToStack, scope) + "strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope) "strcopy" -> { - translateArguments(fcall.args, func, scope) + translateArguments(fcall.args, func, sscope) if(resultToStack) asmgen.out(" jsr prog8_lib.func_strcopy_to_stack") else asmgen.out(" jsr prog8_lib.func_strcopy") } - "memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, scope) + "memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope) "substr", "leftstr", "rightstr" -> { - translateArguments(fcall.args, func, scope) + translateArguments(fcall.args, func, sscope) asmgen.out(" jsr prog8_lib.func_${func.name}") } "exit" -> { - translateArguments(fcall.args, func, scope) + translateArguments(fcall.args, func, sscope) asmgen.out(" jmp prog8_lib.func_exit") } "progend" -> { @@ -138,14 +138,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val // remove the variable for the name, it's not used as a variable only as a tag for the assembler. val nameDecl = scope.statements.single { it is VarDecl && it.name==nameRef.nameInSource.single() } - (scope as Subroutine).asmGenInfo.removals.add(nameDecl) + asmgen.removals.add(Pair(nameDecl, scope)) asmgen.slabs[name] = size } - private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature, scope: Subroutine) { + private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature, scope: Subroutine?) { if(CompilationTarget.instance is Cx16Target) { when(func.name) { "memset" -> { + if(scope==null) + throw AssemblyError("cannot call memset() outside of a subroutine scope") // use the ROM function of the Cx16 asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0) asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1) @@ -164,6 +166,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val return } + if(scope==null) + throw AssemblyError("cannot call memcopy() outside of a subroutine scope") + // use the ROM function of the Cx16 asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0) asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1) @@ -192,7 +197,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } } - private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) if(resultToStack) asmgen.out(" jsr prog8_lib.func_strcmp_stack") @@ -200,7 +205,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.out(" jsr prog8_lib.func_strcmp") } - private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) if(resultToStack) asmgen.out(" jsr prog8_lib.func_sqrt16_stack") @@ -208,7 +213,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.out(" jsr prog8_lib.func_sqrt16_into_A") } - private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) if(resultToStack) asmgen.out(" jsr prog8_lib.func_${func.name}_stack") @@ -474,7 +479,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.assignExpressionToVariable(indexerExpr, "prog8_lib.${operation}_array_u${dt}._arg_index", DataType.UBYTE, null) } - private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) if(resultToStack) asmgen.out(" jsr floats.func_${func.name}_stack") @@ -482,7 +487,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen.out(" jsr floats.func_${func.name}_fac1") } - private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) val dt = fcall.args.single().inferType(program) if(resultToStack) { @@ -972,7 +977,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } } - private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) { + private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) { translateArguments(fcall.args, func, scope) val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT) if(resultToStack) { @@ -1070,7 +1075,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val """) } - private fun translateArguments(args: MutableList, signature: FSignature, scope: Subroutine) { + private fun translateArguments(args: MutableList, signature: FSignature, scope: Subroutine?) { val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) }) fun getSourceForFloat(value: Expression): AsmAssignSource { @@ -1083,6 +1088,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val throw AssemblyError("float literals should have been converted into autovar") } else -> { + if(scope==null) + throw AssemblyError("cannot use float arguments outside of a subroutine scope") + scope.asmGenInfo.usedFloatEvalResultVar2 = true val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position) val addr = AddressOf(variable, value.position) diff --git a/examples/cx16/imageviewer/bmp_module.p8 b/examples/cx16/imageviewer/bmp_module.p8 index 269744d4b..0087088a2 100644 --- a/examples/cx16/imageviewer/bmp_module.p8 +++ b/examples/cx16/imageviewer/bmp_module.p8 @@ -13,17 +13,9 @@ bmp_module { ubyte bpp uword offsetx uword offsety - ubyte[256] palette0 - ubyte[256] palette1 - ubyte[256] palette2 - ubyte[256] palette3 + uword palette = memory("palette", 256*4) uword total_read = 0 - palette0[0] = 0 - palette1[0] = 0 - palette2[0] = 0 - palette3[0] = 0 - if diskio.f_open(8, filenameptr) { size = diskio.f_read(header, $36) if size==$36 { @@ -41,13 +33,13 @@ bmp_module { repeat skip_hdr void c64.CHRIN() total_read += skip_hdr - size = diskio.f_read(&palette0, num_colors*4) + size = diskio.f_read(palette, num_colors*4) if size==num_colors*4 { total_read += size repeat bm_data_offset - total_read void c64.CHRIN() gfx2.clear_screen() - custompalette.set_bgra(&palette0, num_colors) + custompalette.set_bgra(palette, num_colors) decode_bitmap() load_ok = true } diff --git a/examples/cx16/imageviewer/ci_module.p8 b/examples/cx16/imageviewer/ci_module.p8 index d984d3f64..1c0a47f28 100644 --- a/examples/cx16/imageviewer/ci_module.p8 +++ b/examples/cx16/imageviewer/ci_module.p8 @@ -47,14 +47,9 @@ ; (doing it in chunks of 8 kb allows for sticking each chunk in one of the banked 8kb ram blocks, or even copy it directly to the screen) ci_module { - %option force_output - ubyte[256] buffer - ubyte[256] buffer2 ; add two more buffers to make enough space - ubyte[256] buffer3 ; to store a 256 color palette - ubyte[256] buffer4 ; .. and some more to be able to store 1280= - ubyte[256] buffer5 ; two 640 bytes worth of bitmap scanline data sub show_image(uword filename) -> ubyte { + uword buffer = memory("buffer", 620*2) ; enough to store two scanlines of 640 bytes ubyte read_success = false uword bitmap_load_address = progend() ; uword max_bitmap_size = $9eff - bitmap_load_address @@ -62,18 +57,18 @@ ci_module { if(diskio.f_open(8, filename)) { uword size = diskio.f_read(buffer, 12) ; read the header if size==12 { - if buffer[0]=='c' and buffer[1]=='i' and buffer[2] == 9 { - uword width = mkword(buffer[4], buffer[3]) - uword height = mkword(buffer[6], buffer[5]) - ubyte bpp = buffer[7] + if @(buffer+0)=='c' and @(buffer+1)=='i' and @(buffer+2) == 9 { + uword width = mkword(@(buffer+4), @(buffer+3)) + uword height = mkword(@(buffer+6), @(buffer+5)) + ubyte bpp = @(buffer+7) uword num_colors = 2 ** bpp - ubyte flags = buffer[8] + ubyte flags = @(buffer+8) ubyte compression = flags & %00000011 ubyte palette_format = (flags & %00000100) >> 2 ubyte bitmap_format = (flags & %00001000) >> 3 ; ubyte hscale = (flags & %00010000) >> 4 ; ubyte vscale = (flags & %00100000) >> 5 - uword bitmap_size = mkword(buffer[10], buffer[9]) + uword bitmap_size = mkword(@(buffer+10), @(buffer+9)) uword palette_size = num_colors*2 if palette_format palette_size += num_colors ; 3 diff --git a/examples/cx16/imageviewer/iff_module.p8 b/examples/cx16/imageviewer/iff_module.p8 index b6992f8e3..e5f460f49 100644 --- a/examples/cx16/imageviewer/iff_module.p8 +++ b/examples/cx16/imageviewer/iff_module.p8 @@ -4,10 +4,7 @@ %import diskio iff_module { - ; TODO uword cmap = memory("palette", 768) - ubyte[256] cmap - ubyte[256] cmap1 - ubyte[256] cmap2 + uword cmap uword num_colors uword[16] cycle_rates uword[16] cycle_rate_ticks @@ -33,10 +30,8 @@ iff_module { ubyte have_cmap = false ubyte cycle_crng = false ubyte cycle_ccrt = false - cmap[0] = 0 - cmap1[0] = 0 - cmap2[0] = 0 num_cycles = 0 + cmap = memory("palette", 256*4) ; only use 768 of these, but this allows re-use of the same block that the bmp module allocates if diskio.f_open(8, filenameptr) { size = diskio.f_read(buffer, 12) @@ -63,7 +58,7 @@ iff_module { } else if chunk_id == "cmap" { have_cmap = true - diskio.f_read_exact(&cmap, chunk_size_lo) + diskio.f_read_exact(cmap, chunk_size_lo) } else if chunk_id == "crng" { ; DeluxePaint color cycle range @@ -110,7 +105,7 @@ iff_module { height /= 2 ; interlaced: just skip every odd scanline later if camg & $0080 and have_cmap make_ehb_palette() - palette.set_rgb8(&cmap, num_colors) + palette.set_rgb8(cmap, num_colors) if compression decode_rle() else @@ -154,7 +149,7 @@ iff_module { sub make_ehb_palette() { ; generate 32 additional Extra-Halfbrite colors in the cmap - uword palletteptr = &cmap + uword palletteptr = cmap uword ehbptr = palletteptr + 32*3 repeat 32 { @(ehbptr) = @(palletteptr)>>1 @@ -320,7 +315,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1 } if changed - palette.set_rgb8(&cmap, num_colors) ; set the new palette + palette.set_rgb8(cmap, num_colors) ; set the new palette sub do_cycle(uword low, uword high, ubyte reversed) { low *= 3 @@ -332,7 +327,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1 ubyte blue if reversed { - cptr = &cmap + low + cptr = cmap + low red = @(cptr) green = @(cptr+1) blue = @(cptr+2) @@ -346,7 +341,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1 cptr++ @(cptr) = blue } else { - cptr = &cmap + high + cptr = cmap + high red = @(cptr) cptr++ green = @(cptr) diff --git a/examples/cx16/imageviewer/imageviewer.p8 b/examples/cx16/imageviewer/imageviewer.p8 index 6fe2591ba..9e137cdd6 100644 --- a/examples/cx16/imageviewer/imageviewer.p8 +++ b/examples/cx16/imageviewer/imageviewer.p8 @@ -98,9 +98,9 @@ main { } } ; else if strcmp(extension, ".ci")==0 { -; txt.print("loading ") -; txt.print("ci\n") -; if bmp_module.ci_module(filenameptr) { +;; txt.print("loading ") +;; txt.print("ci\n") +; if ci_module.show_image(filenameptr) { ; cx16.wait(180) ; } else { ; load_error(filenameptr) diff --git a/examples/test.p8 b/examples/test.p8 index db52e689c..9197681cd 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,38 +5,15 @@ main { + ;uword cmap = memory("palette", 256*4) ; only use 768 of these, but this allows re-use of the same block that the bmp module allocates + uword num_colors = rnd() + sub start () { - thing() - thing() - thing() - thing() - thing() + txt.chrout('\n') + txt.chrout('\n') test_stack.test() - sub thing() -> ubyte { - uword buffer = memory("buffer", 512) - uword buffer2 = memory("buffer", 512) - uword buffer3 = memory("cache", 20) - - txt.print_uwhex(buffer, true) - txt.chrout('\n') - txt.print_uwhex(buffer2, true) - txt.chrout('\n') - txt.print_uwhex(buffer3, true) - txt.chrout('\n') - buffer+=$1111 - buffer2+=$1111 - buffer3+=$1111 - txt.print_uwhex(buffer, true) - txt.chrout('\n') - txt.print_uwhex(buffer2, true) - txt.chrout('\n') - txt.print_uwhex(buffer3, true) - txt.chrout('\n') - txt.chrout('\n') - return 0 - } } }