VOGONS


First post, by cosam

User metadata
Rank Newbie
Rank
Newbie

This card turned up on that well-know auction site whilst looking for parts for a 486 build. As I could find very little about it online, I thought I’d post my discoveries here. Maybe folks here have more information or other insights.

The attachment et4w32vlbus.jpg is no longer available

That delightfully skewed and off-center heatsink covers a Tseng ET4000 chip, which is what I was looking for. Externally there’s not much in the way of identifying features:

FCC-ID: KAZET4W32VLBUS
Googling this will get you a couple of links to auctions for the same card, at least one of which doesn’t have the heatsink so my guess is this was an after-market addition. So obviously the gist of the product code part is ET4 for ET4000, W32 and VESA Local Bus but searching FCC records for this particular ID returned nothing. I did find some similar ones with the same KAZ prefix, also video cards as it turns out:

Trident Computer Inc, Taiwan  KAZET4TCISABUS   12/23/1992
Trident Computer Inc, Taiwan KAZTCI1DWISABUS 12/14/1992

We probably all recognise the name Trident as the manufacturer of those el-cheapo VGA cards but that’s Trident Microsystems (Santa Clara, CA) and their cards sport FCC grantee code HNG. AFAICT Trident Computer (Taiwan, FCC grantee code: KAZ) has nothing to do with that particular outfit and the name’s either just a coincidence or a shrewd attempt to benefit from the other Trident’s (in)famous reputation.

On the solder side: "ET4W32L1"
Google returned absolutely nothing on this, it might just refer to nothing more than something like "Model ET4W32, PCB Layer 1".

COLORImage® BIOS
Plenty of cards have these and COLORImage appears to be used as a brand name by many. There are records of an expired trademark belonging to Personal Computer Products, Inc. but this postdates the card by a few years.

Dumping the BIOS (I feel I should upload this somewhere but I’m not sure where) revealed the following strings:

Copyright(c)1988 Tseng Laboratories, Inc. 08/23/93 V8.06N
TsengLabs ET4000/W32i VGA Card (VL-Bus) Date : 08/23/93
ColorView

So that was confirmation that it was a W32i, which was before not obvious due to the heatsink. That "ColorView" was registered as a trademark by Trident Computer so that checks out. I guess COLORImage was used similarly but doesn’t have the paper trail.

The card came with 1MB of VRAM as pictured: 8 x AAA1M304P-05, which are 50ns 128K x 8 FPM DRAMs. Those empty sockets where just beckoning to be populated so I looked for more of the same. Surprisingly hard to find compared to the slower varieties, but the Tseng datasheet suggests 50ns for interleaved setups and I wanted to stay on the safe side. Online parts brokers wanted $5 per chip but I managed to find the even faster 45ns chips (deceptively named AAA1M304P-45) for significantly less. Older DOS diagnostics didn’t recognise the extra VRAM but Windows 95 reported the 2MB right off the bat, no jumper changes required.

Speaking of jumpers, there are three and having no information on what they do, I beeped them out. JP1 and JP2 both go to that PAL next to the jumpers so short of popping that out and reverse engineering it (might be a nice rainy-day project some time...) I can only speculate. Experimentation on my DX2 66 suggests they’re something to do with wait states or similar. JP3 is easier; it connects the ET4000 and a pull-up to ISA pin B-04 (IRQ 2).

JP1: 1-2 prevents the machine from booting, 2-3 everything works fine.
JP2: 1-2 gives a marginally better Superscape score than 2-3, so wait states?
JP3: IRQ enable/disable

Anyway, hopefully this post will turn up turn up for others searching for details on this card in the future.

Reply 1 of 17, by elianda

User metadata
Rank l33t
Rank
l33t

Looks similar like my card from Cardex: http://retronn.de/imports/hwgal/hw_et4000_w32i_vlb.html

It is one of the faster ones, however with 0 WS it won't run with much more than 33 MHz VLB. I tried several cards on my Nexgen with 42 MHz VLB and some S3 VLB card cope better with higher frequencies at 0 WS. The card does not have a base 1 WS like the Cirrus Logic cards, which leaves more 'chances' for a fast setup.

Retronn.de - Vintage Hardware Gallery, Drivers, Guides, Videos. Now with file search
Youtube Channel
FTP Server - Driver Archive and more
DVI2PCIe alignment and 2D image quality measurement tool

Reply 2 of 17, by cosam

User metadata
Rank Newbie
Rank
Newbie

I think I stumbled upon your site, actually that page, looking for more info on mine. I'm running this at 33 MHz and still wrapping my head around the wait states, looks like I can't get any lower than 2.

This afternoon I finally traced out the PAL and popped it into my "logic analyzer" 😁

