VOGONS


Reply 20 of 37, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-02-03, 13:19:

The main issue is when "blanking end" after "retrace end" horizontally (as well as retrace usually) it's on the next scanline? So when the horizontal retrace and blanking ends, before the start of the next video memory being rendered (until horizontal total and after that the horizontal display enable skew, if used. So basically back porch until start of active display from VGA pov), the DAC will start outputting on the next scanline. But since the active display isn't started yet, the input status 1 register bit 0 is still indicating 'retrace'? So the software would think it's either on the next scanline or not yet? Is the DAC color assumed 'set' during the start of horizontal retarce (which gives correct results) or assumed from the end of 'retrace' (which would be incorrect as the back porch's overscan area is there as well)?

Yes. If the horizontal character count exceeds "blanking end", the CRT beam is in the left overscan areas of the next scanline. The attribute controller will send the color number in the "overscan color" register to the DAC, and the DAC will output the selected RGB color. The DAC never latches a color value from the attribute controller (for more than a pixel worth of time), nor it postpones CPU color updates. So if copper bars are implemented by changing the DAC values while "input status 1 bit 0" is set, the update will take place during the blanking/retrace period, and at the very end of the horizontal CRTC cycle, the left overscan is already drawn using the new color.

With copper bars, I never observed artifacts in the right overscan area. This need not imply that the input status 1 bit 0 is clear during overscan, because the latency from detecting that this bit is set until the DAC is accessed (using 8-bit ISA I/O) might be high enough to cover the complete right-hand overscan area.

Reply 21 of 37, by coldturkey

User metadata
Rank Newbie
Rank
Newbie

Sorry for the late post, but I'm trying to reconcile how extra vertical porch doesn't change aspect ratio of the displayed picture on your "non control processor" monitor.

For example, 400 line VGA mode @70hz expects 449 total horizontal lines. While the vertical porches are "active" (i.e. the period between vsync pulses), I believe the horizontal sync pulses are still firing. It's my understanding the electron beam is simply "off", but the circuitry is still tracing down the screen "line by line".

The relevance for me is that games like Jazz Jackrabbit are 320x200 (actually 320x199) at 60hz. Because 60hz expects 525 total lines (480 of which are normally active picture), it shows up as letterboxed on my monitor. It also does the same for this other Vogons user: Ancient DOS Games Webshow

I also tried the 60hz TSR in this VGA TSR goodies pack, and it made all my mode 13h games letterboxed. It even indicates this is to be expected in the comments of the source code: wbcbz7's MS-DOS VGA TSR goodies

Is there something in monitors without control processors that changes things so that letterboxing doesn't occur? It feels like they'd have to NOT advance downward line by line during the vertical porch periods (maybe keep scanning the same line over and over?) and then the screen just puts larger gaps between the active scanlines to make them fill out to 4x3?

Sorry for diving so deep, but I'm trying to reconcile the technicalities of what you've experienced vs what it seems others (likely all using multiscan monitors) experience.

Thank you!!

mkarcher wrote on 2024-02-01, 22:31:
Grzyb wrote on 2024-02-01, 22:12:

If HSYNC=31.5kHz and VSYNC=60Hz, then it must be the 480-line mode - no need to look at the SYNC polarity, it's enough to measure the frequencies.

Before monitors had control processors (i.e. up around to 35kHz HSYNC), measuring the sync frequency was more involved than looking at the SYNC polarity. Most VGA monitors synchronize anything between 58Hz and 72Hz, and nothing in their circuitry depends on the sync. Back in the time with a fixed-HSYNC VGA monitor, I experimented with adding extra blanking to lower the refresh rate (to make games run at like 65fps instead of 35fps when it missed every second frame), and found out that adding extra vertical front/back porch did not change the picture size. You could add that much blanking to the 400 line mode to get to 60 Hz - as long as the SYNC polarity indicated 400 lines, the image height was appropriate for 400 lines.

On the other hand, changing sync polarities did not change the capture range of the vertical oscillator - only the VHOLD control on the back of the monitor did.

Reply 22 of 37, by mkarcher

User metadata
Rank l33t
Rank
l33t
coldturkey wrote on 2026-01-15, 18:20:

For example, 400 line VGA mode @70hz expects 449 total horizontal lines. While the vertical porches are "active" (i.e. the period between vsync pulses), I believe the horizontal sync pulses are still firing. It's my understanding the electron beam is simply "off", but the circuitry is still tracing down the screen "line by line".

