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.
| BBC Micro | PC | |||
|---|---|---|---|---|
| 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 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.
Windows™ 95, 98 and Me permit direct access to the hardware ports using the processor's in and out instructions. Although BBC BASIC for Windows has no keywords to perform such access, you can easily achieve it by means of assembly language code. Windows™ NT4, 2000 and XP, however, prohibit direct access to the ports by this means (in so doing they provide better protection against applications crashing the computer) and you must use a special device driver to achieve it. A suitable driver of this kind is supplied with BBC BASIC for Windows (see below).
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. It will not work with Windows™ NT4, 2000 or XP. For those operating systems the method described below (or an equivalent) must be used.
WINIO can be used with all versions of Windows but is of particular value with Windows™ NT4, 2000 and XP because direct hardware port access is prohibited by those versions. Note that you must have administrative privileges to install WINIO on those systems.
BBC BASIC for Windows versions 4.00a and later are supplied with version 2 of WINIO, which is compatible with Windows™ XP. However it seems to be incompatible with Windows™ 95, 98 and Me so the earlier version of WINIO can be found in the BBC BASIC for Windows folder as WINIOV1.DLL and WINIOV1.SYS.
To use WINIO you must incorporate the following code in your BASIC program:
Once this code has been executed, you can read from a port using the following program segment:SYS "LoadLibrary", "WINIO.DLL" TO winio% IF winio% = 0 ERROR 0, "Could not load WINIO" SYS "GetProcAddress", winio%, "InitializeWinIo" TO InitializeWinIo% SYS "GetProcAddress", winio%, "ShutdownWinIo" TO ShutdownWinIo% SYS "GetProcAddress", winio%, "GetPortVal" TO GetPortVal% SYS "GetProcAddress", winio%, "SetPortVal" TO SetPortVal% SYS InitializeWinIo% TO ok% IF (ok% AND 1) = 0 ERROR 0, "Could not initialise WINIO"
The GetPortVal function is passed the port address, a memory location in which to return the data, and the data width of the port in bytes (usually 1).SYS GetPortVal%, address%, ^portdata%, 1
Similarly, you can write to a port using the following program segment:
The SetPortVal function is passed the port address, the data value to be written and the data width of the port in bytes (usually 1).SYS SetPortVal%, address%, portdata%, 1
Once you have finished with WINIO, you should close it down by calling the ShutdownWinIo function:
WINIO.DLL, WINIO.SYS and WINIO.VXD must be in the same directory (folder) as the executable program using them. So when running a BASIC program from the interactive environment they must be in the same directory as BBCWIN.EXE (or BBCWDEM.EXE); this is the normal situation following installation. If using WINIO with a 'compiled' program you must ensure that its files are in the same directory as your executable; this can conveniently be achieved using the embedded files feature of the Compile utility.SYS ShutdownWinIo%
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
|
CONTINUE
|