VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does anyone have an exact list of register differences (and of c0urse missing or added registers on the EGA) between the EGA and VGA interfaces from a CPU perspective?

For some reason, UniPCemu's (S)VGA runs flawlessly, but the EGA (Basically modified status register inputs and disabled read operations for the Sequencer etc. register ports) doesn't want to POST properly?
I know that the horizontal total +3 vs +5, which is properly done on EGA, but why won't it properly POST?

Source code for EGA/VGA video cards can be found here

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

Reply 1 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been looking at the functionality of the Misc Output Register.

Bit 5 is kind of weird. UniPCemu's VGA emulation won't POST properly unless it's functionality seems to be inversed (0=high 64K page(page 2/3 depending on A0), 1=low 64K page (page 0/1 depending on A0)).

Anyone knows how bit 5 works? Afaik A0 of the memory address lines always selects between the odd and even page (either low(page 0/1) or high(page 2/3))? Does bit 5 of the Misc Output Register actually add 2 to the page number (becoming a kind of A2 in the memory address)?

Edit: Or does this affect the location of the mapping to CPU instead? Like the A0000 vs B0000 address or something like that?

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

Reply 2 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t

You are talking about odd/even mode, where A0 from the CPU selects either planes 0&2 or 1&3. Which plane(s) actually get written to is selected by the map mask register, which typically is 03h in odd/even modes, so planes 2 and 3 are out of reach.

As A0 is used to select the planes, there is no A0 bit for the memory address coming from the CPU. Instead, bit 5 from misc out is used as A0 in odd/even modes

Reply 3 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 17:29:

You are talking about odd/even mode, where A0 from the CPU selects either planes 0&2 or 1&3. Which plane(s) actually get written to is selected by the map mask register, which typically is 03h in odd/even modes, so planes 2 and 3 are out of reach.

As A0 is used to select the planes, there is no A0 bit for the memory address coming from the CPU. Instead, bit 5 from misc out is used as A0 in odd/even modes

Isn't bit 0 for the VRAM gotten from CPU address bit 16 when the miscellaneous graphics register bit 1 is set? So does that bit in the register override the bit 5 of the misc output register?

IBM EGA says about that bit:

Chain Odd Maps To Even Maps-When set to 1, this bit directs the processor address bit 0 to be replaced by a higher order bit and […]
Show full quote

Chain Odd Maps To Even Maps-When set to 1,
this bit directs the processor address bit 0 to be
replaced by a higher order bit and odd/even
maps to be selected with odd/even values of the
processor AO bit, respectively.

FreeVGA says about that bit:

Chain O/E -- Chain Odd/Even Enable
"When set to 1, this bit directs the system address bit, A0, to be replaced by a higher-order bit. The odd map is then selected when A0 is 1, and the even map when A0 is 0."

Any idea what it means if that bit is set, when combined with the Misc Output Register bit 5?

Odd/Even mode is determined by another bit, in the Sequencer Memory Mode and Graphics Mode Register:
Sequencer Memory Mode bit 2:

O/E Dis. -- Odd/Even Host Memory Write Adressing Disable
"When this bit is set to 0, even system addresses access maps 0 and 2, while odd system addresses access maps 1 and 3. When this bit is set to 1, system addresses sequentially access data within a bit map, and the maps are accessed according to the value in the Map Mask register (index 0x02)."

EGA documentation says:

Odd/Even-A logical 0 directs even processor addresses to access maps 0 and 2, while odd processor addresses access maps 1 and 3. […]
Show full quote

Odd/Even-A logical 0 directs even processor
addresses to access maps 0 and 2, while odd
processor addresses access maps 1 and 3. A
logical 1 causes processor addresses to
sequentially access data within a bit map. The
maps are accessed according to the value in the
map mask register.

Graphics Mode Register bit 4:

Host O/E -- Host Odd/Even Memory Read Addressing Enable
"When set to 1, this bit selects the odd/even addressing mode used by the IBM Color/Graphics Monitor Adapter. Normally, the value here follows the value of Memory Mode register bit 2 in the sequencer."

