Initial commit: C64 project skeleton with oscar64 submodule
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
# Raster Interrupts
|
||||
|
||||
Source: https://www.c64-wiki.com/wiki/Raster_interrupt
|
||||
|
||||
A raster interrupt is an interrupt trigger signal that the VIC-II can supply, if desired, to the CPU whenever the raster in the VIC's video signal reaches a specific line. With machine code programming, this mechanism can be exploited to perform many kinds of VIC "trickery" — having both text and high-res graphics on screen simultaneously, displaying more than eight hardware-supported sprites at once. This is heavily used on the C64/C128 for computer games and demos.
|
||||
|
||||
The Atari 800, MSX, and Amstrad CPC also support raster interrupts. The 80-column mode on the C128/VDC cannot.
|
||||
|
||||
## Setting up a raster interrupt
|
||||
|
||||
By default, the system is set up to receive timer-based signals from CIA-1's Timer A. To use the VIC raster interrupt:
|
||||
|
||||
```asm
|
||||
Init SEI ; disable IRQ
|
||||
LDA #%01111111
|
||||
STA $DC0D ; switch off interrupt signals from CIA-1
|
||||
|
||||
AND $D011 ; clear MSB of VIC raster
|
||||
STA $D011
|
||||
|
||||
STA $DC0D ; acknowledge pending CIA-1 IRQs
|
||||
STA $DD0D ; acknowledge pending CIA-2 NMIs
|
||||
|
||||
LDA #210 ; set raster line where interrupt shall occur
|
||||
STA $D012
|
||||
|
||||
LDA #<Irq
|
||||
STA $0314 ; set IRQ vector
|
||||
LDA #>Irq
|
||||
STA $0315
|
||||
|
||||
LDA #%00000001
|
||||
STA $D01A ; enable raster interrupt
|
||||
|
||||
CLI ; re-enable IRQ
|
||||
RTS
|
||||
```
|
||||
|
||||
Note: enabling raster interrupts from the VIC takes place *after* setting up everything else. The routine starts with `SEI` because if the interrupt is enabled before e.g. the vector is re-directed, an interrupt may occur while the vector is being altered, sending the CPU to a "random" address and crashing the system.
|
||||
|
||||
## Single ISR example (wiggle border)
|
||||
|
||||
```asm
|
||||
Irq LDA #$07
|
||||
STA $D020 ; border = yellow
|
||||
|
||||
LDX #$90 ; delay ~half a millisecond
|
||||
Pause: DEX
|
||||
BNE Pause
|
||||
|
||||
LDA #$00
|
||||
STA $D020 ; border = black
|
||||
|
||||
ASL $D019 ; acknowledge raster IRQ
|
||||
JMP $EA31 ; into KERNAL standard ISR (handles cursor blink, etc.)
|
||||
```
|
||||
|
||||
The yellow stripe across the border is exactly 8 raster lines wide, set by the pause loop length.
|
||||
|
||||
## Multiple raster ISRs (split-screen: hires top, text bottom)
|
||||
|
||||
The "concatenated" pattern — two routines handling two different raster lines, each setting up the next:
|
||||
|
||||
```asm
|
||||
Irq LDA $D011
|
||||
AND #%11011111
|
||||
STA $D011 ; switch to text mode
|
||||
|
||||
LDA #<Irq2
|
||||
STA $0314
|
||||
LDA #>Irq2
|
||||
STA $0315
|
||||
|
||||
LDA #$0
|
||||
STA $D012 ; next IRQ at line 0
|
||||
|
||||
ASL $D019 ; acknowledge
|
||||
JMP $EA31 ; into KERNAL ISR
|
||||
|
||||
Irq2 LDA $D011
|
||||
ORA #%00100000
|
||||
STA $D011 ; switch to bitmap mode
|
||||
|
||||
LDA #<Irq
|
||||
STA $0314
|
||||
LDA #>Irq
|
||||
STA $0315
|
||||
|
||||
LDA #210
|
||||
STA $D012 ; next IRQ at line 210
|
||||
|
||||
ASL $D019
|
||||
JMP $EA81 ; shorter ROM routine — just restore regs and RTI
|
||||
```
|
||||
|
||||
Only one of the chained routines needs to jump to the full KERNAL ISR; the others can exit through $EA81 (the register-restore stub) for speed.
|
||||
Reference in New Issue
Block a user