• Please review our updated Terms and Rules here

Discussion about consoles

RetroAND

Veteran Member
Joined
Feb 14, 2023
Messages
599
Location
Andorra
Hello,

Since I started studying I wanted to build an arcade machine of custom design. Still, over the years I started to covet more the smaller and cute consoles like the Famicom or the PC-Engine. However, due to my lack of knowledge that wasn't possible. Recently, I have entered to the programmable logic world with CPLDs and VHDL. I think that, with this I might be able to accomplish my goals.

There are some things that I have clearly in my mind about a possible development:
  • I would need to employ CPLDs and/or FPGAs
  • The programmable logic components would only be used as substitute of certain blocks as if they were ASICs
  • CPU, RAM, ROM and other circuitry would remain separated from the programmable components
  • CPU would be a W65C02S as I previously favored the Z80 but production has ended
  • Memory map similar to the one of the PC-Engine, with approx 2MB capacity
  • The console would have BIOS
  • Paranoic diagnostics mode
  • Standard SD cards as cartridge
  • Sega norm for controllers
  • 12-bit RGB
As I said previously, I favored the Z80 because of its bus interface and the I/O separation as well. Also, Renesas is killing the 80C88 now, so the last classic solution now is the W65C02S.

I have also a design both in hardware and in VHDL of a synthesizer, which has 8-bit volume and 5-bit sample waveforms. It is capable of 16 types of rectangular pulses, two ramps/sawtooth, triangle and two different types of noise.

With the cartridge interface I have no doubts, I would have to program a CPLD (ATF1504 minimum) to make it act as interface and DMA device to save and load data into the card.

Where I am struggling the most is with the graphics. I understand that I don't have the required tools yet to address that issue. Still, I am studying the architecture I may end using. I have three candidates so far:
  • Shared RAM for CPU-Video, DMA-request based, with programmable address (Datamaster, PC-88)
  • Shared RAM for CPU-Video, with fixed address (Commodore PET)
  • Separate RAM and VRAM (Coleco, MSX, Sega Mk.III/Master System, PC-E)
After that I understand the basic mechanics for the inner workings of one of these kind of ICs, but I would still need other kinds of help in this aspect.

I would like to hear about your opinions in this respect.

Regards,
Jaume
 
Graphic is always the most challenging aspect of the design; it requires lots of memory, fast processing, and efficient transfer of data from the processor to the graphic engine. 12-bit color is unrealistic for classic processors unless you have the help of modern co-processor.
W65C02 is a great choice for classic processor, not only because it is still in production, also because it can be overclocked to increase its performance. Clock-for-clock, 6502 is about 2-2.5X that of Z80 and W65C02 can be reliably overclocked to 25.175Mhz. At such clock frequency, CPLD is required to satisfy timing since an operation needs to be done in half of 25.175mhz, or 20nS.
Bill
 
Graphic is always the most challenging aspect of the design; it requires lots of memory, fast processing, and efficient transfer of data from the processor to the graphic engine. 12-bit color is unrealistic for classic processors unless you have the help of modern co-processor.
W65C02 is a great choice for classic processor, not only because it is still in production, also because it can be overclocked to increase its performance. Clock-for-clock, 6502 is about 2-2.5X that of Z80 and W65C02 can be reliably overclocked to 25.175Mhz. At such clock frequency, CPLD is required to satisfy timing since an operation needs to be done in half of 25.175mhz, or 20nS.
Bill
Thank you for your input.

Well, something I learned time ago is that the limit is not color width, but the amount of colors displayed per object. Two examples are the CPC+ range of computers or the Sega GameGear. Sixteen colors per object (4bpp) is fine with me, and this could be done by a FPGA mimicking some sort of VDP. But prior to that, I am more worried about the kind of interaction the device should have with the rest of the system.

Jaume
 
@Plasmo
Maybe I haven't expressed myself as clear as I wanted to. You see, I have thought many times about the Commodore PET video interface subcircuit, which can be seen at page 3 of the following document, at zimmers.net. If you look at it closely, you will only find an old, boring monochrome video interface.

Now, imagine that at J7 pin 1 the signal is hijacked and we use it in a 74LS670 as a read address. If we employ Q0-Q2 as outputs we have 8 possible colors. We can increase the depth if we add more 670s with the output in parallel. If we added 3 more we could reach 15-bit RGB. With that, we have not only given color to the PET (hypothetically speaking), but a very fine amount of them. Just that only two can be displayed at the same display due to the nature of the video subsystem. The secret to increase the number of colors is by increasing the number of address lines to that tiny color memory (CRAM). That or do like the 2600, which I won't do.

