Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- * = $0801
- .word (+), 2005 ;pointer, line number
- .null $9e, format("%d", start);will be sys 4096
- + .word 0 ;basic line end
- * = $1000
- ; CONSTANTS
- SCREEN_SCROLL = $D016
- WRITE_PTR = $BB
- READ_PTR = $FB
- SCREEN_PAGE_PTR = $0288
- BORDERCOLOR = $D020
- BGCOLOR = $D021
- CHRCOLOR = $0286
- SPACE = #$20
- SCREENSTART = $0400
- SCREENEND = $07FF
- CIA_TIMER_ORA = $DC0E
- IO_MEM_TAPE_CTRL = $01
- CHAR_ROM = $D000
- CHROUT = $FFD2
- ; GLOBAL VARIABLES
- colIndex .byte 0
- fillDone .byte 0
- xLimit .byte ?
- screenIndex .byte ?
- byteToRead .byte ?
- frontLimit .byte ?
- inter .word ?
- fillBuffer
- ldx #0
- stx byteToRead
- nextRow lda colIndex
- cmp #0
- bne skip0
- sta screenIndex
- lda #40
- sta frontLimit
- jmp fillFront
- skip0
- sec
- lda #40
- sbc colIndex
- sta frontLimit
- sta screenIndex
- fillBack
- ldy byteToRead
- lda (READ_PTR),y ;y starts always at 0
- ldy screenIndex ;y start always at 40 - colIndex
- sta (WRITE_PTR),y
- inc byteToRead
- inc screenIndex
- ldy screenIndex
- cpy #40
- bne fillBack
- lda colIndex
- sta byteToRead
- lda #0
- sta screenIndex
- fillFront
- ldy byteToRead
- lda (READ_PTR),y
- ldy screenIndex
- sta (WRITE_PTR),y
- inc byteToRead
- inc screenIndex
- ldy screenIndex
- cpy frontLimit
- bcc fillFront
- ;update pointers (change row)
- clc
- lda WRITE_PTR
- adc #40
- sta WRITE_PTR
- lda WRITE_PTR+1
- adc #00
- sta WRITE_PTR+1
- clc
- lda READ_PTR
- adc #40
- sta READ_PTR
- lda READ_PTR+1
- adc #00
- sta READ_PTR+1
- ;check rownumber and reset offsets
- lda #0
- sta byteToRead
- inx
- cpx #25
- bcc nextRow
- rts
- notDefault
- ora #128
- sta $D018
- lda #04
- sta SCREEN_PAGE_PTR
- jsr initPointers
- rts
- setScreenColors
- ; set color
- lda #$0b
- sta $0286
- ; set border color
- lda #$00
- sta $D020
- ; set background color
- lda #$0c
- sta $D021
- rts
- initPointers
- lda #00
- sta WRITE_PTR
- lda SCREEN_PAGE_PTR
- sta WRITE_PTR+1
- lda #<screen
- sta READ_PTR
- lda #>screen
- sta READ_PTR+1
- rts
- swapBuffers
- lda $D018
- tax
- and #240
- cmp #16
- bne noDefault
- txa
- and #15 ; x%0000 1111
- ora #128
- sta $D018
- lda #$04
- sta SCREEN_PAGE_PTR
- rts
- noDefault
- txa
- and #15 ; x%0000 1111
- ora #16
- sta $D018
- lda #$20
- sta SCREEN_PAGE_PTR
- rts
- * = $1600
- start
- lda #7
- sta SCREEN_SCROLL
- ; clear the screen
- jsr setScreenColors
- jsr $e544
- jsr initPointers
- jsr fillBuffer
- lda #$20
- sta SCREEN_PAGE_PTR
- jsr initPointers
- inc colIndex
- ; jmp endlessloop
- sei ;disable maskable IRQs
- lda #$7f
- sta $dc0d ;disable timer interrupts which can be generated by the two CIA chips
- sta $dd0d ;the kernal uses such an interrupt to flash the cursor and scan the keyboard, so we better
- ;stop it.
- lda $dc0d ;by reading this two registers we negate any pending CIA irqs.
- lda $dd0d ;if we don't do this, a pending CIA irq might occur after we finish setting up our irq.
- ;we don't want that to happen.
- lda #$01 ;this is how to tell the VICII to generate a raster interrupt
- sta $d01a
- lda #251 ;this is how to tell at which rasterline we want the irq to be triggered
- sta $d012
- lda #$1b ;as there are more than 256 rasterlines, the topmost bit of $d011 serves as
- sta $d011 ;the 9th bit for the rasterline we want our irq to be triggered.
- ;here we simply set up a character screen, leaving the topmost bit 0.
- lda #$35 ;we turn off the BASIC and KERNAL rom here
- sta $01 ;the cpu now sees RAM everywhere except at $d000-$e000, where still the registers of
- ;SID/VICII/etc are visible
- lda #<irq ;this is how we set up
- sta $fffe ;the address of our interrupt code
- lda #>irq
- sta $ffff
- cli ;enable maskable interrupts again
- ; lda $314
- ; sta inter
- ; lda $315
- ; sta inter+1
- ; sei
- ; lda #<IRQ_loop
- ; sta $314
- ; lda #>IRQ_loop
- ; sta $315
- ; cli
- endlessloop
- ; lda #250
- ; cmp $d012
- ; bcc skip9
- ; jsr IRQ_loop
- ;skip9
- lda fillDone
- cmp #1
- beq endlessloop
- jsr fillBuffer
- inc fillDone
- jmp endlessloop
- IRQ_loop
- dec SCREEN_SCROLL
- lda SCREEN_SCROLL
- cmp #$FF
- bne out
- resetScroll
- lda #07
- sta SCREEN_SCROLL
- jsr swapbuffers
- jsr initPointers
- lda #0
- sta fillDone
- inc colIndex
- lda colIndex
- cmp #40
- bne out
- lda #0
- sta colIndex
- out
- rts
- jmp (inter)
- screen
- .byte 160,160,160,160,160,160,160,160,160,160,160,160,160,160,232,230,230,230,230,230,230,230,230,232,160,160,160,160,160,232,230,230,230,230,230,230,232,160,160,160
- .byte 230,230,230,230,232,232,160,160,160,232,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,232,160,232,230,230,230,230,230,230,230,230,230,230,230,230
- .byte 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,104, 46, 46, 46, 46, 46,104,104,230,230,230,230,230,230,230,104, 46, 46, 46, 46,104,230,230,230,230
- .byte 104,104,104,104,104,104,104,104,104,104,104,104,104, 46, 46, 46, 46, 46, 46, 46, 46, 46,104,104,104,104,104,104, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,104,104
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,100,100,100,100,100,100,100,100,100,100,100, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 100,100,100,100,100,100,100, 32, 32, 32, 32, 32,100,100,100,100,100, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45,100,100,100,100,100,100,100,100,100,100
- .byte 32, 32, 32, 32, 32, 32, 32, 45,100,100,100, 45, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32,104,104,104,104,104,104,104,104, 32, 32, 32, 32, 32,104, 32, 32,104, 32, 32, 32, 32, 32,104, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 102,102,102,102,102,102,102,102,102,102,102,102,104,104, 32,102,102,102,102, 32,102,104, 32, 32,102,102,102,102, 32,102, 32,102, 32,102,104, 32,104,102,102,102
- .byte 102,102,104, 32, 32, 32, 32, 32,104,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,104, 32,102,102,102,102,102,102,102,102,102,102,102
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,104, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,104,102,102,102,102,102,102,102,102,102,104, 32,104,102,102,102,104, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,230,230,230,230,230,230,230,230,230,230,230, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 32, 32, 32, 32, 32, 32, 32, 32, 32,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230, 32, 32, 32, 32, 32, 32, 32, 32, 32
- .byte 230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230,230
- .byte 230,230,230,230,232,160,232,230,230,230,230,232,160,160,160,160,160,160,160,232,230,230,232,160,160,160,160,160,160,232,230,230,232,160,160,232,230,230,230,230
- .byte 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160
- .byte 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,160
- irq
- ;Being all kernal irq handlers switched off we have to do more work by ourselves.
- ;When an interrupt happens the CPU will stop what its doing, store the status and return address
- ;into the stack, and then jump to the interrupt routine. It will not store other registers, and if
- ;we destroy the value of A/X/Y in the interrupt routine, then when returning from the interrupt to
- ;what the CPU was doing will lead to unpredictable results (most probably a crash). So we better
- ;store those registers, and restore their original value before reentering the code the CPU was
- ;interrupted running.
- ;If you won't change the value of a register you are safe to not to store / restore its value.
- ;However, it's easy to screw up code like that with later modifying it to use another register too
- ;and forgetting about storing its state.
- ;The method shown here to store the registers is the most orthodox and most failsafe.
- pha ;store register A in stack
- txa
- pha ;store register X in stack
- tya
- pha ;store register Y in stack
- jsr IRQ_loop
- lda #$ff ;this is the orthodox and safe way of clearing the interrupt condition of the VICII.
- sta $d019 ;if you don't do this the interrupt condition will be present all the time and you end
- ;up having the CPU running the interrupt code all the time, as when it exists the
- ;interrupt, the interrupt request from the VICII will be there again regardless of the
- ;rasterline counter.
- ;it's pretty safe to use inc $d019 (or any other rmw instruction) for brevity, they
- ;will only fail on hardware like c65 or supercpu. c64dtv is ok with this though.
- pla
- tay ;restore register Y from stack (remember stack is FIFO: First In First Out)
- pla
- tax ;restore register X from stack
- pla ;restore register A from stack
- rti ;Return From Interrupt, this will load into the Program Counter register the address
- ;where the CPU was when the interrupt condition arised which will make the CPU continue
- ;the code it was interrupted at also restores the status register of the CPU
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement