Skip to content

Instantly share code, notes, and snippets.

@cbmeeks
Last active December 29, 2015 05:39
Show Gist options
  • Save cbmeeks/7623884 to your computer and use it in GitHub Desktop.
Save cbmeeks/7623884 to your computer and use it in GitHub Desktop.
Commodore 64 screen shift
copy_screen_left:
:BeginIRQ()
ldx #0
lda SCR_X_POS
beq !loop0+
cmp #1
beq !loop1+
cmp #2
beq !loop2+
cmp #3
beq !loop3+
jmp !exit+
!loop0:
lda SCR_BUFFER + 1, x
sta DBL_BUFFER, x
inx
bne !loop0-
lda #1
sta SCR_X_POS
jmp !exit+
!loop1:
lda SCR_BUFFER + 256 + 1, x
sta DBL_BUFFER + 256, x
inx
bne !loop1-
lda #2
sta SCR_X_POS
jmp !exit+
!loop2:
lda SCR_BUFFER + 512 + 1, x
sta DBL_BUFFER + 512, x
inx
bne !loop2-
lda #3
sta SCR_X_POS
jmp !exit+
!loop3: // Only need 32 chars on this last row
lda SCR_BUFFER + 768 + 1, x
sta DBL_BUFFER + 768, x
inx
cpx #31
bne !loop3-
lda #0
sta SCR_X_POS
!exit:
:MoveIRQ(100, copy_screen_left)
:ReturnFromIRQ()
.importonce
// Setup IRQ on [line] and point to [address]
.macro SetupIRQ(line, address) {
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 #line // 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 8th 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 #<address // setup interrupt handlers
sta $fffe
lda #>address
sta $ffff
cli // enable maskable interrupts again
}
.macro BeginIRQ() {
pha // store register A in stack
txa
pha // store register X in stack
tya
pha // store register Y in stack
}
.macro ReturnFromIRQ() {
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
inc $d019 // clear interrupt condition (required) ....this will crash a Commodore 65 lol
rti
}
.macro MoveIRQ(line, address) {
lda #line
sta $d012
lda #<address
sta $fffe
lda #>address
sta $ffff
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment