VOGONS


EGA Questions

Topic actions

Reply 20 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2025-12-24, 12:11:

Also interesting to note is, that when I compare the values ending up in the BDA (from said MK_ENV call) when the switches are in inversed order on the graphics card, that the "monochrome" bits (switch 3 open and others closed) actually matches the VGA documented 0010b that's documented to appear there on VGA monochrome monitors (reported by grounding just the ID1 pin). Seeing as the VGA is supposed to be EGA-compatible, it looks like the EGA indeed flips the switch numbers (or wiring them inversed).

I showed you how they are reversed on the PCB just a few posts up. It was just a wiring convenience, I figured to wire them in order they'd have had to have flipped the 153 around compared to all of the other chips that face left, or have the wiring take a different, longer path. Looking at the PCB though, the DIP traces run on one of the inner layers and there would have been room between U15 and U6 to run them from the top which would have put them in order.

So who knows, really. IBM probably didn't care what order they were in as it would only ever confuse emulator authors decades later.

Another optimization that led to a quirk is that all the address lines coming off the ISA bus are passed through inverters and so for most of the address logic on the board, the addresses are inverted. So when chips like the graphics controllers and the sequencer get the A0 line to handle odd/even mode they actually get ~A0. To avoid reversing everything in VRAM they used 74LS258 multiplexers to generate the row and column addresses, which are just like 74LS257's but have inverted outputs.

But this means that the address lines to the BIOS ROM are inverted. It would have cost them an extra chip to invert these addresses back, so what they did is just reverse the contents of the ROM.

Last edited by GloriousCow on 2025-12-24, 17:31. Edited 4 times in total.

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

Reply 21 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie

We can get our terminology mixed because the EGA dip switches are both *reversed in position* and *inverted*.

Many dip switches are logically inverted because this is a common way to hook them up:

The attachment dip_diagram.PNG is no longer available

You tie one side of the DIP switch to ground, then you stick a pull-up resistor network to +V on the traces to whatever is reading the DIPs.
When a DIP switch is OFF, there is no connection to ground, so the resistor network pulls the output line up to +V and the switch reads logical 1.
When a DIP switch is ON, a circuit is completed to ground and the switch reads a logical 0.

Nothing forces you to wire it this way, but the convenient thing about it is that you can put your DIP switch pretty much anywhere there is access to the ground plane and the position of the DIP switch usually has some considerations for user accessibility. Especially on the EGA where they wanted you to be able to access it through the ISA card bracket.

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

Reply 22 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie

Another fun fact is that the same 153 multiplexer, U15, is used both to read the DIP switches and select the clock source.
It's a dual package multiplexer so it can do that. The main problem is that it only has one set of input selection lines.

That means if you want to read all the DIP switches, you have to change the EGA clock. This is of course not of much concern if you do it quickly, once, during POST. Reading them in a tight loop afterwards might have ... interesting results. I suspect your monitor will not enjoy it.

Also you'll recall that you set the clock source using two bits of the Miscellaneous Output Register. Value '11' is not defined for good reason - you'll end up selecting output 3 of U15 which isn't connected. So now your EGA has no clock and just stops running altogether. I have run into a few titles, mostly demos, that actually do this (probably on accident) so I assume that clone cards and the VGA handled it a bit more gracefully.

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

Reply 23 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2025-12-24, 17:37:
Another fun fact is that the same 153 multiplexer, U15, is used both to read the DIP switches and select the clock source. It's […]
Show full quote

Another fun fact is that the same 153 multiplexer, U15, is used both to read the DIP switches and select the clock source.
It's a dual package multiplexer so it can do that. The main problem is that it only has one set of input selection lines.

That means if you want to read all the DIP switches, you have to change the EGA clock. This is of course not of much concern if you do it quickly, once, during POST. Reading them in a tight loop afterwards might have ... interesting results. I suspect your monitor will not enjoy it.

Also you'll recall that you set the clock source using two bits of the Miscellaneous Output Register. Value '11' is not defined for good reason - you'll end up selecting output 3 of U15 which isn't connected. So now your EGA has no clock and just stops running altogether. I have run into a few titles, mostly demos, that actually do this (probably on accident) so I assume that clone cards and the VGA handled it a bit more gracefully.

But isn't a clock select 3 required to read the 4th dipswitch? If it crashes the chip, doesn't that make the 4th dipswitch unreadable?

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

Reply 24 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2025-12-24, 20:39:

But isn't a clock select 3 required to read the 4th dipswitch? If it crashes the chip, doesn't that make the 4th dipswitch unreadable?

I didn't say it crashes, I said it stops running. This is the dot clock, to be specific - it's not needed for reading the register. You just get no video.
Maybe "stops rasterizing" is a more accurate way to phrase it.

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

Reply 25 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2025-12-24, 21:20:
superfury wrote on 2025-12-24, 20:39:

But isn't a clock select 3 required to read the 4th dipswitch? If it crashes the chip, doesn't that make the 4th dipswitch unreadable?

I didn't say it crashes, I said it stops running. This is the dot clock, to be specific - it's not needed for reading the register. You just get no video.
Maybe "stops rasterizing" is a more accurate way to phrase it.

