2

I´m planning to build a small computer system, based on the W65C02 from Western Design Center. This computer system should also have a VGA interface with a graphic and a text mode, defined with the following parameters:

  • 640x480 pixel
  • 25.175 MHz
  • Color mode: 8x8 pixel blocks with one color each (so the whole image fit in 8K RAM)
  • Text mode: ASCII character set

But I´m struggling with the video memory. Please take a look at my schematic (without the text mode).

enter image description here

I don´t know how I should realize the CPU interface for the video RAM. One idea was to use double buffering, so the VGA controller uses another memory than the CPU or is it enough to only write to the memory when a blank phase is active. This would result in 639 pauses with 6,3 µs each and one pause with 1,4 ms per frame (the CPU should run with a clock of 1 MHz).

The next thing is: How do I implement the text mode. My first idea is to use the video data as an address for a character EEPROM (some small EEPROM containing the ASCII character set) and the pixel address bits 0 to 2 for the pixel of the character, stored in the EEPROM. But the EEPROM has an access time of 70 ns. Is this enough? Assuming that I use the textmode and the pixel address is 0, so the first pixel of the EEPROM will be read 70 ns later and then the pixel address is 1. So I have some delay. Is this assumption wrong? How was the text mode in some older PC systems realized?

  • 5
    There is a YouTube vlogger named Ben Eater with an absolutely excellent channel discussing digital design that even I can understand. :-) He recently did a two part video on building the worlds 'worst' video card (his words, not mine), which you might find useful. After walking thru timing and support circuitry, he ultimately pulls his video from a static EEPROM - but I suspect there is a lot of useful information along the way that might help you in your design. Part One is here: youtu.be/l7rce6IQDWs - followed by Part Two here: youtu.be/uqY3FMuMuRo – Geo... Oct 13 '19 at 10:52
  • 1
    Thank you, but I already know these videos :) These videos give me the first impressions how to do it. – Kampi Oct 13 '19 at 13:01
  • So you are planning a low-res graphic mode of 80x60 pixels plus a high-res text mode? Why don't you use block graphic chars then? – Janka Oct 13 '19 at 22:06
  • Honest, as this is a one-off, try to salvage an EF9365 – Janka Oct 13 '19 at 22:11
  • I want use block graphic chars which are stored in an EEPROM. In text mode the content of the display RAM should be interpreted as ASCII character and so the data should be used as address for the EEPROM. In graphic mode the data from the display RAM gets interpreted as RGB data byte for a color cell with a size of 8x8 pixel (like in the C64). – Kampi Oct 14 '19 at 6:01
2

(Preface, this is RC.SE, not EE.SE, so less appropriate for such questions - so I wont go into schematic details)

a) Video RAM Access

As usual there are many ways. The most common are synchronizing CPU speed and video to use 'the' other half. Or separate both RAMs and access only during pause. Or use a dedicated video chip already offering separation.

- Synchronized Memory

Eventually the most common in way used in 6502 systems - at least by number of sold units since every Apple II or Commodore does it. After all, a 1 MHz 6502 needs 2 MHz memory to function, but uses only every second 'slot' for access - leaving half the bandwith for some other device. In this case Video. To build it, a bunch of muxes are needed to access RAM from either (video, CPU) side. While it seams to offer simple access, it does have several disadvantages

  • Grabbing memory from already limited address space

  • Grabbing quite a lot for higher resolutions

  • CPU clock must be in sync with video clock, resulting in rather strange CPU-Speeds (*1)

For a new system I'd rather not go that way. It got way to harsh limitations.

- Separate Memory

This needs about the same set of muxes, but now not handled directly by the CPU, but via a few latches. While adding a tiny overhead in writing to RAM, it simplifies not only design and removes most of the obstacles from synchronized memory but as well

  • Speed of CPU can be set independent of Video and vice versa

  • Frees up lots of rare CPU address space as only 3-4 memory locations are needed within CPU address space, leaving all the 'rest' for program and data

  • Access latches can be organized independent of memory structure, offering a application centric view of like Rows and columns in separate registers

The last one will considerable simplify low level programming, more than offseting the added instructions to set registers, as now conversion between row/column and memory address is done in hardware.

- Use Of a Dedicated Chip

Add a 9928 or 9950, have it do all the video mode, RAM and whatsoever handling and concentrate on video output circuitry.

b) Character ROM access time

Well, it depends on all the timing you want to have. You got to do the math yourself, figuring out how it fits - after all, that's the most basic task here. If you're doing something like classic home computers, it'll be more than enough. Then again, doing it at 100 Hz and high resolution you may want to rethink the whole concept


Why a text mode at all?

Text modes are a classic way to save on RAM need for image storage. Quite handy back when each KiB counted, and large flat bitmaps were a high end luxury. But here you got high resolution bitmap, so why bothering with a text mode at all, complicating the design? Draw them, like next to any computer does nowadays. It'll be just 8 bytes instead of 1, done at quite low level, so not much slow down either. Especially when using separate memory (*2). Offering much freedom in character design and combination of graphics and text as well. There's a reason the very first Mac got bitmap (*3).


*1 - Think the odd speeds of various Commodores, making them run as well at different speeds depending on video standard, creating hurdles for timing dependant software. Or the variable clock length of an Apple II.

