[translation corrected by Gallu - big thx]
3dfx Velocity 100 AGP part#2 [25-years old bug in the system] part#1.
info:
* as it turns out that my velocity does not always work as it should, that's because in some of the older games it has a serious chaffing on the screen, the problem was described and reported on vogons by our lukas12p, it related to malfunctioning games nfs2se and carmagedon2. I also experienced this problem with unreal gold, it worked in glide mode but there was no fog.... for nfs3 it worked ok - strange
* this prompted me to look into the problem, my first focus was unreal, because I had it, after poking around the internet the problem with the lack of fog was solved by adding this entry to the registry:
{
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Class\Display\xxxx\Glide
key: FX_GLIDE_NUM_TMU
value: 2
} string type key, xxxx can be different, depending on how many graphics cards were installed earlier, normally 0000, in my case it was 0018 but it's a test setup for different configurations, you know 😉
* it solved the problem with unreal, but it did not help completely with the 2 previous games
* I only had nfs2se, so I started digging around in sdk glide, I fired up IDA and disassembled the nfs2se exe, I found where the init fog table is, I deactivated it in the new exe, the test went to v2 because there the fog works properly, and indeed it is deactivated, the game looks bit worse but works ok, then I swapped v2 for velocity and.... game fired up without fog but works ok, ugly chaff disappeared 😀
* comparing screenshots of fog on/off it seemed to me that the z-buffer for fog is inverted, because in the background/away the image was ok with textures but crap on close objects, I concluded that fog is "inverted"
* I also checked v3 2000 16MB and the problem was not there - very strange
* I did some tests on diagnostics files for 3dfx, for glide2 crap with fog, but for glide3 it was ok - that was even stranger, because after all they are the same cards
* carving, notes from a chat with a buddy, to whom I reported live the progress of work 😉
{
* i have made many attempts to reverse the loop that generates values for fogtable maps but that had made small differences and improvements, that wasn't it
* in the meantime I made a lot of inline patches, there was a problem with free space in the exe code, I finally fixed it with hiew by using call/jmp, because I did not want to build a whole new environment for the debugger, masm compiler, then recompile and glue exe 😉
* at this point I speculated that the bug must be in the gpu after all, because they implemented the fog arrays in reverse, in the game there are a total of 20 arrays for different cases, each has 64 bytes and contains values in the range 0-ff, there is a function in glide2x.dll that generates this, it is used when you need to reverse the loop to generate this array in reverse order, only a few bytes are missing for the inline patch 😉
* but on the other hand, maybe I could stick the code to reverse the array itself after its generation, then I don't need to patch glide, just paste it in the game exe... such a reverse-order function after the execution of the original procedure, hmmm
* another situation: I have invented an algo for inverting index values from the range 0-63, why should I f* with inverting items, when I can change the main function for calculating values 😉 just for any given 0-63 'do not' and then add 64, perfectly reverses the value, for this I need 15 bytes free, because there is align16 in the exe, I should fit 😀
* and again: i added a patch in glide2x.dll to generate fog table in api and it partially improved, bugs in gpu at 100%
* and the disappoinment: I slowly started to give up on this 'fog' in nfs2, a lot of testing and it f* doesn't work, a little improvement but I wasted my time, it's easier to turn it off and it works perfectly 😉 I think I'll give up coding today and listen to music on my headphones 😀
* I finally found a legitimate carmagedon2 installer, I managed to fix the exe by turning off the fog and it finally looked normal
* in carma2 i tried to invert fog tables, negate indexes but it didn't help much, it must be a bug in early versions of gpu, right after them voodoo3 2000 16mb came out and they worked ok
* I searched the internet, found glide source codes, heavy digging in docs, pdfs, etc...
* and finally: I cracked this 3dfx 😀 the problem is with the card and drivers, the fog works beautifully with nfs2se and carma2 😀
* it wasn't until I downloaded src from glide drivers and rummaged through this crap that I found the place, they had huge problems because of this bug and fixed it wrong, it could have contributed to the downfall of the company too
* it's 1 byte patch, classic jnz->jmp 😀
}
* in the changelog at the beginning of the code there is a visible mention of problems with the fog table, unfortunately no comments in the code but it is visible where it was applied, below important info about changes in the gglide.c file:
{
124 12/18/97 2:13p Peter
fogTable cataclysm
(...)
186 11/18/98 6:29p Dow
Fixed clear problem on banshee/avenger
187 11/24/98 4:21p Jeske
make sure we don't try to apply the banshee (rev<3) fogTable hack to avengers with (rev<3)
}
* as you can see the problem appeared in december 1997 (when the shit hit the fan) and they didn't fix it until a year later in november 1998, unfortunately this fix is bad, because it "spoils" all avengers with revision lower than 3, i.e. for example my velocity 100/v3 1000 8MB and v2 2000 8MB from lukas12p - he even described the problem on vogons but 0 help, a difficult topic 😉
* it can't be ruled out that in banshee chips and early avengers there was a bug in the gpu that required inverting registers from fog and hence these additional conditions, but a quarter of a century has passed and finally it can be corrected 😉
* the list of vulnerable cards is as follows: deviceID=3 and devRev <3, if the card had a bug in the gpu, it will work ok, but if it did not, it will be a chaff with fog on the screen, the bug applies only to games using native glide2x, it is not present in glide3x.dll and that is why nfs3 works ok, the bug also does not apply to all sorts of wrappers like d3d, opengl, nglide etc. - deviceID not quite like that, i will explain later
* crafted glide2x.dll from Amigamerlin v2.9 package, 1 byte classic jnz->jmp patch and.... after dropping it into the directory with the game nfs2se beautiful fog and everything works ok 😀 same with carmagedon2, it is great but there was a dilemma in the analysis because... WHY did my card which has deviceID=5 jump to the code which is intended only for deviceID=3??? - a real brainfu*k
* it made me realize that the error must be somewhere else, even deeper - so, we need to go deeper
* since the critical value is in the condition (gc->bInfo->pciInfo.deviceID == 0x3) I searched all the files from the sources for the string 'pciInfo.deviceID', I found several, the most interesting one is minihwc.c with the following lines:
{
if (hInfo.boardInfo[monitor].h3Mem == 8 ) {
hInfo.boardInfo[monitor].pciInfo.deviceID = SST_DEVICE_ID_H3 ;
}
}
* well I can't believe that someone could write it like that, just a quick verification of the constant SST_DEVICE_ID_H3 and... bingo 😀
{
#define SST_DEVICE_ID_SST1 1
#define SST_DEVICE_ID_SST96 2
#define SST_DEVICE_ID_H3 3
#define SST_DEVICE_ID_H4 4
#define SST_DEVICE_ID_H4_OEM 5
#define SST_DEVICE_ID_AP 6
#define SST_DEVICE_ID_L_AP 6
#define SST_DEVICE_ID_AP_OEM 9
#define SST_DEVICE_ID_H_AP 15
}
* this is where the original error lies, it's in the minihwc.c file inside the hwcInit() function without any checking what card is inserted, the gpu is determined only by the size of the memory, what size? 8MB 😀 so that... if a card with 8MB of vram is inserted, the function will rigidly change the deviceID of the card to SST_DEVICE_ID_H3, that is 3, that is banshee...
* this is a serious bug, because all v3 cards with this amount of memory are susceptible to this regardless of the card ID, and that's why my velocity had the deviceID swapped from 5 to 3 and triggered register inversions from fogtable, this also explains why the v3 2000 lukasa12p works badly - it has 8MB too, f* me 😉
* summarizing this error in 1 line: if vmem 8MB then deviceID=3 and any card becomes voodoo banshee 😀 well, I can't believe how such code can be written 😉
* the only thing left is to disable this nonsense initiation and patch glide2x.dll - I still can't believe what I am seeing 😉
* the patch involves changing the byte under offset 140BF: 75->eb, this will force an unconditional jump to the next instruction with the omission of replacing the card's deviceID
* glide2x.dll patched, tests with nfe2se and carma2 passed, beautiful fog, unreal gold added, because earlier it had a hiccup with operation and did not always start in glide mode and... now beautifully works from the get go, it is the right fog 😀 complete success
* you can now permanently replace this dll in %systemdir% and enjoy trouble-free operation of 8MB vram cards with glide2, this patch may solve problems with other untested games, please comment
* at this time I am curious how this situation affects banshee, unfortunately my card has a burnt gpu and I have no way to check it
* and all owners of v3 cards with 8MB of vram please check the original drivers amigamerlin v2.9 + corrected glide2x.dll, pay attention to the fog or rather lack of it or the havoc it makes on the screen 😉
* used re techniques and static analysis + tools: ida, hiew, totalcmd
it finally works 😀 after 25 years 😀
* hopefully this was NOT the nail in the coffin for 3dfx (but it could have contributed just like the acquisition of stb and sinking $141M + the release of gf256 with t&l by nvidia) - it's a serious flaw and it's clear they didn't patch it, well, we'll probably never know
* inception ended on level 3, 1: fogtable off, 2: fogtable on and disable inversion of values in fogtable registers, 3: fogtable on and disable card swap to banshee if vram 8MB - today I'll end the day with a beer, more than one for sure 😉
* and a final riddle: why do I use the word inversion and not negation, what is the difference in asm between neg and not instructions - this was 1 of the interview questions that candidates for threat analysts position were asked at our company 😉
web:
* lukas12p problem (nfs2se, carma2): 3dfx Voodoo 3 8MB problem
* OpenRift problem (rune gold): Rune Gold: Grey Models in Glide Mode
* Ozzuneoj problem (descent 3, nfs high stakes): 3dfx Velocity 100 (Gateway OEM Voodoo3 1000G) graphics corruption in Glide?
edit:
* added 2 links with problematic cards