The general idea is pretty much as Scali put it. It's one reason why the MODE command has those ",r"/",l" parameters to shift the screen horizontally by changing the hsync position, and why quite a few early CGA games also offered such a setting; you could never be quite sure what a particular monitor was set to, and whether it had user-accessible controls to compensate.
You're correct in decoupling the raster's flyback time from the length of the blanking period: the CRTC lets you change that length, at least for hblank, but this doesn't affect the image's positioning. (What it does affect is the width of the black bars you see when the picture rolls, as the H/V hold circuitry tries to lock on to a sync signal of the right frequency... in case you're interested in emulating that as well.)
The blanking itself is only really there to prevent visible beam output during flyback, but the CGA also uses it to time the actual sync pulses it sends out to the monitor. It generates hblank for the entire duration of the CRTC's hsync signal, and the true hsync pulse it sends out (from my notes) starts 4 hchars into the hblank and lasts 8 hchars. Similarly for the vsync pulse, which really starts 1 scanline into the vblank period and lasts for 3 scanlines... I could be wrong about these numbers, but in any case they're always fixed with respect to the start of the blanking period. So putting aside any user-adjustable controls, the image's centering depends only on the h/v sync positions.
As for how long it takes the beam to physically fly back to the left (or the top) of the raster, that's a good question... but the simple answer is that it doesn't really matter for the issue at hand - I mean, it would matter if you wanted to know the absolute maximum width/height that the visible image could theoretically have, but no properly-adjusted CRT would ever show the full thing; the most realistic thing to do would be to assume some fixed number, and render only the smaller fixed-size 'window' into that area, while centering the image based on the H/V sync position values.
I guess it'd make sense to treat IBM's default positions of 90 hchars and 224 scanlines as '100% centered', even if in practice they may be a bit off by some tiny amount.
For curiosity's sake however, I had a look through Hugo Holden's docs again, since I remembered he had some relevant oscilloscope measurements. In this one, he measures the horizontal fly-back time for CGA as 10.48 µs (compared to 6.70 µs for EGA). That works out to ~150 hdots, which makes for a theoretical maximum width of 912-150 = 762 hdots. Although elsewhere he merely says "10 to 11 µs", so perhaps the precise duration isn't quite set in stone.
Regarding seeing too much of the screen, you're right. The current display aperture is based on the widest extent of the 'full screen' effects in Area5150, specifically the gradient effect right after the 'lets really push the boundaries' effect which is 768 pixels wide. On real hardware, some of those beautiful pixels are almost certainly beneath the display bezel. I agree that its a bit awkward to show so much dead space for the 99% of the time you're not running Area5150 specifically. If we're talking about having CRT shaders, though, it probably makes sense to pass the whole display field to the shader and let the shader crop what it needs to.
Note I didn't say that I was seeing too much width in total, only that too much was visible on the left/right since the centering was off. We did go with 768 pixels (96 chars) as the 'no-borders' width, since we assumed it'd give us graphics all the way out to the edges on most/all monitors. As it happens that's just a bit more than the 762 "maximum" above, so I guess we weren't wrong. 😀
The solid-color dead space you get with the default border size personally doesn't bother me. My 5153 shows less than that, but you can find videos of Area 5150 on other CRT monitors that show some more. Maybe it's worth learning from the C64 scene here... the VICE emulator lets you choose between "normal borders" and "full borders" (as well as "debug borders", which shows the full theoretical frame size, including the areas that should be occupied by flyback and blanking). Having some 'presets' like that for the aperture size might be a good idea.
(Edit: missed Scali's last post, which practically says the same thing!)
[ WEB ] - [ BLOG ] - [ TUBE ] - [ CODE ]