SWAPCOM2 for the IBM PCjr SWAPCOM2.COM exchanges the COM1 and COM2 port addresses stored in RAM memory if the PCjr internal modem is not installed. If the internal modem is installed it does nothing except issue a messge. On the IBM PCjr, the RS232 serial port on the back (marked "S") is used for attaching an external modem or a serial printer. This is fixed by hardware to be at port address 2F8. On all members of the IBM PC family, this is the address of COM2 in BIOS, DOS, and BASIC. The internal modem has the port address 3F8 which is COM1 for all members of the PC family. When it is attached, the ROM BIOS places the internal modem's address, 3F8, in memory at address 0000:0400 during boot up. Then, the ROM BIOS places the port address of the RS232 port, 2F8, in memory at the next higher address, 0000:0402. This is documented in the IBM PCjr Technical Reference, page A-4. At this point, everything is right. BIOS, DOS, and BASIC all expect the port addresses of COM1 (3F8) and COM2 (2F8) to be at these two addresses in memory (0000:0400 and 0000:0402) respectively. In other words, the internal modem is both physically and logically COM1; and the RS232 port is both physically and logically COM2. The problem comes when the internal modem is not present. Then, the ROM BIOS places the port address, 2F8, of the RS232 port at memory address 0000:0400 and nothing is entered at 0000:0402. To quote the IBM PCjr Technical Reference, page 2-126, "Without the Internal Modem installed the RS232 serial port is logically addressed as COM1 in BIOS, DOS, and BASIC even though its address is still hex 2F8 using interrupt level 3." This means that if your communications program goes through DOS to send data to an external modem, you must tell it to use COM1. However, if it uses hardware addresses, you must tell it to use COM2. And, if it does both in different parts of the program (as does PROCOMM), not all features of the program will run properly. SWAPCOM2 simply exchanges the port address at 0000:0400 with the one at 0000:0402. Now, the address of the RS232 port, physically COM2 or 2F8, will be at 0000:0402 which is also logically COM2. In short, SWAPCOM2.COM makes the RS232 serial port on the back COM2 both physically and logically. All programs which refer to it as COM2 will run properly. You can see what SWAPCOM2 does very easily. Check with DEBUG the contents of memory starting at address 0000:0400 for 4 bytes. These are the addresses of the COM1 and COM2 ports respectively. Without the internal modem and before SWAPCOM2 is run, these 4 bytes read: F8 02 00 00 This means that logically COM1 (the first two bytes) is at 2F8. But, as noted previously, 2F8 is the COM2 address for all other PCs. SWAPCOM2 exchanges these and puts 02F8 in the third and fourth bytes which are logically COM2: 00 00 F8 02 Now, the RS232 port will be COM2 both logically and physically and will be accessed correctly as COM2 both by hardware addressing and through BIOS, DOS, BASIC, and other programs. If you run SWAPCOM2 again, the values will be back to their original positions. The difference between SWAPCOM2.COM and SWAPCOM.COM is that SWAPCOM2 puts messages on the screen to tell you what has happened and will not do a swap if the internal modem is installed. With the internal modem installed, SWAPCOM2 reports: "PCjr Internal Modem is installed. COM1 and COM2 are set correctly." No exchange of values is made. Without the internal modem, SWAPCOM2 reports on the first execution: "The RS232 serial port S on the rear of the PCjr in now COM2." On the second execution SWAPCOM2 reports: "RS232 serial port returned to power up address." The script file for SWAPCOM2.COM is shown below. The semicolons and what follows are comments and not to be typed in DEBUG. To see the offsets in the program more clearly, use DEBUG and unassemble starting at 0100 and at 01EA. The code ends at offset 0220, and anything you see after that is not part of SWAPCOM2.COM. DEBUG ;Start DEBUG.COM A 100 ;This starts the assembing at offset 0100 for a COM file. JMP 1EA ;Jump over the text data to start of code at offset 01EA. DB " John M. King, San Rafael, CA 11/3/86 $" ;Will NOT be displayed. DB " PCjr Internal Modem is installed. COM1 and COM2 are set correctly.$" ;First message starts at offset 012A. DB " The RS232 serial port S on the rear of the PCjr is now COM2.$" ;Second message starts at offset 0173. DB " RS232 serial port returned to power up address.$" ;Third message starts at offset 01B5. PUSH DS ;01EA Start of code. Save current segment on stack. MOV AX,0040 ;ROM BIOS data on RS232 ports is at 0000:0400 = 0040:0000. MOV DS,AX ;Make this the current data segment. MOV AX,[0000] ;Put the port address at the COM1 logical address in AX. MOV BX,[0002] ;Put the port address at the COM2 logical address in BX. CMP AX,03F8 ;Check if AX is the physical COM1 address, 3F8. JZ 212 ;If so, jump to 0212 to display "PCjr Int..." first message. MOV [0000],BX ;If not, exchange the port addresses. MOV [0002],AX CMP AX,02F8 ;Check if physical COM2 address, 2F8, was originally at ;logical COM1, 0000:0400, address. JZ 20D ;If so, jump to 020D to display "The RS232..." second msg. MOV DX,01B5 ;If not, set up to display "RS232 ser..." third msg at 01B5. JMP 0215 ;Jump to video display at offset 215. MOV DX,0173 ;020D Set up to display "The RS232..." second msg at 0173. JMP 0215 ;Jump to video display at offset 215. MOV DX,012A ;0212 Set up to display "PCjr Int..." first msg at 012A. POP DS ;0215 Start video display. Get program data segment back. XOR AX,AX ;Zero out AX. MOV AH,09 ;Set up for string display with INT 21, Service 9. INT 21 ;Display the string whose starting offset is in DX. XOR AX,AX ;Zero out AX again. INT 21 ;Exit to DOS. INT 21, Service 0 is equivalent to INT 20. ;Hit the enter key to get out of assembly mode in DEBUG. RCX 120 ;Set code register to the length of the program, 120 hex. N SWAPCOM2.COM ;Name the program SWAPCOM2.COM. W ;Write 120 hex bytes, the whole program. Q ;Quit DEBUG. John M. King 11/3/86