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