VOGONS


First post, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

This is about the IBM version of the VGA ISA card.

So I am trying to complete my VGA emulation and the VGA bios I am using is ibm_vga.bin from minuszerodegrees. There are a few awkward things about the behavior of the bios and you can see how it shares a lot of code with the IBM EGA bios. For example

1) Apparently the card has dipswitches of some kind. The BIOS reads them via "in al, 3C2h". There seem to be 6 of them. Returning 1,1,0,0,0,0 (which I think means off, off, on, on, on, on) makes the BIOS happy. Otherwise it emits 2 long beeps.

2) It expects the (undocumented) flipping of 2 bits in InputStatusRegister1 (the 3BAh/3DAh register that has "are we in VSync?"). I remember even Sarah Walker had to do this for PCEm's EGA emulation (and so do I) and it seems this carried over to VGA. According to normal VGA documentation the top 4 bits are not used in that register, yet the BIOS will "and" them with 0x30.

3) There are some other issues and strangeness (like setting the character height to 0...) that I am trying to debug.

So questions:

1) Does anyone have a picture of said IBM VGA ISA card? Google is not much of help as I get a lot of VGA-compatible cards, which is not what I am after. I assume it exists right?

2) Does IBMulator and/or UniPCEmu emulate properly ibm_vga.bin BIOS and if so how do you deal with my points above?

I looked at UniPCEmu and I do not see how they deal with points 1) and 2) so my guess is the VGA BIOS fails detection but the normal BIOS will use the card anyway.

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 1 of 15, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie

For example IBM PS/55 has this inside (which shows the IBM VGA chip)

https://en.wikipedia.org/wiki/Video_Graphics_ … 941_on_PS55.jpg

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 15, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie

http://www.minuszerodegrees.net/5150/vga/5150_vga.htm

There's a link to IBM PS/2 VGA card.

Port 3C2h should have both interrupt pending bit (7) and monitor sense switch bit (4) to determine attached display type (color VGA / monochrome VGA). Others should be undefined.

Display type sense works so that if you have a color VGA monitor it will load down RGB outputs with termination resistors, if not, the unterminated channels have higher voltage that can be detected with a comparator. So it basically needs to drive non-black pixels on screen before it can sense if there are unterminated pins or not. I don't know if this is used for detecting between all three possible combinations (disconnected/RGB/grayscale) or just a subset.

Port 3DAh will have both the vertical retrace bit (that somehow relates to VSYNC to monitor) and inverted Data Enable bit that tells you if active area on screen is drawn or non-active area is being drawn, so you can use it for all kinds of tricks such as counting lines where the drawing is occuring to do some tricks or waiting to do some updates between lines. Bits 5 and 4 are diagnostic bits, that give you feedback from attribute controller about what 8-bit pixel data is sent to DAC, and some other bits somewhere else can select which two bits from eight are sent to these two diagnostic bits.

Reply 3 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++
vladstamate wrote:
This is about the IBM version of the VGA ISA card. […]
Show full quote

This is about the IBM version of the VGA ISA card.

So I am trying to complete my VGA emulation and the VGA bios I am using is ibm_vga.bin from minuszerodegrees. There are a few awkward things about the behavior of the bios and you can see how it shares a lot of code with the IBM EGA bios. For example

1) Apparently the card has dipswitches of some kind. The BIOS reads them via "in al, 3C2h". There seem to be 6 of them. Returning 1,1,0,0,0,0 (which I think means off, off, on, on, on, on) makes the BIOS happy. Otherwise it emits 2 long beeps.

2) It expects the (undocumented) flipping of 2 bits in InputStatusRegister1 (the 3BAh/3DAh register that has "are we in VSync?"). I remember even Sarah Walker had to do this for PCEm's EGA emulation (and so do I) and it seems this carried over to VGA. According to normal VGA documentation the top 4 bits are not used in that register, yet the BIOS will "and" them with 0x30.

3) There are some other issues and strangeness (like setting the character height to 0...) that I am trying to debug.

So questions:

1) Does anyone have a picture of said IBM VGA ISA card? Google is not much of help as I get a lot of VGA-compatible cards, which is not what I am after. I assume it exists right?

2) Does IBMulator and/or UniPCEmu emulate properly ibm_vga.bin BIOS and if so how do you deal with my points above?

I looked at UniPCEmu and I do not see how they deal with points 1) and 2) so my guess is the VGA BIOS fails detection but the normal BIOS will use the card anyway.

UniPCemu:
1) The dipswitches should be fully emulated. It uses inverted input(1=on), which is inverted when the CPU reads it. Color and mono monitors are properly detected on VGA BIOS. EGA previously crashed it's BIOS, haven't tested since implementing it(Might work by now with the many bugfixes).
2. The input status bits are fully emulated according to chip(CGA/EGA/(S)VGA).

Look at the VGA renderer, VGA_precalcs.c and VGA_IO.c for the implementations of 1&2.

3) Character height 0 doesn't exist: the character heights range from 0-31(depending on CGA vs EGA+). Add 1 to that number for the amount of scanlines of a character cel(Thus 1 to 32 lines range on VGA, CGA was 1-8 if I remember correctly. Look at VGA_precalcs.c and VGA_CGA_MDA for the implementation.).

Edit: Didn't we have part of this conversation before? IBM EGA and text mode woes

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

Reply 4 of 15, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

Edit: Didn't we have part of this conversation before? IBM EGA and text mode woes

We did, but that was EGA, this is VGA. In CAPE I implement this as two separate pieces of code (mirroring two pieces of HW). Plus the BIOS and underlining HW is different enough. For example I did not expect the VGA to have dipswitches. EGA does yes, but VGA? I have never seen a VGA with switches. But apparently they exist. Hence my questions.

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 5 of 15, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

3) Character height 0 doesn't exist: the character heights range from 0-31(depending on CGA vs EGA+). Add 1 to that number for the amount of scanlines of a character cel(Thus 1 to 32 lines range on VGA, CGA was 1-8 if I remember correctly. Look at VGA_precalcs.c and VGA_CGA_MDA for the implementation.).

Yeah, I misspoke, I did not mean actual character height but rather what the bios pokes in the CRTC register. In my traces the VGA BIOS only writes twice to the 9th CRTC register. Once 0 and once 0x40.

 [VGADevice: port 0x3d4 out 0x9] 
[VGADevice: port 0x3d5 out 0x40]

Both 0 and 40h mean same thing: character height of 1. Obviously that cannot be correct. I still think the BIOS does not properly detect the board and eventually exits too early before setting proper CRTC values. I wish I had the VGA BIOS listing (like I have the EGA one) as the EGA one helped me tremendously finding emulation bugs. I guess IBM never made it available.

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 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

The BIOS as well as software are properly reading the switches and responding to it(CheckIt displays and VGA BIOS initializes to monochrome or color mode accordingly, depending on the monitor setup(Settings menu -> Video -> Monitor setting. Options are Color(0110) and B/W,Brownscale,Grayscale,Greenscale(0010, but on VGA+ only atm, EGA forces 0110)).

You can always try to simply run UniPCemu with the VGA BIOS and dump it's results to compare(using the Common log format). Although register logging also enables the currently unimplemented short(compact) version of memory access logging for proper testing.

For more proof look at the VGA connector pin 11,12,4,15 afaik on eg. wikipedia. Those clearly say ID0-3, until E-DDC.

Last edited by superfury on 2017-11-16, 23:07. 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 7 of 15, by vladstamate

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

The BIOS as well as software are properly reading the switches and responding to it(CheckIt displays and VGA BIOS initializes to monochrome or color mode accordingly, depending on the monitor setup(Settings menu -> Video -> Monitor setting. Options are Color(0110) and B/W,Brownscale,Grayscale,Greenscale(0010, but on VGA+ only atm, EGA forces 0110)).

You can always try to simply run UniPCemu with the VGA BIOS and dump it's results to compare(using the Common log format). Although register logging also enables the currently unimplemented short(compact) version of memory access logging for proper testing.

Excellent, I'll try that. Thanks.

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 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

Don't forget to set it to IPS mode(and your emulator as well, if it supports it). That should fix any clock cycle differences between our emulators(which might differ due to different implementations).

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

Reply 9 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

Thinking about it: the fixes on the shift might make it(The EGA BIOS) continue: the shr that wasn't affecting the carry flag(properly) back then might have been fixed in more recent builds.

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

Reply 10 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

Although that seems to have been fixed(it continues to POST and even boot on EGA now), the misc output register is still 0x00, thus nothing is in VRAM, no fonts nor text/attributes? Can you see what's going wrong by comparing logs on the EGA? The memory is mapped properly at physical address 0xB8000, but it's disabled?

Just implemented the EGA register defaults from https://github.com/OBattler/PCem-X/blob/maste … /PCem/vid_ega.c , but still nothing?

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

Reply 11 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just found a bug turning EGA clocks to use VGA clocks instead(EGA vs VGA clock determination checked CGA Extension ID 4(Unused) instead of 3(EGA)). But the BIOS still fails setting up VRAM?

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

Reply 12 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does any one has a VGA vs EGA difference list, listing all differences between EGA and VGA I/O and timings?

I currently have implemented the following differences(the base system is a VGA after all):
- Disable internal video drivers(EGA only).
- ROM is reversed.
- MISC output register starts with bits 1 and 5 set.
- Sequencer register 4 starts with bit 1 set.
- VGA palette is replaced by a constant EGA palette instead(64 colors).

Notes on VGA vs EGA differences: CRTC index 5h bit 7: Start odd memory address (after horizontal retrace) CRTC index 11h read: L […]
Show full quote

Notes on VGA vs EGA differences:
CRTC index 5h bit 7: Start odd memory address (after horizontal retrace)
CRTC index 11h read: Light pen low
CRTC index 17h: bit 4: Output control. When 1, CRTC output is in high-impedance state.

Port 3CC(w): Graphics 1 position register. Bits 0-1. Usually programmed to 0.
Port 3CA(w): Graphics 2 position register. BIts 0-1. Usually programmed to 1.

Graphics index 5 bit 2: Test condition. When 1, Graphics controller output is placed in high-impedance state for testing.

Input Status register 0 bits 5-6: Feature connector code that's input.

- Registers have partly been masked off for compatiblity with VGA output.

byte VGA_RegisterWriteMasks_CRTC[2][0x25] = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //VGA
{0xFF,0xFF,0xFF,0x7F,0xFF,0xFF,0xFF,0x3F,0x1F,0x1F,0x1F,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0xFF,0xFF,0x1F,0xFF,0x1F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}; //EGA
byte VGA_RegisterWriteMasks_Attribute[2][0x15] = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //VGA
{0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x0F,0x3F,0x3F,0x0F,0x00}}; //EGA
byte VGA_RegisterWriteMasks_InputStatus0[2] = {0xFF,0x90};
byte VGA_RegisterWriteMasks_InputStatus1[2] = {0xFF,0x7F};
byte VGA_RegisterWriteMasks_FeatureControl[2] = {0x03,0x03};
byte VGA_RegisterWriteMasks_MiscOutput[2] = {0xFF,0xFF};
byte VGA_RegisterWriteMasks_Sequencer[2][8] = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //VGA
{0x03,0x0F,0x0F,0x0F,0x07,0x00,0x00,0x00}}; //EGA
byte VGA_RegisterWriteMasks_Graphics[2][9] = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //VGA
{0x0F,0x0F,0x0F,0x3F,0x07,0x3F,0x0F,0x0F,0xFF}}; //EGA
//Limits are the maximum valid index+1(the total amount of registers that are addressable by index in the index register(including holes)).
byte VGA_RegisterWriteLimits_CRTC[2] = {0x25,0x19};
byte VGA_RegisterWriteLimits_Attribute[2] = {0x15,0x14};
byte VGA_RegisterWriteLimits_Sequencer[2] = {8,5};
byte VGA_RegisterWriteLimits_Graphics[2] = {9,9};

