VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

How does the VGA respond to the following I/O addresses (used by it's predecessors)?

Ports (hex):
03B8
03D8
0094
46E8

Also, is something supposed to happen when the following ports are written/read:
0063
0213

How should my x86 (atm 80(1)86) emulator respond to I/O to/from these ports? Should they be ignored?

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

Reply 1 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

Port 0x63 is the PPI mode register. Port 0x94 is the PS/2 Programmable Option Select system board enable/setup register. Port 0x213 is the IBM 5161 expansion unit enable/disable register. These can all be found in Ralf Brown's Interrupt List.

I'm not sure about how the VGA responds to the other ports, but I do now have an original 1987 IBM VGA card in my XT. If you write a testcase I'll run it on that machine for you and send you the output.

Reply 2 of 21, by Scali

User metadata
Rank l33t
Rank
l33t

3Bx-range is for monochrome adapters (MDA/Hercules), where 3Dx-range is for colour adapters.
So normally VGA will not respond to 3Bx-ports.

http://scalibq.wordpress.com/just-keeping-it- … ro-programming/

Reply 3 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

Actually that's a good point - VGA can coexist with MDA (if a colour monitor is connected) or with CGA (if a mono monitor is connected) which means that it almost certainly doesn't respond to either port 0x3d8, 0x3b8 or 0x3d9. Whether it responds to 0x3d4/0x3d5 or 0x3b4/0x3b5 depends on bit 0 of port 0x3c2, but there's no point applying the same logic to 0x3d8/0x3b8 since the VGA doesn't actually need those ports for anything.

Reply 4 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

I do know that some SVGA cards generate a NMI when the CGA ports are read/written from/to (CGA mode control etc.). Does the VGA have such an option or generate an NMI in those cases when only a VGA card is installed?

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

Reply 5 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

I do know that some SVGA cards generate a NMI when the CGA ports are read/written from/to (CGA mode control etc.). Does the VGA have such an option or generate an NMI in those cases when only a VGA card is installed?

I'll take a look at my VGA card this weekend and see what interrupt lines are connected up. However, I'm almost certain the IBM VGA doesn't generate any NMIs. For one thing, that behavior does not seem to be in any of the documentation (the only interrupt mentioned is the IRQ2 vertical retrace interrupt).

For another thing, the reason why an SVGA card would generate such NMIs would be in order to emulate a CGA card at register level. The card's BIOS ROM would intercept the NMI, determine the requested mode and then program the corresponding sequences of VGA registers. Trying to implement the same thing in hardware (without NMI) would have been extremely difficult. The IBM VGA card doesn't attempt to emulate CGA at register level and (as previously mentioned) can coexist with CGA so there's no reason to have this functionality.

Reply 6 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

So the NMI is because the CPU can't find any hardware to address when that port is read from/written to without a CGA card installed?

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

Reply 7 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

No, if you write to a port and no device is listening to that address, nothing happens. If you read from a port and no device is present, you get 0x00, 0xff or the last value read/written, depending on the machine.

The NMI is generated by the SVGA card, not the CPU or bus hardware.

Reply 8 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

What happens when multiple devices are listening to the same I/O port? Like port 0x61 (partly the Bus hardware (various bits with invalid parity and check enable, bits 2-7) and partly the PIT&PC Speaker(bits 0-1)).
Are the bits supported filled and the rest always 0 or are the bits given filled and the rest junk or 1s? Can those bits be fetched from different hardware listening to that port? Are the results essentially OR'ed or AND'ed when read?

So when one device gives 11110000b and another device gives 00001111b, does the CPU get 11111111b or 00000000b? Or does only the last device give the result (either device 0 or 1)?

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

Reply 9 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

What happens when multiple devices are listening to the same I/O port?

Writing to devices at once on the same port will generally work fine (both devices will receive the same data). Reading from two devices at the same port is likely to give results ranging from "works fine" to "hardware destruction" (if one device is trying to drive the bus high and one is trying to drive the bus low, resulting in a large flow of current).

superfury wrote:

Like port 0x61 (partly the Bus hardware (various bits with invalid parity and check enable, bits 2-7) and partly the PIT&PC Speaker(bits 0-1)).

They're actually the same device (the 8255 Programmable Peripheral Interface at ports 0x60-0x63). The PIT is separate (at ports 0x40-0x43).

Reply 10 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

My current emulation writes the outgoing I/O (ASM OUT instruction or emulator handler doing the same, e.g. INT 10h handler) to all hardware devices. The hardware itself (VGA, PIC, PIT, DMA, Adlib, Debugger(See Bochs E9 Hack, but with some extras added for control of the emulator using a special output command read/written to port E9&EA), 8042 chip, CMOS, FDC, UART) processes the outgoing byte and gives 1 when processed or 0 when ignored(not processed because it's not listening to the I/O port). The same happens during reads, which give a result (the data read from the I/O port) and status (1 when processed or 0 when ignored).

My current error handling mechanism simply gives all values from the hardware OR'ed with each other for devices giving a 1 (processed) during reads. When no hardware is found (nothing is listening to the I/O port) during reads or writes, the error handling mechanism invokes an emulated (so for the currently emulated CPU) NMI when possible (not already an NMI running, see behaviour of IRET during NMI). When it launches an NMI it sets bit in I/O port 0x61 according to the thing that went wrong:
Bit 6 (value 0x40) is set when a Bus error has occurred. Currently only I/O port instructions (IN, OUT, INS and OUTS instructions) with nothing listening to them triggers this bit set and executes an NMI interrupt.
Bit 7 (value 0x80) is set when a Memory access error has occurred. Currently only the MMU triggers this bit with an NMI executed when it notices that memory is written to that doesn't exist (e.g. writing or reading to/from an address above 1MB memory with only 1MB memory or less emulated).

Is this behaviour correct?

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

Reply 11 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

I think if you NMI on non-existent addresses (IO or memory) you'll run into problems with software that tries to automatically detect which hardware devices are present (by writing to them and seeing if they respond).

On the PC/XT the NMI mechanism is mainly used for memory parity error (bit 7 of port 0x62 for motherboard RAM and bit 6 for expansion board RAM). However, you won't get a parity error for unmapped addresses (only if your expansion board or motherboard is misconfigured to say there's RAM at a particular location but the physical chips aren't present).

The other thing I've heard NMIs being used for is debugging cards - if you're debugging and manage to lock up the machine with interrupts disabled, you can press a button on your debugging card and get an NMI which causes the machine to enter a monitor program from which you can regain control.

I think most emulators don't bother with NMIs at all since there is so little software which depends on them working properly, and neither buggy RAM nor hard crashes are such a problem for emulators.

Reply 12 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie

Oh, the parity status bits are on port 0x62 on PC/XT and port 0x61 on AT - the AT doesn't have a PPI but uses some other chips to implement the corresponding functionality.

Reply 13 of 21, by Harekiet

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Yeah I doubt anyone would bother to emulate those ppi error bits and nmis unless you want to emulate faulty memory
I think like you said some svga devices could use an nmi to help the bios code emulate certain other videocard. I thought the GUS could also use it for emulating adlib/sblaster

Reply 15 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

So my VGA should generate a Bus error NMI when any MDA/CGA/EGA-specific I/O ports,which don't exist on a VGA, are read/written from/to?

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

Reply 16 of 21, by reenigne

User metadata
Rank Oldbie
Rank
Oldbie
superfury wrote:

So my VGA should generate a Bus error NMI when any MDA/CGA/EGA-specific I/O ports,which don't exist on a VGA, are read/written from/to?

Only if you're emulating the kind of card that does that (and has the ROM code to intercept that NMI and turn it into the equivalent VGA register writes). Otherwise you'll get bus errors when running any CGA programs that access CGA registers directly (e.g. Digger or 8088 MPH).

Reply 17 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

Does the IBM VGA BIOS use this? Afaik compatibility is at the BIOS level, so the IBM VGA BIOS uses the NMI? Can anyone verify that?

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

Reply 18 of 21, by Harekiet

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Nah the original vga didn't use NMI. This was only later with more advanced SVGA cards and bored engineers. Original VGA was only CGA compatible through the bios calls and the memory layout was more or less the same.

Reply 19 of 21, by superfury

User metadata
Rank l33t++
Rank
l33t++

Should I include it as an option to be enabled (disabled by default) in my emulator? So the user of my emulator can enable the VGA NMI on precursor register access, which don't exist in my VGA? This will be in the advanced menu of course, since normal users won't know when to use it, together with the other misc. options? Currently ports 3B8, 3D8 and 3D9 generate a NMI when enabled. Is this correct?

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