VOGONS


EGA Questions

Topic actions

Reply 40 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-27, 23:37:

Tell me, is the CGA and Hercules always in word mode and bit 0 is always filled with zero?

Text mode and CGA compatible low-res graphics operate in word mode. There is no BIOS-supported Hercules-compatible mode, although the hardware should be capable of Hercules-compatible memory layout, so I will postpone Hercules for now. Text mode is required to be in word mode, because the EGA hardware needs to fetch the character byte (from plane 0) and the attribute byte (from plane 1) at the same time in on go. Planes 0 and 1 are used as 16-bit memory here. Two 8-bit reads would be too slow. As the character bytes for neighbouring characters are two bytes apart in the ISA memory space, and there is no capability of rotating the ISA address before it gets the VRAM address, the CRTC needs to run in word mode to match that. CGA low-res graphics also requires word mode, because this enables the fetching of 8 pixels at once. On the other hand, in CGA high-res graphics mode, the EGA card operates in byte mode and just uses plane 0, as you can see from the register tables in the EGA BIOS:

  • In text modes and low-res CGA graphics modes (0..5), the second sequencer init byte (plane mask, goes to 3C4, index 2) is 003H, enabling planes 0 and 1, while in high-res CGA graphics mode (mode 6), the value is 001H, enabling just plane 0.
  • In text modes and low-res graphics modes, the graphics controller mode register (sixth byte in the graphics controller block, goes to 3CE, index 5) has bit 4 set (010H in text modes, 030H in low-res CGA graphics modes), while it has bit 4 clear in mode 6 (000H). This bit configures internal operation of the graphics controller, which will at least cause the lowest bit of the read plane select register to be replaced by ISA A0, maybe it also has an effect on what happens to the latches.
  • in text modes and low-res graphics modes, the "miscellaneous" register of the graphics controller has bit 1 set (seventh byte in the graphics controller block, goes to 3CE, index 6). The value is 00EH in text modes, 00FH in CGA low-res graphics modes and 000H in CGA high-res graphics mode. While it seems surprising that the graphics controller has two odd/even bits, their purpose is different. All bits of index 5 are handled by both 16-bit graphics controller (often called graphics controller A and graphics controller B) and configure the internal operation. On the other hand, index 6 is just a general-purpose output register, with the low two bits handled by graphics controller A and bits 2 and 3 handled by graphics controller B. You see an indication for this interpretation in the schematics, which names the pin "GP1" on graphics controller A, but calls the signal generated from it "CHAIN". The "CHAIN" signal enables the munging of ISA address bit 0 using dedicated TTL logic.
  • The sequencer memory mode register of the sequencer (last sequencer byte, goes to 3C4, index 4) is 03H in text modes, 02H in low-res CGA graphics modes and 06H in CGA high-res graphics. Odd/even is controlled by bit 2 in this register (odd/even enabled if 0, odd/even disabled if 1). The purpose of this bit is to prevent /RAS1 and /RAS3 if the ISA address is even and to prevent /RAS0 and /RAS2 if the ISA address is odd, directing data to the correct planes for ISA writes in odd/even mode. This is the opposite of the purpose of the graphics controller mode register that directs data from the correct planes for ISA reads in odd/even mode.

Furthermore, we can observe that bit 1 of the sequencer memory mode register is always set, and that's the bit that allows access to banks 1 to 3 (256K mode). This means that B800:4000 (aka BC00:0000) will end up in bank 1 (the second bank), and thus you only get 4 pages of text in 80x25 modes on a 64K EGA card. If that bit were clear, B800:4000 will alias to bank 0 (so it will hit memory that is present on any EGA configuration), but only if the memory expansion module is not installed, the access will target address 0001 in bank 0. With the memory expansion module installed, the access would target address 0000 in bank 0 and alias to B800:0000. So for optimal text mode usage, it seems to make sense that this bit would be clear on 64K cards, but set if more memory is installed. Note that clearing this bit likely would not only make bank 0 show up at segment BC00, but also prevent access to the fonts stored in banks 1 to 3. On a 64K card, this wouldn't create any issue, as there is no bank 1 to 3, so there is no need to fetch fonts from them, but this shows yet another reason that this bits needs to be set to fully utilize the BIOS-advertised capabilities of a 256K EGA card.

So, the answer to your question (excluding Hercules for now) is that word mode is used in every CGA-compatible mode except high-res graphics. All CGA-compatible modes generate 8 pixels per video RAM access (one text mode character from a character/attribute pair, 8 4-color pixels from a word or 8 2-color pixels from a single byte). Now for "Hercules": If you actually mean mode 7 (MDA text) by that, it will also use word mode. On the other hand, if you think about a monochrome graphics mode with Hercules-type memory layout, it would most likely be implemented just like CGA mode 6 using byte mode.

On the other hand, you might also wonder whether you could use word mode in CGA mode 6 or a Hercules-compatible graphics mode, and as I understand it, the answer is actually: Yes, and you would need it for a Hercules-compatible graphics mode on a 64K EGA card. Mode 0Fh for 64K cards clearly shows that you can get 32K of linear video memory that way, and it is scanned out producing 16 pixels per video memory read. Note that this only works if the memory extension module is not installed, because only then ISA A14 is mapped to A0 in word mode, showing the "odd half of video meory" at A000:4000 (or B000:4000 for Hercules-type, or B800:4000 for CGA-type memory mapping). With a 256K EGA card and the 128K mapping, you could get that mode kind-of working, but instead of having the 4 Hercules "banks" at B000:0000, B000:2000, B000:4000 and B000:6000, they would appear at A000:0000, A000:2000, B000:0000 and B000:2000, which is not compatible to anything.

