Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; soft scrolling background with 4 user defined characters in a 2x2 tile.
- ; it is meant to look a bit like the far background in the game Parallax
- ; but I suck at graphics so it looks nothing like it. ffs!
- ; movement constants
- UP = 1
- DN = 2
- LT = 3
- RT = 4
- ; mem locations for variables, storage, etc
- ; chars & sceen
- chars = $4000
- char0 = $4000 ; locations of the user chars used in the background
- char1 = $4008
- char2 = $4010
- char3 = $4018
- screen = $5000
- ; storage
- temp0 = $6000
- temp1 = $6001
- temp2 = $6002
- temp3 = $6003
- ; key
- lastkey = $10
- actkey = $11
- mask = $12
- matrixlo = $13
- matrixhi = $14
- table = $60a0
- ; general
- counter = $6004
- line_ptr = $6005
- framecounter = $6006
- timer = $6007 ; should work that when framecounter == timer, the scroll happens
- direction = $6008 ; scroll direction
- ; the chars are currently written to characters 0/1/2/3
- * = $c000
- lda #0
- sta line_ptr
- sta temp0
- sta temp1
- sta temp2
- sta temp3
- sta framecounter
- sta direction
- sta counter
- lda #10
- sta timer
- jsr $e544 ; cls
- jsr movechars
- jsr setchars
- jsr fillscreen
- jsr key_setup
- jsr setup_irq
- key_in: jsr keyscan
- lda actkey
- test_k1 cmp #$31 ; 1
- bne test_k2
- lda #10
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_k2: cmp #$32 ; 2
- bne test_k3
- lda #8
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_k3: cmp #$33 ; 3
- bne test_k4
- lda #6
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_k4: cmp #$34 ; 4
- bne test_k5
- lda #4
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_k5: cmp #$35 ; 5
- bne test_k6
- lda #2
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_k6: cmp #$36 ; 6
- bne test_left
- lda #1
- sta timer
- lda #0
- sta framecounter
- jmp key_in
- test_left: cmp #$41 ; (a for left)
- bne test_right
- lda LT
- sta direction
- jmp key_in
- test_right: cmp #$44 ; (d for right)
- bne test_up:
- lda RT
- sta direction
- jmp key_in
- test_up: cmp #$57 ; (w for up)
- bne test_down
- lda UP
- sta direction
- jmp key_in
- test_down: cmp #$53 ; (s for dn)
- bne no_key
- lda DN
- sta direction
- no_key: jmp key_in
- ; code to roll chars here
- ; the characters should be in ram at $4000, and the screen 4K above that.
- roll_left: ldy #$00
- lloop: clc
- lda char0,y
- rol
- sta char0,y
- bcc l_no_carry0
- lda #01
- jmp l_sta_tmp0
- l_no_carry0: lda #0
- l_sta_tmp0: sta temp0
- clc
- lda char1,y
- rol
- sta char1,y
- bcc l_no_carry1
- lda #01
- jmp l_sta_tmp1
- l_no_carry1: lda #0
- l_sta_tmp1: sta temp1
- clc
- lda char2,y
- rol
- sta char2,y
- bcc l_no_carry2
- lda #01
- jmp l_sta_tmp2
- l_no_carry2: lda #0
- l_sta_tmp2: sta temp2
- clc
- lda char3,y
- rol
- sta char3,y
- bcc l_no_carry3
- lda #01
- jmp l_sta_tmp3
- l_no_carry3: lda #0
- l_sta_tmp3: sta temp3
- clc
- lda char1,y
- adc temp0
- sta char1,y
- lda char0,y
- clc
- adc temp1
- sta char0,y
- clc
- lda char3,y
- adc temp2
- sta char3,y
- clc
- lda char2,y
- adc temp3
- sta char2,y
- lda #0
- sta temp0
- sta temp1
- sta temp2
- sta temp3
- iny
- cpy #08
- beq rl_done
- jmp lloop
- rl_done: rts
- roll_right: ldy #0
- rloop: clc
- lda char0,y
- ror
- sta char0,y
- bcc r_no_carry0
- lda #128
- jmp r_sta_tmp0
- r_no_carry0: lda #0
- r_sta_tmp0: sta temp0
- clc
- lda char1,y
- ror
- sta char1,y
- bcc r_no_carry1
- lda #128
- jmp r_sta_tmp1
- r_no_carry1: lda #0
- r_sta_tmp1: sta temp1
- clc
- lda char2,y
- ror
- sta char2,y
- bcc r_no_carry2
- lda #128
- jmp r_sta_tmp2
- r_no_carry2: lda #0
- r_sta_tmp2: sta temp2
- clc
- lda char3,y
- ror
- sta char3,y
- bcc r_no_carry3
- lda #128
- jmp r_sta_tmp3
- r_no_carry3: lda #0
- r_sta_tmp3: sta temp3
- clc
- lda char1,y
- adc temp0
- sta char1,y
- lda char0,y
- clc
- adc temp1
- sta char0,y
- clc
- lda char3,y
- adc temp2
- sta char3,y
- clc
- lda char2,y
- adc temp3
- sta char2,y
- lda #0
- sta temp0
- sta temp1
- sta temp2
- sta temp3
- iny
- cpy #08
- beq rr_done
- jmp rloop
- rr_done: rts
- roll_up: ldy #$01
- ldx #$00
- lda char0,x
- sta temp0
- lda char1,x
- sta temp1
- lda char2,x
- sta temp2
- lda char3,x
- sta temp3
- uloop: lda char0,y
- sta char0,x
- lda char1,y
- sta char1,x
- lda char2,y
- sta char2,x
- lda char3,y
- sta char3,x
- inx
- iny
- cpx #$08
- bne uloop
- lda temp0
- sta char2+7
- lda temp1
- sta char3+7
- lda temp2
- sta char0+7
- lda temp3
- sta char1+7
- rts
- roll_dn: ldy #$06
- ldx #$07
- lda char0,x
- sta temp0
- lda char1,x
- sta temp1
- lda char2,x
- sta temp2
- lda char3,x
- sta temp3
- dloop: lda char0,y
- sta char0,x
- lda char1,y
- sta char1,x
- lda char2,y
- sta char2,x
- lda char3,y
- sta char3,x
- dex
- dey
- cpx #$00
- bne dloop
- lda temp0
- sta char2
- lda temp1
- sta char3
- lda temp2
- sta char0
- lda temp3
- sta char1
- rts
- keyscan
- lda #%11111110
- sta mask
- lda #%11111101
- sta $dc00
- lda $dc01
- and #%10000000
- beq shifted ;left shift pressed
- lda #%10111111
- sta $dc00
- lda $dc01
- and #%00010000
- beq shifted ;right shift pressed
- lda #<keytabunshifted
- sta matrixlo
- lda #>keytabunshifted
- sta matrixhi
- jmp scan
- shifted
- lda #<keytabshifted
- sta matrixlo
- lda #>keytabshifted
- sta matrixhi
- scan ldx #$07
- rowloop
- lda mask
- sta $dc00
- ldy $dc01
- lda table,y
- beq next
- tay
- lda (matrixlo),y
- cmp #$01
- beq next ;skip left shift
- cmp #$02
- beq next ;skip right shift
- cmp lastkey
- beq debounce
- sta lastkey
- sta actkey
- rts
- next
- sec
- rol mask
- lda matrixlo
- clc
- adc #$09
- sta matrixlo
- bcc +
- inc matrixhi
- + dex
- bpl rowloop
- rts
- debounce lda #$ff ;one extra $ff column is added, because the zero value is used to detect unpressed keys
- sta actkey
- rts
- movechars: sei
- lda #$33 ; make the CPU see the Character Generator ROM...
- sta $01
- lda #$d0
- sta $fc
- lda #$40
- sta $fe
- lda #$00
- sta $fb
- sta $fd
- sta counter
- ldy #$00
- ldx #$08
- ll: lda ($fb),y
- sta ($fd),y
- iny
- bne ll
- inc $fc
- inc $fe
- dex
- bne ll
- lda #55
- sta $01
- lda #64
- sta $d018
- lda $dd00
- and #$fe ; and with 254 to switch off bit one
- ora #2 ; switch on bit two
- sta $dd00
- lda $dd02
- ora #3
- sta $dd02
- lda #$40
- sta $fe
- lda #$00
- sta $fd
- lda #$50
- sta $288 ; 648 - screen mem start in pages of 256.
- cli
- rts
- setchars:
- ldx #0
- uc_loop: lda uchars,x
- sta chars,x
- inx
- cpx #$20
- bne uc_loop
- rts
- fillscreen: ; $fb/$fc = ptr for indirect
- ldx #$00 ; set X to zero (black color code)
- stx $d021 ; set background color
- stx $d020 ; set border color
- stx counter
- jsr colour_screen
- start: ldx line_ptr
- lda the_lines,x
- sta $fb
- inx
- lda the_lines,x
- sta $fc
- inc line_ptr
- inc line_ptr
- lda #00
- ldy #00
- line1_fill: sta ($fb),y
- tya ; code to alternate between char 0 and char 1
- ror
- bcc line1_odd
- lda #00
- jmp line1_done
- line1_odd: lda #01
- line1_done: iny
- cpy #40
- bne line1_fill
- lda counter
- cmp #25
- beq all_done
- lda #02
- line2_fill: sta ($fb),y
- tya ; code to alternate between char 0 and char 1 / char 3 and char 3
- ror
- bcc line2_odd
- lda #02
- jmp line2_done
- line2_odd: lda #03
- line2_done: iny
- cpy #80
- bne line2_fill
- inc counter
- lda counter
- cmp #12
- beq all_done
- jmp start
- ; fill the last line with spaces.
- all_done: ldx line_ptr
- lda the_lines,x
- sta $fb
- inx
- lda the_lines,x
- sta $fc
- no_inc2: lda #32
- last_line: sta ($fb),y
- iny
- cpy #40
- bne last_line
- rts
- colour_screen: ldx #$00
- lda #11 ; set foreground to grey in Color Ram, bkground is set to black at $d021
- cloop: sta $d800,x
- sta $d900,x
- sta $da00,x
- sta $dae8,x
- inx ; increment X
- bne cloop ; did X turn to zero yet?
- ; if not, continue with the loop
- rts ; return from this subroutine
- ; keyboard routine from code base
- key_setup:
- ldx #$00
- lda #$00
- - sta table,x
- dex
- bne -
- lda #$ff
- sta lastkey
- lda #$08 ;helper table to index into keyboard matrix
- sta table+%01111111
- lda #$07
- sta table+%10111111
- lda #$06
- sta table+%11011111
- lda #$05
- sta table+%11101111
- lda #$04
- sta table+%11110111
- lda #$03
- sta table+%11111011
- lda #$02
- sta table+%11111101
- lda #$01
- sta table+%11111110
- lda #$08 ;left shift and another key
- sta table+%01111111
- lda #$07
- sta table+%00111111
- lda #$06
- sta table+%01011111
- lda #$05
- sta table+%01101111
- lda #$04
- sta table+%01110111
- lda #$03
- sta table+%01111011
- lda #$02
- sta table+%01111101
- lda #$01
- sta table+%01111110
- lda #$08 ;right shift and another key
- sta table+%01101111
- lda #$07
- sta table+%10101111
- lda #$06
- sta table+%11001111
- lda #$05
- sta table+%11101111
- lda #$04
- sta table+%11100111
- lda #$03
- sta table+%11101011
- lda #$02
- sta table+%11101101
- lda #$01
- sta table+%11101110
- rts
- setup_irq:
- ; setup the irq as per usual
- 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 #$fd ;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
- rts
- irq: ;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
- 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.
- inc framecounter
- lda framecounter
- cmp timer
- bne no_fr_ch
- lda #0
- sta framecounter
- jmp dir_test_up
- no_fr_ch: jmp finish
- dir_test_up: lda direction
- cmp UP
- bne dir_test_dn
- jsr roll_up
- jmp finish
- dir_test_dn: lda direction
- cmp DN
- bne dir_test_lt
- jsr roll_dn
- jmp finish
- dir_test_lt: lda direction
- cmp LT
- bne dir_test_rt
- jsr roll_left
- jmp finish
- dir_test_rt: lda direction
- cmp RT
- bne finish
- jsr roll_right
- jmp finish
- finish 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
- ; character definitions
- uchars
- !by 255
- !by 102
- !by 63
- !by 25
- !by 15
- !by 6
- !by 2
- !by 1
- !by 255
- !by 103
- !by 255
- !by 159
- !by 255
- !by 127
- !by 255
- !by 255
- !by 1
- !by 2
- !by 7
- !by 9
- !by 31
- !by 51
- !by 25
- !by 204
- !by 255
- !by 127
- !by 255
- !by 63
- !by 255
- !by 55
- !by 155
- !by 205
- the_lines
- !by $00, $50
- !by $50, $50
- !by $a0, $50
- !by $f0, $50
- !by $40, $51
- !by $90, $51
- !by $e0, $51
- !by $30, $52
- !by $80, $52
- !by $d0, $52
- !by $20, $53
- !by $70, $53
- !by $c0, $53
- keytabunshifted
- !byte $ff,$14,$0D,$1D,$88,$85,$86,$87,$11 ;0
- !byte $ff,$33,$57,$41,$34,$5A,$53,$45,$01 ;1
- !byte $ff,$35,$52,$44,$36,$43,$46,$54,$58 ;2
- !byte $ff,$37,$59,$47,$38,$42,$48,$55,$56 ;3
- !byte $ff,$39,$49,$4A,$30,$4D,$4B,$4F,$4E ;4
- !byte $ff,$2B,$50,$4C,$2D,$2E,$3A,$40,$2C ;5
- !byte $ff,$5C,$2A,$3B,$13,$01,$3D,$5E,$2F ;6
- !byte $ff,$31,$5F,$04,$32,$20,$02,$51,$03 ;7
- !byte $ff
- keytabshifted
- !byte $ff,$94,$8D,$9D,$8C,$89,$8A,$8B,$91
- !byte $ff,$23,$D7,$C1,$24,$DA,$D3,$C5,$01
- !byte $ff,$25,$D2,$C4,$26,$C3,$C6,$D4,$D8
- !byte $ff,$27,$D9,$C7,$28,$C2,$C8,$D5,$D6
- !byte $ff,$29,$C9,$CA,$30,$CD,$CB,$CF,$CE
- !byte $ff,$DB,$D0,$CC,$DD,$3E,$5B,$BA,$3C
- !byte $ff,$A9,$C0,$5D,$93,$01,$3D,$DE,$3F
- !byte $ff,$21,$5F,$04,$22,$A0,$02,$D1,$83
- !byte $ff
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement