Reply 20 of 54, by superfury
I've just been thinking. Perhaps the EGA BIOS itself would provide some answers?
https://www.os2museum.com/wp/reconstructing-the-ega-bios/
Someone already seemed to have gone the mile a bit and scanned (and fixed some issues with scanning) the BIOS from the EGA documentation?
Then searched for "switch" in the documents.
https://guest:guest@www.os2museum.com/hg/egab … 20f08/VPOST.INC
It was easy to find the switches (search for "switch" reveals RD_SWS (reads the switches from the card and stores in BL. No flipping is performed on the reads.). POR_1 (related) reads to port DX, reads it back and gives bit 4 as bit 3 in BL.
DX is set to MISC OUTPUT register in color mode always when calling POR_1, so it writes the value to the switches and reads it back into BL(after shifting bit 4 (the read bit) to bit 3.
The switches match the flipped versions returned by UniPCemu's misc output register (so set to On=0, Off=1. 0110 b for VGA, 0100b in UniPCemu).
SRLOAD sets DX and the register specified to the parameter (0 if not specified).
INFO_3 has bit 4-7 feature bits, 0-3 switches.
Switches are loaded from highest value (11b) to lowest value (00b). It's stored in opposite order (11b input (switch 4) at bit 0, 00b input (switch 1) at 3. So the switches are stored like this (into INFO_3):
bit 0: switch 4
bit 1: switch 3
bit 2: switch 2
bit 3: switch 1
So it's stored as a literal binary value in the same order as SW1-4 on the board, not flipped from the Input Status #0 reads. So SW3 only (monochrome, as from documentation 0100b) would result in PST_D(RET, which is ignored)? And hi-res color in PST_9? But then there's something intetesting, coming back to it at the end of this post.
Looking at https://guest:guest@www.os2museum.com/hg/egab … 0f08/EGABIG.ASM reveals the layout stored:
INFO at 0040:0087 (bits 2-3 interesting: bit 2: EGA inactive, bit 1: monochrome attached).
INFO_3 at 0040:0088 (bits 3-0: read switches. bits 4-7: feature bits from daughter card? might be required?).
Feature bits might be required later? It is performed by writing 1(Setting only FC0 for bits 4-5 of the storage) or 2 (setting only FC1 for bits 6-7 of the storage) to the feature control register (port 3BA/3DA) and reading back the bits in the binary order stored (so unmodified bit order) into the result bits 4-7 of INFO_3 from input status #0 register bits 5-6 (bit 6 being the upper bit(), bit 5 being the lower bit). It's stored as:
bit 4=FC0 result low bit
bit 5=FC0 result high bit
bit 6=FC1 result low bit
bit 7=FC1 result high bit
UniPCemu currently simply gives the FC bits when it was read as what was last written on said feature control register. Probably incorrect? Just modified it to return 0.
Then, after storing that, it gets juicy at the PST routines from that input (Btw VIDEO_SETUP is the startup vector the BIOS seems to call at the start of the Option ROM).
It has set INFO to 4(EGA inactive, color attached) before.
UniPCemu gives 0100b for monochrome monitor and 0110b for EGA enhanced modes. The reads for said bits are inverted, so 1011b for monochrome and 1001b
Now it's set to monochrome, CGA40 with only SW3 on(officially), thus obtaining
The bits stored into INFO_3(the lower 4 bits) are used to jump to PST_0 though PST_B (used as an word index into the table). The last 4 entries (C through F, which are switches with number 1 and 2 off) are simply returning without doing anything at PST_OUT.
Now, thinking about what's happening, it's odd. The BIOS reads the switches in binary format. But they're stored and used as the lookup table indicates.
The final 4 entries are seemingly invalid. When 0110(off on on off) is used, it's PST_9. But since the monochrome switches end up as 100b=>1011b, it's executing a RET instead? That can't be right.
Now let's look at the PST routines. Virtually all of them are with the EGA in color mode, not monochrome. But some put it in monochrome mode! Specifically, entries 4h,5h,Ah and Bh! Those correspond to SW1,2,3,4 being read as (remember, they're stored in binary order, with SW1 at bit 3 and SW4 at bit 0!):
0100
0101
1010
1011
Performing the bit flip on those to get the actual on(1)/off(0) switch values for those, in the same binary stored order, we get:
1011 (switch 2 off, others on)
1010 (switch 2 and 4 off, others on)
0101 (switch 1 and 4 off, others on)
0100 (switch 2 on, others off)
Now, remember those switch bits being inversted doesn't seems to be the problem. The order seems off though?
Remember, EGA documentation says that 0110 is EGA enhanced, which is obviously working. So far so good.
Now let's look at the switch combinations that result in EGA monochrome modes (again SW1 first, conveniently aligning with the lookup table in binary):
Off off on off for EGA only or w/ CGA 80 (0010b)
On off on off EGA mono w/ CGA 40 (1010b)
On on off on CGA 40 primary w/ EGA mono or none (1101b)
Off on off on CGA 80 primary w/ EGA mono or none (0101b)
Now remember the setup lookup table? 1010b matches.
But all others don't! They won't apply mono mode on the EGA at all! The documentation before it in the assembly listing lists 4, but only 1 matches?
Now remember 0110 matched correctly? So something is correct there!
But if we compare those obvious 4 monochrome mode (evidenced by the misc output register write to put it in monochrome mode!) lookup entries, and comparing the bit values?
EGA Documentation mono switches (let's give them nicknames for ease of use):
0010 (mode first) *nope*
1010 (mode second) *valid*
1101 (mode third) *nope*
0101 (mode fourth) *nope*
And the mono fields that match in the code?
1011 (switch 2 off, others on)
1010 (switch 2 and 4 off, others on)
0101 (switch 1 and 4 off, others on)
0100 (switch 2 on, others off)
Not seeing it? Let's try reversing the bit order of the documentation!
0100 (mode first) *valid*
0101 (mode second) *valid*
1011 (mode third) *valid*
1010 (mode fourth) *valid*
A perfect match!!!
So the index that's given in the misc output register is 0 for switch 4, 1 for switch 3, 2 for switch 1 and 3 for switch 0!
Edit: And MAME confirms it?
https://github.com/MisterTea/MAMEHub/blob/mas … u/bus/isa/ega.c
Look for "dips" in there (without quotes). It seems to confirm, looking at the reported values?
The EGA documentation clearly says (on the Switch Sense):
Bit 3: Switch 4 ; Logical 0 = Switch closed Bit 2: Switch 3 ; Logical 0 = Switch closed Bit 1: Switch 2 ; Logical 0 = Switch clo […]
Bit 3: Switch 4 ; Logical 0 = Switch closed
Bit 2: Switch 3 ; Logical 0 = Switch closed
Bit 1: Switch 2 ; Logical 0 = Switch closed
Bit 0: Switch 1 ; Logical 0 = Switch closed
And looking at the EGA diagrams on what's on and off on the switches, it shows in the picture that On is Closed. So it's clearly bit flipping there.
But the documentation clearly has the order of switches inversed in the BIOS?
Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io