EGA documentation says:

Odd/Even-A logical 1 selects the odd/even addressing mode, which is useful for emulation of the Color Graphics Monitor Adapter c […]
Show full quote

Odd/Even-A logical 1 selects the odd/even
addressing mode, which is useful for emulation of
the Color Graphics Monitor Adapter compatible
modes. Normally the value here follows the value
of the Memory Mode Register bit 3 of the
Sequencer.

Although I'd assume bit 3 should be bit 2, as the register description of the mentioned register puts it at bit 2 instead of bit 3 (which also is used on (S)VGA for Chain 4 mode).

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

Reply 4 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++

So, combining all that, does that mean:
- If misc graphics bit 1 is set, use A16 from the CPU as A0 for VRAM.
- Otherwise, use Misc Output Register bit 5 as A0 for VRAM.

Would that be correct?

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

Reply 5 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 19:46:

Isn't bit 0 for the VRAM gotten from CPU address bit 16 when the miscellaneous graphics register bit 1 is set? So does that bit in the register override the bit 5 of the misc output register?

As I understand it, in odd/even mode (enabled by misc graphics bit 1, A0 is taken from misc output bit 5 unless the 128K mapping (misc graphics bits 2-3 both zero) is active. Only in the latter case, A16 is a valid address bit inside video memory space and it "overrides" misc output bit 5.

Reply 6 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 20:16:
superfury wrote on 2021-06-27, 19:46:

Isn't bit 0 for the VRAM gotten from CPU address bit 16 when the miscellaneous graphics register bit 1 is set? So does that bit in the register override the bit 5 of the misc output register?

As I understand it, in odd/even mode (enabled by misc graphics bit 1, A0 is taken from misc output bit 5 unless the 128K mapping (misc graphics bits 2-3 both zero) is active. Only in the latter case, A16 is a valid address bit inside video memory space and it "overrides" misc output bit 5.

But isn't Odd/Even mode enabled by those other two registers (Sequencer Memory Mode bit 2 cleared for CPU writes and graphics mode register bit 4 set for CPU reads. Otherwise, it's in planar mode instead of odd/even mode and the known and documented planar mechanics apply? (Although Chain 4 overrides both of those to be forced to Chain 4, with A0&A1 determining the plane and A2-A15 determining the offset on the plane. Although that's done on the VGA and up only)

So what happens when Odd/Even mode is enabled for reads and/or writes, a read/write is done and misc graphics register bit 1 is cleared?

Or do I have the misc output register bit 1 reversed to what it's supposed to be?

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

Reply 7 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 20:23:

But isn't Odd/Even mode enabled by those other two registers (Sequencer Memory Mode bit 2 cleared for CPU writes and graphics mode register bit 4 set for CPU reads. Otherwise, it's in planar mode instead of odd/even mode and the known and documented planar mechanics apply? (Although Chain 4 overrides both of those to be forced to Chain 4, with A0&A1 determining the plane and A2-A15 determining the offset on the plane. Although that's done on the VGA and up only)

So what happens when Odd/Even mode is enabled for reads and/or writes, a read/write is done and misc graphics register bit 1 is cleared?

As I understand it, all three bits should be in sync:

  • Sequencer Memory Mode bit 2 decides whether A0 selects memory maps on writes.
  • Graphics Mode bit 4 decides whether A0 selects memory maps on reads.
  • Misc graphics bit 1 decides wheter A0 is forwarded to VRAM (bit clear) or replaced by Misc Output bit 5 or CPU A16 (bit set)

Reply 8 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 20:29:
As I understand it, all three bits should be in sync: […]
Show full quote
superfury wrote on 2021-06-27, 20:23:

But isn't Odd/Even mode enabled by those other two registers (Sequencer Memory Mode bit 2 cleared for CPU writes and graphics mode register bit 4 set for CPU reads. Otherwise, it's in planar mode instead of odd/even mode and the known and documented planar mechanics apply? (Although Chain 4 overrides both of those to be forced to Chain 4, with A0&A1 determining the plane and A2-A15 determining the offset on the plane. Although that's done on the VGA and up only)

So what happens when Odd/Even mode is enabled for reads and/or writes, a read/write is done and misc graphics register bit 1 is cleared?

As I understand it, all three bits should be in sync:

  • Sequencer Memory Mode bit 2 decides whether A0 selects memory maps on writes.
  • Graphics Mode bit 4 decides whether A0 selects memory maps on reads.
  • Misc graphics bit 1 decides wheter A0 is forwarded to VRAM (bit clear) or replaced by Misc Output bit 5 or CPU A16 (bit set)

So:
- If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, use planar mode addressing for writes. The other mentioned bits aren't used for that.
- If Graphics Mode bit 4 isn't in Odd/Even mode, the same applies as mentioned abover for Sequencer Memory Mode bit 2.
- If the read/write is in odd/even mode, then:
-- If Misc Graphics bit 1 is cleared, VRAM A0 is forwarded from the CPU's A0 bit. What does Miscellaneous Output Register bit 5 do in this case? It can't forward both to the same bit?
-- If Misc Graphics bit 1 is set, VRAM A0 is set from A16 from the CPU?

Or is it simply:
-- If Misc Graphics bit 1 is cleared, VRAM A0 is forwarded from the CPU's A0 bit.
-- If Misc Graphics bit 1 is set, VRAM A0 is set from A16 from the CPU. If Miscellaneous Output Register bit 5 it set, it's forced to 1.

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

Reply 9 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 20:39:
So: - If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, use planar mode addressing for writes. The other mentioned bits are […]
Show full quote

So:
- If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, use planar mode addressing for writes. The other mentioned bits aren't used for that.
- If Graphics Mode bit 4 isn't in Odd/Even mode, the same applies as mentioned abover for Sequencer Memory Mode bit 2.
- If the read/write is in odd/even mode, then:
-- If Misc Graphics bit 1 is cleared, VRAM A0 is forwarded from the CPU's A0 bit if Miscellaneous Output Register bit 5 is cleared. Otherwise, set A0 for VRAM?
-- If Misc Graphics bit 1 is set, VRAM A0 is set from A16 from the CPU?

I would implement it like this:

  • If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, always access all planes as indicated by the Sequencer Map Mask register. If Sequencer Memory Mode bit 2 is in odd even mode, use Map Mask & 0x05 if A0 is clear and Map Mask & 0x0A if A0 is set.
  • If Graphics Mode bit 4 isn't in Odd/Even mode, read from the plane indicated by the Read Map Select register. If Graphics Mode bit 4 is in Odd/Even mode, replace the lowest bit of the Read Map select register by A0.
  • If Misc graphics bit 1 is cleared, always forward CPU A0 to VRAM A0. If Misc Graphics bit 1 is set, (A) use CPU A16 as A0 if Misc Graphics bit 2/3 are both cleared or (B) use Misc Output bit 5 otherwise.

Note how the first two bullet points only specify what planes are affected by the cycle, whereas the last bullet point only specifies what address is affected by the cycle. Misc output bit 5 is basically an "A16 substitute" in all memory maps where you don't have 128K video address space and thus A16 is not a usable address line.

Reply 10 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 20:47:
I would implement it like this: […]
Show full quote
superfury wrote on 2021-06-27, 20:39:
So: - If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, use planar mode addressing for writes. The other mentioned bits are […]
Show full quote

So:
- If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, use planar mode addressing for writes. The other mentioned bits aren't used for that.
- If Graphics Mode bit 4 isn't in Odd/Even mode, the same applies as mentioned abover for Sequencer Memory Mode bit 2.
- If the read/write is in odd/even mode, then:
-- If Misc Graphics bit 1 is cleared, VRAM A0 is forwarded from the CPU's A0 bit if Miscellaneous Output Register bit 5 is cleared. Otherwise, set A0 for VRAM?
-- If Misc Graphics bit 1 is set, VRAM A0 is set from A16 from the CPU?

I would implement it like this:

  • If Sequencer Memory Mode bit 2 isn't in Odd/Even mode, always access all planes as indicated by the Sequencer Map Mask register. If Sequencer Memory Mode bit 2 is in odd even mode, use Map Mask & 0x05 if A0 is clear and Map Mask & 0x0A if A0 is set.
  • If Graphics Mode bit 4 isn't in Odd/Even mode, read from the plane indicated by the Read Map Select register. If Graphics Mode bit 4 is in Odd/Even mode, replace the lowest bit of the Read Map select register by A0.
  • If Misc graphics bit 1 is cleared, always forward CPU A0 to VRAM A0. If Misc Graphics bit 1 is set, (A) use CPU A16 as A0 if Misc Graphics bit 2/3 are both cleared or (B) use Misc Output bit 5 otherwise.

Note how the first two bullet points only specify what planes are affected by the cycle, whereas the last bullet point only specifies what address is affected by the cycle.

That first bullet point was already done in my emulator's source code.
Those latter 2 for odd/even mode was done for A0 shifting of value 0x5 (becoming 0xA if set) for input to the read/write stage (which handles the normal VGA read and write mode mechanics).
Then:
- When misc graphics mode 1 was set, replaced A0 for VRAM with the CPU's A16.
- Otherwise, didn't replace A0 for VRAM but changed the planes to read/write from 0/1(as selected by the A0 bit from the CPU during the bullet point 2 of yours) to 2/3(determined by the A0 bit from the CPU in the same way).

So the planes part is working properly, but the address part isn't?

This is what I've gotten with this combined for Odd/Even mode:

void VGA_OddEven_decode(byte towrite, uint_32 offset, byte *planes, uint_32 *realoffset)
{
INLINEREGISTER uint_32 realoffsettmp;
INLINEREGISTER byte calcplanes;
calcplanes = realoffsettmp = offset; //Take the default offset!
calcplanes &= 1; //Take 1 bit to determine the odd/even plane (odd/even)!
if (GETBITS(getActiveVGA()->registers->GraphicsRegisters.REGISTERS.MISCGRAPHICSREGISTER,1,1)) //Replace A0 with high order bit?
{
realoffsettmp &= ~1; //Clear bit 0 for our result!
if (VGA_MemoryMapSelect == 0) //128K window?
{
realoffsettmp |= ((offset >> 16) & 1); //Bit 16 becomes bit A0 for VRAM!
}
else //Misc Output Register High/Low page becomes A0 for VRAM!
{
realoffsettmp |= GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER, 5, 1); //Apply high page if needed!
}
}
//Otherwise, CPU A0 becomes VRAM A0?
if (decodingbankunfiltered == 0) //Not unfiltered?
{
writebank <<= 1; //Shift to it's position!
writebank &= (0xE0000|getActiveVGA()->precalcs.extraSegmentSelectLines); //3/5 bits only!
readbank <<= 1; //Shift to it's postion!
readbank &= (0xE0000|getActiveVGA()->precalcs.extraSegmentSelectLines); //3/5 bits only!
}
*realoffset = realoffsettmp; //Give the calculated offset!
*planes = (0x5 << calcplanes); //Convert to used plane (0&2 or 1&3)!
#ifdef ENABLE_SPECIALDEBUGGER
if (specialdebugger||verboseVGA) //Debugging special?
#else
if (verboseVGA) //Debugging special?
#endif
{
dolog("VGA", "%s using Odd/Even: Memory aperture offset %08X=Planes: %04X, Offset: %08X, VRAM offset: %08X, Bank: %08X", towritetext[towrite ? 1 : 0], offset, *planes, *realoffset, (*realoffset<<2), towrite?writebank:readbank);
}
}

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

Reply 11 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 20:55:

This is what I've gotten with this combined for Odd/Even mode:
(code snipped)

This looks about the way I expect it to be handled in real hardware. I'm unsure about read map selection, though. You seem to always read from the first bit set in *planes, so after OddEven_decode, you will always read from plane 0 or 1. This might be correct, but my guess is (I need to test that on hardware, though) that if the read map select register is 2 or 3, you should read from 2 or 3 instead of 0 or 1.

Reply 12 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 21:19:
superfury wrote on 2021-06-27, 20:55:

This is what I've gotten with this combined for Odd/Even mode:
(code snipped)

This looks about the way I expect it to be handled in real hardware. I'm unsure about read map selection, though. You seem to always read from the first bit set in *planes, so after OddEven_decode, you will always read from plane 0 or 1. This might be correct, but my guess is (I need to test that on hardware, though) that if the read map select register is 2 or 3, you should read from 2 or 3 instead of 0 or 1.

Well, it's mapping to either 0/1 or 1/3 depending on the set bit in the result planes (0x5 for 0/2, 0xA for 1/3). Said mask (5 or A) is then passed through a second stage (the read or write mode operation) which reads from the very first plane found (in order from 0 to 3) or all planes at the same time (read mode 1, with the color don't care logic etc.).
Writes use the map mask register (some Tseng chips forcing it to 0xF in certain SVGA modes), masking the bits off with the mentioned mask (5 or A) to obtain the planes to write to.

That can be seen in the step after this step: the read and write mode operation: https://bitbucket.org/superfury/unipcemu/src/ … e/vga/vga_mmu.c
It's immediately after the call to the odd/even decoding. That's at line 846(writes) and 721(reads).

It only uses the read map select register for latches and planar modes.

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

Reply 13 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 21:33:
mkarcher wrote on 2021-06-27, 21:19:

This looks about the way I expect it to be handled in real hardware. I'm unsure about read map selection, though. You seem to always read from the first bit set in *planes, so after OddEven_decode, you will always read from plane 0 or 1. This might be correct, but my guess is (I need to test that on hardware, though) that if the read map select register is 2 or 3, you should read from 2 or 3 instead of 0 or 1.

Well, it's mapping to either 0/1 or 1/3 depending on the set bit in the result planes (0x5 for 0/2, 0xA for 1/3). Said mask (5 or A) is then passed through a second stage (the read or write mode operation) which reads from the very first plane found (in order from 0 to 3) or all planes at the same time (read mode 1, with the color don't care logic etc.).

I'm confident you wanted to write either 0/2 or 1/3, just as you go on explaining 0x05 and 0x0A. I was referring to your implementation of read mode 0, and you confirmed my understanding "always read from the first bit set in *planes". Your code makes it impossible to read planes two or three while in odd/even mode. I assume (but don't know) that you can read from planes two or three if you set the read map select register to two or three.

Reply 14 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 22:01:
superfury wrote on 2021-06-27, 21:33:
mkarcher wrote on 2021-06-27, 21:19:

This looks about the way I expect it to be handled in real hardware. I'm unsure about read map selection, though. You seem to always read from the first bit set in *planes, so after OddEven_decode, you will always read from plane 0 or 1. This might be correct, but my guess is (I need to test that on hardware, though) that if the read map select register is 2 or 3, you should read from 2 or 3 instead of 0 or 1.

Well, it's mapping to either 0/1 or 1/3 depending on the set bit in the result planes (0x5 for 0/2, 0xA for 1/3). Said mask (5 or A) is then passed through a second stage (the read or write mode operation) which reads from the very first plane found (in order from 0 to 3) or all planes at the same time (read mode 1, with the color don't care logic etc.).

