

         *= $2000    ;Assemble to $2000

         cld         ;Clear Decimal Mode
         sei         ;Disable IRQ's
         lda #$1f    ;Disable CIA IRQ's
         sta $dc0d
         sta $dd0d

         lda #<nmi   ;Install NMI into
         ldx #>nmi   ;Hardware NMI and
         sta $fffa   ;RESET Vectors
         sta $fffc
         stx $fffb
         stx $fffd

         lda #<irq1  ;Install RASTER IRQ
         ldx #>irq1  ;into Hardware
         sta $fffe   ;Interrupt Vector
         stx $ffff

         lda #$35    ;Set MMU to RAM at
         ldx #$ff    ;$a000-$bfff and
         sta $01     ;$e000-$ffff
         txs         ;Clear the STACK

         lda #$01    ;Enable RASTER IRQ
         ldx #$1b    ;High bit of RASTER
         ldy #$34    ;compare register
         sta $d01a   ;and RASTER IRQ to
         stx $d011   ;line $34
         sty $d012
                     ;NOTE double IRQ
                     ;cannot be on or
                     ;around a BAD LINE!
                     ;(Fast Line)

         lda #$0e    ;Set Background
         ldx #$06    ;and Border colors
         ldy #$00    ;to default and
         sta $d020   ;turn off sprites
         stx $d021
         sty $d015

         jsr clrscreen
         jsr clrcolor
         jsr printtext

         asl $d019   ;Ack any previous
         lda $dc0d   ;IRQ's
         lda $dd0d

         cli         ;Renable IRQ's

         jmp *       ;Endless Loop


irq1
         sta reseta1 ;Preserve A,X and Y
         stx resetx1 ;Registers
         sty resety1 ;VIA self modifying
                     ;code
                     ;(Faster than the
                     ;STACK is!)

         lda #<irq2  ;Set IRQ Vector
         ldx #>irq2  ;to point to the
         ldy #$35    ;next part of the
         sta $fffe   ;Stable IRQ
         stx $ffff   ;ON NEXT LINE!
         sty $d012
         asl $d019   ;Ack RASTER IRQ
         tsx         ;We want the IRQ
         cli         ;To return to our
         nop         ;endless loop
         nop         ;NOT THE END OF
         nop         ;THIS IRQ!
         nop
         nop         ;Execute nop's
         nop         ;until next RASTER
         nop         ;IRQ Triggers
         nop
         nop         ;2 cycles per
         nop         ;instruction so
         nop         ;we will be within
         nop         ;1 cycle of RASTER
         nop         ;Register change

         nop  ;<--- remove 1 NOP for PAL
irq2
         txs         ;Restore STACK
                     ;Pointer
         ldx #$08    ;Wait exactly 1
         dex         ;lines worth of
         bne *-1     ;cycles for compare
         bit $ea     ;Minus compare
         nop         ;cycles

         nop  ;<--- remove 1 NOP for PAL

         lda #$35    ;RASTER change yet?
         cmp $d012
         beq start   ;If no waste 1 more
                     ;cycle
start
         nop         ;Some delay
         nop         ;So stable can be
         nop         ;seen

         lda #$0e    ;Colors
         ldx #$06

         sta $d021   ;Here is the proof
         stx $d021

         lda #<irq3  ;Set IRQ to point
         ldx #>irq3  ;to subsequent IRQ
         ldy #$68    ;at line $68
         sta $fffe
         stx $ffff
         sty $d012
         asl $d019   ;Ack RASTER IRQ

         lda #$00    ;Reload A,X,and Y
reseta1  = *-1       ;registers
         ldx #$00
resetx1  = *-1
         ldy #$00
resety1  = *-1

         rti         ;Return from IRQ

irq3
         sta reseta2 ;Preserve A,X,and Y
         stx resetx2 ;Registers
         sty resety2

         ldx #$0a    ;Waste some more
         dex         ;time so effect
         bne *-1     ;can be seen
         nop

         lda #$0e    ;More colors
         ldx #$06

         sta $d021   ;Cool! subsequent
         stx $d021   ;IRQ's are also
                     ;stable :-)
                     ;Unless you are
                     ;running realtime
                     ;code :-)

         ldy #$13    ;Waste time so this
         dey         ;IRQ does not try
         bne *-1     ;to reoccur on the
                     ;same line!

         lda #<irq1  ;Reset Vectors to
         ldx #>irq1  ;first IRQ again
         ldy #$34    ;at line $34
         sta $fffe
         stx $ffff
         sty $d012
         asl $d019   ;Ack RASTER IRQ

         lda #$00    ;Reload A,X,and Y
reseta2  = *-1       ;registers
         ldx #$00
resetx2  = *-1
         ldy #$00
resety2  = *-1

         rti         ;Return from IRQ

                     ;Pound RESTORE to
                     ;get back to Turbo
nmi
         asl $d019   ;Ack all IRQ's
         lda $dc0d
         lda $dd0d
         lda #$81    ;reset CIA 1 IRQ
         ldx #$00    ;remove raster IRQ
         ldy #$37    ;reset MMU to roms
         sta $dc0d
         stx $d01a
         sty $01
         ldx #$ff    ;clear the stack
         txs
         cli         ;reenable IRQ's
         jmp $9000   ;back to Turbo

clrscreen
         lda #$20    ;Clear the screen
         ldx #$00
clrscr   sta $0400,x
         sta $0500,x
         sta $0600,x
         sta $0700,x
         dex
         bne clrscr
         rts
clrcolor
         lda #$03    ;Clear color memory
         ldx #$00
clrcol   sta $d800,x
         sta $d900,x
         sta $da00,x
         sta $db00,x
         dex
         bne clrcol
         rts

printtext
         lda #$16    ;C-set = lower case
         sta $d018

         ldx #$00
moretext lda text1,x

         bpl lower   ;upper case ?
         eor #$80    ;yes

         bne lower+2

lower    and #$3f    ;lower case
         sta $0450,x
         inx
         cpx #$78
         bne moretext
exit     rts

text1
         .text "Stable Raster IRQ sourc"
         .text "e (PAL/NTSC)     "
         .text "All Code by Fungus 1996"
         .text "                 "
         .text "Feel free to use and mo"
         .text "dify this code :)"
