RTR logo

BBC BASIC for Windows

BBC BASIC for SDL 2.0

VDU Emulation



Introduction to VDU commands

On the BBC Microcomputer and Acorn Archimedes the VDU commands perform a number of important actions, primarily involving the screen display and graphics. Although not strictly part of BASIC, most of these commands have been emulated by BBC BASIC for Windows and BBC BASIC for SDL 2.0.

The VDU statement takes a list of numeric arguments (constants or variables) and sends their least significant bytes as characters to the currently selected output stream.

A 16 bit value (word) can be sent if the value is followed by a semi-colon. It is sent as a pair of characters, the least significant byte first.


VDU code summary

NumberMeaning
0 Null - it does nothing.
1 Send the next character to the printer ONLY.
2 Enable the printer.
3 Disable the printer.
4 Write text at the text cursor position.
5 Write text at the graphics cursor position.
6 Enable output to the screen.
7 Bell - make a short 'beep'.
8 Move the text cursor backwards one character.
9 Move the text cursor forwards one character.
10 Move the text cursor down one line.
11 Move the text cursor up one line.
12 Clear the text area - identical to CLS.
13 Move the text cursor to the start of the current line.
14 Enable the auto-paging mode.
15 Disable the auto-paging mode.
16 Clear the graphics area - identical to CLG.
17 Define a text colour - identical to COLOUR.
18 Define a graphics colour - identical to GCOL.
19 Select a colour palette.
20 Restore the default logical colours.
21 Disable output to the screen.
22 Select the screen mode - identical to MODE.
23 Create user-defined characters and screen modes, etc.
24 Define a graphics viewport.
25 Identical to PLOT.
26 Restore the default text and graphics viewports.
27 Send the next character to the screen.
28 Define a text viewport.
29 Set the graphics origin - identical to ORIGIN.
30 Home the text cursor to the top left of the screen.
31 Move the text cursor - identical to TAB(x,y).
127 Backspace and delete.


VDU 0

Does nothing. In other words, it is ignored.
VDU 0

VDU 1

Provided the printer has been enabled (with VDU 2), the next character (byte) is sent to the printer driver and not to the screen. If the printer is not enabled, the character is discarded. Any 8-bit value (0 to 255) can be sent.

VDU 1 provides a simple way of sending single characters to the printer driver. It works whether the VDU has been disabled with the VDU 21 command or not. For example VDU 1,12 will send a 'form feed' and force the current page to be printed.

Note that you should not attempt to send printer-specific control characters (e.g. for setting the font, style etc.) as this won't work. BBC BASIC uses the Windows™ printer drivers and changes to the font or style must be made with the *PRINTERFONT command.

VDU 1,12

VDU 2

(BBC BASIC for Windows only)
VDU 2 enables the printer. It causes all subsequent text output to be sent to both the screen and the printer.

The following control characters are acted upon by the printer: cursor left (VDU 8), cursor right (VDU 9), cursor down (VDU 10), cursor up (VDU 11), form feed (VDU 12), carriage return ( VDU 13) and home (VDU 30).

Bytes which are parameters for VDU commands are not sent to the printer. For example,

VDU 17,65
does not send 'A' (CHR$65) to the printer.

If you need to line up columns on the printer using TAB(X) ensure you select a monospaced (fixed-pitch) font, for example:

*PRINTERFONT Courier New,12
Note that BBC BASIC assumes that the printer is a page printer. That is, output will not be printed until the current page is complete (i.e. a CLS or VDU 12 was sent, or the BASIC program terminates). This ensures that printer output is not mixed up with that from other programs running at the same time. You can force the current page to print using:
VDU 2,1,12,3

VDU 3

(BBC BASIC for Windows only)
VDU 3 disables the printer. It cancels the effect of VDU 2 so that subsequent output to the screen is not also sent to the printer. If you want to force the page to be printed immediately, send a form-feed (VDU 12) before the VDU 3.
VDU 3
VDU 2,1,12,3

VDU 4

VDU 4 causes text to be written at the text cursor position in the normal way. This is the default mode.

Characters can be positioned only at text coordinates within the text viewport; the text viewport scrolls as necessary. Characters are written using the current text foreground colour on an opaque background of the current text background colour (see COLOUR).

VDU 4

VDU 5

VDU 5 causes text to be written at the graphics cursor position. It works in all modes except MODE 7.

Characters may be positioned at any graphics coordinate within the graphics viewport. The top left corner of the character cell is the reference point. Characters are clipped to the limits of the graphics viewport if necessary. No scrolling takes place.

Characters are plotted using the current graphics foreground colour and in the current graphics foreground plotting mode (see GCOL).

The character background is 'transparent', i.e. it does not change what was previously displayed underneath. VDU 127 (DEL) is an exception; it backspaces and deletes just as it does in the normal text mode, using the current background GCOL rules and colour.

VDU 5

VDU 6

VDU 6 enables output to the VDU screen. It cancels the effect of VDU 21.
VDU 6

VDU 7

(BBC BASIC for Windows only)
VDU 7 causes a short audible 'beep'.
VDU 7

VDU 8

VDU 8 moves the text cursor one character in the negative 'X' direction (normally left, but this can be changed using VDU 23,16). By default, if the cursor was at the start of a line, it moves to the end of the previous line (right edge of the text viewport). If it was also at the top line of the text viewport, the viewport scrolls down (except in the VDU 5 mode). The cursor is constrained to remain within the text viewport.
VDU 8

VDU 9

VDU 9 moves the text cursor one character in the positive 'X' direction (normally right, but this can be changed using VDU 23,16). By default, if the cursor was at the end of a line, it moves to the start of the next line (left edge of the text viewport). If the cursor was also at the bottom of the text viewport, the viewport scrolls up (except in the VDU 5 mode). The cursor is constrained to remain within the text viewport.
VDU 9

VDU 10

VDU 10 moves the text cursor one line in the positive 'Y' direction (normally down, but this can be changed using VDU 23,16). By default, if the cursor was on the bottom line of the text viewport, the viewport scrolls up (except in VDU 5 mode). Scrolling is paused if <Ctrl> and <Shift> are held down together. The cursor is constrained to remain within the text viewport.
VDU 10

VDU 11

VDU 11 moves the text cursor one line in the negative 'Y' direction (normally up, but this can be changed using VDU 23,16). By default, if the cursor was on the top line of the text viewport, the viewport scrolls down (except in VDU 5 mode). The cursor is constrained to remain within the text viewport.
VDU 11

VDU 12

VDU 12 clears the text viewport to the current text background colour and moves the text cursor to column 0, row 0 (normally the top-left corner of the text viewport, but this can be changed using VDU 23,16); it is identical to CLS. If sent to the printer (e.g. using VDU 2,1,12,3) it causes the current page to be printed.
VDU 12
VDU 2,1,12,3

VDU 13

VDU 13 moves the text cursor to column 0 within the current row (normally the left edge of the text viewport, but this can be changed using VDU 23,16). The cursor is constrained to remain within the text viewport.
VDU 13

VDU 14

VDU 14 enables auto-paging mode. Scrolling will stop after each page. When the text viewport has been filled, output is paused until <Shift> is pressed.
VDU 14

VDU 15

VDU 15 disables auto-paging mode. This is the default condition.
VDU 15

VDU 16

VDU 16 clears the graphics viewport using the current background GCOL action and colour. It does not move the graphics cursor. VDU 16 is identical to CLG. VDU 16 does nothing in MODE 7.
VDU 16

VDU 17

VDU 17 is identical to COLOUR. The next byte determines the text foreground or background colour. See COLOUR for more details. The example below sets the text foreground colour to red (assuming that VDU 19 has not been used to change the default logical to physical colour assignments).
VDU 17,1

VDU 18

VDU 18 is identical to GCOL. It takes the next two characters as the plotting mode and graphics colour respectively. Thus,
VDU 18,mode,colour
and
GCOL mode,colour
have the same effect. See the Graphics and colours section for more details.

VDU 19

VDU 19 sets the colour palette, i.e. the mapping between logical colours and physical colours.

VDU 19 takes the next five characters as parameters. The first parameter is the logical colour to be set and the remaining parameters determine the physical colour that it is to be set to.

If the second parameter is in the range 0 to 15 this determines the physical colour as an offset into the physical palette, in this case the remaining three parameters are ignored.

VDU 19,logical,physical,0,0,0

If the second parameter is −1 (or 255) the physical colour is determined by interpreting the remaining three parameters as red, green and blue values in the range 0 to 63, where 0 is none and 63 is maximum.

VDU 19,logical,-1,r,g,b

If the second parameter is 16 the physical colour is determined by interpreting the remaining three parameters as red, green and blue values in the range 0 to 255, where 0 is none and 255 is maximum.

VDU 19,logical,16,R,G,B

VDU 20

The VDU 20 command performs two distinct actions:
VDU 20

VDU 21

VDU 21 disables the VDU drivers until a VDU 6 is received. All VDU commands except 1 and 6 are ignored. If the printer is enabled, VDU commands 8 to 13 will still be sent to the printer.
VDU 21

VDU 22

VDU 22 is identical to MODE, except that MODE zeros the value of COUNT whereas VDU 22 does not. The mode is set according to the value of the byte following the VDU 22 command. The example below sets mode 3.
VDU 22,3
VDU 22 also resets all the screen driver variables (colour, palette, viewports, cursor position, graphics origin, etc). In particular, VDU 22 performs the actions of VDU 4, VDU 12, VDU 15, VDU 20 and VDU 26.

In BBC BASIC for SDL 2.0 only, VDU 22 resets the user-defined characters to their default appearance. Therefore characters may only be redefined after the VDU 22 or MODE statement.

See the Graphics and colours section and the keyword MODE for further details.

VDU 22,mode

VDU 23

VDU 23 is used for several different purposes: to create user-defined characters, to control the appearance of the text cursor (caret), to scroll the display, to select a user-defined display mode, to determine line thickness and to control the way the text cursor moves.

User-defined characters

Characters from &20 to &FF (32 to 255) may be programmed using the VDU 23 command. The programmable characters are not available in MODE 7.

The format of the VDU 23 command is;

VDU 23,char_no,r1,r2,r3,r4,r5,r6,r7,r8
'Char_no' is the character number to be programmed and 'r1' to 'r8' are the values of the bytes which define the character, top to bottom. For example, the character illustrated below is defined as character 130 by the following VDU 23 command.
VDU 23,130,32,98,226,62,62,35,33,33

. . * . . . . .     r1 = 32
. * * . . . * .     r2 = 98
* * * . . . * .     r3 = 226
. . * * * * * .     r4 = 62
. . * * * * * .     r5 = 62
. . * . . . * *     r6 = 35
. . * . . . . *     r7 = 33
. . * . . . . *     r8 = 33
User defined characters occupy a 'cell' which is 8 dots wide by 8 dots high. The number of rows of user defined text which may be displayed on the screen depends on the vertical resolution of the display mode in use.

Note that although the current character font can be changed to any size using the *FONT command, user-defined characters are always the same size in a particular display MODE.

Text cursor control

The text cursor (caret) may be disabled and enabled using the VDU 23 command as shown below. The first is equivalent to the BASIC statement OFF and the second to the statement ON.
VDU 23,1,0;0;0;0; : REM Disable cursor
VDU 23,1,1;0;0;0; : REM Enable cursor
The shape of the text cursor can be controlled (to some degree) by using VDU 23 to set the start line and end line of the cursor 'block'; this affects its height and vertical position. The 'start line' and 'end line' are controlled by the following commands:
VDU 23,0,10,s,0;0;0; : REM Set start line
VDU 23,0,11,e,0;0;0; : REM Set end line
For example, the text cursor is normally a flashing underline in 'insert' mode and a flashing block in 'overtype' mode. To turn it from an underline into a block without changing to 'overtype' mode you can use the following command:
VDU 23,0,10;0;0;0;
This facility should be used with care.

The width of the text cursor can also be set:

VDU 23,0,18,w,0;0;0; : REM Set cursor width
This sets the width of the cursor to w pixels. If w is zero (the default) the cursor is set to the average character width of the current font.

For example, to set the cursor to a vertical line two pixels wide use the following code:

VDU 23,0,18,2,0;0;0;23,0,10;0;0;0;

Scrolling the window

The contents of BASIC's output window (or just the current text viewport) can be scrolled, by one character width or height, using VDU 23,7:
VDU 23,7,m,d,0;0;0;
where m and d are as follows:

m = 0scroll just the text viewport
m = 1scroll BASIC's entire output window
d = 0scroll right one character
d = 1scroll left one character
d = 2scroll down one row
d = 3scroll up one row

Cursor movement control

The way the text cursor (caret) moves after a character has been output is determined by the state of eight flag bits; both screen and printer output are affected. One or more of the flag bits can be modified as follows:
VDU 23,16,x,y,0;0;0;
where the existing 8-bit flags byte is first ANDed with y and then exclusive-ORed with x. To set the entire flags byte to the value f you can do:
VDU 23,16,f;0;0;0;
or
VDU 23,16,f|
The flag bits control the cursor movement as follows (bit 7 must be zero):
Flag bitAction
Bit 6 = 0  The text cursor is constrained to remain within the viewport/page (e.g. by wrapping or scrolling).
Bit 6 = 1The text cursor can move beyond the edge of the viewport/page (except in VDU 4 mode).
Bit 5 = 0The text cursor moves after a character is output.
Bit 5 = 1The text cursor does not move after a character is output.
Bit 4 = 0If appropriate the text viewport scrolls, or the printer page is ejected.
Bit 4 = 1The text cursor wraps to the opposite edge of the viewport/page.
Bit 3 = 0The 'X' direction is horizontal and the 'Y' direction is vertical.
Bit 3 = 1The 'X' direction is vertical and the 'Y' direction is horizontal.
Bit 2 = 0The 'positive' vertical direction is downwards.
Bit 2 = 1The 'positive' vertical direction is upwards.
Bit 1 = 0The 'positive' horizontal direction is rightwards.
Bit 1 = 1The 'positive' horizontal direction is leftwards.
Bit 0 = 0In VDU 4 mode, 'pending scroll' is enabled.
Bit 0 = 1In VDU 4 mode, 'pending CRLF' is enabled.
Bits 1, 2 and 3 affect the column and row addressing used by TAB(X,Y), POS and VPOS. The default value of all the bits is zero.

In 'pending scroll' mode, if a character would normally cause the text viewport to scroll (thus causing the top line to be lost) it will not do so until just before the next character is output. If the cursor is repositioned (e.g. using VDU 13, VDU 30 or VDU 31) before the next character is output, no scroll will take place.

In 'pending CRLF' mode, if a character would normally cause a CRLF action (the text cursor wrapping to the beginning of the next line) it will not do so until just before the next character is output. If the cursor is repositioned before the next character is output, no CRLF will take place.

MODE 7 extensions

BBC BASIC for Windows v6.14a or later and BBC BASIC for SDL 2.0 only
The ability, in MODE 7, to display black text and mosaics, and to select an alternative character set, may be enabled as follows:
VDU 23,18,3,1,0;0;0;
or
VDU 23,18,3,1|
To disable these features change the 1 to 0.

User-defined modes

Although the MODE statement gives a wide choice of different display modes, there may be circumstances when a mode with different characteristics is required. The VDU 23 command can be used to select a user-defined mode as follows:
VDU 23,22,width;height;charx,chary,ncols,charset
where:
width = window width in pixels (e.g. 640)
height = window height in pixels (e.g. 512)
charx = character width in pixels (e.g. 8)
chary = character height in pixels (e.g. 16)
ncols = number of colours (e.g. 16)
charset = 0 for ANSI, 1 for OEM (IBM PC), 8 for UTF-8
Note that the width and height values must be followed by semicolons. You should choose the width and height values to be integer multiples of the charx and chary values respectively. For example, you can select a mode which has 10 (large!) characters per line and 8 lines of text as follows:
VDU 23,22,640;512;64,64,16,0
The maximum values for width and height are 1920 and 1440 respectively.

By default the background colour is black and the text colour is white. To select a mode with a white background and black text add 128 to the charset value.

If the charset value is set to 8, text output to the screen or printer is assumed to be in UTF-8 format. This gives access to the complete Basic Multilingual Plane (including alphabets like Greek, Cyrillic, Arabic, Hebrew etc.) whilst remaining compatible with ASCII. To utilise this mode you should select a Unicode font after the VDU 23 command:

VDU 23,22,640;512;8,16,16,8
*FONT Arial,16

Line thickness

Straight lines and outline shapes, plotted using VDU 25 (or, equivalently, using DRAW, LINE, CIRCLE, ELLIPSE, RECTANGLE etc.), are normally one pixel thick. The thickness can be changed to a different value as follows:
VDU 23,23,t;0;0;0;
or
VDU 23,23,t|
where t is the required line thickness in pixels. Note that only solid lines can have their thickness changed, not dotted or dashed lines.

VDU 24

In all modes except MODE 7, VDU 24 defines a graphics viewport. The following four words (pairs of bytes) are the X & Y coordinates of the bottom left corner of the viewport and the X & Y coordinates of the top right corner of the viewport, inclusive, in that order. The coordinates are with respect to the current graphics origin.

It is particularly easy to select invalid viewport limits if the graphics origin has been moved. It is advisable, therefore, to precede a VDU 24 command with a VDU 29,0;0; command or ORIGIN 0,0 statement to reset the graphics origin.

The following example defines a graphics viewport with the bottom left corner at 200,100 and the top right corner at 500,300.

