mirror of
https://github.com/irmen/prog8.git
synced 2024-12-01 15:52:54 +00:00
Merge branch 'irmen:master' into issue40(EOF,EOL)
This commit is contained in:
commit
34b2a65ccb
@ -106,6 +106,12 @@ internal class AstIdentifiersChecker(private val program: Program, private val e
|
|||||||
if(subroutine.isAsmSubroutine && subroutine.statements.any{it !is InlineAssembly}) {
|
if(subroutine.isAsmSubroutine && subroutine.statements.any{it !is InlineAssembly}) {
|
||||||
errors.err("asmsub can only contain inline assembly (%asm)", subroutine.position)
|
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)
|
super.visit(subroutine)
|
||||||
|
@ -1502,7 +1502,7 @@ $label nop""")
|
|||||||
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
|
val saveA = evalBytevalueWillClobberA(ptrAndIndex.first) || evalBytevalueWillClobberA(ptrAndIndex.second)
|
||||||
if(saveA)
|
if(saveA)
|
||||||
out(" pha")
|
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)
|
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
|
||||||
if(saveA)
|
if(saveA)
|
||||||
out(" pla")
|
out(" pla")
|
||||||
@ -1514,7 +1514,7 @@ $label nop""")
|
|||||||
out(" lda (${asmSymbolName(pointervar)}),y")
|
out(" lda (${asmSymbolName(pointervar)}),y")
|
||||||
} else {
|
} else {
|
||||||
// copy the pointer var to zp first
|
// 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)
|
assignExpressionToRegister(ptrAndIndex.second, RegisterOrPair.Y)
|
||||||
out(" lda (P8ZP_SCRATCH_W2),y")
|
out(" lda (P8ZP_SCRATCH_W2),y")
|
||||||
}
|
}
|
||||||
|
@ -1696,7 +1696,7 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
|
|||||||
internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) {
|
internal fun translateDirectMemReadExpression(expr: DirectMemoryRead, pushResultOnEstack: Boolean) {
|
||||||
|
|
||||||
fun assignViaExprEval() {
|
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 (asmgen.isTargetCpu(CpuType.CPU65c02)) {
|
||||||
if (pushResultOnEstack) {
|
if (pushResultOnEstack) {
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W2) | dex | sta P8ESTACK_LO+1,x")
|
asmgen.out(" lda (P8ZP_SCRATCH_W2) | dex | sta P8ESTACK_LO+1,x")
|
||||||
|
@ -319,10 +319,9 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
|
|||||||
register!!
|
register!!
|
||||||
if(requiredDt largerThan valueDt) {
|
if(requiredDt largerThan valueDt) {
|
||||||
// we need to sign extend the source, do this via temporary word variable
|
// we need to sign extend the source, do this via temporary word variable
|
||||||
val scratchVar = asmgen.asmVariableName("P8ZP_SCRATCH_W1")
|
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", DataType.UBYTE, sub)
|
||||||
asmgen.assignExpressionToVariable(value, scratchVar, DataType.UBYTE, sub)
|
asmgen.signExtendVariableLsb("P8ZP_SCRATCH_W1", valueDt)
|
||||||
asmgen.signExtendVariableLsb(scratchVar, valueDt)
|
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register)
|
||||||
asmgen.assignVariableToRegister(scratchVar, register)
|
|
||||||
} else {
|
} else {
|
||||||
val target: AsmAssignTarget =
|
val target: AsmAssignTarget =
|
||||||
if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters))
|
if(parameter.value.type in ByteDatatypes && (register==RegisterOrPair.AX || register == RegisterOrPair.AY || register==RegisterOrPair.XY || register in Cx16VirtualRegisters))
|
||||||
|
@ -115,7 +115,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
SourceStorageKind.MEMORY -> {
|
SourceStorageKind.MEMORY -> {
|
||||||
fun assignViaExprEval(expression: Expression) {
|
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))
|
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
|
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
|
||||||
else
|
else
|
||||||
@ -320,7 +320,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
if(targetDt in WordDatatypes) {
|
if(targetDt in WordDatatypes) {
|
||||||
|
|
||||||
fun assignViaExprEval(addressExpression: Expression) {
|
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))
|
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
|
asmgen.out(" lda (P8ZP_SCRATCH_W2)")
|
||||||
else
|
else
|
||||||
@ -2089,7 +2089,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
fun storeViaExprEval() {
|
fun storeViaExprEval() {
|
||||||
when(addressExpr) {
|
when(addressExpr) {
|
||||||
is NumericLiteralValue, is IdentifierReference -> {
|
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))
|
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
||||||
else
|
else
|
||||||
@ -2098,7 +2098,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
else -> {
|
else -> {
|
||||||
// same as above but we need to save the A register
|
// same as above but we need to save the A register
|
||||||
asmgen.out(" pha")
|
asmgen.out(" pha")
|
||||||
assignExpressionToVariable(addressExpr, asmgen.asmVariableName("P8ZP_SCRATCH_W2"), DataType.UWORD, null)
|
assignExpressionToVariable(addressExpr, "P8ZP_SCRATCH_W2", DataType.UWORD, null)
|
||||||
asmgen.out(" pla")
|
asmgen.out(" pla")
|
||||||
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
asmgen.out(" sta (P8ZP_SCRATCH_W2)")
|
||||||
|
@ -1778,7 +1778,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> {
|
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("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (P8ZP_SCRATCH_W2),y
|
lda (P8ZP_SCRATCH_W2),y
|
||||||
@ -1846,7 +1846,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
asmgen.out(" sta (P8ZP_SCRATCH_W1),y")
|
||||||
}
|
}
|
||||||
else -> {
|
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("""
|
asmgen.out("""
|
||||||
ldy #0
|
ldy #0
|
||||||
lda (P8ZP_SCRATCH_W2),y
|
lda (P8ZP_SCRATCH_W2),y
|
||||||
|
@ -165,10 +165,21 @@ For Windows it's possible to get that as well; check out `AdoptOpenJDK <https://
|
|||||||
For MacOS you can use the Homebrew system to install a recent version of OpenJDK.
|
For MacOS you can use the Homebrew system to install a recent version of OpenJDK.
|
||||||
|
|
||||||
Finally: an **emulator** (or a real machine ofcourse) to test and run your programs on.
|
Finally: an **emulator** (or a real machine ofcourse) to test and run your programs on.
|
||||||
In C64 mode, thhe compiler assumes the presence of the `Vice emulator <http://vice-emu.sourceforge.net/>`_.
|
In C64 mode, the compiler assumes the presence of the `Vice emulator <http://vice-emu.sourceforge.net/>`_.
|
||||||
If you're targeting the CommanderX16 instead, there's the `x16emu <https://github.com/commanderx16/x16-emulator>`_.
|
If you're targeting the CommanderX16 instead, there's the `x16emu <https://github.com/commanderx16/x16-emulator>`_.
|
||||||
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::
|
.. toctree::
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
TODO
|
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
|
- 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
|
- simplify cx16.joystick_get2() once this cx16 rom issue is resolved: https://github.com/commanderx16/x16-rom/issues/203
|
||||||
|
@ -23,7 +23,7 @@ main {
|
|||||||
|
|
||||||
c64.SCROLX &= %11110111 ; 38 column mode
|
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 target_height = 10
|
||||||
ubyte active_height = 24
|
ubyte active_height = 24
|
||||||
@ -130,7 +130,7 @@ spritedata $0f00 {
|
|||||||
|
|
||||||
irq {
|
irq {
|
||||||
ubyte smoothx=0
|
ubyte smoothx=0
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
smoothx = (smoothx-1) & 7
|
smoothx = (smoothx-1) & 7
|
||||||
main.perform_scroll = smoothx==7
|
main.perform_scroll = smoothx==7
|
||||||
c64.SCROLX = (c64.SCROLX & %11111000) | smoothx
|
c64.SCROLX = (c64.SCROLX & %11111000) | smoothx
|
||||||
|
@ -7,7 +7,7 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
txt.print("playing the music from boulderdash,\nmade in 1984 by peter liepa.\n\n")
|
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 note_index = 0
|
||||||
ubyte delay = 0
|
ubyte delay = 0
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
c64.EXTCOL++
|
c64.EXTCOL++
|
||||||
delay++
|
delay++
|
||||||
if delay >= 8 {
|
if delay >= 8 {
|
||||||
|
@ -26,7 +26,7 @@ main {
|
|||||||
cx16.screen_set_mode(128) ; low-res bitmap 256 colors
|
cx16.screen_set_mode(128) ; low-res bitmap 256 colors
|
||||||
cx16.FB_init()
|
cx16.FB_init()
|
||||||
cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch display all the way to the bottom
|
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 {
|
repeat {
|
||||||
; don't exit
|
; don't exit
|
||||||
@ -44,7 +44,7 @@ irq {
|
|||||||
|
|
||||||
ubyte[32] pixels = 0 to 31
|
ubyte[32] pixels = 0 to 31
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
next_irq_line += 6
|
next_irq_line += 6
|
||||||
anim1 += 4
|
anim1 += 4
|
||||||
anim2 += 6
|
anim2 += 6
|
||||||
|
@ -31,7 +31,7 @@ main {
|
|||||||
palette.set_color(0, 0)
|
palette.set_color(0, 0)
|
||||||
palette.set_color(16, 0)
|
palette.set_color(16, 0)
|
||||||
|
|
||||||
cx16.set_rasterirq(&irq.irq, 0)
|
cx16.set_rasterirq(&irq.irqhandler, 0)
|
||||||
|
|
||||||
repeat {
|
repeat {
|
||||||
; don't exit
|
; don't exit
|
||||||
@ -45,7 +45,7 @@ irq {
|
|||||||
uword next_rasterline = 0
|
uword next_rasterline = 0
|
||||||
const ubyte increment = 4 ; 4 scanlines = 2 lores pixels per color swap (2 scanlines is too tight)
|
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 {
|
if phase & 1 == 0 {
|
||||||
%asm {{
|
%asm {{
|
||||||
lda #0 ; activate palette #0 (first set of colors)
|
lda #0 ; activate palette #0 (first set of colors)
|
||||||
|
@ -13,7 +13,7 @@ main {
|
|||||||
txt.plot(14,14)
|
txt.plot(14,14)
|
||||||
txt.print("raster bars!")
|
txt.print("raster bars!")
|
||||||
|
|
||||||
cx16.set_rasterirq(&irq.irq, 0)
|
cx16.set_rasterirq(&irq.irqhandler, 0)
|
||||||
|
|
||||||
repeat {
|
repeat {
|
||||||
; don't exit
|
; don't exit
|
||||||
@ -39,7 +39,7 @@ irq {
|
|||||||
ubyte yanim = 0
|
ubyte yanim = 0
|
||||||
const ubyte barheight = 4
|
const ubyte barheight = 4
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
uword c = colors[color_idx]
|
uword c = colors[color_idx]
|
||||||
color_idx++
|
color_idx++
|
||||||
color_idx &= 31
|
color_idx &= 31
|
||||||
|
@ -5,7 +5,7 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
c64.SCROLY &= %11101111 ; blank the screen
|
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 {
|
repeat {
|
||||||
; enjoy the moving bars :)
|
; enjoy the moving bars :)
|
||||||
@ -22,7 +22,7 @@ irq {
|
|||||||
ubyte color = 0
|
ubyte color = 0
|
||||||
ubyte yanim = 0
|
ubyte yanim = 0
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
if color!=len(colors) {
|
if color!=len(colors) {
|
||||||
c64.EXTCOL = colors[color]
|
c64.EXTCOL = colors[color]
|
||||||
c64.RASTER += barheight ; next raster Irq for next color
|
c64.RASTER += barheight ; next raster Irq for next color
|
||||||
|
@ -46,14 +46,14 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c64.SPENA = 255 ; enable all sprites
|
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 {
|
irq {
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
c64.EXTCOL--
|
c64.EXTCOL--
|
||||||
|
|
||||||
; float up & wobble horizontally
|
; float up & wobble horizontally
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage dontuse
|
%zeropage dontuse
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
label:
|
label:
|
||||||
|
@ -38,7 +38,7 @@ main {
|
|||||||
c64.SPRPTR[i] = $0a00/64
|
c64.SPRPTR[i] = $0a00/64
|
||||||
}
|
}
|
||||||
c64.SPENA = 255 ; enable all sprites
|
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 {
|
irq {
|
||||||
ubyte angle
|
ubyte angle
|
||||||
|
|
||||||
sub irq() {
|
sub irqhandler() {
|
||||||
angle++
|
angle++
|
||||||
c64.MSIGX=0
|
c64.MSIGX=0
|
||||||
ubyte @zp spri
|
ubyte @zp spri
|
||||||
|
Loading…
Reference in New Issue
Block a user