Isn't the same true for clock #2? Since only clocks #0 and #1 are connected?
My emulator indeed stops rendering entirely once the 3rd and 4th clocks are set (as they're set to 0Hz on EGA/VGA. The Tseng SVGA chips do have all clocks (16 in fact) however).
Somewhat interesting is that my emulation of the Tseng chips is seemingly the most accurate of all Tseng ETx000(/W32) emulators, even emularing more hidden stuff like the extra CGA translation ROM and enhanced 8 font text mode.

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

Reply 26 of 58, by GloriousCow

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote on 2025-12-25, 10:44:

Isn't the same true for clock #2? Since only clocks #0 and #1 are connected?
My emulator indeed stops rendering entirely once the 3rd and 4th clocks are set (as they're set to 0Hz on EGA/VGA. The Tseng SVGA chips do have all clocks (16 in fact) however).
Somewhat interesting is that my emulation of the Tseng chips is seemingly the most accurate of all Tseng ETx000(/W32) emulators, even emularing more hidden stuff like the extra CGA translation ROM and enhanced 8 font text mode.

Yes, that's correct - it's just that this isn't set by accident as often as 11 is, for whatever reason.

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

Reply 27 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
GloriousCow wrote on 2025-12-24, 21:20:

I didn't say it crashes, I said it stops running. This is the dot clock, to be specific - it's not needed for reading the register. You just get no video.
Maybe "stops rasterizing" is a more accurate way to phrase it.

As a side effect, it also stops refreshing the video RAM, as everything the EGA card does on its own is synchronized to the dot clock. As this also is true for video memory requests from the iSA bus, you get better text mode performance in the high-res EGA text mode (16.257MHz) than in the low-res SGA text mode (14.318 MHz).

On the other hand, some S3 Super-VGA graphics chips, e.g. the 928, do lock up if you select a non-present dot clock.

Reply 28 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-24, 00:54:
The easiest way to do it is like this. […]
Show full quote
mkarcher wrote on 2025-12-16, 22:53:

While I previously claimed that the bit likely exists, I'm actually unsure whether you can have the CRTC address counter wrap around at 16K (the CRTC address counter counts 32-bit units of video RAM, so 16K in that counter is 64KB of RAM). I will check documentation and report back what I find.

The easiest way to do it is like this.

mov ax,40h
mov es,ax
and byte ptr es:[87h],9Fh
mov ax,0Eh
int 10h
.....

EDIT This post is obseleted by Re: EGA Questions and just kept for historic reference. superfury mentioned the control bit in the sequencer that forces all video memory access to go to bank 0 (or to the first 16K addresses in the single bank in later EGA clones using 256K x 4 memory chips).

I would be surprised if that works. What that code does, if I understand it correctly, is to fake a 64K EGA before setting mode 0Eh. As far as I know, mode 0Eh is programmed exactly the same way by the EGA BIOS, no matter what memory size is indicated in the BIOS data area. In the mean time, I checked the CRTC EGA register documentation, and couldn't find any bit that makes the CRTC address counter wrap from 3FFF to 0000 to allow cyclic access to the first 64K, but I did find something that should be good enough for "infinite scroll" purposes: There is the "Hercules compatibility" bit in the CRTC mode register (Index 0x17, bit 1). If you set that bit, the video memory address bit 14 (the one that distinguishes between 4000 and 0000) will be replaced by bit 1 of the character scanline counter - which will be 0 all the time in EGA graphics modes, so 0000..3FFF is accessed when the address counter actually is 4000..7FFF, but after reaching 7FFF, you will get to 8000, not to 0000 again. So you don't get infinite repetitions of the first 64K, just two of them, which should be enough.

Last edited by mkarcher on 2025-12-26, 11:33. Edited 1 time in total.

Reply 29 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-21, 00:14:

Is it possible to set 640x200 mode with at least two pages (4 or 2 colors) on an EGA graphics card with 64 KB of VRAM? If so, how exactly do I do this?
Will this mode work on EGA graphics cards with more VRAM? Will this mode work on original VGA graphics cards?

Check how 64K mode 10h differs from standard mode 10h, and apply those differences to mode 0Eh. If I understand it correctly, you will need to enable odd/even mode, and configure the CRTC to word mode with 14-bit rotation. That will result in a 4-color 2-page variant of mode 0Eh, and is supposed to work the same way on the original VGA card as well.

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.

Reply 30 of 58, by SoftCat

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

I would be surprised if that works. What that code does, if I understand it correctly, is to fake a 64K EGA before setting mode 0Eh. As far as I know, mode 0Eh is programmed exactly the same way by the EGA BIOS, no matter what memory size is indicated in the BIOS data area. In the mean time, I checked the CRTC EGA register documentation, and couldn't find any bit that makes the CRTC address counter wrap from 3FFF to 0000 to allow cyclic access to the first 64K, but I did find something that should be good enough for "infinite scroll" purposes: There is the "Hercules compatibility" bit in the CRTC mode register (Index 0x17, bit 1). If you set that bit, the video memory address bit 14 (the one that distinguishes between 4000 and 0000) will be replaced by bit 1 of the character scanline counter - which will be 0 all the time in EGA graphics modes, so 0000..3FFF is accessed when the address counter actually is 4000..7FFF, but after reaching 7FFF, you will get to 8000, not to 0000 again. So you don't get infinite repetitions of the first 64K, just two of them, which should be enough.

Tell me, does the "Address Wrap" bit in the CRTC mode register (Index 0x17, bit 5) not work for me (in the word address mode)?

Last edited by SoftCat on 2025-12-26, 00:14. Edited 1 time in total.

Reply 31 of 58, by SoftCat

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

Check how 64K mode 10h differs from standard mode 10h, and apply those differences to mode 0Eh.

Yes, thank you, I thought so too.

Reply 32 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++

Isn't 64K wrapping exactly what sequencer register 04h bit 1 does, when cleared? Disable A16 and higher, clearing them? Basically just ANDed with each of those bits?

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

Reply 33 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-25, 23:59:

Tell me, does the "Address Wrap" bit in the CRTC mode register (Index 0x17, bit 5) not work for me (in the word address mode)?

No, that bit does not seem to be helpful for infinite scrolling, for multiple purposes:

First, I assumed we are talking about 16-color modes. Those modes are not using word mode. The word mode is only used in text modes, CGA-compatible graphics modes, and the 4-color variant of mode 10h. As that bit only affects word mode, it is useless in mode 0Eh.

Second, the idea of this bit select where bit 0 comes from when converting from the CRTC address counter to RAM addresses. So in 64K mode 10h, the internal CRTC address counter is still counting up by one, but only every 16 pixels instead of every 8 pixels (3d4, Index 0x17, bit 3), and the sequencer only reads RAM every 16 pixels (3C4, index 1, bit 2). This makes the counter count from 0 to 0x36B0 during a frame. In word mode, the internal CRTC counter is shifted by one bit before being sent to the video RAM addressing part. This results in even addresses between 0 and 0x6D60, which obviously exceeds the maximum address of a 64K EGA, which is 0x3FFF. After shifting the complete 16-bit value, bit 0 is filled with either a copy of the counter bit 13 or 15. Looking at the quite comprehensive C&T CS8240 datasheet (a clone EGA chipset), they claim that you get bit 13 as A0 if one or both of these conditions is true: (a) the memory size in the Sequencer register is configured to 64K or (b) Index 0x17, bit 5 is clear, otherwise bit 15 is used.

In use-bit13-mode, you will get the sequence 3FFC, 3FFE, 4001, 4003 and so on, which will shift to the odd bytes after 8K character clocks. At this point, superfury is correct according to the C&T documentation:

superfury wrote on 2025-12-26, 00:17:

Isn't 64K wrapping exactly what sequencer register 04h bit 1 does, when cleared? Disable A16 and higher, clearing them? Basically just ANDed with each of those bits?

The nomenclature in the datasheet is different, but you are generally correct. As the EGA card is meant to be thought of as 64K * 32, not 256K * 8, the address bits in most documentation about the EGA card are just numbered 0 to 15, so there is no A16 and higher. The bit you mean by "A16" is called A14 in that documentation, and indeed, in graphics mode, the sequencer disables A14 and A15 (or A16 and A17 according to your way of counting) in 64K mode. It's even more interesting in text mode: in text mode, the 32-bit memory is split into two 16-bit memory pieces that have separate address lines! Planes 0&1 use address line set A, while planes 2&3 use address line set B. This allows the EGA card to fetch a character and attribute byte combination from planes 0&1 while at the same time fetching font data for the character code previously loaded from plane 2. In text mode, the sequencer generates A14/A15 for planes 0&1 from the CRTC output (possibly masked in 64K mode), and generates A14/15 for planes 2&3 from the selected character map.

Note that with the original "4 banks of 16K x 32" design, there were no address bits A14 and A15 on that side anymore, but there were bank selects instead. In 64K mode, the Sequencer always enables bank 0, while in 256K mode, the selected bank depends on address bits A13 or A15 from the CRTC. So if you put the EGA card into 64K mode, the sequence 3FFC, 3FFE, 4001, 4003 generated by the CRTC will be masked to get 3FFC, 3FFE, 0001, 0003 for the video RAM, as required for 64K mode 10h. The combination of putting the sequencer in 256K mode (allowing multiple banks) and using "rotate using bit 13" seems pointless, because this will make the EGA card use the even bytes of the first bank, followed by the odd bytes of the second bank (according to the C&T documentation), which is practically useless, but likely implemented for compatibility with the IBM EGA implementation, which had the same practically useless behaviour for this setting combination that likely was never intended to be practically used.

Another interesting aspect in the C&T datasheet is how A0 to video RAM is generated for CPU cycles mode depending on the card configuration. As I'm not able to find the application notes for that chipset, I have some issues interpreting the table that describes the generation of CRTC A0. That table refers to three input pins. One is "CHAIN" which is driven by the odd/even mode setting as programmed in the graphics controller (3CE, index 6, bit 1), the second one is "MEMOPT", which is driven by the memory size bit already mentioned by superfury (3C4, index 4, bit 1), but the source of third one, called "SAM" is not described in the chipset datasheet. I have to assume that this bit is generated from the video memory address range selection bits (3CE, index 6, bits 2 and 3), and is set if the 128K mode (A000..BFFF) is selected. Given that interpretation:

  • In byte mode, A0 is always passed through (obviously)
  • If 128K address space is not enabled, A0 is generated from the inverted page bit in 3C2 in 256K mode, but from A14 in 64K mode. So you need to configure the card to 64K mode to get the 4-color mode 10h working.
  • If 128K address space is enabled and the card is in 256K mode, CPU address bit A16 is used as A0. This means A000-AFFF provides access to the even addresses in video memory, and B000-BFFF provides access to the the add addresses in video memory, with planes 1 and 3 being visible at odd CPU addresses, and planes 0 and 2 being visible at even CPU addresses. The table indicates that if you configure 128K address space in 64K memory mode, A0 from the CPU is just passed through. This is either a misprint, or is an artifact because IBM did not intend that configuration to be used in practice. It makes no sense to pass through A0 in odd/even mode.

Reply 34 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
SoftCat wrote on 2025-12-24, 00:54:
The easiest way to do it is like this. […]
Show full quote
mkarcher wrote on 2025-12-16, 22:53:

While I previously claimed that the bit likely exists, I'm actually unsure whether you can have the CRTC address counter wrap around at 16K (the CRTC address counter counts 32-bit units of video RAM, so 16K in that counter is 64KB of RAM). I will check documentation and report back what I find.

The easiest way to do it is like this.

mov ax,40h
mov es,ax
and byte ptr es:[87h],9Fh
mov ax,0Eh
int 10h
.....

This has a decent chance of working, despite my earlier comment claiming the opposite. As superfury mentioned, the 64K/256K selection bit in the sequencer generates a CRTC address wrap at 16K of EGA 32-bit addressing (64kilobytes), and it makes sense to assume that the sequencer bit is configured using the bit in the BIOS data area. You better check whether there is dedicated logic to set this bit in the BIOS code, or whether you only get the "64K" mode from the mode parameter table for modes 0Fh/10h in 64K configuration.

Reply 35 of 58, by superfury

User metadata
Rank l33t++
Rank
l33t++

It would make sense that the bit for '64K' mode (in Sequencer register 04h) just masks off MA16 and MA17 when cleared. That way memory wraps around 64K and does so in all modes (and it's the most simple to implement, as it's a simple memory mask (as well as it being the only thing the sequencer controls)).
The mapping from MA13 and MA16 to MA0 and MA1 respectively is done in other registers (the MAP13 bit).
The MA0 from inverted page bit is the default for the MA0 mapping (if MA13 mapping isn't enabled). And for MA1 it's just MA1 itself, although those bits depend on the odd/even mode used (for the sequencer or CPU respectively).
Edit: My bad, bit 0/1 of the row scan counter is the default for the rendering there.
http://www.osdever.net/FreeVGA/vga/crtcreg.htm#17
Or the entire documentation (or what's left of it):
http://www.osdever.net/FreeVGA/vga/vga.htm

Unfortunately, one page of said documentation is missing: 'Attribute Controller Operation' (WIP).

One nice thing about the FreeVGA documentation is that a lot of it (except some bits becoming just their default settings of '0' on EGA) applies to the EGA as well, as (S)VGA is a superset of EGA.

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

Reply 36 of 58, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2025-12-27, 20:53:

It would make sense that the bit for '64K' mode (in Sequencer register 04h) just masks off MA16 and MA17 when cleared. That way memory wraps around 64K and does so in all modes (and it's the most simple to implement, as it's a simple memory mask (as well as it being the only thing the sequencer controls)).

That's true, especially for the original 4-bank variant of the EGA. The sequencer is supposed to generate the /RAS for the different "planes" and /CAS for the different banks. If all addresses are mapped to /CAS0 instead of the four different /CAS outputs, you get the wrapping as required. Looking at the schematics for the IBM EGA card, I expect that's exactly how its implemented and all the 64K bit does on the IBM EGA.

On the other hand, the logic I cited from the C&T CS8240 datasheet does exist on the IBM card as well, and it is realized in discrete logic (U29 on sheet 4 is a 74LS151 1-of-8 multiplexer). The inputs to that multiplexers are signals named exactly as in the C&T datasheet. You get the signal called CHAIN from the graphics controller A, which controls odd/even mode for memory adressing. You get the "128K memory mapping is enabled" signal from Q0 of the memory address decoder ROM U48, and you get the "/MEMOPT" signal. The inputs to the multiplexers are also just as described in the C&T datasheet.

The key difference between the C&T design and the IBM design is the source of the /MEMOPT signal: On the IBM EGA card, /MEMOPT is driven high by a pullup on the EGA card (the resistor connected to pin 11 resistor in the resistor array U38), and pulled low if the memory expansion board is installed. This means: The card changes behaviour depending on the physical presence of the memory expansion board, which is not controllable by the BIOS. Namely:

  • With the memory extension module installed, the video memory A0 for CPU access is taken from the inverted page bit in 3C2 if a 32K or the 64K memory map is selected, and taken from ISA A16 if the 128K memory map is selected. This behaviour is well known, as it is the same as on any VGA or super-VGA card.
  • With the memory module not installed, i.e. a physical 64K configuration, video memory A0 for CPU access is taken from ISA A14 if a 32K or the 64K memory map is selected, and just passed through if teh 128K map is selected.

Passing through ISA A0 in odd-even mode makes no sense, but selecting the 128K memory map on a 64K EGA card also makes no sense. i still don't get why IBM chose that behaviour for this corner case, though. There is one key observation to make, though: 64K mode 0Fh / mode 10h is only supported by the EGA hardware if the memory expansion board is not installed. The 4-color graphcis mode relies on ISA A14 being remapped to video RAM A0 (and getting all 8 text pages in text mode does so as well), which is not available if the memory expansion board is installed. Patching the BIOS configuration bits does not generate a working 4-color mode on the IBM EGA card with the module installed.

Now, you might rightfully ask yourself: Why does the sequencer need software configuration to switch between the 64K and the 256K mode, when the address remapping in word mode automatically adjusts to the presence of the memory expansion board? This question is (as a lot of other ideosyncracies of the EGA design) answered by one design constraint IBM obviously had on their EGA card: No chip with more than 40 pins! DIP40 was the biggest industry standard IC package available at that time. There were higher pin count packages, most notably the 68000 processor, but they were niche packages. Finding a manufacturer for custom chips in DIP-68 would have been more difficult than finding a manufacturer for DiP-40 chips. The sequencer needs to know whether it should enable the /CAS demultiplexer, or it should always drive /CAS0, but it has no free pin to input the /MEMOPT signal. That's why the signal needs to be set by software. And as the sequencer is out of pins, the software-controller 64K/256K flag in the sequencer also can not be output from the sequencer.

Another consequence of the DIP-40 limit is: The Attribute controller has no address input. That's why the Attribute Controller needs to use that nasty flip-flop so index and data can be transferred on the same I/O address. The Attribute Controller also implements the status register that is used to reset the flip-flop, so the flip-flop logic does not need any extra pin.

superfury wrote on 2025-12-27, 20:53:
The mapping from MA13 and MA16 to MA0 and MA1 respectively is done in other registers (the MAP13 bit). The MA0 from inverted pag […]
Show full quote

The mapping from MA13 and MA16 to MA0 and MA1 respectively is done in other registers (the MAP13 bit).
The MA0 from inverted page bit is the default for the MA0 mapping (if MA13 mapping isn't enabled). And for MA1 it's just MA1 itself, although those bits depend on the odd/even mode used (for the sequencer or CPU respectively).
Edit: My bad, bit 0/1 of the row scan counter is the default for the rendering there.
http://www.osdever.net/FreeVGA/vga/crtcreg.htm#17
Or the entire documentation (or what's left of it):
http://www.osdever.net/FreeVGA/vga/vga.htm

This is an entirely different thing, though: Now you are talking about mapping the CRTC address counter to video memory addresses, not about the mapping of ISA address bits to video memory addressing. Only the mapping between the CRTC address counter and video memory address bits is controlled using the CRTC mode register.

Reply 37 of 58, by SoftCat

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-12-26, 11:27:
No, that bit does not seem to be helpful for infinite scrolling, for multiple purposes: […]
Show full quote
SoftCat wrote on 2025-12-25, 23:59:

Tell me, does the "Address Wrap" bit in the CRTC mode register (Index 0x17, bit 5) not work for me (in the word address mode)?

No, that bit does not seem to be helpful for infinite scrolling, for multiple purposes:

First, I assumed we are talking about 16-color modes. Those modes are not using word mode. The word mode is only used in text modes, CGA-compatible graphics modes, and the 4-color variant of mode 10h. As that bit only affects word mode, it is useless in mode 0Eh.

Second, the idea of this bit select where bit 0 comes from when converting from the CRTC address counter to RAM addresses. So in 64K mode 10h, the internal CRTC address counter is still counting up by one, but only every 16 pixels instead of every 8 pixels (3d4, Index 0x17, bit 3), and the sequencer only reads RAM every 16 pixels (3C4, index 1, bit 2). This makes the counter count from 0 to 0x36B0 during a frame. In word mode, the internal CRTC counter is shifted by one bit before being sent to the video RAM addressing part. This results in even addresses between 0 and 0x6D60, which obviously exceeds the maximum address of a 64K EGA, which is 0x3FFF. After shifting the complete 16-bit value, bit 0 is filled with either a copy of the counter bit 13 or 15. Looking at the quite comprehensive C&T CS8240 datasheet (a clone EGA chipset), they claim that you get bit 13 as A0 if one or both of these conditions is true: (a) the memory size in the Sequencer register is configured to 64K or (b) Index 0x17, bit 5 is clear, otherwise bit 15 is used.

In use-bit13-mode, you will get the sequence 3FFC, 3FFE, 4001, 4003 and so on, which will shift to the odd bytes after 8K character clocks. At this point, superfury is correct according to the C&T documentation:

Thank you very much for the detailed explanation!
Tell me, is the CGA and Hercules always in word mode and bit 0 is always filled with zero?

Last edited by SoftCat on 2025-12-28, 00:10. Edited 1 time in total.

Reply 38 of 58, by SoftCat

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2025-12-26, 11:31:

This has a decent chance of working, despite my earlier comment claiming the opposite. As superfury mentioned, the 64K/256K selection bit in the sequencer generates a CRTC address wrap at 16K of EGA 32-bit addressing (64kilobytes), and it makes sense to assume that the sequencer bit is configured using the bit in the BIOS data area. You better check whether there is dedicated logic to set this bit in the BIOS code, or whether you only get the "64K" mode from the mode parameter table for modes 0Fh/10h in 64K configuration.

Yes, thank you, I will take a closer look at the BIOS listing.

Reply 39 of 58, by SoftCat

User metadata
Rank Member
Rank
Member

I looked at the BIOS listing. The memory capacity information only affects Fh and 10h modes.

;----- ESTABLISH ADDRESSING TO THE CORRECT MODE TABLE ENTRY

MAKE_BASE PROC NEAR
ASSUME DS:ABS0
PUSH CX
PUSH DX
CALL SET_BASE ; GET PARM TBL PTR
MOV AH,CRT_MODE
TEST INFO,060H ; TEST FOR BASE CARD
JZ B_M_1 ; MIN MEMORY

;----- WE HAVE A MEMORY EXPANSION OPTION HERE

CMP AH,0FH
JNE B_M_2
ADD BX,BASE_2 - BASE_1
JMP B_M_OUT
B_M_2:
CMP AH,010H
JNE B_M_1
ADD BX,BASE_2 + M_TBL_LEN - BASE_1
JMP B_M_OUT
B_M_1:
CMP AH,03H
JA B_M_3 ; SKIP ENHANCED PORTION