The attachment breadboard.jpg is no longer available

Some of it's used to do address decoding for the BIOS at 0xC0000. The rest takes the jumper settings and VLB ID2 (wait states) and ID3 (bus speed) as inputs and produces signals for the ET4000, including WAT<1:0> which set wait states. So the jumper settings turn out to be:

JP1    JP2    Memory WS    I/O WS
2+3 2+3 4 4
2+3 1+2 3 3
1+2 2+3 2 4
1+2 1+2 1* 3

* = zero WS

Reply 3 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++
cosam wrote on 2020-03-15, 15:42:
I think I stumbled upon your site, actually that page, looking for more info on mine. I'm running this at 33 MHz and still wrapp […]
Show full quote

I think I stumbled upon your site, actually that page, looking for more info on mine. I'm running this at 33 MHz and still wrapping my head around the wait states, looks like I can't get any lower than 2.

This afternoon I finally traced out the PAL and popped it into my "logic analyzer" 😁

The attachment breadboard.jpg is no longer available

Some of it's used to do address decoding for the BIOS at 0xC0000. The rest takes the jumper settings and VLB ID2 (wait states) and ID3 (bus speed) as inputs and produces signals for the ET4000, including WAT<1:0> which set wait states. So the jumper settings turn out to be:

JP1    JP2    Memory WS    I/O WS
2+3 2+3 4 4
2+3 1+2 3 3
1+2 2+3 2 4
1+2 1+2 1* 3

* = zero WS

So JP1 adds 2 memory waitstates, if you look to the values in binary:

JP1    JP2    Memory WS    I/O WS
2+3 2+3 3 3
2+3 1+2 2 2
1+2 2+3 1 3
1+2 1+2 0* 2

I'm curious though, what about the memory mapping in register 30h? How does that map in this card?
A21/A20 are directly mapped to A21 and A20. What about the other bits (SEG2, SEG1 and SEG0 on the chip)?

The documentation says:
'Local bus bits 5:0 compare to inputs SEG2, SEG1, SEG0, A<23> and A<22> respectively. If System Linear Mode is disabled, the comparison is ANDed with inputs A<21> and A<20>, which must be low. If System Linear Mode is disabled, A<21> and A<20> are address inputs.

I'm curious how this is wired to the upper address bits. What's relayed on SEG2-SEG0(pin 26,28,38)? They should be at one side (pin 1-40).

Elianda, I can see pin 38 going down to that black block at the bottom, the one closest to the resistor to the left to of that MC74F04N chip?
Pin 26 is at the same place under that black block, but at the bottom.
Pin 28 is the line between those 2 lines.
So those bottom 3 lines to the left of the black block are, from bottom to top, pins 26(SEG2), 28(SEG1), 38(SEG0).
Can you see where those lead to?

Interestingly, on the OP's card, SEG0 doesn't seem to be connected. Pins 26(SEG2) and 28(SEG1) are connected to the little triangle of holes left to the chip. Pin 26(SEG2) is the top one on the image, Pin 28(SEG1) is the right one in said triangle. The remaining pin in said triangle is pin 29 (M(emory)/IO).
It'd be interesting to know where those two 'holes' lead to as well (interestingly, pin 38(SEG0) doesn't seem to be connected, which sound odd).

You also might be able to probe as it were for the actual address translation used in said register by filling the first few bytes of VRAM with some kind of signature, setting the CRTC 30h register to a value (0-31) and checking where in memory (in 4MB base addresses) the data pops up. Of course under MS-DOS or the like (not a protected-mode OS), as you don't want to mess up a protected-mode OS that's using said extended memory addresses.
They must be mapped to address bits 24 or higher at least, so that's at address increments of 16MB at least, maybe more?
Edit: Believing SVGAlib, it's mapped linearly? So that'd be bits 24-29 set in reg 30h, (or bits 22-23 on ISA)?
https://github.com/ryanmcgrath/svgalib-1/blob … rivers/et4000.c

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

Reply 4 of 17, by mkarcher

User metadata
Rank l33t
Rank
l33t

The idea of SEG0 to SEG2 is to offload some of the address decoding to external hardware. The pins SEG0..SEG2 as well as A20..A23 are only used for memory cycles and not for I/O cycles. You can chose between a VGA compatible operation mode (in which the video memory is at A0000..BFFFF) or linear access mode, in which the video memory is mapped at a 4MB region at some higher location in address space.

