diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt index 5bbe337a7..9d93627a2 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt @@ -106,6 +106,12 @@ internal class AstIdentifiersChecker(private val program: Program, private val e if(subroutine.isAsmSubroutine && subroutine.statements.any{it !is InlineAssembly}) { errors.err("asmsub can only contain inline assembly (%asm)", subroutine.position) } + + if(subroutine.name == subroutine.definingBlock().name) { + // subroutines cannot have the same name as their enclosing block, + // because this causes symbol scoping issues in the resulting assembly source + nameError(subroutine.name, subroutine.position, subroutine.definingBlock()) + } } super.visit(subroutine) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt index fe3cd9007..212911571 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/AsmGen.kt @@ -1502,7 +1502,7 @@ $label nop""") val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second) if(saveA) out(" pha") - assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) if(saveA) out(" pla") @@ -1514,7 +1514,7 @@ $label nop""") out(" lda (${asmSymbolName(pointervar)}),y") } else { // copy the pointer var to zp first - assignExpressionToVariable(ptrAndIndex.first, asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + assignExpressionToVariable(ptrAndIndex.first, "P8ZP_SCRATCH_W2", DataType.UWORD, null) assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y) out(" lda (P8ZP_SCRATCH_W2),y") } diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt index 2a5c22c1c..7a53daff6 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/ExpressionsAsmGen.kt @@ -1696,7 +1696,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) { fun assignViaExprEval() { - asmgen.assignExpressionToVariable(expr.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + asmgen.assignExpressionToVariable(expr.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, null) if (asmgen.isTargetCpu(CpuType.CPU65c02)) { if (pushResultOnEstack) { asmgen.out(" lda (P8ZP_SCRATCH_W2) | dex | sta P8ESTACK_LO+1,x") diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt index c0b877803..f44866ef1 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/FunctionCallAsmGen.kt @@ -319,10 +319,9 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg register!! if(requiredDt largerThan valueDt) { // we need to sign extend the source, do this via temporary word variable - val scratchVar = asmgen.asmVariableName("P8ZP_SCRATCH_W1") - asmgen.assignExpressionToVariable(value, scratchVar, DataType.UBYTE, sub) - asmgen.signExtendVariableLsb(scratchVar, valueDt) - asmgen.assignVariableToRegister(scratchVar, register) + asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", DataType.UBYTE, sub) + asmgen.signExtendVariableLsb("P8ZP_SCRATCH_W1", valueDt) + asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register) } else { val target: AsmAssignTarget = if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters)) diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt index 5750cf73a..5b80f89c5 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AssignmentAsmGen.kt @@ -115,7 +115,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen } SourceStorageKind.MEMORY -> { fun assignViaExprEval(expression: Expression) { - assignExpressionToVariable(expression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, assign.target.scope) + assignExpressionToVariable(expression, "P8ZP_SCRATCH_W2", DataType.UWORD, assign.target.scope) if (asmgen.isTargetCpu(CpuType.CPU65c02)) asmgen.out(" lda (P8ZP_SCRATCH_W2)") else @@ -320,7 +320,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen if(targetDt in WordDatatypes) { fun assignViaExprEval(addressExpression: Expression) { - asmgen.assignExpressionToVariable(addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + asmgen.assignExpressionToVariable(addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, null) if (asmgen.isTargetCpu(CpuType.CPU65c02)) asmgen.out(" lda (P8ZP_SCRATCH_W2)") else @@ -2089,7 +2089,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen fun storeViaExprEval() { when(addressExpr) { is NumericLiteralValue, is IdentifierReference -> { - assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null) if (asmgen.isTargetCpu(CpuType.CPU65c02)) asmgen.out(" sta (P8ZP_SCRATCH_W2)") else @@ -2098,7 +2098,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen else -> { // same as above but we need to save the A register asmgen.out(" pha") - assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null) + assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null) asmgen.out(" pla") if (asmgen.isTargetCpu(CpuType.CPU65c02)) asmgen.out(" sta (P8ZP_SCRATCH_W2)") diff --git a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt index 4af648264..ba60bee07 100644 --- a/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/cpu6502/codegen/assignment/AugmentableAssignmentAsmGen.kt @@ -1778,7 +1778,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, asmgen.out(" sta (P8ZP_SCRATCH_W1),y") } else -> { - asmgen.assignExpressionToVariable(mem.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, target.scope) + asmgen.assignExpressionToVariable(mem.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope) asmgen.out(""" ldy #0 lda (P8ZP_SCRATCH_W2),y @@ -1846,7 +1846,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program, asmgen.out(" sta (P8ZP_SCRATCH_W1),y") } else -> { - asmgen.assignExpressionToVariable(memory.addressExpression, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, target.scope) + asmgen.assignExpressionToVariable(memory.addressExpression, "P8ZP_SCRATCH_W2", DataType.UWORD, target.scope) asmgen.out(""" ldy #0 lda (P8ZP_SCRATCH_W2),y diff --git a/docs/source/index.rst b/docs/source/index.rst index 33a355cc1..4b2090f37 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -165,10 +165,21 @@ For Windows it's possible to get that as well; check out `AdoptOpenJDK `_. +In C64 mode, the compiler assumes the presence of the `Vice emulator `_. If you're targeting the CommanderX16 instead, there's the `x16emu `_. -Make sure you use cx16 emulator and roms **V39 or newer**! Starting from version 6.5, prog8 targets that system version. -Your program may work on V38 but that will only be by luck. + +.. attention:: **Commander-X16 V38 vs V39** + Starting with Prog8 7.0 the Commander-X16 support targets the upcoming v39 version of the emulator + and roms, which reflects the current state of the hardware design. + Unfortunately, these have not yet been officially released (at the time of writing, v38 is still + the latest official release). So you have to either compile them from source yourself + or obtain a precompiled version from someone else. + Your cx16 program compiled by prog8 7.0 is meant for v39 but *may* still work on the older v38 release of the emulator. + For this to work you should make sure that the program is not using floating point, nor the ram/rom bank switching logic provided by the libraries. + You can also choose to just stick with Prog8 6.4 (which still targets cx16 v38) and wait it out till + the emulator v39 is officially released - but you won't be able to benefit from the compiler improvements + made for prog 7.0 this way. + .. toctree:: diff --git a/docs/source/todo.rst b/docs/source/todo.rst index ae227a5f1..c8d812cb4 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,10 +2,6 @@ TODO ==== -- fix scope compilation errors for sub with same name as block (kefrenbars example, 'irq') - -- add example in documentation for %asminclude and %asmbinary on how to refer to its contents via label or whatever - - test all examples (including imgviewer, assembler and petaxian) before release of the new version - simplify cx16.joystick_get2() once this cx16 rom issue is resolved: https://github.com/commanderx16/x16-rom/issues/203 diff --git a/examples/balloonflight.p8 b/examples/balloonflight.p8 index 1b7fe3a5d..a39eac281 100644 --- a/examples/balloonflight.p8 +++ b/examples/balloonflight.p8 @@ -23,7 +23,7 @@ main { c64.SCROLX &= %11110111 ; 38 column mode - c64.set_rasterirq(&irq.irq, 200, false) ; enable animation via raster interrupt + c64.set_rasterirq(&irq.irqhandler, 200, false) ; enable animation via raster interrupt ubyte target_height = 10 ubyte active_height = 24 @@ -130,7 +130,7 @@ spritedata $0f00 { irq { ubyte smoothx=0 - sub irq() { + sub irqhandler() { smoothx = (smoothx-1) & 7 main.perform_scroll = smoothx==7 c64.SCROLX = (c64.SCROLX & %11111000) | smoothx diff --git a/examples/bdmusic-irq.p8 b/examples/bdmusic-irq.p8 index 1d74a5dff..2bb1fb30c 100644 --- a/examples/bdmusic-irq.p8 +++ b/examples/bdmusic-irq.p8 @@ -7,7 +7,7 @@ main { sub start() { txt.print("playing the music from boulderdash,\nmade in 1984 by peter liepa.\n\n") - c64.set_rasterirq(&irq.irq, 60, true) ; enable playback via raster irq + c64.set_rasterirq(&irq.irqhandler, 60, true) ; enable playback via raster irq } } @@ -16,7 +16,7 @@ irq { ubyte note_index = 0 ubyte delay = 0 - sub irq() { + sub irqhandler() { c64.EXTCOL++ delay++ if delay >= 8 { diff --git a/examples/cx16/kefrenbars.p8 b/examples/cx16/kefrenbars.p8 index ed9c586d5..a3c6ce6be 100644 --- a/examples/cx16/kefrenbars.p8 +++ b/examples/cx16/kefrenbars.p8 @@ -26,7 +26,7 @@ main { cx16.screen_set_mode(128) ; low-res bitmap 256 colors cx16.FB_init() cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch display all the way to the bottom - cx16.set_rasterirq(&irq.irq, 0) + cx16.set_rasterirq(&irq.irqhandler, 0) repeat { ; don't exit @@ -44,7 +44,7 @@ irq { ubyte[32] pixels = 0 to 31 - sub irq() { + sub irqhandler() { next_irq_line += 6 anim1 += 4 anim2 += 6 diff --git a/examples/cx16/multipalette.p8 b/examples/cx16/multipalette.p8 index d09b202c0..a4801d102 100644 --- a/examples/cx16/multipalette.p8 +++ b/examples/cx16/multipalette.p8 @@ -31,7 +31,7 @@ main { palette.set_color(0, 0) palette.set_color(16, 0) - cx16.set_rasterirq(&irq.irq, 0) + cx16.set_rasterirq(&irq.irqhandler, 0) repeat { ; don't exit @@ -45,7 +45,7 @@ irq { uword next_rasterline = 0 const ubyte increment = 4 ; 4 scanlines = 2 lores pixels per color swap (2 scanlines is too tight) - sub irq() { + sub irqhandler() { if phase & 1 == 0 { %asm {{ lda #0 ; activate palette #0 (first set of colors) diff --git a/examples/cx16/rasterbars.p8 b/examples/cx16/rasterbars.p8 index 9ec647070..df73756bc 100644 --- a/examples/cx16/rasterbars.p8 +++ b/examples/cx16/rasterbars.p8 @@ -13,7 +13,7 @@ main { txt.plot(14,14) txt.print("raster bars!") - cx16.set_rasterirq(&irq.irq, 0) + cx16.set_rasterirq(&irq.irqhandler, 0) repeat { ; don't exit @@ -39,7 +39,7 @@ irq { ubyte yanim = 0 const ubyte barheight = 4 - sub irq() { + sub irqhandler() { uword c = colors[color_idx] color_idx++ color_idx &= 31 diff --git a/examples/rasterbars.p8 b/examples/rasterbars.p8 index 5f80d4192..6057810de 100644 --- a/examples/rasterbars.p8 +++ b/examples/rasterbars.p8 @@ -5,7 +5,7 @@ main { sub start() { c64.SCROLY &= %11101111 ; blank the screen - c64.set_rasterirq(&irq.irq, 40, false) ; register exclusive raster irq handler + c64.set_rasterirq(&irq.irqhandler, 40, false) ; register exclusive raster irq handler repeat { ; enjoy the moving bars :) @@ -22,7 +22,7 @@ irq { ubyte color = 0 ubyte yanim = 0 - sub irq() { + sub irqhandler() { if color!=len(colors) { c64.EXTCOL = colors[color] c64.RASTER += barheight ; next raster Irq for next color diff --git a/examples/sprites.p8 b/examples/sprites.p8 index 938204527..d336e6a65 100644 --- a/examples/sprites.p8 +++ b/examples/sprites.p8 @@ -46,14 +46,14 @@ main { } c64.SPENA = 255 ; enable all sprites - c64.set_rasterirq(&irq.irq, 255, true) ; enable animation + c64.set_rasterirq(&irq.irqhandler, 255, true) ; enable animation } } irq { - sub irq() { + sub irqhandler() { c64.EXTCOL-- ; float up & wobble horizontally diff --git a/examples/test.p8 b/examples/test.p8 index 0fda1c93c..043f30c2c 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,7 +1,6 @@ %import textio %zeropage dontuse - main { label: diff --git a/examples/wizzine.p8 b/examples/wizzine.p8 index f56eedd3d..f50946f07 100644 --- a/examples/wizzine.p8 +++ b/examples/wizzine.p8 @@ -38,7 +38,7 @@ main { c64.SPRPTR[i] = $0a00/64 } c64.SPENA = 255 ; enable all sprites - c64.set_rasterirq(&irq.irq, 230, true) ; enable animation + c64.set_rasterirq(&irq.irqhandler, 230, true) ; enable animation } } @@ -46,7 +46,7 @@ main { irq { ubyte angle - sub irq() { + sub irqhandler() { angle++ c64.MSIGX=0 ubyte @zp spri