VOGONS


First post, by VileR

User metadata
Rank l33t
Rank
l33t

A little while ago I came across a strange little CGA issue, where certain writes to the 6845 CRTC registers were causing unexplained visual glitches.
This didn't seem to be documented anywhere else, and looking into it led me down an interesting rabbit hole. I ended up detailing my findings over two blog posts, but here's the EXTREME TL;DR EDITION:

* If the Vertical Sync Position register (R7) is modified during the active raster period, the CRTC may output an unintended vsync pulse at the instant of the *write* operation.
* This occurs even though the character row counter doesn't match the target value - a specific correlation must exist between the old *and* new R7 values and the current character row.
* There are other factors at work, such as the timing of the write operation (w.r.t. the character clock cycle), and evidently the chip's temperature(!) as well.

If you want the complete lowdown, see these links. You'll find some video examples of what I'm talking about, a lot of theoretical ramblings and bitwise formulas, and automated test results laid out in a bunch of charts.... which have a surprising relationship with the Sierpinski Triangle fractal set, of all things:

1. Old Chips, New Glitches: the CGA/CRTC "Phantom" VSync
2. More CGA CRTC Glitching: HD6845(R) vs. MC6845

At this point, I believe I have a good-enough characterization of how this glitch behaves on IBM CGA boards, at least on the 4.77 MHz PC/XT bus - whether they use Motorola's MC6845 or Hitachi's HD6845(R). We've gotten a full set of results from both chips, and the analysis is complete enough to be useful, so that pretty much ticks the boxes I really wanted to tick.

Still, it could be educational to broaden the scope of the research a bit. Evidently this behavior depends on the silicon implementation, and there were plenty of CGA clones which used other 6845-type CRTCs:
- Hitachi's HD6845S
- CIC's "8645BE"
- UMC's UM6845(R)
- the Bulgarian CM607
...and so on. Also, due to the nature of this glitch, faster ISA clock rates may change the picture as well.

If anyone feels like helping out with that, here are a few test programs:

Filename
CGA-r7-glitch-tests.zip
File size
7.77 KiB
Downloads
40 downloads
File license
Public domain
Notes and instructions

R7MIN.COM is a cut-down version of the automated test run described in my blog posts:

  • This one should run in ~6 minutes (as opposed to 20+ hours) - it covers only a small subset of test cases, but I hand-picked them to be somewhat representative.
  • All status reads will be logged to a .CSV file; if you post it here, we could compare the results against the existing MC6845/HD6845R data.
  • This test reduces the DRAM refresh rate (Timer 1) quite a lot, for reasons detailed in my posts. This wasn't a problem on the two systems we tested on; but if your PC hangs or becomes unstable, you can add  /S  on the command line, and it'll keep to the "safe" default (the results will be different, but perhaps still useful).

VSPOS-L.COM and VSPOS-U.COM won't log anything, but you can dial in any combination of parameters (old R7 value, new R7 value, CRTC character row), and see for yourself whether the telltale flickering black bar shows up. Might be helpful, especially if the automated test picks up no glitches at all - which could very well be the case, depending on the CGA card/CRTC/bus speed.
"-L" lets you test the lower range of CRTC character rows (00h-54h), "-U" is for the upper ones (55h-7Fh).

  • If the selected character row is equal to one of the R7 values ("from"/"to"), you'll naturally see a stable, non-flickering black bar: this isn't a glitch - just the standard expected behavior. The interesting cases are those where all three values are different.
  • R7 is in fact rewritten on *every* row. In the row you select, it'll test the desired parameters and check the status register for a vsync pulse. Elsewhere, the rewrites will simply set a default value to maintain a stable vertical sync.
    So if you see the 'phantom' black bar, look for changes in the "VSync status reads" counter: if it keeps going up, your selected parameters are the ones truly causing the glitch. But if it doesn't move, then the glitch is actually being caused by the changes between one of your selected values and the default vsync position. The real values responsible for it will typically be found on the following or preceding row.
  • the "/S" argument won't work here, but you can explicitly specify a custom DRAM refresh rate on the command line, in hexadecimal. E.g. "VSPOS-L 12" will set it to 12h, which is the PC's normal rate. Either way, pressing space will change it to 13h, which is exactly 1/4 of the horizontal scan rate, so the glitch will appear to "stabilize"; but testing should be done with the default value (4Bh) if possible.

It'd be especially interesting to see data from one of those other 6845-compatible chips, or from any 6845 running on a >4.77 MHz ISA bus. But even if you test the same hardware we did (IBM CGA, MC6845 or HD6845R, 4.77 MHz PC/XT), the results could still be valuable. Who knows - perhaps different batches of the same chips have a different response to the marginal write timings that seem to be causing this phenomenon.

