5

I have been using the following code to get comm port addresses from BIOS in QuickBasic 4.5:

PRINT "Hex addresses for ports 0 to 3 from BIOS."
DEF SEG = 0
FOR x = 0 TO 3
    z = &H400 + x * 2
    p = PEEK(z)
    q = PEEK(z + 1)
    a = q * &H100 + p
   PRINT " COM" + STR$(x); ": " + HEX$(a)
NEXT
DEF SEG

However when I increase FOR x = 0 to 3 into FOR x = 0 to 7 it returns x378 for 4 (which is LPT1) and 5, 6, and 7, return 0 and I need a way to read comm ports 4, 5, 6, and 7.

I know in Control Panel → Device Manager → Ports I can read them from the resources tab, but I want my program to read them. Any help?

3
  • 8
    On a gennuie PC, and that's what BIOS is about there are only 4 COM ports. Any other COM port may not only be on arbitrary addresses (and interrupts) but also use complete different (non 8250) hardware. For clarity you might want to add what a 'QB45' is. Also, what DOS/Windows versions you intend this to run on. – Raffzahn Feb 3 at 8:02
  • 4
    QB45 is almost certainly “QuickBasic 4.5”. I agree that the OP should make this explicit. Note also that this means that the program runs from DOS or from a DOS emulator. – Euro Micelli Feb 3 at 16:50
  • I am assuming: port 4 = 3E0, port 5 = 2E0, port 6 = 338, port 7 = 238 – Azathoth Feb 4 at 6:36
13

Well, this is to be expected; the BIOS Data Area has only four slots for I/O addresses of serial ports, with slots for parallel ports immediately following. In the MEMORY.LST file from Ralf Brown’s, we can find the following entries0:

MEM 0040h:0000h - BASE I/O ADDRESS OF FIRST SERIAL I/O PORT
MEM 0040h:0002h - BASE I/O ADDRESS OF SECOND SERIAL I/O PORT
MEM 0040h:0004h - BASE I/O ADDRESS OF THIRD SERIAL I/O PORT
MEM 0040h:0006h - BASE I/O ADDRESS OF FOURTH SERIAL I/O PORT
MEM 0040h:0008h - BASE I/O ADDRESS OF FIRST PARALLEL I/O PORT
MEM 0040h:000Ah - BASE I/O ADDRESS OF SECOND PARALLEL I/O PORT
MEM 0040h:000Ch - BASE I/O ADDRESS OF THIRD PARALLEL I/O PORT
MEM 0040h:000Eh - BASE I/O ADDRESS OF FOURTH PARALLEL I/O PORT (pre-PS/2)
MEM 0040h:000Eh - SEGMENT OF EXTENDED BIOS DATA SEGMENT (PS/2, newer BIOSes)

If the machine has more serial ports than can fit in the BDA, the base I/O port address will have to be obtained in some other way.1 Or perhaps not at all: it may be possible to access such a port via a DOS driver (by opening a handle to the COM device file and using DOS system calls to interact with it) or interrupt &h14 (though in BASIC that is only possible by calling assembly code, e.g. via CALL ABSOLUTE). Without knowing the specific device which provides the ports, it’s not feasible to say much more, or explain how Windows manages to discover those ports.

However, the question seems to imply that the BASIC program is run in a DOS box under Windows. If that’s the case, it’s worth remembering that DOS boxes are virtualised environments that don’t have direct access to hardware anyway: I/O port traffic is handled by the DOS virtual machine and passed to the appropriate Windows driver, which may map it to a completely different device. This means that the I/O ports available in the DOS box do not have to correspond to the same I/O ports that the host system uses natively. But it also gives us another alternative: one may simply try reassigning the serial port number to a lower one to make it available with the expected device name and I/O address in the DOS box. (I have not actually tried this myself, but I know that the port number can be reassigned for at least some devices.)


0 The listing uses offsets from segment 0040h instead of segment zero, but that’s just different notation for the same physical address. The use of this segment base to access the BIOS Data Area is customary (and beneficial, since for example the keyboard buffer pointers stored in the BDA are relative to this segment base), but not mandatory; it’s just as often that the BDA is accessed via segment zero, for example the VBE version 3 protected-mode interface requires a selector for accessing the BDA as-if via segment zero.

1 And that’s assuming it’s an 8520-compatible UART accessible over the ISA/LPC bus in the first place; say, RS-232 adapters over USB have to be operated in a completely different manner.

5
13

The BIOS list only contains addresses of up to four standard 8250-type COM ports found at boot at the standard addresses.

It will not contain more than four ports, it will not contain any non-8250 type COM ports, and COM ports at non-standard addresses, such as PCIE COM ports, and USB COM ports which don't have an IO address to begin with. It will not contain ports only found by Windows drivers etc.

1
  • It sounds like getting more than 4 comm ports addresses is a NO then. – Azathoth Feb 3 at 23:10
6

The BIOS data area only has room for addresses of four com ports, at 40:00 through 40:07.

More serial ports would be driven by some device driver with some other place to store the address(es) and IRQ(s).

2
  • I am using the X00 device driver for 8 ports. – Azathoth Feb 3 at 23:37
  • 1
    Unless memory serves me extraordinarily badly, x00 only supports 4 ports under DOS. Since you're apparently running Windows, perhaps something like Netfoss or Syncfoss would work better for you? I never had more than a couple of serial ports, so I can't say from direct experience though. I remember Fidonet quite fondly (formerly 1:128/77.3). – Jerry Coffin Feb 3 at 23:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.