[net.micro.cbm] OK - so I'll post the Raster interrupt code ...

goodenough@vogon.DEC (Jeff Goodenough, IPG Reading DEC-UK) (03/06/86)

Well, this isn't really any longer than some of the postings to this
newsgroup, so specially for "dave3" and Marco, and any others who might want
it, here is my sample code for handling Raster Interrupts.  In any case,
my brain starts to hurt after about the eighth node in a routing.  Perhaps
we can persuade you all to convert to VMS and DECnet :-) :-)

NOTE: If some of the code looks a bit non-standard (e.g. BYT) it's because
      I wrote my own assembler, and made some tweaks to the "standard" to
      make things a bit easier.

Jeff.
		=*=		=*=		=*=

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 is
somewhat peculiar, and only *it* 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.