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