VOGONS


IBM EGA and text mode woes

Topic actions

First post, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Hi all,

(this is related to emulating an original IBM EGA card with original IBM EGA ROM).

In my effort to add EGA emulation I am hitting a strange issue. No matter what position are the 4 switches on the EGA card are the IBM EGA ROM insists on setting the initial text mode as either 320x200 or 320x350 (depending on the switches position), which is mode 1, 40x25. I spent some time studying the ROM code (it comes in the EGA manual from IBM) and from what I can see it keys off what text mode to set based on the BIOS DATA entry 40h:87h which is specific to EGA. Specifically bit 1 says 1 if Monochrome monitor connected 0 otherwise. For me that is 1 and the ROM code checks against that then sets text mode 1

The executed code flow looks like this (this happens inside the EGA ROM and it is the last time the mode is being set):

TEST [0x487], 0x2
JE 0x1f; jump to next line, JE succeeds
CALL 0xfdf8
AND [0x410], 0xcf
OR [0x410], 0x10
MOV AX, 0x1
INT 0x10

What I want is the ROM to set mode 3 (80x25).

I traced the BIOS writes and nobody really writes value 2 at 40:87, or rather not intentional.

In the real world how would the EGA know what kind of monitor is connected beside the dip switch positions which the owner has access to?

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 2 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
dr.zeissler wrote:

Thank you very much for that! I'll read it to see if it answers my questions. Seems to have a lot of useful stuff in it!

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 3 of 37, by SarahWalker

User metadata
Rank Member
Rank
Member

What are you returning for bits 4-5 (the diagnostic bits) of port 3da? You might be failing the EGA self-test - it will set 40 column mode for the duration of the test and won't execute another mode set if it fails. I found on PCem that flipping those two bits on every read to 3da was enough to get it to pass.

Reply 4 of 37, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

Well, the motherboard (planar) display select DIP switches must be set (emulated) to ON,ON which means logic bits 0,0, if that matters - I don't know what BIOS you are running.

Also, when the VGA DIP switch is ON, the value is logic 0, and OFF position is logic 1, do you emulate that correctly?

Reply 5 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
SarahWalker wrote:

What are you returning for bits 4-5 (the diagnostic bits) of port 3da? You might be failing the EGA self-test - it will set 40 column mode for the duration of the test and won't execute another mode set if it fails. I found on PCem that flipping those two bits on every read to 3da was enough to get it to pass.

Thank you Sarah. I was actually not touching the diagnostic bits. I tried flipping them on read and that did not produce any difference. I would like to implement properly at some point as they seem to be tied to color outputs. On a side note I do not think that PCem does the correct thing when flipping the bits :

ega->stat ^= 0x30; /*Fools IBM EGA video BIOS self-test*/

as that would also flip the bit 0 and bit 3 (vertical retrace and display enable) when they are 1, would not it?

Another thing I noticed is the light-pen latch is not emulated in PCem. Since the EGA BIOS seems to read that I added it but it made no difference to my problem, so that must not be it.

Jepael wrote:

Well, the motherboard (planar) display select DIP switches must be set (emulated) to ON,ON which means logic bits 0,0, if that matters - I don't know what BIOS you are running.

Also, when the VGA DIP switch is ON, the value is logic 0, and OFF position is logic 1, do you emulate that correctly?

The problem with this is port 0x62 is required for the motherboard to return the plane dip switches (unless I am wrong and thinking of different ones). That only exists in 8255 on the IBM PC and XT motherboards. It does not exist in the 8042 in the AT motherboards. I am not sure how IBM deals with that on AT system. I'll need to check the BIOS listing.

Either way I think I am returning correct 00 for the low bits of the upper dipswitch values (as to read them you are required to read port 0x62 twice). It made no difference. I am running a selection of BIOSes. On the XT emulation: IBM 5160 and PCXT Turbo and on the IBM PC/AT: IBM 5170 (from Jan 84) and an AMI 286 bios. No difference 🙁

I think Sarah is right that I am somehow failing the EGA detection so the BIOS (EGA bios that is) is falling on the lowest common denominator (40x25), mode 1. I need to debug more and understand why. Thank you both for the help.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 6 of 37, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

On an AT there is a jumper that can be read through keyboard controller.

But the first thing the EGA bios does is it overwrites the 40h:87h with 4, so the information must come from somewhere else.

One point of detection failure could be the measurement of time between frames with timer maybe?

Reply 7 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
vladstamate wrote:

as that would also flip the bit 0 and bit 3 (vertical retrace and display enable) when they are 1, would not it?

I am an idiot sorry, the PCEm code is correct.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 8 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

The initial mode is based on the dipswitches set afaik. It's dependant on the dipswitches, which returned bits depends on the misc output register to select the dipswitches to read, which are flipped:

