From a95677564ecc1df4d02e25169c9bb54b75b550a6 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 21 Feb 2021 22:17:28 +0100 Subject: [PATCH] changed system irq/rasterirq setting routines --- compiler/res/prog8lib/c64/syslib.p8 | 100 +++++++++--------- .../compiler/astprocessing/AstChecker.kt | 13 --- compiler/src/prog8/optimizer/CallGraph.kt | 3 +- docs/source/targetsystem.rst | 24 +---- docs/source/todo.rst | 2 + examples/balloonflight.p8 | 2 +- examples/bdmusic-irq.p8 | 2 +- examples/rasterbars.p8 | 4 +- examples/sprites.p8 | 2 +- examples/test.p8 | 33 ++++-- examples/wizzine.p8 | 2 +- 11 files changed, 84 insertions(+), 103 deletions(-) diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 9da60a794..ed8a217d6 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -304,27 +304,13 @@ asmsub disable_runstop_and_charsetswitch() clobbers(A) { }} } -asmsub set_irqvec_excl() clobbers(A) { - %asm {{ - sei - lda #<_irq_handler - sta c64.CINV - lda #>_irq_handler - sta c64.CINV+1 - cli - rts -_irq_handler jsr set_irqvec._irq_handler_init - jsr irq.irq - jsr set_irqvec._irq_handler_end - lda #$ff - sta c64.VICIRQ ; acknowledge raster irq - lda c64.CIA1ICR ; acknowledge CIA1 interrupt - jmp c64.IRQDFEND ; end irq processing - don't call kernel - }} -} - -asmsub set_irqvec() clobbers(A) { +asmsub set_irq(uword handler @AY, ubyte useKernal @Pc) clobbers(A) { %asm {{ + sta _modified+1 + sty _modified+2 + lda #0 + adc #0 + sta _use_kernal sei lda #<_irq_handler sta c64.CINV @@ -333,9 +319,23 @@ asmsub set_irqvec() clobbers(A) { cli rts _irq_handler jsr _irq_handler_init - jsr irq.irq +_modified jsr $ffff ; modified jsr _irq_handler_end - jmp c64.IRQDFRT ; continue with normal kernel irq routine + lda _use_kernal + bne + + lda #$ff + sta c64.VICIRQ ; acknowledge raster irq + lda c64.CIA1ICR ; acknowledge CIA1 interrupt + ; end irq processing - don't use kernal's irq handling + pla + tay + pla + tax + pla + rti ++ jmp c64.IRQDFRT ; continue with normal kernal irq routine + +_use_kernal .byte 0 _irq_handler_init ; save all zp scratch registers and the X register as these might be clobbered by the irq routine @@ -388,7 +388,7 @@ IRQ_SCRATCH_ZPWORD2 .word 0 }} } -asmsub restore_irqvec() clobbers(A) { +asmsub restore_irq() clobbers(A) { %asm {{ sei lda #_raster_irq_handler - sta c64.CINV+1 - cli - rts - -_raster_irq_handler - jsr set_irqvec._irq_handler_init - jsr irq.irq - jsr set_irqvec._irq_handler_end - lda #$ff - sta c64.VICIRQ ; acknowledge raster irq - jmp c64.IRQDFEND ; end irq processing - don't call kernel - - }} -} - ; ---- end of C64 specific system utility routines ---- } diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 91ce39ab8..18bf60b72 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -41,19 +41,6 @@ internal class AstChecker(private val program: Program, } } - // there can be an optional single 'irq' block with a 'irq' subroutine in it, - // which will be used as the 60hz irq routine in the vm if it's present - val irqBlocks = program.modules.flatMap { it.statements }.filter { it is Block && it.name=="irq" }.map { it as Block } - if(irqBlocks.size>1) - errors.err("more than one 'irq' block", irqBlocks[0].position) - for(irqBlock in irqBlocks) { - val irqSub = irqBlock.subScope("irq") as? Subroutine - if (irqSub != null) { - if (irqSub.parameters.isNotEmpty() || irqSub.returntypes.isNotEmpty()) - errors.err("irq entrypoint subroutine can't have parameters and/or return values", irqSub.position) - } - } - super.visit(program) } diff --git a/compiler/src/prog8/optimizer/CallGraph.kt b/compiler/src/prog8/optimizer/CallGraph.kt index 00f2b9c27..0b8ab593e 100644 --- a/compiler/src/prog8/optimizer/CallGraph.kt +++ b/compiler/src/prog8/optimizer/CallGraph.kt @@ -16,8 +16,7 @@ import prog8.compiler.IErrorReporter import java.nio.file.Path private val alwaysKeepSubroutines = setOf( - Pair("main", "start"), - Pair("irq", "irq") + Pair("main", "start") ) private val asmJumpRx = Regex("""[\-+a-zA-Z0-9_ \t]+(jmp|jsr)[ \t]+(\S+).*""", RegexOption.IGNORE_CASE) diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst index 8555e5b61..6a5f9c795 100644 --- a/docs/source/targetsystem.rst +++ b/docs/source/targetsystem.rst @@ -139,26 +139,12 @@ IRQ Handling ============ Normally, the system's default IRQ handling is not interfered with. -You can however install your own IRQ handler. -This is possible ofcourse by doing it all using customized inline assembly, -but there are a few library routines available to make setting up C-64 IRQs and raster IRQs a lot easier (no assembly code required). +You can however install your own IRQ handler (for clean separation, it is advised to define it inside its own block). +There are a few library routines available to make setting up C-64 60hz IRQs and Raster IRQs a lot easier (no assembly code required). For the C64 these routines are:: - c64.set_irqvec() - c64.set_irqvec_excl() - - c64.set_rasterirq( ) - c64.set_rasterirq_excl( ) - - c64.restore_irqvec() ; set it back to the systems default irq handler - -If you activate an IRQ handler with one of these, it expects the handler to be defined -as a subroutine ``irq`` in the module ``irq`` so like this:: - - irq { - sub irq() { - ; ... irq handling here ... - } - } + c64.set_irq(uword handler_address, boolean useKernal) + c64.set_rasterirq(uword handler_address, uword rasterline, boolean useKernal) + c64.restore_irq() ; set everything back to the systems default irq handler diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 8d97c1f06..1ae85cc85 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,8 @@ TODO ==== +- rename kernel -> kernal +- add sys.halt() that is smart on the 65c02 - add sound to the cx16 tehtriz - add const arrays and cost strings diff --git a/examples/balloonflight.p8 b/examples/balloonflight.p8 index ce1929ea5..1b7fe3a5d 100644 --- a/examples/balloonflight.p8 +++ b/examples/balloonflight.p8 @@ -23,7 +23,7 @@ main { c64.SCROLX &= %11110111 ; 38 column mode - c64.set_rasterirq(200) ; enable animation + c64.set_rasterirq(&irq.irq, 200, false) ; enable animation via raster interrupt ubyte target_height = 10 ubyte active_height = 24 diff --git a/examples/bdmusic-irq.p8 b/examples/bdmusic-irq.p8 index 174d16c0f..1d74a5dff 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(60) ; enable raster irq + c64.set_rasterirq(&irq.irq, 60, true) ; enable playback via raster irq } } diff --git a/examples/rasterbars.p8 b/examples/rasterbars.p8 index c056d4813..efdbc8f95 100644 --- a/examples/rasterbars.p8 +++ b/examples/rasterbars.p8 @@ -4,8 +4,8 @@ main { sub start() { - c64.SCROLY &= %11101111 ; blank the screen - c64.set_rasterirq_excl(40) ; register exclusive raster irq handler + c64.SCROLY &= %11101111 ; blank the screen + c64.set_rasterirq(&irq.irq, 40, false) ; register exclusive raster irq handler repeat { ; enjoy the moving bars :) diff --git a/examples/sprites.p8 b/examples/sprites.p8 index 90598dff7..938204527 100644 --- a/examples/sprites.p8 +++ b/examples/sprites.p8 @@ -46,7 +46,7 @@ main { } c64.SPENA = 255 ; enable all sprites - c64.set_rasterirq(51) ; enable animation + c64.set_rasterirq(&irq.irq, 255, true) ; enable animation } } diff --git a/examples/test.p8 b/examples/test.p8 index ac0489f71..75c13bcbf 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -7,18 +7,11 @@ main { ; $1F9C0 - $1F9FF PSG registers sub start() { + c64.set_rasterirq(&irq.irq, 100, true) - ubyte xx=33 - when xx { - 1 -> { - } - 2 -> { - } - else -> { - } - else -> { - } - } + sys.wait(100) + + c64.restore_irq() ; uword freq = 1181 ; cx16.vpoke(1, $f9c0, lsb(freq)) @@ -28,3 +21,21 @@ main { } } + +irq { + uword counter = 0 + + sub irq() { + c64.EXTCOL++ + ubyte xx + repeat 20 { + xx++ + } + c64.EXTCOL-- + + @($0400) = lsb(counter) + @($0401) = msb(counter) + + counter++ + } +} diff --git a/examples/wizzine.p8 b/examples/wizzine.p8 index 9211a817e..dd6daab34 100644 --- a/examples/wizzine.p8 +++ b/examples/wizzine.p8 @@ -37,7 +37,7 @@ main { c64.SPRPTR[i] = $0a00/64 } c64.SPENA = 255 ; enable all sprites - c64.set_rasterirq(220) ; enable animation + c64.set_rasterirq(&irq.irq, 230, true) ; enable animation } }