byte VGA_RegisterWriteMask_CRTCIndex[2] = {0xFF,0x1F};
byte VGA_RegisterWriteMask_AttributeIndex[2] = {0xFF,0x3F};
byte VGA_RegisterWriteMask_SequencerIndex[2] = {0xFF,0x1F};
byte VGA_RegisterWriteMask_GraphicsIndex[2] = {0xFF,0x0F}; //A.k.a. Graphics 1 and 2 Address register

(Index 1 is the EGA mask, index 0 is the VGA mask)

Port 3D4:

	case 0x3D4: //CRTC Controller Address Register		ADDRESS
if (!GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER,0,1)) goto finishinput; //Block: we're a mono mode addressing as color!
readcrtaddress:
if (getActiveVGA()->enable_SVGA!=3) //Not EGA?
{
*result = getActiveVGA()->registers->CRTControllerRegisters_Index; //Give!
ok = 1;
}
break;

Port 3D5:

	case 0x3D5: //CRTC Controller Data Register		DATA
if (!GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER,0,1)) goto finishinput; //Block: we're a mono mode addressing as color!
readcrtvalue:
if ((getActiveVGA()->enable_SVGA!=3) || (((getActiveVGA()->registers->CRTControllerRegisters_Index==0x11) || (getActiveVGA()->registers->CRTControllerRegisters_Index==0x12)) && (getActiveVGA()->enable_SVGA==3))) //Not EGA or EGA light pen registers?
{
*result = PORT_readCRTC_3B5(); //Read port 3B5!
ok = 1;
}
break;

Port 3C0:

	case 0x3C0: //Attribute Address/Data register		ADDRESS/DATA
//Do nothing: write only port! Undefined!
if (getActiveVGA()->enable_SVGA!=3) //Not EGA?
{
*result = (VGA_3C0_PALR<<5)|VGA_3C0_INDEXR; //Give the saved information!
ok = 1;
}
break;

Port 3C1:

	case 0x3C1: //Attribute Data Read Register		DATA
if (VGA_3C0_INDEXR>=VGA_RegisterWriteLimits_Attribute[(getActiveVGA()->enable_SVGA==3)?1:0]) break; //Out of range!
if (getActiveVGA()->enable_SVGA!=3) //Not EGA?
{
*result = getActiveVGA()->registers->AttributeControllerRegisters.DATA[VGA_3C0_INDEXR]; //Read from current index!
ok = 1;
}
break;

Input status #0 register:

	case 0x3C2: //Read: Input Status #0 Register		DATA
