Obstacle race 8 data lines lcd
;; custom characters 8 locations 0-7
;; command $40 | (location << 3) to access cgram
;; followed by 8 x 5 bytes data
;; to display send (byte)0-7 of data
PORTB = $6000 ; 8 bits on the right
PORTA = $6001 ; 3 bit last 3 on the left
DDRB = $6002
DDRA = $6003
PCR = $600c
IFR = $600d
IER = $600e
E = %10000000 ; enable pin
RW = %01000000 ; r/w pin
RS = %00100000 ; register select 0=cmd 1=data
Cx = $0200
Xx = $0201
Rx = $0202 ; variables for val_to_dec
countup = $0203 ; num of jumps
countdown = $40 ; cycle 0-31, after 16x cycle 0-15
jump = $41 ; switch for jumping 1=up,0=down
endz = $42 ; end of swapping/ cycle
temp1 = $43 ; save line1,0
temp2 = $44 ; save line2,0
endy = $45 ; end of print line1 & 2
line1 = $020a ; 32 bytes
line2 = $022a ; 32 bytes
.org $8000
reset:
ldx #$ff
txs ; init stack pointer in page1 $01xx
cli ; clear interrupt disable
lda #$82 ; set bit 8 (enable other bits) and bit 2 (CA1)
sta IER ; interrupt enable register
lda #$00 ; CA1 is 0, negative active edge
sta PCR ; peripheral control register
lda PORTA ; read ORA clears interrupt flag
lda #%11111111 ; all outputs
sta DDRB
lda #%11100000 ; 3 pins output
sta DDRA
lda #%00111000 ; 8-bit mode, 2-lines, 5x8 font
jsr lcd_instruction
lda #%00001100 ; display on, blink off, cursor off
jsr lcd_instruction
lda #%00000110 ; increment and shift cursor, no shift display
jsr lcd_instruction
lda #%00000001 ; clear screen
jsr lcd_instruction
jsr delay
init:
lda #%00000001 ; clear screen
jsr lcd_instruction
lda #$0
sta countup
sta Cx
sta Xx
sta Rx
sta jump ; 1 = up 0 = down
lda #$10
sta countdown ; 16
lda #$20
sta endy ; 32
; create custom chars in cgram
lda #$40 ; 0100 000 - 0111 1000 (0-7) $40 | (location << 3)
jsr lcd_instruction
jsr print_custom_man1 ; cust[0]
jsr print_custom_man2 ; cust[1]
jsr print_tree ; cust[2]
jsr print_empty_space ; cust[3]
jsr print_crash ; cust[4]
; create 2 lines of cust-chars
; e(16x)ebbbeeeeebbbeeee e(16x)eeeeebbbeeeeebbb
ldx #$0
lda #$3 ; empty space
initlp:
sta line1,x
sta line2,x ; 0-15
inx
cpx #$20
bne initlp
jsr add_tree_line1
jsr add_tree_line2
stage1: ; set cursor at #$80, print line1,
; cursor at #$c0 , print line2,
; check collision and print_man
; cycle and add_obstacles
lda #$80
jsr lcd_instruction
ldx #$0
st_lp1: ; print line1
lda line1,x ; 0-31
jsr print_char
inx
cpx endy ; first 32, later 16
bne st_lp1
lda #$c0
jsr lcd_instruction
ldx #$0
st_lp2:
lda line2,x ; print line2
jsr print_char
inx
cpx endy
bne st_lp2
st_lp3:
jsr print_man
jsr delay
jsr cycle
jsr more_trees
jsr delay
jmp stage1
endless:
jmp endless
;-------------------start of sub-routines---------------
add_tree_line1: ; add the trees
ldx #$10
lda #$2 ; 16 and 24
sta line1,x ; trees
ldx #$18
sta line1,x
inx
sta line1,x
rts
add_tree_line2: ; add trees to line2
ldx #$14
lda #$2 ; 20 and 28
sta line2,x ; trees
ldx #$1c
sta line2,x
rts
finish:
lda jump
beq fin_down
lda #$84
jsr lcd_instruction
fin_up:
lda #$4
jsr print_char
lda #$8d ; cursor 1,0
jsr lcd_instruction
jsr val_to_dec
jmp endless
fin_down:
lda #$c4
jsr lcd_instruction
jmp fin_up
print_man:
lda jump
beq print_down ; 1=up, 0=down
ldx #$4
lda line1,x ; what is in line1,4
cmp #$3 ; empty?
bne finish
lda #$84
jsr lcd_instruction
lda #$0
jsr print_char
rts
print_down:
ldx #$4
lda line2,x ; what is in line1,4
cmp #$3 ; empty?
bne finish
lda #$c4
jsr lcd_instruction
lda #$1
jsr print_char
rts
cycle:
lda countdown
bne change_endz ; 1=long line, 0=short line
lda #$0f ; temp<-0<-1<-2 ... 15<-temp
sta endz
lda #$10
sta endy ; print line,x 0-15 ends 16
cy_start:
ldx #$0
ldy #$1
lda line1,x
sta temp1
lda line2,x
sta temp2
cy_lp1
lda line1,y
sta line1,x
lda line2,y
sta line2,x
iny
inx
cpx endz ; 15 or 31
bne cy_lp1
lda temp1
sta line1,x
lda temp2
sta line2,x
rts
change_endz:
lda #$1f
sta endz ; 31 = last in line1 & 2
dec countdown ;
lda #$0
sta countup
jmp cy_start
more_trees:
ldx #$0
lda line1,x
cmp #$3 ; empty
bne line2_next
inx
lda line1,x
cmp #$2 ; tree
bne line2_next
inx
lda line1,x
cmp #$3 ; empty
bne try_next
lda #$2
sta line1,x ; tree at 3
rts
try_next:
cmp #$2 ; tree
bne more_out
inx
lda #$2
sta line1,x
rts
line2_next:
ldx #$0
lda line2,x
cmp #$3 ; empty
bne more_out
inx
lda line2,x
cmp #$2 ; tree
bne more_out
inx
lda line2,x
cmp #$3 ; empty
bne try2_next
lda #$2
sta line2,x
rts
try2_next:
cmp #$2 ; tree
bne more_out
inx
lda #$2
sta line2,x
rts
more_out:
rts
val_to_dec:
lda countup
vd_100:
cmp #$64 ; >=100 ?
bcs vd_hunderd ; c=1, no borrow
vd_10:
cmp #$0a ; >=10 ?
bcs vd_ten
vd_ones:
sta Rx
ldx Cx
lda str,x
jsr print_char
ldx Xx
lda str,x
jsr print_char
ldx Rx
lda str,x
jsr print_char
rts
vd_hunderd:
sec
sbc #$64 ; subtract 100
ldx Cx
inx
stx Cx ; Cx+1
jmp vd_100
vd_ten:
sec
sbc #$0a ; subtract 10
ldx Xx
inx
stx Xx ; Xx + 1
jmp vd_10
man1: .byte $C,$C,$10,$1C,$F,$C,$A,$A
man2: .byte $C,$C,$0,$E,$1C,$C,$1A,$13
tree: .byte $15,$0E,$15,$17,$0C,$04,$04,$04
crash: .byte $11,$13,$0A,$16,$0F,$0F,$12,$11
str: .byte "0123456789"
print_custom_man1:
ldx #$0
man1_loop:
lda man1,x
jsr print_char
inx
cpx #$8
bne man1_loop
rts
print_custom_man2:
ldx #$0
man2_loop:
lda man2,x
jsr print_char
inx
cpx #$8
bne man2_loop
rts
print_empty_space:
ldx #$0
empty_loop:
lda #$0
jsr print_char
inx
cpx #$8
bne empty_loop
rts
print_tree
ldx #$0
tree_loop:
lda tree,x
jsr print_char
inx
cpx #$8
bne tree_loop
rts
print_crash:
ldx #$0
crash_loop:
lda crash,x
jsr print_char
inx
cpx #$8
bne crash_loop
rts
busy_wait: ; subroutine
pha
lda #%00000000 ; portb inputs
sta DDRB
busy_loop:
lda #RW
sta PORTA
lda #(RW | E)
sta PORTA
lda PORTB
and #%10000000
bne busy_loop
lda #RW
sta PORTA
lda #%11111111 ; portb outputs
sta DDRB ; address $6002
pla
rts
delay: ; subroutine
ldx #$ff
ldy #$ff
delay_loop:
dex ; (2 cycles)
bne delay_loop ; (3 cycles in loop, 2 cycles at end)
dey
bne delay_loop
rts
lcd_instruction: ; subroutine
jsr busy_wait
sta PORTB ; a to PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTA ; 0 to PORTA
lda #E ; Set E bit to send instruction
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTA
rts
print_char: ; subroutine
jsr busy_wait
sta PORTB
lda #RS ; set RS, clear E
sta PORTA
lda #(RS | E) ; set RS, set E
sta PORTA
lda #RS ; set RS, clear E
sta PORTA
rts
nmi:
irq:
inc countup
ldx jump ; load 1 or 0
beq flip ; jump=0
dec jump
bit PORTA ; read ORA clears interrupt flag
rti
flip:
inc jump
bit PORTA ; read ORA clears interrupt flag
rti
.org $fffa
.word nmi
.word reset
.word irq