VOGONS


First post, by TimmermanV

User metadata
Rank Newbie
Rank
Newbie

I just finished and released TweakPCI, which is a utility to view and optionally modify PCI configuration registers. It can be used to tweak settings that are not accessible otherwise. (Of course, you'll need a technical reference of your device to know what you're doing) I thought it might be of interest to someone on this forum.
Code and executable release are here: https://github.com/TimmermanV/TweakPCI

Some time ago I wrote something similar in assembler to be able to configure the chipset on my 486. The BIOS didn't recognise the CPU in put in and used default safe/slow settings for the RAM etc. (See topic Hp Vectra VE 4/100 to 5x86 133mhz but slow mem performance) While my previous utility was usabale only to configure the SIS 496/497 chipset, TweakPCI can be used for any PCI device, as long as you know the device and vendor identifiers.

I used Open Watcom 1.9 and I wrote it in C. While working on it I wanted the application to be a real-mode program. (Adding DOS4/GW or some other extender would make the executable needlessly larger and slower to start) However, I didn't find any way to use int386 in a real-mode program. I ended up writing my own alternative to this function in assembler. (using Watcom's pragma aux) If anyone knows of a way to use Watcom's int386 in a real-mode program, I'd love to hear it. 😀

While working on TweakPCI, I found a similar program by Uwe Sieber: PCISET.

Reply 1 of 14, by Revolter

User metadata
Rank Member
Rank
Member

Thanks! It works perfectly fine in DOS 6.22 (both real and protected modes) for the purposes of driverless ESS Solo-1 operation and configuration, and is of the same processing speed as PCISET. Compiled it on the real thing via "open-watcom-c-dos-1.9.exe".

For those with the same usage scenario in mind - here is my batch file (this is what ESSOLO.COM actually does when you run it):

TWEAKPCI.EXE 1969 125D B41 0=00010000
TWEAKPCI.EXE 1969 125D B40 0=01111111
TWEAKPCI.EXE 1969 125D B52 0=00000000
TWEAKPCI.EXE 1969 125D B51 0=00000001
TWEAKPCI.EXE 1969 125D B50 0=00000000
TWEAKPCI.EXE 1969 125D B61 0=00000000
TWEAKPCI.EXE 1969 125D B60 0=00000000
SET BLASTER=A220 I5 D1 T4

Celeron 800, 512MB, GeForce2 MX, ES1938S/DB S2, Windows ME/DOS 6.22

Reply 2 of 14, by mkarcher

User metadata
Rank l33t
Rank
l33t
TimmermanV wrote on 2022-08-06, 13:35:

I used Open Watcom 1.9 and I wrote it in C. While working on it I wanted the application to be a real-mode program. (Adding DOS4/GW or some other extender would make the executable needlessly larger and slower to start) However, I didn't find any way to use int386 in a real-mode program. I ended up writing my own alternative to this function in assembler. (using Watcom's pragma aux) If anyone knows of a way to use Watcom's int386 in a real-mode program, I'd love to hear it. 😀

I recently wrote a similar utility, in a way that it can be compiled using Borland C or Watcom C, and resorted to inline assembly, with hand-coded db 66h prefixes for 32-bit instructions. So, alas, no int386 to be found in there. If you still want to take a look, peek at https://github.com/karcherm/dostools/blob/main/pci.c . That repo also has a "dumpmem" tool that can be used to dump memory from anywhere in the 32-bit address space of 386-like processors into a file.

Reply 3 of 14, by TimmermanV

User metadata
Rank Newbie
Rank
Newbie
Revolter wrote on 2022-08-06, 15:52:

Thanks! It works perfectly fine in DOS 6.22 (both real and protected modes)

Awesome! Thanks for trying it out. You should be able to shorten it even more. Multiple registers can be set using a single command and adjacent registers can be combined. I think you should be able to change all those registers in one go like this: (this is 99 characters long)

TWEAKPCI.EXE 1969 125D W40 0=0001000001111111 D50 0=000000000000000100000000 W60 0=0000000000000000

That does also read/write B53 though. If that has some side effects you could try this: (106 characters)

TWEAKPCI.EXE 1969 125D W40 0=0001000001111111 B52 0=00000000 W50 0=0000000100000000 W60 0=0000000000000000

Do you actually need to set all those bits? If some of them are already correct by default, you may be able to shorten it even more. It also looks like TweakPCI could use another syntax that would allow you to specify the number of bits to set... I'll think about it.

mkarcher wrote on 2022-08-06, 18:42:

I recently wrote a similar utility, in a way that it can be compiled using Borland C or Watcom C, and resorted to inline assembly, with hand-coded db 66h prefixes for 32-bit instructions.

That's pretty cool, tanks for the tip! I considered using inline assembly, but didn't think of using hand coded prefixes. I have some other things I'd like to do first, but I think I'll give your approach a try later.

Reply 4 of 14, by Revolter

User metadata
Rank Member
Rank
Member
TimmermanV wrote on 2022-08-07, 09:00:

Multiple registers can be set using a single command and adjacent registers can be combined. I think you should be able to change all those registers in one go like this:

Cool, thanks for the examples! I noticed it could combine multiple commands in a single run yesterday after posting, and when you showed me how to wrap adjacent registers together I've settled on the following (mainly readability's sake):

TWEAKPCI.EXE 1969 125D B41 0=00010000 B40 0=01111111 B52 0=00000000 B51 0=00000001 B50 0=00000000 W60 0=0000000000000000
TimmermanV wrote on 2022-08-07, 09:00:

Do you actually need to set all those bits? If some of them are already correct by default, you may be able to shorten it even more.