Let's leave aside the issue with the address width. Let's focus on another important part of the diagram. You see that 6540 on the right part of the sheet? Replace it with a RAM. With this we can define our own characters... but they aren't characters anymore, but tiles... because we can draw anything we wanted in those 8x8 areas. The issue with this part is coordination with the rest of the system in order to gather the required resources and also allow the CPU to write in that space.

Now let's look at the pair of 6550... that is the tile map memory. It allows us to place the tiles wherever we want. Imagine they were bigger... and that we intercepted the video addresses before the 74LS157s. If we added them with the contents of a pair of registers by employing some 74LS283 we would obtain coarse scrolling.

If the character memory was read by the video subsystem in words instead of bytes, we could get more colors per pixel. If the same condition was to happen with the map memory, the number of tiles could be much higher.

So, as you see, I have some idea of what I could do to bring color and variety of patterns into the mix. However, what I want to learn by this debate is to know what would be the best way to interact with the VRAM or the whole RAM, and of course the microprocessor.

Greetings,
Jaume
 
Last edited:
Some 6502-based systems (eg. Apple) had video hardware which accessed memory during the clock phase opposite where CPU accesses happen. So CPU and video have the same memory bandwidth without contention between the two. Speeds were limited with contemporary memory, but with '90s era SRAM perhaps you could make this work at 10MHz+

Another thing to consider is that CPU and video clocks were often directly related to the number pixels or characters displayed on the screen. For instance, the PC-Engine video memory bus usually runs at 5.37MHz, producing 256 pixels / 32 characters horizontally with one clock per pixel. (Other configurations are also possible on PCE.) The PCE has 16-bit memory for video, so for every character width (8 pixels) it needs to fetch one word from the map, and two words of character data (4 bits * 8 pixels), leaving plenty of bandwidth left over during the active display. (During H-blank it fetches sprite data.) For a different example, Amiga has video hardware and a 68000 sharing the same (chipmem) bus, where one 16-bit word can be fetched every two 7MHz clocks. With 640 pixels (14MHz pixel clock) it can show 4 bits per pixel, but this blocks access by the CPU, slowing it down considerably.
 
@bakemono
So, I understand that, unless both devices are clocked at the same frequency, things are prone to go wrong if sharing the same memory. Is this correct?

Then the correct approach would be to separate the VRAM from the main memory, even if this complicates the design... This also has the drawback that the video device becomes a bottleneck when having accesses. I will seriously consider it.

Thank you
 
@bakemono
So, I understand that, unless both devices are clocked at the same frequency, things are prone to go wrong if sharing the same memory. Is this correct?
There are exceptions, but I would say that's true in general, yes.
Then the correct approach would be to separate the VRAM from the main memory, even if this complicates the design
Keeping them separate is likely easier to design but harder to build. You'll have more chips on the board, but fewer concerns with how they interface.
 
Keeping them separate is likely easier to design but harder to build. You'll have more chips on the board, but fewer concerns with how they interface.
Thank you again.

I will have this in account. After all, even if it means more components it also means more design freedom.
 
Let's leave aside the issue with the address width. Let's focus on another important part of the diagram. You see that 6540 on the right part of the sheet? Replace it with a RAM. With this we can define our own characters... but they aren't characters anymore, but tiles... because we can draw anything we wanted in those 8x8 areas. The issue with this part is coordination with the rest of the system in order to gather the required resources and also allow the CPU to write in that space.

If you're up for a boring badly-produced Youtube video I built a prototype of a shared video memory system a few years ago that demonstrates shared memory with user-definable tiles combined with a 6502 CPU, that conceptually can be thought of an evolution of a PET-style video card. An "innovative" aspect of the design is it allows the "tiles" to be of arbitrary height; they're limited to 8 monochrome pixels wide in this prototype, but by changing the pixel generation hardware you could do whatever you want.