I'm not including the full two-pass automated test that truly checks every combination. That one takes a long time to run, but more importantly, the set of test-cases for the second pass depends on the results of the first one - and right now it doesn't parse them directly, so they're hard-coded into the second pass and may need to be regenerated. But if someone really wants to try it, let me know.

If you try it out, and can post your .CSV output, please note the relevant details - CGA card make and model, CRTC chip designation, machine type and CPU/bus speed. Thank you!
(Yes, some non-CGA video setups use the 6845 as well - MDA, Hercules/"MGA", PCjr, and so on. But as I don't have the hardware, I can't come up with suitable test setups, so these programs will only work on CGA).

[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]

Reply 1 of 8, by kdr

User metadata
Rank Member
Rank
Member

Very interesting!

Inside the 6845 there will be a register or latch which holds the current value of R7, and this is fed to a comparator whose other input comes from the vertical counter. The comparator will be purely combinatorial logic. As the inputs to the comparator change, the various logic gates of the comparator begin to settle on the new output value, but (as we see here) the output of the comparator might glitch back and forth for a while as everything settles down. When a new value is clocked into R7, there'll be a bit of skew at the register output, since some bits of R7 will change to the new output value before other bits change. If you change R7 at a particularly unlucky time, the comparator output could glitch TRUE momentarily due to this skew at the precise time that the CCLK goes high and the rest of the logic samples the comparator's output, and thus erroneously ending the current frame. (In proper terms: we've managed to violate the setup time requirement by changing R7 asynchronously to CCLK.)

Reply 2 of 8, by VileR

User metadata
Rank l33t
Rank
l33t
kdr wrote on 2023-05-06, 09:46:

Inside the 6845 there will be a register or latch which holds the current value of R7, and this is fed to a comparator whose other input comes from the vertical counter. The comparator will be purely combinatorial logic. As the inputs to the comparator change, the various logic gates of the comparator begin to settle on the new output value, but (as we see here) the output of the comparator might glitch back and forth for a while as everything settles down. When a new value is clocked into R7, there'll be a bit of skew at the register output, since some bits of R7 will change to the new output value before other bits change. If you change R7 at a particularly unlucky time, the comparator output could glitch TRUE momentarily due to this skew at the precise time that the CCLK goes high and the rest of the logic samples the comparator's output, and thus erroneously ending the current frame. (In proper terms: we've managed to violate the setup time requirement by changing R7 asynchronously to CCLK.)

Yeah, that seems to be more or less what's happening - at least you're more succinct than the long-winded hypothesis in my first blog post. 😉 Although that the frame doesn't actually end, since Vertical Total (R4) isn't being modified; the glitch causes the CRTC to drive "VS" high, but that only makes the CGA start a vertical retrace cycle (blanking + sync). Luckily the monitor's oscillator seems to provide enough tolerance for the actual sync pulse to have no effect, at least when it's doesn't occur too close to the bottom of the screen, so the blanking is the only visible symptom.

This makes me wonder about Vertical Total as well... I haven't encountered comparator glitches when modifying VTotal. But that could be because an end-of-frame condition requires *two* counters to reach specific values (VTotal + Scanline Adjust, R4+R5), so it's much more difficult to trigger by accident.

Interestingly, I had a report that the HD6845S doesn't seem to exhibit the glitch at all. That's Hitachi's revision with slightly better specs - I think it was used mostly in HGC/MGA cards, but some CGA clones have it as well. It has a higher limit on the character clock rate (3.7 MHz vs. the R's 3.0), and some of the timing constraints differ accordingly: https://archive.org/details/bitsavers_hitachi … up?view=theater.
I suppose that could be enough to avoid the issue, at least with a 4.77 MHz system I/O clock. But it should be interesting to see some actual test data.

[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]

Reply 3 of 8, by rasz_pl

User metadata
Rank l33t
Rank
l33t

Reminds me of C64. Unlike contemporary consoles VIC2 didnt support hardware scrolling beyond 7bit offsets, that 8th pixel required copying 2000 bytes to manually shift text and color ram 🙁 Big oversight considering C64 can only copy ram at <120KB/s with all the tricks. Smoothly scrolling screen at full framerate will use all of the CPU on the PAL model just to copy data around with nothing to spare for game logic. Very late into C64 life, long after its heyday, scene coders started discovering weird VIC-2 tricks. VSP ("Variable Screen Placement", also called DMA Delay), FLD, Line Crunch, AGSP ("Any Given Screen Position") - force VIC2 to start rendering video from arbitrary ram offset, now scrolling requires copying just 80 bytes per 8 pixel offset. Implementation is ugly, exploiting silicon bugs, prone to causing ram refresh corruption and computer crash if done badly/having unlucky hardware. Afaik the only C64 game that ever used it is 1993 "Mayhem in Monsterland" and it looks and plays FANTASTIC, pretty much Sonic the Hedgehog lever great 🙁

Open Source AT&T Globalyst/NCR/FIC 486-GAC-2 proprietary Cache Module reproduction

Reply 4 of 8, by Scali

User metadata
Rank l33t
Rank
l33t
rasz_pl wrote on 2023-05-07, 14:54:

Reminds me of C64. Unlike contemporary consoles VIC2 didnt support hardware scrolling beyond 7bit offsets, that 8th pixel required copying 2000 bytes to manually shift text and color ram 🙁 Big oversight considering C64 can only copy ram at <120KB/s with all the tricks.

Exactly, so you had to use a tile-based approach, where you'd have a limited set of graphical tiles, and the rest would be 'background tiles' which didn't have to be replaced, as they were just sky (all blue) or whatnot.
https://www.youtube.com/watch?v=eEpQCCA7S1g

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 5 of 8, by Jo22

User metadata
Rank l33t++
Rank
l33t++

Sorry for the intrusion, but I must often think of the C128 and Sharp MZ-800 video chips when I think of CGA's hi-resolution mode: MOS 8563 and PCG

https://en.wikipedia.org/wiki/MOS_Technology_8563
https://www.manualslib.com/manual/862056/Shar … 800.html?page=7

Another rival of the Motorola CRTC is the NEC µPD7220.
It was used in the form of the U82720 in Robotron x86 PCs (ex-GDR), which also could handle CGA.
Maybe that's helpful to know. The µPD7220 was a fine character generator.

https://en.wikipedia.org/wiki/NEC_µPD7220

https://de.wikipedia.org/wiki/EC_1834
https://www.robotrontechnik.de/html/computer/ec1834.htm

"Time, it seems, doesn't flow. For some it's fast, for some it's slow.
In what to one race is no time at all, another race can rise and fall..." - The Minstrel

//My video channel//

Reply 6 of 8, by zyga64

User metadata
Rank Oldbie
Rank
Oldbie
rasz_pl wrote on 2023-05-07, 14:54:

Reminds me of C64. Unlike contemporary consoles VIC2 didnt support hardware scrolling beyond 7bit offsets, that 8th pixel required copying 2000 bytes to manually shift text and color ram 🙁 Big oversight considering C64 can only copy ram at <120KB/s with all the tricks. Smoothly scrolling screen at full framerate will use all of the CPU on the PAL model just to copy data around with nothing to spare for game logic. Very late into C64 life, long after its heyday, scene coders started discovering weird VIC-2 tricks. VSP ("Variable Screen Placement", also called DMA Delay), FLD, Line Crunch, AGSP ("Any Given Screen Position") - force VIC2 to start rendering video from arbitrary ram offset, now scrolling requires copying just 80 bytes per 8 pixel offset. Implementation is ugly, exploiting silicon bugs, prone to causing ram refresh corruption and computer crash if done badly/having unlucky hardware. Afaik the only C64 game that ever used it is 1993 "Mayhem in Monsterland" and it looks and plays FANTASTIC, pretty much Sonic the Hedgehog lever great 🙁

Fred's Back series is another well known example of using AGSP technique. https://www.youtube.com/watch?v=2jFByRmPK3s
But now there is known fix for "VSP crash" bug: https://kodiak64.com/blog/future-of-VSP-scrolling

1) VLSI SCAMP /286@20 /4M /CL-GD5422 /CMI8330
2) i420EX /486DX33 /16M /TGUI9440 /GUS+ALS100+MT32PI
3) i430FX /K6-2@400 /64M /Rage Pro PCI /ES1370+YMF718
4) i440BX /P!!!750 /256M /MX440 /SBLive!
5) iB75 /3470s /4G /HD7750 /HDA

Reply 7 of 8, by VileR

User metadata
Rank l33t
Rank
l33t

I wasn't sure how the C64 scrolling talk was relevant here (was it meant to go in the "scrolling over the edge" thread?), but it was intriguing to read up on that "VSP crash". Apparently the underlying cause is similar to the 6845's vsync glitch: electro-mechanical factors along the line may cause the logic voltages to be flipped at inopportune moments within the I/O cycle. This results in metastable binary states on specific bus lines, and the respective values become indeterminate. But in this case the affected circuit is the DRAM refresh subsystem... with predictably disastrous effects.

Makes for an interesting parallel either way. But back on topic, I see that the test programs have gotten a few downloads, so do feel free to post some interesting results. 😀

[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]

Reply 8 of 8, by rasz_pl

User metadata
Rank l33t
Rank
l33t
VileR wrote on 2023-05-08, 06:04:

I wasn't sure how the C64 scrolling talk was relevant here

sorry for off topic, It was meant as 'have a look at a similarly weird glitch discovered in that other vintage platform, it even has actually useful side effect'

Open Source AT&T Globalyst/NCR/FIC 486-GAC-2 proprietary Cache Module reproduction