That's correct. Even during vertical retrace, the horizontal oscillator in the monitor is still running and sweeping the beam from left to right as usual. Stopping and re-starting the horizontal deflection for each frame would be very challenging, especially to get the oscillator stable quick enough that there is no distortion at the top of the screen. There is a considerable amount of energy oscillating between being magnetically stored in the deflection field and electrically stored in capacitors on the monitor PCB.

coldturkey wrote on 2026-01-15, 18:20:

The relevance for me is that games like Jazz Jackrabbit are 320x200 (actually 320x199) at 60hz. Because 60hz expects 525 total lines (480 of which are normally active picture), it shows up as letterboxed on my monitor. It also does the same for this other Vogons user: Ancient DOS Games Webshow

This is clearly a non-supported use case. Standard VGA supports 350 visible scan lines at 70 Hz (for EGA compatible resolution), 400 visible scan lines at 70 Hz and 480 visible scan lines at 60Hz. VGA monitors are not required to display a "sensible" picture if you drive 400 (or 398) visible scan lines at 60 Hz. You should be aware that the horizontal and vertical deflection circuits in a classic CRT monitor are completely seperate circuits, so the vertical deflection circuit doesn't even are about whether "there are scan lines during the front/back porch". So we do not need to consider what happens to the horizontal deflection when looking at the issue you see Jazz Jackrabbit letterboxed.

The vertical oscillator needs to support the three modes I mentioned above, that is 350 lines / screen, 400 lines / screen and 480 lines / screen. This means the sweeping speed is different. As the horizontal frequency is fixed at 31.5 kHz, we don't need to distinguish between the vertical scan rate in millimeters per line or millimeters per millisecond, as there is a fixed factor between it. Classic VGA monitors may implement the vertical oscillator in a way that supports three different deflection rates supporting the three official line counts. The deflection rate may be implemented by applying one of three fixed voltages to the deflection coil, as the rate of change of the magnetic field in a coil is directly proportional to the applied voltage. Thus, a straightforward implementation of a VGA monitor vertical oscillator would choose between three different operating voltages that make either 350, 400 or 480 lines fill the screen, and it would choose the operating voltage based on the sync polarity. If a monitor works this way, it will display Jazz Jackrabbit correctly, without letterboxing. The extra added black lines to slow the frame rate to 60 Hz will be above and below the visible area. There is no guarantee that the range of the circuit driving the vertical oscillator is big enough to allow a stable linear sweep with 40 extra black lines on the top and bottom - but it is very likely, as the 350-line mode also works using excessive front and back porch, although it only uses 25 extra lines above and below the the 350-line picture to use the same timing as a 400-line picture. Because vertically stretching a 400-line picture in a way that 350 lines fill the whole screen is required to work, vertically stretching a 480-line picture in a way that 400 lines fill the whole screen is likely to work as well.

It starts getting messy as soon as monitors start to get "more intelligent" than the fixed frequency VGA monitor. IBM used the fourth polarity combination of HSync/VSync that originally signified the 200-line NTSC-like CGA timing to indicate the 8514/A mode of 1024 @ 87Hz interlaced, but as soon as a monitor is supposed to support more then 4 vertical resolutions, just adjusting the vertical oscillator depending on the sync polarities no longer works. This starts happening as soon as a monitor is intended to support the three classic VGA resolution, 800*600 and 1024*768, so basically any SVGA monitor needs to evaluate sync rates to choose appropriate vertical deflection rates. And that's where you are clearly out of luck with custom timings, as there is no specification that indicates whether a 60 Hz timing with 525 lines, while the sync polarities indicate 400 visible lines is supposed to be displayed with 480 or 400 visible lines - a monitor may choose either of these variants, or may just happen to display the image at an entirely wrong height.

coldturkey wrote on 2026-01-15, 18:20:

I also tried the 60hz TSR in this VGA TSR goodies pack, and it made all my mode 13h games letterboxed. It even indicates this is to be expected in the comments of the source code: wbcbz7's MS-DOS VGA TSR goodies

The VGA60HZ utility goes all the way to fully reprogram the vertical timing to 480 line mode, including the adjustment to the sync polarity. This part of the assembly code will set HSync and VSync to negative, explicitly instructing the monitor to display the black letterbox bars above/below the 400 visible lines as part of the visible image:

                mov     dx, 0x3CC
in al, dx
or al, 0xC0
mov dl, 0xC2
out dx, al ; misc. output

