VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

When I look at the miscellanious output register, which is set at int10_modes.cpp, it sets bit 5 on always. Shouldn't this bit be cleared always? (When a real VGA gets the bit set, it will redirect all VRAM output to the high planes (plane 2&3 instead of 0&1), which will cause text modes to redirect all text and attributes to planes 2 (character RAM)&3(unused), instead of 0(text RAM)&1(attribute RAM)). Is this correct? I'm using the code within my own emulator, but it seems wrong using the freeVGA documentation as a reference.

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

Reply 1 of 4, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

In most cases the emulated video BIOS behaves similar to real ones. However, if you have doubts, debugger builds of DOSBox have the LDGFXROM command to load and initialize real video BIOS ROM images, and their behavior can be observed. If you find a discrepancy with real video BIOSes, and particularly if it causes some issue with a game, please do report your findings.

Reply 2 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've looked at the FreeVGA docs again:
Sequencer Memory Mode Register bit 5 seems to have the highest priority, forwarding to all planes if set (using the read map during read or the bit mask during write to select the correct plane(s), sequentually accessing it).

When it's set to 0, even addresses map to map 0 and 2, odd addresses map to map 1&3.

I'm still wondering how the Misc Graphics Register, bit 1 affects all this:
When 1: A0 is replaced with a high order bit (Misc Output Register bit 5 ?)
(When 0:) The odd map is selected when A0 is set. When not set, the even map is selected.

So setting it to 1 causes the Misc Output Register to override the function of bit A0? Which is then used in selecting the map to use?

Text modes set:
Misc Graphics Register bit 1=1,
Sequencer Memory Mode bit 2=1,
Misc Output Register bit 5=1.

So this would translate adresses Sequentially using the Read map and map mask only?

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

Reply 3 of 4, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

For text modes, look at VGA_TEXT_PageHandler in vga_memory.cpp to see how DOSBox uses registers in reading and writing video memory -- and I suggest looking at SVN, because there have been changes since 0.74.

Reply 4 of 4, by superfury

User metadata
Rank l33t++
Rank
l33t++

My current code for read and write operations is:

(OPTINLINE is a define which gives __inline or inline depending on the compiler)

//decodeCPUaddress(Write from CPU=1; Read from CPU=0, offset (from VRAM start address), planes to read/write (4-bit mask), offset to read/write within the plane(s)).
OPTINLINE void decodeCPUaddress(byte towrite, uint_32 offset, byte *planes, uint_32 *realoffset)
{
if (ActiveVGA->registers->SequencerRegisters.REGISTERS.SEQUENCERMEMORYMODEREGISTER.Chain4Enable) //Chain 4 mode?
{
*planes = (1 << (offset & 0x3)); //Lower bits, create bitmask!
*realoffset = offset;
*realoffset >>= 2; //Rest of the bits. Multiples of 4 wont get written!
return; //Done!
}
//if (!ActiveVGA->registers->SequencerRegisters.REGISTERS.SEQUENCERMEMORYMODEREGISTER.EnableOE) //Odd/even mode disabled? (According to Dosbox, this value is 0!)
//Sequential mode?
if (!(ActiveVGA->registers->GraphicsRegisters.REGISTERS.GRAPHICSMODEREGISTER.OddEvenMode //Odd/even mode possible?
&& ActiveVGA->registers->GraphicsRegisters.REGISTERS.MISCGRAPHICSREGISTER.EnableOddEvenMode
&& ActiveVGA->registers->SequencerRegisters.REGISTERS.SEQUENCERMEMORYMODEREGISTER.EnableOE
)) //Sequential mode?
{
if (towrite) //Writing access?
{
*planes = 0xF; //Write to all planes possible, map mask register does the rest!
}
else
{
*planes = 1; //Load plane 0!
*planes <<= ActiveVGA->registers->GraphicsRegisters.REGISTERS.READMAPSELECTREGISTER.ReadMapSelect; //Take this plane!
}
*realoffset = offset; //Direct offset into VRAM!
//The offset is used directly!
return; //Done!
}

//Odd/even mode used (compatiblity case)?
*planes = 1; //Default to plane 0!
/*if (ActiveVGA->registers->ExternalRegisters.MISCOUTPUTREGISTER.OE_HighPage
&& ActiveVGA->registers->GraphicsRegisters.REGISTERS.MISCGRAPHICSREGISTER.EnableOddEvenMode
&& (offset & 1)) //Use high page?
{
*planes <<= 2; //Shift to the high planes!
}*/
/*if (offset & 1) //High plane selected?
{
*planes <<= 1; //Take the high plane!
}
*realoffset = offset;
*realoffset &= ~1; //Calculate the correct offset within the VRAM! Bit 0 is cleared: we address even bytes only!
*/

//Do the same as VPC!
register byte calcplanes;
calcplanes = offset;
calcplanes &= 1; //Take 1 bit to determine the plane (0/1)!
calcplanes = (1 << calcplanes); //The plane calculated (0/1)!
calcplanes |= (calcplanes << 2); //Add the high plane for destination!
offset &= 0xFFFE; //Take the offset within the plane!
*planes = calcplanes; //Load the planes to address!
*realoffset = offset; //Load the offset to address!
}

The input is:
towrite: 1 on CPU writes, 0 on CPU reads.
offset: The offset from the start of the VRAM window (0xA0000, 0xB0000, 0xB8000, so B80001 can become 1, 0x80001 or 180001 with the 128K aperture).

The result is:
planes: The planes to read/write (bitmask, bit0=plane 0, bit1=plane1, bit2=plane2, bit3=plane3)
realoffset: The offset to read/write within the plane(s).

Anyone can tell me if this is (in)correct? If incorrect, what's wrong? How is this fixed?

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