mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
breaking change: sys.set_irq() and sys.set_rasterirq() no longer have useKernal parameter! The irq handler routine must return a boolean instead in the A register.
When it returns true it means run the system IRQ handler afterwards. When it returns false, the system handler is NOT ran afterwards.
This commit is contained in:
parent
a83e9d9a0a
commit
08ac459a41
@ -431,13 +431,10 @@ save_SCRATCH_ZPWORD2 .word 0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_irq(uword handler @AY, bool useKernal @Pc) clobbers(A) {
|
||||
asmsub set_irq(uword handler @AY) clobbers(A) {
|
||||
%asm {{
|
||||
sta _modified+1
|
||||
sty _modified+2
|
||||
lda #0
|
||||
rol a
|
||||
sta _use_kernal
|
||||
sei
|
||||
lda #<_irq_handler
|
||||
sta cbm.CINV
|
||||
@ -450,20 +447,20 @@ _irq_handler
|
||||
cld
|
||||
_modified
|
||||
jsr $ffff ; modified
|
||||
pha
|
||||
jsr sys.restore_prog8_internals
|
||||
lda _use_kernal
|
||||
bne +
|
||||
lda #$ff
|
||||
pla
|
||||
beq +
|
||||
jmp cbm.IRQDFRT ; continue with normal kernal irq routine
|
||||
+ 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 cbm.IRQDFRT ; continue with normal kernal irq routine
|
||||
|
||||
_use_kernal .byte 0
|
||||
}}
|
||||
@ -485,13 +482,10 @@ asmsub restore_irq() clobbers(A) {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0, bool useKernal @Pc) clobbers(A) {
|
||||
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
|
||||
%asm {{
|
||||
sta _modified+1
|
||||
sty _modified+2
|
||||
lda #0
|
||||
rol a
|
||||
sta set_irq._use_kernal
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
sei
|
||||
@ -508,19 +502,19 @@ _raster_irq_handler
|
||||
cld
|
||||
_modified
|
||||
jsr $ffff ; modified
|
||||
pha
|
||||
jsr sys.restore_prog8_internals
|
||||
lda #$ff
|
||||
sta c64.VICIRQ ; acknowledge raster irq
|
||||
lda set_irq._use_kernal
|
||||
bne +
|
||||
; end irq processing - don't use kernal's irq handling
|
||||
pla
|
||||
beq +
|
||||
jmp cbm.IRQDFRT ; continue with kernal irq routine
|
||||
+ pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
+ jmp cbm.IRQDFRT ; continue with kernal irq routine
|
||||
|
||||
_setup_raster_irq
|
||||
pha
|
||||
|
@ -433,13 +433,10 @@ save_SCRATCH_ZPWORD2 .word 0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_irq(uword handler @AY, bool useKernal @Pc) clobbers(A) {
|
||||
asmsub set_irq(uword handler @AY) clobbers(A) {
|
||||
%asm {{
|
||||
sta _modified+1
|
||||
sty _modified+2
|
||||
lda #0
|
||||
rol a
|
||||
sta _use_kernal
|
||||
sei
|
||||
lda #<_irq_handler
|
||||
sta cbm.CINV
|
||||
@ -452,23 +449,21 @@ _irq_handler
|
||||
cld
|
||||
_modified
|
||||
jsr $ffff ; modified
|
||||
pha
|
||||
jsr sys.restore_prog8_internals
|
||||
lda _use_kernal
|
||||
bne +
|
||||
lda #$ff
|
||||
pla
|
||||
beq +
|
||||
jmp cbm.IRQDFRT ; continue with normal kernal irq routine
|
||||
+ 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 cbm.IRQDFRT ; continue with normal kernal irq routine
|
||||
|
||||
_use_kernal .byte 0
|
||||
}}
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub restore_irq() clobbers(A) {
|
||||
@ -487,13 +482,10 @@ asmsub restore_irq() clobbers(A) {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0, bool useKernal @Pc) clobbers(A) {
|
||||
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
|
||||
%asm {{
|
||||
sta _modified+1
|
||||
sty _modified+2
|
||||
lda #0
|
||||
rol a
|
||||
sta set_irq._use_kernal
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
sei
|
||||
@ -510,19 +502,19 @@ _raster_irq_handler
|
||||
cld
|
||||
_modified
|
||||
jsr $ffff ; modified
|
||||
pha
|
||||
jsr sys.restore_prog8_internals
|
||||
lda #$ff
|
||||
sta c64.VICIRQ ; acknowledge raster irq
|
||||
lda set_irq._use_kernal
|
||||
bne +
|
||||
; end irq processing - don't use kernal's irq handling
|
||||
pla
|
||||
pla
|
||||
beq +
|
||||
jmp cbm.IRQDFRT ; continue with kernal irq routine
|
||||
+ pla
|
||||
tay
|
||||
pla
|
||||
tax
|
||||
pla
|
||||
rti
|
||||
+ jmp cbm.IRQDFRT ; continue with kernal irq routine
|
||||
|
||||
_setup_raster_irq
|
||||
pha
|
||||
|
@ -104,11 +104,11 @@ psg {
|
||||
}
|
||||
}
|
||||
|
||||
sub envelopes_irq() {
|
||||
sub envelopes_irq() -> bool {
|
||||
; 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,
|
||||
; 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, true)
|
||||
; Example: cx16.set_irq(&psg.envelopes_irq)
|
||||
; 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)
|
||||
@ -170,6 +170,7 @@ psg {
|
||||
pop(cx16.r2L)
|
||||
pop(cx16.r1L)
|
||||
popw(cx16.r0)
|
||||
return true ; run the system IRQ handler afterwards
|
||||
}
|
||||
|
||||
ubyte[16] envelope_states
|
||||
|
@ -930,13 +930,10 @@ asmsub cleanup_at_exit() {
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub set_irq(uword handler @AY, bool useKernal @Pc) clobbers(A) {
|
||||
asmsub set_irq(uword handler @AY) clobbers(A) {
|
||||
%asm {{
|
||||
sta _modified+1
|
||||
sty _modified+2
|
||||
lda #0
|
||||
rol a
|
||||
sta _use_kernal
|
||||
sei
|
||||
lda #<_irq_handler
|
||||
sta cx16.CINV
|
||||
@ -953,17 +950,17 @@ _irq_handler
|
||||
cld
|
||||
_modified
|
||||
jsr $ffff ; modified
|
||||
pha
|
||||
jsr sys.restore_prog8_internals
|
||||
lda _use_kernal
|
||||
bne +
|
||||
; end irq processing - don't use kernal's irq handling
|
||||
lda #1
|
||||
pla
|
||||
beq +
|
||||
jmp (restore_irq._orig_irqvec) ; continue with normal kernal irq routine
|
||||
+ lda #1
|
||||
sta cx16.VERA_ISR ; clear Vera Vsync irq status
|
||||
ply
|
||||
plx
|
||||
pla
|
||||
rti
|
||||
+ jmp (restore_irq._orig_irqvec) ; continue with normal kernal irq routine
|
||||
|
||||
_use_kernal .byte 0
|
||||
}}
|
||||
|
@ -142,14 +142,23 @@ There are a few library routines available to make setting up C64 60hz IRQs and
|
||||
|
||||
These routines are::
|
||||
|
||||
sys.set_irq(uword handler_address, bool useKernal)
|
||||
sys.set_rasterirq(uword handler_address, uword rasterline, boolean useKernal)
|
||||
sys.set_irq(uword handler_address)
|
||||
sys.set_rasterirq(uword handler_address, uword rasterline)
|
||||
sys.restore_irq() ; set everything back to the systems default irq handler
|
||||
|
||||
The IRQ handler routine must return a boolean value (0 or 1) in the A register.
|
||||
0 means do *not* run the system IRQ handler routine afterwards, 1 means run the system IRQ handler routine afterwards.
|
||||
|
||||
|
||||
**CommanderX16 specific notes**
|
||||
|
||||
Note that for the CommanderX16 the "useKernal" parameter doesn't exists for the set_rasterirq() routine;
|
||||
it will always disable the system IRQ handler (which also means the default sys.wait() routine won't work anymore)
|
||||
Note that for the CommanderX16 the set_rasterirq() will disable VSYNC irqs and never call the system IRQ handler regardless
|
||||
of the return value of the user handler routine. This also means the default sys.wait() routine won't work anymore,
|
||||
when using this handler.
|
||||
|
||||
These two helper routines are not particularly suited to handle multiple IRQ sources on the Commander X16.
|
||||
It's possible but it requires correct fiddling with IRQ enable bits, acknowledging the IRQs, and properly calling
|
||||
or not calling the system IRQ handler routine.
|
||||
|
||||
The Commander X16 syslib provides two additional routines that should be used *in your IRQ handler routine* if it uses the Vera registers.
|
||||
They take care of saving and restoring the Vera state of the interrupted main program, otherwise the IRQ handler's manipulation
|
||||
|
@ -2,7 +2,7 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- IRQ callback should return boolean to tell Prog8 to call the kernal ISR or not.
|
||||
- use TRB/TSB instructions more on the x16 such as when ack vera irq bits
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
|
||||
|
@ -23,7 +23,7 @@ main {
|
||||
|
||||
c64.SCROLX &= %11110111 ; 38 column mode
|
||||
|
||||
sys.set_rasterirq(&irq.irqhandler, 200, false) ; enable animation via raster interrupt
|
||||
sys.set_rasterirq(&irq.irqhandler, 200) ; enable animation via raster interrupt
|
||||
|
||||
ubyte target_height = 10
|
||||
ubyte active_height = 24
|
||||
@ -130,10 +130,11 @@ spritedata $0f00 {
|
||||
|
||||
irq {
|
||||
ubyte smoothx=0
|
||||
sub irqhandler() {
|
||||
sub irqhandler() -> bool {
|
||||
smoothx = (smoothx-1) & 7
|
||||
main.perform_scroll = smoothx==7
|
||||
c64.SCROLX = (c64.SCROLX & %11111000) | smoothx
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ main {
|
||||
|
||||
sub start() {
|
||||
txt.print("playing the music from boulderdash,\nmade in 1984 by peter liepa.\n\n")
|
||||
sys.set_rasterirq(&irq.irqhandler, 60, true) ; enable playback via raster irq
|
||||
sys.set_rasterirq(&irq.irqhandler, 60) ; enable playback via raster irq
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ irq {
|
||||
ubyte note_index = 0
|
||||
ubyte delay = 0
|
||||
|
||||
sub irqhandler() {
|
||||
sub irqhandler() -> bool {
|
||||
c64.EXTCOL++
|
||||
delay++
|
||||
if delay >= 8 {
|
||||
@ -41,6 +41,7 @@ irq {
|
||||
}
|
||||
|
||||
c64.EXTCOL--
|
||||
return true
|
||||
}
|
||||
|
||||
; details about the boulderdash music can be found here:
|
||||
|
@ -5,7 +5,7 @@ main {
|
||||
|
||||
sub start() {
|
||||
c64.SCROLY &= %11101111 ; blank the screen
|
||||
sys.set_rasterirq(&irq.irqhandler, 40, false) ; register exclusive raster irq handler
|
||||
sys.set_rasterirq(&irq.irqhandler, 40) ; register exclusive raster irq handler
|
||||
|
||||
repeat {
|
||||
; enjoy the moving bars :)
|
||||
@ -22,7 +22,7 @@ irq {
|
||||
ubyte color = 0
|
||||
ubyte yanim = 0
|
||||
|
||||
sub irqhandler() {
|
||||
sub irqhandler() -> bool {
|
||||
if color!=len(colors) {
|
||||
c64.EXTCOL = colors[color]
|
||||
c64.RASTER += barheight ; next raster Irq for next color
|
||||
@ -35,5 +35,6 @@ irq {
|
||||
c64.RASTER = math.sin8u(yanim)/2+30 ; new start of raster Irq
|
||||
}
|
||||
c64.SCROLY &= $7f ; set high bit of the raster pos to zero
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -46,14 +46,14 @@ main {
|
||||
}
|
||||
|
||||
c64.SPENA = 255 ; enable all sprites
|
||||
sys.set_rasterirq(&irq.irqhandler, 255, true) ; enable animation
|
||||
sys.set_rasterirq(&irq.irqhandler, 255) ; enable animation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
irq {
|
||||
|
||||
sub irqhandler() {
|
||||
sub irqhandler() -> bool {
|
||||
c64.EXTCOL--
|
||||
|
||||
; float up & wobble horizontally
|
||||
@ -68,6 +68,7 @@ irq {
|
||||
}
|
||||
|
||||
c64.EXTCOL++
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ main {
|
||||
c64.set_sprite_ptr(i, $0a00) ; alternatively, set directly: c64.SPRPTR[i] = $0a00 / 64
|
||||
}
|
||||
c64.SPENA = 255 ; enable all sprites
|
||||
sys.set_rasterirq(&irq.irqhandler, 230, true) ; enable animation
|
||||
sys.set_rasterirq(&irq.irqhandler, 230) ; enable animation
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ irq {
|
||||
ubyte angle1=200
|
||||
ubyte angle2=0
|
||||
|
||||
sub irqhandler() {
|
||||
sub irqhandler() -> bool {
|
||||
angle1 += 2
|
||||
angle2 += 3
|
||||
c64.MSIGX=0
|
||||
@ -61,5 +61,6 @@ irq {
|
||||
if msb(x) c64.MSIGX++
|
||||
}
|
||||
c64.EXTCOL-=8
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ main {
|
||||
sub explosion() {
|
||||
; this subroutine is not used but it is an example of how to make a sound effect using the psg library!
|
||||
psg.silent()
|
||||
sys.set_irq(&psg.envelopes_irq, true)
|
||||
sys.set_irq(&psg.envelopes_irq)
|
||||
psg.voice(0, psg.LEFT, 0, psg.NOISE, 0)
|
||||
psg.voice(1, psg.RIGHT, 0, psg.NOISE, 0)
|
||||
psg.freq(0, 1000)
|
||||
@ -59,7 +59,7 @@ main {
|
||||
psg.silent()
|
||||
psg.voice(0, psg.LEFT, 63, psg.TRIANGLE, 0)
|
||||
psg.voice(1, psg.RIGHT, 63, psg.TRIANGLE, 0)
|
||||
sys.set_irq(&psg.envelopes_irq, true)
|
||||
sys.set_irq(&psg.envelopes_irq)
|
||||
|
||||
repeat {
|
||||
uword note
|
||||
|
@ -679,7 +679,7 @@ sound {
|
||||
sub init() {
|
||||
cx16.vpoke(1, $f9c2, %00111111) ; volume max, no channels
|
||||
psg.silent()
|
||||
sys.set_irq(&psg.envelopes_irq, true)
|
||||
sys.set_irq(&psg.envelopes_irq)
|
||||
}
|
||||
|
||||
sub blockrotate() {
|
||||
|
@ -59,7 +59,7 @@ zsound_lib:
|
||||
|
||||
pcm_init()
|
||||
pcm_trigger_digi(digi_bank, digi_address)
|
||||
sys.set_irq(&zsm_playroutine_irq, true)
|
||||
sys.set_irq(&zsm_playroutine_irq)
|
||||
|
||||
txt.print("\nstreaming from file, playback in irq!\n")
|
||||
uword size = 1
|
||||
@ -79,7 +79,8 @@ zsound_lib:
|
||||
pcm_stop() ;unreached
|
||||
}
|
||||
|
||||
sub zsm_playroutine_irq() {
|
||||
sub zsm_playroutine_irq() -> bool {
|
||||
pcm_play()
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,21 @@
|
||||
%import palette
|
||||
%import textio
|
||||
%import syslib
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
sys.save_prog8_internals()
|
||||
txt.print("ok\n")
|
||||
sys.restore_prog8_internals()
|
||||
sys.set_rasterirq(&handler, 200)
|
||||
txt.print("installed\n")
|
||||
}
|
||||
|
||||
sub handler() -> bool {
|
||||
palette.set_color(0, $f00)
|
||||
repeat 1000 {
|
||||
cx16.r0++
|
||||
}
|
||||
palette.set_color(0, $000)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user