[WORKING] Simple 6502 SBC from scratch (Deck65)
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Looking back through the topic, I don't find any link to, or listing of, your LCD code. Do you have it posted somewhere? I looked in your github repo also, and didn't find it; that doesn't mean it's not there though, as I never can find anything on github! I have sample LCD code in various forms at http://wilsonminesco.com/6502primer/LCDcode.asm .
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Nice looking board!
You are, in fact, producing actual characters, just not the ones you expect. Those symbols are part of the HD44780 character set. You're also getting the right number of characters. That's fairly encouraging! If I'm reading your post right, you're getting a *different* set of unexpected characters each time through your test code? That could be crosstalk on your data lines. But it also could be one of those annoyingly easy to make but hard to find programming errors. I mean, if you did a: instead of a: you would get whatever happens to be in RAM interpreted as character data.
and3rson wrote:
No matter what I tried, I couldn't produce any actual characters. The screen initializes, the cursor advances, but the garbage is always there.
Code: Select all
lda 'B' ; ZP addressing mode - store the contents of memory location $0042 in the .A registerCode: Select all
lda #'B' ; immediate addressing mode - store the value $42 in the .A register"The key is not to let the hardware sense any fear." - Radical Brad
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Paganini wrote:
Nice looking board!
You are, in fact, producing actual characters, just not the ones you expect. Those symbols are part of the HD44780 character set. You're also getting the right number of characters. That's fairly encouraging! If I'm reading your post right, you're getting a *different* set of unexpected characters each time through your test code? That could be crosstalk on your data lines. But it also could be one of those annoyingly easy to make but hard to find programming errors. I mean, if you did a: instead of a: you would get whatever happens to be in RAM interpreted as character data.
and3rson wrote:
No matter what I tried, I couldn't produce any actual characters. The screen initializes, the cursor advances, but the garbage is always there.
Code: Select all
lda 'B' ; ZP addressing mode - store the contents of memory location $0042 in the .A registerCode: Select all
lda #'B' ; immediate addressing mode - store the value $42 in the .A registerYou are absolutely right! That TOTALLY flew over my head.
Garth - sorry, I totally forgot to commit my current code.
Here it is (it's almost a carbon copy from here: http://www.6502.org/mini-projects/optrexlcd/lcd.htm):
Code: Select all
.ifndef __SIM65C02__
; Vectors are not needed for Sim65
.segment "VECTORS"
.word nmi ; nmi
.word init ; main code
.word irq ; interrupt handler
.endif
.segment "ZEROPAGE"
.res 3 ;6510 register area
V0: .res 1
V1: .res 1
V2: .res 1
V3: .res 1
.segment "IO"
; LCD
LCD0: .res 1
LCD1: .res 1
LCD_BAD: .res 254
.segment "CODE"
; wait: ; Wait around a thousand cycles or so
; phx
; ldx #$FF
; wait0:
; dex
; bne wait0
; plx
; rts
lcdbusy:
pha
lcdbusy0:
lda LCD0
and #%10000000
bne lcdbusy0
pla
rts
lcdinit:
pha
phx
ldx #$04
lcdinit0:
lda #%10101010 ; digital analyzer trigger
lda #%00111000 ; 8 bit, 2 lines, 5x8
sta LCD0
jsr lcdbusy
dex
bne lcdinit0
lda #%00000110 ; increment, no shift
sta LCD0
jsr lcdbusy
lda #%00001111 ; display on, cursor on, blink on
sta LCD0
jsr lcdbusy
lda #%10000000 ; ddgram address set: $00
sta LCD0
jsr lcdbusy
plx
pla
rts
lcdclear:
pha
lda #%00000001 ; clear
sta LCD0
jsr lcdbusy
lda #%10000000 ; ddram address set: $00
sta LCD0
jsr lcdbusy
pla
rts
lcdprint:
pha
sta LCD1
jsr lcdbusy
pla
rts
; .export _main
; _main:
init:
jsr lcdinit
jsr lcdclear
lda 'A'
jsr lcdprint
lda 'B'
jsr lcdprint
lda 'C'
jsr lcdprint
lda 'D'
jsr lcdprint
lda 'E'
jsr lcdprint
lda 'F'
jsr lcdprint
lda 'G'
jsr lcdprint
lda 'H'
jsr lcdprint
lda '0'
jsr lcdprint
lda '1'
jsr lcdprint
lda '2'
jsr lcdprint
lda '3'
jsr lcdprint
lda '4'
jsr lcdprint
lda '5'
jsr lcdprint
lda '6'
jsr lcdprint
lda '7'
jsr lcdprint
lda LCD0 ; for debug
stp
So now the only issue is that screen fails to initialize when I connect anything to Ф2. Additionally, if I touch Ф2 with a wire while characters are being printed, it starts printing blank chars until I release the wire. And sometimes, it just doesn't initialize at all (but DDRAM address still increases on prints). Weird!
I think I'll disassemble the whole "piggyback" thing and try to do proper soldering job on a separate daughterboard. I think those legs that I bent upwards could be the reason...
EDIT: Forgot to mention - different 2004 display behaves the same, so it's the problem with my board. Just as expected.
EDIT 2: I've just replaced the "piggyback" with a "daughterboard", and now the screen is constantly blank (since I needed to extend Ф2 to reach to the daughterboard). Oh well!
Last edited by and3rson on Sun Mar 05, 2023 7:54 pm, edited 1 time in total.
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
and3rson wrote:
I've added '#' before characters and it worked! Thank you!
Quote:
So now the only issue is that screen fails to initialize when I connect anything to Ф2. Additionally, if I touch Ф2 with a wire while characters are being printed, it starts printing blank chars until I release the wire. Weird!
"The key is not to let the hardware sense any fear." - Radical Brad
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Paganini wrote:
and3rson wrote:
I've added '#' before characters and it worked! Thank you!
Quote:
So now the only issue is that screen fails to initialize when I connect anything to Ф2. Additionally, if I touch Ф2 with a wire while characters are being printed, it starts printing blank chars until I release the wire. Weird!
What's strange though is that this reproduces even at 100Hz, and even with manual clock for Ф0 (I'm using second DS1813 for executing one cycle at a time) - and all signals seem perfect: no noise, no spikes, no smooth edges, stable voltage levels.
(My CPU is W65C02S, so it works great with <1Hz frequencies.)
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
I've double-checked the timings and could not find any anomalies there.
Here's "lda #%00111000; sta LCD0" (captured at 1KHz): (You can see 6 high bits of 00111000 - "8 bit, 2 lines, 5x8" initialization, and LCDEN correctly falls with Ф2.)
UPDATE: Turns out not! The above capture happens only part of the time. Here's the same place (writing 00111000 to LCD0) during a different capture (captured at 1KHz): For some reason, data becomes invalid at the same moment when Ф2 (and LCDEN) goes low. Also, sometimes LCDEN lags behind Ф2, and sometimes both Ф2 & LCDEN properly go low while data is valid.
I feel like Ф2 is lagging for some reason.
Here's my clock part for reference: "STEP" comes from DS1813, "CLK" comes from crystal generator (or from attiny45 if I'm going below 100 KHz).
EDIT: I guess I should try ditching PHI2O whatsoever and rely only on PHI2. It thought PHI2O was the one that's supposed to be used in synchronizing reads/writes/enables, and I trusted it, but it betrayed me!
Besides, WDC recommend not using PHI2O & PHI1O. However, I still thought PHI2O is the correct signal for synchronizations. The naming is really confusing!
Question: should other legacy chips (e. g. 6522 VIA) use PHI2 or PHI2O?
Here's "lda #%00111000; sta LCD0" (captured at 1KHz): (You can see 6 high bits of 00111000 - "8 bit, 2 lines, 5x8" initialization, and LCDEN correctly falls with Ф2.)
UPDATE: Turns out not! The above capture happens only part of the time. Here's the same place (writing 00111000 to LCD0) during a different capture (captured at 1KHz): For some reason, data becomes invalid at the same moment when Ф2 (and LCDEN) goes low. Also, sometimes LCDEN lags behind Ф2, and sometimes both Ф2 & LCDEN properly go low while data is valid.
I feel like Ф2 is lagging for some reason.
Here's my clock part for reference: "STEP" comes from DS1813, "CLK" comes from crystal generator (or from attiny45 if I'm going below 100 KHz).
EDIT: I guess I should try ditching PHI2O whatsoever and rely only on PHI2. It thought PHI2O was the one that's supposed to be used in synchronizing reads/writes/enables, and I trusted it, but it betrayed me!
Besides, WDC recommend not using PHI2O & PHI1O. However, I still thought PHI2O is the correct signal for synchronizations. The naming is really confusing!
Question: should other legacy chips (e. g. 6522 VIA) use PHI2 or PHI2O?
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
...so I've disconnected w65c02's pin 39 from the board and merged oscillator input (PHI2) with former PHI2O like so:
And then, this happened.
No more issues with Ф2 when probing, everything works just as expected! Tested with 500KHz, 2MHz is too fast and the screen stays blank. But for that I'll use my VIA, this is just for testing.
And then, this happened.
No more issues with Ф2 when probing, everything works just as expected! Tested with 500KHz, 2MHz is too fast and the screen stays blank. But for that I'll use my VIA, this is just for testing.
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
I use pin 37 (PH0IN) for the system clock even on Rockwell R65C02 parts.
Couldn't you plug that 32K RAM directly into the 32-pin RAM socket (offset by 2 pins)? Is pin 30 connected to 5v VCC as in your schematic?
and3rson wrote:
Michael - that's a small DIP-28 to DIP-32 SRAM adapter, my AS6C1008 hasn't arrived yet, so I'm sticking to a 32Kx8 SRAM that I had.
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Michael wrote:
I use pin 37 (PH0IN) for the system clock even on Rockwell R65C02 parts.
Couldn't you plug that 32K RAM directly into the 32-pin RAM socket (offset by 2 pins)? Is pin 30 connected to 5v VCC as in your schematic?
and3rson wrote:
Michael - that's a small DIP-28 to DIP-32 SRAM adapter, my AS6C1008 hasn't arrived yet, so I'm sticking to a 32Kx8 SRAM that I had.
Here's what my current SBC with working LCD looks like. Turns out the NAND piggyback was not so bad after all.
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
and3rson wrote:
I've then rewired a low-active LCD/EN to to through this NAND [...] And this is where all the weird stuff started happening.
Experience has taught me that weird stuff and floating CMOS inputs are sometimes synonymous!
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
They're not floating; they're waving for help!
Neil
Neil
- BigDumbDinosaur
- Posts: 9425
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
barnacle wrote:
They're not floating; they're waving for help!
Neil
Neil
Lightning rods!
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
"One fought back!" - Bill Herd. 
Considering how I bent the poor thing's legs, it surely must be in pain! But it's getting the job done right.
I've spent a ridiculous amount of time trying to make LCD work with VIA. The VIA is great, the problem is HD44780 being a total arse with its 4-bit mode timings and with the initialization sequence.
After going around in circles, probing my LCD for hours with a digital analyzer, and reflashing my EPROM like 300 times, I've finally made it work. Many examples on the internet send 8-bit initialization nibble before switching to 4-bit mode, I couldn't get it to work unless I changed all 4 writes to 4-bit init. It still doesn't work reliably - most of the time it doesn't init on power-on, requiring me to reset manually.
Logic analyzer was extremely helpful - It helped my find places where I accidentally left some VIA lines floating by setting them as input when they were supposed to output, and gave me a good vision of the "shape" of the signal as well as of all the timings. I wanted to have as little busy waiting as possible, so I actually implemented reading of busy flag via 4-bit line.
My LCD code is here (don't judge me to hard, I'm still very new to 6502 assembly): https://github.com/and3rson/65ad02/blob ... /src/lcd.s
It still contains a lot of busywaits for timing, but at least I've gotten the thing to work, and it's really fast - redrawing the entire screen takes less than 100ms. I think it can be improved since all my CPU delays are heavily padded. It also includes some nice tty-like screen scrolling, terminal style.
My old VIA-less code for 8-bit LCD operation is here: https://github.com/and3rson/65ad02/blob ... old/lcd2.s - but it doesn't work with clock speed >500 KHz.
As for now, my SBC is successfully running @ 4 MHz, LCD is working, interrupts are firing, and I still have two control lines & 9 I/O bits available in my VIA.
My next stop is bit-banging a PS/2 keyboard & interfacing with I2C devices.
<rant>
I wish PS/2 protocol had 8-bit packets! It could then work so nicely with 6522's shift register...
</rant>
I also managed to configure VIA to generate periodic interrupts - it's going to be very handy with playing .SID tracks from HVSC (https://hvsc.c64.org/). I've did some basic testing and could hear a very faint sound coming from my speakers - I guess those capacitor values in C64 schematic are indeed very important! (I suck at analog circuits!)
Garth - your LCD ASM examples were very helpful!
Jeff - thanks for the tip, I've pulled the inputs up to be on the safe side!
Considering how I bent the poor thing's legs, it surely must be in pain! But it's getting the job done right.
I've spent a ridiculous amount of time trying to make LCD work with VIA. The VIA is great, the problem is HD44780 being a total arse with its 4-bit mode timings and with the initialization sequence.
After going around in circles, probing my LCD for hours with a digital analyzer, and reflashing my EPROM like 300 times, I've finally made it work. Many examples on the internet send 8-bit initialization nibble before switching to 4-bit mode, I couldn't get it to work unless I changed all 4 writes to 4-bit init. It still doesn't work reliably - most of the time it doesn't init on power-on, requiring me to reset manually.
Logic analyzer was extremely helpful - It helped my find places where I accidentally left some VIA lines floating by setting them as input when they were supposed to output, and gave me a good vision of the "shape" of the signal as well as of all the timings. I wanted to have as little busy waiting as possible, so I actually implemented reading of busy flag via 4-bit line.
My LCD code is here (don't judge me to hard, I'm still very new to 6502 assembly): https://github.com/and3rson/65ad02/blob ... /src/lcd.s
It still contains a lot of busywaits for timing, but at least I've gotten the thing to work, and it's really fast - redrawing the entire screen takes less than 100ms. I think it can be improved since all my CPU delays are heavily padded. It also includes some nice tty-like screen scrolling, terminal style.
My old VIA-less code for 8-bit LCD operation is here: https://github.com/and3rson/65ad02/blob ... old/lcd2.s - but it doesn't work with clock speed >500 KHz.
As for now, my SBC is successfully running @ 4 MHz, LCD is working, interrupts are firing, and I still have two control lines & 9 I/O bits available in my VIA.
My next stop is bit-banging a PS/2 keyboard & interfacing with I2C devices.
<rant>
I wish PS/2 protocol had 8-bit packets! It could then work so nicely with 6522's shift register...
</rant>
I also managed to configure VIA to generate periodic interrupts - it's going to be very handy with playing .SID tracks from HVSC (https://hvsc.c64.org/). I've did some basic testing and could hear a very faint sound coming from my speakers - I guess those capacitor values in C64 schematic are indeed very important! (I suck at analog circuits!)
Garth - your LCD ASM examples were very helpful!
Jeff - thanks for the tip, I've pulled the inputs up to be on the safe side!
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
Update: I think I've improved the timings a bit. I used vdelay (https://github.com/bbbradsmith/6502vdelay) to have more-or-less realistic delays.
The display works much better now with a small caveat: every even boot is garbled. However, on initial power-up it's OK, and so it is after 2, 4, 6 (and so on) resets.
I think it's due to duplicate initialization after repeated resets: I'm writing initialization nibble 3 times before writing full bytes, so every even boot has a "nibble-skew" problem.
The only solution I can think of now is to completely cut the power of LCD when /RES is asserted - say, with a mosfet. This way LCD will hard-reset on every reset. Anyone had similar issues?
EDIT: I think another solution is to save initialization flag in RAM, and then do LCD initialization conditionally, thus avoiding re-initializations. Is SRAM initialized with zeroes by default? If so, this method should be very easy.
EDIT 2: Turns out not - SRAM is not zeroed on power-up. I could still write some "magic" value there, but statistically this would only work 1/256 times.
Also, "clear" function doesn't seem to set busy flag properly: I still had to add explicit 4ms delay to make it work.
The display works much better now with a small caveat: every even boot is garbled. However, on initial power-up it's OK, and so it is after 2, 4, 6 (and so on) resets.
I think it's due to duplicate initialization after repeated resets: I'm writing initialization nibble 3 times before writing full bytes, so every even boot has a "nibble-skew" problem.
Code: Select all
; Initialize 4-bit mode
; First strobe
lda #%0010
jsr lcd_writenib
lda #$00
ldx #$40
jsr vdelay ; 4 ms
; Second strobe
lda #%0010
jsr lcd_writenib
lda #$00
ldx #$02
jsr vdelay ; 128 us
; Third strobe
lda #%0010
jsr lcd_writenib
lda #$00
ldx #$01
jsr vdelay ; 64 us
; *Real* initialization starts here
lda #%00101000 ; 4 bit, 2 lines, 5x8
jsr lcd_writecmd
jsr lcd_busy
lda #%00000110 ; increment, no shift
jsr lcd_writecmd
jsr lcd_busy
lda #%00001111 ; display on, cursor on, blink on
jsr lcd_writecmd
jsr lcd_busy
lda #%00000001 ; Clear screen
jsr lcd_writecmd
jsr lcd_busy
lda #$00
ldx #$40
jsr vdelay ; 4 ms - "clear" doesn't seem to assert busy flag, so we need to wait explicitly...
EDIT: I think another solution is to save initialization flag in RAM, and then do LCD initialization conditionally, thus avoiding re-initializations. Is SRAM initialized with zeroes by default? If so, this method should be very easy.
EDIT 2: Turns out not - SRAM is not zeroed on power-up. I could still write some "magic" value there, but statistically this would only work 1/256 times.
Also, "clear" function doesn't seem to set busy flag properly: I still had to add explicit 4ms delay to make it work.
/Andrew
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
deck65 - 6502 slab with screen and keyboard | ПК-88 - SBC based on KM1810VM88 (Ukrainian i8088 clone) | leo80 - simple Z80 SBC
nice65 - 6502 assembly linter | My parts, footprints & 3D models for KiCad/FreeCAD
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: [WORKING] Simple 6502 SBC from scratch (65ad02)
and3rson wrote:
Garth - your LCD ASM examples were very helpful!
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?