Not using word mode for CGA mode 6 on 64K cards seems like a lost opportunity! if you operate the card in 16-pixels-per-memory-read mode, you require only half as much memory reads for video scanout, and thus it seems you could use the 2:3 split between CRTC access to video memory instead of the 4:1 split. Typically, the 2:3 split (2 cycles to the CRTC, 3 cycles available for ISA access) is only used in 320-pixel modes, while the 4:1 split that provides twice the bandwidth to the CRTC is used in 640-pixel modes. This split type is selected using bit 1 of the sequencer clocking mode register (3C4, index 1), and you see that this bit is clear (high CRTC bandwidth) in modes 2,3,6,7, but set (high ISA bandwidth) in modes 0,1,4,5. Looking at the mode 0F/10 tables, IBM did not use the mode with low CRTC bandwidth for the 64K variant of the EGA card. At the moment, i don't know whether this is for technical reasons (i.e. the 2 cycles assigned to the CRTC does not match the timing pattern required to support 4-color graphics modes) or for political reasons, as running the sequencer in high-ISA-bandwidth mode on 64K cards in 4-color mode 10h, but running it in low-ISA-bandwidth mode on 256K cards may cause a notable performance loss in the EGA signature mode if the user upgrades from 64K to 256K, which is not something IBM likely wants their users to experience, even it is perfectly explainable that a 16-color mode leaves less drawing bandwidth to the CPU than a 4-color mode does. If the low-bandwidth mode actually works in 4-color mode 10h, it might have been a good idea to provide both the "fast 4-color mode" and the "slow 16-color mode" on 256K cards. But just as we discussed that the 720x350 (or 720x348) Hercules-type resolution is missing on EGA mono, while the card could perfectly provide it, it seems like IBM tried to limit mode proliferation by purposefully limiting the amount of video modes available.

By the way, that makes me wonder about VGA mode 11 (640x480 monochrome). That mode could be implemented in the 32-pixels-at-a-time mode (VGA only, not present on EGA) using doubleword mode (VGA only again), instead of byte mode only using plane 0, which would provide performance advantage because less bandwith is needed by the CRTC and also because early 16-bit ISA VGA cards only allowed 16-bit cycles in word and doubleword mode, but we likely should keep this tangent out of this thread...

Reply 41 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++

About VGA mode 11h's shift register behaviour, yes, that's indeed true. And probably true on EGA as well, as it's the same shift register being used. (https://hackaday.io/project/6150-beckman-du-6 … -a-new-vga-mode)

Right now, my emulator performs 'translation' from the CPU memory address to VRAM planar address in odd/even mode like this:
1. Load the offset into both the plane select and offset variable.
2. Only take the lowest bit of the plane select to select odd/even planes.
3. Replace bit 0 of the offset with:
3.1. 128K window with sequencer memory mode register bit 1 set: bit 16
3.2 128K window with sequencer memory mode register bit 1 cleared: bit 14
3.3 Non-128K window: miscellaneous output register bit 5 inverted.
4. Calculate the planes to read using 5 shifted left by the bit obtained from the CPU, selecting planes 0&2 or 1&3.
5. If it's a read, if the read map select register bit 1 is cleared, mask the lower planes (bits 0/1 of the plane select), otherwise the higher planes (bits 2/3).

