Let's Make a simple 6502-based computer, Part 4: A KS0108-based graphical LCD

Channel:
Subscribers:
5,450
Published on ● Video Link: https://www.youtube.com/watch?v=QQ-jPt3YSVE



Duration: 1:11:34
1,727 views
39


My final addition to this computer is a 128x64-pixel graphical LCD with a pleasant blue backlight. We don't do much with it, but it works, and the rest from here is all software. For more stuff like this, check out Ben Eater's channel here: https://www.youtube.com/channel/UCS0N5baNlQWJCUrhCEo8WlA

To finish off the story about the clock circuit: After making these videos, I did get my hands on a Rockwell TTL 6502, and it works perfectly with the clock circuit I showed in the first video (the one which uses a 2 MHz crystal and a 74F04 chip). So the circuit I showed really does work with a TTL 6502, it just doesn't work with the WDC 65C02.

The original website documenting the construction of this project can be found at these two locations:
http://lateblt.tripod.com/6502prj1.htm
http://lateblt.tripod.com/6502prj2.htm

So, at a relatively high-level view, the program in this video does the following:
- Make all VIA I/O pins be outputs
- Set D/I on the LCD low to send an instruction
- Put 00111111 on data bus (which is the "turn LCD on" command)
(Actually we use 11111100 because the data bus is wired "backwards".)
- Toggle the LCD's enable pin so that the command takes effect
- Set D/I high for pixel data
- Put 10110111 on the data bus (a fairly random pixel pattern which I chose)
- Keep toggling the enable pin infinitely

About the wiring shown in this video:
The LCD's data bus goes to the PB pins on the VIA.
Pin 12 on the LCD goes to PA7. (Chip Select 1, always 0 in this video.)
Pin 13 on the LCD goes to PA6. (Chip Select 2, always 0 in this video.)
Pin 15 on the LCD goes to PA5. (R/W, always 0 in this video.)
Pin 16 on the LCD goes to PA4. (D/I)
Pin 17 on the LCD goes to PA3. (Enable)

An assembly-language rendition of the program looks like this:

;Make all VIA's pins be outputs
LDA #$FF
STA $8002 ;Data direction register B
STA $8003 ;Data direction register A
;Put D/I low for instruction
LDA #$00 ;D/I low, Enable low
STA $8001 ;ORA, outputs to the LCD's control pins
;Put 3Fh into the accumulator, which is the "turn LCD on" command
;Actually use FCh, because the data bus is backwards
LDA #$FC
;Put the accumulator on ORB, which connects to the LCD's data bus
STA $8000
;Toggle the LCD's Enable pin to make the command take effect
LDA #$08 ;00001000 (Only enable is on)
STA $8001 ;ORA
LDA #$00
STA $8001 ;ORA
;LCD should now be on
;Put D/I high for data
LDA #$10 ;00010000
STA $8001 ;ORA
;D/I is now high
;Store 10110111 (B7h) (pixel pattern) in the accumulator
LDA #$B7
;...And put it in ORB
STA $8000
;Toggle LCD's Enable
LDA #$18 ;00011000 (D/I and Enable are on)
STA $8001 ;ORA
LDA #$10 ;00010000 (D/I remains on)
STA $8001 ;ORA
;Keep toggling Enable infinitely
JMP $E026

And here is what it actually looks like in terms of bits in the EEPROM:

0000000000000: 10101001 (A9) ;LDA #$FF
0000000000001: 11111111 (FF)
0000000000010: 10001101 (8D) ;STA $8002
0000000000011: 00000010 (02)
0000000000100: 10000000 (80)
0000000000101: 10001101 (8D) ;STA $8003
0000000000110: 00000011 (03)
0000000000111: 10000000 (80)
0000000001000: 10101001 (A9) ;LDA #$00
0000000001001: 00000000 (00)
0000000001010: 10001101 (8D) ;STA $8001
0000000001011: 00000001 (01)
0000000001100: 10000000 (80)
0000000001101: 10101001 (A9) ;LDA #$FC
0000000001110: 11111100 (FC)
0000000001111: 10001101 (8D) ;STA $8000
0000000010000: 00000000 (00)
0000000010001: 10000000 (80)
0000000010010: 10101001 (A9) ;LDA #$08
0000000010011: 00001000 (08)
0000000010100: 10001101 (8D) ;STA $8001
0000000010101: 00000001 (01)
0000000010110: 10000000 (80)
0000000010111: 10101001 (A9) ;LDA #$00
0000000011000: 00000000 (00)
0000000011001: 10001101 (8D) ;STA $8001
0000000011010: 00000001 (01)
0000000011011: 10000000 (80)
0000000011100: 10101001 (A9) ;LDA #$10
0000000011101: 00010000 (10)
0000000011110: 10001101 (8D) ;STA $8001
0000000011111: 00000001 (01)
0000000100000: 10000000 (80)
0000000100001: 10101001 (A9) ;LDA #$B7
0000000100010: 10110111 (B7)
0000000100011: 10001101 (8D) ;STA $8000
0000000100100: 00000000 (00)
0000000100101: 10000000 (80)
0000000100110: 10101001 (A9) ;LDA #$18
0000000100111: 00011000 (18)
0000000101000: 10001101 (8D) ;STA $8001
0000000101001: 00000001 (01)
0000000101010: 10000000 (80)
0000000101011: 10101001 (A9) ;LDA #$10
0000000101100: 00010000 (10)
0000000101101: 10001101 (8D) ;STA $8001
0000000101110: 00000001 (01)
0000000101111: 10000000 (80)
0000000110000: 01001100 (4C) ;JMP $E026
0000000110001: 00100110 (26)
0000000110010: 11100000 (E0)