//Switch sense: 0=Switch closed(value of the switch being 1)
switchval = ((getActiveVGA()->registers->switches)>>GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER,2,3)); //Switch value to set!
switchval = ~switchval; //Reverse the switch for EGA+!
SETBITS(getActiveVGA()->registers->ExternalRegisters.INPUTSTATUS0REGISTER,4,1,(switchval&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!
*result &= VGA_RegisterWriteMasks_InputStatus0[(getActiveVGA()->enable_SVGA==3)?1:0]; //Apply the write mask to the data written to the register!
ok = 1;
break;

Disabled registers(reads):

	case 0x3C5: //Sequencer Data Register			DATA
case 0x3C6: //DAC Mask Register?
case 0x3C7: //Read: DAC State Register DATA
case 0x3C8: //DAC Address Write Mode Register ADDRESS
case 0x3C9: //DAC Data Register DATA
case 0x3CA: //Read: Feature Control Register DATA
case 0x3CC: //Read: Miscellaneous Output Register DATA
case 0x3CF: //Graphics Controller Data Register DATA

Input Status #1 register(write):

	case 0x3DA: //Input Status #1 Register (color)	DATA
if (GETBITS(getActiveVGA()->registers->ExternalRegisters.MISCOUTPUTREGISTER,0,1)) //Block: we're a mono mode addressing as color!
{
readInputStatus1:
SETBITS(getActiveVGA()->registers->CRTControllerRegisters.REGISTERS.ATTRIBUTECONTROLLERTOGGLEREGISTER,7,1,0); //Reset flipflop for 3C0!

*result = getActiveVGA()->registers->ExternalRegisters.INPUTSTATUS1REGISTER; //Give!
const static byte bittablelow[2][4] = {{0,4,1,6},{0,4,1,8}}; //Bit 6 is undefined on EGA!
const static byte bittablehigh[2][4] = {{2,5,3,7},{2,5,3,8}}; //Bit 7 is undefined on EGA!
byte DACOutput = getActiveVGA()->CRTC.DACOutput; //Current DAC output to give!
SETBITS(*result,4,1,GETBITS(DACOutput,bittablelow[(getActiveVGA()->enable_SVGA==3)?1:0][GETBITS(getActiveVGA()->registers->AttributeControllerRegisters.REGISTERS.COLORPLANEENABLEREGISTER,4,3)],1));
SETBITS(*result,5,1,GETBITS(DACOutput,bittablehigh[(getActiveVGA()->enable_SVGA==3)?1:0][GETBITS(getActiveVGA()->registers->AttributeControllerRegisters.REGISTERS.COLORPLANEENABLEREGISTER,4,3)],1));
if (getActiveVGA()->enable_SVGA==3) //EGA has lightpen support here?
{
SETBITS(*result,1,1,GETBITS(getActiveVGA()->registers->EGA_lightpenstrobeswitch,1,1)); //Light pen has been triggered and stopped pending? Set light pen trigger!
SETBITS(*result,2,1,GETBITS(~getActiveVGA()->registers->EGA_lightpenstrobeswitch,2,1)); //Light pen switch is open(not pressed)?
}
ok = 1;
}
break;

Disabled writes:

	case 0x3C6: //DAC Mask Register?
case 0x3C7: //Write: DAC Address Read Mode Register ADDRESS
case 0x3C8: //DAC Address Write Mode Register ADDRESS
case 0x3C9: //DAC Data Register DATA

Graphics controller data register:

	case 0x3CF: //Graphics Controller Data Register		DATA
if (getActiveVGA()->registers->GraphicsRegisters_Index>=VGA_RegisterWriteLimits_Graphics[(getActiveVGA()->enable_SVGA==3)?1:0]) break; //Invalid index!
value &= VGA_RegisterWriteMasks_Graphics[(getActiveVGA()->enable_SVGA==3)?1:0][getActiveVGA()->registers->GraphicsRegisters_Index]; //Apply the write mask to the data written to the register!
getActiveVGA()->registers->GraphicsRegisters.DATA[getActiveVGA()->registers->GraphicsRegisters_Index] = value; //Set!
VGA_calcprecalcs(getActiveVGA(),WHEREUPDATED_GRAPHICSCONTROLLER|getActiveVGA()->registers->GraphicsRegisters_Index); //We have been updated!
ok = 1;
break;

Extra EGA support(writes):

	//EGA compatibility!
case 0x3DB:
if (getActiveVGA()->enable_SVGA==3) //EGA?
{
//Light pen latch is to be cleared!
getActiveVGA()->registers->EGA_lightpenstrobeswitch &= ~3; //Stop strobe(pending)&measurement ready flag?
}
break;
case 0x3DC:
if (getActiveVGA()->enable_SVGA==3) //EGA?
{
//Light pen latch is to be triggered!
getActiveVGA()->registers->EGA_lightpenstrobeswitch |= 1; //Start strobing(pending)?
}
break;

Precalcs(Misc Output register):

		if (VGA->enable_SVGA==3) //EGA?
{
if (VGA->registers->ExternalRegisters.MISCOUTPUTREGISTER&0x10) //Disable internal video drivers?
{
VGA->precalcs.EGA_DisableInternalVideoDrivers = 1; //Disable it!
}
else //Enable internal video drivers?
{
VGA->precalcs.EGA_DisableInternalVideoDrivers = 0; //Enable it!
}
}

//Update our dipswitches according to the emulated monitor!
//Dipswitch source: https://groups.google.com/d/msg/comp.sys.ibm.pc.classic/O-oivadTYck/kLe4xxf7wDIJ
pattern = 0x6; //Pattern 0110: Enhanced Color - Enhanced Mode, 0110 according to Dosbox's VGA
//Pattern 0001=CGA, Pattern 0010=MDA
if (DAC_Use_BWMonitor(0xFF)) //Are we using a non-color monitor?
{
pattern = 0x2; //Bit 1=Monochrome?, originally 0010 for Monochrome!
}

if (VGA->enable_SVGA==3) //EGA?
{
pattern = 0x6; //Start up as a EGA 80x25 color!
}

//Set the dipswitches themselves!
VGA->registers->switches = pattern; //Set the pattern to use!

- DAC isn't updated(EGA can't change the DAC, since it has no software DAC). Emulated using unchanging VGA DAC entries&DAC mask register.
- Different clocks:

void initVGAclocks(byte extension)
{
if (extension!=3) //VGA clock?
{
VGA_clocks[0] = VGA25MHZ; //25MHZ clock!
VGA_clocks[1] = VGA28MHZ; //28MHZ clock!
}
else //EGA clock?
{
VGA_clocks[0] = MHZ14; //14MHz clock!
VGA_clocks[1] = 16000000.0f; //16MHz clock
}
VGA_clocks[2] = 0.0; //Unused!
VGA_clocks[3] = 0.0; //Unused!
}

- Light pen is added on EGA(called the same as CGA):

void EGA_checklightpen(word currentlocation, byte is_lightpenlocation, byte is_lightpenpressed) //Check the lightpen on the current location!
{
word lightpenlocation;
if (getActiveVGA()->enable_SVGA==3) //EGA is emulated?
{
if (((getActiveVGA()->registers->EGA_lightpenstrobeswitch&3)==1) || (is_lightpenlocation && ((getActiveVGA()->registers->EGA_lightpenstrobeswitch&2)==0))) //Light pen preset and strobing? Are we the light pen location?
{
getActiveVGA()->registers->EGA_lightpenstrobeswitch &= ~1; //Clear the preset: we're not set anymore!
getActiveVGA()->registers->EGA_lightpenstrobeswitch |= 2; //The light pen register is now set!
lightpenlocation = currentlocation; //Load the current location for converting to CGA location!
//Now set our lightpen location!
getActiveVGA()->registers->lightpen_high = ((lightpenlocation>>8)&0xFF); //Our high bits!
getActiveVGA()->registers->lightpen_low = (lightpenlocation&0xFF); //Our low bits!
}
//Always update the CGA lightpen button(live state)!
getActiveVGA()->registers->EGA_lightpenstrobeswitch &= ~4; //Default: clear the pressed switch indicator: we're depressed!
getActiveVGA()->registers->EGA_lightpenstrobeswitch |= ((is_lightpenpressed&1)<<2); //Set if we're switched or not!
}
}

Those are all EGA changes I've made to the VGA emulation(and CRT emulation for video adapters). Essentially it's (like CGA/MDA) a (S)VGA with EGA compatibility software patches strapped on(modifying the base VGA behaviour for EGA). CGA/MDA works in much the same way, but customizes various input/output completely, disabling the VGA entirely and using the common rendering subsystem(VGA_renderer.c) to render it's contents.

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

Reply 13 of 15, by Jepael

User metadata
Rank Oldbie
Rank
Oldbie
vladstamate wrote:
superfury wrote:

Edit: Didn't we have part of this conversation before? IBM EGA and text mode woes

We did, but that was EGA, this is VGA. In CAPE I implement this as two separate pieces of code (mirroring two pieces of HW). Plus the BIOS and underlining HW is different enough. For example I did not expect the VGA to have dipswitches. EGA does yes, but VGA? I have never seen a VGA with switches. But apparently they exist. Hence my questions.

I don't think any VGA-only board has DIP switches.

And PS/2 Model 50 has onboard VGA chipset that has no monitor ID pins, so those are a later invention. It does however have the monitoring of RGB analog voltages. So just R,G,B,HS,VS are connected, and of course GND on few pins, but that schematic has some errors so I don't trust what pins are GND.

Reply 15 of 15, by superfury

User metadata
Rank l33t++
Rank
l33t++

I see one difference at https://github.com/OBattler/86Box/blob/master … video/vid_ega.c :
- port 3C8 returns 2.

That's all I see at a glance.

Edit: After implementing it in UniPCemu, it still doesn't enable VRAM? The misc output register is still cleared? So no output still?

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