I have no idea what happens to ROM decoding at C0000..C7FFF in linear addressing mode, so I am ignoring ROM cycles at the moment. In "standard VGA" mode, A0..A19 are used to get a location inside a 1MB area (typically the first MB of memory). A20 and A21 need to be zero in that mode, but you can program whatever you want as requirement for A22, A23, SEG0, SEG1 and SEG2. The boot-up configuration is that the ET4000/W32 chip responds to A22 = 0, A23 = 0, SEG0 = 1, SEG1 = 1 and SEG2 = 1. The video card needs to ensure that you get that pattern whenever the VL bus addresses anything within the first 4MB, but not if any other "relevant" address above 4MB is accessed. "relevant" in this context refers to systems that don't require decoding of all address bits. For example, a lot of early 486 systems only decode up to A25, so the whole address space repeats every 64MB. In a system like that, getting a mirror of the VGA memory at 64MB + A0000 is not relevant. One straightforward way to connect the ET4000 to local bus address lines is to have A22 and A23 connected to the corresponding VL pins (through a buffer chip, due to the multiplexed address/data pins), and send A24, A25 and A26 through a fast inverter (e.g. a 74F04, as indicated in the "Local Bus Special Note" in the data sheet). In that case, the ET4000 chip will respond at the VGA-compatible A0000..BFFFF area and mirrors this access every 128MB (as A27..A31 are ignored). This is most likely how elianda's card is designed. If you want to use linear framebuffer access instead of banked access, you need to reprogram CTRC register 30 to compare the high address bits to a different pattern, so the ET4000 chips responds to a 4MB region that does not overlap with the first MB. In the case of elianda's card, this means you need to program the base address divided by 4MB and the XORred with 0x1C into that register. For example, for an LFB start at 68MB, the division yields 17 (0x11), which is 0x0D after toggling the "top" 3 bits to compensate the effect of the 74F04. The default value of 0x1C in CR30 thus needs to be replaced by 0x0D, and afterwards you can turn on "system linear mode". Do not ever think about turning on system linear mode before moving the windows, because in that case the ET4000 will conflict with system memory in the first 4MB of address space!

This simple design is undesireable if a system cares about more than 128MB of address space. In that case, more address lines need to be decoded for the ET4000 to be able to decide whether it is addressed. A very common way to decode more address lines on graphics cards of that age is a NOR gate. A NOR gate outputs a 1 only if all of its input pins are 0, so a single SEGx input pin of the ET4000 can be used to check multiple address lines for being zero. I see a 74F02 at U17 on the OP card. That chip contains 4 two-input NOR gates. This chip could, for example be used to combine A24 & A25 to SEG0, A26 & A27 to SEG1 and A28 & A29 to SEG2, increasing the usable system address space from 128MB to 1GB. On the other hand, this only works nicely for standard VGA addressing mode, not for system linear mode, because you can not individually program patterns for A28 and A29, but only program the ET4000 to respond when both are zero (default), or when any one or both are one. This would mean programming the comparator to expect SEG2 = 0 would map the linear framebuffer at 256MB (A28=1), at 512MB (A29=1) and at 768MB (A28 = 1 and A29 = 1), so the usable address space of the system drops down from 1GB to 256MB. On the other hand, there is no reason to use A22 and A23 for exactly those address lines. A smarter move would be to sen A22 & A23 into one of the NOR gates for a SEG input, and have the two highest relevant address lines (A28 and A29 in my example) instead sent as A22 / A23 into the ET4000 chip. This allows enabling of a linear framebuffer at some addresses above 768MB only by programming the comparator to expect "A22" and "A23" (which would actually correspond to A28 and A29) to be high.

As you see, the addresses that can be used for linear framebuffer access and how to set up those addresses are dependend on the glue logic between the VL bus and the ET4000 chip. This is one reason why linear framebuffers on VL cards were usually not used by "general purpose" drivers. Those drivers can not know what specific card they are used with, so touching CR30 is not safe with them. svgalib may implement the correct logic for some ET4000/W32 boards, but that logic does not apply to all of them.

Last edited by mkarcher on 2024-09-28, 17:36. Edited 1 time in total.

Reply 6 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

Were there any ET4000/W32i PCI cards using a PCI BAR for linear mode instead? Maybe selecting those missing address bits that way?

So adding a PCI interface like for W32p, but instead of reporting the revision ID in the registers and PCI registers for 2/5/6/7(rev A/B/C/D), report revision ID 03h (W32i)?

Last edited by superfury on 2024-09-29, 03:53. Edited 1 time in total.

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

Reply 7 of 17, by Grzyb

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-09-29, 03:17:

Were there any ET4000/W32i PCI cards using a PCI BAR for linear mode instead? Maybe selecting those missing address bits that way?

AFAIK there was no ET4000/W32i PCI cards - the first Tseng chip with PCI support was W32p.

Kiełbasa smakuje najlepiej, gdy przysmażysz ją laserem!

Reply 8 of 17, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-09-29, 03:17:

