Most PCs have either one or two serial ports, called COM1 and (if present) COM2. However it is possible to have additional ports (COM3, COM4 etc.) if required for special purposes. BBC BASIC for Windows can access these extra ports if they have a suitable Windows™ driver.
Serial ports can only be accessed by one application at a time, so if a port is currently in use by another program, BBC BASIC will not be able to open it (the OPENUP function will return the value zero).
The fields within the string have the following meanings:port% = OPENUP("COM1: baud=9600 parity=N data=8 stop=1")
Optionally you can include the following parameters if supported by your PC:
Parameter Meaning baud Sets the baud rate (speed) of the port to the specified value. Permitted values are 75, 110, 150, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400 and 115200. parity Enables or disables parity generation and checking. Permitted values are N (signifying no parity), E (signifying even parity) and O (signifying odd parity). data Sets the number of data bits in each transmitted character. Permitted values are 7 and 8. stop Sets the number of stop bits. Permitted values are 1 and 2.
You can also use a shorthand form of the string, where the parameter values are simply separated by commas:
Parameter Meaning xon Enables or disables XON/XOFF (software) flow-control. Permitted values are on and off. odsr Enables or disables output flow-control using the Data Set Ready (DSR) input. Permitted values are on and off. octs Enables or disables output flow-control using the Clear To Send (CTS) input. Permitted values are on and off. dtr Controls the Data Terminal Ready (DTR) output. Permitted values are on, off and hs (handshake). rts Controls the Request To Send output (RTS). Permitted values are on, off, hs (handshake) and tg (toggle). idsr Contols the DSR sensitivity. Permitted values are on and off.
If the open operation succeeds, OPENUP will return a non-zero channel number. Up to four ports may be open simultaneously, with channel numbers 1, 2, 3 and 4. If the open operation fails (for example because the port is already in use) OPENUP will return zero.port% = OPENUP("COM1: 9600,N,8,1")
To avoid your program 'hanging up' while waiting for data on a serial port, you can use the EXT# function to discover how many characters (if any) are waiting to be read. If you read only that number of characters you can guarantee that your program will never be waiting a long time for data to arrive:
port% = OPENUP("COM1: baud=9600 parity=N data=8 stop=1") IF port% = 0 PRINT "Could not open COM1" : END REPEAT chars% = EXT#port% IF chars% <> 0 THEN FOR count% = 1 TO chars% data% = BGET#port% REM. Do something with the data NEXT ENDIF REM. Do something useful here UNTIL FALSE
The EOF# function and the PTR# pseudo-variable are not meaningful in the case of a serial port, and if used will result in the Invalid channel error.
|DIN Plug||D25 Socket||D9 Socket|
|pin A||<———>||pin 2||pin 3||Data from PC to BBC Micro|
|pin B||<———>||pin 3||pin 2||Data from BBC Micro to PC|
|pin C||<———>||pin 7||pin 5||Signal ground|
|pin D||\ Connect|
|pin E||/ together|
|Connect /||pin 4||pin 7||Request to send (output from PC)|
|together \||pin 5||pin 8||Clear to send (input to PC)|
|Connect /||pin 6||pin 6||Data set ready (input to PC)|
||||pin 8||pin 1||Carrier detect (input to PC)|
|together \||pin 20||pin 4||Data terminal ready (output from PC)|
If the transfer fails, carry out the following checks:
Data files which are read entirely using BGET# or GET$# will not need conversion. However, files which are read using INPUT# or READ# must be converted using the FCONVERT utility supplied (it can be found in the EXAMPLES\TOOLS directory).
Data files read with a mixture of BGET# (or GET$#) and INPUT# (or READ#) are a nuisance. It may be possible to convert them, but you will get a number of 'Bad data' errors reported and you may confuse the FCONVERT utility. If this happens, you will need to write your own data conversion program and in order to do this you will need to know the structure of the data file and the way data is stored by the Acorn version of BBC BASIC.
Unlike the serial ports, no parameters need to be specified. Normally you can only write to a parallel port, although you may be able to read from a bi-directional port in some circumstances.port% = OPENUP("LPT1:")
Most PCs have just one parallel port, called LPT1. Parallel ports can only be accessed by one application at a time, so if a port is currently in use by another program, BBC BASIC will not be able to open it (the OPENUP function will return the value zero).
If a printer is already installed on the specified port, attempting to open the port may fail (depending on the operating system version and printer driver in use). In that case you should write to the printer using the normal methods, i.e. using VDU 2 etc.
You should copy the file inpout32.dll from the downloaded ZIP file (probably in the Win32 subdirectory) to your BBC BASIC for Windows library folder (usually C:\Program Files\BBC BASIC for Windows\LIB\). Under Windows Vista™, Windows 7™, Windows 8/8.1™ or Windows 10/11™ you will need administrator privileges to do that.
To use InpOut32 incorporate the following code in your BASIC program:
Once this code has been executed, you can read from an input port using the following statement:SYS "LoadLibrary", @lib$+"inpout32.dll" TO inpout32% IF inpout32% = 0 ERROR 100, "Cannot load inpout32.dll" SYS "GetProcAddress", inpout32%, "Inp32" TO `Inp32` SYS "GetProcAddress", inpout32%, "Out32" TO `Out32`
Similarly, you can write to an output port using the following statement:SYS `Inp32`, portaddress% TO portdata%
SYS `Out32`, portaddress%, portdata%
If using InpOut32 with a 'compiled' BASIC program you must ensure that inpout32.dll is available; this can conveniently be achieved using the following Compiler Directive:
When InpOut32 is used on Windows Vista™, Windows 7™, Windows 8/8.1™ or Windows 10/11™ BBC BASIC for Windows (or your compiled program) must be run in administrator mode. One way of doing that is to right-click on the desktop icon and select 'Run as administrator'. If you want to avoid the inconvenience of doing that, the InpOut32 ZIP file contains the utility InstallDriver.exe; instructions for using it are in the file ReadMe.txt.REM!Embed @lib$+"inpout32.dll"
Once this code has been executed, you can read from a port using the following program segment:DIM P% 6 [OPT 0 .inport in al,dx : movzx eax,al : ret .outport out dx,al : ret : ]
The static variable D% is first loaded with the port address (this gets copied into the processor's edx register), then the data is read from the port using the USR function.D% = address% data% = USR(inport)
Similarly, you can write to a port using the following program segment:
Here D% is loaded with the port address and A% is loaded with the data value (they get copied into the processor's edx and eax registers respectively) and the actual port write is performed using the CALL statement.D% = address% A% = data% CALL outport
Note that, as stated previously, this method will only work with Windows™ 95, 98 and Me.
When not used for these purposes, the modem control and status signals are available for user I/O. The only special feature to note is that the voltage levels on these lines (generally) correspond to the RS232 specification, that is they swing from a negative voltage (in the range −5 Volts to −12 Volts) to a positive voltage (+5 Volts to +12 Volts).
The signals available for this use, and the corresponding pins on the serial port connectors, are as follows:
Name Direction D25 socket D9 socket RTS output pin 4 pin 7 CTS input pin 5 pin 8 DSR input pin 6 pin 6 CD input pin 8 pin 1 DTR output pin 20 pin 4 RI input pin 22 pin 9 GND ground pin 7 pin 5
com% = OPENUP("COM1:9600,N,8,1") IF com% = 0 ERROR 0,"Could not open serial port" REM. Set RTS: SYS "EscapeCommFunction", @hfile%(com%), 3 REM. Clear RTS: SYS "EscapeCommFunction", @hfile%(com%), 4 REM. Set DTR: SYS "EscapeCommFunction", @hfile%(com%), 5 REM. Clear DTR: SYS "EscapeCommFunction", @hfile%(com%), 6 CLOSE #com%
The variable modemstatus% will contain a value corresponding to the states of the inputs as follows (the values may be combined):com% = OPENUP("COM1:9600,N,8,1") IF com% = 0 ERROR 0,"Could not open serial port" SYS "GetCommModemStatus", @hfile%(com%), ^modemstatus% CLOSE #com%
CTS 16 DSR 32 RI 64 CD 128