joncampbell123 / dosbox-x

DOSBox-X fork of the DOSBox project
GNU General Public License v2.0
2.81k stars 383 forks source link

Parallel port base address #2214

Open rderooy opened 3 years ago

rderooy commented 3 years ago

Describe the bug This is meant to be a discussion.

Right now when you enable printer ports in DOSBox-X, the first one is 0x378 then 0x278 and the third gets 0x3bc as defined in src/hardware/parport/parport.cpp

But this seems to be wrong from what I find online.

If 0x3bc exists (as typically found on MDA and Hercules graphics cards) the numbering should be:

If 0x3bc does not exist, the numbering should be:

See also https://en.wikipedia.org/wiki/Parallel_port#IBM_PC_implementation

rderooy commented 3 years ago

@emendelson may have some ideas about this, since he was the one that asked for LPT4-7.

rderooy commented 3 years ago

My thought we be to either start numbering at 0x3BC, or to switch numbering scheme the moment you enable at least three LPT ports.

emendelson commented 3 years ago

@rderooy I don't have any thoughts on this. As far as I know, the port number has no practical effect on applications running under DOSBox-X, but I could be wrong. @Wengier would know more.

For what it's worth, the motherboard LPT1 port on my current (Lenovo ThinkCentre) system is at 0x378, and that's where every other system I've ever had has also placed the port address.

rderooy commented 3 years ago

This is a long time ago, but I have a recollection that on my 486 back in the day, I could select between LPT1 being on 0x3BC or 0x378. For my earlier 8088 and 386 I don't remember what IO port the parallel port used.

I also seem to recollect that to have an Enhanced Parallel port (EPP), it needed to be on 0x378.

But my memory may be failing me ;-)

emendelson commented 3 years ago

The hardware setup in my Lenovo machine lets me choose between 378 and 278 as the parallel port address. I seem to remember those as the choices in my old machines, but I could be imagining it.

rderooy commented 3 years ago

My ThinkCentre here is a little too new to have a parallel port. But for sure, over time the usage of 0x3BC started to decline, such that later machines don't even offer the option for it any longer. But still that does not mean that assigning it to the 3rd parallel port is correct.

joncampbell123 commented 3 years ago

Make it an option, for the first parallel port to exist at 0x3BC.

@rderooy My understanding of enhanced parallel ports is that they have traditional I/O ports at 0x378 and additional I/O ports at 0x778.

emendelson commented 3 years ago

@rderooy - I believe your ThinkCentre has a parallel port header, but it doesn't show up in the setup unless you actually attach a port to the header. My model is a M901t. The port header isn't shown in the hardware maintenance manual, but it's there. It's shown in the hardware maintenance manual for the latest M90t model, however, so it's likely to be in your system also. The part number for the cable and port is 04X2763; for the low-profile version, 04X2764.

rderooy commented 3 years ago

As a test, I enabled 3 printer ports, and ran System Information 8.0. The strange thing was that in addition to finding 3 parallel ports, it now also found 2 serial ports despite the fact that my config has no serial ports defined. Unfortunately SI does not report the IO resources used.

I then tried the same with Win98SE, and the moment I booted with 3 parallel ports enabled, it found new hardware. But not only did it find 3 parallel ports, it also suddenly found 2 serial ports.

In addition, Win98SE is reporting that the 3rd parallel port is not functioning properly (code 24). Screenshot from 2021-01-24 20-50-38

rderooy commented 3 years ago

As a test, I restored my Win98SE HDD image to the previous state. I then changed the io base address order around in src/hardware/parport/parport.cpp such that the order is 3BC,378, 278 and re-compiled.

When starting Win98, it again found new hardware, but this time LPT1 was reported as not working. So for some reason Windows is not happy with the emulated parallel port at 0x3BC.

rderooy commented 3 years ago

@emendelson I checked the bios of my ThinkCentre E93z and there is no mention of either serial or parallel.

