added irq routines for cx16

This commit is contained in:
Irmen de Jong 2021-02-21 23:41:50 +01:00
parent 0e62f5b759
commit 334f86480a
5 changed files with 199 additions and 20 deletions

View File

@ -294,6 +294,12 @@ asmsub init_system() {
}} }}
} }
asmsub init_system_phase2() {
%asm {{
rts ; no phase 2 steps on the C64
}}
}
asmsub disable_runstop_and_charsetswitch() clobbers(A) { asmsub disable_runstop_and_charsetswitch() clobbers(A) {
%asm {{ %asm {{
lda #$80 lda #$80
@ -410,7 +416,7 @@ asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0, ubyte useKernal @P
sty _modified+2 sty _modified+2
lda #0 lda #0
adc #0 adc #0
sta _use_kernal sta set_irq._use_kernal
lda cx16.r0 lda cx16.r0
ldy cx16.r0+1 ldy cx16.r0+1
sei sei
@ -422,15 +428,13 @@ asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0, ubyte useKernal @P
cli cli
rts rts
_use_kernal .byte 0
_raster_irq_handler _raster_irq_handler
jsr set_irq._irq_handler_init jsr set_irq._irq_handler_init
_modified jsr $ffff ; modified _modified jsr $ffff ; modified
jsr set_irq._irq_handler_end jsr set_irq._irq_handler_end
lda #$ff lda #$ff
sta c64.VICIRQ ; acknowledge raster irq sta c64.VICIRQ ; acknowledge raster irq
lda _use_kernal lda set_irq._use_kernal
bne + bne +
; end irq processing - don't use kernal's irq handling ; end irq processing - don't use kernal's irq handling
pla pla

View File

@ -102,10 +102,11 @@ asmsub MEMTOP2() -> ubyte @A {
cx16 { cx16 {
; 65c02 hardware vectors: ; irq and hardware vectors:
&uword NMI_VEC = $FFFA ; 6502 nmi vector, determined by the kernal if banked in &uword CINV = $0314 ; IRQ vector (in ram)
&uword RESET_VEC = $FFFC ; 6502 reset vector, determined by the kernal if banked in &uword NMI_VEC = $FFFA ; 65c02 nmi vector, determined by the kernal if banked in
&uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in &uword RESET_VEC = $FFFC ; 65c02 reset vector, determined by the kernal if banked in
&uword IRQ_VEC = $FFFE ; 65c02 interrupt vector, determined by the kernal if banked in
; the sixteen virtual 16-bit registers ; the sixteen virtual 16-bit registers
@ -453,7 +454,7 @@ _loop ldy #0
} }
; ---- system stuff ----- ; ---- system stuff -----
asmsub init_system() { asmsub init_system() {
; Initializes the machine to a sane starting state. ; Initializes the machine to a sane starting state.
; Called automatically by the loader program logic. ; Called automatically by the loader program logic.
%asm {{ %asm {{
@ -485,8 +486,166 @@ asmsub init_system() {
}} }}
} }
asmsub init_system_phase2() {
%asm {{
sei
lda cx16.CINV
sta restore_irq._orig_irqvec
lda cx16.CINV+1
sta restore_irq._orig_irqvec+1
cli
rts
}}
} }
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 cx16.CINV
lda #>_irq_handler
sta cx16.CINV+1
lda cx16.VERA_IEN
ora #%00000001 ; enable the vsync irq
sta cx16.VERA_IEN
cli
rts
_irq_handler jsr _irq_handler_init
_modified jsr $ffff ; modified
jsr _irq_handler_end
lda _use_kernal
bne +
; end irq processing - don't use kernal's irq handling
lda cx16.VERA_ISR
ora #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
_irq_handler_init
; save all zp scratch registers and the X register as these might be clobbered by the irq routine
stx IRQ_X_REG
lda P8ZP_SCRATCH_B1
sta IRQ_SCRATCH_ZPB1
lda P8ZP_SCRATCH_REG
sta IRQ_SCRATCH_ZPREG
lda P8ZP_SCRATCH_W1
sta IRQ_SCRATCH_ZPWORD1
lda P8ZP_SCRATCH_W1+1
sta IRQ_SCRATCH_ZPWORD1+1
lda P8ZP_SCRATCH_W2
sta IRQ_SCRATCH_ZPWORD2
lda P8ZP_SCRATCH_W2+1
sta IRQ_SCRATCH_ZPWORD2+1
; stack protector; make sure we don't clobber the top of the evaluation stack
dex
dex
dex
dex
dex
dex
cld
rts
_irq_handler_end
; restore all zp scratch registers and the X register
lda IRQ_SCRATCH_ZPB1
sta P8ZP_SCRATCH_B1
lda IRQ_SCRATCH_ZPREG
sta P8ZP_SCRATCH_REG
lda IRQ_SCRATCH_ZPWORD1
sta P8ZP_SCRATCH_W1
lda IRQ_SCRATCH_ZPWORD1+1
sta P8ZP_SCRATCH_W1+1
lda IRQ_SCRATCH_ZPWORD2
sta P8ZP_SCRATCH_W2
lda IRQ_SCRATCH_ZPWORD2+1
sta P8ZP_SCRATCH_W2+1
ldx IRQ_X_REG
rts
IRQ_X_REG .byte 0
IRQ_SCRATCH_ZPB1 .byte 0
IRQ_SCRATCH_ZPREG .byte 0
IRQ_SCRATCH_ZPWORD1 .word 0
IRQ_SCRATCH_ZPWORD2 .word 0
}}
}
asmsub restore_irq() clobbers(A) {
%asm {{
sei
lda _orig_irqvec
sta cx16.CINV
lda _orig_irqvec+1
sta cx16.CINV+1
lda cx16.VERA_IEN
and #%11110000 ; disable all Vera IRQs
ora #%00000001 ; enable only the vsync Irq
sta cx16.VERA_IEN
cli
rts
_orig_irqvec .word 0
}}
}
asmsub set_rasterirq(uword handler @AY, uword rasterpos @R0) clobbers(A) {
%asm {{
sta _modified+1
sty _modified+2
lda cx16.r0
ldy cx16.r0+1
sei
lda cx16.VERA_IEN
and #%11110000 ; clear other IRQs
ora #%00000010 ; enable the line (raster) irq
sta cx16.VERA_IEN
lda cx16.r0
sta cx16.VERA_IRQ_LINE_L
lda cx16.r0+1
lsr a
ror a
and #%10000000
ora cx16.VERA_IEN
sta cx16.VERA_IEN ; high bit of the raster line
lda #<_raster_irq_handler
sta cx16.CINV
lda #>_raster_irq_handler
sta cx16.CINV+1
cli
rts
_raster_irq_handler
jsr set_irq._irq_handler_init
_modified jsr $ffff ; modified
jsr set_irq._irq_handler_end
; end irq processing - don't use kernal's irq handling
lda cx16.VERA_ISR
ora #%00000010
sta cx16.VERA_ISR ; clear Vera line irq status
ply
plx
pla
rti
}}
}
}
sys { sys {
; ------- lowlevel system routines -------- ; ------- lowlevel system routines --------

View File

@ -133,12 +133,14 @@ internal class AsmGen(private val program: Program,
out("_prog8_entrypoint\t; assembly code starts here\n") out("_prog8_entrypoint\t; assembly code starts here\n")
if(!options.noSysInit) if(!options.noSysInit)
out(" jsr ${compTarget.name}.init_system") out(" jsr ${compTarget.name}.init_system")
out(" jsr ${compTarget.name}.init_system_phase2")
} }
options.output == OutputType.PRG -> { options.output == OutputType.PRG -> {
out("; ---- program without basic sys call ----") out("; ---- program without basic sys call ----")
out("* = ${program.actualLoadAddress.toHex()}\n") out("* = ${program.actualLoadAddress.toHex()}\n")
if(!options.noSysInit) if(!options.noSysInit)
out(" jsr ${compTarget.name}.init_system") out(" jsr ${compTarget.name}.init_system")
out(" jsr ${compTarget.name}.init_system_phase2")
} }
options.output == OutputType.RAW -> { options.output == OutputType.RAW -> {
out("; ---- raw assembler program ----") out("; ---- raw assembler program ----")

View File

@ -148,3 +148,8 @@ For the C64 these routines are::
c64.set_rasterirq(uword handler_address, uword rasterline, boolean useKernal) c64.set_rasterirq(uword handler_address, uword rasterline, boolean useKernal)
c64.restore_irq() ; set everything back to the systems default irq handler c64.restore_irq() ; set everything back to the systems default irq handler
And for the Commander X16:
cx16.set_irq(uword handler_address, boolean useKernal) ; vsync irq
cx16.set_rasterirq(uword handler_address, uword rasterline) ; note: disables kernal irq handler! sys.wait() won't work anymore
cx16.restore_irq() ; set everything back to the systems default irq handler

View File

@ -7,17 +7,10 @@ main {
; $1F9C0 - $1F9FF PSG registers ; $1F9C0 - $1F9FF PSG registers
sub start() { sub start() {
uword color=0 cx16.set_rasterirq(&irq.irq, 100)
repeat { ;cx16.set_irq(&irq.irq, true)
cx16.vpoke(1, $fa00+6*2, lsb(color))
cx16.vpoke(1, $fa01+6*2, msb(color))
color++
}
;c64.set_rasterirq(&irq.irq, 100, true)
sys.wait(100) sys.wait(100)
cx16.restore_irq()
;c64.restore_irq()
; uword freq = 1181 ; uword freq = 1181
; cx16.vpoke(1, $f9c0, lsb(freq)) ; cx16.vpoke(1, $f9c0, lsb(freq))
@ -29,10 +22,26 @@ main {
irq { irq {
%option force_output
uword counter = 0 uword counter = 0
sub irq() { sub irq() {
cx16.vpoke(1, $fa00+6*2, lsb(counter))
cx16.vpoke(1, $fa01+6*2, msb(counter))
repeat 20 {
uword xx
repeat 16 {
xx++
}
cx16.vpoke(1, $fa00+6*2, 0)
cx16.vpoke(1, $fa01+6*2, 255)
repeat 16 {
xx++
}
cx16.vpoke(1, $fa00+6*2, 0)
cx16.vpoke(1, $fa01+6*2, 0)
}
counter++ counter++
} }
} }