move cx16 irq examples to new API, fix some bugs in the handler

This commit is contained in:
Irmen de Jong
2023-11-22 23:23:10 +01:00
parent 16851746d6
commit 1b2296ad5b
14 changed files with 69 additions and 28 deletions

View File

@ -433,9 +433,9 @@ save_SCRATCH_ZPWORD2 .word 0
asmsub set_irq(uword handler @AY) clobbers(A) { asmsub set_irq(uword handler @AY) clobbers(A) {
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
sei
lda #<_irq_handler lda #<_irq_handler
sta cbm.CINV sta cbm.CINV
lda #>_irq_handler lda #>_irq_handler
@ -484,11 +484,11 @@ asmsub restore_irq() clobbers(A) {
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) { asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
lda cx16.r0 lda cx16.r0
ldy cx16.r0+1 ldy cx16.r0+1
sei
jsr _setup_raster_irq jsr _setup_raster_irq
lda #<_raster_irq_handler lda #<_raster_irq_handler
sta cbm.CINV sta cbm.CINV

View File

@ -435,9 +435,9 @@ save_SCRATCH_ZPWORD2 .word 0
asmsub set_irq(uword handler @AY) clobbers(A) { asmsub set_irq(uword handler @AY) clobbers(A) {
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
sei
lda #<_irq_handler lda #<_irq_handler
sta cbm.CINV sta cbm.CINV
lda #>_irq_handler lda #>_irq_handler
@ -484,11 +484,11 @@ asmsub restore_irq() clobbers(A) {
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) { asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
lda cx16.r0 lda cx16.r0
ldy cx16.r0+1 ldy cx16.r0+1
sei
jsr _setup_raster_irq jsr _setup_raster_irq
lda #<_raster_irq_handler lda #<_raster_irq_handler
sta cbm.CINV sta cbm.CINV

View File

@ -108,7 +108,7 @@ psg {
; If you want to use real-time volume envelopes (Attack-Sustain-Release), ; If you want to use real-time volume envelopes (Attack-Sustain-Release),
; you have to call this routine every 1/60th second, for example from your vsync irq handler, ; you have to call this routine every 1/60th second, for example from your vsync irq handler,
; or just install this routine as the only irq handler if you don't have to do other things there. ; or just install this routine as the only irq handler if you don't have to do other things there.
; Example: cx16.set_irq(&psg.envelopes_irq) ; Example: cx16.set_vsync_irq_handler(&psg.envelopes_irq)
; NOTE: this routine calls save/restore_vera_context() for you, don't nest this or call it yourself! ; NOTE: this routine calls save/restore_vera_context() for you, don't nest this or call it yourself!
; cx16.r0 = the volume word (volume scaled by 256) ; cx16.r0 = the volume word (volume scaled by 256)

View File

@ -854,7 +854,15 @@ asmsub restore_vera_context() clobbers(A) {
; Commander X16 IRQ dispatcher routines ; Commander X16 IRQ dispatcher routines
asmsub enable_irq_handlers() clobbers(A,Y) { inline asmsub disable_vera_irqs() clobbers(A) {
; Disable all Vera IRQ sources. Note that it does NOT set the CPU IRQ disabled status bit!
%asm {{
lda #%00001111
trb cx16.VERA_IEN
}}
}
asmsub enable_irq_handlers(bool disable_all_irq_sources @Pc) clobbers(A,Y) {
; Install the "master IRQ handler" that will dispatch IRQs. ; Install the "master IRQ handler" that will dispatch IRQs.
; to the registered handler for each type. (Only Vera IRQs supported for now). ; 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: ; The handlers don't need to clear its ISR bit, but have to return 0 or 1 in A:
@ -862,7 +870,10 @@ asmsub enable_irq_handlers() clobbers(A,Y) {
%asm {{ %asm {{
php php
sei sei
lda #<_irq_dispatcher bcc +
lda #%00001111
trb cx16.VERA_IEN ; disable all IRQ sources
+ lda #<_irq_dispatcher
ldy #>_irq_dispatcher ldy #>_irq_dispatcher
sta cx16.CINV sta cx16.CINV
sty cx16.CINV+1 sty cx16.CINV+1
@ -873,14 +884,15 @@ _irq_dispatcher
jsr sys.save_prog8_internals jsr sys.save_prog8_internals
cld cld
lda cx16.VERA_ISR lda cx16.VERA_ISR
and cx16.VERA_IEN ; only consider the bits for sources that can actually raise the IRQ
lsr a lsr a
bcc + bcc +
_mod_vsync_jump _mod_vsync_jump
jsr _default_vsync_handler ; modified jsr _default_vsync_handler ; modified
cmp #0 cmp #0
bne _dispatch_end bne _dispatch_end
lda #1 ldy #1
sta cx16.VERA_ISR sty cx16.VERA_ISR
bra _return_irq bra _return_irq
+ lsr a + lsr a
bcc + bcc +
@ -934,10 +946,13 @@ 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. ; 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. ; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
%asm {{ %asm {{
php
sei
sta enable_irq_handlers._mod_vsync_jump+1 sta enable_irq_handlers._mod_vsync_jump+1
sty enable_irq_handlers._mod_vsync_jump+2 sty enable_irq_handlers._mod_vsync_jump+2
lda #1 lda #1
tsb cx16.VERA_IEN tsb cx16.VERA_IEN
plp
rts rts
}} }}
} }
@ -947,6 +962,8 @@ asmsub set_line_irq_handler(uword rasterline @R0, uword address @AY) clobbers(A,
; You can use sys.set_rasterline() later to adjust the rasterline on which to trigger. ; 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. ; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
%asm {{ %asm {{
php
sei
sta enable_irq_handlers._mod_line_jump+1 sta enable_irq_handlers._mod_line_jump+1
sty enable_irq_handlers._mod_line_jump+2 sty enable_irq_handlers._mod_line_jump+2
lda cx16.r0 lda cx16.r0
@ -954,6 +971,7 @@ asmsub set_line_irq_handler(uword rasterline @R0, uword address @AY) clobbers(A,
jsr sys.set_rasterline jsr sys.set_rasterline
lda #2 lda #2
tsb cx16.VERA_IEN tsb cx16.VERA_IEN
plp
rts rts
}} }}
} }
@ -962,10 +980,13 @@ 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. ; 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. ; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
%asm {{ %asm {{
php
sei
sta enable_irq_handlers._mod_sprcol_jump+1 sta enable_irq_handlers._mod_sprcol_jump+1
sty enable_irq_handlers._mod_sprcol_jump+2 sty enable_irq_handlers._mod_sprcol_jump+2
lda #4 lda #4
tsb cx16.VERA_IEN tsb cx16.VERA_IEN
plp
rts rts
}} }}
} }
@ -974,10 +995,13 @@ 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. ; 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. ; NOTE: unless a proper irq handler is already running, you should enclose this call in set_irqd() / clear_irqd() to avoid system crashes.
%asm {{ %asm {{
php
sei
sta enable_irq_handlers._mod_aflow_jump+1 sta enable_irq_handlers._mod_aflow_jump+1
sty enable_irq_handlers._mod_aflow_jump+2 sty enable_irq_handlers._mod_aflow_jump+2
lda #8 lda #8
tsb cx16.VERA_IEN tsb cx16.VERA_IEN
plp
rts rts
}} }}
} }
@ -1075,9 +1099,9 @@ asmsub cleanup_at_exit() {
asmsub set_irq(uword handler @AY) clobbers(A) { asmsub set_irq(uword handler @AY) clobbers(A) {
; Sets the handler for the VSYNC interrupt, and enable that interrupt. ; Sets the handler for the VSYNC interrupt, and enable that interrupt.
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
sei
lda #<_irq_handler lda #<_irq_handler
sta cx16.CINV sta cx16.CINV
lda #>_irq_handler lda #>_irq_handler
@ -1126,11 +1150,11 @@ _orig_irqvec .word 0
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) { asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
; Sets the handler for the LINE interrupt, and enable (only) that interrupt. ; Sets the handler for the LINE interrupt, and enable (only) that interrupt.
%asm {{ %asm {{
sei
sta _modified+1 sta _modified+1
sty _modified+2 sty _modified+2
lda cx16.r0 lda cx16.r0
ldy cx16.r0+1 ldy cx16.r0+1
sei
lda cx16.VERA_IEN lda cx16.VERA_IEN
and #%11110000 ; disable all irqs but the line(raster) one and #%11110000 ; disable all irqs but the line(raster) one
ora #%00000010 ora #%00000010
@ -1162,6 +1186,8 @@ _modified jsr $ffff ; modified
asmsub set_rasterline(uword line @AY) { asmsub set_rasterline(uword line @AY) {
%asm {{ %asm {{
php
sei
sta cx16.VERA_IRQLINE_L sta cx16.VERA_IRQLINE_L
lda cx16.VERA_IEN lda cx16.VERA_IEN
and #%01111111 and #%01111111
@ -1172,6 +1198,7 @@ asmsub set_rasterline(uword line @AY) {
and #%10000000 and #%10000000
ora cx16.VERA_IEN ora cx16.VERA_IEN
sta cx16.VERA_IEN sta cx16.VERA_IEN
plp
rts rts
}} }}
} }

View File

@ -2,7 +2,6 @@
TODO TODO
==== ====
- move x16 irq examples over to new style handler
- optimize sys.set_rasterline on X16 - optimize sys.set_rasterline on X16
- document new x16 irq handling stuff in docs - document new x16 irq handling stuff in docs

View File

@ -7,7 +7,8 @@ main {
sub explosion() { sub explosion() {
; this subroutine is not used but it is an example of how to make a sound effect using the psg library! ; this subroutine is not used but it is an example of how to make a sound effect using the psg library!
psg.silent() psg.silent()
sys.set_irq(&psg.envelopes_irq) cx16.enable_irq_handlers(true)
cx16.set_vsync_irq_handler(&psg.envelopes_irq)
psg.voice(0, psg.LEFT, 0, psg.NOISE, 0) psg.voice(0, psg.LEFT, 0, psg.NOISE, 0)
psg.voice(1, psg.RIGHT, 0, psg.NOISE, 0) psg.voice(1, psg.RIGHT, 0, psg.NOISE, 0)
psg.freq(0, 1000) psg.freq(0, 1000)
@ -16,7 +17,7 @@ main {
psg.envelope(1, 63, 80, 0, 6) psg.envelope(1, 63, 80, 0, 6)
sys.wait(100) sys.wait(100)
psg.silent() psg.silent()
sys.restore_irq() cx16.disable_irq_handlers()
} }
sub sweeping() { sub sweeping() {
@ -59,7 +60,9 @@ main {
psg.silent() psg.silent()
psg.voice(0, psg.LEFT, 63, psg.TRIANGLE, 0) psg.voice(0, psg.LEFT, 63, psg.TRIANGLE, 0)
psg.voice(1, psg.RIGHT, 63, psg.TRIANGLE, 0) psg.voice(1, psg.RIGHT, 63, psg.TRIANGLE, 0)
sys.set_irq(&psg.envelopes_irq)
cx16.enable_irq_handlers(true)
cx16.set_vsync_irq_handler(&psg.envelopes_irq)
repeat { repeat {
uword note uword note
@ -76,6 +79,7 @@ main {
} }
psg.silent() psg.silent()
cx16.disable_irq_handlers()
} }
sub print_notes(ubyte n1, ubyte n2) { sub print_notes(ubyte n1, ubyte n2) {

View File

@ -39,7 +39,8 @@ main {
palette.set_color(0, $000) palette.set_color(0, $000)
palette.set_color(1, $af8) palette.set_color(1, $af8)
sys.set_rasterirq(&irq, 340) ; time it so that the page flip at the end occurs near the bottom of the screen to avoid tearing cx16.enable_irq_handlers(true)
cx16.set_line_irq_handler(340, &irq) ; time it so that the page flip at the end occurs near the bottom of the screen to avoid tearing
repeat { repeat {
; don't exit ; don't exit
@ -55,7 +56,7 @@ main {
uword anim3 = $e321 uword anim3 = $e321
uword anim4 = $7500 uword anim4 = $7500
sub irq() { sub irq() -> bool {
; palette.set_color(0, $f00) ; debug rastertime ; palette.set_color(0, $f00) ; debug rastertime
@ -82,6 +83,7 @@ main {
cx16.VERA_L1_TILEBASE = vmembase << 2 ; flip to next backbuffer cx16.VERA_L1_TILEBASE = vmembase << 2 ; flip to next backbuffer
; palette.set_color(0, $000) ; palette.set_color(0, $000)
return false
} }
sub init_buffers() { sub init_buffers() {

View File

@ -21,7 +21,8 @@ main {
txt.print("random gradients") txt.print("random gradients")
irq.make_new_gradient() irq.make_new_gradient()
sys.set_rasterirq(&irq.irqhandler, irq.top_scanline) cx16.enable_irq_handlers(true)
cx16.set_line_irq_handler(irq.top_scanline, &irq.irqhandler)
repeat { repeat {
} }
@ -41,7 +42,7 @@ irq {
ubyte[32+32+16] blinds_lines_blues ubyte[32+32+16] blinds_lines_blues
sub irqhandler() { sub irqhandler() -> bool {
set_scanline_color(color_ix) set_scanline_color(color_ix)
color_ix++ color_ix++
@ -66,6 +67,7 @@ irq {
} }
sys.set_rasterline(next_irq_line) sys.set_rasterline(next_irq_line)
return false
} }
sub make_new_gradient() { sub make_new_gradient() {

View File

@ -24,7 +24,8 @@ main {
palette.set_rgb(&colors, len(colors)) palette.set_rgb(&colors, len(colors))
gfx2.screen_mode(1) ; lores 256 colors gfx2.screen_mode(1) ; lores 256 colors
cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch 1 line of display all the way to the bottom cx16.VERA_DC_VSCALE = 0 ; display trick spoiler.......: stretch 1 line of display all the way to the bottom
sys.set_rasterirq(&irq.irqhandler, 0) cx16.enable_irq_handlers(true)
cx16.set_line_irq_handler(0, &irq.irqhandler)
repeat { repeat {
; don't exit ; don't exit
@ -34,7 +35,7 @@ main {
irq { irq {
const ubyte BAR_Y_OFFSET = 5 const ubyte BAR_Y_OFFSET = 6
uword next_irq_line = 0 uword next_irq_line = 0
ubyte anim1 = 0 ubyte anim1 = 0
ubyte av1 = 0 ubyte av1 = 0
@ -42,7 +43,7 @@ irq {
ubyte av2 = 0 ubyte av2 = 0
ubyte[32] pixels = 0 to 31 ubyte[32] pixels = 0 to 31
sub irqhandler() { sub irqhandler() -> bool {
next_irq_line += BAR_Y_OFFSET next_irq_line += BAR_Y_OFFSET
anim1 += 7 anim1 += 7
anim2 += 4 anim2 += 4
@ -61,5 +62,6 @@ irq {
} }
sys.set_rasterline(next_irq_line) sys.set_rasterline(next_irq_line)
return false
} }
} }

View File

@ -9,7 +9,7 @@
main { main {
sub start() { sub start() {
cx16.enable_irq_handlers() cx16.enable_irq_handlers(true)
cx16.set_line_irq_handler(150, &irq.line_irq) cx16.set_line_irq_handler(150, &irq.line_irq)
cx16.set_vsync_irq_handler(&irq.vsync_irq) cx16.set_vsync_irq_handler(&irq.vsync_irq)

View File

@ -23,7 +23,7 @@ main {
irq { irq {
sub master_handler() -> bool { sub master_handler() -> bool {
ubyte irqsrc = cx16.VERA_ISR ubyte irqsrc = cx16.VERA_ISR & cx16.VERA_IEN ; only consider sources that are enabled
ror(irqsrc) ror(irqsrc)
if_cs { if_cs {
vsync_irq() vsync_irq()

View File

@ -16,7 +16,8 @@ main {
txt.plot(14,14) txt.plot(14,14)
txt.print("raster bars!") txt.print("raster bars!")
sys.set_rasterirq(&irq.irqhandler, 0) cx16.enable_irq_handlers(true)
cx16.set_line_irq_handler(0, &irq.irqhandler)
repeat { repeat {
; don't exit ; don't exit
@ -42,7 +43,7 @@ irq {
ubyte yanim = 0 ubyte yanim = 0
const ubyte barheight = 4 const ubyte barheight = 4
sub irqhandler() { sub irqhandler() -> bool {
uword c = colors[color_idx] uword c = colors[color_idx]
color_idx++ color_idx++
color_idx &= 31 color_idx &= 31
@ -57,5 +58,6 @@ irq {
palette.set_color(0, c) palette.set_color(0, c)
sys.set_rasterline(next_irq_line) sys.set_rasterline(next_irq_line)
return false
} }
} }

View File

@ -679,7 +679,8 @@ sound {
sub init() { sub init() {
cx16.vpoke(1, $f9c2, %00111111) ; volume max, no channels cx16.vpoke(1, $f9c2, %00111111) ; volume max, no channels
psg.silent() psg.silent()
sys.set_irq(&psg.envelopes_irq) cx16.enable_irq_handlers(true)
cx16.set_vsync_irq_handler(&psg.envelopes_irq)
} }
sub blockrotate() { sub blockrotate() {

View File

@ -59,7 +59,8 @@ zsound_lib:
pcm_init() pcm_init()
pcm_trigger_digi(digi_bank, digi_address) pcm_trigger_digi(digi_bank, digi_address)
sys.set_irq(&zsm_playroutine_irq) cx16.enable_irq_handlers(true)
cx16.set_vsync_irq_handler(&zsm_playroutine_irq)
txt.print("\nstreaming from file, playback in irq!\n") txt.print("\nstreaming from file, playback in irq!\n")
uword size = 1 uword size = 1
@ -77,6 +78,7 @@ zsound_lib:
} }
pcm_stop() ;unreached pcm_stop() ;unreached
cx16.disable_irq_handlers()
} }
sub zsm_playroutine_irq() -> bool { sub zsm_playroutine_irq() -> bool {