Effortpost
Effortpost
I guess one thing you could do is to frankenstein a much bigger ROM chip in place of the 8K character generator, provide some kind of switching mechanism to change the address line selection at will, and fill it up with a whole bunch of fonts.
Like this:
https://imgur.com/5kSWdET (picture by Keropi / VOGONS). :smile:
That depicts an IBM CGA sold in Greece by Memotek, IBM's official distributor at the time. The chip is 32K and contains 10 fonts (with room to spare for 6 more).
Waaaait a minute... How quickly could that thing switch fonts? Could the switch have occurred between two scanlines?
I'm just spitballing here, but imagine a font consisting only of barcode-like vertical stripes. Since the pixels in rows 1 thru 7 of such a character are identical to what's in the character's row 0, we can only look at that single row or scanline. Actually that's the only one of interest to us, the rest could even be blank. Either way, since the characters are 8 pixels wide, 256 characters cover all possible combinations from 00000000 via 01010101 thru 11111111. It looks like we'd only need one extra font. And it probably wouldn't require much complexity in terms of extra daughterboard circuitry to yield the ROT13, ROT14, ROT15, etc. versions of that font, making every combination available in every position.
Alas, there is a problem:
We're not going to be able to also switch fonts mid-scanline, every eight pixels, between different characters. We can at best hope that maybe we can switch fonts between scanlines. Assuming that's even possible. So in order for something interesting to come out of this, we would not simply need to switch to another font each scanline, we'd rather have to address the elephant in the room, which is that this could only help if we were dealing with just a single-character column of text. The moment additional characters come in besides that single-character column, the dependency of our font on what pixel patterns are in those other columns, and on previously-completed scanlines, and previously-printed characters, make the need for additional combinations of characters and fonts increase exponentially. So even hypothetical fast font switching and potentially switching every scanline wouldn't really help.
Except there's that 80x100 text mode that's otherwise used for the 160x100/16c mode.
With 100 (4 x 25) lines of text and a character cell register reduced to two, there are only two lines in play anymore for each character, the top two. So to cover all possible combinations, we would need a font with 256 x 256 = 65,536 characters. That's, like, Unicode plane territory.
Oh, but except we don't.
The characters give us only the pixel pattern and any actual colours would be defined elsewhere, in attribute bytes. Since it's possible to simply invert any text character's foreground and background colours, we don't actually need 256 combinations at all, we only need half of that, from 00000000 through 01111111. That's 128 x 128 = 16,384 characters. Since we really only need 2 x 8 pixels per character (the first two lines), each of these tweak-mode characters could be defined in 2 bytes. Or even two fewer bits in theory, since the leftmost bits are all zero, however manipulating and saving those bits would be too costly in a speed-sensitive scenario, so let's forget about that. Now 128 x 128 x 2 bytes = 32KB.
Wikipedia says 32KB EPROMs came out in 1978, and by 1981 even 64KB EPROMs were on the market.[0] Meaning, we would in fact have had enough space to store the required information. And even if it turned out that (perhaps for lookup speed reasons) the full 8 x 8 pixels needed to be stored despite only 8 x 2 pixels being strictly required for each tweaked text mode character, that's 128 x 128 x 8 bytes = 128KB, and even a ROM of that size would still be period-correct after 1982.
And yet, there is another problem:
Even with something as advanced as, or more advanced than that Memotek replacement daughterboard for the character ROM,[1] I don't think the CGA could be convinced to simply handle a single font containing 16,384 characters. But it's what you would need to have available to freely pick any character for any combination that might show up in a single line.[2] However, CGA just deals with 256-character fonts and that's it. I have two or three ideas on how to solve this. Maybe more. I'll start with the more ambitious ones:
- If our hypothetical replacement daughterboard were able to dynamically generate fonts on the fly, then it could use a ROM-stored 32KB character palette to pick and choose and generate just the right font for each of the 100 lines of tweakmode text. Maybe that's what you (VileR) meant when you spoke of changing the address line selection at will? Since we've only 80 text columns max and we have 128 spots to be filled off that character palette on the fly, we're more than covered. In fact, we wouldn't even need to change all the characters, we could just print the 80 characters from 0xB0 through 0xFF on each text line, and then only change those 80 characters when advancing from one line of tweaked text to another. Our daughterboard would need sufficient high-speed onboard logic for that; it would need:
[*=1]a 32KB EPROM chip providing the character palette,
[*=1]a socket for the original character ROM to slot back into, and
[*=1]software to support the new mode.
Yes, that would be a hardware-assisted mode, but it would be period-correct "what could have been" hardware. An affordable CGA hardware upgrade which might not have cost more than the price of a computer game or two. The result:
640x200px APA with 16 simultaneous colours available in 80x100 colour tiles, with 2 colours per 8x2px tile.
And if the daughterboard did the heavy lifting with the on-the-fly font generation, this need not even be slow. Yes, that's hardware-assisted, but it's fast fullscreen 16 colour with 640x200 pixels all-points addressable and only a little attribute clash. Much less so than on the Speccy, I reckon.
- Oh, but what's the difference between advancing from one line of tweaked text to another and advancing from one scanline to another? None except, if we wanted to do on-the-fly font changing shenanigans in between each of the 200 scanlines as opposed to only between each of the 100 tweaktext lines, we'd need to do those shenanigans twice as often. However, if whatever speed penalty this may incur is acceptable, then we should be able to drastically reduce our ROM size requirements. We'd no longer need 128 x 128 = 16,384 2-byte characters, we'd just need 256 single-byte ones. The reason we'd need 256 instead of 128 is because our foreground/background colour inversion trick is no longer a good option, because even if any relevant attribute bytes could be changed so the colours could be swapped between scanlines, and even if this wouldn't mess with the previously-completed last scanline, it would clearly take too long to do that too. So we need 256 possible patterns. However, if fonts can be changed between scanlines, then we don't need 256 x 256 characters, we just need 256. That removes the need for an outsize character palette. The traditional CGA font size is 8 x 8px x 256 = 2KB, but we might get away with sparsely storing only a single 256-byte font. That original 8KB CGA character ROM would have contained the less than 4KB MDA font[3] and the thin and thick CGA fonts (2KB each), but people really only needed 2KB (the fat font) most of the time. Even with everything left as is, there's room to spare and stick our mini-character palette / font on the existing chip if we're willing to reburn it. Or just put a ready-made 8KB replacement ROM on the daughterboard. If it once again turned out that (again perhaps for lookup speed reasons) the full 8 x 8 pixels needed to be stored despite only 8 x 2 pixels being strictly required for each tweaked text mode character, that's 256 x 8 bytes = 2KB. A cheap 2KB EPROM on our daughterboard might do, or better yet, since the <4KB MDA font on IBM's character ROM is never needed for CGA, delete that, and then an 8KB EPROM on the daugher board could fit the thick font, the thin font, and our special to-be-recombined font in 6K with room to spare. Again, the result would be as above:
640x200px APA with 16 simultaneous colours available in 80x100 colour tiles, with 2 colours per 8x2px tile.
The difference would be that changing and switching fonts twice as often would be slower, but without the need for large EPROMs, the daughterboard would be cheaper.
- But what if it turned out we cannot dynamically generate fonts on the fly? What if it turned out we can only change to ready-made fonts as they are? We could still do somthing interesting by sacrificing resolution. We would stay in 80x100 tweakmode, but we'd forget about 640x200 and aim for 320x200. Now the combinations needed would range from 00000000 via 0011001100 through 11111111, i.e. we'd always change two pixels at a time. A side benefit: Our bigger doublet "virtual pixels" are now closer to square. Now that's 16 combinations per scanline, and with 80x100 tweakmode using two scanlines, we need 16 x 16 = 256 combinations, which a single font can provide, no more dynamic font generation required. All that'd required anymore then would be the ability to change fonts wholesale, to change to that special font when entering the graphics mode we're creating. You could do that with the above Memotek daughterboard. You'd just need to burn a special font with all the possible combinations for those 8x2 tweakmode pixels onto the Memotek's character ROM. Heck, maybe such a font is already there? Has anyone looked for that? But wait, there's more: The IBM CGA card also contains P3. That's supposed to be a jumper, but it may be the case that there are no actual jumper pins installed, with P3 left as a pair of blank pads. Still if you're willing to use a soldering iron, you could install jumper pins and pins or no bins, you could attach or solder on a cable to a little toggle switch you could snake out of the case. Toggling that switch would switch between the fat (default) font and the thin font that no one ever used. If you were willing to re-burn your character ROM and replace the thin font with your special all-the-tweakmode-combinations font here, you could manually flip that switch when entering the mode and again when exiting it. If you're using an original IBM 5150, then maybe P3 could even be wired to the onboard cassette motor relay (because again, no one ever used cassettes on the 5150) and then the switch could be toggled under software control. Or maybe the same could be achieved with a little relay-dongle serial or parallel port adapter also wired to the CGA's P3. In any case, these are possibly extremely simple and extremely inexpensive hardware modifications, but they could still provide:
320x200px APA with 16 simultaneous colours available in 80x100 colour tiles, with 2 colours per 8x2px tile.
The only issues with this are, it's still a hardware mod and it would still be as susceptible to snow as all the other modes.
Purely as an aside:
Maybe to reduce the time required to avoid snow, we could use 40x100 tweakmode instead of 80x100 tweakmode, and thus still get about the same effective resolution as the colour composite mode, but in RGBI:
160x200px APA with 16 simultaneous colours available in 40x100 colour tiles, with 2 colours per 8x2px tile.
Or, if we can generate fonts on the fly as per the first two options above, then stepping down to 40x100 tweakmode could still yield:
320x200px APA with 16 simultaneous colours available in 40x100 colour tiles, with 2 colours per 8x2px tile.
These 40x100 tweakmode options probably aren't good ones though: The attribute clash would get pretty bad given the doubled width of those colour tiles.
- What if modifying hardware was not an option?
This is where I've been meaning to talk to reengine over his "1K colours on CGA: How it's done" post. I'm not sure we've ever talked but there's always a first time. Basically I'm wondering if the same resource-intensive "100 scanline frame with 1 scanline per row" trick that 8088MPH used for display on a colour composite display could also be used with output intended for a colour RGBI display. Because it turns out, once we're happy to aim for a 320px horizontal and only 100 scanlines, then we don't even need a special font. The special font was only needed because we were looking for 16 top patterns times 16 bottom patterns. But if we could use the 80x100 tweaked text mode in a squished way with only 100 scanlines instead of 200, then we could ignore the second line of pixels for each character. All we'd need is characters with the right 16 patterns in their top line. We're looking for all the combinations from 0x0 through 0xF. Can we get those? Sadly, no. But we noted above that we actually only need half the number of patterns. Back then it was 128 instead of 256 patterns, now it's 8 instead of 16 patterns, but the reason we only need half remains the same: Because we can invert foreground and background colours per character thanks to attribute bytes. Unfortunately we have neither all the patterns from 00000000 through 00111111 nor all the patterns from 11000000 through 11111111 in our existing fat font. There are gaps in each. However, the gaps are in different places, and if we use attribute bytes to reverse only certain characters, we can make this work. This may not be a complete list, but you get the idea:
00000000 (space)
00000011 REVERSE 5, 7, B, P, R, T
00001100 j
00001111 ▐ 222 0xDE, √ 251 0xFB, ♂ 11 0x0B
00110000 !, $, `
00110011 REVERSE H, U, V, Y, ä 132 x84, Ü 154 x9A
00111100 C, G
00111111 ♪ 13 0x0D
11000000 \
11000011 Ö 153 0x99, ½ 171 0xAB, ¼ 172 0xAC
11001100 H, U, V, Y, ä 132 x84, Ü 154 x9A
11001111 REVERSE !, $, `
11110000 L
11110011 REVERSE j
11111100 5, 7, B, P, R, T
11111111 █ 219 0xDB, ▀ 223 0xDF
We could just use these characters with the right attribute bytes and thus, if this can actually be made to work, we might be able to get:
letterboxed widescreen 320x100px APA with 16 simultaneous colours available in 80x100 colour tiles, with 2 colours per 4x1px tile.
Without hardware modifications! The question is, would this actually work, and how many CPU cycles would be left on a 4.77MHz 8088 PC like the 5150 or 5160?
Enough to still query the keyboard and do small screen modifications? Fast-moving action and CPU-intensive chess and the like may be out, and it would probably also be impossible even for the likes of you to port Commander Keen to widescreen 16-colour RGBI, but would it be enough for an adventure game interpreter? How about a proper 16-colour RGBI version of King's Quest and the likes? I've heard tell there even might be slideshow-like card games that perhaps could take full advantage of good 16-colour CGA RGBI graphics...
NB: If each scanline could somehow be repeated once, then perhaps this could even be stretched vertically to fill the screen. In that case, a screen-filling 320x100 16-colour mode could result, but the pixels would again be the same aspect ratio as 640x200-mode pixels, but they'd be twice as tall and twice as wide. This may not be possible though.
NB, take two: Pixel artists might not be limited to the above 16 regular patters and could use all the unique patterns available in the fat font. I think there are 35 + their reverse = 70, so a little more than a quarter of the full 256. In that sense, this would really be a 320+ mode, but of course once you start colouring outside the lines and going beyond 320px, it's no longer all-points addressable.
640px APA would again require hardware modifications, but with a different special font including all the possible combinations from 0x00 through 0xFF only in the top line of each character's pixels as per what we started out with, we could, with this same 100 scanline hack, perhaps get to:
letterboxed widescreen 640x100px APA with 16 simultaneous colours available in 80x100 colour tiles, with 2 colours per 8x1px tile.
Effortpost complete.
Corrections? Questions? Comments? Complaints? Perhaps even answers to my questions? Or practical experiments that are above my pay grade?
[0] For context, 128KB EPROMs became available the next year, and by 1983, the year the IBM 5153 came out, even 256KB EPROMs were already on the market.
[1] IBM calls it a ROS character generator or ROS display generator; ROS for Read-Only Storage.
[2] That there are only 40 or at most 80 characters per line doesn't really help us. Fewer than 8 characters per line would help, but a limit of 40 or 80 doesn't.
[3] Don't ask, it's just there, and... oh alright: (9-1) x 14px x 256 = 3,584 bytes, which makes me wonder why they didn't store 9 x 14px x 256 = 4,032 bytes < 4KB. I suppose once again bit-manipulation is hard.