But I fired up an old ThinkPad T400 (from 2008), and it does have serial and parallel options in the BIOS (you need the docking station to actually use them, which I don't have).

And when I enable the parallel port option, it defaults to Base I/O address 3BC

On a slightly newer ThinkPad T430 (2012) there is again no mention of serial and parallel options in the BIOS.

emendelson commented 3 years ago

@rderooy Ah - I see: you have one of those all-in-one ThinkCentres. They never had parallel or serial ports. But all the traditional desktop models - tower and small-form-factor - have both. Recent ThinkPads don't have those ports either, but, as you say, older ones do.

rderooy commented 3 years ago

@emendelson the important part, in my mind at least, is that the ThinkPad defaulted to 3BC, which is something I recall was normal on IBM systems. At least those that where actually made by IBM and not just re-branded "commodity" hardware.

joncampbell123 commented 3 years ago

Windows is correct that port 3BCh doesn't work. There's a mismatch in port bitmasking between matching the I/O port and deciding which port you're using.

src/hardware/parport/parport.cpp line 107 (read) and 135 (write).

Note it masks by 0xFFFC for matching base I/O but the switch statement is (port&7). 0x3BC-0x3BF at that point misses the 0-2 cases, 0x3BC-0x3BF maps to +4 to +7.

So even though parport emulation is handling the I/O, it's ignoring it because of the masking mismatch.

Fixing now.

joncampbell123 commented 3 years ago

Try the latest commit. Even as LPT3, Windows 95 is happy with port 3BCh now.

emendelson commented 3 years ago

@rderooy You're right: I have an ancient ThinkPad 760XL. I booted it to Windows NT 4.0, which reports that the parallel port address is 03BC. The "Easy Setup" BIOS program doesn't seem to offer any way to change it, but maybe I've forgotten how to use it. (I have the hardware maintenance manual for it somewhere...)

rderooy commented 3 years ago

@joncampbell123 thanks! Do you know also why when you activate the three parallel ports, it also activates serial?

@emendelson That is what I recall. I actually started with a 750Cs (if you discount the PS/2 Model P70 luggable that I shortly used) and from what I recall there was a key to press to go into the "advanced" mode of the BIOS.

joncampbell123 commented 3 years ago

@rderooy COM1 and COM2 are enabled by default. Whether the parallel ports are enabled or not should not determine if serial ports are enabled.

emendelson commented 3 years ago

@rderooy - I've looked in the Hardware Maintenance Manual for the advanced setup option, but can't find it. There was a program called "ps2" (in DOS) that set advanced options, but I can't check on it because I put the ThinkPad 760Xl back in the closet. Will report when I look at it again.

rderooy commented 3 years ago

@emendelson I can assure you that there is a hidden advanced setup on those ThinkPads with Easy Setup, and I'm not referring to the PS2 dos program. The key combo was not in the HMM from what I recall.

When your in easy setup, try and press CTRL-A. and if that does not work, try other CTRL key combinations.

edit have a look here: https://thinkwiki.de/760#FAQ

translated:

Q: Is it true that there are hidden menus in Easy Setup?
A: Yes, but these are special settings that you shouldn't play with as the risk of wrecking the ThinkPad is quite high. The settings can be reached as follows:
Press Ctrl + D in the "Config" menu: Calls the XCMOS Utility. This can be used to edit the values ​​of certain CMOS registers. Exit with F3.
Press Ctrl + A in the "Test" menu: Displays settings for the so-called loop test. This allows selected hardware components to be tested in an endless loop.
Press Ctrl + E in the "Test" menu (but press Ctrl + A beforehand): Displays a list of errors that have been registered during hardware tests.
In the "Test" menu press Ctrl + K (but press Ctrl + K before) : Interactive test for the keyboard.
emendelson commented 3 years ago

@rderooy - I pulled out the 760XL again, and found the XCMOS utilty and the others in that list, but I can't find any menus for setting the port address of the parallel port (unless that's something you set by hand in the XCMOS utility). I'll ask at Thinkpads.com.

EDIT: Discussion here:

https://forum.thinkpads.com/viewtopic.php?f=6&t=131915&p=854283#p854252

dbjh commented 1 year ago

Apologies for resurrecting an old thread, but an important piece of information is missing. If the parallel port base is mapped to I/O address 0x3BC the ECP registers will not be available, even if the chipset supports ECP. That is, according to Interfacing the Standard Parallel Port (page 15). For example, in order to change the mode of the parallel port the ECP registers need to be available (mapped).

dbjh commented 1 year ago

Windows is correct that port 3BCh doesn't work. There's a mismatch in port bitmasking between matching the I/O port and deciding which port you're using.

src/hardware/parport/parport.cpp line 107 (read) and 135 (write).

Note it masks by 0xFFFC for matching base I/O but the switch statement is (port&7). 0x3BC-0x3BF at that point misses the 0-2 cases, 0x3BC-0x3BF maps to +4 to +7.

So even though parport emulation is handling the I/O, it's ignoring it because of the masking mismatch.

Fixing now. Originally posted by @joncampbell123 in #2214 (comment)

With all due respect, but you did not solve the entire issue, because the analysis is somewhat mistaken.

  1. The problem was simply the incorrect mask in the switch statement (which picked up bit 2 for port values of 0x3bc - 0x3be). Since the switch has cases 0 - 2, the mask should be 3. Arguably more correct would be to replace the switch statement with an if-else statement to avoid dealing with case 3. The current code looks like a complicated way of testing whether the difference between port and one of the known base addresses is less than or equal to 7. It actually is testing whether the difference has a value of which bits 3 - 15 are set. It allows through differences outside that range. If port has a value that is 3 to 7 higher than the nearest known base address it will be allowed through and the switch will happily refer to cases 3 - 7, which don't exist. Not a big deal, but it makes no sense -- the purpose of that code is to call 1 of 3 methods of CParallel, so why act as if there are 8 options to choose from? Similarly for values of port that result in a difference where bit 16 or higher are set. That is worse, because it allows wrap-around. However, that issue was already present in the original code. It could be solved by changing port to a 16-bit type or simpler and more locally by enlarging the mask to cover bits 3 - 31 of a Bitu. Please consider my pull request (https://github.com/joncampbell123/dosbox-x/pull/4105) first ;-)
  2. The original code applied a bitmask of 7 which should have been 3. The way it applied the bitmask 0xfffc had a different meaning than the way your changes apply bit masks, as you described: it ensured that the port address matched bits 2 - 15 of one of the known base addresses (which always have bits 0 - 1 set to 0).

In my pull request I did not consider the log message, and I just applied the simpler fix to the original code.