I'm confident you wanted to write either 0/2 or 1/3, just as you go on explaining 0x05 and 0x0A. I was referring to your implementation of read mode 0, and you confirmed my understanding "always read from the first bit set in *planes". Your code makes it impossible to read planes two or three while in odd/even mode. I assume (but don't know) that you can read from planes two or three if you set the read map select register to two or three.

For now I've made it so it uses bit 1 of the read map select register to mask off the low 2 bits of the resulting memory map, causing it to read the high memory map(2/3) instead of the low one(0/1). Of course that only happens that way in Odd/Even mode. Memory Map Select bit 0 is completely ignored (officially read map select is only used during planar modes after all).

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

Reply 15 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2021-06-27, 22:01:

I assume (but don't know) that you can read from planes two or three if you set the read map select register to two or three.

I tested the behaviour in text mode (which uses odd/even) on a Trident TVGA8900, an ET4000AX and a GeForce 4 MX 420. On all three of these cards, I can read the font from plane 2 (every second byte) when I set the read map select register to 2 or 3, whereas I get the characters and attributes, when I set the read map select register to 0 or 1.

Reply 16 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2021-06-27, 22:34:
mkarcher wrote on 2021-06-27, 22:01:

I assume (but don't know) that you can read from planes two or three if you set the read map select register to two or three.

I tested the behaviour in text mode (which uses odd/even) on a Trident TVGA8900, an ET4000AX and a GeForce 4 MX 420. On all three of these cards, I can read the font from plane 2 (every second byte) when I set the read map select register to 2 or 3, whereas I get the characters and attributes, when I set the read map select register to 0 or 1.

OK. So that's now properly emulated.

It's still setting up the Misc Output Register incorrectly, though?
It's pretty much set to 00h all the time, preventing any VRAM writes (including font writes, so the font uploading to VRAM also fails) and after the BIOS POSTs (and the hard disk clears the screen to take over the boot process, using the video interrupt function 00h mode 03h to switch to a cleared screen), it completely hangs due to waiting for port 3DA to become non-retracing (but it's giving 0xFF due to the Misc Output Register being 00h, thus the port is actually mapped at port 3BAh)?

Forcing the Misc Output Register bit 2 to be set causes the first screen to show (including the XT memory count for example), but once it tries to clear the screen using interrupt 10h function 00h a hang occurs because port 3DAh is unmapped (it's at 3BAh due to the misc output register bit 0 being cleared).

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

Reply 17 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2021-06-27, 22:42:

It's still setting up the Misc Output Register incorrectly, though?
It's pretty much set to 00h all the time,

Can you post a link to the BIOS that exhibits this behaviour?

Reply 18 of 72, by mkarcher

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2021-06-27, 22:34:

I tested the behaviour in text mode (which uses odd/even) on a Trident TVGA8900, an ET4000AX and a GeForce 4 MX 420. On all three of these cards, I can read the font from plane 2 (every second byte) when I set the read map select register to 2 or 3, whereas I get the characters and attributes, when I set the read map select register to 0 or 1.

There is a practical use case for this: The 640x350 4-color mode on 64KB EGA cards. In this mode, odd/even is used to create two virtual 32K planes out of the four 16K planes. You access the first virtual plane with write mask = 3, read map = 0, and the other virtual plane with write mask = 0x0C, read map = 2. Which means the EGA card needs to have a control bit that makes it use A14 instead of A16 as replacement for A0, possibly memory mode, bit 1.

Reply 19 of 72, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just managed to find the issue. It was handling port 3CA writes to feature control instead of graphics 2 position and port 3CC writes to miscellaneous output register instead of graphics 1 position (it still does on other (S)VGA graphics cards though).

Now I don't see it causing VRAM issues anymore and the font is correctly setup (together with the other settings mostly).

I just still see it setting up a kind of weird text mode though, with only 40 pixels instead of the proper 80?

Edit: OK. So I'll replace A16 with A14 when Sequencer Memory Mode register bit 1 is cleared.

Edit: Hmmm... According to CheckIt diangostics, the EGA only has 64K RAM installed? But it has 256K RAM installed? The jumper seems to be set to 0110 according to it?

Edit: During the Landmark BIOS test, I see the VRAM filled up to address 1FFFC, so that's up to planar (dword) address 7FFF(2 bits are appended at the right(LSb) for the plane).

Edit: A dump of registers from UniPCemu:

Filename
EGA incorrect timing_20210628_0903.zip
File size
26.93 KiB
Downloads
48 downloads
File comment
EGA incorrect timing register dump and screen capture
File license
Fair use/fair dealing exception
Last edited by superfury on 2021-06-28, 07:04. Edited 6 times in total.

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