you might want to NOP out the OUT instruction if you are curious how a specific monitor responds the to 480-line 60Hz timing with the sync polarity indicating 400 visible lines (which is likely what Jazz does). In the COM file, that's the byte EE at offset 1D, which can be replaced by 90.

coldturkey wrote on 2026-01-15, 18:20:

Is there something in monitors without control processors that changes things so that letterboxing doesn't occur? It feels like they'd have to NOT advance downward line by line during the vertical porch periods (maybe keep scanning the same line over and over?) and then the screen just puts larger gaps between the active scanlines to make them fill out to 4x3?

If you are talking about CRT monitors, your mental image on the display process is wrong. The monitor does not work like a printer or fax machine in the way that the vertical position of the beam is stepped at the end of each line, and a step could easily be omitted, but the vertical position of the beam is continously increasing at an approximately fixed rate. Possibly, the horizontal and vertical deflection are not at an exact 90 degree angle to mitigate the issue that the right end of each line would be slightly lower than the left end, or a small amount of the horizontal deflection signal is electronically coupled into the vertical deflection coil.

This means there is no way to "pause" vertical deflection for uninteresting lines. The correct way to handle 400 lines at 60 Hz is just to increase picture height (deflection strenght) by 20%.

If you are thinking about how an LCD monitor processes the image before sending it to the digital fixed-resolution panning, all bets are off. It will do whatever the firmware instructs the sampling and scaling logic to do.

Reply 23 of 37, by coldturkey

User metadata
Rank Newbie
Rank
Newbie

Thank you for the incredibly detailed response! And yes, all my experiments are on CRTs.

Where I was struggling was that in the references I was reading the sync polarities seemed like they were supposed to set both the refresh rate and the number of active lines (e.g. 640x350 @ 70Hz: H-Positive, V-Negative; 640x400 @ 70Hz: H-Negative, V-Positive; 640x480 @ 60Hz: H-Negative, V-Negative)

If the sync polarities are just for telling the monitor the number of active lines (at least for fixed frequency VGA monitors), then I see how setting the polarity for 640x400 and then running at 60hz instead of 70 might fill the screen on many fixed frequency CRTs (though as you point out, it is a non-standard implementation). I may end up scoping the sync lines when I'm running Jazz Jackrabbit to confirm the polarities. If it shows H-Negative;V-Negative, then I guess the programmers were targeting a letterboxed output. If it shows H-Negative;V-Positive, then I guess they were hoping it would fill the screen.

I'm definitely going to hex edit the VGA60hz utility as per your instructions to see what that does on my display as well.

I used to own a few fixed frequency VGA monitors, but I got rid of them when I "upgraded" to multisync. Now I'm wishing I still had them around for testing.

Again, thank you so much for your detailed response and examining the vga60hz utility. If I end up scoping the sync polarities while playing Jazz Jackrabbit, I'll post back here.

Reply 24 of 37, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie

I'm working on PLL emulation for MartyPC and I'm curious to see how it's going to handle this sort of thing. Unfortunately Jazz Jackrabbit is not something I can run on an 8088 - were there any other titles that did this letterboxing trick?

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 25 of 37, by coldturkey

User metadata
Rank Newbie
Rank
Newbie

This Nerdly Pleasures blogpost has a list of games that used weird graphics modes:
https://nerdlypleasures.blogspot.com/2014/09/ … tions-when.html

GloriousCow wrote on 2026-01-17, 16:41:

I'm working on PLL emulation for MartyPC and I'm curious to see how it's going to handle this sort of thing. Unfortunately Jazz Jackrabbit is not something I can run on an 8088 - were there any other titles that did this letterboxing trick?

Reply 26 of 37, by coldturkey

User metadata
Rank Newbie
Rank
Newbie
coldturkey wrote on 2026-01-17, 08:25:

If it shows H-Negative;V-Negative, then I guess the programmers were targeting a letterboxed output. If it shows H-Negative;V-Positive, then I guess they were hoping it would fill the screen.

Well, mystery solved. I scoped the sync lines for Jazz Jackrabbit, and it was indeed H-Negative; V-Positive. So now we know the intentions of the programmers even though it doesn't work on multiscan monitors (or at least the ones that people have uploaded pictures of).

coldturkey wrote on 2026-01-17, 08:25:

I'm definitely going to hex edit the VGA60hz utility as per your instructions to see what that does on my display as well.

