goodenough@vogon.DEC (Jeff Goodenough, IPG Reading DEC-UK) (03/10/86)
I'm told my original posting was incomplete, so here is another attempt. I've marked the end, so you can check. I don't understand why it was incomplete, as the copy I got back was OK. =*= Sample code for raster interrupts This example assumes that the screen is split in half, the top half in hires bitmap mode, and the bottom half in normal character mode. The screen memory is 1Kb from $0400-$07FF (default), the character memory 2Kb from $1000-17FF (Character ROM image - default), and the bitmap (potentially) 8Kb from $2000-$3FFF. Since only the first half of the bitmap is actually displayed, the second half ($3000-$3FFF) could be used to store other information (code or data). Note that the VIC chip only *thinks* it sees the character ROM at $1000-$17FF. The ROM isn't actually there, so there's nothing to stop you storing other code/data in these locations. Equates VIC =$D000 ; start of VIC chip BITMAP =$2000 ; start of bitmap SCVAL =147 ; split at scan line 147 (top of row 13) CHROUT =$FFD2 ; kernel routine: output character IRQ =$EA31 ; kernel interrupt routine Data RASVAL BYT 0 ; byte to store current raster value Initialization code (put this somewhere at the beginning of your program): SEI ; inhibit interrupts LDA #<INT ; set up interrupt vector STA $0314 LDA #>INT STA $0315 CLI ; re-enable interrupts Subroutine to turn split screen/bitmap on: BMON LDA #11 ; example - sets screen/border to Grey 1 STA VIC+$20 ; (if you want to) STA VIC+$21 SEI ; inhibit interrupts LDA #0 STA RASVAL ; set raster value to top of screen (0) STA VIC+$12 ; store in VIC raster compare register LDA VIC+$11 ; clear bit 8 of raster value (always 0) AND #$7F STA VIC+$11 LDA VIC+$1A ; VIC IRQ mask register ORA #1 ; enable raster interrupt BMON1 STA VIC+$1A CLI ; enable interrupts LDA #147 JMP CHROUT ; clear screen and return Subroutine to turn split screen/bitmap off: BMOFF LDA #14 ; example - resets screen/border to Lt Blue STA VIC+$20 ; (if you want to) STA VIC+$21 SEI ; inhibit interrupts LDA #$1B ; turn off bitmap mode STA VIC+$11 LDA #$08 ; turn off multicolor mode STA VIC+$16 ; (if you turned it on) LDA #$14 ; map VIC back to character memory STA VIC+$18 LDA VIC+$1A ; VIC IRQ mask register AND #$FE ; disable raster interrupt JMP BMON1 Interrupt routine: INT LDA #1 BIT VIC+$1A ; are raster interrupts enabled? BEQ MINT ; br if not, to main interrupt service BIT VIC+$19 ; had an interrupt, but is it a raster int? BEQ MINT ; br if not STA VIC+$19 ; clear the latched raster interrupt bit LDA RASVAL ; get the last-stored scan value BNE RINT1 ; br if not at top of screen LDA #$3B ; enable bitmap mode STA VIC+$11 LDA #$18 ; map VIC to bitmap (also right value for ; setting multicolor mode in VIC+$16) STA VIC+$18 LDX #SCVAL ; get the required scan line value BNE RINT2 ; (branch assumes SCVAL non-zero!) ; RINT1 LDX #0 ; at split - get top of screen value [LDA #$08 ; clear multicolor mode if you set it] RINT2 STX RASVAL ; save the new scan value STX VIC+$12 ; store in raster compare register [STA VIC+$16 ; set or clear multicolor bit] ; ; Following code mimics kernel interrupt exit ; LDA $DC0D PLA TAY PLA TAX PLA RTI ; MINT <any other interrupt handling you need to do> JMP IRQ ; jump to kernel interrupt handling Jeff. [End of Raster interrupt code example]