VOGONS


First post, by root42

User metadata
Rank l33t
Rank
l33t

I just read in another thread about Hercules CGA emulation. I do remember from way back that friends, who had only Hercules graphics, used such programs. I dove right in with VGA graphics, so I never had to bother.

But how exactly do those emulators work? Do not spare on the nitty gritty technical details!

YouTube and Bonus
80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, SnarkBarker & GUSar Lite, PC MIDI Card+X2+SC55+MT32, OSSC

Reply 1 of 4, by Scali

User metadata
Rank l33t
Rank
l33t

There are a few variations, but in general it is something like this:
Hercules has 64k of memory, where the second 32k is disabled by default, but can be mapped to segment B800h, the same segment as a CGA card uses.
This means that if you enable the second page, and run CGA software, it will 'automagically' write into the Hercules video memory.
If you then also install a TSR that intercepts CGA calls to BIOS int 10h, you can replace the CGA calls with Hercules-compatible calls to enable/disable emulation, set the correct display mode, draw text, pixels and such.

The trick then is to convert the raw CGA data in segment B800h to a visible bitmap on Hercules. There are a few ways to do that.
One is to set up the first 32k (segment B000h) as the visible screen, and periodically copy the data from the 'CGA' buffer to the visible screen, converting the data in the process (CGA is 320x200 or 640x200, and Hercules is 720x350, so aspect conversion is required).

Another way to do that is to set the second 32k up as the visible screen directly, and programming a special tweak mode to create a 'fake' 640x200 window with the same memory layout as CGA (generally this means they skip some scanlines).

The colours 'automatically' work out correctly, because in 320x200, CGA uses 2 bits per pixel. This means that effectively you have 640 bits per scanline, the same as in 640x200 monochrome mode. The 2 bits will generate some basic dithering pattern.

So in short, Hercules emulators exploit the fact that CGA and Hercules are very similar in terms of memory and layout (both also use a Motorola 6845 CRTC to generate the display).
The main difference is that Hercules uses 4 page interleaving, where CGA uses 2-page interleaving... That is, CGA has the even scanlines on one page, and the odd ones on the second (a limitation because the Motorola 6845 CRTC can only handle up to 127 rows per screen), where Hercules has a 4-way scheme to get all 350 scanlines on screen.

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

Reply 2 of 4, by dr.zeissler

User metadata
Rank l33t
Rank
l33t

some emulators do tweaking with the refresh-rate. 60hz instead of 50hz, therefore I have to use a multiscan on some cga-emulation on hercules

Retro-Gamer 😀 ...on different machines

Reply 3 of 4, by root42

User metadata
Rank l33t
Rank
l33t

Ok, that is already a pretty neat answer and makes a lot of sense. However, I do not understand the interleaving part... How are pages defined? What is their size, and how does the "writing directly to the HGC memory" then work out, if the interleaving is different?

YouTube and Bonus
80486DX@33 MHz, 16 MiB RAM, Tseng ET4000 1 MiB, SnarkBarker & GUSar Lite, PC MIDI Card+X2+SC55+MT32, OSSC

Reply 4 of 4, by Scali

User metadata
Rank l33t
Rank
l33t
root42 wrote:

Ok, that is already a pretty neat answer and makes a lot of sense. However, I do not understand the interleaving part... How are pages defined? What is their size, and how does the "writing directly to the HGC memory" then work out, if the interleaving is different?

In CGA, the even scanlines are stored in segment B800h, so scanlines 0, 2, 4... 198
The odd scanlines are stored in segment BA00h, so scanlines 1, 3, 5... 199
Each scanline has 320 pixels, of 2 bits each, so that is a total of (320*2)/8 = 80 bytes per scanline.
These are often called 'bitplanes', although they are somewhat different from 'classic' bitplanes as used by EGA for example (where each bit of a pixel is in a separate plane).
So CGA has two of these 'bitplanes', 8k each, for a total of 16k of memory. This is the entire visible area. There is no additional offscreen memory (aside from a few 'spare' scanlines, since 100 scanlines of 80 bytes only make up 8000 bytes of the 8192).

In Hercules, things are basically the same, except you have 350 scanlines in total and 32k for an entire screen (and it has two screen pages, so you can select a second 32k page for a second screen buffer).
This means that they interleaved it like this (for the second page that is):
Scanlines 0, 4, 8... in the first bitplane at segment B800h
Scanlines 1, 5, 9... in the second bitplane at segment BA00h
Scanlines 2, 6, 10... in the third bitplane at segment BC00h
Scanlines 3, 7, 11... in the fourth bitplane at segment BE00h

Does that make sense?
Again, the problem they work around here is that the CRTC can only 'think' in up to 127 rows. So they basically 'repeat' the same row 4 times on Hercules, switching between the bitplanes for each scanline.
This way the CRTC 'thinks' there are only 87 rows on screen, which fits inside its 7-bit counter register, which can only go up to 127.
The reason behind this is that the CRTC was designed for text displays, not graphics. So it 'thinks' that CGA graphics mode is a mode with 80 characters and 100 rows, where each character is two scanlines high.
On Hercules it thinks graphics mode is 87 rows, with characters of 4 scanlines high.

Because of this hack, it is not possible to have a linear framebuffer layout for larger resolutions on a 6845.

So if you run CGA software on Hercules, it will only write to the first and second bitplane on the Hercules card.

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