First post, by dartfrog
A place for me to post about my card and driver development without spamming other's threads. I have recently made a huge win. Real data from a PicoGus on Windows 10!
---
For those unaware, I've been working on a weird but promising setup: using an IT8888 PCI-to-ISA bridge behind an IT8893 PCIe-to-PCI bridge, under Windows 10, with the goal of eventually supporting ISA DMA / DDMA-style access for things like PicoGUS. Specifically my goal is to support old CNC ISA cards, which is a much bigger task than something like a GUS.
The hardware topology currently looks like this:
Lenovo ThinkCentre M93p / Intel i7-4790 / Chipset Intel Q87Intel PCIe Root Port-> ITE IT8893 PCIe-to-PCI bridge (on motherboard)-> ITE IT8888 PCI-to-ISA bridge (my PCI-ISA card)-> ISA slot-> PicoGUS / ISA POST card
The IT8888 is detected by Windows as a PCI device. I wrote a KMDF diagnostic driver and a user-mode tool, "it8888ctl.exe", to poke at PCI config space, IT8888 config registers, port I/O, DDMA registers, traces, and a DMA common buffer.
At first, the IT8888 itself looked alive: PCI config reads worked, the device started, and I could program its positive decode windows. For example, the IT8888 was configured with classic legacy-style I/O decode windows:
cfg58 = e4000220 ; SB-ish 0x220 windowcfg5c = e3000330 ; MPU/GUS-ish 0x330 windowcfg60 = e2000388 ; OPL 0x388 window
But actual ISA I/O reads from "0x220", "0x330", and "0x388" all returned "0xFF". At first I thought maybe the IT8888 was not initialized correctly, or maybe the ISA device was not responding.
The real issue turned out to be upstream bridge forwarding.
I added a "pci-dumpcfg" command to dump arbitrary PCI config space by bus/device/function. That showed the IT8893 bridge and the Intel root port both had their I/O forwarding windows effectively disabled/inverted:
I/O base = 0xf0/f1I/O limit = 0x00/0x01decoded as base 0xf000, limit 0x0fff
So even though the IT8888 was configured to decode "0x220", the upstream PCIe/PCI bridge chain was not forwarding those low I/O cycles to it.
I then added raw CF8/CFC PCI config access to the driver, because Windows/HAL config writes were failing for the bridge registers. With that, I could manually open the bridge I/O windows.
For example, opening both bridges to forward "0x8000–0x8FFF" now works:
bridge-iowin 0:28.3 0x8000-0x8fffcommand old=0x0404 new=0x0405io base new=0x80io limit new=0x80bridge-iowin 3:0.0 0x8000-0x8fffcommand old=0x0407 new=0x0407io base new=0x80io limit new=0x80
"pci-dumpcfg" then confirms:
I/O window decoded: 0x00008000-0x00008fffcontains 0x8390: YES
I tried two approaches after that.
First, I tried mapping legacy ISA ports into the high forwarded window:
0x220 -> 0x82200x330 -> 0x83300x388 -> 0x8788
The IT8888 accepted these high decode values:
cfg58 = e4008220cfg5c = e3008330cfg60 = e2008788
Port I/O to those addresses now reaches the driver and is forwarded by the bridges, but plain reads from an ISA POST card naturally just return "0xFF" because a POST card mostly cares about writes to port "0x80".
I also tried opening the bridge windows to "0x0000–0x0FFF" for true legacy I/O. That technically works, but it is dangerous and started causing hangs after some commands. That makes sense: forwarding the whole low legacy I/O page through a PCI bridge can collide with chipset/PIC/PIT/DMA/ACPI/VGA legacy regions. So I am avoiding that except for very short controlled tests.
The big breakthrough was with PicoGUS.
PicoGUS has its own management/control protocol at:
control: 0x1D0data low: 0x1D1data high: 0x1D2
So I mapped that into the safe high bridge window: IT8888 cfg60 = e20081d0
Then I opened both upstream bridges to "0x8000–0x8FFF" and talked to PicoGUS at "0x81D0–0x81D2".
This worked.
Protocol read:
out 0x81D0 <- 0xCCout 0x81D0 <- 0x01in 0x81D2 -> 0x03
Firmware string read:
out 0x81D0 <- 0xCCout 0x81D0 <- 0x02in 0x81D2 -> 0x70in 0x81D2 -> 0x69in 0x81D2 -> 0x63in 0x81D2 -> 0x6fin 0x81D2 -> 0x67in 0x81D2 -> 0x75in 0x81D2 -> 0x73in 0x81D2 -> 0x2d
Which decodes to:
picogus-
This text is actually from the PicoGUS, specifically it's part of the "picogus-gus vX.X.X" text where X.X.X is the version number. pgusinit tells you this text and version number when it detects a PicoGUS. The fact we can see this in Win10 is a major step. After 2 years of messing about, I finally got provable real data from an ISA card on Windows 10 on a modern-ish PC (4th gen chipset Q87).
So the full path is proven:
Windows 10 kernel driver-> Intel PCIe root port-> IT8893 PCIe-to-PCI bridge-> IT8888 PCI-to-ISA bridge-> ISA bus-> PicoGUS
This is a pretty big milestone. It means the card is reachable through the bridge chain if the bridge I/O windows and IT8888 decode windows are configured carefully.
Current lessons learned:
The IT8888 was not the only problem.The upstream IT8893/root-port I/O forwarding windows matter.Windows does not necessarily allocate/enable legacy I/O forwarding for this bridge chain.Raw PCI config writes via CF8/CFC were needed to force bridge I/O windows open.Forwarding 0x0000–0x0FFF is risky and can hang the system.A safer strategy is forwarding 0x8000–0x8FFF and mapping IT8888 decode windows into that range.PicoGUS management/control protocol works through a high alias, proven by reading the firmware string.
The next step is to add proper PicoGUS helper commands to "it8888ctl", instead of manually doing byte pokes. Something like:
pgus-protocolpgus-fwstringpgus-read <cmd> <count>pgus-write8 <cmd> <value>pgus-write16 <cmd> <value>pgus-get-sbpgus-set-sb 0x220 irq dma type
After that, the next milestone is configuring PicoGUS into SB mode and testing SB DSP reset through an aliased SB window:
IT8888 cfg58 = e4008220 ; SB aliasIT8888 cfg5c = e3008330 ; MPU aliasIT8888 cfg60 = e2008788 ; OPL alias
Then test:
out 0x8226 <- 1out 0x8226 <- 0in 0x822Ein 0x822A
The hoped-for result is the classic SB reset response:
0x822A -> 0xAA
There is still a lot left, like supporting real CNC ISA cards, especially real DMA/DDMA behavior. But at this point I have proven that real ISA hardware behind a PCIe-to-PCI-to-ISA chain can be reached from Windows 10, as long as the bridge and IT8888 decode windows are configured manually.
All my hardware, code, docs, and tests are in the repo in my signature, and specifically for this thread, the folder contains the code and driver in "DartFrogTek/PCIe-PCI-ISA/DFT_VMDA8/it8888vdma_win10_predosbox"
What i'm currently working on:
Stop manually poking bytes and add real it8888ctl PicoGUS helpers, including real DMA/DDMA work.
---
Below is a section to talk about why im doing this on Win10, there is method to the madness.
wrote:I'm doing this under Windows 10 first because it is the harshest and most useful test environment for this project. […]
I'm doing this under Windows 10 first because it is the harshest and most useful test environment for this project.
In DOS or Windows 9x, software can usually hit legacy ISA I/O ports directly and the system firmware/chipset may already have some legacy behavior enabled. That makes it easier to get a sound card or POST card to respond, but it also hides which part of the bridge chain is actually working.
Windows 10 is much stricter. It does not automatically make this PCIe -> PCI -> ISA chain behave like a real 1990s ISA bus. The OS did not give the upstream bridges useful legacy I/O forwarding windows, and normal low ISA ports like `0x220`, `0x330`, and `0x388` were not forwarded to the IT8888 at all. I had to prove and manually configure each layer:
PCI config access worksIT8893/root port I/O forwarding worksIT8888 positive decode workskernel port I/O reaches the bridgereal ISA hardware respondsThat is why Windows 10 is useful here: if I can make the chain work from a modern protected OS with manually configured bridge windows, then I have proven the actual hardware path is functional instead of relying on BIOS magic.
It also makes DOS and older Windows easier to reason about later. Once the correct IT8893 bridge window and IT8888 decode settings are known, I can reproduce those settings from a DOS tool, Windows 9x VxD/WDM driver, or even an option-ROM/init utility. The working Windows 10 driver gives me a known-good register recipe.
So this is not "Windows 10 because I expect Win10 to be the final ISA gaming environment." It is more like a diagnostic proving ground. If PicoGUS answers through this chain on Windows 10, then the same bridge/decode configuration should be portable to DOS or older Windows, where the software stack is actually more compatible with ISA sound hardware.
The current PicoGUS result is exactly that kind of proof:
Windows 10 driver-> manually opens root port + IT8893 I/O window-> programs IT8888 decode window-> performs port I/O-> PicoGUS returns firmware string bytes: "picogus-"That means the electrical and bridge path is real. The next job is packaging the same initialization into a cleaner tool/driver so DOS, Win9x, or other older environments can set the bridges up before using the ISA device normally.
---
A small section about possible address-translation fallback via FPGA incase some legacy ISA devices require the IT8888 or ISA bus to see the original low addresses exactly, an FPGA could translate the address phase of PCI transactions:
wrote:One possible fallback is a small FPGA/CPLD interposer that performs address translation on the PCI side before the IT8888 sees t […]
One possible fallback is a small FPGA/CPLD interposer that performs address translation on the PCI side before the IT8888 sees the cycle.
The current software approach is to keep the upstream bridges forwarding a safe high I/O window, such as:
0x8000–0x8FFFand then program the IT8888 to decode high aliases like:
0x81D0 for PicoGUS control0x8220 for Sound Blaster0x8330 for MPU-4010x8788 for OPLThis already works for PicoGUS control access, so an FPGA is not needed for that part. However, if some legacy ISA devices require the IT8888 or ISA bus to see the original low addresses exactly, an FPGA could translate the address phase of PCI transactions:
0x8220 -> 0x02200x8330 -> 0x03300x8788 -> 0x0388while leaving data phases unchanged.
That would let the host and upstream bridges use a safe high I/O window, while the IT8888/ISA side sees traditional legacy addresses. This is not the first choice because modifying PCI address/data lines in real time is timing-sensitive and should be done with proper glue logic, not a microcontroller bit-bang hack. A small CPLD/FPGA would be the right tool if it becomes necessary.
For now, the better result is that PicoGUS has already responded through a pure software-configured high alias. The FPGA idea remains a fallback only if certain ISA devices cannot tolerate high-address aliasing or if real SB/DMA behavior requires exact low-address presentation.
Potential PCIe-to-PCI-to-ISA pathway repository: https://github.com/DartFrogTek/PCIe-PCI-ISA