mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
cx16: optimized sys.set_rasterline()
This commit is contained in:
parent
1b2296ad5b
commit
98570ac456
@ -854,7 +854,7 @@ asmsub restore_vera_context() clobbers(A) {
|
||||
|
||||
; Commander X16 IRQ dispatcher routines
|
||||
|
||||
inline asmsub disable_vera_irqs() clobbers(A) {
|
||||
inline asmsub disable_irqs() clobbers(A) {
|
||||
; Disable all Vera IRQ sources. Note that it does NOT set the CPU IRQ disabled status bit!
|
||||
%asm {{
|
||||
lda #%00001111
|
||||
@ -863,9 +863,9 @@ inline asmsub disable_vera_irqs() clobbers(A) {
|
||||
}
|
||||
|
||||
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).
|
||||
; 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,
|
||||
; where 1 means: continue with the system IRQ handler, 0 means: don't call that.
|
||||
%asm {{
|
||||
php
|
||||
@ -1007,10 +1007,10 @@ asmsub set_aflow_irq_handler(uword address @AY) clobbers(A) {
|
||||
}
|
||||
|
||||
|
||||
asmsub disable_irq_handlers() {
|
||||
inline asmsub disable_irq_handlers() {
|
||||
; back to the system default IRQ handler.
|
||||
%asm {{
|
||||
jmp sys.restore_irq
|
||||
jsr sys.restore_irq
|
||||
}}
|
||||
}
|
||||
|
||||
@ -1189,15 +1189,15 @@ asmsub set_rasterline(uword line @AY) {
|
||||
php
|
||||
sei
|
||||
sta cx16.VERA_IRQLINE_L
|
||||
lda cx16.VERA_IEN
|
||||
and #%01111111
|
||||
sta cx16.VERA_IEN
|
||||
tya
|
||||
lsr a
|
||||
ror a
|
||||
and #%10000000
|
||||
ora cx16.VERA_IEN
|
||||
sta cx16.VERA_IEN
|
||||
bcs +
|
||||
lda #%10000000
|
||||
trb cx16.VERA_IEN
|
||||
plp
|
||||
rts
|
||||
+ lda #%10000000
|
||||
tsb cx16.VERA_IEN
|
||||
plp
|
||||
rts
|
||||
}}
|
||||
|
@ -138,7 +138,7 @@ IRQ Handling
|
||||
|
||||
Normally, the system's default IRQ handling is not interfered with.
|
||||
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 C64 60hz IRQs and Raster IRQs a lot easier (no assembly code required).
|
||||
There are a few library routines available to make setting up 60hz/vsync IRQs and raster/line IRQs a lot easier (no assembly code required).
|
||||
|
||||
These routines are::
|
||||
|
||||
@ -146,7 +146,7 @@ These routines are::
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
@ -158,9 +158,10 @@ 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.
|
||||
or not calling the system IRQ handler routine. See the section below for perhaps a better and easier solution that
|
||||
is tailored to this system.
|
||||
|
||||
The Commander X16 syslib provides two additional routines that should be used *in your IRQ handler routine* if it uses the Vera registers.
|
||||
The Commander X16 syslib provides some 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
|
||||
will corrupt any Vera operations that were going on in the main program. The routines are::
|
||||
|
||||
@ -184,3 +185,42 @@ will corrupt any Vera operations that were going on in the main program. The rou
|
||||
of corrupting variables and floating point calculations that are being executed
|
||||
in the interrupted main program. These memory locations should be backed up
|
||||
and restored at the end of the handler, further increasing its execution time...
|
||||
|
||||
|
||||
Commander X16 specific IRQ handling
|
||||
===================================
|
||||
|
||||
Instead of using the routines in `sys` as mentioned above (that are more or less portable
|
||||
across the C64,C128 and cx16), you can also use the special routines made for the Commander X16,
|
||||
in `cx16`. The idea is to let Prog8 do the irq dispatching and housekeeping for you, and that
|
||||
your program only has to register the specific handlers for the specific IRQ sources that you want to handle.
|
||||
|
||||
Look at the examples/cx16/multi-irq-new.p8 example to see how these routines can be used.
|
||||
Here they are, all available in `cx16`:
|
||||
|
||||
``disable_irqs ()``
|
||||
Disables all Vera IRQ sources. Note that the CPU irq disable flag is not changed by this routine.
|
||||
you can manipulate that via ``sys.set_irqd()`` and ``sys.clear_irqd()`` as usual.
|
||||
|
||||
``enable_irq_handlers (bool disable_all_irq_sources)``
|
||||
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.
|
||||
|
||||
``set_vsync_irq_handler (uword address)``
|
||||
Sets the verical sync interrupt handler routine. Also enables VSYNC interrupts.
|
||||
|
||||
``set_line_irq_handler (uword rasterline, uword address)``
|
||||
Sets the rasterline interrupt handler routine to trigger on the specified raster line.
|
||||
Also enables LINE interrupts.
|
||||
You can use ``sys.set_rasterline()`` later to adjust the rasterline on which to trigger.
|
||||
|
||||
``set_sprcol_irq_handler (uword address)``
|
||||
Sets the sprite collision interrupt handler routine. Also enables SPRCOL interrupts.
|
||||
|
||||
``set_aflow_irq_handler (uword address)``
|
||||
Sets the audio buffer underrun interrupt handler routine. Also enables AFLOW interrupts.
|
||||
|
||||
``disable_irq_handlers ()``
|
||||
Hand control back to the system default IRQ handler.
|
||||
|
@ -2,9 +2,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- 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
|
||||
xx |= %0001000, xx &= %1110111
|
||||
|
||||
|
@ -3,14 +3,19 @@
|
||||
%import syslib
|
||||
%zeropage basicsafe
|
||||
|
||||
; Example that shows a way to handle multiple IRQ sources on the X16.
|
||||
; 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 {
|
||||
sub start() {
|
||||
sys.set_rasterline(150)
|
||||
sys.set_irq(&irq.master_handler)
|
||||
cx16.VERA_IEN |= 2 ; also enable line irq
|
||||
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("\n\n\nx16 irq handlers installed (old style)\n")
|
||||
txt.print("red = vsync irq\n")
|
||||
txt.print("green = first line irq\n")
|
||||
txt.print("blue = second line irq\n")
|
||||
}
|
||||
@ -18,7 +23,7 @@ main {
|
||||
|
||||
irq {
|
||||
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)
|
||||
if_cs {
|
||||
vsync_irq()
|
||||
|
Loading…
Reference in New Issue
Block a user