*2 - With readable latches a simple INC ROW will do all necessary address handling.

*3 - And as well why the planned 6809 got replaced by a 68k - having a considerable bitmap in 64 KiB address space sucks.

| improve this answer | |
2

How do I implement the text mode.

The usual method is to send the video data Byte to the 8 higher address inputs of the character ROM to select the character pattern, and the low bits of the video line counter to the low ROM address inputs (eg. A0-3 for an 8x16 font) to select the pattern row. The character ROM then outputs 8 bits which are latched and serialized to pixels via a parallel to serial shift register. Since the ROM is only read once at the start of each character row, the access time just has to be less than 8 pixels.

But will 70nS be fast enough for VGA? At 25.175MHz and 640 pixels (80 characters per line) the pixel width is 39.7ns. Multiplied by 8 pixels per character gives you ~310ns for ROM access - plenty enough.

If you want individually colored characters then you also need color attributes stored in another area of video RAM (which could be a small separate RAM chip eg. 2kx8 for 80x25 characters). This is read at the same time as the character ROM, and its output latched while the row pixels are being sent. The upper and lower nibbles of the latched attribute Byte are fed into a 4 bit 2-1 mux switched by the pixel bit to color each pixel. The 4 bit output is then converted to analog to produce 16 foreground and 16 background colors.

| improve this answer | |
-1

I've been musing about stuff like this here: Thinking through the design of a TTL video card: what memory chips and how to manage memory? and the people didn't like it. I never get the value of shutting down explorative discussions. Ah well.

I think you need to consider the clock speed your system will run on. If you go for 640x480 you clock at 25.175 MHz as you said, and that isn't a speed that the 6502 is normally run on, the W65C02S can do 14 MHz.

If you really want to run the CPU in 1 MHz, your video circuit should make the clock signal for the CPU and give it whatever is left over. But I figure if you want raster line interrupts and light pen strobe interrupts, you want to do better than run the CPU in the video blank phases.

I think the constraints and math goes like this: your video card sets the beat, since it cannot wait and keep in sync. So the video card in any way generates the clock for the CPU. That's settled.

The video card needs a lot of bandwidth from RAM. In monochrome mode that would be access for one byte every 8 pixels. 3.14 MHz, 318 ns. Double that for CPU to get in on the interleaved cycles and you will need 150 ns RAM. That is what I have read these DRAMS could do squeezing the refresh in as well. I could be wrong on the exact numbers.

For a 4 color palette mode with palette changeable for each 8x8 pixel block (e.g. C64 VIC-II style) you need 2 bits per pixel, so your run on the RAM doubles down. This is why the C64 could not do more than 320x200.

If you wanted to run everything at full blast in 25.175 MHz with one byte per pixel, and the CPU in interleaving cycles, you would need the RAM to squeeze into 19 ns cycles. Is there any SRAM chip that can do that? I doubt it.

I have my eyes on the HM628512P-5 with 512k x 8bit at 55 ns access time. No way to come even close!

This is where my thinking has moved to use dedicated video memory and do it in parallel. My favorite would be a 1Mx4 bit chip, and I would use 3 in parallel for a 12 bit color space. But even then, at 640x480 I would need it to respond in 39.8 ns. Which is still too fast! So perhaps a 1M x 1 bit organization and I would use 9 in parallel to have 3 bits for each color channel, MCM6227 or CY7C107D perhaps? That CY can do 10 ns. With that we could even do wider. But I would really like to stick to DIP packages, not surface mount.

What I would like is an exhaustive list of all SRAMs that are still available that are DIP packages and I would find my size and speed.

As for all those other "modes" they are just variations on the theme how you end up with your RGB values to send to the monitor. If you get one byte for an 80 character wide text mode display, your memory bandwidth goes down to 39.25 kHz. The bits you get from the CHAR-ROM, and then the bits to pixels using whatever color palettes from RAM or internal registers.

Now have you thought about the design of your sprite overlays already? With mask (alpha channel?) and pixels? I have, would need an adder to add the offset and then for each sprite read the memory or internal registers for XOR mask OR pixels on the fly to determine the final RGB value. This lead me to really appreciate what the VIC-II was all doing at the same time, and makes me think even more about having separate video RAM instead of using the regular CPU's memory.

By the way, did you think about how to interface the video RAM with the CPU? I would hate to write through a little port setting pixel address and pixel value one by one. I am thinking of mapping the VRAM into the CPU's address space, write to it, and then un-map it to continue working with the normal RAM underneath.

And to complete the brainstorming here, in my hunt for RAM chips, I also saw dual-port RAM. They went up to 8k x 8bit, and have two sets of separate A and D pins. I don't remember the speed.

| improve this answer | |
  • I interpret the reference to 8x8 pixel blocks as saying that the output dot clock would be 1/8 of the normal VGA dot clock, i.e. 3.15MHz. – supercat May 13 at 15:47
  • Having the CPU access an "outside" memory by setting an X and Y address and then feeding sequential bytes while X or Y increments or decrements is often nicer than having a memory-mapped display, especially if one can configure a region of address space so that reads will cause the value read to be sent to the display. – supercat May 13 at 20:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.