Created
November 13, 2023 03:07
-
-
Save cesarmiquel/b4977b6f1badb01eed60c8cbdae7c007 to your computer and use it in GitHub Desktop.
C64 left scroller
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//============================================================ | |
// resources | |
//============================================================ | |
.const logo_width = 10 + 93 + 10 | |
.const logo_height = 14 | |
.const state_1 = 1 | |
.const state_2 = 2 | |
.const state_3 = 3 | |
.const screen_bg_color = BLACK | |
.const paused = $1a | |
.const next_scrollx = $1b | |
.const scroll_state = $1c | |
.const scroll_offset = $1d // fine grain scroll | |
.const offset = $1e | |
.const scroll_dir = $1f | |
//============================================================ | |
// resources: PETSCII and SID data | |
//============================================================ | |
// https://csdb.dk/sid/?id=26164 | |
// Dull - Jeroen Soede - Released: 1989 SoedeSoft | |
// Relocated to $1000 with sidreloc | |
.var music = LoadSid("dull-reloc.sid") | |
.var intro_data = LoadBinary( "rc/logo.char" ) | |
.var intro_data_color = LoadBinary( "rc/logo.color" ) | |
//============================================================ | |
// symbols | |
//============================================================ | |
.const screen_ram = $0400 // location of screen ram | |
.const color_ram = $d800 // location of screen ram | |
.pc = $0801 "Basic Upstart" | |
:BasicUpstart(start) // 10 sys$0810 | |
.pc =$0810 "Program" | |
start: | |
//============================================================ | |
// Initialize involved VIC-II registers | |
//============================================================ | |
main: | |
sei // set interrupt disable flag | |
jsr clear_screen | |
// Init music | |
lda #music.startSong-1 | |
jsr music.init | |
lda #$01 // Set Interrupt Request Mask... | |
sta $d01a // ...we want IRQ by Rasterbeam (%00000001) | |
// triger irq on line 200 | |
lda #210 | |
sta $d012 | |
lda $d011 | |
and #%01111111 | |
sta $d011 | |
lda #<irq // point IRQ Vector to our custom irq routine | |
ldx #>irq | |
sta $0314 // store in $314/$315 | |
stx $0315 | |
lda #$00 // trigger interrupt at row zero | |
sta $d012 | |
sta scroll_state | |
// offset of logo | |
lda #0 | |
sta offset | |
sta paused | |
lda #7 | |
sta scroll_offset | |
// scroll direction 1: left, -1: right | |
lda #1 | |
sta scroll_dir | |
cli // clear interrupt disable flag | |
jmp * // infinite loop | |
//============================================================ | |
// Main loop called on each interrupt | |
//============================================================ | |
irq: | |
dec $d019 // acknowledge IRQ / clear register for next interrupt | |
lda #210 // wait for line 210 | |
cmp $d012 | |
bne *-3 | |
// Play SID | |
jsr music.play | |
// read keyboard and check for [space] | |
lda #$7F // %01111111 | |
sta $dc00 | |
lda $dc01 | |
and #$10 // mask %00010000 | |
bne !+ | |
lda paused | |
eor #1 | |
sta paused | |
!: | |
lda paused | |
bne finish_irq | |
// Smooth scroll always | |
jsr smooth_scroll | |
lda scroll_state | |
cmp #state_1 | |
bne !+ | |
jsr state_1_callback | |
jmp finish_irq | |
!: | |
cmp #state_2 | |
bne !+ | |
jsr state_2_callback | |
jmp finish_irq | |
!: | |
cmp #state_3 | |
bne finish_irq | |
jsr state_3_callback | |
finish_irq: | |
lda $d011 // Reset bit 3 for the next frame | |
ora #$08 | |
sta $d011 | |
jmp $ea31 // return to Kernel routine | |
// smoooth scroll ------------------------------- | |
smooth_scroll: | |
sec | |
lda scroll_offset | |
sbc #3 | |
sta scroll_offset | |
cmp #0 | |
bmi !+ | |
jmp finish_scroll | |
// Reset scroll x de 0 -> 7 | |
!: | |
lda #7 | |
sta scroll_offset | |
lda $d016 | |
// reset bit | |
and #%11110000 | |
ora #%00000111 | |
sta next_scrollx | |
lda #state_1 | |
sta scroll_state | |
rts | |
finish_scroll: | |
lda $d016 | |
and #%11110000 | |
ora scroll_offset | |
sta $d016 | |
rts | |
// state 1 ------------------------------- | |
state_1_callback: | |
clc | |
inc offset | |
lda offset | |
cmp #logo_width | |
bmi draw | |
lda #0 | |
sta offset | |
draw: | |
jsr scroll_screen_left | |
lda next_scrollx | |
sta $d016 | |
lda #state_2 | |
sta scroll_state | |
rts | |
// state 2 ------------------------------- | |
state_2_callback: | |
lda #<petscii_data | |
clc | |
adc offset | |
sta $20 | |
lda #>petscii_data | |
bcc !+ | |
adc #1 | |
!: | |
sta $21 | |
lda #$c8+39 // fila 5 | |
sta $22 | |
lda #$04 | |
sta $23 | |
jsr write_last_col | |
lda #state_3 | |
sta scroll_state | |
rts | |
// state 3 ------------------------------- | |
state_3_callback: | |
// | |
// Color | |
// | |
lda #<petscii_color_data | |
clc | |
adc offset | |
sta $20 | |
lda #>petscii_color_data | |
bcc !+ | |
adc #1 | |
!: | |
sta $21 | |
lda #$c8+39 | |
sta $22 | |
lda #$d8 | |
sta $23 | |
jsr write_last_col | |
lda #state_1 | |
sta scroll_state | |
rts | |
write_last_col: | |
ldx #0 | |
ldy #0 | |
!loop: | |
lda ($20), y | |
sta ($22), y | |
clc | |
lda $20 | |
adc #logo_width | |
sta $20 | |
bcc !+ | |
inc $21 | |
!: | |
clc | |
lda $22 | |
adc #40 | |
sta $22 | |
bcc !+ | |
inc $23 | |
!: | |
inx | |
cpx #logo_height | |
bmi !loop- | |
rts | |
clear_screen: | |
ldx #screen_bg_color | |
stx $d021 // write to screen color register | |
ldx #$00 // start of loop | |
stx $d020 // write to border color register | |
clear_loop: | |
lda #$20 // #$20 is the spacebar screencode | |
sta screen_ram, x // fill four areas with 256 spacebar characters | |
sta screen_ram + $100,x | |
sta screen_ram + $200,x | |
sta screen_ram + $300,x | |
lda #$0c // puts into the associated color ram dark grey ($0c)... | |
sta $d800,x // and this will become color of the scroll text | |
sta $d900,x | |
sta $da00,x | |
sta $dae8,x | |
inx | |
bne clear_loop | |
rts | |
draw_logo: | |
lda #<petscii_data | |
sta $20 | |
lda #>petscii_data | |
sta $21 | |
lda #$c8 // fila 5 | |
sta $22 | |
lda #$04 | |
sta $23 | |
jsr copydata | |
lda #<petscii_color_data | |
sta $20 | |
lda #>petscii_color_data | |
sta $21 | |
lda #$c8 | |
sta $22 | |
lda #$d8 | |
sta $23 | |
jsr copydata | |
rts | |
copydata: | |
ldx #0 | |
copydata2: | |
ldy #0 | |
!loop: | |
lda ($20), y | |
sta ($22), y | |
iny | |
cpy #40 | |
bmi !loop- | |
clc | |
lda $20 | |
adc #logo_width | |
sta $20 | |
bcc !+ | |
inc $21 | |
!: | |
clc | |
lda $22 | |
adc #40 | |
sta $22 | |
bcc !+ | |
inc $23 | |
!: | |
inx | |
cpx #logo_height | |
bmi copydata2 | |
rts | |
scroll_screen_left: | |
ldx #0 | |
!loop: | |
.for(var x=5;x<5+logo_height;x++) { | |
lda screen_ram + x*40 + 1, x | |
sta screen_ram + x*40, x | |
lda color_ram + x*40 + 1, x | |
sta color_ram + x*40, x | |
} | |
inx | |
cpx #39 | |
bpl !+ | |
jmp !loop- | |
!: | |
rts | |
//============================================================ | |
// SID | |
//============================================================ | |
.pc = music.location "Music" | |
.fill music.size, music.getData(i) | |
.print "SID Data" | |
.print "--------" | |
.print "location=$"+toHexString(music.location) | |
.print "init=$"+toHexString(music.init) | |
.print "play=$"+toHexString(music.play) | |
.print "songs="+music.songs | |
.print "startSong="+music.startSong | |
.print "size=$"+toHexString(music.size) | |
.print "name="+music.name | |
.print "author="+music.author | |
.print "copyright="+music.copyright | |
.print "" | |
.print "Additional tech data" | |
.print "--------------------" | |
.print "header="+music.header | |
.print "header version="+music.version | |
.print "flags="+toBinaryString(music.flags) | |
.print "speed="+toBinaryString(music.speed) | |
.print "startpage="+music.startpage | |
.print "pagelength="+music.pagelength | |
//============================================================ | |
// PETSCII DATA | |
//============================================================ | |
petscii_data: | |
.pc = * "PETSCII char" | |
.fill intro_data.getSize(), intro_data.get(i) | |
petscii_color_data: | |
.pc = * "PETSCII color" | |
.fill intro_data_color.getSize(), intro_data_color.get(i) | |
// vim: se ft=kickass: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment