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.