Would it be difficult to have a user-defined palette for when the bits-per-pixel is low? I remember on the Amiga that even 4-bpp could look pretty decent for games when referencing 12-bit colors.
Yes, it is tricky to do that while still allowing the cpu to update it. Normally it's only necessary for the video circuit to access the RAM once every few pixels - in my case it's 4 - which allows the CPU to write to the RAM in the gaps. But the palette generally needs to be read on every pixel, at 25MHz (or 36MHz in my case now). You need very fast RAM to support that, ideally dual-port RAM. It may be possible to somehow fetch all the data for all 4 pixels in one go - but that's then quite wide, it would need several separate RAM chips to get enough output bits. It's possible though.
I hadn't thought of it like that, thanks for taking the time to think about it. I was (probably naively) thinking that the bitmap ram could continue to have the same cpu interface and timings, but there could be a level of indirection on the readout (which might not need to involve the cpu but would incur some timing implications anyway). I've never built anything nearly so complex as a video card, though. Thanks again, and geek on!
@@AppliedCryogenics The way I see it, the main limitation is bandwidth from whatever RAM is involved last of all. We can increase the bandwidth by using faster RAM or more RAM in parallel (like I do for the framebuffer, getting 16 bits from two ICs at the start of each 4 pixel cycle). So for a palette, maybe two ICs could be inserted before the shift registers to provide four bits each of red, green, blue, and intensity, to represent the RGBI values for each of the four pixels. It could be a nice system and still allow time for the CPU to update the palette in between these accesses. Alternatively, a fast enough RAM IC can be used after the shift registers, but not interleaving palette writes - hold them up until the end of each scanline, when the palette RAM doesn't need to be driving the display output. Then the cpu can write it as much as it likes. I had some crazy thoughts about how we could use the overscan in the framebuffer to provide updated palette data here and reduce wiring. It's a bit half-baked though and I need to make a more stable foundation at this point before doing that kind of thing!
Yes I think the next step is probably to go back to the design stage. I've been umming and ahhing a lot, there are many places different choices could be made and it could be interesting to talk through them.
Great video, I've just ordered the PCB's of my own card based on Slu4's version, but using a GAL for the H / V detection and counter resets, as well as a character ROM and a colour RAM. My daughter wants me to write that is has a picture of an axolotl on it as well. I ended up going with a bunch of d-latches for latching in the X, Y, Colour and character, that's on decoded from a 138. It all *SEEMS* to work, and gives me a character display that's similar to the C64 but with 8 bit colours. I got the whole down to 17 chips in the end, so I'm *fairly* happy with that. I could use another GAL and probably knock it down to 13, but life is short. I'm excited to see where you take this if you go back to first principals.
Once again impressed you managed to get something useful out of a 36MHz signal on a breadboard. You might be radiating some RF there. I'm going to try for 640x480 using a 6845 when I get my hands on a few - it might be overclocking it a bit but it's probably going to work. For a start it'll be monochrome like my existing circuit but I like the idea of replacing 5 IC's with a 6845 - then I can use the extra space for color. And then just maybe I can use that as a basis for an 8 bit ISA card for IBM PC & XT.
Sounds interesting. I think the 6845 may be OK depending what horizontal speed it supports. 8 pixels of VGA requires about pi MHz, funnily enough. I think typical systems in the early 80s when the 6845 was common probably used a 1 or 2 MHz clock, but they were standard definition, so had about half the horizontal refresh rate, much more time to play with
I think it would be interesting to see a system designed to be modular, with different outputs for digital, VGA, etc. A design that went from a very wide data bus (even 64 bits? Or more?) down to the normal width to reduce the circuitry needing high-speed capabilities would also be interesting.
I have thought about a modular design where image generation layers can be added or removed in a stack. So the core generates the sync signals, then you can add a background layer with bitmaps graphics, then maybe some sprite layers on top, and a text layer above everything. Or interchange any of the layers if you like. It could be interesting to build that way.
Your setup is very interesting and a nice proof of concept. My personal thoughts are that 800x600 is just a tad too big for any meaningful realtime graphics on a 8 bit computer. Having a crisp text mode is nice but the TTL logic seems to be near its limits. Using off-the-shelf TTL chips is very future proof and should allow the design to be used for years to come. Getting a simple design onto a PCB with surface mount components (where it is possible) has a lot of potential. Limiting the feature set to the minimum for acceptable graphics and text might be the way to go. In my opinion, limiting oneself to a certain spec and trying to get the most out of it is a more interesting way to design and build retro hardware. The specs should follow limits of the chosen hardware. Setting boundaries can be hard when you have FPGAs, modern design tools and cheap MCUs on your hands. The limit of using TTL chips only should be a natural barrier for feature creep ;-) ---- I always liked the ATARI monochrome 640x400 video mode (with is sub-modes) for its effective usage of a 32K memory space. Expanding that to 64K with 4 colors or 96K with 8 colors might be usable as well but bank switching several times for a single screen will be a big hurdle. A 8MHz 6502 might be fast enough to display 640x400 uncompressed 4bit color FMV at 15Hz but having several sub-modes is nice too (LoFi for the win). Adding a small LUT for either fixed or dynamic color tables might be nice too. Having the ability to switch from 3bit grayscale to 3bit color can be a huge boon if the switching is software controlled. Two different color tables that can be switched each scan line would get you some kind of primitive color dithering. --- The Apple IIgs used 640x200/4c and 320x200/16c 'HighRes' modes with an in-memory color-table. Since there is some memory space left in the 32768 bytes of available memory space for the graphics (320x200/16c = 32000KiB -> 768b left), Apple decided to give each scan line a 4bit LUT-index and add the 16 LUTs (with 16c->4096c) at the end of the memory space.(1/2)b LUT-IDX per line 200x4bit= 100byte, 16x 4bit x 16bit LUT = 512 byte. There are some additional switches and configuration in the other 156 bytes. You can archive 256 on screen colors without any cpu board using this method. Up to 3200 colors are possible with scan-line timed LUT-manipulation. I think that they found a nice way to get the most out of such a limited feature set.
Thanks, lots of good for thought, and I agree entirely regarding trying to get the most out of a chosen set of constraints. For what it's worth, the higher resolutions were a distraction that I never believed were really practical for a 6502 to drive. Its bandwidth is too low. But it would be interesting to look into hardware acceleration to help out there, at least some of the latching behaviors of EGA/VGA, but I'd also like to go further towards 2D and 3D rendering. I'll always keep it within the TTL-style constraint though I think. Anyway that's one tack. The other tack is likely going back to 320x240 and making a more well- rounded system based on that. It's a better fit for the bandwidth capability of a 6502, and more likely to result in a system that can support games for example. I may then get to a point that I'm happy to commit something to a PCB as well. I guess the other tack is pure text modes, keeping the high resolution but just for text so lower CPU bandwidth and less VRAM required. I really want to pursue all of these, but just keep changing my mind. We'll have to see how it goes! Regarding 640x400, my first "simplest VGA" circuit used that resolution (it was actually a rather awkward 40x480 overall I think!) I moved away from it because none of my monitors seemed to support it properly. They all reported it as 720x400, rather than 640x400, and expected a different pixel clock, so my pixels were shown in irregular widths. It was a shame to have to go up to 640x480 as the RAM requirement doubled...
@@GeorgeFoot 640x480@60hz is the way to go for the 'physical' output for the sake of compatibility. The "display resolution" can be less than that and you have a lot of possible modes in that boundary. Maybe even degrade the VGA-hardware to a simple frame buffer with some registers for pixel doubling (or color expansion) and do anything fancy in software? Dual-port access for the frame memory will be very helpful if you decide to later implement a 2d/3d "co-processor". Setting a limited feature set for the basic graphics interface and implementing it to a semi-final design is important. If you have that block finished, you can think more freely about other stuff. Having limits that cannot be changed is the best way to get creative with solutions. Your demonstrations are pretty amazing and i would not have imagined that the shown features were possible on pure TTL logic.
Interesting. 36Mhz is pretty close to half the pixel clock for 720p. While 1280x720 is a bit much for a retro/hobby computer, it does have some really nice horizontal divisors, 640 for 80 columns and 256 for nes style sprite graphics. I wonder if a "GPU" of sorts is the way to go. By that I mean a semi programmable state machine that moves pixels around. Technically this is a blitter, but they usually require quite a lot of baby sitting from the CPU. I'm thinking something programmable enough that it can batch process blits so that it is functionally equivalent to actual tilemap, sprite, or bitmap style video hardware.
I'm planning to look into hardware acceleration for sure. I'd probably start with a subset of the EGA/VGA features, giving the ability to write a colour to a bitmask of pixels, and maybe allow fast copying of data across multiple planes through internal latches without having to load all the data to/from the 8 bit CPU. That would enable a lot to begin with. Beyond that I would like to gradually build up more of a command-driven GPU and perhaps work towards 3D rendering in that way. If we can render at least horizontal stripes with perspective then that's most of the work, and it doesn't feel like too much of a stretch, if you'll pardon the pun!
@@GeorgeFoot To be honest I'd probably skip EGA/VGA, they are kind of rubbish. Instead have a look at old arcade machines, as some have schematics and quite detailed explanations about how they work, Defender for example. Since you are interested in 3D "I, Robot" might be worth a look. It uses a custom bitslice TTL 3D co-processor. I've had a bit of time to think about what the hardware might look like. I think it's best described as a programmable pixel mover. It has auto incrementing source and destination registers, and will be able to move a pixel per clock cycle from video memory to a back buffer. Programming is best described as register transfer level. It needs to be able to load data from a display list,tilemap etc. into it's control registers then do a transfer based on those settings. A transfer will just be a move instruction repeated for however many pixels need to be moved. For transparent pixels this will be a conditional move e.g if pixel is zero disable back buffer WE. This won't be as efficient as real hardware but we have cheap 10ns SRAM so can compensate with much higher clock rates. The idea here is to have something that is simple but flexible enough to emulate various styles of pixel graphics. Scaling should be possible with what I had in mind. I think it might just require replacing the source/destination counters with fixed point adders and add a couple of registers to store the x/y offset/step size. I'm not sure how many fractional bits would be required, and since this is just a programmable pixel mover the CPU would be responsible for calculating the offsets.
You want to toggle each bit when the clock rises if all the lower bits are currently set. If your PLD supports T flip-flops then that's cheap and easy e.g. O0.T = 1, O1.T=O0.Q, O2.T=O0.Q&O1.Q, etc. But if it only supports D flip-flops then you need to fully define its "next" state, which is equal to its current state XOR the AND of all the lower bits. This uses up a lot of product terms and can be tricky to fit into small PLDs.
Good job, but too many wires tangled with each other. As a viewer, I don't understand what's going on in the background. If the wires are on the breadboard, like Ben Eater videos Will be better
Yes for sure, if it was working better I'd probably recap how it works more clearly. The rest of the circuit is identical to earlier videos though, which show the evolution to this point and hopefully explain how it works.
Really impressive!! Moreso for being on a breadboard and right next to the TV. I wouldn't be surprised if you were getting RF from it
Haha yes, I ought to try measuring that! There are certainly some rather long wire loops carrying the 36MHz signal to the shift registers.
@@GeorgeFoot : Wrap some aluminum foil around it, see if that helps anything...
Excellent work. It has been very entertaining following this project.
Thanks, I'm sure it will continue in one form or another!
Would it be difficult to have a user-defined palette for when the bits-per-pixel is low? I remember on the Amiga that even 4-bpp could look pretty decent for games when referencing 12-bit colors.
Yes, it is tricky to do that while still allowing the cpu to update it. Normally it's only necessary for the video circuit to access the RAM once every few pixels - in my case it's 4 - which allows the CPU to write to the RAM in the gaps. But the palette generally needs to be read on every pixel, at 25MHz (or 36MHz in my case now). You need very fast RAM to support that, ideally dual-port RAM. It may be possible to somehow fetch all the data for all 4 pixels in one go - but that's then quite wide, it would need several separate RAM chips to get enough output bits. It's possible though.
I hadn't thought of it like that, thanks for taking the time to think about it. I was (probably naively) thinking that the bitmap ram could continue to have the same cpu interface and timings, but there could be a level of indirection on the readout (which might not need to involve the cpu but would incur some timing implications anyway). I've never built anything nearly so complex as a video card, though. Thanks again, and geek on!
@@AppliedCryogenics The way I see it, the main limitation is bandwidth from whatever RAM is involved last of all. We can increase the bandwidth by using faster RAM or more RAM in parallel (like I do for the framebuffer, getting 16 bits from two ICs at the start of each 4 pixel cycle). So for a palette, maybe two ICs could be inserted before the shift registers to provide four bits each of red, green, blue, and intensity, to represent the RGBI values for each of the four pixels. It could be a nice system and still allow time for the CPU to update the palette in between these accesses.
Alternatively, a fast enough RAM IC can be used after the shift registers, but not interleaving palette writes - hold them up until the end of each scanline, when the palette RAM doesn't need to be driving the display output. Then the cpu can write it as much as it likes. I had some crazy thoughts about how we could use the overscan in the framebuffer to provide updated palette data here and reduce wiring. It's a bit half-baked though and I need to make a more stable foundation at this point before doing that kind of thing!
Looks pretty clean
Async.... oh yeah...... love you man. Very eager to see where you're going.
Amazing work !
Very well done. That is no small feat getting that to work so well on breadboards. Thanks for all the inspiration for my own projects.
Thanks - I do wish it worked better though!
Looking forward to (hopefully) seeing the process of making a new VGA circuit!
Yes I think the next step is probably to go back to the design stage. I've been umming and ahhing a lot, there are many places different choices could be made and it could be interesting to talk through them.
@@GeorgeFoot please do! I’ve been watching a series here on TH-cam by James Sharman, who is also making a VGA circuit, very interesting stuff.
Yes, he has a much more specific design in mind I think, it is nice to see it coming together more and more.
Great video, I've just ordered the PCB's of my own card based on Slu4's version, but using a GAL for the H / V detection and counter resets, as well as a character ROM and a colour RAM. My daughter wants me to write that is has a picture of an axolotl on it as well. I ended up going with a bunch of d-latches for latching in the X, Y, Colour and character, that's on decoded from a 138. It all *SEEMS* to work, and gives me a character display that's similar to the C64 but with 8 bit colours. I got the whole down to 17 chips in the end, so I'm *fairly* happy with that. I could use another GAL and probably knock it down to 13, but life is short.
I'm excited to see where you take this if you go back to first principals.
That makes sense - I like the register-based design.
Great video! I always learn a lot from your videos.
Once again impressed you managed to get something useful out of a 36MHz signal on a breadboard. You might be radiating some RF there.
I'm going to try for 640x480 using a 6845 when I get my hands on a few - it might be overclocking it a bit but it's probably going to work. For a start it'll be monochrome like my existing circuit but I like the idea of replacing 5 IC's with a 6845 - then I can use the extra space for color.
And then just maybe I can use that as a basis for an 8 bit ISA card for IBM PC & XT.
Sounds interesting. I think the 6845 may be OK depending what horizontal speed it supports. 8 pixels of VGA requires about pi MHz, funnily enough. I think typical systems in the early 80s when the 6845 was common probably used a 1 or 2 MHz clock, but they were standard definition, so had about half the horizontal refresh rate, much more time to play with
Great job. That's really high resolution for an 8 bit machine.
Awesome content, more uploads required :)
I think it would be interesting to see a system designed to be modular, with different outputs for digital, VGA, etc.
A design that went from a very wide data bus (even 64 bits? Or more?) down to the normal width to reduce the circuitry needing high-speed capabilities would also be interesting.
I have thought about a modular design where image generation layers can be added or removed in a stack. So the core generates the sync signals, then you can add a background layer with bitmaps graphics, then maybe some sprite layers on top, and a text layer above everything. Or interchange any of the layers if you like. It could be interesting to build that way.
Your setup is very interesting and a nice proof of concept. My personal thoughts are that 800x600 is just a tad too big for any meaningful realtime graphics on a 8 bit computer. Having a crisp text mode is nice but the TTL logic seems to be near its limits. Using off-the-shelf TTL chips is very future proof and should allow the design to be used for years to come. Getting a simple design onto a PCB with surface mount components (where it is possible) has a lot of potential. Limiting the feature set to the minimum for acceptable graphics and text might be the way to go. In my opinion, limiting oneself to a certain spec and trying to get the most out of it is a more interesting way to design and build retro hardware. The specs should follow limits of the chosen hardware. Setting boundaries can be hard when you have FPGAs, modern design tools and cheap MCUs on your hands. The limit of using TTL chips only should be a natural barrier for feature creep ;-)
----
I always liked the ATARI monochrome 640x400 video mode (with is sub-modes) for its effective usage of a 32K memory space. Expanding that to 64K with 4 colors or 96K with 8 colors might be usable as well but bank switching several times for a single screen will be a big hurdle. A 8MHz 6502 might be fast enough to display 640x400 uncompressed 4bit color FMV at 15Hz but having several sub-modes is nice too (LoFi for the win). Adding a small LUT for either fixed or dynamic color tables might be nice too. Having the ability to switch from 3bit grayscale to 3bit color can be a huge boon if the switching is software controlled. Two different color tables that can be switched each scan line would get you some kind of primitive color dithering.
---
The Apple IIgs used 640x200/4c and 320x200/16c 'HighRes' modes with an in-memory color-table. Since there is some memory space left in the 32768 bytes of available memory space for the graphics (320x200/16c = 32000KiB -> 768b left), Apple decided to give each scan line a 4bit LUT-index and add the 16 LUTs (with 16c->4096c) at the end of the memory space.(1/2)b LUT-IDX per line 200x4bit= 100byte, 16x 4bit x 16bit LUT = 512 byte. There are some additional switches and configuration in the other 156 bytes.
You can archive 256 on screen colors without any cpu board using this method. Up to 3200 colors are possible with scan-line timed LUT-manipulation. I think that they found a nice way to get the most out of such a limited feature set.
Thanks, lots of good for thought, and I agree entirely regarding trying to get the most out of a chosen set of constraints. For what it's worth, the higher resolutions were a distraction that I never believed were really practical for a 6502 to drive. Its bandwidth is too low. But it would be interesting to look into hardware acceleration to help out there, at least some of the latching behaviors of EGA/VGA, but I'd also like to go further towards 2D and 3D rendering. I'll always keep it within the TTL-style constraint though I think. Anyway that's one tack.
The other tack is likely going back to 320x240 and making a more well- rounded system based on that. It's a better fit for the bandwidth capability of a 6502, and more likely to result in a system that can support games for example. I may then get to a point that I'm happy to commit something to a PCB as well.
I guess the other tack is pure text modes, keeping the high resolution but just for text so lower CPU bandwidth and less VRAM required.
I really want to pursue all of these, but just keep changing my mind. We'll have to see how it goes!
Regarding 640x400, my first "simplest VGA" circuit used that resolution (it was actually a rather awkward 40x480 overall I think!) I moved away from it because none of my monitors seemed to support it properly. They all reported it as 720x400, rather than 640x400, and expected a different pixel clock, so my pixels were shown in irregular widths. It was a shame to have to go up to 640x480 as the RAM requirement doubled...
@@GeorgeFoot 640x480@60hz is the way to go for the 'physical' output for the sake of compatibility. The "display resolution" can be less than that and you have a lot of possible modes in that boundary. Maybe even degrade the VGA-hardware to a simple frame buffer with some registers for pixel doubling (or color expansion) and do anything fancy in software? Dual-port access for the frame memory will be very helpful if you decide to later implement a 2d/3d "co-processor". Setting a limited feature set for the basic graphics interface and implementing it to a semi-final design is important. If you have that block finished, you can think more freely about other stuff. Having limits that cannot be changed is the best way to get creative with solutions.
Your demonstrations are pretty amazing and i would not have imagined that the shown features were possible on pure TTL logic.
Interesting. 36Mhz is pretty close to half the pixel clock for 720p. While 1280x720 is a bit much for a retro/hobby computer, it does have some really nice horizontal divisors, 640 for 80 columns and 256 for nes style sprite graphics.
I wonder if a "GPU" of sorts is the way to go. By that I mean a semi programmable state machine that moves pixels around. Technically this is a blitter, but they usually require quite a lot of baby sitting from the CPU. I'm thinking something programmable enough that it can batch process blits so that it is functionally equivalent to actual tilemap, sprite, or bitmap style video hardware.
I'm planning to look into hardware acceleration for sure. I'd probably start with a subset of the EGA/VGA features, giving the ability to write a colour to a bitmask of pixels, and maybe allow fast copying of data across multiple planes through internal latches without having to load all the data to/from the 8 bit CPU. That would enable a lot to begin with.
Beyond that I would like to gradually build up more of a command-driven GPU and perhaps work towards 3D rendering in that way. If we can render at least horizontal stripes with perspective then that's most of the work, and it doesn't feel like too much of a stretch, if you'll pardon the pun!
@@GeorgeFoot To be honest I'd probably skip EGA/VGA, they are kind of rubbish. Instead have a look at old arcade machines, as some have schematics and quite detailed explanations about how they work, Defender for example. Since you are interested in 3D "I, Robot" might be worth a look. It uses a custom bitslice TTL 3D co-processor.
I've had a bit of time to think about what the hardware might look like. I think it's best described as a programmable pixel mover. It has auto incrementing source and destination registers, and will be able to move a pixel per clock cycle from video memory to a back buffer. Programming is best described as register transfer level. It needs to be able to load data from a display list,tilemap etc. into it's control registers then do a transfer based on those settings. A transfer will just be a move instruction repeated for however many pixels need to be moved. For transparent pixels this will be a conditional move e.g if pixel is zero disable back buffer WE. This won't be as efficient as real hardware but we have cheap 10ns SRAM so can compensate with much higher clock rates.
The idea here is to have something that is simple but flexible enough to emulate various styles of pixel graphics.
Scaling should be possible with what I had in mind. I think it might just require replacing the source/destination counters with fixed point adders and add a couple of registers to store the x/y offset/step size. I'm not sure how many fractional bits would be required, and since this is just a programmable pixel mover the CPU would be responsible for calculating the offsets.
arduino test? possiable?
How do you use a PLD as a counter?
You want to toggle each bit when the clock rises if all the lower bits are currently set. If your PLD supports T flip-flops then that's cheap and easy e.g. O0.T = 1, O1.T=O0.Q, O2.T=O0.Q&O1.Q, etc. But if it only supports D flip-flops then you need to fully define its "next" state, which is equal to its current state XOR the AND of all the lower bits. This uses up a lot of product terms and can be tricky to fit into small PLDs.
How many colors? 16color? 512color? 16.000color?
This is an upgrade to my previous one, so still only 8 colours (3bpp). The RAM requirement goes through the roof otherwise!
Waw!
Good job, but too many wires tangled with each other. As a viewer, I don't understand what's going on in the background. If the wires are on the breadboard, like Ben Eater videos
Will be better
Yes for sure, if it was working better I'd probably recap how it works more clearly. The rest of the circuit is identical to earlier videos though, which show the evolution to this point and hopefully explain how it works.