How can the Hack computer be extended to use color? If you know of any tutorial sites that would help with this, I'd be very interested! I realize this will require me to dig deeper into how a framebuffer works, and while i've read about that and have a general understanding of it, I'm looking for something that goes into the specifics of how to build that out.
This will be tricky, since one bit represents one memory-mapped pixel. These days, 32-bit color pixels are represented as argbnnnn in 64-bit registers. I believe it would take significant hacking of both the architecture and simulator to get color.
I understand that Hack, out of the box, doesn't support color for these reasons. But what I'm really asking here is for a link to a tutorial that would help me to make the needed changes. I understand I'd have to give Hack more RAM, widen the buses, and make changes to the Screen memory map. The part of that that I'm most confused about is the last bit. Assuming that I had beefed up ram and the bus widths, what would i have to do to the Screen memory map to tell the screen to use colors? I've been trying to find a tutorial on that very thing and I'm coming up empty. I probably don't know how to google that properly. Just googling "frame buffer" doesn't get me what I'm looking for. What keywords should I be searching for, then? Thanks.
The first question is how many bits per pixels (BPP) are you going to use. HACK uses 1 BPP, which gives us two colors. You can go with 2 BPP, which will give you four colors. Not many, but a good option is to use the additional two as light gray and dark gray. This will give you the option to create interesting effects like simple anti-aliasing.
We can have 3 BPP. This would give us 8 colors -- enough for a basic palette. But 3 isn't a very good number of bits to use, because you can't easily pack them in words. One option is to pack 5 pixels in a 16-bit word and just "loose" the last bit. Or you can use this bit to switch between different palettes for the 5-pixel group. The Apple II uses a similar technique to increase the number of colors it can display. But this creates various visual problems, because you change the palette for several adjacent pixels at the same time.
4 BPP seems to be the lowest meaningful amount to have real color. The original IBM PC has several graphics modes, one of which is with 4 BPP.
When you increase the BPP you either need more memory or you need to lower the resolution. For example, you can switch from 512×256 to 256×256 and can have two bits per pixel. Or you can go to 256×128 and have 4BPP. For comparison, the original IBM PC had 160×100 resolution, when using the 16 color mode.
Alternatively, you want to increase the video memory. All of it is mapped as a normal computer memory in the HACK platform, so it will eat up the "normal" memory, if we don't change the architecture. Currently the address is 15-bit, so increasing it to 16 seems possible without too many changes and will give you plenty of space even for double buffering. One problem would be how to load 16-bit addresses. The @XXX instruction works with 15 bits only.
A third option would be to "split" the screen memory in pages and map a single page to be addressable and usable by the computer. For example, you can take select one word in the "normal" memory to indicate which page is in use. Let's say address 16383 (0x3FFF), the one just before the video memory for this purpose. You can then use the it's lowest two bits to select between 4 pages of video memory for 4 BPP mode. You can use some of the other bits to implement things like double buffering and "programmable" palette. This option will require only minimal change in the architecture, but a bigger one in the OS.
In the Hardware Simulator, it's a matter of changing the bitmap canvas with something that uses the appropriate number of bits per pixel. Then you need to interpret the values according to scheme you chose. You'd like to take a look at builtInChips.Screen and SimulatorsGUI.ScreenComponent classes.
When using real hardware, like the old CRT monitors, you need to again "interpret" the values and use a DAC to generate the correct wavelengths at the right time to display the desired color.
So, if I were to bump up the BPP to 4, how would the monitor (assume LCD here) know which bit in the Memory Map corresponds to which color? Would it somehow know that I decided that Ram Addresses 16384 to 16387 should correspond to the color of the top left pixel on the screen? And that 16388 to 16391 correspond to the color of the next pixel over?
No, that's what your video card does. I don't know much about how the LCD monitors work, so I'll use the CRT for explanation.
In CRT you have this ray, which starts from the top left corner of the screen, "scans" the first row, then moves to the second row, and so on till it finishes the last one. It then goes back to the beginning and does the same thing. The video card controls the intensity of this beam, which hits the phosphor on the screen and lights it up. High energy means light pixel and low energy means dark pixel. The phosphor looses its light roughly just before it gets hit again by the next scan.
For color, you need 3 RGB-colored phosphors per pixel and 3 guns. You again control the intensity on each gun individually, thus producing different colors.
So the video card "knows" when each pixel needs to be refreshed, it reads this pixel's data from the video memory, decides which color it needs to produce, and generates the appropriate levels for the red, the green and the blue ray. The monitor receives this signal and fires the guns with the specified intensity, thus producing the desired color on the specified part of the screen.