VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been looking at the XGA documentation's 16-bit monitor ID documentation and tried to implement it's behaviour into my own emulation's bit reporting (really nibble-reporting, but the nibble in this case is precalculated (the A,B,C,D ones in the documentation).

Basically, I've used the following function to calculate the nibbles to send for each subsequent documented timestamp (the A, B, C, D nibbles):

void VGA_encodeDisplayIDpacket(VGA_Type *VGA, word data) //Encodes a display ID packet for use.
{
byte bit;
word result;
VGA->precalcs.hasExtendedIDbits = 1; //Has extended ID bits!
//Now, go and encode the packet into the four chunks to report.
result = 0; //Init the result!
//bit 0 of the result comes from packet 0, bit 1 from packet 1 etc.
//id0 delivers nibble 0, id1 delivers nibble 1 etc.
for (bit=0;bit<0x10;++bit) //process all bits.
{
SETBITS(result, (((bit&3)<<2)|(bit>>2)), 1, GETBIT(data, bit));
}
VGA->precalcs.extendedIDbits = result; //Set the resulting packets!
}

The SETBITS and getbits use almost the same syntax:
SETBITS(x,shift,mask,val)
GETBIT(x,bitnr)

shift in this case is the same as bitnr on the other function. mask is fixed to 1 to write 1-bit values into the resulting variable.
The basics of SETBITS is like x=(x&(~mask<<shift))|((val&mask)<<shift)
And getbit is the same way roughly ((x>>bitnr)&1) . It just assumes a bitmask of 1.

Is this behaviour correct to build the nibbles for the specified monitor ID? The order of the resulting nibbles is basically the same as A,B,C,D (literally indexed in that way, including the inversion (3-x) performed when the counter is applied to the current nybble number to obtain 3(D),2,1,0(A) from the lookup table's 0(A),1,2,3(D)). And the resulting bits (for example bitnumber modulo 0) is the ID pin to put it at (ID0,1,2,3).

Is this behaviour correct?

I've based this on the IBM XGA documenation page 3-215.

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

Reply 1 of 1, by superfury

User metadata
Rank l33t++
Rank
l33t++

After some more experimenting with my VGA emulation, I've managed to get the emulation driving the VGA's emulated ID pins to give the result as the XGA documentation says it should be read. Basically, it works like this now:
- Whenever the sequencer is reset (one of the first register's two LSb bits set), the connected monitor starts timing. Changing horizontal or vertical retrace polarity also resets this timing. Clearing both bits stops the timers and makes it report the normal VGA-documented pins again (which are a 4-bit value always, based on the known grounded pins (indicating a color or monochrome monitor).
- When the timer counts 15 microseconds worth of clocks, it looks at the retrace polarities and replaces the output of the ID pins with one of the four bit sets documented to be one of the four bits of each nibble based on it (for example bits 0,4,8,12 of the 16-bit identification value).

The polarities of the misc output register are used for this, combined with the sequencer register 0's lower 2 bits (whose setting enables the logic).

I've made a simple pascal readout program that follows the protocol mentioned in the XGA documentation:
- First, set bit 0 of sequencer register 0
- Second, set bit 1 of said register.
- Then, for each of the 4 bit values to read (into variable A,B,C,D):
-- Set the misc output register's top 2 bits to drive the retrace lines for the set of pins to read out. Although officially on a XGA-specific register (some register 50h I think), the misc output register should deliver the same signals during reset?
-- Wait 15 uSec. (Actually 1 mSec due to pascal timing limitations)
-- Write just the ID bitnumbers of the bits to retrieve to the misc output register's clock select bits and read the result bit from the input status #0 register.
-- Store the result into variables A,B,C,D respectively after each pins read (each with the above delay and retrace polarity changes)
- When all four are read, restore the registers.
- Pop the top bit off A,B,C,D with A containing the MSb of the nibble and D the LSb.
- Repeat the popping for the entire 16-bit value.
- Display the read nibbles from the monitor and the decoded 16-bit value.

It seems to run fine from what I can see.

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