This all worked as you suggested. The utility before changing the byte utilized H-Negative;V-Negative. So letterboxing was intended. When I changed the byte and re-scoped the sync, it was indeed H-Negative; V-Positive. This actually made it MORE letterboxed on my monitor, where extremely black lines were on the top and bottom of what looked to be slightly less dark black lines before finally displaying the picture of the game. I had the brightness really turned up so the two types of black lines could contrast against each other (see attached picture).

Now I really want a fixed frequency monitor to compare against what I'm seeing on my multiscan!

Reply 27 of 37, by mkarcher

User metadata
Rank l33t
Rank
l33t
coldturkey wrote on 2026-01-17, 21:44:

The utility before changing the byte utilized H-Negative;V-Negative. So letterboxing was intended. When I changed the byte and re-scoped the sync, it was indeed H-Negative; V-Positive. This actually made it MORE letterboxed on my monitor, where extremely black lines were on the top and bottom of what looked to be slightly less dark black lines before finally displaying the picture of the game. I had the brightness really turned up so the two types of black lines could contrast against each other (see attached picture).

Now that's funny. It means the monitor is responding to sync polarities at the VGA 60 Hz timing, but if you apply H-Neg, V-Pos, it does not configure the vertical oscillator for 400 lines, but my impression is that the vertical oscillator is set up for around 550 lines in the active time of a 60 Hz frame, which is approximately the same sweep rate as 600 lines in the active time of a 56Hz frame. Your monitor seems to switch the vertical oscillator into the mode required for 800*600 at 35.2kHz / 56 Hz, a very common early SVGA mode when you try to run 400 lines at 60 Hz. A classic (fixed-frequency) VGA monitor wouldn't do that, as it has no requirement to support the 800*600 mode.

Reply 28 of 37, by coldturkey

User metadata
Rank Newbie
Rank
Newbie

I dug out another multiscan monitor I had just to see if it behaved the same for Jazz Jackrabbit and VGA60hz (both the unpatched and patched versions). Everything was basically the same except vga60hz produced identical letterboxing for the unpatched and patched versions.

I then tried an EGA 350 line game and the newer multisync automatically stretched it to 4x3 while the older one left it somewhat squished and letterboxed (pictures attached). Of course you can always manually adjust things, but I was a bit surprised that EGA 350 line did not automatically fill the screen on the one monitor...

Reply 30 of 37, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2026-01-19, 12:07:

So, what happens while the retrace signal is still kept active? For example from retrace start till end? Does it keep the deflection active?

In all but the most basic monitors (IBM 5151, cough!), the deflection is alway active, driven by an oscillator inside the monitor. This oscillator is synchronized to the horizontal/vertical sync pulses using a PLL. The osciallator may be synchronized to the starting edge, the rising edge or the center of the sync pulse, depending on monitor construction, but the width of the sync pulse is usually not influencing oscillator behaviour.

On the other hand, an active sync pulse might force blanking on some monitors, so overly long sync pulses may blank image contents.

Reply 31 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

What I mean is:
1. The sync signal goes from low to high, causing the beam to go up (vertical retrace) or left (horizontal retrace).
2. The signal stays high for a certain duration (in character clocks or scanlines).
3. The signal goes low again.