VDU 24,200;100;500;300;
VDU 24,left;bottom;right;top;
Be very careful not to omit the final semicolon.

VDU 25

VDU 25 is identical to the PLOT statement. See the Graphics and colours section or the keyword PLOT for more details.
VDU 25,mode,x_coord;y_coord;
The following example draws a line in the current foreground colour to the point 350,525:
VDU 25,5,350;525;

VDU 26

VDU 26 resets the text and graphics viewports to their default positions (filling the whole screen), homes the text cursor to the top left of the screen (0,0), resets the graphics origin to the bottom left of the screen (0,0) and moves the 'current point' to the graphics origin.

Important note: VDU 26 resets the text and graphics viewports to the current size of BASIC's screen (output window), not to the default size appropriate to the current MODE. In the event that BASIC's output window has been resized by the user (by dragging a corner or side) or has a reduced size because the display resolution is inadequate for the selected MODE, VDU 26 may alter the relative alignment of text and graphics. If this could be a problem, avoid the use of VDU 26 (or make sure the display resolution is sufficient and prevent the user resizing the window).

VDU 26

VDU 27

VDU 27 sends the next byte to the screen without interpreting it as a control character. It allows graphics characters corresponding to VDU 0 to VDU 31 and VDU 127 to be displayed. It acts for characters sent to the screen in a similar manner to the way VDU 1 does for characters sent to the printer.
VDU 27,127

VDU 28

VDU 28 defines a text viewport. The following four bytes are the X & Y coordinates of the bottom left corner of the viewport and the X & Y coordinates of the top right corner of the viewport, inclusive, in that order. The coordinates are with respect to the text origin (top left) and are measured in 'character positions'.

If the text cursor is outside the new viewport, it is moved to the new home position (top left of the viewport). If it is inside the new viewport, it is not moved.

The following example defines a text viewport with the bottom left corner at X=0, Y=15 and the top right corner at X=30, Y=3 .

VDU 28,0,15,30,3
VDU 28,left,bottom,right,top

VDU 29

VDU 29 moves the graphics origin to the coordinates specified by the following two words (pairs of bytes). The first word specifies the X coordinate of the new origin and the second specifies the Y coordinate. Subsequent graphics commands operate with respect to this origin. VDU 29 has the same effect as the ORIGIN statement.

The following example sets the graphics origin to 640,400:

VDU 29,640;400;
ORIGIN 640,400 

VDU 30

In VDU 4 mode, VDU 30 homes the text cursor to column 0, row 0 (normally the top-left corner of the text viewport, but this can be changed using VDU 23,16). In VDU 5 mode, VDU 30 homes the graphics cursor to the 'top left' corner of the graphics viewport.
VDU 30

VDU 31

VDU 31 is identical to PRINT TAB(x,y). It positions the text cursor according to the following two bytes, the first determining the column number and the second the row number. Normally column 0 is the left of the text viewport and row 0 is the top of the text viewport, but this can be changed using VDU 23,16. The example below positions the text cursor in column 15 and row 10.
VDU 31,15,10
See the keyword TAB for further details.
VDU 31,col,row

VDU 127

Deletes the character to the left of the cursor and backspaces the cursor to this position. In VDU 4 mode this has the same effect as the sequence backspace-space-backspace (VDU 8,32,8).
VDU 127


Operating System interface

Introduction to star commands

On the BBC Microcomputer and Acorn Archimedes, star (*) commands provide access to the 'operating system'. These commands can either be 'resident' (i.e. permanently part of the operating system) or 'transient' (i.e. loaded when required). Modern operating systems do not have 'resident' commands in quite the same way, so BBC BASIC for Windows and BBC BASIC for SDL 2.0 implement their own resident commands as part of the application. However, 'transient' or 'external' commands can still be activated via the star commands (or OSCLI).

File specifiers

Many of the 'star' commands are concerned with files; whenever a filename or file specifier is used it must comply with the relevant naming conventions of the operating system:
[drive:][\][path\]filename[.ext] (Windows)
[/][path/]filename[.ext] (most other OSes)
drive: The single letter name of the drive where the file will be found. The colon is mandatory. If the drive name is omitted, the current drive is assumed.
path The list of directories and sub-directories (folders) which must be followed in order to find the specified file. If the path is omitted, the current directory is assumed.
filename The name of the file. If this contains spaces the entire file specifier should be enclosed in quotation marks (see below).
ext The optional extension of the file. If an extension is used it must be separated from the filename by a full-stop. If the extension is omitted, a default extension is (usually) assumed. To access a file which has no extension, append a full stop (period).
Because Windows™ will accept both backslash (\) and forward slash (/) as a directory delimiter, using forward slash consistently will maximise compatibility between operating systems. Also, whilst Windows and some other operating systems are insensitive to the case of file and directory names, many are case-sensitive. So for maximum compatibility you should be careful always to use the correct case. These precautions are particularly important when using BBC BASIC for SDL 2.0.

File and directory names generally do not need to be enclosed in quotes. However if a file or directory name includes any spaces (or punctuation characters) you must enclose it in quotes; unmatched quotes will cause a 'Bad string' error. If you need to use the OSCLI statement there are two main ways of incorporating quotation marks, with CHR$(34) or using the 'escape' sequence "". For example both the following will work:

