VOGONS


Reply 20 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

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 […]
Show full quote

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

Reply 21 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Having implemented that seems to fix the video screen past the POST to display at least?
The POST still doesn't display anything (the switches having been set to switch 3 on and all others off)?
Edit: Hmmm... Checkit doesn't seem to work partly? When launched blind (nothing is written to VRAM somehow after booting the hard disk) starting Checkit makes it restore video operations?

Then displaying the menus shows no EGA dipswitch info? Other information is shown though?

Then running all the video checks makes it hang waiting on port 3DA bit 0 to toggle while the card is in monochrome graphics mode? So it won't respond at said address, hanging the BIOS apparently (checked it's executing at segment C000, with the adapter in mono mode (misc output register bit 0 is cleared)) 😖

During boot, I see something in the BIOS writing to B86FA/C/E though?

Edit: Yeah, it's the BIOS, or something like it.
Adjusting the start (and end) address manually to B8000-BFFFF (even with the memory window actually being different) shows the BIOS properly booting (the RAM count at least) as well as the MS-DOS booting sequence.

Running MS-DOS then works to render again for a bit.
Running checkit diagnostics after that makes it go out of 'alignment' so to speak again (wrong memory area).
Then modifying it back to what it's supposed to be (B0000-B7FFF) makes it render again.

Selecting the video text test makes it hang again in the BIOS this time?

Edit: The CD test should work, as the memory test, so the OVER label should be reached in mono mode at least?

But i'd need to compile it myself (and somehow revert the ROM for proper usage and validate against original ROM to be sure)? With MASM of course. But i'll need an x86 emulator to run it on 64-bit Windows 10/11 I think? Probably Dosbox or perhaps even UniPCemu itself (assuming no CPU bugs ofc).

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

Reply 22 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Got the source code to compile with masm inside Dosbox 0.74.3.
The size isn't rounded to the boundary?

Also would need the code listing of the entire binary after linking?

Edit: OK, adjusted MK.BAT a bit for Dosbox:

del *.obj
del *.lst
del *.exe
del *.bin

8086\MASM /l VBIOS.ASM;
8086\MASM /l VCGMN.ASM;
8086\MASM /l VCGMNFDG.ASM;
8086\MASM /l VCGDDOT.ASM;
8086\MASM /l VEND.ASM;

8086\LINK /CO /LINENUMBERS VBIOS VCGMN VCGMNFDG VCGDDOT VEND;

8086\EXE2BIN VBIOS.EXE EGABIOS.BIN

Now it generates VBIOS.LST.
Then with the formula:
"3FFFh - offset"
I can translate between addresses in the listing and addresses in the original EGA ROM.
Although the EGA ROM seems to have some extra data after the end of the listing?

Oddly it's off with said formula sometimes compared to the source listing?

Edit: Just checked the masm compiled version using vbindiff against the original ROM.

I see some bytes being different from the original at the main part of the ROM at some places, but I think it's mostly data. Until 6FF, there's no errors in the generated ROM at least 😁

Besides some small byte changes (mainly offset related), it looks fine. The first change after that (at 05FF) is within the offsets for AH8 (function 08h of the interrupt 10h jumptable). Various other entries there as well.
Then:
0CF3 (VRET's offset low offset byte being 1 higher in the real ROM)
0E96 (PAL_ON offset low offset byte changed, 1 higher in real ROM)
0EF5 VRET again
0F1A V_RET again (bit 0 of immediate set)
0FAE CH_GEN pointer bit 0 set
0FD4 DO_MAP bit 0 set.
1132 V_RET again I think
115A same (bit 8 again set)
12CE same
1DB6 became 1DB7 in the real ROM (PAL_ON procedure).
13EB same, one higher (+100h instead of bit 8 set). Same deal again.
14C6 "
151F "
15A6 "
15CF "
164A "

Then there's a big change that throws the remainder of the ROM off.
At instruction 16F2 (just past the MK_ES label), a different opcode is used for the AND DI,030h. It uses opcode 81 modr/m "E7 30 00" instead of "83 E7 30". That causes all data after that to shift 1 byte earlier because of said padding byte. That goes on until address 222E. That's where VBIOS.LST ends it's SUBTTL CRLF procedure.
And guess what's in there, according to the source listings? V_RET (at address 219D).

All those are in the mode set and INT 10h functionality. Probably not that interesting to look at this point, as we're mostly interested in the POST itself (mode set is probably working correctly itself). It's the little things in between that are interesting (stuff like CRT manipulation and checks etc.) in this case.
Probably lots more after that, seeing those small changes.
Though mostly the ROM is intact enough to use for checking what the EGA's actually doing during POST. Behaviour seems correct mostly (other than relative/absolute offsets (x86) being off by a byte in the high byte of an address)

Most changes seem to be V_RET being 100h bytes ahead in memory?
The main issue mostly is the weird address change for said V_RET function (219D in the documentation). It's at 219E inside the original ROM!

Thinking about it, most of the issues with the ROM addressing (current version of MASM MS-DOS (https://vintechworld.blogspot.com/2017/10/dow … -windows10.html)) stem from that weird alternate instruction encoding with the extra byte? That instruction at address 16F2 using opcode 81h instead of opcode 83h (that masm generates) seems to have moved the ROM after that slightly out of alignment wrt said pointers.

The instruction affected is:

16F2  83 E7 30              C		AND	DI,030H 

That's supposed to be 81 E7 30 00 in the original ROM!

Otherwise, the ROM is usable without issues I think. Nice job on the guy that got it scanned 😁 Bringing me one step closer to figure out this EGA POST mess (and probably other people busy with EGA emulation too).

Edit: Found it! It's VGRW.INC, line 144 and EGABIG.ASM, line 4126 (same code, but in the larger file). Somehow need to get the assembler to use opcode 81h instead of 83h.
The VBIOS.LST has it at line 4463.
Edit: Since I couldn't find a way to make MASM use the proper 81h encoding used, I manually forced it:

	db 081H, 0E7H, 030H, 000H ;AND	DI,030H

Now, excluding the padding to 16KB and the final checksum byte(46h at 3FFF), it matches the output of the official ROM perfectly 😁
All it would need is to be reversed (as in byte order of the entire file) for a real EEPROM (or emulator) to use, since the address lines are reversed on EGA.

So we've gotten a good source listing with debugger breakpoint addresses to use now at last! 😁
Edit: OK. According to PCjs, just MASM 4 is enough to archieve the same I just did?
https://www.pcjs.org/software/pcx86/dev/rom/ibm/ega/

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

Reply 23 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. So after the first part (reading the switches) BL is set to 0Bh. So the switches have been read as 1011b. So that is indeed one of the monochrome modes at least?
It triggers first calling ENV_0 then ENV_3 at PST_B.
Before that, it sets INFO to EGA active monitor, wait for display enable enable, monochrome attached, set C_TYPE EMULATE ACTIVE.

It then calls ENV_0 followed by ENV_3. Why setup a mode 03h video first, then mode 07h after? Or is that setting up any potential CGA for color mode?
It calls the Generic Super PC/Turbo XT BIOS INT 10h handler, which I also got the source code of in this case (needs to be compiled to be used after downloaded after all, no Dosbox required for that).
Edit: Yay. A logging error made it hang itself parsing it's own buffer! 😖 That's at F000:F117 (filling the CGA (not connected) regen buffer with empty text with the debugger logging the memory transaction).
The call using INT 42h is at 0EF3 inside the EGA ROM. All that's left is jumping to V_RET, which cleans up the stack and returns from the interrupt handler to the INT 10h caller (the ENV_0 routine in this case).
Perhaps not important. It's just loading the CGA register ranges (which isn't emulated) in this case after that.
Anyways, after that it just cleanup after that until returning to the EGA BIOS ENV_0 routine (I don't see anything special in said code). Just stack cleanup and returning to the EGA handler there. The EGA then restores the cursor position in the

Would need to resume at said point at a later point in time. I'll be updating this again then. Nothing interesting though until the return to the EGA ROM (as no hardware is responding (at CGA addresses, since the EGA is in mono mode) there).

Edit: The INT 10h calls (both ENV_0(motherboard) and ENV_3(monochrome EGA mode 7 setup) both seem to work properly. The monochrome text mode is setup and the POST testing continues onwards to the next steps of the EGA validation. 😁
The registers seem to be setup correctly for the entire video card at least. The INT 10h calls also don't set the carry flag on return, which is good as well.

So then it's onwards to the POST tests themselves (the POST label)!
Video memory itself is present at address B0000 as it should.
I see it arriving at address 317h, at the start of the CRTC timing, which is followed by the color test (this might be interesting, as it's in mono mode?). It should operate using a blank character (DBh) in reverse video mode (attribute 0Fh) for 80 characters (1 character line of VRAM).
But that's for when I got more time.

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

Reply 24 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. Some more testing. During the first (cursor) test, I see it using the color adapter. Isn't it supposed to be using the monochrome adapter there? INFO's bit 1 is cleared at said point, which it shouldn't?

Location EBFh still has it set?

INT 42h call being executed still has the monochrome bit set?
It's unchanged after returning.

V_RET is at line 6599 of my source code...
The INFO variable is still 0Eh there. So it's still in monochrom mode...
So the BIOS doesn't screw up so far.
C000:0170 is supposed to setup monochrome text mode.
It leaves with the INFO byte set to 02h. So it's still in monochrome mode, EGA active.

At 0247 it's still in monochrome mode (value 02h).
A jump is executed to POD14.

It reaches 32E and setups the EGA in monochrome mode 07h (ENV_3 again).

It reaches location 3F6 (the start of the attribute controller it seems, looking for correct results on the color outputs)?

Oddly the comments about the input status #0 register mux bits say it's testing for pixels to come on or off?

UniPCemu simply reports the MUX results as being the last DAC input for active display. When it's in overscan it doesn't change, thus if I understand it, it never goes 'off'?

Looking at the documentation (POD14 test):
41B: See if dot comes on
42B: See if dot goes off
43A: Dot turned off
446: Check next dot
448: Error in POD14 test
466: POD14 test finished

Edit: Huh? It uses port 3C0 to write the index, then 3C1 to write the data to the attribute controller?
Edit: Just checked my own code. That's an exception for EGA only (VGA+ don't do that anymore). If it's in data mode, writes to 3C1 are redirected to 3C0 effectively, but only if it's in data mode (weird EGA BIOS behaviour).

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

Reply 25 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. After a lot more single stepping, I see it executing at offset 61Ah now.

I see it's executing the memory test now?
Edit: And it seems to execute properly, returning to the motherboard BIOS POST routines looping the option ROMs.

Although the BIOS still tries to use a non-existent color card (perhaps by setting the switches to a color card when calling INT 10h)?
The switches are set to EGA/VGA right now. Should they be "MDA" (both flipped from EGA/VGA setting) with a EGA with monochrome monitor?

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

Reply 26 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Is there any software that is known to use the 3-color (4 including blink) mode F monochrome EGA graphics?
Tried Simcity 1 but it seems to only use the lower plane?

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

Reply 27 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

I'm wondering now...
Is switches SW3=On, others off on EGA for primary EGA or secondary EGA?

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

Reply 28 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-02-10, 10:22:

I'm wondering now...
Is switches SW3=On, others off on EGA for primary EGA or secondary EGA?

The ultimate reference is the original documentation: https://minuszerodegrees.net/ibm_ega/IBM%20EG … nstructions.pdf

The setting SW1/SW2/SW3/SW4 as off/off/on/off is listed in table 1 on PDF page 27 (document page 19) as "EGA is the only card, monochrome monitor connected". It is also listed in table 4 (CGA & EGA installed, EGA[mono] is the primary adapter). The row in that table is labelled "EGA: monochrome monitor, CGA: no monitor", so this setting does not cause the IBM mainboard BIOS to initialize the CGA card. In practice, this setting is: "EGA card is the primary card (with a monochrome monitor connected), a CGA card may be present, but is not initialized on boot".

Reply 29 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2024-02-10, 10:59:
superfury wrote on 2024-02-10, 10:22:

I'm wondering now...
Is switches SW3=On, others off on EGA for primary EGA or secondary EGA?

The ultimate reference is the original documentation: https://minuszerodegrees.net/ibm_ega/IBM%20EG … nstructions.pdf

The setting SW1/SW2/SW3/SW4 as off/off/on/off is listed in table 1 on PDF page 27 (document page 19) as "EGA is the only card, monochrome monitor connected". It is also listed in table 4 (CGA & EGA installed, EGA[mono] is the primary adapter). The row in that table is labelled "EGA: monochrome monitor, CGA: no monitor", so this setting does not cause the IBM mainboard BIOS to initialize the CGA card. In practice, this setting is: "EGA card is the primary card (with a monochrome monitor connected), a CGA card may be present, but is not initialized on boot".

Well, it seems that the Generic PC/Turbo XT BIOS actually does initialize the 'CGA' card (it writes the MC6845 CRTC (port 3Dx range) and other registers on the INT 10h call during said INT 42h from the EGA).

In my case (since I have the XT-IDE Universal BIOS) the hard-disk ROM actually starts the correct video mode (and makes the display half-active, rendering itself properly in text mode on the EGA.
But once the boot process starts, it switches back to the 'primary' CGA (non-existent RAM) card memory range? The EGA remains in text mode at that point. MS-DOS (blindly if typed (in my case press F5 to skip the MS-DOS 6.22 boot menu first)) executing "mode mono" fixes the display to be properly used from that point onwards.

Oddly enough, after POSTing the EGA and continuing motherboard POST, the EGA passes through INT 10h function 00h mode 03h to the motherboard BIOS once (probably INT 42h)?
I see the function INT 10h calls by the onboard BIOS ROM properly reaching the EGA BIOS entry point otoh? So there's something going wrong there? The EGA is in proper monochrome text mode though, according to it's registers?

It seems to be properly rendering the screen, but the BIOS doesn't properly write to VRAM?

Last edited by superfury on 2024-02-10, 14:05. Edited 2 times in total.

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

Reply 30 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-02-10, 13:47:

Well, it seems that the Generic PC/Turbo XT BIOS actually does initialize the 'CGA' card (it writes the MC6845 CRTC (port 3Dx range) and other registers on the INT 10h call during said INT 42h from the EGA).

Well, that is a surprise for me. I didn't expect the EGA BIOS to call into the mainboard BIOS in the case of "CGA: no monitor connected".

superfury wrote on 2024-02-10, 13:47:

In my case (since I have the XT-IDE Universal BIOS) the hard-disk ROM actually starts the correct video mode (and makes the display half-active, rendering itself properly in text mode on the EGA.
But once the boot process starts, it switches back to the 'primary' CGA (non-existent RAM) card memory range? The EGA remains in text mode at that point.

The switch setting you cited is meant to leave the EGA the active card (in mode 7) after POST, and I have no idea what configuration is applied to the CGA card (as you neither selected 40x25 or 80x25), but likely the CGA is posted into some text mode. Is it possible that the XT-IDE Universal BIOS switches to the color card (i.e. it performs the same thing as MODE CO80 would perform), or do you happen to have "mode co80" in your autoexec.bat?

superfury wrote on 2024-02-10, 13:47:

Oddly enough, after POSTing the EGA and continuing motherboard POST, the EGA passes through INT 10h function 00h mode 03h to the motherboard BIOS once (probably INT 42h)?
I see the function INT 10h calls by the onboard BIOS ROM properly reaching the EGA BIOS entry point otoh? So there's something going wrong there? The EGA is in proper monochrome text mode though?

That's intended behaviour, especially if the video display type in the equipment byte is set to anything non-MONO (not 30h). If the EGA DIP switches indicate "mono monitor on EGA" and the equipment display type indicates non-mono, the EGA BIOS is supposed to forward mode sets to the mainboard BIOS, and until you initiate another mode set with the equipment byte set to MONO, all other BIOS calls are likely also forwarded to the mainboard BIOS. There is a configuration bit ("EGA is the active card") somewhere around 40:87, which is used by non-modeset calls to decide whether the EGA BIOS or the INT 42 mainboard BIOS is supposed to handle the call. This bit is updated during modeset calls.

Reply 31 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

Oddly enough, https://stanislavs.org/helppc/bios_data_area.html lists the :88h is documented reversed of how the BIOS loads it in UniPCemu right now (according to my interpretation of the jumptable based on the start of the POST setup after reading the dipswitches and feature registers)?

UniPCemu sets SW2 only (others off) and the variable in the BDA contains 0Bh at address 0488h in RAM.

The EGA BIOS really reads the dipswitches, but practically inverses the bits in the result from the bits in the MISC OUTPUT REGISTER outputs to read it. So clock #0 returns bit #3, clock #1 returns bit #2, clock #2 returns bit #1 and clock #3 returns bit #0 as stored there.

;----- READ THE SWITCH SETTINGS ON THE CARD

RD_SWS PROC NEAR
ASSUME DS:ABS0
MOV DH,3
MOV DL,MISC_OUTPUT
MOV AL,1
OUT DX,AL

;----- COULD BE 0,4,8,C

MOV AL,0DH
CALL POR_1
SHR AL,1
SHR AL,1
SHR AL,1
MOV BL,AL

MOV AL,9
CALL POR_1
SHR AL,1
SHR AL,1
OR BL,AL

MOV AL,5
CALL POR_1
SHR AL,1
OR BL,AL

MOV AL,1
CALL POR_1
OR BL,AL

AND BL,0FH
RET
RD_SWS ENDP

POR_1 writes AL to port 3C2 (register DX), then reads it back from it.

So the bits are stored in opposite order? Only entries 0h-Bh are valid in it's resulting BL register (otherwise causing the 'crash' that's documented for the undefined dipswitches apparently on the EGA cards).

T5	LABEL	WORD
DW OFFSET PST_0
DW OFFSET PST_1
DW OFFSET PST_2
DW OFFSET PST_3
DW OFFSET PST_4
DW OFFSET PST_5
DW OFFSET PST_6
DW OFFSET PST_7

DW OFFSET PST_8
DW OFFSET PST_9
DW OFFSET PST_A
DW OFFSET PST_B
DW OFFSET PST_OUT
DW OFFSET PST_OUT
DW OFFSET PST_OUT
DW OFFSET PST_OUT

In this table, PST_4, PST_5, PST_A and PST_B put the card in monochrome mode based on that RD_SWS value (it's the index into the table, shifted left to entry size of couse).
So that's read cases (switches off/on in order from bits 0 through 3):
0100b (on off on on)
0101b (on off on off)
1010b (off on off on)
1011b (off on off off)

The main difference between them is (all using the mono address 3Bx space and putting the card in mono mode):
0100b (on off on on) ENV_3 ENV_X
0101b (on off on off) ENV_3 ENV_0
1010b (off on off on) ENV_X ENV_3
1011b (off on off off) ENV_0 ENV_3
ENV_X sets up 40x25 color alpha (mode 1, equipment 01b). ENV_0 sets up 80x25 color alpha (mode 3, equipment 10b). ENV_3 sets up monochrome alpha (mode 7, equipment 11b).

Last edited by superfury on 2024-02-10, 14:25. Edited 1 time in total.

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

Reply 32 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-10, 14:06:

The EGA BIOS really reads the dipswitches, but practically inverses the bits in the result from the bits in the MISC OUTPUT REGISTER outputs to read it. So clock #0 returns bit #3, clock #1 returns bit #2, clock #2 returns bit #1 and clock #3 returns bit #0 as stored there.

So the bits are stored in opposite order? Only entries 0h-Bh are valid in it's resulting BL register (otherwise causing the 'crash' that's documented for the undefined dipswitches apparently on the EGA cards).

DIP switches are often inverted when read. You will see this in the PPI as well on the PC/XT. I believe this is due to the design of the switch, which leaves the circuit "open" when the switch is off, so it was common to use a pull-up resistor when connecting to the DIP that would then connect to ground. This gives a logical 1 when the DIP is off and a logical 0 when the DIP is on.

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

Reply 33 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++

It's both inverted and reverted if I'm using the proper terms.
On=0, off=1 (=inverted)
clock #0=SW#3 and clock #3=SW#0 (=reverted)

Otherwise, the IBM documentation on the switches and resulting table entries doesn't match the monochrome modes properly (not selecting 3Bx or aborting in some cases)?

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

Reply 34 of 54, by GloriousCow

User metadata
Rank Member
Rank
Member
superfury wrote on 2024-02-10, 14:27:
It's both inverted and reverted if I'm using the proper terms. On=0, off=1 (=inverted) clock #0=SW#3 and clock #3=SW#0 (=reverte […]
Show full quote

It's both inverted and reverted if I'm using the proper terms.
On=0, off=1 (=inverted)
clock #0=SW#3 and clock #3=SW#0 (=reverted)

Otherwise, the IBM documentation on the switches and resulting table entries doesn't match the monochrome modes properly (not selecting 3Bx or aborting in some cases)?

Looking at the schematic, it doesn't look like the DIP can actually be read directly. The four DIP pins go into a 4-1 multiplexer - the schematic omits the select lines.

EDIT: Ah right, we can only read one switch at a time via CLKSEL. That's normal
Pin one of the DIP is connected to C3 of the multiplexer. That explains your reversed order.

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

Reply 35 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
GloriousCow wrote on 2024-02-10, 14:50:
Looking at the schematic, it doesn't look like the DIP can actually be read directly. The four DIP pins go into a 4-1 multiplex […]
Show full quote
superfury wrote on 2024-02-10, 14:27:
It's both inverted and reverted if I'm using the proper terms. On=0, off=1 (=inverted) clock #0=SW#3 and clock #3=SW#0 (=reverte […]
Show full quote

It's both inverted and reverted if I'm using the proper terms.
On=0, off=1 (=inverted)
clock #0=SW#3 and clock #3=SW#0 (=reverted)

Otherwise, the IBM documentation on the switches and resulting table entries doesn't match the monochrome modes properly (not selecting 3Bx or aborting in some cases)?

Looking at the schematic, it doesn't look like the DIP can actually be read directly. The four DIP pins go into a 4-1 multiplexer - the schematic omits the select lines.

EDIT: Ah right, we can only read one switch at a time via CLKSEL. That's normal
Pin one of the DIP is connected to C3 of the multiplexer. That explains your reversed order.

Do you have an explanation of what cases 4,5,A,B order of calling the different INT 10h modes? Why would the BIOS setup monochrome mode and use color memory addresses after that (CGA memory mapping B8000+) while the card expects B0000+?
The same thing seems to happen once MS-DOS starts booting?

Edit: Also, is there any MS-DOS software that tests mode 0Fh's 4-color graphics in any way (the blinking and low/high intensity white using bitplane 2) you know of? The INT 10h only supports plane 0 it seems? Is there any way to render to plane 2 instead?

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

Reply 36 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t
mkarcher wrote on 2024-02-10, 14:01:
superfury wrote on 2024-02-10, 13:47:

Well, it seems that the Generic PC/Turbo XT BIOS actually does initialize the 'CGA' card (it writes the MC6845 CRTC (port 3Dx range) and other registers on the INT 10h call during said INT 42h from the EGA).

Well, that is a surprise for me. I didn't expect the EGA BIOS to call into the mainboard BIOS in the case of "CGA: no monitor connected".

It's no longer surprinsing when you notice that not only "EGA mono only" and "EGA mono / CGA no monitor" use the same DIP switch pattern, but "EGA mono / CGA 80x25" also uses that pattern. So everything goes to plan when the CGA registers are initialized with this switch configuration.

Reply 37 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-02-10, 15:40:

Do you have an explanation of what cases 4,5,A,B order of calling the different INT 10h modes? Why would the BIOS setup monochrome mode and use color memory addresses after that (CGA memory mapping B8000+) while the card expects B0000+?
The same thing seems to happen once MS-DOS starts booting?

The idea of the diffent order of calling the INT 10h mode set calls is that the first mode set call initializes the "secondary" card. This sets up the hardware of the secondary card and the BIOS data area for the mode to be initialized on the secondary card. Then another mode set call is made to initialize the "primary" card. That call initializes the hardware of the primary card (leaving the hardware of the secondary card alone) and overwrites the BIOS data area for operation on the primary card. After that call sequence, the secondary card is initialized and the display contents on the secondary card can be changed by direct video memory access (but software would have way to confirm what mode the secondary card is in) only, whereas the primary card is accessible using BIOS calls and software can use the BIOS data area contents to find out what mode is currently programmed on the primary card.

superfury wrote on 2024-02-10, 15:40:

Edit: Also, is there any MS-DOS software that tests mode 0Fh's 4-color graphics in any way (the blinking and low/high intensity white using bitplane 2) you know of? The INT 10h only supports plane 0 it seems? Is there any way to render to plane 2 instead?

You might give CHECKIT a try. It should display a test pattern using the full color palette in all modes supported by the current video card. I don't know whether they implemented proper EGA mono support, though.

Reply 38 of 54, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2024-02-10, 17:19:
The idea of the diffent order of calling the INT 10h mode set calls is that the first mode set call initializes the "secondary" […]
Show full quote
superfury wrote on 2024-02-10, 15:40:

Do you have an explanation of what cases 4,5,A,B order of calling the different INT 10h modes? Why would the BIOS setup monochrome mode and use color memory addresses after that (CGA memory mapping B8000+) while the card expects B0000+?
The same thing seems to happen once MS-DOS starts booting?

The idea of the diffent order of calling the INT 10h mode set calls is that the first mode set call initializes the "secondary" card. This sets up the hardware of the secondary card and the BIOS data area for the mode to be initialized on the secondary card. Then another mode set call is made to initialize the "primary" card. That call initializes the hardware of the primary card (leaving the hardware of the secondary card alone) and overwrites the BIOS data area for operation on the primary card. After that call sequence, the secondary card is initialized and the display contents on the secondary card can be changed by direct video memory access (but software would have way to confirm what mode the secondary card is in) only, whereas the primary card is accessible using BIOS calls and software can use the BIOS data area contents to find out what mode is currently programmed on the primary card.

superfury wrote on 2024-02-10, 15:40:

Edit: Also, is there any MS-DOS software that tests mode 0Fh's 4-color graphics in any way (the blinking and low/high intensity white using bitplane 2) you know of? The INT 10h only supports plane 0 it seems? Is there any way to render to plane 2 instead?

You might give CHECKIT a try. It should display a test pattern using the full color palette in all modes supported by the current video card. I don't know whether they implemented proper EGA mono support, though.

I already did try CHECKIT. It just seemed to display colors #0 and #1. #2(blinking white) and #3(bright white) seems unused (or always using color #0 and #3)?

I am currently writing a little test program that (according to a simple INT 10h function AX=000Fh and the documentation on using the memory map register (Sequencer #2) to filter the planes (value 01h for low, value 04h for high) to write). Then simply write the 8 pixels (high bits first) to the A000:offset window, offsets displaced by A0h bytes from CPU point of view).

After that simply wait for a keypress to return to mode 03h and terminate the program.

There's some UniPCemu debugger port (UNIPCEMU.PAS from the UniPCemu pascal source code folder) stuff as well, but that's currently disabled.
It's not in source control yet though, still am writing and testing it's functionality.
But that's the basics of what I'm doing right now.

It switches to graphics mode 0Fh so far, but nothing is displayed yet? (after mode mono of course)

Needed to reboot a bit after trying to load mouse.com from command.com inside Turbo Pascal 6.0 though. Perhaps not the brightest idea (running mouse.com and then exit back to turbo.exe).

Mode 07h seems mostly function, according to TESTMDA.PAS's dumped attributes on the screen?
But most-non ~01h (underline) attributes with blink set cause the font to disappear (only underline is visible blinking)?

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

Reply 39 of 54, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-02-10, 18:05:

I already did try CHECKIT. It just seemed to display colors #0 and #1. #2(blinking white) and #3(bright white) seems unused (or always using color #0 and #3)?

I remember reading about EGA mono capabilities in the MS-DOS 3.3 GWBASIC manual 30 years ago. GWBASIC thus might support that mode out-of-the-box. As does EGAVGA.BGI as provided by Borland... Both of these environments should make all four "colors" available.