(* The system already allows the characters/tiles to be either 6 or 8 pixels wide, that could be made arbitrary, although the microcontroller I'm using for a CRTC does set a *minimum* limit of 6 bits wide because it takes that many clock ticks to add an 8 bit number to a 16 bit number for the next memory fetch.)

The TL;DR with this system is the CRTC address is used to fetch a byte from the "framebuffer" (tile array, character buffer, whatever you want to call it), and that byte is added to an 8 bit offset to the 256 byte wide table that holds the bit patterns for that line of the currently selected tile/font, which is used as the address for a second memory fetch that loads the output shift register. All of this memory is shared with a 6502 CPU, but the video fetches all happen on the off side of the cycle per the usual so there's no memory contention. The "character rate" of the system is only 1/6th or 1/8th of the pixel clock (which is what the memory is effectively clocked at), so if you want to elaborate this by, say, adding additional cycles where you fetch attribute bytes, the only limit is that you have to complete however many fetches you need before it's time to start the cycle over again. You also need RAM that's able to keep pace with this, of course, but this isn't a problem; SRAM with access times under 20ns is readily available. If the target for your game console is an old-tyme resolution like 320x240 a pixel is around 125ns and a full 8-bit character is a microsecond. You could get even more bandwidth out of this system by fetching 16 or more bits at a time; the only cost is you need to double the size of the intermediate buffers.

... anyway, back to the point. If you watch the video/pause it and look at my diagrams essentially the only cost to turn a hardcoded "fetch and shove it through a dedicated character generator ROM" system into one that allows arbitrary user-defined tiles stored in the same shared memory is an 8-bit buffer to latch the framebuffer value in so a separate RAM fetch can be made for the glyph. Again, just by adding some additional buffers you could add a third fetch that would get an attribute byte... and if you wanted more than 256 possible tiles you could even make bits in that attribute byte contribute to the address offset, allowing you to mix multiple tile sets on the same line. If the pixel output chain includes a DAC you could have an attribute fetch that references a specific palette set... again, the real limit is just how many buffers you need to fill in each tile window. (Note that you'll probably need an A/B set of buffers for things like attributes; my system uses the latch inside the shift register to output its mono pixels, but something like a color map is going to need to be held static for the whole pixel period and atomically loaded at the start of the next pixel from the latches that are filled by the actual memory operations.)

FWIW, my prototype allows full-screen vertical and horizontal scrolling (including treating the active area on the screen as a window to a larger "virtual" tile space) in tile-size increments, but that's all in the CRTC's ballpark. (For now all the demonstrations I've done of this are hardcoded into the CRTC's internal code, I've come up with ideas for allowing the CRTC to read a "register file" stored at an arbitrary place in RAM during the vertical refresh interval, but I haven't had time to seriously work on this or evolve it in literal years.) I'm going to guess you *don't* want to use an Atmel CPU as a CRT like I did, you want to implement the functionality inside of your CPLD/FPGA, but that shouldn't be a huge deal. I just use cycle-counting code of the Atmel because I wanted to build something out of breadboardable/through-hole parts, which effectively limits programmable logic to GALs. (You could build a programmable CRTC out of GALs, counters, and latches, but it'd be a lot of parts.) Strictly speaking my system actually allows single-line granularity for scrolling in the vertical direction already, if you wanted single-pixel horizontal resolution (that wouldn't jibber the borders around, mine *could* do it with that) you could tack on a masking system that would allow that as well, although I'm not really sure it would be worth it unless your tiles were very wide.

Obviously the thing this entirely lacks is sprites. Tile graphics like this are good for backgrounds, but if you want to move large objects around onscreen with pixel-level granularity you're probably going to want to either:

A: layer something else on top of a tile system, or
B: maybe think of using a more straightforward bitmap system combined with blitters.
 
Last edited:
If you're up for a boring badly-produced Youtube video I built a prototype of a shared video memory system a few years ago that demonstrates shared memory with user-definable tiles combined with a 6502 CPU, that conceptually can be thought of an evolution of a PET-style video card. An "innovative" aspect of the design is it allows the "tiles" to be of arbitrary height; they're limited to 8 monochrome pixels wide in this prototype, but by changing the pixel generation hardware you could do whatever you want.

(* The system already allows the characters/tiles to be either 6 or 8 pixels wide, that could be made arbitrary, although the microcontroller I'm using for a CRTC does set a *minimum* limit of 6 bits wide because it takes that many clock ticks to add an 8 bit number to a 16 bit number for the next memory fetch.)

The TL;DR with this system is the CRTC address is used to fetch a byte from the "framebuffer" (tile array, character buffer, whatever you want to call it), and that byte is added to an 8 bit offset to the 256 byte wide table that holds the bit patterns for that line of the currently selected tile/font, which is used as the address for a second memory fetch that loads the output shift register. All of this memory is shared with a 6502 CPU, but the video fetches all happen on the off side of the cycle per the usual so there's no memory contention. The "character rate" of the system is only 1/6th or 1/8th of the pixel clock (which is what the memory is effectively clocked at), so if you want to elaborate this by, say, adding additional cycles where you fetch attribute bytes, the only limit is that you have to complete however many fetches you need before it's time to start the cycle over again. You also need RAM that's able to keep pace with this, of course, but this isn't a problem; SRAM with access times under 20ns is readily available. If the target for your game console is an old-tyme resolution like 320x240 a pixel is around 125ns and a full 8-bit character is a microsecond. You could get even more bandwidth out of this system by fetching 16 or more bits at a time; the only cost is you need to double the size of the intermediate buffers.

... anyway, back to the point. If you watch the video/pause it and look at my diagrams essentially the only cost to turn a hardcoded "fetch and shove it through a dedicated character generator ROM" system into one that allows arbitrary user-defined tiles stored in the same shared memory is an 8-bit buffer to latch the framebuffer value in so a separate RAM fetch can be made for the glyph. Again, just by adding some additional buffers you could add a third fetch that would get an attribute byte... and if you wanted more than 256 possible tiles you could even make bits in that attribute byte contribute to the address offset, allowing you to mix multiple tile sets on the same line. If the pixel output chain includes a DAC you could have an attribute fetch that references a specific palette set... again, the real limit is just how many buffers you need to fill in each tile window. (Note that you'll probably need an A/B set of buffers for things like attributes; my system uses the latch inside the shift register to output its mono pixels, but something like a color map is going to need to be held static for the whole pixel period and atomically loaded at the start of the next pixel from the latches that are filled by the actual memory operations.)

FWIW, my prototype allows full-screen vertical and horizontal scrolling (including treating the active area on the screen as a window to a larger "virtual" tile space) in tile-size increments, but that's all in the CRTC's ballpark. (For now all the demonstrations I've done of this are hardcoded into the CRTC's internal code, I've come up with ideas for allowing the CRTC to read a "register file" stored at an arbitrary place in RAM during the vertical refresh interval, but I haven't had time to seriously work on this or evolve it in literal years.) I'm going to guess you *don't* want to use an Atmel CPU as a CRT like I did, you want to implement the functionality inside of your CPLD/FPGA, but that shouldn't be a huge deal. I just use cycle-counting code of the Atmel because I wanted to build something out of breadboardable/through-hole parts, which effectively limits programmable logic to GALs. (You could build a programmable CRTC out of GALs, counters, and latches, but it'd be a lot of parts.)

Obviously the thing this entirely lacks is sprites. Tile graphics like this are good for backgrounds, but if you want to move large objects around onscreen with pixel-level granularity you're probably going to want to either:

A: layer something else on top of a tile system, or
B: maybe think of using a more straightforward bitmap system combined with blitters.
Thank you very much.

It's late in my zone, but I will watch tomorrow. It sounds pretty interesting.
 
It's late in my zone, but I will watch tomorrow. It sounds pretty interesting.

If I get around to implementing the ability for the MCU that's acting as the CRTC to be programmed by the CPU by treating an area of RAM like a register file one thing that would be very possible with this system is displaying different video modes on a per-scanline basis, selectively scrolling just a region of the screen, etc; basically it would be pretty easy to give it capabilities vaguely similar to the ANTIC display list processor in the Atari 800 computers. But, again, if you want actual hardware sprites that's a whole other can of worms.

(To put it another way, I guess, this is closer to the VIC-I in the VIC-20 than the VIC-II in the C64.)
 
I always thought that sprites have a similarity with the cursor

Sure, there's a... continuum, between a sprite and a cursor, but obviously a gaming sprite is *much* more complex.

Remember of course that many small personal computers (including the Commodore PET) don't have hardware cursors at all; they just use software to blink or set a reverse video attribute at the memory location the cursor is defined at. (Even the PETs that have 6845 CRTCs, which support a hardware cursor, don't use it; you can set the register in the CRTC but the output isn't hooked to anything.) The next step up is something like the 6845 supports, which is just a register that's set with a memory location in the frame buffer; when the CRTC's address counter matches that value there's an output set, and the actual pixel output circuitry can do whatever it wants with that information. (render an underline, set reverse video, whatever.) This is *basically* like a sprite, except a sprite A: usually is wider than a single tile, B: can be set on pixel boundaries, not tile boundaries, both horizontally and vertically, C: could potentially overlap with other sprites, and D: may support things like transparency, where parts of the background or lower sprites can show through. All of this means you need to have higher resolution position matching, the ability to match multiple positions, possibly some collision detection logic, and the pixel rendering chain is going to have to be able to do the memory fetches for both the background bitmap/tilemap and the bitmaps for the sprites themselves.

Anyway, this is why it's not generally considered feasible to do hardware sprites with discrete TTL chips; the equivalent to even a relatively simple sprite processor like a VIC-II is going to be several PCB's worth of latches, counters, comparitors, etc.(*)

Hardware sprites started falling out of favor by the mid-80's in preference of things like blitters that allow unattended copying of arbitrary hunks of "sprite data" directly into a bitmap display... although I suppose you could argue that the support modern video cards have for arbitrarily sized textures and hardware compositing of multiple layers is effectively sprites on steroids.

(*Edit: FWIW, it was pretty common for otherwise completely dumb graphic frame buffers in 80's/early 90's era "workstation class" computers to have a *single* modestly-sized graphical sprite with transparency support to use for the mouse cursor, because doing *one* with TTL hardware or PALs isn't too much of a stretch. There's an anecdote, I think it's on folklore.org, relating how Bill Gates was surprised how the Macintosh drew its mouse arrow in software instead of having one.)
 
Last edited:
Back
Top