I know there are *a lot* of threads on this subject here, but I decided to share the solution which I found easiest to implement by myself.
I recently got a really neat display based on T6963C. Its resolution is 240x64 and it supports both character & graphic modes. It also includes char generator ROM.
Attachment:
File comment: Image from product page on AliExpress
24064.jpg [ 85.5 KiB | Viewed 1167 times ]
However, it doesn't support 4-bit addressing as HD44780 & friends do, so using VIA is off the table since it needs 8 data bits + /RD & /WR + EN + C/D (12 total, reset & font selection can be hardwired.)
I could probably use some shift registers, but man -
this display would work so well with native 6502 parallel bus... And it would be much faster than bit-banging with VIA.
"Why not connect it to 6502 directly then?" - well, I run @ 8 MHz, and T6963C is said to work properly at <4 MHz. So let's underclock the bus then!
I spend a fair amount of time trying to get this working with D flip-flops, however most of components are hard to find over the weekend, so I tried simulating them. Eventually I remembered I still have several GAL20V8B around.
Here's my idea:
- GAL20V8 operating in registered mode, master clock (16 MHz, comes directly from oscillator) drives GAL's CLK line, GAL is permanently enabled.
- GAL controls PHO ("Phase Out") output as register, which goes to 6502's PHI2.
- If /SLOW is asserted, GAL serves as 3-bit counter and flips PHO on overflow:
f(PHO) = f(CLK) / 16 = 1 MHz
- Otherwise, GAL flips PHO every cycle:
f(PHO) = f(CLK) / 2 = 8 MHz
Code:
GAL20V8
Slowbus
CLK NC /SLOW NC NC NC NC NC NC NC NC GND
/OE NC PHO Q2 Q1 Q0 NC NC NC NC NC VCC
; If /SLOW is asserted, this works as 3-bit counter: [PHO (MSB), Q1, Q0]
; Q0 (LSB)
Q0.R = SLOW * /Q0
; Q1
Q1.R = SLOW * /Q1 * Q0 + SLOW * Q1 * /Q0
; Q2 (used for debugging only)
Q2.R = SLOW * /Q2 * Q1 * Q0 + SLOW * Q2 * /Q1 + SLOW * Q2 * /Q0
; Output clock
PHO.R =
; Fast mode, f(PHO) = f(CLK) / 2
/SLOW * /PHO
; Slow mode (3-bit ocunter, PHO as Q2), f(PHO) = f(CLK) / 16
+ SLOW * /PHO * Q1 * Q0
+ SLOW * PHO * /Q1
+ SLOW * PHO * /Q0
DESCRIPTION
PHO = CLK / 16 if /SLOW is asserted or CLK / 2 otherwise
Simulated timing diagram:
Attachment:
slowbus_diagram.png [ 43.64 KiB | Viewed 1168 times ]
Test program:
Code:
main:
nop
nop
stz $D200 ; Write to I/O region, $D200-$D2FF mapped via '138 to /SLOW
jmp main
Schematic (I used GAL16V8 for presentation purpose since my Kicad doesn't have GAL20V8):
Attachment:
slowbus_schematic.png [ 30.57 KiB | Viewed 1168 times ]
Actual test:
Attachment:
slowbus_real.png [ 12.39 KiB | Viewed 1168 times ]
Surprisingly, this worked really well. Obviously, PHO will go to 6502 only: VIA will still use CLK/2 (probably divided through GAL as well in order to avoid clock skew between 6502 & VIA and ensure matching clock edges).
EDIT: I think that with enough tinkering it would be possible to use the same GAL for Clock Domain Crossing (if that's the correct term) to communicate with SID (which always has to run on 1 MHz).
EDIT 2: Clock speed is addicting... I used to run my SBC @ 1 MHz for some time and it felt great, but once I went to 8 MHz - the former feels so slow! Especially with LCD redraws & lots of I2C/SPI bit-banging. But I feel like 8 MHz is the best of both worlds for me: fast enough to feel good, and slow enough to still be analyzable, compatible with most components, and also relieving me from thinking about all the timings of my daisy-chained 7400 glue logic & ROM/RAM timings.
_________________
/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