Hey everyone. I recently built a 6502 computer using ben eater's videos. I got everything working on the breadboard with ram, rom, 6522 and 16x2 LCD so I figured I'd try to do something on my own. I bought a 128x64 LCD that uses an ST7920 chip and due to the fact that I've only got 5 pins left on the VIA chip I figured I'd try out bit banging SPI to communicate with it. I found this post from a while back
viewtopic.php?p=45555 where Dr Jefyll shows some methods for bit banging SPI using the VIA and I've been trying to use some of that code. I'm pretty new to assembly and electronics so I decided I would try to just get something working first then try to optimize from there.
From what I can tell from reading the data sheet (
https://www.lcd-module.de/eng/pdf/zubeh ... hinese.pdf) each data frame consists of 3 bytes:
1.) Sync bit - 5 1's followed by RW, RS and an additional zero to complete the byte (last 3 are 0's in my case)
2.) Most significant nibble followed by 4 0's
3.) Least significant nibble followed by 4 0's
I have my LCD hooked up like this:
VCC -> Connect to 5V
GND -> Connect to GND
RS -> Connect to 5V
RW (MOSI) -> VIA PA0
E (CLOCK) -> VIA PA1
PSB -> Connect to GND
RST -> Connect to 5V
A (or BLA) -> Connect to 5V
K (or BLK) -> Connect to GND
Here is the code I'm using to send a SPI byte:
Code:
SYNC_START = %00000010
lcd_spi_send:
stz PORTA
;==========================
; Step 1.) send 5 1s
;==========================
ldx #5
ldy #SYNC_START
sty PORTA
@startsync:
; pulse clock 5 times
inc PORTA
dec PORTA
dex
bne @startsync
;==========================
; Step 2.) send 3 0s
; RW, RS, and extra 0
; to round out byte
;==========================
stz PORTA
ldx #3
@endbits:
; pulse clock 3 times
inc PORTA
dec PORTA
dex
bne @endbits
;==========================
; Step 3.) first nibble
;==========================
ldy #00000010 ; constant for mosi high
ldx #4
@nibble_1:
asl A ; put bit into carry
bcs @mosi_1_1
stz PORTA ; clock = 0, mosi = 0
inc PORTA ; pulse clock
dec PORTA
jmp @dec_1
@mosi_1_1:
sty PORTA ; clock = 0, mosi = 1
inc PORTA ; pulse clock
dec PORTA
@dec_1:
dex
bne @nibble_1
;==========================
; Step 4.) 4 sync bits
;==========================
stz PORTA
ldx #4
@sync_bits_1:
inc PORTA
dec PORTA
dex
bne @sync_bits_1
;==========================
; Step 5.) second nibble
;==========================
ldy #00000010 ; constant for mosi high
ldx #4
@nibble_2:
asl A ; put bit into carry
bcs @mosi_1_2
stz PORTA ; clock = 0, mosi = 0
inc PORTA ; pulse clock
dec PORTA
jmp @dec_2
@mosi_1_2:
sty PORTA ; clock = 0, mosi = 1
inc PORTA ; pulse clock
dec PORTA
@dec_2:
dex
bne @nibble_2
;==========================
; Step 6.) 4 sync bits
;==========================
stz PORTA
ldx #4
@sync_bits_2:
inc PORTA
dec PORTA
dex
bne @sync_bits_2
rts
and then I'm using it like this:
Code:
lda #%11111111 ; PORT A to output
sta DDRA
; Basic function mode
lda #%00110000
jsr lcd_spi_send
jsr delay
; clear screen
lda #%00000001
jsr lcd_spi_send
jsr delay
; entry mode set
lda #%00000110
jsr lcd_spi_send
jsr delay
; display control
lda #%00001100
jsr lcd_spi_send
jsr delay
lda #%00000010
jsr lcd_spi_send
jsr delay
The data sheet said to wait 72 microseconds between commands, so I've added this delay code. Most likely overkill but it is what it is.
Code:
delay:
ldy #$ff
ldx #$ff
@loop:
dex
bne @loop
dey
bne @loop
rts
I'm expecting to see a cursor or something, but there is no change in the display at all. I'm not really sure what to do to debug this. Do you guys see anything wrong in my code?