6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 4:32 am

All times are UTC




Post new topic Reply to topic  [ 3 posts ] 
Author Message
PostPosted: Sat May 06, 2023 7:43 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
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
24064.jpg [ 85.5 KiB | Viewed 1176 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
slowbus_diagram.png [ 43.64 KiB | Viewed 1177 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
slowbus_schematic.png [ 30.57 KiB | Viewed 1177 times ]


Actual test:

Attachment:
slowbus_real.png
slowbus_real.png [ 12.39 KiB | Viewed 1177 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


Last edited by and3rson on Wed May 10, 2023 6:32 pm, edited 3 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat May 06, 2023 8:28 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
One caution with using the output of a GAL to drive the Ø2 inputs of the 65C02/65C816/65C22, etc., is a GAL’s output levels are TTL, not CMOS. According to the WDC data sheets, clock inputs are supposed to swing at CMOS levels, and should have a rise/fall time no greater than 5ns. While the GAL’s outputs will easily meet the 5ns requirement, it is questionable as to whether they will reach what constitutes a valid CMOS logic 1 when high.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
PostPosted: Sun May 07, 2023 2:28 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
BigDumbDinosaur wrote:
One caution with using the output of a GAL to drive the Ø2 inputs of the 65C02/65C816/65C22, etc., is a GAL’s output levels are TTL, not CMOS. According to the WDC data sheets, clock inputs are supposed to swing at CMOS levels, and should have a rise/fall time no greater than 5ns. While the GAL’s outputs will easily meet the 5ns requirement, it is questionable as to whether they will reach what constitutes a valid CMOS logic 1 when high.


I did not think about this! Thanks for pointing that out. I might add a TTL-CMOS level converter in my next build for this. Would a Schmitt trigger be sufficient for this or is something more complex required?

Meanwhile, my 6502/6522/T6963C/GAL are doing really well together: I was able to load & run a program from uSD card (through VIA) which properly initialized my 24064 display (underclocked with GAL):

Attachment:
IMG_20230507_172834_988.jpg
IMG_20230507_172834_988.jpg [ 173.72 KiB | Viewed 1115 times ]

(Might be hard to notice "Hello" in the top-left corner since I forgot to clear screen VRAM beforehand.)

This display can draw up to 48 cols x 8 rows (with 5x8 font). Plenty of space for my needs, and those 4 extra rows are exactly what I was missing with my 4004 LCD.

_________________
/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


Top
 Profile  
Reply with quote  
PostPosted: Sun May 07, 2023 3:54 pm 
Offline

Joined: Fri Dec 21, 2018 1:05 am
Posts: 1120
Location: Albuquerque NM USA
Gal22V10 datasheet shows Voh vs Ioh curve. You can see at output current of 2-3mA, the output voltage will reach 3.5V. So you should be able to drive W65C02 clock if GAL output is not loaded.
Bill


Top
 Profile  
Reply with quote  
PostPosted: Wed May 10, 2023 6:20 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
So Lattice's GAL20V8 worked with my SBC, however it was failing test vectors with my TL866-II unless I set test levels to 3.3V instead of 5V. :) Seems like TL866 probably latches asserted pins too fast, before the levels rise to CMOS level due to higher input capacitance (if I understand electronics, which I sometimes feel like I don't.)

I've decided to switch to ATF PLDs for several reasons:
- They are TTL/CMOS compatible;
- They are still made.

I've ordered a bunch from Mouser, 8 outputs feels enough for my purposes, including address decoding & R/W qualification:

Attachment:
gal_slowbus_addr_rw.png
gal_slowbus_addr_rw.png [ 36.19 KiB | Viewed 1017 times ]


Code:
GAL16V8
Addr

CLK  /SLOW /RST   A15   A14   A13   A12   RW    NC    GND
/OE   PHV   Q2    Q1    PHI2 /WD   /RD   /ROM  /IO    VCC

;;;;;;;;;;;;;;;;;;;;;;;;
; Address decoder, bus underclocking, R/W qualifier
; If /SLOW is asserted, this works as 3-bit counter: [PHV (MSB), Q1, PHI2 (LSB)]
;


;;;;;;;;;;;;;;;;;;;;;;;;
; Bus underclocking
;
PHI2.R = /RST  * /PHI2

Q1.R =   /RST  *  SLOW  * /Q1  *  PHI2
       + /RST  *  SLOW  *  Q1  * /PHI2

Q2.R =   /RST  *  SLOW  * /Q2  *  Q1 * PHI2
       + /RST  *  SLOW  *  Q2  * /Q1
       + /RST  *  SLOW  *  Q2  * /PHI2

PHV =
    ; Fast mode (PHV=Q0)
         /SLOW  *  PHI2
    ; Slow mode (PHV=Q2)
       +  SLOW  *  Q2

; PHI2 =     Q0


;;;;;;;;;;;;;;;;;;;;;;;;
; R/W qualifier
;
WD =      PHV  * /RW
RD =      PHV  *  RW


;;;;;;;;;;;;;;;;;;;;;;;;
; Address decoder
;
; RAM =    /A15
ROM =     A15  * /A14  +  A15  *  A14  *  A13
IO =      A15  *  A14  * /A13  *  A12

DESCRIPTION
PHV = CLK / 16 if /SLOW is asserted or CLK / 2 otherwise
PHI2 = CLK / 2


RAM/EN is not managed by GAL, since it's simply tied to RAM's A15 ($0000-$7FFF), and I still use '138 for 8x256B I/O segments.

I also found this nice utility that can convert to and from .lgc format and a more human-readable .toml - https://github.com/evolutional/xgpro-logic - and made some tests to make sure my PLD behaves as expected:

Code:
[[ics]]
# Test vectors for GAL20V8 since I don't have GAL16V8 on me yet.
name = "SlowBus-GAL20V8"
pins = 24
vcc = 3.3
vectors = [
    #  __        _     ____
    #  SR5432R   O V21ФWRRI

    # Reset
   "CX10XXXXXXXG1XLZZZHHXXXV",

    # Slow bus
    # Fast mode
   "CX11XXXXXXXG0XHLLHXXXXXV",
   "CX11XXXXXXXG0XLLLLXXXXXV",
    # Slow mode
   "CX01XXXXXXXG0XLLLHXXXXXV",
   "CX01XXXXXXXG0XLLHLXXXXXV",
   "CX01XXXXXXXG0XLLHHXXXXXV",
   "CX01XXXXXXXG0XHHLLXXXXXV",
   "CX01XXXXXXXG0XHHLHXXXXXV",
   "CX01XXXXXXXG0XHHHLXXXXXV",
   "CX01XXXXXXXG0XHHHHXXXXXV",
   "CX01XXXXXXXG0XLLLLXXXXXV",
    # Fast mode (again)
   "CX11XXXXXXXG0XHLLHXXXXXV",
   "CX11XXXXXXXG0XLLLLXXXXXV",

    # Read/write qualifier
    # /WD + /RD when Ф2=0
   "0X11XXXX0XXG0XLLLLHHXXXV",
   "0X11XXXX1XXG0XLLLLHHXXXV",
    # /WD + /RD when Ф2=1
   "CX11XXXX0XXG0XHLLHLHXXXV",
   "0X11XXXX1XXG0XHLLHHLXXXV",
    # /WD + /RD when Ф2=0 (again)
   "CX11XXXX1XXG0XLLLLHHXXXV",

    # Address decoder
    # /RAM enable ($0000-$7FFF)
   "0X110000XXXG0XXXXXXXHHXV",
   "0X110001XXXG0XXXXXXXHHXV",
   "0X110010XXXG0XXXXXXXHHXV",
   "0X110011XXXG0XXXXXXXHHXV",
   "0X110100XXXG0XXXXXXXHHXV",
   "0X110101XXXG0XXXXXXXHHXV",
   "0X110110XXXG0XXXXXXXHHXV",
   "0X110111XXXG0XXXXXXXHHXV",
    # /ROM enable ($8000-$BFFF, 16K LOROM)
   "0X111000XXXG0XXXXXXXLHXV",
   "0X111001XXXG0XXXXXXXLHXV",
   "0X111010XXXG0XXXXXXXLHXV",
   "0X111011XXXG0XXXXXXXLHXV",
    # Unused ($C000-$CFFF)
   "0X111100XXXG0XXXXXXXHHXV",
    # I/O ($D000-$DFFF)
   "0X111101XXXG0XXXXXXXHLXV",
    # /ROM enable ($E000-$DFFF, 8K HIROM)
   "0X111110XXXG0XXXXXXXLHXV",
   "0X111111XXXG0XXXXXXXLHXV",
]


I'm running XGPro under wine with patched libusb, works great:

Attachment:
gal_test_pass.png
gal_test_pass.png [ 61.57 KiB | Viewed 1017 times ]

_________________
/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


Last edited by and3rson on Thu Jun 01, 2023 7:56 pm, edited 3 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sat May 20, 2023 10:19 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
New board - GAL + 240x64 LCD (T6963C) are doing great! Using GAL20V8 until my ATF EEPLD arrives.

I'm running master clock @ 16 MHz, CPU is clocked between 8 MHz & 2 MHz based on LCD/EN.

Also, some new fancy stuff:
  • DS1307 (I2C RTC) with CR2032 battery
  • MCP9808 (temperature sensor, mounted under the 6502 (well, it's all CMOS nowadays and things aren't getting as hot as NMOS did, but I still wanted to be able to "get CPU temperature" in a fancy way).
  • Slot for ESP8266 (ESP01) to talk to it with 6551 - I want to write a simple telnet client to be able to connect to some C64 BBS that are still running. Gonna try out something like https://github.com/dhansel/WifiModem or write my own firmware - I worked a lot with ESP8266 and really love them.

Still left one '00 for reset LED and also just in case I'll need to reroute things. Life taught me it's always good to have at least several spare NAND gates on the board which is still WIP.

1K pot for LCD contrast is definitely too low and is getting warm, will replace it with 10K.

Last but not least, it took me 16 revisions to add the damn power switch. Friggin' finally!

Attachment:
v16_gal_and_t6963c.jpg
v16_gal_and_t6963c.jpg [ 172.91 KiB | Viewed 902 times ]


And the entire thing is lass than 1" thick (excluding standoff legs):

Attachment:
v16_thicc.jpg
v16_thicc.jpg [ 119.74 KiB | Viewed 902 times ]


Perfect fit! (Well, I had to slightly bend metal legs that hold display's case & PCB together.) Clearance is ~0.4" (11 mm) - just enough to fit chips with machine-tooled sockets, as well as barrel jack.

Attachment:
v16_it_fits.jpg
v16_it_fits.jpg [ 113.27 KiB | Viewed 901 times ]


I also renamed my SBC to Deck65 - the name might imply that there should be like a dozen of stacked things, but I'm a modest person and only have 2 layers!

/Andrew

_________________
/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


Top
 Profile  
Reply with quote  
PostPosted: Thu Jun 01, 2023 6:20 pm 
Offline
User avatar

Joined: Fri Feb 17, 2023 11:59 pm
Posts: 163
Location: Lviv, Ukraine
Turns out ATF16V8 is (fully?) compatible with GAL16V8 (at least for my usecase). I was able to program it using the same .jed file that I used for my GAL16V8 (actually GAL20V8B - I simply changed pin mapping by removing 4 pins, because I don't have GAL16V8). I used galasm & minipro for programming both (using TL866-II). I expected some incompatibility, but it worked out of the box!

Also, I found it simple to temporarily use '20V8 in place of '16V8, since I don't use pins 2, 11, 13, & 23 (all of them are inputs). So I simply had to join some pins: CLK (1+2), GND (11+12), /CE (13+14), & VCC (23+24).

_________________
/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


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 66 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron