Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Dual PCI video card joy !

0 views
Skip to first unread message

Dan

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
Well, after much useful advice from some of your good selves, and a
weekend of hair pulling, I managed to get two different (in chipset)
SVGA cards to coexist happily. Below is the method I used; its a bit
less flash than some of the suggestions given, but that's mainly due to
a couple of questions I now have:

i) How do you enable write access to C000h ? I tried OUTing to ports 22h
and 23h (index and data ports of the 82C212, although I gather that I
may not actually have one, or it may be incompatible with others) since
this was the only lead I had. But that didn't work (all reads from 23h
gave 0FFh).
ii) Where is the video cards BIOS image stored before it is copied to
C000h ? I tried copying the first 32K of the framebuffer on the
non-initialised video card (the 'Expansion ROM base address' register
was set to zero on both cards; I just assumed this was an offset in the
framebuffer), having enabled it of course, but that just seemed to be
junk; in fact, on what is now my secondary card, all I got was a string
of 0FFhs again (although that may be because it was very cheap :-)

Other than that, it works fine; all VGA modes are supported on both
cards via the Primary's BIOS, obviously, and that's good enough for me !
(I haven't tried the idea of swapping BIOSes in order to change into
higher modes yet, just getting here was hard enough, so that's an
exercise for another time !)

So, thanks again, and if anyone else wants help with this, just mail
me, and I'll do what I can.

Dan
(to reply by mail, remove the 'removeme.' from my address)

Setting up a secondary video card with a different chipset from the
primary:

i) Only one card will be activated at bootup, so arrange the video cards
so that the intended Secondary is actually the Primary (or just remove
the Primary altogether).
ii) Copy the BIOS from C000h to disk (its length in bytes is given by
the byte at C000:0002 multiplied by 512)
iii) Put the Primary back in its place so that is activated by default
iv) Disable the Primary card's memory access, I/O response and, if
necessary, bus mastering via PCI register 04h, and enable the same
things on the Secondary card (**see below**)
v) Load the BIOS image into DOS memory somewhere and far call the code
at offset 3 (e.g. 9000:0003). With a bit of luck, the BIOS will be
relocatable, and will run happily anywhere in memory (even though my
Primary card had the lines

mov ax,cs
cmp ax,C000h

changing C000 to the correct segment address seemed to work fine; it's
worth stepping through it with a debugger before actually calling it)
vi) Change the PCI configuration back to what it was before, activating
the Primary card
vii) Far call the Primarys BIOS at C000:0003 to reinitialise Int 10 and
other vectors, BDA etc.
viii) Now, just enable whichever card you want to write to (and disable
the other) as above, and access it using A000 & B800 as normal. As
mentioned above, all standard video modes can be initialised on either
card using the Primary's BIOS (unless you're unlucky.....), and the
Primary can still be used for any of the SVGA modes that its BIOS
supports.

(NB: If both cards have the same or similar chipsets, the method is
almost the same, without the need for saving/loading the Secondarys
BIOS; just enable the Secondary, disable the Primary, call C000:0003,
then do the same for the Primary)

(** Note: I'm not sure if it is necessary to disable Bus-Mastering on
the Primary/enable it on the Secondary; this just seemed a reasonable
precaution, and did no harm **)

I would welcome any comments on the validity of the above, and of course
any questions should please be emailed. Note that this is intended to
help those who had no clue where to start, so please excuse the 'idiot's
guide' style :-)


wbinvd

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
Dan wrote in message <36B9D2...@removeme.hotmail.com>...

|i) How do you enable write access to C000h ? I tried OUTing to ports 22h
|and 23h (index and data ports of the 82C212, although I gather that I
|may not actually have one, or it may be incompatible with others) since
|this was the only lead I had. But that didn't work (all reads from 23h
|gave 0FFh).

You'll have to read your chipset manual how to enable write accesses
and other things. If you have an intel chipset, go to http://developer.intel.com/
and download your chipset manual.

If it's an intel chipset, the register name is probably
Programmable Attribute Map Register (PAM), but it could
be called something else.

|ii) Where is the video cards BIOS image stored before it is copied to
|C000h ? I tried copying the first 32K of the framebuffer on the
|non-initialised video card (the 'Expansion ROM base address' register
|was set to zero on both cards; I just assumed this was an offset in the
|framebuffer), having enabled it of course, but that just seemed to be
|junk; in fact, on what is now my secondary card, all I got was a string
|of 0FFhs again (although that may be because it was very cheap :-)

A PCI card's BIOS can only be accessed if both Memory Access Enable
bit is set (PCI command reg, dword offset 1), and the Expansion ROM
Base Address bit 0 is set to 1 (Enable ROM).

You'd use code something like this to enable access to it:

mov edx,Bus device/func + 04h ;04=PCI Command Register
call ReadPCIWord ;PCI COmmand reg is a word
mov SavedPCICmdReg,ax ;Save to restore it later when you're done
or al,02h ;Set Memory Access Enable bit
call WritePCIWord ;Update PCI Cmd reg

cli
mov edx,Bus device/func + 30h ;Expansion ROM Base
; Address for PCI type 0 headers
call ReadPCIDword
mov SavedExpROMAddr,eax ;Save it for later
mov eax,0FFFFFFFEh ;Expansion ROM is disabled; bit 0 is cleared
call WritePCIDword
call ReadPCIDword
test eax,eax
jz NoROM ;Shouldn't happen for you
and ax,0F800h ;Clear reserved bits
not eax
;EAX=Expansion ROM alignment you must align it to.
;But we're feeling lazy today, so we'll use a predefined address.
mov eax,000C0000h
;C0000h might conflict with your normal RAM if you don't disable
;it through the chipset. It works on my chipset, though.

;To initialize a PCI ROM, you MUST copy it to RAM and
;you must pass the bus and device it's installed in in AX.
;AH should be the bus number, AL=Device/Func.

;Copy it to RAM now (Enable Write access to C0000 (NOT READ)),
;and do the copy. Then enable Read/Write access to C0000h

mov ax,C000
mov es,ax
mov cx,size of image/4
xor si,si
xor di,di
rep movs dword ptr es:[di],es:[si]

;Enable read/write access to C0000 now.

mov edx,bus dev/func + 30h ;Expansion ROM for type 0 PCI headers
xor eax,eax ;Disable ROM (Bit 0 = cleared)
call WritePCIDword

mov ax,bus dev/func ;AH=Bus,AL=Dev/func
pushad
call C000:0003 ;Initialize it
popad

;Write protect C0000 now.
;Restore the register now if needed (PCI cmd reg)

NOTE: A PCI expansion ROM should be able to be run ANYWHERE
(at least in the low MB for PC's), so it doesn't matter
if you copy the BIOS code to 8000:0000, or even 2000:0000.

NOTE2: It's perfectly legal for a PCI device to resize its
memory (to smaller). If it did, you'll have to recalculate
its checksum (probably not needed, only if you write a BIOS).


wbinvd

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
|NOTE: A PCI expansion ROM should be able to be run ANYWHERE
|(at least in the low MB for PC's), so it doesn't matter
|if you copy the BIOS code to 8000:0000, or even 2000:0000.

What I really meant was, each PCI ROM when copied to RAM
can have any segment (1234:0000, 5678:0000, etc)

0 new messages