Brendan wrote:Hi,
Combuster wrote:Some worknotes regarding the reverse engineering - I tried writing a Mach64 driver once (there is at least some documentation, but its incomplete), but the card played rather nasty. I tried dumping the registers by loading the bios image into bochs to see if it worked, then modified its sourcecode to log all I/O accesses. What appeared is that the card is apparently timing sensitive. - it would wait for a vertical synchronisation pulse at times. Also, when copying over the access list (including the vsync) the screen went just blank. (instead of one of the two messed up 640x480 modes I managed to get myself, with exactly the same code)
So, just logging writes is likely not enough - you also need timing information, and possibly writes that depend on reads.
You logged the I/O port accessses of a ROM designed for Mach64 *while* it was trying to configure the Cirrus Logic video card emulated by Bochs (that would lack all the "Mach64 specific" extensions), and it worked enough to get messed up 640*480 video modes sometimes? That sounds quite encouraging to me...
It seems my braindump was open for multiple interpretations
I'll try again
[flood]
I hacked together some mach64 driver snippets to see if I could set high resolution modes. There is a decent amount of info in VGADOC on Mach64 cards so at first I hoped it would be straightforward to parse the document, compute some register values then pump them to the card. There was no free lunch - the documentation was off with how to access the mach64 i/o ports. It referred to a ISA mach64, while my 3d rage is a PCI card (AGP even), After a while I figured that registers documented to be in 'memory' actually referred to an I/O range. (its location is given in a BAR). So far so good, I wrote a tool that printed the mach64 registers to the screen. I noticed that some of the mach64 registers are shared with the VGA registers, i.e. if you change one the other is modified accordingly. It also suggested that I wouldn't need to load all the CRT registers before changing video modes. So, I tried enabling the native mode bit, and the screen turned into a garbage of pixels with the expected resolution. To fix the colors, I used some VGA code to enter Mode-X (320x240) to be able to write to all bytes in the framebuffer. After loading a suitable screen contents, I repeated the procedure and got a 640x480 mode (mode X is doublescanned, and the VGA needs two pixel clocks to compute and display 256-color value). However, only the rightmost 256 pixels showed as expected - the rest of the screen were copies of this range towards the left. Trying to set the virtual width VGA register, or the corresponding mach64 had no effect. Looking at the Xorg driver didn't bring any enlightenment.
I tried a different approach. I wrote a bootsector program that set the 640x480x256 I was trying to get, dumped the mach64 registers, then return to text mode to print it. After copying the values I noticed that some bits were set during mode switch that were not documented by VGADOC. I copy-pasted the register dump to my test driver and attempted to load the result into the registers. The result was pretty much the same garbled screen. However, after rebooting with the same code, it occasionally gave a different screen where the columns of pixels were ordered in a different fashion.
I rebooted into win98, and made a dump of the video bios and sent it to my dev pc. I loaded it into bochs to see what it would do, and it produced a working system (I didn't try SVGA calls as those were most likely to fail for being mach64-dependent rather than for the emulated CL card). I modified the bochs sourcecode to report all I/O accesses, and looked at the result, I then changed the source again, this time to return all ones rather than zeroes on unknown reads. the registers accessed and the values written were identical. The ports written were as expected, except for two things: the bios VSynced somewhere in the code, it looped through all vesa banks (probably filling 0xA000:xxxx with zeroes in the meantime as there were a lot of timer interrupts in that part). I copied the register loads, and replaced the vsync accesses with the proper function and tried the mach64 card, which now caused the attached monitor not to display anything at all (it reported a bad signal)
after trying some other things, which at best resulted in the garbled displays mentioned above, I gave up to spend my time on the next kernel generation that wouldn't have the fundamental flaws that made implementing v8086 mode (and several other things) hell.
[/flood]
i.e., your party just got cancelled
The worst part about this is that an OS would need to do the same to support multiple video cards if those video cards are in "VGA compatable mode", and I doubt the "I/O port access logger" would help to get any of the information necessary to make video cards work without "VGA compatability conflicts".
Logging indeed doesn't help solving the vga conflict. However, you can often use the LFB (which is outside VGA space) to write to the screen with a minimal driver. You can then tell the pci system to ignore the vga accesses to that device so you don't need to "hotseat" the cards unless you want to change video modes. It won't work for text mode though...