Then afterwards, the write or read mode is applied.
The read mode has an oddity there: the latch is loaded from the calculated VRAM offset (64K) and afterwards the read mode (0 or 1) is applied. The read mode 1 just uses the latches for it's result. Read mode 0 however does read VRAM and simply returns the lowest plane selected by the planes selected in the above calculation. This VRAM read, as well as the loading of the latches always read all 4 planes in one go (as a 32-bit doubleword). Since the VRAM is effectively mapped like 'plane 0 byte 0, plane 1 byte 0, plane 2 byte 0, plane 3 byte 0, plane 0 byte 1 etc.' the entire doubleword can be read in one go for either CPU or latch reading, as well as being loaded that way in text/graphics modes (for plane0/1 for text mode or for the shift register in all graphics modes).
Text mode just uses the plane0/1 bytes and fetches the glyph from VRAM from plane 2 itself.
Graphics mode on the other hand loads it into a shift register, which is (for optimization) decoded into 8 pixels in one go, with the loaded value functioning as a shift register with taps every 8 bits (so bit 0,8,16,24 have the taps in planar mode for example, shifting out 1 bit at a time, for 8 bits in one go). The shift register retains it's values and is simply rotated left by 8 bits after that to keep the shift register functioning when it isn't loaded every 8 pixels (16 or 32 pixel modes, as the hackaday post mentions).
Logically, this should be able to be done on EGA just as well as on VGA (excluding any register bits that aren't implemented in the EGA of course).

So just the final VRAM handling itself, which reads using an address supplied either a 32-bits block containing all 4 planes (when loading the latch for rendering (this is also the shift register in graphics modes) or the latch for the CPU (when the CPU reads from VRAM) just masks it's address bit masking off the top 2 bits in '64K' mode (sequencer register 4 bit 1 being cleared masks off any bits past MA15).

That's the way it's implemented for odd/even mode inside UniPCemu right now.

One nice thing about only 64K of memory inside UniPCemu is that the VRAM addressing itself doesn't change with less memory. Plane 0-3 are always available, granted that the amount of VRAM configured is a multiple of 4 bytes (otherwise the final address will only have a part of it's planes available, starting from plane 0).

Of course, the sequencer register 4 bit 1 also has an extra effect on it's VRAM plane 2 fetches: it forces the base offset to be 0 instead of character set A/B stuff that's usually calculated, just as is documented.

One interesting things that my emulator also performs is that it shadows the VRAM plane 2 data into a lookup table for fast decoding of the pixels to render in text mode (which is updated either globally (all character glyphs, like on a mode change (like the sequencer memory mode bit 1 being changed)) or locally (just the byte that's written into VRAM).

About that shift 4 (bit 4) mode, yes it's VGA-only. But the shift 2 (bit 2, SLR bit) exists on the EGA as well, so it can be used to perform 16-bit latches instead of the usual 8-bit in much the same way (using the same shift register, just shifting 16 bits every 2 loads (of which one load isn't performed due to already having been load into the shift register)).

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

Reply 42 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t

I think you are looking at read mode 0 in a different way than the hardware does. Every 8-bit ISA read (lets not talk about 16-bit (S)VGA cards right now) always causes a 32-bit read from the video RAM to the 32-bit latch (aka the four 8-bit bit latches). The difference is only how the read result is calculated from the latch contents. In read mode 0, you get the plane indicated by the "read plane select" register (which is always a single, unique plane, so no need to talk about the "lowest active plane"). In the case of odd/even addressing, replace the lowest bit of the read plane select register by A0. In case of chain-4 addressing (VGA only), use A0 and A1 instead of the contents of the read plane select register.

Manipulation of A0 is not implemented correctly in 64K EGA mode. Actually, as I extracted from the C&T CS8240 datasheet and the IBM EGA schematics, A0 is replaced by

  • A16 if 128K map is enabled, and the card is in 256K mode
  • ~MiscOut5 if 128K map is disabled, and the card is in 256K mode (you also apply this case in 64K mode, which is not how iBM or C&T EGA hardware behaves)
  • A14 if 128K map is disabled, and the card is in 64K mode (you apply this if 128K map is enabled, which is wrong)
  • A0 is left alone if 128K map is enabled and the card is in 64K mode. (this variant makes no sense, but that's what IBM did and cloners were forced to copy)

Note that "card is in 256K mode" means a different thing on the original IBM EGA card than using C&T chipset: On the original IBM card, the "card is in 256K mode" if the memory expansion piggyback PCB is physically installed, no matter what register values are programmed. On the C&T chipset, the card is in "256K mode" if memory mode bit 1 is set.

Reply 43 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2025-12-28, 13:36:
I think you are looking at read mode 0 in a different way than the hardware does. Every 8-bit ISA read (lets not talk about 16-b […]
Show full quote

I think you are looking at read mode 0 in a different way than the hardware does. Every 8-bit ISA read (lets not talk about 16-bit (S)VGA cards right now) always causes a 32-bit read from the video RAM to the 32-bit latch (aka the four 8-bit bit latches). The difference is only how the read result is calculated from the latch contents. In read mode 0, you get the plane indicated by the "read plane select" register (which is always a single, unique plane, so no need to talk about the "lowest active plane"). In the case of odd/even addressing, replace the lowest bit of the read plane select register by A0. In case of chain-4 addressing (VGA only), use A0 and A1 instead of the contents of the read plane select register.

Manipulation of A0 is not implemented correctly in 64K EGA mode. Actually, as I extracted from the C&T CS8240 datasheet and the IBM EGA schematics, A0 is replaced by

  • A16 if 128K map is enabled, and the card is in 256K mode
  • ~MiscOut5 if 128K map is disabled, and the card is in 256K mode (you also apply this case in 64K mode, which is not how iBM or C&T EGA hardware behaves)
  • A14 if 128K map is disabled, and the card is in 64K mode (you apply this if 128K map is enabled, which is wrong)
  • A0 is left alone if 128K map is enabled and the card is in 64K mode. (this variant makes no sense, but that's what IBM did and cloners were forced to copy)

Note that "card is in 256K mode" means a different thing on the original IBM EGA card than using C&T chipset: On the original IBM card, the "card is in 256K mode" if the memory expansion piggyback PCB is physically installed, no matter what register values are programmed. On the C&T chipset, the card is in "256K mode" if memory mode bit 1 is set.

So on the original EGA card, Sequencer register 04h bit 1 has no effect on the odd/even mode? But on (S)VGA cards it does have effect?

Edit: Also, what software do you recommend for testing all these EGA/VGA settings to behave properly? I just run CheckIt Diagnostics (and ofc a BIOS POST first) for starters, followed by some EGA/VGA games like:
- Duke Nukem (EGA)
- Simcity 2000 ((S)VGA, 386+)
- Jazz Jackrabbit (VGA, 386+)
- Hocus Pokus
- Eye of the Beholder (VGA)
- Doom 1/2 (VGA)
- Winter Games (VGA, 386+)
- 688 attack sub
- Lotus 123 R3 (some nice EGA compatibility stuff in it's text/graphics rendering)
- Silpheed
- VGATest2

Any other good advice for test programs for EGA/VGA emulation?

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

Reply 44 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2025-12-28, 16:51:

So on the original EGA card, Sequencer register 04h bit 1 has no effect on the odd/even mode? But on (S)VGA cards it does have effect?

I didn't do a survey across VGA cards, but i can definitely tell you that on the original IBM EGA sequencer, there is no output pin indicating the state of 3C4, index 04, bit 1. Also, the sequencer has no output for video RAM address bit 0. So clearly, it is impossible for sequencer register 04 bit 1 to have an effect on A0 generation on the original IBM EGA card. The C&T CS8240 EGA chipset i keep referencing (because i have the data sheet at hand) has a different architecture. It is meant for either a single bank of 16K * 32 (8 chips of 16K * 4), or a single bank of 64K * 32 (8 chips of 64K * 4), and it has no hardware input to know which type of memory is installed (in contrast to the IBM EGA card, on which there is a presence detect pin for the memory expansion module, so the hardware can detect whether it is in a 64K configuration or more memory is available). The C&T Sequencer, the 82C432A, does have an output pin for index 04, bit 1, called "MEMOPT", just like IBM calls the hardware presence detect signal for the memory expansion module. The MEMOPT signal is handled by addressing logic inside the C&T CRTC, the 82C434A in exactly the same way as IBM implemented in dedicated logic. C&T managed to put a lot of addressing logic into the CRTC (which is discrete TTL chips on the IBM card) by using a 84-pin PLCC package for the CRTC instead of a 40-pin DIP package.

So, I can confirm that on the IBM EGA, 3C4, index 04, bit 1 has no effect on video RAM A0 generation, while on EGA cards based on the C&T 8240 chipset, it does. I have no idea whether any cards that do not support a 64K memory configuration at all (that is any VGA card) still implements the "use ISA A14 for VRAM A0" logic at all. As 64K EGA cards were obsolete by ~1987, and the installed base was quite low, I suppose you will not find a lot of software that depends on the specifics of odd/even mode in a 64K configuration.

I'm sorry, but I don't think I can give a nice overview on software exercising different EGA features. Maybe you should get the authors of Area 5150 and 8088 MPH to do an EGA demo next, which would provide excellent test material 😉

Reply 45 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2025-12-28, 16:51:

Edit: Also, what software do you recommend for testing all these EGA/VGA settings to behave properly? I just run CheckIt Diagnostics (and ofc a BIOS POST first) for starters, followed by some EGA/VGA games like:
- Duke Nukem (EGA)

Any other good advice for test programs for EGA/VGA emulation?

You're familiar with some of these already, but I provide this list for anyone that runs across this thread:

Commander Keen 1 (EGA/VGA) - this is a good test for start address latch timing, if you get it wrong on the EGA scrolling will be jerky and sometimes look like you jump backwards a bit.
Commander Keen 4 (EGA/VGA) - Keen 4 was the first keen title on a new engine that used 256K wraparound logic instead of the old dynamic tile refresh engine from Keen 1-3. It has an SVGA compatibility mode for SVGA cards with > 256K RAM that do not gate said RAM off behind a feature bit.
Dangerous Dave in the Haunted Mansion (EGA) - The title screen is 2x wide and pans smoothly right and left until the user starts the game. Scrolling should be smooth and not jerky. Look for a hardware capture if possible as many youtube videos just show an emulator handling it badly.
Fantasy Land (EGA) - a rare, extensive test of the EGA's text-mode pel panning and vsync interrupts. Requires EGA dip switch set to force 15.7Khz text mode. (CGA monitor)
Gauntlet (EGA) - another title that requires EGA vsync interrupt emulation.
Catacombs 3d (EGA/VGA) - a good example to try on EGA and VGA as it has a HUD drawn via the line compare register and the handling of that is a bit different on each card.
"Yo!" by Future Crew (VGA) - a demo that shows off VGA text mode pel panning effects, and also uses a line-compare split screen - a good test of pel-pan + line compare logic. All scrolling effects should be smooth and pixel-accurate.
EGAD - https://archive.org/details/EGAD_EGA_Demo - Besides showing off various effects in 640x350 mode, it has an EGA palette tester.
Windows 3.0/3.1 - The EGA and VGA drivers are good workouts for your planar read and write modes. Moving windows around and cards in Solitaire should not result in pixel artifacts being left un-erased.
Ironman Offroad (EGA) - Supports 6-bit color in 15.7Khz mode on supporting monitors.
Lemmings (VGA) - in "high performance" mode the game reprograms the attribute palette registers in a black region between the playfield and HUD every frame.
EGAPALET (EGA) https://forum.vcfed.org/index.php?threads/ega … de.67207/page-2 - This will show 64 simultaneous colors on screen on an EGA. Needs a 286 or about an 8Mhz 8088.
MELT (EGA) https://forum.vcfed.org/index.php?threads/ega … 3/#post-1366687 demonstrates per-scanline pel-panning for raster effects.
Beverly Hills Cop (EGA) - Shows a per-scanline pel-panning effect in the intro text scroll.

There is a particularly interesting VGA torture test if you emulate the Tseng ET4000AX.
Copper (VGA) - https://www.pouet.net/prod.php?which=2048 https://www.youtube.com/watch?v=hSv4gbxZJr8

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

Reply 46 of 58, by Jo22

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2025-12-29, 19:10:

There is a particularly interesting VGA torture test if you emulate the Tseng ET4000AX.
Copper (VGA) - https://www.pouet.net/prod.php?which=2048 https://www.youtube.com/watch?v=hSv4gbxZJr8

Hi! Years ago I've run the Copper demo on a couple of ISA VGAs out of curiosity.
Interestingly, the on-board Trident 9000 VGA chip in a 286 PC seemed to be able to handle some of the ET-4000 effects (partially).
https://www.youtube.com/watch?v=NcyDC2mGQa4

"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 47 of 58, by SoftCat

User metadata
Rank Member
Rank
Member

mkarcher, thank you so much for the detailed explanation! I'll be looking into it little by little.
It turns out that EGA and (S)VGA cards have more precise horizontal scrolling (by 8 pixels) in mode 6 than CGA cards. I'm only referring to the scrolling achieved by changing the starting address. DOSBox has a bug here: in mode 6, horizontal scrolling is always by 16 pixels.
Incidentally, back in the 90s, the game "Leisure Suit Larry in the Land of the Lounge Lizards" (1987) ran in mode 6 on my EGA card for some reason. That is, the card was recognized as CGA. Now I'm curious, why did this happen?

Reply 48 of 58, by SoftCat

User metadata
Rank Member
Rank
Member

Can anyone share with me the C&T CS8240 datasheet?

Reply 50 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-30, 15:32:

Here, I found it, but it says "CS4280." Is that it?
https://theretroweb.com/expansioncards/s/unkn … -ega-c-t-cs4280

Yes, the datasheet linked for the chips on that card is the datasheet I referenced multiple times in this thread. I guess the card name has a typo.

Reply 51 of 58, by SoftCat

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-12-30, 17:23:

Yes, the datasheet linked for the chips on that card is the datasheet I referenced multiple times in this thread. I guess the card name has a typo.

Got it, thank you.

Reply 52 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++

What happens when the odd/even addressing mode is used for the current read or write mode and bit 1 of the miscellaneous graphics register (index 06h of the graphics controller) is cleared? What is put on the MA0 of the resulting memory address (as it's mapping to plane 0/1 or 2/3 instead)?

From what I can gather about the menioned LS151 on sheet 4 of 11:
- The misc output register CHAIN bit supplies bit 1 of the LS151 mux select (it's B pin)
- The A pin is from sheet 11 MEMOPT (active low). Some memory expansion bit? So if memory expansion, it's low (0), otherwise high (1)? Perhaps the extended memory bit? It seems to select A14 in one specific case? Is this perhaps from the sequencer memory mode register bit 1?
- The C pin goes to Q0 (14) of U48. No clue what that contains. Some ROM output? From what I can tell by your information, this is the 128K address map being enabled?

Those 3 pins specify one of the D pins for output?
And the D pins are connected to:
D0: A0
D1: A0
D2: PGSEL (sheet 9). This seems to be the misc output register bit 5
D3: A14
D4: A0
D5: A0
D6: A16
D7: A0

Those D inputs are chosen from, according to the documentation, using the CBA pins as a 3-bit number (C the most significant bit and A the least significant bit).

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

Reply 53 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2026-01-02, 22:58:

What happens when the odd/even addressing mode is used for the current read or write mode and bit 1 of the miscellaneous graphics register (index 06h of the graphics controller) is cleared? What is put on the MA0 of the resulting memory address (as it's mapping to plane 0/1 or 2/3 instead)?

Bit 4 of 3CE index 5 (not the bit you mentioned) decides how read mode 0 is handled. if that bit is set (graphics controller in odd/even mode), the plane is selected using the ISA A0 and bit 1 of of the read plane select (aka read map select register). if bit 4 of 3CE index 5 is clear, the read plane is selected using both select bits from the read plane select register.

The only purpose of 3CE index 6 is to set the level of the output pins GP0/GP1 of the IBM graphics controller (bit 0/1 of 3CE set GP0/GP1 of Graphics Controller A; bit 2/3 of 3CE set GP0/GP1 of Graphics Controller B). These bits are called GRAPHICS, CHAIN, CDSEL0 and CDSEL1 in the IBM schematics. 3CE index 6 has not effect on the operation of the graphics controller.

superfury wrote on 2026-01-02, 22:58:

- The misc output register CHAIN bit supplies bit 1 of the LS151 mux select (it's B pin)

Correct.

superfury wrote on 2026-01-02, 22:58:

- The A pin is from sheet 11 MEMOPT (active low). Some memory expansion bit? So if memory expansion, it's low (0), otherwise high (1)? Perhaps the extended memory bit? It seems to select A14 in one specific case? Is this perhaps from the sequencer memory mode register bit 1?

On the IBM EGA, /MEMOPT is driven by the expansion board. See PDF page 102 of https://minuszerodegrees.net/oa/OA%20-%20IBM% … s%20Adapter.pdf . MEMOPT is pin 50 of the expansion board connector, and pulled up by a resistor on the EGA base PCB. The expanion board pulls it to ground (the ground symbol located at the right side of the connector P1). This bit is not controlled by software using some register bit.

Of course, that approach only works if upgrading RAM actually involves a hardware change as it does on the IBM EGA. Cards based on the CS8240 do not have that possibility. There is no jumper to be set if you replace 4464 chips by 44256 chips, and you don't have to install any extra PCB. Chips & Technology thus decided to derive /MEMOPT from sequencer memory mode register. As far as i understand it, on a CS8240-based EGA card with 256K installed, if you clear sequencer memory mode bit 1, it will behave like an IBM EGA card without the memory expansion board. Behaving like a 64K card if more memory is present is something the original IBM EGA card can not do: On the original IBM EGA card, as soon as the memory board is installed, /MEMOPT is always low.

superfury wrote on 2026-01-02, 22:58:

- The C pin goes to Q0 (14) of U48. No clue what that contains. Some ROM output? From what I can tell by your information, this is the 128K address map being enabled?

Yeah, that's correct. There is a clue on the IBM schematic: If you follow the trace from the ROM output to the right towards the pullup resistor, you will find the label "A000:128K".

superfury wrote on 2026-01-02, 22:58:
Those 3 pins specify one of the D pins for output? And the D pins are connected to: D0: A0 D1: A0 D2: PGSEL (sheet 9). This seem […]
Show full quote

Those 3 pins specify one of the D pins for output?
And the D pins are connected to:
D0: A0
D1: A0
D2: PGSEL (sheet 9). This seems to be the misc output register bit 5
D3: A14
D4: A0
D5: A0
D6: A16
D7: A0

Those D inputs are chosen from, according to the documentation, using the CBA pins as a 3-bit number (C the most significant bit and A the least significant bit).

Thats completely correct. U37 on page 9 (74LS273) is the latch implementing the misc output register.

If bit 1 (B input) is cleared (that is CHAIN is not set), you get one of D0, D1, D4 or D5, which is A0 in any case. As bit 0 (A input) is connect to /MEMOPT), D2/D6 is used if /MEMOPT is clear (memory expansion board installed, i.e. card in "256K mode"). D3/D7 is used if /MEMOPT is set (memory expansion board is not installed, i.e. card in "64K mode"). So that's why with the memory module, you get the page select bit (misc output 5) or A16, but without the memory module installed, you get A14 or A0, the latter being pointless. In my oppinion, it would make much more sense if D7 would have been connected to A14 just as D3.

Maybe you wonder why the page bit in the misc output register is inverted, but you don't see any inverters in that path. That's because the address bits on the EGA card are inverted using the 74LS04 invertering drivers U45-U47, and the EGA card internally operates using negated addresses. The only thing that is not inverted is the PGSEL bit, and that's why the PGSEL bit is functionally inverted.

Note that 128K and 192K are valid memory amounts on the original IBM EGA card, but the card will be in "256K mode", as i call it. While 64K cards are uncommon, 128K and 192K configurations are likely really rare to encounter in practice. OTOH, 128K would be the logical step up from single-page 4-color at 640*350 to single page 16-color at 640*350, so 128K might have made some sense in 1985. Most later EGA clones (e.g. the C&T 8240 chipset) just support a single bank (of either 64kBit or 256kBit chips), so they physically can not be equipped with 128K or 192K.

Reply 54 of 58, by SoftCat

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-12-25, 22:15:

The VGA hardware also provides the necessary functionality to get a 2-color 4-page mode, whilst the EGA hardware does not. As VGA always has at least 256K of RAM, which provides a 16-color 4-page mode, this is likely not interesting.

I think you can implement page switching on both EGA and VGA using palette tricks. Specifically, you can create a 2-page 4-color and 4-page 2-color 640x200 mode on a 64 KB EGA. You can also create a 2-page 4-color and 4-page 2-color 640x480 mode on a 256 KB VGA.
For a 2-page 4-color 640x200 mode on a 64 KB EGA, the palette should be set as follows:

Page 1

0000b --> 000000b
0001b --> 010000b
0010b --> 000111b
0011b --> 010111b
0100b --> 000000b
0101b --> 010000b
0110b --> 000111b
0111b --> 010111b
1000b --> 000000b
1001b --> 010000b
1010b --> 000111b
1011b --> 010111b
1100b --> 000000b
1101b --> 010000b
1110b --> 000111b
1111b --> 010111b

Page 2

0000b --> 000000b
0001b --> 000000b
0010b --> 000000b
0011b --> 000000b
0100b --> 010000b
0101b --> 010000b
0110b --> 010000b
0111b --> 010000b
1000b --> 000111b
1001b --> 000111b
1010b --> 000111b
1011b --> 000111b
1100b --> 010111b
1101b --> 010111b
1110b --> 010111b
1111b --> 010111b

For a 4-page 2-color 640x200 mode on a 64 KB EGA, the palette should be set as follows:

Page 1

0000b --> 000000b
0001b --> 000111b
0010b --> 000000b
0011b --> 000111b
0100b --> 000000b
0101b --> 000111b
0110b --> 000000b
0111b --> 000111b
1000b --> 000000b
1001b --> 000111b
1010b --> 000000b
1011b --> 000111b
1100b --> 000000b
1101b --> 000111b
1110b --> 000000b
1111b --> 000111b

Page 2

0000b --> 000000b
0001b --> 000000b
0010b --> 000111b
0011b --> 000111b
0100b --> 000000b
0101b --> 000000b
0110b --> 000111b
0111b --> 000111b
1000b --> 000000b
1001b --> 000000b
1010b --> 000111b
1011b --> 000111b
1100b --> 000000b
1101b --> 000000b
1110b --> 000111b
1111b --> 000111b

Page 3

0000b --> 000000b
0001b --> 000000b
0010b --> 000000b
0011b --> 000000b
0100b --> 000111b
0101b --> 000111b
0110b --> 000111b
0111b --> 000111b
1000b --> 000000b
1001b --> 000000b
1010b --> 000000b
1011b --> 000000b
1100b --> 000111b
1101b --> 000111b
1110b --> 000111b
1111b --> 000111b

Page 4

0000b --> 000000b
Show last 16 lines
0001b --> 000000b
0010b --> 000000b
0011b --> 000000b
0100b --> 000000b
0101b --> 000000b
0110b --> 000000b
0111b --> 000000b
1000b --> 000111b
1001b --> 000111b
1010b --> 000111b
1011b --> 000111b
1100b --> 000111b
1101b --> 000111b
1110b --> 000111b
1111b --> 000111b

Reply 55 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2026-01-20, 23:00:
mkarcher wrote on 2025-12-25, 22:15:

The VGA hardware also provides the necessary functionality to get a 2-color 4-page mode, whilst the EGA hardware does not. As VGA always has at least 256K of RAM, which provides a 16-color 4-page mode, this is likely not interesting.

I think you can implement page switching on both EGA and VGA using palette tricks. Specifically, you can create a 2-page 4-color and 4-page 2-color 640x200 mode on a 64 KB EGA. You can also create a 2-page 4-color and 4-page 2-color 640x480 mode on a 256 KB VGA.

Yes, of course. I was thinking inside the wrong box. The palette method works, and also allows to display a mix of both "pages" (either one in front; one page red/one page blue) using clever palette settings.

I was specifically thinking inside the box that the pages should appear one after the other on the ISA bus, just as the odd/even + word mode logic does in 640x350/4colors. VGA can do chain-4/dword mode and 32 monochrome pixels per word, while EGA only supports 16 pixels (4 colors each) per word. The palette pages don't appear at different ISA addresses, instead you need to select them using the read map select / write mask register - which is most likely a good thing, because this also allows access to each monochrome page without any I/O port access. It also allows four pages at 640x480 in the 64K address space.

Thanks for bringing this idea into this thread.

Reply 56 of 58, by SoftCat

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2026-01-21, 00:40:

Yes, of course. I was thinking inside the wrong box. The palette method works, and also allows to display a mix of both "pages" (either one in front; one page red/one page blue) using clever palette settings.

I was specifically thinking inside the box that the pages should appear one after the other on the ISA bus, just as the odd/even + word mode logic does in 640x350/4colors. VGA can do chain-4/dword mode and 32 monochrome pixels per word, while EGA only supports 16 pixels (4 colors each) per word. The palette pages don't appear at different ISA addresses, instead you need to select them using the read map select / write mask register - which is most likely a good thing, because this also allows access to each monochrome page without any I/O port access. It also allows four pages at 640x480 in the 64K address space.

Thanks for bringing this idea into this thread.

I myself didn’t know anything about this method before and only figured it out recently.

Reply 57 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've just been thinking. If the sequencer memory mode register bit 1 has no effect on the EGA memory mapping (and instead comes from the memory expansion being installed (grounded) or not), what effect does it actually have?

Edit: Just took another look into the EGA and FreeVGA documentation.
It looks like the EGA splits the memory mode bits into two compared to the VGA?
EGA:
bit 0: alpha. set to enable the character generator map select function
bit 1: extended memory. 0 for memory expansion board not installed. 1 for installed and enables extended memory access through bits 14 and 15.

FreeVGA:
bit 1: extended memory. enables memory form 64K to 256KB when set to 1. This also enables the character map selection in register 03h.

Did FreeVGA mix up the bits? Or is there some documentation error somewhere?

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

Reply 58 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2026-01-21, 09:32:
It looks like the EGA splits the memory mode bits into two compared to the VGA? EGA: bit 0: alpha. set to enable the character g […]
Show full quote

It looks like the EGA splits the memory mode bits into two compared to the VGA?
EGA:
bit 0: alpha. set to enable the character generator map select function
bit 1: extended memory. 0 for memory expansion board not installed. 1 for installed and enables extended memory access through bits 14 and 15.

FreeVGA:
bit 1: extended memory. enables memory form 64K to 256KB when set to 1. This also enables the character map selection in register 03h.

The bit 1 documentation is actually intending to express the same thing, but I see how you are confused. WHATVGA/VGADOC still has both bits documented, so if bit 0 documentation is missing from FreeVGA, that's likely an omission. OTOH, the EGA/VGA card has multiple bits that control the switch between text/graphics mode distributed over the different components of the EGA card. As the VGA is a single-chip solution, it is possible that VGA uses one of the other bits to toggle between text mode and graphics mode for the function of 3C4, index 4, bit 0.

But it seems I should help to clear your confusion first, and I try to explain stuff using the original EGA schematics. The first thing you need to be aware of is that the memory address bus on the EGA is split in two halves. Planes 0 and 1 (on sheet 6/11) use address bus A, consisting of AA0..AA7, while Planes 2 and 2 (on sheet 7/11) use address bus B, consisting of BA0..BA7. (see also footnote 1). Both memory busses are on the memory expansion board connector as well, because the split address bus is required for proper text mode operation. The designators and sheet numbers show in the memory expansion schematics are a mess and do not help understanding what's really going on, it seems like they did insufficient quality control on the expansion board schematics.

In text mode, only memory address bus A is driven from the CRTC address during CRTC-controlled memory cycles, while address bus B is driven from the scanline counter and the current character code. On the original EGA, this is implemented using discrete logic. Looking at all the memory address bus driving chips, we find:

  • U42 and U52 on sheet 3/11 that drive the CRTC address to memory address bus A. U42 drives the column address and U52 drives the row address. The signals MUX and MUX# are used to enable either the row or the column driver. U6b (pins 4,5,6 of U6) is used to enable the row driver if MUX is high and CRT/CPU# indicates a CRTC cycle. Similarly, U6c (pins 9,10,11 of U6) enable the column driver of MUX# is high and CRT/CPU# indicates a CRTC cycle.
  • U22 and U19, also on sheet 3/11 are used to drive the CRTC address to memory address bus B. The enable logic is similar, but instead of two-input NAND gates, these chips are enabled by 3-input NAND gates: U5b generates the row driver (U22) enable signal similarly to U6b, and U5c generates the column driver (U19) enable signal similar to U6c. The third input of the NAND gates is connected to the output of U17c, which calculates the OR of the GRAPHICS signal (3CE, index 6, bit 0) and the "SREF ADDR" signal. The latter signal indicates that the current memory cycle is a refresh cycle - not a scanout cycle. This signal is originally generated by the CRTC on pin 20 (called REF on the CRTC, and REF ADDR as "signal name", which is misprinted as "REF AGR" on the right edge of sheet 3/11), but it is then synchronized to the character clock using U18b on sheet 5/11. This means these drivers for address bus B are only active in graphics mode and during refresh.
  • U53 and U43 on sheet 4/11 drive address bus A from the ISA addresses. They are enable whenever CRT/CPU# indicates a CPU (ISA) cycle.
  • U4 and U13 on sheet 4/11 drive address bus B from the ISA addresses. They are enable whenever CRT/CPU# indicates a CPU (ISA) cycle.
  • finally, U12 and U3 on sheet 5/11 drive address bus B from the latched row counter and plane 0 data (character code) for font access. Their enable signal is generated using the combination of U27a and U6a/U6d: U27a produces a high ouput only if GRAPHICS is low (inverted to GRAPHICS# by U26b, so if the card is in text mode) and REF ADDR was latched low (inverted by U18b) and CRT/CPU# is high, i.e. this is a CRT cycle. U6a/U6d then enable the row or column driver depending on the MUX state.

All this stuff does not deal with selecting the correct bank. Bank selection on the original EGA card is performed by the sequencer by having one CAS output per bank. Just like the address bits, the CAS signals are also split into "bus A" (for planes 0/1) and "bus B" (for planes 2/3). So the sequencer also needs to know what address source it uses to drive the correct CAS signal. The sequencer knows whether a CPU or a CRTC cycle is hapenning (it outputs the CRT/CPU# signal), and it has both the CPU/ISA A14/A15 bits as input, as well as the CRT A14/A15 bit. On the other hand, the sequencer is not connected to the GRAPHICS signal output by Graphics Controller A, so the sequencer is unable to replicate the address source selection I explained for the lower address bits. This is where both bits 0 and 1 of the CRTC start having an effect. If bit 1 is clear, the CRTC always, unconditionally routes all memory cycles to bank 0, essentially filling the 64K*32 address space of the EGA card with 4 copies of bank 0. On the other hand, if bit 1 is set, the bank selection has to be consistent with the address sources. So on CPU cylces, the sequencer always uses A14/A15 from the ISA bus. On CRTC cycles, the CRTC uses A14/A15 from the CRTC for memory address bus A, but for memory address bus B, it uses CRTC address bits 14/15 only in graphics mode, while in text mode (according to 3C4, index 4, bit 0), it uses the bank indicated in the character map select register. It uses bits 0/1 of that register if attribute bit 3 (foreground intensity) is low, and bits 2/3 of that register, if attribute bit 3 is high. The sequencer gets this bit on pin 3 (called CG) from M1D3 (plane 1, data bit 3).

So this essentially means that the character map select register is only used if bit 0 indicates text mode and bit 1 allows the uses of other banks than bank 0.

1: I first wondered why there are 8 multiplexed address bits, because the memory is organized as 16K * 4, which just needs 14 address bits, so with row/column multiplexing, 7 bits should be enough. Turns out that the TMS4416 chips use 8 row bits and 6 column bits.