Idea still holds, as the sourcecode for freedos is available. So you should modify the code with brendans solutions. Sounds easier than it will be imho.Dex wrote:Thanks os64dev, but i was meaning from a using FreeDos on a real PC, point of view.
VGA Graphics Question [x86]
Author of COBOS
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
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.
Also, PCI is tricky when it comes to VGA cards. All VGA cards I've seen do not report the port and memory range in the BARs. The PCI spec says that that's legal behaviour. The result is that you can not relocate the VGA registers without card-specific code. Summarized, you can operate on only one VGA-mode card at the time. (it seems though that you can use the pci configuration space to prevent one card from listening to any non-config accesses, which would include the vga accesses. I haven't tested it though as all my bioses refuses to keep the onboard video in working condition with a second card in place.)
On another note, you can look for a large memory range in the pci configuration. For all cards I have tested, it corresponds to the LFB, and it works even in vga modes (down with the mode-x plane switching
)
So, just logging writes is likely not enough - you also need timing information, and possibly writes that depend on reads.
Also, PCI is tricky when it comes to VGA cards. All VGA cards I've seen do not report the port and memory range in the BARs. The PCI spec says that that's legal behaviour. The result is that you can not relocate the VGA registers without card-specific code. Summarized, you can operate on only one VGA-mode card at the time. (it seems though that you can use the pci configuration space to prevent one card from listening to any non-config accesses, which would include the vga accesses. I haven't tested it though as all my bioses refuses to keep the onboard video in working condition with a second card in place.)
On another note, you can look for a large memory range in the pci configuration. For all cards I have tested, it corresponds to the LFB, and it works even in vga modes (down with the mode-x plane switching
![Twisted Evil :twisted:](./images/smilies/icon_twisted.gif)
I do not think you need to modify the freedos source code, better to run a app on top of freedos, But i was more thinking of implementing a DexOS ver.os64dev wrote:Idea still holds, as the sourcecode for freedos is available. So you should modify the code with brendans solutions. Sounds easier than it will be imho.Dex wrote:Thanks os64dev, but i was meaning from a using FreeDos on a real PC, point of view.
And i agree with Combuster, reverse engineering is never straight forward, but its still a worthwhile project.
Hi,
![Wink ;)](./images/smilies/icon_wink.gif)
![Sad :(](./images/smilies/icon_sad.gif)
I took a quick look on my development machine using "lspci -v -s 00:02.0":
It looks like everything is there except the legacy display memory mapping at 0x000A0000 and the VGA compatible I/O ports.
I'm guessing there's card-specific code to enable the VGA compatible stuff that's enabled by the video card's ROM initialization code. There is also a "VGA enable" bit in PCI bridges that controls the forwarding of these VGA accesses.
This means we'd only be able to access one video card at a time, and we'd need to prevent all other cards from responding to memory and I/O port accesses. We may also need to mess with PCI bridges to make sure VGA compatible accesses are forwarded to the currently active video card.
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".
Cheers,
Brendan
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...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.
![Wink ;)](./images/smilies/icon_wink.gif)
You're rightCombuster wrote:Also, PCI is tricky when it comes to VGA cards. All VGA cards I've seen do not report the port and memory range in the BARs. The PCI spec says that that's legal behaviour. The result is that you can not relocate the VGA registers without card-specific code. Summarized, you can operate on only one VGA-mode card at the time. (it seems though that you can use the pci configuration space to prevent one card from listening to any non-config accesses, which would include the vga accesses. I haven't tested it though as all my bioses refuses to keep the onboard video in working condition with a second card in place.)
![Sad :(](./images/smilies/icon_sad.gif)
I took a quick look on my development machine using "lspci -v -s 00:02.0":
Code: Select all
00:02.0 VGA compatible controller: ATI Technologies Inc 3D Rage IIC 215IIC [Mach64 GT IIC] (rev 7a) (prog-if 00 [VGA])
Subsystem: Intel Corporation Unknown device 4756
Flags: bus master, stepping, medium devsel, latency 66, IRQ 19
Memory at fa000000 (32-bit, prefetchable) [size=16M]
I/O ports at 1000 [size=256]
Memory at f9000000 (32-bit, non-prefetchable) [size=4K]
[virtual] Expansion ROM at 30040000 [disabled] [size=128K]
Capabilities: [5c] Power Management version 1
I'm guessing there's card-specific code to enable the VGA compatible stuff that's enabled by the video card's ROM initialization code. There is also a "VGA enable" bit in PCI bridges that controls the forwarding of these VGA accesses.
This means we'd only be able to access one video card at a time, and we'd need to prevent all other cards from responding to memory and I/O port accesses. We may also need to mess with PCI bridges to make sure VGA compatible accesses are forwarded to the currently active video card.
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".
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
- Combuster
- Member
- Posts: 9301
- Joined: Wed Oct 18, 2006 3:45 am
- Libera.chat IRC: [com]buster
- Location: On the balcony, where I can actually keep 1½m distance
- Contact:
It seems my braindump was open for multiple interpretationsBrendan wrote:Hi,
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...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.
![Sad :(](./images/smilies/icon_sad.gif)
[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
![Wink :wink:](./images/smilies/icon_wink.gif)
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...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".