diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index a6a1db607..df29cba93 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -238,7 +238,8 @@ cx16 { &ubyte VERA_CTRL = VERA_BASE + $0005 &ubyte VERA_IEN = VERA_BASE + $0006 &ubyte VERA_ISR = VERA_BASE + $0007 - &ubyte VERA_IRQ_LINE_L = VERA_BASE + $0008 + &ubyte VERA_IRQLINE_L = VERA_BASE + $0008 ; write only + &ubyte VERA_SCANLINE_L = VERA_BASE + $0008 ; read only &ubyte VERA_DC_VIDEO = VERA_BASE + $0009 ; DCSEL= 0 &ubyte VERA_DC_HSCALE = VERA_BASE + $000A ; DCSEL= 0 &ubyte VERA_DC_VSCALE = VERA_BASE + $000B ; DCSEL= 0 @@ -931,6 +932,7 @@ asmsub cleanup_at_exit() { } asmsub set_irq(uword handler @AY) clobbers(A) { + ; Sets the handler for the VSYNC interrupt, and enable that interrupt. %asm {{ sta _modified+1 sty _modified+2 @@ -939,9 +941,8 @@ asmsub set_irq(uword handler @AY) clobbers(A) { sta cx16.CINV lda #>_irq_handler sta cx16.CINV+1 - lda cx16.VERA_IEN - ora #%00000001 ; enable the vsync irq - sta cx16.VERA_IEN + lda #1 + tsb cx16.VERA_IEN ; enable the vsync irq cli rts @@ -974,8 +975,8 @@ asmsub restore_irq() clobbers(A) { lda _orig_irqvec+1 sta cx16.CINV+1 lda cx16.VERA_IEN - and #%11110000 ; disable all Vera IRQs - ora #%00000001 ; enable only the vsync Irq + and #%11110000 ; disable all Vera IRQs but the vsync + ora #%00000001 sta cx16.VERA_IEN cli rts @@ -984,6 +985,7 @@ _orig_irqvec .word 0 } asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) { + ; Sets the handler for the LINE interrupt, and enable (only) that interrupt. %asm {{ sta _modified+1 sty _modified+2 @@ -991,8 +993,8 @@ asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) { ldy cx16.r0+1 sei lda cx16.VERA_IEN - and #%11110000 ; clear other IRQs - ora #%00000010 ; enable the line (raster) irq + and #%11110000 ; disable all irqs but the line(raster) one + ora #%00000010 sta cx16.VERA_IEN lda cx16.r0 ldy cx16.r0+1 @@ -1010,9 +1012,8 @@ _raster_irq_handler _modified jsr $ffff ; modified jsr sys.restore_prog8_internals ; end irq processing - don't use kernal's irq handling - lda cx16.VERA_ISR - ora #%00000010 - sta cx16.VERA_ISR ; clear Vera line irq status + lda #2 + tsb cx16.VERA_ISR ; clear Vera line irq status ply plx pla @@ -1022,7 +1023,7 @@ _modified jsr $ffff ; modified asmsub set_rasterline(uword line @AY) { %asm {{ - sta cx16.VERA_IRQ_LINE_L + sta cx16.VERA_IRQLINE_L lda cx16.VERA_IEN and #%01111111 sta cx16.VERA_IEN diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index 2b8811765..4477e8a5c 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -117,6 +117,7 @@ class TestCompilerOnExamplesCx16: FunSpec({ "kefrenbars", "keyboardhandler", "mandelbrot", + "multi-irq", "plasma", "rasterbars", "snow", diff --git a/docs/source/todo.rst b/docs/source/todo.rst index ae221d70c..7b17f3298 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,7 +2,8 @@ TODO ==== -- use TRB/TSB instructions more on the x16 such as when ack vera irq bits +- use TRB/TSB instructions more on the x16 such as when ack vera irq bits cx16.VERA_ISR |= 4 + xx |= %0001000, xx &= %1110111 - [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 .... @@ -23,6 +24,8 @@ Compiler: - Currently "320*240/8/8" gives integer overflow, so: allow constant integer subexpressions to contain out of range integers (>65535 etc) as long as the final constant value is within byte/word range. - Multidimensional arrays and chained indexing, purely as syntactic sugar over regular arrays. - fix the other cases of "TODO index could also be a binexpr" (in AssignmentAsmGen), but these are for float arrays so rarely used. +- make a form of "manual generics" possible like: varsub routine(T arg)->T where T is expanded to a specific type + (this is already done hardcoded for several of the builtin functions) - [much work:] more support for (64tass) SEGMENTS ? - (What, how, isn't current BSS support enough?) diff --git a/examples/cx16/multi-irq.p8 b/examples/cx16/multi-irq.p8 new file mode 100644 index 000000000..68f50b3c5 --- /dev/null +++ b/examples/cx16/multi-irq.p8 @@ -0,0 +1,86 @@ +%import palette +%import textio +%import syslib +%zeropage basicsafe + +; Example that shows a way to handle multiple IRQ sources on the X16. +; Currently only Vera interrupts are supported. + +main { + sub start() { + sys.set_rasterline(150) + sys.set_irq(&irq.master_handler) ; ..will just enable vsync.. + cx16.VERA_IEN |= 2 ; .. so also enable line irq here. + + txt.print("\n\n\nisr installed\n") + txt.print("red = vsync\n") + txt.print("green = first line irq\n") + txt.print("blue = second line irq\n") + } +} + +irq { + sub master_handler() -> bool { + ubyte irqsrc = cx16.VERA_ISR + ror(irqsrc) + if_cs { + vsync_irq() + return true ; run system IRQ handler. It will ack the vsync IRQ as well. + } + ror(irqsrc) + if_cs { + line_irq() + cx16.VERA_ISR |= 2 ; ack the irq + return false + } + ror(irqsrc) + if_cs { + sprcol_irq() + cx16.VERA_ISR |= 4 ; ack the irq + return false + } + ror(irqsrc) + if_cs { + aflow_irq() + ; note: AFLOW can only be cleared by filling the audio FIFO for at least 1/4. Not via the ISR bit. + return false + } + + ; weird irq + return false + } + + sub vsync_irq() { + cx16.save_vera_context() + palette.set_color(0, $f00) + repeat 1000 { + cx16.r0++ + } + palette.set_color(0, $000) + cx16.restore_vera_context() + } + + sub line_irq() { + cx16.save_vera_context() + if cx16.VERA_SCANLINE_L==150 { + palette.set_color(0, $0f0) + sys.set_rasterline(200) ; prepare next line irq + } else { + palette.set_color(0, $00f) + sys.set_rasterline(150) ; back to first line irq + } + repeat 500 { + cx16.r0++ + } + palette.set_color(0, $000) + cx16.restore_vera_context() + } + + sub sprcol_irq() { + ; nothing here yet + } + + sub aflow_irq() { + ; nothing here yet + } +} diff --git a/examples/test.p8 b/examples/test.p8 index 7944fc55d..17d53f20f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,17 +5,79 @@ main { sub start() { - sys.set_rasterirq(&handler, 200) - txt.print("installed\n") + sys.set_rasterline(150) + sys.set_irq(&irq.master_handler) + cx16.VERA_IEN |= 2 ; also enable line irq + + txt.print("\n\n\nisr installed\n") + txt.print("red = vsync\n") + txt.print("green = first line irq\n") + txt.print("blue = second line irq\n") + } +} + +irq { + sub master_handler() -> bool { + ubyte irqsrc = cx16.VERA_ISR + ror(irqsrc) + if_cs { + vsync_irq() + return true ; run system IRQ handler. It will ack the vsync IRQ as well. + } + ror(irqsrc) + if_cs { + line_irq() + cx16.VERA_ISR |= 2 ; ack the irq + return false + } + ror(irqsrc) + if_cs { + sprcol_irq() + cx16.VERA_ISR |= 4 ; ack the irq + return false + } + ror(irqsrc) + if_cs { + aflow_irq() + ; note: AFLOW can only be cleared by filling the audio FIFO for at least 1/4. Not via the ISR bit. + return false + } + + ; weird irq + return false } - sub handler() -> bool { + sub vsync_irq() { + cx16.save_vera_context() palette.set_color(0, $f00) repeat 1000 { cx16.r0++ } palette.set_color(0, $000) + cx16.restore_vera_context() + } - return true + sub line_irq() { + cx16.save_vera_context() + if cx16.VERA_SCANLINE_L==150 { + palette.set_color(0, $0f0) + sys.set_rasterline(200) ; prepare next line irq + } else { + palette.set_color(0, $00f) + sys.set_rasterline(150) ; back to first line irq + } + repeat 500 { + cx16.r0++ + } + palette.set_color(0, $000) + cx16.restore_vera_context() + } + + sub sprcol_irq() { + ; nothing here yet + } + + sub aflow_irq() { + ; nothing here yet } }