mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
new X16 irq handler routines and examples
This commit is contained in:
parent
935450a45f
commit
16851746d6
@ -850,8 +850,149 @@ asmsub restore_vera_context() clobbers(A) {
|
|||||||
rts
|
rts
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
; Commander X16 IRQ dispatcher routines
|
||||||
|
|
||||||
|
asmsub enable_irq_handlers() clobbers(A,Y) {
|
||||||
|
; Install the "master IRQ handler" that will dispatch IRQs.
|
||||||
|
; to the registered handler for each type. (Only Vera IRQs supported for now).
|
||||||
|
; The handlers don't need to clear its ISR bit, but have to return 0 or 1 in A:
|
||||||
|
; where 1 means: continue with the system IRQ handler, 0 means: don't call that.
|
||||||
|
%asm {{
|
||||||
|
php
|
||||||
|
sei
|
||||||
|
lda #<_irq_dispatcher
|
||||||
|
ldy #>_irq_dispatcher
|
||||||
|
sta cx16.CINV
|
||||||
|
sty cx16.CINV+1
|
||||||
|
plp
|
||||||
|
rts
|
||||||
|
|
||||||
|
_irq_dispatcher
|
||||||
|
jsr sys.save_prog8_internals
|
||||||
|
cld
|
||||||
|
lda cx16.VERA_ISR
|
||||||
|
lsr a
|
||||||
|
bcc +
|
||||||
|
_mod_vsync_jump
|
||||||
|
jsr _default_vsync_handler ; modified
|
||||||
|
cmp #0
|
||||||
|
bne _dispatch_end
|
||||||
|
lda #1
|
||||||
|
sta cx16.VERA_ISR
|
||||||
|
bra _return_irq
|
||||||
|
+ lsr a
|
||||||
|
bcc +
|
||||||
|
_mod_line_jump
|
||||||
|
jsr _default_line_handler ; modified
|
||||||
|
ldy #2
|
||||||
|
sty cx16.VERA_ISR
|
||||||
|
bra _dispatch_end
|
||||||
|
+ lsr a
|
||||||
|
bcc +
|
||||||
|
_mod_sprcol_jump
|
||||||
|
jsr _default_sprcol_handler ; modified
|
||||||
|
ldy #4
|
||||||
|
sty cx16.VERA_ISR
|
||||||
|
bra _dispatch_end
|
||||||
|
+ lsr a
|
||||||
|
bcc +
|
||||||
|
_mod_aflow_jump
|
||||||
|
jsr _default_aflow_handler ; modified
|
||||||
|
; note: AFLOW can only be cleared by filling the audio FIFO for at least 1/4. Not via the ISR bit.
|
||||||
|
bra _dispatch_end
|
||||||
|
+ lda #0
|
||||||
|
_dispatch_end
|
||||||
|
cmp #0
|
||||||
|
beq _return_irq
|
||||||
|
jsr sys.restore_prog8_internals
|
||||||
|
jmp (sys.restore_irq._orig_irqvec) ; continue with normal kernal irq routine
|
||||||
|
_return_irq
|
||||||
|
jsr sys.restore_prog8_internals
|
||||||
|
ply
|
||||||
|
plx
|
||||||
|
pla
|
||||||
|
rti
|
||||||
|
|
||||||
|
_default_vsync_handler
|
||||||
|
lda #1
|
||||||
|
rts
|
||||||
|
_default_line_handler
|
||||||
|
lda #0
|
||||||
|
rts
|
||||||
|
_default_sprcol_handler
|
||||||
|
lda #0
|
||||||
|
rts
|
||||||
|
_default_aflow_handler
|
||||||
|
lda #0
|
||||||
|
rts
|
||||||
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asmsub set_vsync_irq_handler(uword address @AY) clobbers(A) {
|
||||||
|
; Sets the VSYNC irq handler to use with enable_irq_handlers(). Also enables VSYNC irqs.
|
||||||
|
; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
|
||||||
|
%asm {{
|
||||||
|
sta enable_irq_handlers._mod_vsync_jump+1
|
||||||
|
sty enable_irq_handlers._mod_vsync_jump+2
|
||||||
|
lda #1
|
||||||
|
tsb cx16.VERA_IEN
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub set_line_irq_handler(uword rasterline @R0, uword address @AY) clobbers(A,Y) {
|
||||||
|
; Sets the LINE irq handler to use with enable_irq_handlers(), for the given rasterline. Also enables LINE irqs.
|
||||||
|
; You can use sys.set_rasterline() later to adjust the rasterline on which to trigger.
|
||||||
|
; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
|
||||||
|
%asm {{
|
||||||
|
sta enable_irq_handlers._mod_line_jump+1
|
||||||
|
sty enable_irq_handlers._mod_line_jump+2
|
||||||
|
lda cx16.r0
|
||||||
|
ldy cx16.r0+1
|
||||||
|
jsr sys.set_rasterline
|
||||||
|
lda #2
|
||||||
|
tsb cx16.VERA_IEN
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub set_sprcol_irq_handler(uword address @AY) clobbers(A) {
|
||||||
|
; Sets the SPRCOL irq handler to use with enable_irq_handlers(). Also enables SPRCOL irqs.
|
||||||
|
; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
|
||||||
|
%asm {{
|
||||||
|
sta enable_irq_handlers._mod_sprcol_jump+1
|
||||||
|
sty enable_irq_handlers._mod_sprcol_jump+2
|
||||||
|
lda #4
|
||||||
|
tsb cx16.VERA_IEN
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub set_aflow_irq_handler(uword address @AY) clobbers(A) {
|
||||||
|
; Sets the AFLOW irq handler to use with enable_irq_handlers(). Also enables AFLOW irqs.
|
||||||
|
; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
|
||||||
|
%asm {{
|
||||||
|
sta enable_irq_handlers._mod_aflow_jump+1
|
||||||
|
sty enable_irq_handlers._mod_aflow_jump+2
|
||||||
|
lda #8
|
||||||
|
tsb cx16.VERA_IEN
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
asmsub disable_irq_handlers() {
|
||||||
|
; back to the system default IRQ handler.
|
||||||
|
%asm {{
|
||||||
|
jmp sys.restore_irq
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sys {
|
sys {
|
||||||
; ------- lowlevel system routines --------
|
; ------- lowlevel system routines --------
|
||||||
|
|
||||||
@ -962,9 +1103,7 @@ _modified
|
|||||||
plx
|
plx
|
||||||
pla
|
pla
|
||||||
rti
|
rti
|
||||||
|
}}
|
||||||
_use_kernal .byte 0
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
asmsub restore_irq() clobbers(A) {
|
asmsub restore_irq() clobbers(A) {
|
||||||
|
@ -117,7 +117,8 @@ class TestCompilerOnExamplesCx16: FunSpec({
|
|||||||
"kefrenbars",
|
"kefrenbars",
|
||||||
"keyboardhandler",
|
"keyboardhandler",
|
||||||
"mandelbrot",
|
"mandelbrot",
|
||||||
"multi-irq",
|
"multi-irq-old",
|
||||||
|
"multi-irq-new",
|
||||||
"plasma",
|
"plasma",
|
||||||
"rasterbars",
|
"rasterbars",
|
||||||
"snow",
|
"snow",
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- move x16 irq examples over to new style handler
|
||||||
|
- optimize sys.set_rasterline on X16
|
||||||
|
- document new x16 irq handling stuff in docs
|
||||||
|
|
||||||
- use TRB/TSB instructions more on the x16 such as when ack vera irq bits cx16.VERA_ISR |= 4
|
- use TRB/TSB instructions more on the x16 such as when ack vera irq bits cx16.VERA_ISR |= 4
|
||||||
xx |= %0001000, xx &= %1110111
|
xx |= %0001000, xx &= %1110111
|
||||||
|
|
||||||
|
51
examples/cx16/multi-irq-new.p8
Normal file
51
examples/cx16/multi-irq-new.p8
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
%import palette
|
||||||
|
%import textio
|
||||||
|
%import syslib
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
; Example that shows a way to handle multiple IRQ sources on the X16.
|
||||||
|
; This uses the "NEW" way using the X16 specific interrupt handler routines in cx16.
|
||||||
|
; Currently only Vera interrupts are supported. VIA irqs are an exercise for the reader.
|
||||||
|
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
cx16.enable_irq_handlers()
|
||||||
|
cx16.set_line_irq_handler(150, &irq.line_irq)
|
||||||
|
cx16.set_vsync_irq_handler(&irq.vsync_irq)
|
||||||
|
|
||||||
|
txt.print("\n\n\nx16 irq handlers installed (new style)\n")
|
||||||
|
txt.print("red = vsync irq\n")
|
||||||
|
txt.print("green = first line irq\n")
|
||||||
|
txt.print("blue = second line irq\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
irq {
|
||||||
|
sub vsync_irq() -> bool {
|
||||||
|
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() -> bool {
|
||||||
|
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()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,9 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
; Example that shows a way to handle multiple IRQ sources on the X16.
|
; Example that shows a way to handle multiple IRQ sources on the X16.
|
||||||
; Currently only Vera interrupts are supported.
|
; This uses the "OLD" way using the interrupt handler routines in sys.
|
||||||
|
; (see multi-irq-new example to do it the "new" way)
|
||||||
|
; Currently only Vera interrupts are supported. VIA irqs are an exercise for the reader.
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
@ -12,8 +14,8 @@ main {
|
|||||||
sys.set_irq(&irq.master_handler) ; ..will just enable vsync..
|
sys.set_irq(&irq.master_handler) ; ..will just enable vsync..
|
||||||
cx16.VERA_IEN |= 2 ; .. so also enable line irq here.
|
cx16.VERA_IEN |= 2 ; .. so also enable line irq here.
|
||||||
|
|
||||||
txt.print("\n\n\nisr installed\n")
|
txt.print("\n\n\nx16 irq handlers installed (old style)\n")
|
||||||
txt.print("red = vsync\n")
|
txt.print("red = vsync irq\n")
|
||||||
txt.print("green = first line irq\n")
|
txt.print("green = first line irq\n")
|
||||||
txt.print("blue = second line irq\n")
|
txt.print("blue = second line irq\n")
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user