changed system irq/rasterirq setting routines

This commit is contained in:
Irmen de Jong 2021-02-21 22:17:28 +01:00
parent 4aca8bb8df
commit a95677564e
11 changed files with 84 additions and 103 deletions

View File

@ -304,27 +304,13 @@ asmsub disable_runstop_and_charsetswitch() clobbers(A) {
}}
}
asmsub set_irqvec_excl() clobbers(A) {
%asm {{
sei
lda #<_irq_handler
sta c64.CINV
lda #>_irq_handler
sta c64.CINV+1
cli
rts
_irq_handler jsr set_irqvec._irq_handler_init
jsr irq.irq
jsr set_irqvec._irq_handler_end
lda #$ff
sta c64.VICIRQ ; acknowledge raster irq
lda c64.CIA1ICR ; acknowledge CIA1 interrupt
jmp c64.IRQDFEND ; end irq processing - don't call kernel
}}
}
asmsub set_irqvec() clobbers(A) {
asmsub set_irq(uword handler @AY, ubyte useKernal @Pc) clobbers(A) {
%asm {{
sta _modified+1
sty _modified+2
lda #0
adc #0
sta _use_kernal
sei
lda #<_irq_handler
sta c64.CINV
@ -333,9 +319,23 @@ asmsub set_irqvec() clobbers(A) {
cli
rts
_irq_handler jsr _irq_handler_init
jsr irq.irq
_modified jsr $ffff ; modified
jsr _irq_handler_end
jmp c64.IRQDFRT ; continue with normal kernel irq routine
lda _use_kernal
bne +
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 c64.IRQDFRT ; continue with normal kernal irq routine
_use_kernal .byte 0
_irq_handler_init
; save all zp scratch registers and the X register as these might be clobbered by the irq routine
@ -388,7 +388,7 @@ IRQ_SCRATCH_ZPWORD2 .word 0
}}
}
asmsub restore_irqvec() clobbers(A) {
asmsub restore_irq() clobbers(A) {
%asm {{
sei
lda #<c64.IRQDFRT
@ -404,8 +404,15 @@ asmsub restore_irqvec() clobbers(A) {
}}
}
asmsub set_rasterirq(uword rasterpos @ AY) clobbers(A) {
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0, ubyte useKernal @Pc) clobbers(A) {
%asm {{
sta _modified+1
sty _modified+2
lda #0
adc #0
sta _use_kernal
lda cx16.r0
ldy cx16.r0+1
sei
jsr _setup_raster_irq
lda #<_raster_irq_handler
@ -415,13 +422,24 @@ asmsub set_rasterirq(uword rasterpos @ AY) clobbers(A) {
cli
rts
_use_kernal .byte 0
_raster_irq_handler
jsr set_irqvec._irq_handler_init
jsr irq.irq
jsr set_irqvec._irq_handler_end
lda #$ff
sta c64.VICIRQ ; acknowledge raster irq
jmp c64.IRQDFRT
jsr set_irq._irq_handler_init
_modified jsr $ffff ; modified
jsr set_irq._irq_handler_end
lda #$ff
sta c64.VICIRQ ; acknowledge raster irq
lda _use_kernal
bne +
; end irq processing - don't use kernal's irq handling
pla
tay
pla
tax
pla
rti
+ jmp c64.IRQDFRT ; continue with kernal irq routine
_setup_raster_irq
pha
@ -445,28 +463,6 @@ _setup_raster_irq
}}
}
asmsub set_rasterirq_excl(uword rasterpos @ AY) clobbers(A) {
%asm {{
sei
jsr set_rasterirq._setup_raster_irq
lda #<_raster_irq_handler
sta c64.CINV
lda #>_raster_irq_handler
sta c64.CINV+1
cli
rts
_raster_irq_handler
jsr set_irqvec._irq_handler_init
jsr irq.irq
jsr set_irqvec._irq_handler_end
lda #$ff
sta c64.VICIRQ ; acknowledge raster irq
jmp c64.IRQDFEND ; end irq processing - don't call kernel
}}
}
; ---- end of C64 specific system utility routines ----
}

View File

@ -41,19 +41,6 @@ internal class AstChecker(private val program: Program,
}
}
// there can be an optional single 'irq' block with a 'irq' subroutine in it,
// which will be used as the 60hz irq routine in the vm if it's present
val irqBlocks = program.modules.flatMap { it.statements }.filter { it is Block && it.name=="irq" }.map { it as Block }
if(irqBlocks.size>1)
errors.err("more than one 'irq' block", irqBlocks[0].position)
for(irqBlock in irqBlocks) {
val irqSub = irqBlock.subScope("irq") as? Subroutine
if (irqSub != null) {
if (irqSub.parameters.isNotEmpty() || irqSub.returntypes.isNotEmpty())
errors.err("irq entrypoint subroutine can't have parameters and/or return values", irqSub.position)
}
}
super.visit(program)
}

View File

@ -16,8 +16,7 @@ import prog8.compiler.IErrorReporter
import java.nio.file.Path
private val alwaysKeepSubroutines = setOf(
Pair("main", "start"),
Pair("irq", "irq")
Pair("main", "start")
)
private val asmJumpRx = Regex("""[\-+a-zA-Z0-9_ \t]+(jmp|jsr)[ \t]+(\S+).*""", RegexOption.IGNORE_CASE)

View File

@ -139,26 +139,12 @@ IRQ Handling
============
Normally, the system's default IRQ handling is not interfered with.
You can however install your own IRQ handler.
This is possible ofcourse by doing it all using customized inline assembly,
but there are a few library routines available to make setting up C-64 IRQs and raster IRQs a lot easier (no assembly code required).
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 C-64 60hz IRQs and Raster IRQs a lot easier (no assembly code required).
For the C64 these routines are::
c64.set_irqvec()
c64.set_irqvec_excl()
c64.set_rasterirq( <raster line> )
c64.set_rasterirq_excl( <raster line> )
c64.restore_irqvec() ; set it back to the systems default irq handler
If you activate an IRQ handler with one of these, it expects the handler to be defined
as a subroutine ``irq`` in the module ``irq`` so like this::
irq {
sub irq() {
; ... irq handling here ...
}
}
c64.set_irq(uword handler_address, boolean useKernal)
c64.set_rasterirq(uword handler_address, uword rasterline, boolean useKernal)
c64.restore_irq() ; set everything back to the systems default irq handler

View File

@ -2,6 +2,8 @@
TODO
====
- rename kernel -> kernal
- add sys.halt() that is smart on the 65c02
- add sound to the cx16 tehtriz
- add const arrays and cost strings

View File

@ -23,7 +23,7 @@ main {
c64.SCROLX &= %11110111 ; 38 column mode
c64.set_rasterirq(200) ; enable animation
c64.set_rasterirq(&irq.irq, 200, false) ; enable animation via raster interrupt
ubyte target_height = 10
ubyte active_height = 24

View File

@ -7,7 +7,7 @@ main {
sub start() {
txt.print("playing the music from boulderdash,\nmade in 1984 by peter liepa.\n\n")
c64.set_rasterirq(60) ; enable raster irq
c64.set_rasterirq(&irq.irq, 60, true) ; enable playback via raster irq
}
}

View File

@ -4,8 +4,8 @@
main {
sub start() {
c64.SCROLY &= %11101111 ; blank the screen
c64.set_rasterirq_excl(40) ; register exclusive raster irq handler
c64.SCROLY &= %11101111 ; blank the screen
c64.set_rasterirq(&irq.irq, 40, false) ; register exclusive raster irq handler
repeat {
; enjoy the moving bars :)

View File

@ -46,7 +46,7 @@ main {
}
c64.SPENA = 255 ; enable all sprites
c64.set_rasterirq(51) ; enable animation
c64.set_rasterirq(&irq.irq, 255, true) ; enable animation
}
}

View File

@ -7,18 +7,11 @@ main {
; $1F9C0 - $1F9FF PSG registers
sub start() {
c64.set_rasterirq(&irq.irq, 100, true)
ubyte xx=33
when xx {
1 -> {
}
2 -> {
}
else -> {
}
else -> {
}
}
sys.wait(100)
c64.restore_irq()
; uword freq = 1181
; cx16.vpoke(1, $f9c0, lsb(freq))
@ -28,3 +21,21 @@ main {
}
}
irq {
uword counter = 0
sub irq() {
c64.EXTCOL++
ubyte xx
repeat 20 {
xx++
}
c64.EXTCOL--
@($0400) = lsb(counter)
@($0401) = msb(counter)
counter++
}
}

View File

@ -37,7 +37,7 @@ main {
c64.SPRPTR[i] = $0a00/64
}
c64.SPENA = 255 ; enable all sprites
c64.set_rasterirq(220) ; enable animation
c64.set_rasterirq(&irq.irq, 230, true) ; enable animation
}
}