case 0x3C2: //Read: Input Status #0 Register		DATA
SETBITS(getActiveVGA()->registers->ExternalRegisters.INPUTSTATUS0REGISTER,4,1,(((~getActiveVGA()->registers->switches)>>(GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER,2,3)&3))&1)); //Depends on the switches. This is the reverse of the actual switches used! Originally stuck to 1s, but reported as 0110!
*result = getActiveVGA()->registers->ExternalRegisters.INPUTSTATUS0REGISTER; //Give the register!
ok = 1;
break;

So essentially, the misc output register bits 2-3 select the bit to return from the switches, which is flipped and read on Input Status Register #0 bit 4.

It's usualy set to 6(0110b) for a color monitor. 2(0010b) for monochrome monitor(MDA).

I don't know the output of Input Status register 0 bit 5 through.

See: http://www.osdever.net/FreeVGA/vga/extreg.htm

Fields Clock Select(CS) and Switch Sense.

Results of the switch sense were verified using CheckIt Diagnostics.

Edit: About the MUX output, simply give the two bits that the attribute controller gives as a DAC index(entry number 0-255 into the DAC color table):
https://www-user.tu-chemnitz.de/~kzs/tools/whatvga/vga.txt

Base it on Attribute Register 12h, bits 4-5:

3C0h index 12h (r/W): Attribute: Color Plane Enable Register bit 0 Bit plane 0 is enabled if set. 1 Bit plane 1 is en […]
Show full quote

3C0h index 12h (r/W): Attribute: Color Plane Enable Register
bit 0 Bit plane 0 is enabled if set.
1 Bit plane 1 is enabled if set.
2 Bit plane 2 is enabled if set.
3 Bit plane 3 is enabled if set.
4-5 Video Status MUX. Diagnostics use only.
Two attribute bits appear on bits 4 and 5 of the Input
Status Register 1 (3dAh).
Value EGA VGA
0 Red/Blue Bit 2/Bit 0
1 Blue'/Green Bit 5/Bit 4
2 Red'/Green' Bit 3/Bit 1
3 Bit 7/Bit 6

So simply store the current DAC index when rendering and give those VGA bits as a result based on index 12 bits 4-5 selecting 2 bits from the current DAC index to give on Input Status Register 1.

Last edited by superfury on 2017-02-19, 21:48. Edited 3 times in total.

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

Reply 9 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Superfury, does the IBM EGA BIOS work on your emulator? Search for EGA here on minuszerodegrees.net: http://www.minuszerodegrees.net/rom/rom.htm

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 10 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

It seems like I am off by 4 scanlines in the internal check so it errors out and never sets any graphic mode other than 40x25 🙁

The BIOS is hardcoded to expect 350 scanlines of vert/horiz retrace intervals and it sees 354.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 11 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

It probably will(seeing as I'm accurately emulating both CGA and VGA so far), only the MUX bits aren't implemented yet. I'll try to implement it tomorrow and test the ROM after that.

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

Reply 12 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Awesome, hopefully you will see 80x25 text mode at boot time. If you see 40x25 it means something went wrong.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 13 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've quickly implemented the MUX output in UniPCemu. It's value is the current outputting DAC Index of the Attribute Controller(8-bit DAC index on Active Display or Overscan DAC Index, whichever is displaying at the time of the read). Is that correct?

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

Reply 14 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

That sounds somewhat correct.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 15 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'll need to make a special EGA case though: it appears the EGA ROM address lines are reversed, according to minuszerodegrees(so reversing the offset in the ROM? So address X becomes address 16K-x instead. Also, the Settings menu would need to be extended to support the EGA case for the EGA ROM to be properly emulated, with a seperate EGAROM.BIN option being added).

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

Reply 16 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

I'll need to make a special EGA case though: it appears the EGA ROM address lines are reversed, according to minuszerodegrees(so reversing the offset in the ROM? So address X becomes address 16K-x instead. Also, the Settings menu would need to be extended to support the EGA case for the EGA ROM to be properly emulated).

Yes that is correct, the addresses for that ROM are reversed.

In fact that is true for the ATI EGA Wonder as well.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 17 of 37, by superfury

User metadata
Rank l33t++
Rank
l33t++

After a bit of work, the ROM works without problems. There's now the simple problem of the ROM code waiting for the retrace bit(Input Status 1 register bit 0) to clear on the Color(3DA instead of 3BA) port, but the Misc Output register is set up for monochrome operations, making the register return 0xFF(because it doesn't respond to the port), sending the program into an infinite loop because it's reading the wrong port(or has the Misc Output Register set up wrong, to use monochrome(3BA(Input Status 1 register)/3BX(CRTC) instead of color(3DA(Input Status 1 register)/3DX(CRTC)))).