What happens during step 2? Does the signal just render black on the display horizontally (horizontal retrace) or black lines (vertical retrace with multiple horizontal retraces deflecting to the left)? Or is it stuck to the top or left of the screen (being pulled by an active magnet)?
Right now, my implementation acts like it's stuck left and/or top(for vertical retrace) during the retrace period (step 2).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 32 of 37, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2026-01-19, 22:50:
What I mean is: 1. The sync signal goes from low to high, causing the beam to go up (vertical retrace) or left (horizontal retra […]
Show full quote

What I mean is:
1. The sync signal goes from low to high, causing the beam to go up (vertical retrace) or left (horizontal retrace).
2. The signal stays high for a certain duration (in character clocks or scanlines).
3. The signal goes low again.

What happens during step 2? Does the signal just render black on the display horizontally (horizontal retrace) or black lines (vertical retrace with multiple horizontal retraces deflecting to the left)? Or is it stuck to the top or left of the screen (being pulled by an active magnet)?
Right now, my implementation acts like it's stuck left and/or top(for vertical retrace) during the retrace period (step 2).

In most monitors, the sync signal does not directly control any magnets.* In the monitor there will be some sort of sync processor chip - in the 5153 its a Hitachi HA11235.
The sync processor contains horizontal and vertical PLLs. The sync processor itself is deciding whether to perform the horizontal or vertical flyback, it is just using the sync inputs from the card to adjust its own oscillators within some allowable range.

Vertical deflection resumes immediately after flyback. There is no way to "pause" the beam or hold it in place.

*with the exception of the 5151 which lacks a horizontal PLL and is pretty much directly controlled by the horizontal sync from the MDA. In which case you are likely to blow something up if you muck around with the horizontal sync too much, probably one of the transistors in the horizontal drive circuit.

The SAMS' guide for the 5151 describes a troubleshooting process for loss horizontal sync:

"Inject a horizontal signal at the base of Transistor TR23. If the raster returns, check voltages and components associated with […]
Show full quote

"Inject a horizontal signal at the base of Transistor TR23. If
the raster returns, check voltages and components
associated with Horizontal Drive Transistor (TR22) and the
Horizontal Drive Transformer (T501). If the raster does not
return, check Transistor TR23, Diode D502. Transformer
associated circuitry. The high voltage rectifier is
insformer T502 and may be defective."

This does imply that with a lack of horizontal sync altogether, that the beam may indeed actually hang out at the right side of the screen. I can't imagine running it like that is very good for it. I'm not sure there's utility in attempting to emulate this.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 33 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

So how should I handle the sync signals then? Like I said, right now it clears the horizontal or vertical CRTC axis for rendering the next pixel. Holding the signal high keeps it there until it's lowered. Or should I just trigger on going high, then render black pixels normally each clock for the remainder of the programmed sync?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 34 of 37, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on Yesterday, 11:20:

So how should I handle the sync signals then? Like I said, right now it clears the horizontal or vertical CRTC axis for rendering the next pixel. Holding the signal high keeps it there until it's lowered. Or should I just trigger on going high, then render black pixels normally each clock for the remainder of the programmed sync?

I'm pretty confident the sync pulses are edge triggered.* It should be a positive edge trigger for positive vsync and a negative edge trigger for negative vsync. On most monitors the beam should be disabled during flyback, but there is some residual leakage that can make the vertical flyback path visible if you crank the brightness way up. A good question might be how long flyback takes. The voltages involved preclude me from investigating with my oscilloscope. I'd say that rendering black pixels is a reasonable choice to make, but I would choose a fixed period rather than stretching it out over the full length of the pulse.

Here's a real world example: on the CGA, the horizontal sync width is set to 10 in both 40 and 80 column modes. Given that the dot clock is halved in 40 column mode, this means that the hsync width is twice as wide. The picture is only centered evenly when switching between 80 and 40 column modes if you ignore this and used a fixed flyback period.

What is fun is if you actually emulate the horizontal and vertical sync PLLs. You can get a realistic 'screen bounce' when changing video modes.
https://oldbytes.space/@gloriouscow/115782818382812860

This is not a new technique and other emulators have done it prior, but I think it's neat. Note that there are some newer demo effects that involve generating an sync pulse that must be ignored by the monitor's PLL, although simply putting in logic to enforce a minimum time between sync pulses would probably be sufficient.

*EDIT: Somehow missed mkarcher's post above, so this repeats some of what he said. He mentions that on some monitors the flyback may be triggered by the center of the pulse, which I have no reason to doubt given his proven exepertise. I am fairly confident that on the 5153 it is the start of the pulse, or else I cannot see how 40 and 80 column modes maintain alignment, but on other monitors you may not want to make that assumption. If I can find a safe way to probe this someday, it might be interesting to compare the sync signals from the CRTC, the sync signals on the video output, and the flyback control signals out of the sync processor, so you can see the relative timings of each.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 36 of 37, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on Yesterday, 16:08:

And without the PLL emulation?

Whatever makes sense to you. I think I had logic to ignore vsyncs if we weren't past scanline 200. What are your goals? This stuff really only has an affect in demos that do fancy CRTC timing tricks.

MartyPC: A cycle-accurate IBM PC/XT emulator | https://github.com/dbalsom/martypc

Reply 37 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

Currently retraces are instant, without any PLL logic. I can make it render the 'retrace' as normal scanline data (1 pixel/clock) instead of retracing the entire retrace period, but I don't know what that'll do to the image aspect ratio (if it becomes more or less correct or too much?).

Edit: My first attempt: turning retraces into blanking rendering horizontal pixels.

The attachment UniPCemu_20260121_1929_retracesbecomeblanking.png is no longer available

And yeah, I know it's an unfinished graphics card I'm working on adding emulation for atm. It's still a WIP for the newer features (basically a slightly extended W32i right now).
On VGA I'm getting 712x522 rendered pixels (including retrace timings).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io