Apparently so: I've tried reducing the line to only include new bits against the power-on defaults, but it doesn't work this way.

Revolter wrote on 2022-08-06, 15:52:

same processing speed as PCISET

I take it back, btw: with all registers processed in one go it is actually noticeably faster on slow enough systems (tested under artificial slowdown conditions via CpuSpd, but still) 😀 I like it even more now over PCISET!

Celeron 800, 512MB, GeForce2 MX, ES1938S/DB S2, Windows ME/DOS 6.22

Reply 5 of 14, by BloodyCactus

User metadata
Rank Oldbie
Rank
Oldbie
TimmermanV wrote on 2022-08-06, 13:35:

I used Open Watcom 1.9 and I wrote it in C. While working on it I wanted the application to be a real-mode program. (Adding DOS4/GW or some other extender would make the executable needlessly larger and slower to start) However, I didn't find any way to use int386 in a real-mode program. I ended up writing my own alternative to this function in assembler. (using Watcom's pragma aux) If anyone knows of a way to use Watcom's int386 in a real-mode program, I'd love to hear it. 😀

not helpful now, but I have one its in;
https://github.com/stu/dos_code/tree/main/e820

it has a cpu.asm that builds with nasm, and you use it like the normal funtion. sere the e820lst for dumping e820 memory blocks on using it.

it also has a detectcpu in the asm so you can double check the user has a 386+ if you need to do it too.

--/\-[ Stu : Bloody Cactus :: [ https://bloodycactus.com :: http://kråketær.com ]-/\--

Reply 6 of 14, by TimmermanV

User metadata
Rank Newbie
Rank
Newbie
BloodyCactus wrote on 2022-08-07, 16:35:

not helpful now, but I have one its in;
https://github.com/stu/dos_code/tree/main/e820

Cool, thanks! I already see I could learn some things from your version. Thanks for sharing. 😀

Reply 8 of 14, by Calvero

User metadata
Rank Member
Rank
Member
TimmermanV wrote on 2022-08-06, 13:35:

I used Open Watcom 1.9 and I wrote it in C. While working on it I wanted the application to be a real-mode program. (Adding DOS4/GW or some other extender would make the executable needlessly larger and slower to start) However, I didn't find any way to use int386 in a real-mode program. I ended up writing my own alternative to this function in assembler. (using Watcom's pragma aux) If anyone knows of a way to use Watcom's int386 in a real-mode program, I'd love to hear it. 😀

I guess you can use int86 instead of int386.

Reply 9 of 14, by TimmermanV

User metadata
Rank Newbie
Rank
Newbie
Calvero wrote on 2022-08-08, 13:06:

I guess you can use int86 instead of int386.

Using int86 will not allow me to use 32-bit registers and I'd like to be able to read/write 32-bit values in my program. Of course I could split those read/write operations and perform two 16-bit read/writes but I didn't like that, as that felt too much as a workaround.

Reply 11 of 14, by digger

User metadata
Rank Oldbie
Rank
Oldbie

Cool! Thanks for sharing this with the world! 😃

Another interesting use case, when combined with the (Free)DOS DEBUG tool in a batch file, would be to have TweakPCI obtain the base I/O address of a parallel or serial port on a PCI or PCIe card and then using DOS DEBUG to register it as an LPTx device in the BIOS Data Area, so as to make such a port accessible to (well-written) DOS programs. I found a closed-source tool that can do the same thing, but being able to do this with open-source software would be even better. 🙂

By the way, are you by any chance aware of the Open Watcom v2 fork? It's seeing daily development and has gained quite a few improvements over Open Watcom 1.9 over the years. It's also still available for DOS.

Reply 12 of 14, by zyzzle

User metadata
Rank Member
Rank
Member

Would love if we could develop so sort of repository for PCI registers on various devices as a kind of ready-reference. This program isn't useful out of the box, as it requires you to "know" which devices and exactly which registers you need to modify. Not a complaint. Could it be used, for example, to overclock PCI V3 cards? What are some common cards which it has the greatest potential to 'unlock' from within DOS?

Reply 13 of 14, by DoZator

User metadata
Rank Member
Rank
Member
zyzzle wrote on 2022-08-13, 07:39:

Would love if we could develop so sort of repository for PCI registers on various devices as a kind of ready-reference. This program isn't useful out of the box, as it requires you to "know" which devices and exactly which registers you need to modify. Not a complaint. Could it be used, for example, to overclock PCI V3 cards? What are some common cards which it has the greatest potential to 'unlock' from within DOS?

I join this wish. A detailed description of which registers should be changed in this or that case would be very wonderful. Today, this issue is becoming increasingly relevant, due to the increasingly unscrupulous attitude of motherboard manufacturers to the implementation of PCI support on motherboards, which is very critical for unsupported legacy devices (Audio\video\network cards and other devices).

Not infrequently, the system BIOS is not as good as it needs to be, and the PCI is not configured properly, so the devices refuse to fully work (Up to Windows freezing). With the help of this utility, it is sometimes possible to fix this by making the necessary settings manually. If, of course, you know what to configure.

Some users share their solutions, but there is still no single WIKI where all this information would be collected together and regularly updated with a description of various problems of PCI devices on various hardware and how to fix them.

Reply 14 of 14, by XPK

User metadata
Rank Newbie
Rank
Newbie

For reference, there is a similar tool from 1997 in the Garbo ftp archive https://ftp.lip6.fr/pub/pc/garbo/pc/sysutil/pci07.zip. It features some descriptions for some of the chipsets of the era. Improperly configured PCI devices are nothing new.