Any idea what's causing this? The EGA+ video cards just give the current status of h&vretrace on it(1 when horizontally or vertically retracing, 0 otherwise) on bit 0, with the vretrace status being directly outputted on bit 3(1 during retrace, 0 otherwise).

Edit: Looking at the input again: I notice it reading the Input Status 1 register a few (3 or 4) times, then it changes the card into mono mode and continues reading the COLOR port(3DA), sending itself into an infinite loop?

The results are(using the VGA clocking):
1(3BA), 0(3DA), 0(3DA), 1(3DA), 0(3DA). huge delay, infinite loop because it's reading the color register during mono operation(Misc Output Register bit 0 is set).

So it goes from retrace, leaves retrace, enters retrace, leaves retrace, then changes the Misc Output Register mode to monochome and continues reading the color register, locking itself up?

Edit: Improved the clocking a bit by implementing 14MHz(14.31818MHz XT clock) and 16MHz(onboard clock) instead of the VGA clocking. Although the problem with the infinite loop still occurs.

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

Reply 18 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

Like I said, EGA BIOS is not that easy to get working. But it is good for us it is doing so many checks as it makes our emulators more accurate. There are a few things possibly wrong here.

superfury wrote:

After a bit of work, the ROM works without problems. There's now the simple problem of the ROM code waiting for the retrace bit(Input Status 1 register bit 0) to clear on the Color(3DA instead of 3BA) port, but the Misc Output register is set up for monochrome operations, making the register return 0xFF(because it doesn't respond to the port), sending the program into an infinite loop because it's reading the wrong port(or has the Misc Output Register set up wrong, to use monochrome(3BA(Input Status 1 register)/3BX(CRTC) instead of color(3DA(Input Status 1 register)/3DX(CRTC)))).

It should not have set up for Monochrome. If it does the EGA failed the self test. The EGA bios will use the correct ports if it detects the EGA card. It might use the EGA card with the monochrome monitor but that does not impact the 3da port selection. If you want to see what part of the test you failed check the ROM manual page 117-118 (those are actual acrobat reader pages, in document those are pages 113-114). http://minuszerodegrees.net/oa/OA%20-%20IBM%2 … s%20Adapter.pdf

Also PCEm (and I) respond to either 3BA or 3DA if monochrome mode is set on. So you can try that.

superfury wrote:
Any idea what's causing this? The EGA+ video cards just give the current status of h&vretrace on it(1 when horizontally or verti […]
Show full quote

Any idea what's causing this? The EGA+ video cards just give the current status of h&vretrace on it(1 when horizontally or vertically retracing, 0 otherwise) on bit 0, with the vretrace status being directly outputted on bit 3(1 during retrace, 0 otherwise).

Edit: Looking at the input again: I notice it reading the Input Status 1 register a few (3 or 4) times, then it changes the card into mono mode and continues reading the COLOR port(3DA), sending itself into an infinite loop?

The results are(using the VGA clocking):
1(3BA), 0(3DA), 0(3DA), 1(3DA), 0(3DA). huge delay, infinite loop because it's reading the color register during mono operation(Misc Output Register bit 0 is set).

So it goes from retrace, leaves retrace, enters retrace, leaves retrace, then changes the Misc Output Register mode to monochome and continues reading the color register, locking itself up?

Edit: Improved the clocking a bit by implementing 14MHz(14.31818MHz XT clock) and 16MHz(onboard clock) instead of the VGA clocking. Although the problem with the infinite loop still occurs.

If you are stuck where I think you are, then you are stuck in the roughly same place I am. Again look at the page 113-114 in the BIOS listing in the EGA documentation and check which exit path it took for you. The EGA bios will do something like this:

MOV BL, error code
JMP <error handler>
<execute beeps>

The error code is basically how many subtests you passed.

Last edited by vladstamate on 2017-02-20, 14:14. Edited 1 time in total.

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/

Reply 19 of 37, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

I am logging all execution in 0xc0000-0xf0000 and than I inspect in against the EGA listing to see where it has problems.

For me the BIOS runs but I am failing the number of horizontal enables test in a full vertical sweep so because of that it switches to 40x25. Everything works fine for me after that (even graphics mode, I tried few games like Eye of the Beholder and Police Quest I and both detect EGA and run fine) but I want it to properly pass its self test 😀

YouTube channel: https://www.youtube.com/channel/UC7HbC_nq8t1S9l7qGYL0mTA
Collection: http://www.digiloguemuseum.com/index.html
Emulator: https://sites.google.com/site/capex86/
Raytracer: https://sites.google.com/site/opaqueraytracer/