Two messages display with delay for 4 bit LCD
; latest 6502 board
;
PORTB = $6000 ; 8 bits PB0-PB7
PORTA = $6001 ; 8 bits PA0-PA7
DDRB = $6002 ; data direction B bits
DDRA = $6003 ; data direction A bits
E = %00001000 ; PB3 connected
RW = %00000100 ; PB2 connected
RS = %00000010 ; PB1 connected
keep = $0200 ; store A
.org $8000
reset:
ldx #$ff
txs ; init stack pointer
lda #$0
sta keep ; keep = 0
lda #%11111110 ; 7 outputs PB1 -PB7, PB0 free
sta DDRB
lda #%00000001 ; 7 pins input, 1 output (PA0 led)
sta DDRA
lda #%00000001
sta PORTA ; turn off led (sink)
jsr short_delay ; necessary?
lda #%00000010 ; 4-bit mode
jsr lcd_instruction
lda #%00101000 ; 4-bit mode, 2-lines, 5x8 font
jsr lcd_instruction
lda #%00001110 ; display on, blink on, cursor off
jsr lcd_instruction
lda #%00000110 ; increment and shift cursor, no shift display
jsr lcd_instruction
lda #%00000001 ; clear screen
jsr lcd_instruction
lda #%10000000 ; cursor (0,0) line 1, pos 1
jsr lcd_instruction
jsr short_delay
print_msg1:
lda #%10000000 ; cursor (0,0) line 1, pos 1
jsr lcd_instruction
jsr blink_led
ldx #0
loop_msg1:
lda msg1,x
beq print_msg2 ; if msg1,x == zero
jsr print_char
inx
jmp loop_msg1
print_msg2:
jsr delay ; here is a delay
lda #%10000000 ; home
jsr lcd_instruction
jsr blink_led
ldx #0
loop_msg2:
lda msg2,x
beq loop ; if msg2,x == zero
jsr print_char
inx
jmp loop_msg2
loop:
jsr delay
jmp print_msg1
msg1: .asciiz "Hello, Everybody"
msg2: .asciiz "Goodbye to you "
short_delay:
ldx #$ff ; (2 cycles)
ldy #$2f ; (2 cycles)
short_loop:
dex ; (2 cycles)
bne short_loop ; (3 cycles in loop, 2 cycles at end)
dey
bne short_loop
rts
delay: ; delay for 1MHz
ldx #$ff ; (2 cycles)
ldy #$ff ; (2 cycles)
lda #$0a ; #$02 much faster
delay_loop:
nop
dex ; (2 cycles)
bne delay_loop ; (3 cycles in loop, 2 cycles at end)
nop
dey
bne delay_loop
nop
sbc #1
bne delay_loop
rts
lcd_instruction: ; 1. remove low nibble ; 2. move lnibble to high bit
sta keep ; save A in keep
and #$F0 ; lda & 1111 0000
sta PORTB
; Clear RS/RW/E bits no necessary
; Set E bit to send instruction
ora #E ; lda or E xxxx 0000 or 0000 1000
sta PORTB
; Clear RS/RW/E bits
and #$F0 ; lda & 1111 0000
sta PORTB
lda keep ; load lda from memory
asl ; shift left 4x 0000 xxxx -> xxxx 0000
asl
asl
asl
sta PORTB
; Set E bit to send instruction
ora #E ; lda or E xxxx 0000 or 0000 1000
sta PORTB
; Clear RS/RW/E bits
and #$F0 ; lda & 1111 0000
sta PORTB
rts
print_char:
sta keep ; save A in keep
and #$F0 ; lda & 1111 0000
sta PORTB
; clear E, set RS
and #$f0 ; lda & 1111 0000
ora #RS ; lda or 0000 0010
sta PORTB
; set E, set RS
ora #E ; lda or 0000 1000
ora #RS ; lda or 0000 0010
sta PORTB
; clear E, set RS
and #$f0 ; lda & 1111 0000
ora #RS ; lda or 0000 0010
sta PORTB
lda keep ; load A from memory
asl ; shift left 4x
asl
asl
asl
sta PORTB
; clear E, set RS
and #$f0 ; lda & 1111 0000
ora #RS ; lda or 0000 0010
sta PORTB
; set E, set RS
ora #E ; lda or 0000 1000
ora #RS ; lda or 0000 0010
sta PORTB
; clear E, set RS
and #$f0 ; lda & 1111 0000
ora #RS ; lda or 0000 0010
sta PORTB
rts
blink_led:
lda PORTA
and #%00000001 ; xxxx xxx0 & 0000 0001
beq blink_on ; if zero flag set
lda #%00000000
sta PORTA
rts
blink_on:
lda #%00000001
sta PORTA
rts
.org $fffc
.word reset
.word $0000