Were there any ET4000/W32i PCI cards using a PCI BAR for linear mode instead?

For that to happen, the card needs to implement PCI BARs. The ET4000/W32i neither knows what PCI is, nor what a BAR is. The PCI interface would need to be implemented as glue logic between the PCI connector and the ET4000/W32i chip, basically a kind of limited PCI-to-486-local-bus bridge. This is possible, but comparing the cost of developing your own bridge solution to just buying a W32p chip (which was available when demand for PCI graphcis cards came up) shows the commercial unviability of this approach. So I very much doubt there is any commercial PCI graphics card with a W32i.

Cards built as one-off prototypes by enthusiasts (e.g. as an exercise in FPGA programming) don't count as "commercial cards" for me, but if they would exist, we might already have a VOGONS post about this kind of card.

Reply 9 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2024-09-29, 06:53:
superfury wrote on 2024-09-29, 03:17:

Were there any ET4000/W32i PCI cards using a PCI BAR for linear mode instead?

For that to happen, the card needs to implement PCI BARs. The ET4000/W32i neither knows what PCI is, nor what a BAR is. The PCI interface would need to be implemented as glue logic between the PCI connector and the ET4000/W32i chip, basically a kind of limited PCI-to-486-local-bus bridge. This is possible, but comparing the cost of developing your own bridge solution to just buying a W32p chip (which was available when demand for PCI graphcis cards came up) shows the commercial unviability of this approach. So I very much doubt there is any commercial PCI graphics card with a W32i.

Cards built as one-off prototypes by enthusiasts (e.g. as an exercise in FPGA programming) don't count as "commercial cards" for me, but if they would exist, we might already have a VOGONS post about this kind of card.

In my case it's an x86 emulator, so I can implement it however I'd like with this mode.
If maintaining compatibility with said chip (being in ISA mode), then:
- XOR the reg 30h with 1C for the A22-A26 lines to expect (apparently normal ET4000/W32i behaviour). But it has just 2 inputs in ISA mode (SEGE at bit 1(high for upper or unmapped(1M area), low for lower) and A22 driven directly to bit 0 (A22 on the chip)?). So, the XOR isn't needed?
- Take the PCI BAR A23-A31 for the upper address lines to match (driving SEGE to 1 for match in linear mode, 0 otherwise?).

