Going crazy trying to get this 4 x 20 Character display working. All I get are a screen full of blocks (well initially I get a single line, then it flips to a full screen) I tested on a 2x16 also and get the same results, so I think my issue is in my initialization code. Code is deeply taken from what Garth has in his primer, and I stole the delay_ms function from somewhere.... I feel like it's a timing issue but can't seem to suss it out. Logic Analyzer shows that the bits are being sent properly, and the RS and EN lines are getting toggled appropriately... Any suggestions or help is appreciated...
The LCD is connected for 4-bit mode to VIA1 Port A 0 through 5
V1A0 - D4
V1A1 - D5
V1A2 - D6
V1A3 - D7
V1A4 - RS
V1A5 - EN
Code:
.setcpu "6502"
VIA1_ORB = $B100
VIA1_ORA = $B101
VIA1_DDRB = $B102
VIA1_DDRA = $B103
.segment "VECTORS"
.word nmi
.word reset
.word irq
.zeropage
tmp1: .byte $00
.code
reset: jmp main
nmi: rti
irq: rti
main: jsr reset_lcd
ldx #$0
loop: lda hello,x
beq hold
jsr send_lcd_data
inx
jmp loop
hold: jmp hold
send_lcd_nibble:
; XD XD EN RS D7 D6 D5 D4
; write the nibble
sta VIA1_ORA
ora #%00100000 ; Turn on enable pin
sta VIA1_ORA
AND #%11011111 ; Turn off enable pin
sta VIA1_ORA
RTS
send_lcd_instr:
pha
lsr A
lsr A
lsr A
lsr A
jsr send_lcd_nibble
PLA
AND #%00001111
JMP send_lcd_nibble
send_lcd_data:
pha
LSR A
LSR A
LSR A
LSR A
ora #%00010000
JSR send_lcd_nibble
PLA
AND #%00001111
ORA #%00010000
jmp send_lcd_nibble
reset_lcd:
lda #$FF
sta VIA1_DDRA
lda #$00
sta VIA1_ORA
lda #50
jsr _delay_ms
lda #$03 ;0011 - Do Setup
sta VIA1_ORA
ldx #$23 ;100011 - Same value, but with enable
stx VIA1_ORA ; Do the Enable
sta VIA1_ORA ; Send again without enable
lda #50
jsr _delay_ms
ldx #$23
stx VIA1_ORA ; with enable
lda #$03
sta VIA1_ORA ; wihtout enable
lda #50
jsr _delay_ms
ldx #$23
stx VIA1_ORA ; with enable
lda #$03
sta VIA1_ORA ; wihtout enable
lda #50
jsr _delay_ms
lda #$02
sta VIA1_ORA ; 4 - bit address (0010),
ldx #$22 ;
stx VIA1_ORA ; 4 - bit address (with enable)
sta VIA1_ORA ; 4 - bit address (no enable)
lda #$2B
jsr send_lcd_instr ; two line display, 5x10 font
lda #$0C
jsr send_lcd_instr ; Display on, no cursur, no blink
lda #$01
jsr send_lcd_instr ; Clear the screen
lda #$06
sta send_lcd_instr ;
lda #$02
sta send_lcd_instr ;
rts
; stole this from somewhere, it's hardcoded for 1MHz
_delay_ms: sta tmp1 ; 3
txa ; 2
pha ; 3
tya ; 2
pha ; 3
ldx tmp1 ; 3
ldy #190 ; 2
@loop1: dey ; 190 * 2
bne @loop1 ; 190 * 3 - 1
@loop2: dex ; 2
beq @return ; (x - 1) * 2 + 3
nop ; 2
ldy #198 ; 2
@loop3: dey ; 198 * 2
bne @loop3 ; 198 * 3 - 1
jmp @loop2 ; 3
@return: pla ; 4
tay ; 2
pla ; 4
tax ; 2
lda tmp1 ; 3
rts ; 6 (+ 6 for JSR)
hello: .byte "Hello, World!",$00