OSCLI "CD "+CHR$(34)+directory$+CHR$(34)
OSCLI "CD """+directory$+""""

When an 'ambiguous' file specifier is needed the standard wildcard characters (? and *) may be used.

Accessing star commands

The star commands may be accessed directly or via the OSCLI statement. OSCLI must be used when all or part of the star command needs to be determined at run-time (i.e. is a variable rather than a constant). The two examples below both access the *HELP command.
*HELP
OSCLI("HELP")
A star command must be the last (or only) command on a program line and its argument may not be a variable. Unlike keywords, star commands are not case-sensitive (and are not affected by *LOWERCASE).

Similarly named star commands

If you wish to execute an OS command with the same name as a resident command, precede it with a second star. For example,
*COPY
will execute BBC BASIC's resident file copy command but
**COPY
will pass the command to the operating system.

Errors in star commands

If a star command is mistyped, or does not exist, it will be interpreted as an 'external' command and passed to the OS for execution. If it is not the name of a valid shell command or executable, an error will result which may be reported in the console window. However this may appear on the screen very transitorily, if at all, and it may not be apparent what has happened. In addition this error cannot always be detected or trapped by BBC BASIC.

For this reason, the *FX (with the exception of *FX 15 and *FX 21) and *TV commands are trapped and ignored. These two star commands are commonly found in programs for the BBC Micro, but they have no counterpart in other OSes.


Star command summary

CommandFunction
*BYE exit the BASIC program and close its window
*CHDIR (*CD) display or change the current directory
*COPY copy a file
*DELETE (*DEL) delete a file
*DIR (*.) list the directory contents
*DISPLAY display a standard bitmap (BMP) file
*DUMP list the contents of a file in hexadecimal
*EGA emulate an EGA or CGA display
*ERASE (*ERA) delete a file
*ESC enable or disable the Escape key
*EXEC accept console input from a file
*FLOAT select floating-point numeric precision
*FONT select a screen font and style
*FX flush keyboard and/or sound buffers
*GSAVE synonymous with *SCREENSAVE
*HARDCOPY copy graphics to the printer
*HELP display version information
*HEX control hexadecimal conversion and shift operators
*INPUT redirect console input
*KEY program a function or special key
*LIST display the contents of a program file
*LOAD load a file into memory
*LOCK set a file to read-only status
*LOWERCASE enable or disable lower-case keywords
*MARGINS set the printer page margins
*MKDIR (*MD) create a sub-directory (folder)
*MDISPLAY display a BMP image stored in memory
*NOEGA cancel the effect of *EGA
*OSK display or hide the On Screen Keyboard
*OUTPUT (*OPT) redirect console output
*PLAY play a MIDI file
*PRINTER select a printer
*PRINTERFONT select a printer font and style
*QUIT exit the BASIC program and close its window
*REFRESH control when the screen is refreshed
*RENAME (*REN) rename a file
*RMDIR (*RD) remove (delete) a directory
*RUN run a shell command or executable program
*SAVE save memory to a file
*SCREENSAVE save the output window as a BMP file
*SPOOL copy console output to a file
*SPOOLON append console output to an existing file
*STEREO position a sound channel on the stereo stage
*SYS enable trapping of additional system messages
*TEMPO control the speed of the SOUND statement
*TIMER control the periodicity of the ON TIME interrupt
*TV accepted but ignored
*TYPE display the contents of a text file
*UNLOCK set a file to read-write status
*VOICE allocate a sound channel to a specific waveform
*| a comment


*BYE

Exit the interpreter and return to the calling program. If the BASIC program is running in the interactive environment, the program's output window closes and control is returned to the command and editing window.

If the BASIC program is running stand-alone (e.g. having been converted to an application bundle or executable with the Compile command) control is returned to the operating system.

*BYE is synonymous with the *QUIT command and the QUIT statement.

Syntax:

*BYE

*CHDIR (*CD)

Change the current working directory (folder) to a different drive and/or path. The syntax is similar to the CD command available at a Command Prompt.
*CHDIR BBCBASIC/DOC
*CD A:/LETTERS/RATES
*CD "Program Files"
OSCLI "CD """+directory$+""""
*CD followed only by a slash will change the current working directory to the root (top level) directory of the current drive. *CD followed only by a drive name will change the current working directory to the root directory of that drive.
*CHDIR /
*CD A:
*CD on its own will display the current working directory (folder). If your program needs to know the current directory you can either use *CD and SPOOL the output to a file, or in Windows™ you can use the GetCurrentDirectory API function:
DEF FNcurrentdirectory
DIM cd% LOCAL 255
SYS "GetCurrentDirectory", 256, cd%
= $$cd%

Syntax:

*CD [d:][/][pth]
*CHDIR [d:][/][pth]

*COPY

Copy a file. The syntax is similar to the COPY command available at a Command Prompt, except that the filename extension defaults to .BBC if omitted. To specify a filename with no extension, add a final full-stop.
*COPY srcfile.dat destfile.dat
OSCLI "COPY """+sourcefile$+""" """+destfile$+""""
(BBC BASIC for Windows only)
If the command exceeds 254 characters in length a Bad name error will result. In that case you can use the Windows™ API instead (the extensions must be included explicitly):
SYS "CopyFile", sourcefile$, destfile$, 0
The above commands will copy only one file at a time; wildcards are not permitted in the file specifiers. If you wish to include wildcards in order to copy more than one file, you can use the **COPY command which will be executed by Windows™. Alternatively you can use the following routine based on the FindFirstFile and FindNextFile Windows™ API functions:
DEF PROCcopyfiles(src$,dst$,afsp$)
LOCAL dir%, buf%, sh%, res%, fpt%, num%
DIM dir% LOCAL 317, buf% LOCAL 260

IF RIGHT$(src$,1) <> "\" src$ += "\"
IF RIGHT$(dst$,1) <> "\" dst$ += "\"

SYS "FindFirstFile", src$+afsp$, dir% TO sh%
IF sh% <> -1 THEN
  REPEAT
    SYS "GetFullPathName", dir%+44, 260, buf%, ^fpt% TO num%
    buf%?num% = 13
    IF (!dir% AND 16) = 0 THEN
      SYS "CopyFile", src$+$fpt%, dst$+$fpt%, 0 TO res%
      IF res% = 0 PRINT "File copy failed"
    ENDIF
    SYS "FindNextFile", sh%, dir% TO res%
  UNTIL res% = 0
  SYS "FindClose", sh%
ENDIF
ENDPROC
The parameters are the source and destination directories and a file specification containing wildcards (* or ?).

Syntax:

*COPY ufsp ufsp

*DELETE (*DEL)

Delete the specified disk file. The syntax is similar to the DEL or RM command available at a Command Prompt except that the extension defaults to .BBC if it is omitted. To specify a filename with no extension, add a final full-stop.
*DEL GAME1.DTA
OSCLI "DEL """+file$+""""
This command will delete only one file at a time; a wildcard is not permitted in the file specifier. If you wish to include wildcards in order to delete more than one file, you can use an operating system command such as **del (Windows™) or *rm (most other OSes).

Syntax:

*DEL ufsp
*DELETE ufsp

*DIR

*.

List the disk directory. The syntax is similar to the DIR or LS command available at a Command Prompt except that the extension defaults to .BBC if it is omitted. To specify a filename with no extension, add a final full-stop.

*DIR List all .BBC files in the current directory (folder).
*DIR B:*.*  List all files on disk B.
*.*.* List all the files in the current directory.

Syntax:

*DIR [afsp]

*DISPLAY

Display a bitmap image file, optionally specifying its width and height:
*DISPLAY bmpfile
*DISPLAY bmpfile x,y
*DISPLAY bmpfile x,y,w,h
OSCLI "DISPLAY """+bmpfile$+""" "+STR$x+","+STR$y+","+STR$w+","+STR$h
In BBC BASIC for Windows the file must be in .BMP format; in BBC BASIC for SDL 2.0 it may alternatively be in .GIF, .JPG, .PNG or .TGA format.

The specified position (x,y) corresponds to the bottom-left corner of the image, and is given in BBC BASIC graphics units. The size and shape of the image may optionally be specified, in which case the image is scaled as necessary; this may result in a loss of quality. If the width and height are omitted the image is displayed without scaling.

The position and size values must be integers; if necessary use the INT function to ensure there is no decimal point.

If the filename extension is omitted, .BMP is assumed. See also *MDISPLAY and *SCREENSAVE.

When the image is scaled, you may find that the quality is improved by preceding the *DISPLAY command with one of the following statements, as appropriate:

SYS "SetStretchBltMode", @memhdc%, 3                    : REM BBC BASIC for Windows
SYS "SDL_SetHint", "SDL_RENDER_SCALE_QUALITY", "linear" : REM BBC BASIC for SDL 2.0

BBC BASIC for Windows v6.10a or later and BBC BASIC for SDL 2.0 only
An additional parameter may be specified, corresponding to a hexadecimal value that will be interpreted as a 'transparent' or 'key' colour; any pixels with this colour in the image will not be plotted and whatever was 'behind' will show through:

OSCLI "DISPLAY """+bmpfile$+""" x,y,w,h,k"
The key colour must be specified in whatever format the BMP file uses internally, so if it's a 24 bits-per-pixel RGB file specify a six-digit hexadecimal value in the format rrggbb (if the key colour is black specify it as 1000000). If the file has a different pixel format specify it in whatever representation the file uses. In the special case of a 16 bits-per-pixel file ensure that you choose a key colour which has low RGB values, for example R=1, G=1, B=1 which corresponds to the hexadecimal value 0421 in a RGB555 file.

BBC BASIC for Windows v6.11a or later and BBC BASIC for SDL 2.0 only
If you specify the width and/or height as negative values the image will be automatically flipped: horizontally, vertically or both. The specified position still corresponds to the bottom-left corner of the original (unflipped) image. This feature does not work if the 'transparent' or 'key' colour option is used.

Syntax:

*DISPLAY ufsp [num,num[,num,num[,hex]]]

*DUMP

(BBC BASIC for SDL 2.0 only)
Lists the contents of the specified file in hexadecimal and ASCII. Optionally the start offset and the total number of bytes to be listed (or alternatively the end offset) may be specified as hexadecimal numbers. Character codes outside the range &20 to &7E are printed as dots.
*DUMP myfile.txt 
*DUMP myfile.txt 1000 +80

Syntax:

*DUMP ufsp [hexstart [hexend]]
*DUMP ufsp [hexstart [+hexlen]]

*EGA

This command is provided for BBC BASIC (86) compatibility. *EGA ON causes screen modes 0 to 15 to be mapped to the dimensions and number of colours they would have in BBC BASIC (86) when the *EGA command is used, i.e. modes of which an EGA adaptor and monitor are capable.

*EGA OFF causes screen modes 0 to 15 to be mapped to the dimensions and number of colours they would have in BBC BASIC (86) when the *EGA command is not used (or the *EGA OFF command is used), i.e. modes of which a CGA adaptor and monitor are capable.

BBC BASIC (86) programs which include a *EGA (or *EGA ON) command should therefore select an appropriate mode without needing to be modified. BBC BASIC (86) programs which don't include a *EGA command should be modified by adding a *EGA OFF command.

If you need to cancel the effect of *EGA, use *NOEGA.

*EGA ON
*EGA OFF
*NOEGA

Syntax:

*EGA [ON|OFF]

*ERASE (*ERA)

This command is synonymous with *DELETE.

Syntax:

*ERASE ufsp

*ESC

Disable or enable the abort action of the ESCape key.
*ESC OFF
*ESC ON
After *ESC OFF the <Esc> key simply returns the ASCII code for ESCape (27). *ESC ON (or *ESC) restores the normal abort action of the <Esc> key.

Syntax:

*ESC [ON|OFF]

*EXEC

Accept console input from the specified file instead of from the keyboard. If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.
*EXEC STARTUP.CMD
OSCLI "EXEC """+cmdfile$+""""
Once the entire file has been read, keyboard input is restored. *EXEC without a filename closes the file and restores keyboard input immediately.

Syntax:

*EXEC [ufsp]

*FLOAT

Select the required floating-point numeric precision (40, 64 or 80); the default is *FLOAT 40:
*FLOAT 40
*FLOAT 64
*FLOAT 80
The *FLOAT command affects the precision with which floating-point values are stored and retrieved using floating-point indirection or in data files (PRINT# and INPUT# statements). When reading or modifying a data file you should always use the same *FLOAT mode as when it was originally written.

BBC BASIC for Windows v5.95a or earlier only
The *FLOAT command additionally controls the precision of variant (suffixless) numeric variables; only *FLOAT40 (the default) and *FLOAT 64 are available. In *FLOAT40 mode variant (real) numbers have approximately a 9 significant-figure accuracy; in *FLOAT64 mode they have approximately a 15 significant-figure accuracy. BBC BASIC for Windows doesn't necessarily run any more slowly in *FLOAT64 mode (in fact, it may run more quickly because it uses the CPU's numeric data processor) but variant numeric variables and arrays occupy more memory.

BBC BASIC for Windows v5.95a or earlier only
Variant variables created in *FLOAT40 mode are independent of variables created in *FLOAT64 mode, and can co-exist. In the rare circumstance that you need to copy a 40-bit variable into a 64-bit variable, or vice versa, you can do that only in *FLOAT40 mode by adding a # suffix to the name of the 64-bit variable. One use for that facility is to read a data file written in a different *FLOAT mode:

*FLOAT 40
INPUT #file, A
A# = A
*FLOAT 64
PRINT A#
The above program segment reads a 40-bit value from a data file, then copies it into a 64-bit variable.

BBC BASIC for Windows v5.95a or earlier only
Numeric constants are converted to 40-bit or 64-bit binary floating-point format according to which *FLOAT mode is currently selected. If you want to force conversion to a 64-bit double, even when in *FLOAT40 mode, you can do so by adding a # (hash) suffix:

A# = 1.234#
B# = PI#
PRINT PI#-PI

*FONT

Select the specified font (typeface) and size, and optionally select an attribute (bold, italic, underscore and/or strikeout); The required attribute(s) are specified using the letters B, I, U and Q respectively. The underscore (U) and strikeout (Q) attributes are mutually-exclusive. The size should be specified in 'points' (1/72 inch).

BBC BASIC for Windows:
If the specified font is not installed, an attempt will be made to select a font similar to the one you requested (you can find out which font has been selected using the GetTextFace Windows API function):

*FONT Arial,16
*FONT Courier New,20,U
*FONT Letter Gothic,12,BI
OSCLI "FONT "+fontname$+","+STR$pt%+","+style$

BBC BASIC for SDL 2.0:
The font must be specified as the full path and filename of the .TTF or .OTF file; this means that you must usually use OSCLI since the path is likely to be variable (if the font file does not exist, a "No such font" error will result):

OSCLI "FONT """ + @lib$ + "DejaVuSans"",16"
OSCLI "FONT """ + @lib$ + "DejaVuSansMono"",20,U"
OSCLI "FONT """ + @lib$ + "FreeSerif"",12,BI"
OSCLI "FONT """+fontfile$+""","+STR$pt%+","+style$

If no typeface, size or style is specified, *FONT selects the default font:

*FONT
Note that the size at which the font is displayed on the screen depends on the current dots per inch (dpi) setting. This is most commonly 96dpi, but may be 120dpi (or another value) if Large Fonts have been selected or when using some high-resolution displays. Ideally you should ensure that your program works satisfactorily with either setting.

Use the *FONT command with care, as selecting a font other than the default can cause unwanted side-effects. For example, if you select a proportional-spaced font and then use the INPUT statement, the input editing features provided will not work correctly. The <backspace> key will not correctly 'blank' (on the screen) the previous character entered, nor will the <cursor left> and <cursor right> keys have the desired effect. This problem can be circumvented by using the FNpsinput function listed below; this implements most of the features of the INPUT statement but will work correctly with a proportional-spaced font:

DEF FNpsinput(X%,Y%,prompt$) : LOCAL A$,C%,K%
VDU 23,0,18,2,0;0;0;23,0,10;0;0;0;
REPEAT : OFF
  PRINT TAB(X%,Y%) prompt$;A$;"    ";
  PRINT TAB(X%,Y%) prompt$;LEFT$(A$,C%);
  ON : REPEAT K% = INKEY(1) : UNTIL K%<>-1
  CASE K% OF
    WHEN 8,127: IF C% A$ = LEFT$(A$,C%-1) + MID$(A$,C%+1) : C% -= 1
    WHEN 13:
    WHEN 136: IF C% C% -= 1
    WHEN 137: IF C% < LEN(A$) C% += 1
    OTHERWISE: A$ = LEFT$(A$,C%) + CHR$K% + MID$(A$,C%+1) : C% += 1
  ENDCASE
UNTIL K% = 13
PRINT
= A$
The function takes as parameters the column and row numbers (as would be needed by TAB(X,Y)) and a prompt string. It returns the string which was entered by the user.

Syntax:

*FONT [name,size[,style]]

*FX

With the exception of *FX 15 and *FX 21, all the *FX commands are ignored.

*FX 15,n and *FX21,n flush selected internal buffers as follows:

*FX 15,0 flushes all the internal buffers
*FX 15,1 flushes the currently selected input buffer
*FX 21,0 flushes the keyboard buffer
*FX 21,4 flushes the channel 0 SOUND buffer
*FX 21,5 flushes the channel 1 SOUND buffer
*FX 21,6 flushes the channel 2 SOUND buffer
*FX 21,7 flushes the channel 3 SOUND buffer

Syntax:

*FX num,num

*GSAVE

This command is synonymous with *SCREENSAVE.

Syntax:

*GSAVE ufsp [num,num,num,num]

*HARDCOPY

(BBC BASIC for Windows only)
Copy graphics from the screen to the printer.
*HARDCOPY x, y, w, h, X, Y, W, H
A rectangular region of BASIC's output window is copied to the printer (assuming your printer supports bit-mapped graphics). The parameters are as follows:
x, yThe coordinates, in BBC BASIC graphics units, of the bottom-left corner of the region to be printed.
w, hThe width and height, in BBC BASIC graphics units, of the region to be printed.
X, YThe offset, in millimetres, from the top-left corner of the printable area of the paper to the top-left corner of the printed graphics.
W, HThe width and height, in millimetres, of the printed graphics.
You can print more than one graphic on the same page by using *HARDCOPY multiple times with different offsets specified. Similarly you can combine graphics and text by using *HARDCOPY in conjunction with the VDU 2 and VDU 3 commands. When the entire contents of the page have been output, send a form-feed character (e.g. VDU 2,1,12,3) to cause it to be printed.

If you have increased the size of the graphics 'canvas' to be greater than the size of your output window (for example using the technique used in SCROLL.BBC) then you can use *HARDCOPY to print the entire canvas, not just what is visible on the screen.

If you omit the destination parameters (X, Y, W, H) the selected region is automatically scaled and centered to fit the page. If you omit all the parameters, the entire output window is scaled and centered to fit the page.

Syntax:

*HARDCOPY [num,num,num,num[,num,num,num,num]]

*HELP

Display the name and version number of BBC BASIC.
*HELP
This results in the following message (or something like it) being displayed:
BBC BASIC for Windows 6.14a

Syntax:

*HELP

*HEX

BBC BASIC for Windows v6.00a or later and BBC BASIC for SDL 2.0 only
Control whether the hexadecimal conversion (& and ~) and bit-shift (<< and >>) operators treat their operands as 32-bit or 64-bit integers. In the (default) *HEX 32 mode the operators work in a fashion which is compatible with earlier versions of BBC BASIC; the operands are treated as 32-bit signed integers. In *HEX 64 mode the operands are treated as 64-bit signed integers.
*HEX 32
*HEX 64
For example consider the following program:
PRINT ~TRUE
PRINT &FFFFFFFF
PRINT 2000000000 << 1
In *HEX 32 mode the output is:
  FFFFFFFF
        -1
-294967296
In *HEX 64 mode the output is:
FFFFFFFFFFFFFFFF
4.2949673E9
       4E9

*INPUT

Redirect console input to come from a communications port rather than from the local keyboard:
*INPUT 1
OSCLI "INPUT "+STR$channel%
The number following *INPUT corresponds to the channel number returned by the OPENUP function used to open the required comms port; this will be in the range 1 to 4 (see the Serial I/O section for details). Since this is determined at run-time, you will normally need to use OSCLI to access this command.

*INPUT 0 restores normal (keyboard) console input.

The following special values provide improved support for console mode programs:

*INPUT 13   as *INPUT 1, except that 'non overlapped' I/O is used.
*INPUT 14 as *INPUT 2, except that 'non overlapped' I/O is used.
*INPUT 15 as *INPUT 3, except that 'non overlapped' I/O is used.

Syntax:

*INPUT num

*KEY

*K.

Redefine a function or cursor key to return the specified string.

*KEY 2 "This is key 2"
OSCLI "KEY "+STR$keynum%+" """+keystr$+""""
The 'key number' is from 1 to 24 as follows:
NoKey NoKey
1f1 12Left
2f2 13Right
3f3 14Down
4f4 15Up
5f5 16Ctrl/Left (or mouse wheel down)
6f6 17Ctrl/Right (or mouse wheel up)
7f7 18Home
8f8 19End
9f9 20PgUp
10f10 21PgDn
11   Shift/Tab (or f11)   22Ins
24Backspace 23   Del

The string may contain the 'escape' symbol '|' in order to include non-printing characters. For example, |M indicates CR (carriage-return), |? indicates DEL, || indicates the escape character itself and |! causes bit 7 of the following character to be set. If the string is enclosed in quotes (which is optional), |" allows the character " to be included in the string.

If there is insufficient room for the string, a 'Bad string' error will occur and the key will be loaded with as much of the string as would fit.

*KEY num without a string will empty the specified key and return it to its normal code (see GET).

Compatibility with some BBC Micro programs can be improved by redefining the Backspace key to return the code 127 (DEL) rather than 8 (BS). That can be achieved as follows:

*KEY 24 |?

Syntax:

*KEY num [str]

*LIST

*LI.

List the specified internal format (tokenised) program file to the screen. If the filename extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.

*LIST progfile
OSCLI "LIST "+progfile$
Note that no indentation or syntax colouring takes place.

You can use this command to display the contents of a program file saved in BBC BASIC (.BBC) format. You can pause the display either by holding down <Shift> and <Ctrl> simultaneously, or by first entering 'paged' mode by typing Ctrl/N (VDU 14). In 'paged' mode, the display pauses until <Shift> is pressed. To cancel 'paged' mode press Ctrl/O ( VDU 15).

To display a program saved in ASCII text (.BAS) format use *TYPE.

Syntax:

*LIST ufsp

*LOAD

*L.

Load a specified file into memory at a specified address. The load address must always be specified. If the filename extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.

OSCLI "LOAD A:WOMBAT "+STR$~A%%
OSCLI "LOAD """+file$+""" "+STR$~address%%
The load address must be given as a hexadecimal number. Since, in BBC BASIC for SDL 2.0, this may be a 64-bit number you should ensure that you have enabled *HEX 64 mode, and that you have used either a suffixless variable (e.g. addr) or a 64-bit numeric variable (e.g. addr%%).

You must ensure that the specified address is valid and that there is sufficient room for the file to be loaded there. Generally, the address should have been allocated using the DIM statement. If you fail to take these precautions it is very likely that *LOAD will crash BBC BASIC!

You can optionally specify the maximum number of bytes to be loaded (prefixed by a + sign) or, equivalently, the first address not to be loaded. The value must be specified as a hexadecimal number:

OSCLI "LOAD """+file$+""" "+STR$~addr%%+" +"+STR$~max%
OSCLI "LOAD """+file$+""" "+STR$~addr%%+" "+STR$~(addr%+max%)
You must specify the maximum size when loading into an area of memory allocated by DIM LOCAL or an operating system API function.

Syntax:

*LOAD ufsp hexaddr
*LOAD ufsp hexaddr +hexsize
*LOAD ufsp hexaddr hextop

*LOCK

Set the specified file to 'read-only' status. If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.
*LOCK WOMBAT.DAT
OSCLI "LOCK """+file$+""""
Once a file has been made read-only, any attempt to write to it will result in the Access denied error.

Syntax:

*LOCK ufsp

*LOWERCASE

Allow BASIC keywords, hexadecimal numbers and numbers in 'exponent' (E) format to be accepted in lower-case:
*LOWERCASE ON
This affects the recognition of keywords by EVAL. For example if *LOWERCASE ON has been executed, EVAL("pi") will return the value of PI. Otherwise it would result in a No such variable error.

A word will only be recognised as a keyword if it is entirely capitals or entirely lower-case. A word consisting of a mixture of capitals and lower-case characters will never be mistaken for a keyword.

*LOWERCASE ON also allows lower-case hexadecimal numbers to be accepted (for example &abcd) and the use of a lower-case "e" in numbers entered in 'exponent' format (e.g. 1.2e-3).

To disable the acceptance of lower-case keywords etc. use *LOWERCASE OFF.

When entering statements or commands in Immediate mode the acceptance of lower-case keywords etc. is controlled by the Lowercase keywords item in the Options menu.

Syntax:

*LOWERCASE [ON|OFF]

*MARGINS

(BBC BASIC for Windows only)
Set the printer page margins.
*MARGINS left,bottom,right,top
This sets the printer page margins to the specified values in millimetres. BASIC will not print closer to the edge of the paper than these values. Initially all four margins are set to 10 mm, but note that both the *PRINTER and *PRINTERFONT commands reset the margins to zero, not to 10 mm.

Syntax:

*MARGINS num,num,num,num

*MKDIR (*MD)

Create a new directory (folder) with the given name. The syntax is similar to the MKDIR command available at a Command Prompt:
*MD D:DATA
*MKDIR /BBCBASIC/TRIALS
OSCLI "MKDIR """+directory$+""""
If a directory with that name already exists, the File exists error will result.

Syntax:

*MD [d:][/]path
*MKDIR [d:][/]path

*MDISPLAY

Display a bitmap image stored in memory, optionally specifying its width and height:
OSCLI "MDISPLAY "+STR$~addr
OSCLI "MDISPLAY "+STR$~addr+" x,y"
OSCLI "MDISPLAY "+STR$~addr+"  x,y,w,h"
In BBC BASIC for Windows the image in memory must be in .BMP format; in BBC BASIC for SDL 2.0 it may alternatively be in .GIF, .JPG, .PNG or .TGA format.

The memory address must be given as a hexadecimal number. Since, in BBC BASIC for SDL 2.0, this may be a 64-bit number you should ensure that you have enabled *HEX 64 mode, and that you have used either a suffixless variable (e.g. addr) or a 64-bit numeric variable (e.g. addr%%).

The specified position (x,y) corresponds to the bottom-left corner of the image, and is given in BBC BASIC graphics units. The size and shape of the image may optionally be specified, in which case the image is scaled as necessary; this may result in a loss of quality. If the width and height are omitted the image is displayed without scaling.

BBC BASIC for Windows v6.10a or later and BBC BASIC for SDL 2.0 only
An additional parameter may be specified, corresponding to a hexadecimal value that will be interpreted as a 'transparent' or 'key' colour; any pixels with this colour in the image will not be plotted and whatever was 'behind' will show through:

BBC BASIC for Windows v6.11a or later and BBC BASIC for SDL 2.0 only
If you specify the width and/or height as negative values the image will be automatically flipped: horizontally, vertically or both. The specified position still corresponds to the bottom-left corner of the original (unflipped) image. This feature does not work if the 'transparent' or 'key' colour option is used.

OSCLI "MDISPLAY "+STR$~addr+"  x,y,w,h,k"
The key colour must be specified in whatever format the bitmap data uses internally, so if it's a 24 bits-per-pixel bitmap specify a six-digit hexadecimal value in the format rrggbb (if the key colour is black specify it as 1000000). If the bitmap has a different pixel format specify it in whatever representation the bitmap uses. In the special case of a 16 bits-per-pixel bitmap ensure that you choose a key colour which has low RGB values, for example R=1, G=1, B=1 which corresponds to the hexadecimal value 0421 in a RGB555 bitmap.

The quality of the displayed image will be affected by your current display settings (right-click on the desktop, select Properties then Settings). For best results ensure you are using High Colour (16-bit) or True Colour (24-bit), but see the Compatibility limitations section for notes on the effects of the different settings.

The position and size values must be integers; if necessary use the INT function to ensure there is no decimal point.

When the image is scaled, you may find that the quality is improved by preceding the *MDISPLAY command with one of the following statements, as appropriate:

SYS "SetStretchBltMode", @memhdc%, 3                    : REM BBC BASIC for Windows
SYS "SDL_SetHint", "SDL_RENDER_SCALE_QUALITY", "linear" : REM BBC BASIC for SDL 2.0

*MDISPLAY is useful if you want to display the same image many times, since using *DISPLAY involves an overhead of reading the file each time. With *MDISPLAY you can load the file once (using *LOAD) and then display it many times. See also *SCREENSAVE.

Syntax:

*MDISPLAY hexaddr [num,num[,num,num[,hex]]]

*NOEGA

Cancels the effect of *EGA ON or *EGA OFF. After *NOEGA no mapping of modes takes place.

Syntax:

*NOEGA

*OSK

(BBC BASIC for SDL 2.0 only)
*OSK or *OSK ON displays the on-screen keyboard, if available, and *OSK OFF hides it. When running on a mobile platform (Android or iOS), the on-screen keyboard will be automatically displayed if the GET function or INPUT statement is used.
*OSK ON
*OSK OFF
This command may not have an effect if an external (USB or Bluetooth) keyboard is connected.

Syntax:

*OSK [on|off]

*OUTPUT (*OPT)

Redirect console output to go to a communications port rather than the screen:
*OUTPUT 2
OSCLI "OUTPUT "+STR$channel%
The number following *OUTPUT corresponds to the channel number returned by the OPENUP function used to open the required comms port; this will be in the range 1 to 4 (see the Serial I/O section for details). Since this is determined at run-time, you will normally need to use OSCLI to access this command.

*OUTPUT 0 restores normal (screen) console output.

The following special values provide improved support for console mode programs and for emulating the LPRINT statement available in some BASIC dialects:

*OUTPUT 13   as *OUTPUT 1, except that 'non overlapped' I/O is used.
*OUTPUT 14 as *OUTPUT 2, except that 'non overlapped' I/O is used.
*OUTPUT 15 output is redirected to the printer (BBC BASIC for Windows only).

Outputting text in *OUTPUT 15 mode has the side-effect of doing a VDU 3,6.

Syntax:

*OUTPUT num

*PLAY

(BBC BASIC for Windows only)
Plays the specified MIDI file, assuming a suitable sound card is fitted.
*PLAY midifile
OSCLI "PLAY """+midifile$+""""
Once a MIDI file is playing you cannot issue another *PLAY command until it has stopped (doing so will result in the Device unavailable error). However, you can cancel the current MIDI file using SOUND OFF.

You can discover whether a MIDI file is playing by using the @midi% System variable; this will be non-zero if a MIDI file is playing.

If the filename extension is omitted, .MID is assumed.

If you have a SoundBlaster™-compatible sound card, you can control the playback volume as follows:

SYS "auxSetVolume", 1, volume% + (volume% << 16)
where volume% is in the range 0 (minimum) to 65535 (maximum). Note that the volume change will affect all subsequent MIDI audio output.

Syntax:

*PLAY ufsp

*PRINTER

(BBC BASIC for Windows only)
Select the specified printer. Normally BBC BASIC uses the current default printer, but you can select a different printer using this command.
*PRINTER HP Laserjet Plus
OSCLI "PRINTER "+printer$
The printer name is case insensitive, but otherwise must be precise. If the specified printer does not exist the No such printer error will result.

Changing the printer initialises the page margins to zero, not to the default value of 10 millimetres. You should normally follow the *PRINTER command with a *MARGINS command to set the page margins appropriately.

An alternative way of changing the printer is to present the user with the Print Setup dialogue box which will allow him not only to select the printer but also the printer options (e.g. print quality), page orientation and paper size.

Syntax:

*PRINTER name

*PRINTERFONT

(BBC BASIC for Windows only)
Select the specified printer font (typeface) and size, and optionally select an emphasis style (bold, italic and/or underlined).
*PRINTERFONT Arial,16
*PRINTERFONT Courier New,20,U
*PRINTERFONT Letter Gothic,12,BI
If the *PRINTERFONT command is mistyped, or if the requested font is not installed, Windows™ will do its best to select a font similar to the one you requested. Unfortunately it doesn't always do this very well, and the result can be the selection of a 'symbols' font. If this happens, what is printed won't make much sense!

Changing the printer font initialises the page margins to zero. You may need to follow the *PRINTERFONT command with a *MARGINS command to reset the page margins appropriately.

Syntax:

*PRINTERFONT name,size[,style]

*QUIT

This command is synonymous with *BYE and the QUIT statement.

Syntax:

*QUIT

*REFRESH

By default the screen (BASIC's output window) is refreshed, i.e. updated, at times determined by the operating system. Typically if several things are being plotted in quick succession it will wait until all the changes have been made before refreshing the screen. This is normally perfectly satisfactory, but there may be special circumstances when you need to take control of when the refresh occurs.

For example if displaying an animated graphic you may need to force the display to update immediately, otherwise one or more frames of the animation may never be seen. Alternatively you may want to delay the refresh until an entire frame has been drawn, to reduce flicker. The options are as follows:

*REFRESHforces an immediate screen refresh.
*REFRESH OFFdisables the automatic refresh; the screen will only be updated as the result of a *REFRESH command.
*REFRESH ONrestores the normal behaviour.
In BBC BASIC for SDL 2.0 *REFRESH waits for vertical sync, i.e. it synchronises the refresh to the display frame rate. This can result in much smoother motion in animated scenes.

Syntax:

*REFRESH [ON|OFF]

*RENAME (*REN)

Rename a disk file. The syntax is similar to the REN command available at a Command Prompt, except that the extension defaults to .BBC if it is omitted. To specify a filename with no extension, add a final full-stop.
*REN OLDFILE NEWFILE
OSCLI "REN """+oldname$+""" """+newname$+""""
If a file already exists with the new name, a File exists error will occur.

(BBC BASIC for Windows only)
If the length of the command exceeds 254 characters a Bad name error will result. In that case you can use the Windows™ API instead (the extensions must be included explicitly):

SYS "MoveFile", oldname$, newname$

Syntax:

*REN ufsp ufsp
*RENAME ufsp ufsp

*RMDIR (*RD)

Remove (delete) the directory with the given name. The syntax is similar to the RMDIR command available at a Command Prompt:
*RD D:DATA
*RMDIR /BBCBASIC/TRIALS
OSCLI "RMDIR """+directory$+""""
You can only remove an empty directory. If the directory contains any files you will get an 'Access denied' error. If the directory doesn't exist, you will get a File or path not found error.

Syntax:

*RD [d:][/]path
*RMDIR [d:][/]path

*RUN

*/

Run the specified external shell command or executable program and return to BBC BASIC; care should be taken to ensure that the specified command is valid since an error may not necessarily be reported if not.

BBC BASIC will wait until the command completes, but if you terminate the command string with a semicolon (;) then it will not wait but will return immediately.

*ping 192.168.2.1
OSCLI "RUN " + command$

Syntax:

*RUN command [;]

*SAVE

*S.

Save an area of memory to a disk file. If the filename extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.

OSCLI "SAVE PROGFILE "+STR$~PAGE+" "+STR$~TOP
OSCLI "SAVE """+file$+""" "+STR$~start%%+" +"+STR$~length%
You must specify the start address and either the length of the area of memory (preceded by a +) or the first address not to save. There is no 'load address' or 'execute address'.

The start address must be given as a hexadecimal number. Since, in BBC BASIC for SDL 2.0, this may be a 64-bit number you should ensure that you have enabled *HEX 64 mode, and that you have used either a suffixless variable (e.g. addr) or a 64-bit numeric variable (e.g. addr%%).

Syntax:

*SAVE ufsp aaaaaaaa +llllllll
*SAVE ufsp aaaaaaaa bbbbbbbb

*SCREENSAVE

Save BASIC's output window (or part of it) as a standard bitmap (.BMP) file.
*SCREENSAVE screen.bmp xpos,ypos,width,height
OSCLI "SCREENSAVE """+file$+""" "+STR$xpos%+","+STR$ypos%+","+STR$width%+","+STR$height%
If no position or size is specified, the entire window is saved (so long as the graphics ORIGIN hasn't been changed). Otherwise the rectangle whose bottom-left corner is at xpos,ypos and whose size is width (horizontal) by height (vertical) is saved. The position and size are given in BASIC's graphics units.

You can, of course, copy BASIC's output window to the clipboard using Alt-PrintScreen.

To display an image saved with *SCREENSAVE see *DISPLAY and *MDISPLAY.

Syntax:

*SCREENSAVE ufsp [num,num,num,num]

*SPOOL

Copy all subsequent console output to the specified file. If the filename is omitted, any current spool file is closed and spooling is terminated. If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.
*SPOOL LISTING.TXT
OSCLI "SPOOL """+file$+""""
*SPOOL
See also *EXEC and *SPOOLON.

Syntax:

*SPOOL [ufsp]

*SPOOLON

Append all subsequent console output to the specified file. If the file does not exist, the File or path not found error will occur. If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.
*SPOOLON LISTING.TXT
OSCLI "SPOOLON """+file$+""""
You can use this command to add text to the end of a previously used spool file.

Syntax:

*SPOOLON ufsp

*STEREO

(BBC BASIC for SDL 2.0 only)
This command positions the output from a sound channel on the stereo stage. It takes two parameters, the SOUND channel number (0-3) and a value in the range -127 (corresponding to 'fully left') to +127 (corresponding to 'fully right'). A value of zero signifies 'centre stage'. In BBC BASIC for Windows an equivalent facility is available from the HQSOUND library.
*STEREO 2,-64
OSCLI "STEREO " + STR$chan% + "," + STR$pan%

Syntax:

*STEREO num,num

*SYS

This command controls what events result in an ON SYS (and, in the case of BBC BASIC for SDL 2.0, ON MOUSE) interrupt.

BBC BASIC for Windows:
By default only WM_COMMAND messages result in an ON SYS interrupt. *SYS 1 in addition enables interrupts from the WM_NOTIFY, WM_DROPFILES, WM_MENUSELECT, WM_INITMENU, WM_INITMENUPOPUP, WM_HOTKEY, WM_HELP and WM_CONTEXTMENU messages; refer to Microsoft documentation for details.

BBC BASIC for SDL 2.0:
By default ON SYS interrupts are not generated. *SYS 2 enables ON MOUSE interrupts from SDL_FINGERDOWN, SDL_FINGERUP and SDL_FINGERMOTION events. *SYS 4 enables ON SYS interrupts from SDL_MULTIGESTURE events.

The ON SYS handler must test the value of the @msg% system variable to determine which message was received, as follows:

Message@msg%
WM_NOTIFY78
WM_HELP83
WM_CONTEXTMENU123
WM_COMMAND273
WM_INITMENU278
WM_INITMENUPOPUP279
WM_MENUSELECT287
WM_DROPFILES563
WM_HOTKEY786
SDL_FINGERDOWN&700
SDL_FINGERUP&701
SDL_FINGERMOTION&702
SDL_MULTIGESTURE&802
*SYS is equivalent to *SYS 0; it restores the default condition of intercepting only WM_COMMAND.

The @wparam% value of the WM_NOTIFY message contains the control's ID in the LS 16-bits (LOWORD) and the notification code in the MS 16-bits (HIWORD). This makes it possible to determine the notification code even when the parameter block pointed to by @lparam% is no longer valid.

The @wparam% value of the WM_HELP message contains the context type in the LS 16-bits (LOWORD) and the control's ID in the MS 16-bits (HIWORD). This makes it possible to determine the control's ID even when the parameter block pointed to by @lparam% is no longer valid.

Syntax:

*SYS [num]

*TEMPO

Set the units of the duration parameter of the SOUND statement to the specified number of centiseconds (hundredths of a second). The default units are twentieths of a second (equivalent to *TEMPO 5) which is suitable for most purposes. If you are using SOUND to play music, selecting *TEMPO 4 will cause it to play more quickly and selecting *TEMPO 6 will cause it to play more slowly.

You can select a short unit, for example one centisecond, if you want finer control over the duration of sounds. This may be important if you are using SOUND for purposes other than music, for example to generate morse code. Selecting a shorter unit also reduces the latency (the time between executing the SOUND statement and the sound actually being produced). However it places greater demands on your PC and on some systems may cause the sound output to 'stutter'.

Note that the maximum duration of a single SOUND statement is 254 times the selected unit.

*TEMPO 4
By adding 128 to the *TEMPO value you can configure SOUND channel 0 to be a 'tone' channel rather than a 'noise' channel; this makes it possible to generate 'four voice' music:
*TEMPO 132
BBC BASIC for Windows v6.14a or later and BBC BASIC for SDL 2.0 only
By adding 64 to the *TEMPO value the 'pitch envelope auto-repeat' feature is configured to work in a way more compatible with the BBC Micro. This is also the default mode if no *TEMPO command is used:
*TEMPO 68

Syntax:

*TEMPO num

*TIMER

Set the periodicity of the ON TIME interrupt to the specified number of milliseconds; the smallest value you can specify is 10 ms (resulting in approximately 100 ON TIME interrupts per second).
*TIMER 200
Note that the timer period determines the flash rate of flashing characters in MODE 7. You are recommended not to change it when using that mode. The default periodicity (if no *TIMER command is issued) is 250 milliseconds (4 Hz).

Syntax:

*TIMER num

*TV

The *TV command is trapped and ignored.

Syntax:

*TV

*TYPE

*T.

Type the specified file to the screen. If the filename extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.

*TYPE modes.txt
OSCLI "TYPE """+file$+""""
You can use this command to display the contents of an ASCII file. You can pause the display either by holding down <Shift> and <Ctrl> simultaneously, or by first entering 'paged' mode by typing Ctrl/N (VDU 14). In 'paged' mode, the display pauses until <Shift> is pressed. To cancel 'paged' mode press Ctrl/O ( VDU 15).

To display a program saved in internal (tokenised) format use *LIST.

Syntax:

*TYPE ufsp

*UNLOCK

Set the specified file to 'read/write' status. If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop.
*UNLOCK ADDRESS.DTA
OSCLI "UNLOCK """+file$+""""
This command reverses the effect of *LOCK.

Syntax:

*UNLOCK ufsp

*VOICE

(BBC BASIC for SDL 2.0 only)
This command assigns a particular 'voice' or 'waveform' to a sound channel. It takes two parameters, the SOUND channel number (0-3) and a waveform number (0-7) which may be considered analogous to an organ 'stop'. In BBC BASIC for Windows an equivalent facility is available from the HQSOUND library.
*VOICE 3,3
OSCLI "VOICE " + STR$chan% + "," + STR$wave%
The available voices are as follows:

VoiceDescription
0Square wave
1Triangular wave
2'Gemshorn'
3'Lieblich Gedeckt'
4'Flute' (sine wave)
5'Salizional'
6'Viola da Gamba'
7'Dulciana'

Syntax:

*VOICE num,num

*|

This is a comment line. Anything following the '|' is ignored. The effect is similar to the REM statement, except that comments delimited by *| are retained in a compiled executable even if the Remove REMs crunch option is selected. Thus you should normally avoid using *| if you intend to 'compile' your program.

Syntax:

*| any text

Additional OS Interfaces

In addition to the facilities already described BBC BASIC provides a very limited emulation of the BBC Micro's OSBYTE and OSWORD functions.

Read current character - OSBYTE &87

The following program segment returns the ASCII code of the character at the current text cursor position and assigns it to a variable called 'char':
A% = &87
char = (USR(&FFF4) AND &FF00) DIV 256

Read character dot pattern - OSWORD &0A

The following program segment reads the dot pattern of a character:
DIM pattern 8
?pattern = character
A% = &0A
X% = pattern MOD 256 : Y% = pattern DIV 256
CALL &FFF1
The ASCII value is loaded into byte zero of the 9 byte table called 'pattern' and the pattern is returned in the 8 bytes 'pattern?1' to 'pattern?8'. As with the BBC Micro, the address of the table 'pattern' is passed in X% and Y%.

Note that the pattern is read from a built-in font which resembles that of the BBC Micro. It does not necessarily correspond to the actual font which is used when text is written to the screen by BASIC.

Read teletext character dot pattern - OSWORD &8B

(BBC BASIC for SDL 2.0 only)
The following program segment reads the dot pattern of a teletext (MODE 7) character:
DIM block 43
block?0 = 4
block?1 = 44
block?2 = character
A% = &8B
X% = block MOD 256 : Y% = block DIV 256
CALL &FFF1
The character dot-matrix (16x20) is read into the 40 bytes 'block?4' to 'block?43' inclusive.

Write teletext character dot pattern - OSWORD &8C

(BBC BASIC for SDL 2.0 only)
The following program segment writes the dot pattern of a teletext (MODE 7) character:
DIM block 43
block?0 = 44
block?1 = 4
block?2 = character
A% = &8C
X% = block MOD 256 : Y% = block DIV 256
CALL &FFF1
The character dot-matrix (16x20) is written from the 40 bytes 'block?4' to 'block?43' inclusive.

Assembler access to OS routines

Your x86 assembler programs may access the OSBGET, OSBPUT, OSRDCH, OSASCI, OSNEWL, OSWRCH, OSWORD, OSBYTE and OSCLI routines by name as shown below:
CALL "osbget" ; Read byte from file to AL, EBX contains channel number
CALL "osbput" ; Write byte from AL to file, EBX contains channel number
CALL "osrdch" ; Read keyboard character to AL
CALL "osasci" ; Write AL to the VDU drivers (plus LF if CR)
CALL "osnewl" ; Write LF,CR
CALL "oswrch" ; Write AL to the VDU drivers
CALL "osword" ; Read character dot pattern, EDX addresses buffer
CALL "osbyte" ; Read character at cursor position to AL
CALL "oscli"  ; Various OS commands, EDX addresses string
CALL "osline" ; Read a line from the console, EDX addresses buffer (DL=0)
CALL "osshut" ; Close a file, EBX = channel number
CALL "getptr" ; Read file pointer, EBX = channel number, result in EDX:EAX
CALL "setptr" ; Set file pointer, EBX = channel number, EDX:EAX = value
CALL "getext" ; Read file length, EBX = channel number, result in EDX:EAX
CALL "setext" ; Set file length, EBX = channel number, EDX:EAX = value
CALL "osopen" ; Open a file, EDX addresses filename, AL = 0 (read)
              ; 1 (create) or 2 (update), channel number returned in EAX
All strings are CR-terminated. In the case of 'oskey' the carry flag is cleared if no key was pressed within the timeout period. In the case of 'osbget' the carry flag is cleared if at end-of-file. In BBC BASIC for Windows v6.00a or later only the EDX register contains the most significant 32-bits of the file pointer/length.

Left CONTENTS

CONTINUE Right


Best viewed with Any Browser Valid HTML 3.2!
© Richard Russell 2021