Then, it would report the card as an ET4000/W32p, but the lower 8 bits of the ID instead of being 2/5/6/7, being 3 (indicating W32i's ID reflected in the CRTCB register with the ID and bit 7 set for PCI mode support (ISA has bits 6/7 clear, VLB has just bit 6 set).

Then, enabling the card's linear mode and setting bit 1 of reg 30h (SEGE?), with bit 0 being A22, the BAR area would drive SEGE high(1) and A22 normally? And for non-linear mode (BAR disabled by clearing and maybe disabling in command register?), drive SEGE=1 when A31-A22 are set and W32i A20-21 high too, all being 0(low) otherwise?

So basically:
- Non-linear mode: clear bits 1-0 of reg 30h and the BAR.
- linear mode: set BAR bits 30-23. Set bit 1 of reg 30h, with bit 0 to A22's value to use.

Would that be correct for such an PCI-ISA interface?

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

Reply 10 of 17, by mkarcher

User metadata
Rank l33t
Rank
l33t
superfury wrote on 2024-09-29, 11:26:

In my case it's an x86 emulator, so I can implement it however I'd like with this mode.

I don't get why you would want to emulate a hypothetical W32i with PCI BARs instead of a W32p. If your emulated system has PCI, just emulate a PCI-connected W32p. Tools like UNIVBE will know how to deal with the linear addressing in PCI mode. If I understand the ET4000 datasheet correctly, the PCI implementation is incomplete in this regard, and while you may set the A24..A31 for the 16MB linear region, the chip does not use the low 6 bits of this register, but the high 6 bits of CR30 instead, and the driver writer should copy the BAR bits into CR30 when enabling system linear mode.

In case you want to emulate a system without a PCI bus, it does not make sense to me to talk about BARs. If you keep emulating a W32p in that case, you can emulate one of the modes with "full" address decoding. These modes have all address lines (A2..A31) connected to the W32p chip, and the linear base can be chosen in CR30 anywhere within the first gigabyte of virtual address space. The W32p does not respond to local bus cycles if either A30 or A31 is high. Of course, a board designer of a W32p local bus graphics card could intentionally miswire the address bits so A29 and A31 are swapped. This would allow the linear region to appear either in the first 512MB, or anywhere in the 512MB above 2G, the latter making sure there will be no conflict with even 1GB of physical RAM. As 1GB physical RAM + VL slots is likely not to be seen in practice, I expect the variant of "A2..A31 lines wired as intended" to be a quite typical design for W32p VL cards.

superfury wrote on 2024-09-29, 11:26:

If maintaining compatibility with said chip (being in ISA mode), then:

If you are going to emulate an W32i in ISA mode, graphics drivers might very well expect to find the LFB in the low 16M, as higher addresses are not available on the ISA bus. The data sheet suggests to connect A23 directly to SEGE, allowing to place the 4MB address window at 0MB (don't do that, obviously), 4MB, 8MB or 12MB. These four possiblities are selected using the low two bits of CR30 (which are not affected by the XOR at all.

Then, it would report the card as an ET4000/W32p, but the lower 8 bits of the ID instead of being 2/5/6/7, being 3 (indicating W32i's ID reflected in the CRTCB register with the ID and bit 7 set for PCI mode support (ISA has bits 6/7 clear, VLB has just bit 6 set).

Oh, I think I start to get what you are thinking about. You may be thinking about an emulated PCI-to-W32i bridge. There are different ways to design something like that. To get the performance benefit of a 32-bit wide host data bus, a hypothetical physical card would definitely use the W32i in local bus mode, not in ISA mode. If I were to design a bridge like that, I'd likely implement a mapping like SEG0..SEG2 being 111 for A24..A31 all being zero (low 16MB), 110 for A24..A31 matching the top 8 bits of the BAR and 000 otherwise. Software could program CR30 to 0x1C for low-1MB VGA compatible mode, use 0x18..0x1B to choose a 4MB window inside the 16MB range selected by the BAR and the card will not respond at all for any other range.

Reply 11 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++
mkarcher wrote on 2024-09-29, 14:27:
I don't get why you would want to emulate a hypothetical W32i with PCI BARs instead of a W32p. If your emulated system has PCI, […]
Show full quote
superfury wrote on 2024-09-29, 11:26:

In my case it's an x86 emulator, so I can implement it however I'd like with this mode.

I don't get why you would want to emulate a hypothetical W32i with PCI BARs instead of a W32p. If your emulated system has PCI, just emulate a PCI-connected W32p. Tools like UNIVBE will know how to deal with the linear addressing in PCI mode. If I understand the ET4000 datasheet correctly, the PCI implementation is incomplete in this regard, and while you may set the A24..A31 for the 16MB linear region, the chip does not use the low 6 bits of this register, but the high 6 bits of CR30 instead, and the driver writer should copy the BAR bits into CR30 when enabling system linear mode.

In case you want to emulate a system without a PCI bus, it does not make sense to me to talk about BARs. If you keep emulating a W32p in that case, you can emulate one of the modes with "full" address decoding. These modes have all address lines (A2..A31) connected to the W32p chip, and the linear base can be chosen in CR30 anywhere within the first gigabyte of virtual address space. The W32p does not respond to local bus cycles if either A30 or A31 is high. Of course, a board designer of a W32p local bus graphics card could intentionally miswire the address bits so A29 and A31 are swapped. This would allow the linear region to appear either in the first 512MB, or anywhere in the 512MB above 2G, the latter making sure there will be no conflict with even 1GB of physical RAM. As 1GB physical RAM + VL slots is likely not to be seen in practice, I expect the variant of "A2..A31 lines wired as intended" to be a quite typical design for W32p VL cards.

superfury wrote on 2024-09-29, 11:26:

If maintaining compatibility with said chip (being in ISA mode), then:

If you are going to emulate an W32i in ISA mode, graphics drivers might very well expect to find the LFB in the low 16M, as higher addresses are not available on the ISA bus. The data sheet suggests to connect A23 directly to SEGE, allowing to place the 4MB address window at 0MB (don't do that, obviously), 4MB, 8MB or 12MB. These four possiblities are selected using the low two bits of CR30 (which are not affected by the XOR at all.

Then, it would report the card as an ET4000/W32p, but the lower 8 bits of the ID instead of being 2/5/6/7, being 3 (indicating W32i's ID reflected in the CRTCB register with the ID and bit 7 set for PCI mode support (ISA has bits 6/7 clear, VLB has just bit 6 set).

Oh, I think I start to get what you are thinking about. You may be thinking about an emulated PCI-to-W32i bridge. There are different ways to design something like that. To get the performance benefit of a 32-bit wide host data bus, a hypothetical physical card would definitely use the W32i in local bus mode, not in ISA mode. If I were to design a bridge like that, I'd likely implement a mapping like SEG0..SEG2 being 111 for A24..A31 all being zero (low 16MB), 110 for A24..A31 matching the top 8 bits of the BAR and 000 otherwise. Software could program CR30 to 0x1C for low-1MB VGA compatible mode, use 0x18..0x1B to choose a 4MB window inside the 16MB range selected by the BAR and the card will not respond at all for any other range.

OK. I adjusted my emulation a bit:
- The values in register now match what you mention on SEG0..SEG2 (it inverts the bits, then checks them if to enable, takes only the low 2 bits for the base address if enabled (if the flipped version has the top 3 bits set to 0 it's legacy, if flipped is 4 then the low 2 bits define the aperture 4MB address, otherwise it's 'disabled' (it will take the same mapping as legacy, as it's split in my emulation). Then, after it's determined the base address, it'll check the PCI BAR's settings. If the BAR is enabled (command register bit 2 is set to enable memory aperture), it'll OR the top 8 bits of BAR0 (the A24-A31 bits) into the base address, creating the actual base address to use (otherwise, it'll leave it alone and in the first 16MB space).
The memory BAR is also implemented to report a size of 24 bits (so a 16MB memory aperture).
The PCI revision field reported is 3 (which should be ET4000/W32i Rev B). The W32i's CRTCB/Sprite control register top bits also are modified to report bus select of Local Bus and bit 7 set to indicate PCI support (reserved in the ET4000/W32i documentation). The CRTCB/Sprite row offset high register (index EC) will report 3h in the top 4 bits (indicating ET4000/W32i rev B).
Based those changed bits off the source code of 86box's ET4000/W32 source code (the CRTCB/Sprite control register (index EFh) having the new ID added instead of the last written value by the CPU now, to indicate VLB support and PCI support(PCI being newly added and the top 4 bits being properly ROM now)).

Edit: And improved the ET4000AX version to use the same PCI linear handling, but using 2 more address bits (instead of using register 30h) from the PCI BAR instead (extending the bits supplies from 8 to 10 bits and decreasing the BAR window to 4MB instead of 16MB (effectively making it drive the low 2 bits itself (bits 22:23 in the BAR) instead of from the CRTC register 30h low bits (bits 1:0))).

The motherboard BIOS at least correctly detects the BAR size and configures it for use.

Don't know of any software that'll use it yet though.

Edit: Tried searching for if such a PCI-to-VLB adapter exists, to use VLB cards on PCI motherboards (rougly in the way I implemented it), but I can find nothing, only the other way around (connect PCI to VLB busses, like you connect ISA to PCI/VLB busses). Nobody ever thought of connecting a VLB card to an PCI-only motherboard, after PCI won the war?

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

Reply 13 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

I've been thinking a bit...
Since on a PCI bus, the ISA 16MB aperture conflicts with stuff like RAM, perhaps reimplement the ET4000(/W32/I) PCI device as a IT8888 device?
https://www.ite.com.tw/en/product/cate2/IT8888

It seems to be a simple PCI-to-ISA bus that can support:
- Substractive decoding: Plain ISA bus at base 0 for both I/O and memory (normal mode). Register 50h bit 0 set for this.
- Register 50h provides what we need:
- Bits 7-6 control palette snooping.
- Bit 0 enables substractive decode (ISA space) when set, positive decode as enabled otherwise(see below).

During positive decode, we can then:
- use 6 I/O spaces of 0-128 bytes(in powers of 2). Probably enough for all ET4000/W32/I register ranges?
- the 4MB aperture anywhere within 4GB memory space(32-bit, A31-14 can be specified for a base address of 16KB-2MB apertures, so you'd need 2 apertures mapped continuously for this to work).

Thus this can possibly be used with the ET4000/W32/I chipsets, using the chip in ISA mode (as documented earlier)? Except it's a direct base address in this case, split into two continuous ranges for the full 4MB coverage?

So:
- SEG0-2 driven 110HLb(4MB) when addressed in 4MB mode, A23 H, A22 L for mapping extended.
- SEG0-2 driven 111xxb when addressed in ISA-compatible mode (normal VRAM window).

Though bits 0-1 of the register 30h would be cleared in all cases, as it's handled by the PCI-to-ISA bus?

Edit: The IO spaces can be used during positive decoding mode, assuming it can be put into the 6 IO spaces.
Luckily it can, but it only barely has enough mappings:
3C2
3C3
3CA
3CC
^ IO space o 16 bytes mapped to 3Cxh

3#4
3#5
3#8
3#A
^ IO space 1(B) and 2(D) 16 bytes mapped to 3B0h and 3D0h.

3C0/1
3CB
3CD
3CE/F
^ IO space 3 16 bytes mapped to 3C0h.

46E8
^ IO space 4 1 byte mapped to 46E8h.

21XA/B
^ IO space 5 2 bytes mapped to 21XAh.

Edit: Found out something. PCI vs ISA accesses (using the remapping functionality of the chip) can't be used to detect if it's using the remapped (e.g. 0/4/8/12MB 4MB area) or legacy ISA (at phyiscal address A0000 for example) area.
So the main card part of the set would need to handle those inputs itself somehow. Probably just as it's implemented right now. So just as a plain ISA card with extended mapping enabled for the 110b case with bits 1:0 specifying the A22-A23 lines to use.
Then to remap the ISA space for A24-A32 you'd need to set the PCI-to-ISA bus to positively decode, setup the IO spaces in any order (required to maintain I/O functionality) and map the ISA spaces for the memory map high using two of the memory BARs (the PCI registers past offset 50h) and set the register 30h of the W32 accordingly. And of course disable them and put the PCI-to-ISA controller into substractive mode when using the ISA memory mapping instead (and update register 30h to 111xxb).

Edit: Since support is provided by a VESA BIOS, perhaps it can be extended with a MS-DOS linear memory wrapper executable? Thus handle AX=4Fxxh calls and return AX=004Fh on success, passing through to the original driver with bit 14 masked off. Then if the call was made with bit 14 set and the call was a success (AX=4F at this point), enable/disable the memory aperture by scanning PCI and updating register 30h accordingly (to, for example map it to physical address C0000000h in linear memory mode)?

Thus (according to https://wiki.osdev.org/VESA_Video_Modes ):
- Use a generic function call to detect where the card is located in PCI space.
- Use a generic function call to set the base address for a previously found card PCI-to-ISA bus.
function 4F01: use the generic call to detect the card. Then passthrough with CX bit 14 cleared. If detected on a PCI-to-ISA bus, update the attribute word bit 7 (linear mode support) at ES:DI to be set, set doubleword ES:DI+28 to C0000000h to the used framebuffer location.
function 4F02: use the generic call to detect the card. If detected on a PCI-to-ISA bus, passthrough with BX bit 14 cleared (setting up the normal mode), otherwise passthrough as-is (legacy support) and return to caller. If AX becomes non-4F, abort. Otherwise, go and check if bit 14 is set or not. If set, set register 30h of the ET4000 chip for the memory block to the address and update the PCI configuration detected to use said address (register 50h bit 0 cleared, bits 6-7 to enable DAC registers and register 58-64 dword BARs to the mentioned sizes and base addresses and dword 70/74 to the used memory blocks (low and high 2MB blocks, memory BARs at 78h and 7Ch set to 0 to disable)). Otherwise, set register 30h to 1Ch and disable the PCI configuration back to ISA mode (setting register 50h bit 0 to return to legacy mode).

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

Reply 14 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

OK. After a whole day of programming got the IT8888G PCI-to-ISA bridge implemented in my emulator (although unused by the VGA still).

I've adjusted one default register value though, in the front-end: the bit that controls substractive (ISA from what I understand) vs additive decoding (PCI from what I understand, supporting remapping) defaults to substractive decoding. The same with the default DAC register handling.

Edit: And moved the Tseng PCI card old PCI emulation hack to be emulated on the new PCI-to-ISA bridge that's added for it alone at the moment. Multiple of such bridges can now be added into the emulation (though it's currently the only device needing it).

Edit: Windows 95 somehow says that the newly implemented ISA bus is having an error? It seems to be correctly put in ISA mode (substractive decoding mode), as it's initialized with that setting for compatiblilty (although the documentation says it's officially in positive decoding mode on powerup?). Won't power-up in positive decoding mode (thus not mapping RAM or IO spaces) cause issues with booting, as the video card is in there?
Mind, I am using the stock Windows 95 PCI to ISA bus driver there. Perhaps I'd need one for the chip itself?

Edit: Hmmm... Perhaps the setting for substractive decoding isn't supposed to handle it this way? Thus it would enter legacy mode (handling 0-16MB addresses) when no I/O BARs (for I/O accesses) or memory BARs (for memory accesses) are specified (the top bits of those registers all cleared)? And the same for substractive mode (since it's a if-nobody-claims-on-the-bus mode apparently)?

Edit: Adjusted the substractive decoding an positive decoding registers as follows:
- Substractive decoding now enables the ISA memory space. It's also adjusted to properly include the final address (address FFFFh/FFFFFFh) in this case, which was a bug.
- Postive decoding checks the positive decoding registers (which now again is the documented default). It's also adjusted so that when no ranges are enabled, it enables legacy mode instead (again 0 though FFFFh(I/O) or FFFFFFh(memory) including).

It's still not clear if the IT8888G (same with the IT8888F version) can disable the I/O or Memory areas by clearing the command register bits? It says it has the low 3 bits set on power-up, but the register documentation mentions that they're R/O? Is that allowed for a PCI-to-ISA bridge?
Edit: Fixed a bug with the IT8888G's subclass properly depending on the ROM ISA spaces and Timing Control register instead of the ISA space register, thus reporting the card's ID correctly.

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

Reply 15 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

With regard to the custom UniVBE executable to adjust to support LFB on ET4000/W32I (or ET4000AX), perhaps this app can be adjusted to support that (like I said earlier):
https://github.com/LowLevelMahn/NoUniVBE

Simply setup the bus by programming register 30h of the ET4000AX or W32I, then update the PCI-to-ISA (IT8888G that has the subsystem vendor ID of 100C(Tseng labs), subsystem device ID 3200h for AX, 3203h for ET4000/W32I), and perform the passthough as documented above in my earlier post?

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

Reply 16 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

Actually, thinking about it, does bits 2-4 even need to be set to a different value than 111b for linear modes? Can't it just remain to 111b and use the low 2 bits to map A22-A23 (when register 36h bit 4 is set)?

Interestingly, the ET4000AX also has support for a 16MB memory map but doesn't specify anything about how it's mapped? Could it be that it's actually mapped using the 3CD Segment Select register low/high 4 bits? Low 4 bits for A20-A23 during writes and the high 4 bits during reads (since it's otherwise 'unused' during such linear mode)? Those are 2x 4 bits that aren't officially defined in that mode (since they only are defined for normal VGA-compatible mode). That would make sense why it isn't documented as such, but the A20-A23 address lines do need to be connected to the chip (they wouldn't make sense to be there otherwise if it wasn't for this)?

CRTC register 36h on ET4000AX:

Bit 4, when set to 1, will define the most significant 4-bits of display memory address lines as directly from the microprocess […]
Show full quote

Bit 4, when set to 1, will define the most significant 4-bits of display memory
address lines as directly from the microprocessor address bus (linear system). Note
also that GDC Indexed Register 6, bits 3 & 2 must be set for 128K byte$ (0,0).

Since the linear system responds to a contiguous 1MB address space, the host
addresses (A<23:20>) should be used to avoid address conflicts with the host.

When set to 0, defines these address lines as derived from the Segment Select
Register (port 3CD).

Would make sense in some way. Simply a combination of the wiring of register 3CD into the top 4 bits, with a switch (this bit 4) to toggle it into a match for 4 higher bits(A20-A23) instead of a replacement(source) on A16-A19.
So basically:
Toggle off:
Internal A16-A19 routed from Segment Select (mapped low or high by R/W pin)
Top A17-A19 matched to be 6 (hardwired), thus matching segment A and B. Maybe routed using some hidden internal register and mask (to select A0(64K)/A*(128K)/B0(32K)/B8(32K))?
Toggle on:
Internal A16-A19 routed from CPU A16-A19
Top A16-A19 matched to be Segment Select low or high (mapped low or high by R/W pin).

It's probably some kind of internal switching pin like used for some of the other support logic (like with the XROM chips).

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

Reply 17 of 17, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just did some research, diving back into the W32i manual, and lo and behold:
6.2.1 ISA bus special note
Strapping SYSW low causes:
- A22-A17 from AT LA22-LA17.
- LA23 needs to be connected to SEGE.
- MEMW/MEMR from AT connector.

And in ISA mode, register 30h bits 1 compares to SEGE(being LA23) and A22(being LA22), when DB11 is grounded during RESET.
Bits 4-2 aren't used in ISA linear mode (ignored according to the register description).
The power-on value of the low 2 bits is 0, so it's map 0 (LA23 cleared and LA22 cleared).
There is no distinction with non-linear mode, since bits 1:0 are effectively cleared to 0 in Segmented mode, thus forcing it to be at LA23-22 being 0?
In linear mode, thus bits 1:0 correspond to LA23-22 directly (mapped there using SEGE and LA22). So the memory is mapped at 4MB indicated by bits 1:0.
So the memory addresses are:
0: 0MB (forced when in Segmented mode (reg 36h bit 4 cleared, this also forces A21-A20 to be also matched for being low, thus being at 0-FFFFFh ISA addressing (low 1MB space)))
1: 4MB
2: 8MB
3: 12MB

Those are the actual ISA base addresses according to the ET4000/W32i documentation.

Looking at Alex's project (https://www.alexandrugroza.ro/microelectronic … r-schematic.png) it's indeed setup to this ISA mode exactly. The SEGE is mapped to A23 there, it's in ISA mode, with DB11 grounded by default (during RESET) and DB14-12 floating to map 21xA to 217A.
So indeed, bits 1/0 mapping to A23/A22 in linear mode and A23-A20 zeroed in segment mode looks to be correct behaviour. The upper SEG2-SEG0 are disconnected, but unused in ISA mode.

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