Keywords MID\$ to PRINT

MID\$

A function which returns a part of a string starting at a specified position and with a given length. If there are insufficient characters in the string, or the length is not specified, then all the characters from the specified start position onwards are returned. MID\$ may also be used to the left of an equals sign to change part of a string whilst leaving the rest alone.
```C\$ = MID\$(A\$,start_posn,num)
C\$ = MID\$(A\$,Z)
MID\$(A\$,4,2) = B\$
```
You can use this function to select any part of a string. For instance, if
```name\$="BBC BASIC for Windows"
```
then
```part\$=MID\$(name\$,5,3)
```
would set part\$ to "BAS". If the third parameter is omitted or there are insufficient characters to the right of the specified position, MID\$ returns the right hand part of the string starting at the specified position. Thus,
```part\$=MID\$(name\$,15)
```
would set part\$ to "Windows".

For example,

```name\$="BBC BASIC for Windows"
FOR i=5 TO 15
PRINT MID\$(name\$,i,11)
NEXT
```
would print
```BASIC for W
ASIC for Wi
SIC for Win
IC for Wind
C for Windo
for Window
for Windows
or Windows
r Windows
Windows
Windows
```
When using MID\$ on the left of an equals sign, and the expression to the right of the equals sign evaluates to a string with fewer characters than the specified sub-string length, only that number of characters is changed. For example:
```A\$ = "BBC BASIC"
MID\$(A\$,5,4) = "ZZ"
```
will set A\$ equal to "BBC ZZSIC". Although the sub-string length is set to four, only two characters are actually modified since that is the length of the string "ZZ".

Syntax

```<s-var>=MID\$(<string>,<numeric>[,<numeric>])
MID\$(<s-var>,<numeric>[,<numeric>])=<string>
```

Associated Keywords

LEFT\$, RIGHT\$, LEN, INSTR

MOD

An operator returning the signed remainder after an integer division. The result is always an integer.
```X=A MOD B
```
MOD is defined such that,
```A MOD B = A - ( A DIV B ) * B.
```
If you are doing integer division (DIV) of whole numbers it is often desirable to know the remainder (a 'teach children to divide' program for instance). For example, 23 divided by 3 is 7, remainder 2. Thus,
```PRINT 23 DIV 3
PRINT 23 MOD 3
```
would print
```         7
2
```
You can use real numbers in these calculations, but they are truncated to their integer part before BBC BASIC calculates the result. Thus,
```PRINT 23.1 DIV 3.9
PRINT 23.1 MOD 3.9
```
would give exactly the same results as the previous example.

MOD can also be used as a function which operates on an entire numeric array. It returns the modulus (the square-root of the sum of the squares of all the elements) in the array. See the array arithmetic section.

Syntax

```<n-var>=<numeric> MOD <numeric>
<n-var>MOD=<numeric>
<n-var>=MOD(<array()>)
```

DIV

MO.

A statement to set the screen display mode. The screen (i.e. BASIC's output window) is cleared and all the graphics and text parameters (colours, origin, etc) are reset to their default values.

The following example sets the display to mode 3:

```MODE 3
```
BBC BASIC for Windows and BBC BASIC for SDL 2.0 start in a default display mode, with black text on a white background. When a MODE statement is executed the window dimensions are changed to those appropriate to that mode, with (initially) white text on a black background.

Available modes

The available display modes and the resolution of which they are capable are listed below. MODEs 0 to 7 are compatible with MODEs 0 to 7 on the BBC Micro (with some minor differences). No attempt has been made to emulate the screen modes of the Acorn Archimedes, other than MODEs 0 to 7.
Mode Text (chars)Graphics (pixels) Graphics unitsLogical Colours
0 80x32 640x512 1280x1024 2
1 40x32 640x512 1280x1024 4
2 20x32 640x512 1280x1024 16
3 80x25 640x500 1280x1000 16
4 40x32 640x512 1280x1024 2
5 20x32 640x512 1280x1024 4
6 40x25 640x500 1280x1000 16
7 40x25 teletext teletext 8
8 80x32 640x512 1280x1024 16
9 40x32 640x512 1280x1024 16
10 90x36 720x576 1440x1152 16
11 45x36 720x576 1440x1152 16
12 120x48 960x768 1920x1536 16
13 60x48 960x768 1920x1536 16
14 160x64 1280x1024 2560x2048 16
15 80x64 1280x1024 2560x2048 16
16 80x25 640x400 1280x800 16
17 40x25 640x400 1280x800 16
18 80x30 640x480 1280x960 16
19 40x30 640x480 1280x960 16
20 100x30 800x600 1600x1200 16
21 50x30 800x600 1600x1200 16
22 128x48 1024x768 2048x1536 16
23 64x48 1024x768 2048x1536 16
24 144x54 1152x864 2304x1728 16
25 72x54 1152x864 2304x1728 16
26 160x60 1280x960 2560x1920 16
27 80x60 1280x960 2560x1920 16
28 180x54 1440x1080 2880x2160 16
29 90x54 1440x1080 2880x2160 16
30 200x75 1600x1200 3200x2400 16
31 100x75 1600x1200 3200x2400 16
32 80x25 640x400 1280x800 2
33 40x25 640x400 1280x800 4
Graphics are available in all modes except MODE 7.

As well as these predefined modes you can also select a 'custom' mode with VDU 23,22.

MODE n is equivalent to VDU 22,n.

MODE can also be used as a function. It returns the current mode number (or −1 if no MODE statement has been executed, or a 'custom' mode is in use).

Syntax

```MODE <numeric>
<n-var> = MODE
```

CLS, CLG, VDU

MOUSE

A multi-purpose statement which controls, or returns information about, the mouse. The different variants of the statement are as follows:

MOUSE x,y,b

This returns the current position of the mouse pointer and the status of the mouse buttons; 'x', 'y' and 'b' are the names of numeric variables (which needn't have previously been defined). The variables 'x' and 'y' are set to the position of the mouse pointer in BBC BASIC graphics units, and are affected by the current graphics origin. The variable 'b' is set to a value between 0 and 7 depending on which mouse buttons are pressed: the value 1 indicates that the right button is pressed, 2 that the middle button (if any) is pressed and 4 that the left button is pressed. The values may be combined.

Important note: On some Operating Systems MOUSE works whether or not your program has the input focus. This can occasionally be useful, but often you will prefer to detect a mouse button being pressed only when the user is working with your program. In that case you can check for input focus. Alternatively you may find ON MOUSE better suited to your needs.

The state of the mouse buttons can also be tested using INKEY with the parameters −10 (left), −11 (middle) and −12 (right). The mouse wheel, if any, cannot be tested directly but rotation of the wheel causes characters 140 or 141 to be inserted into the keyboard buffer; these can be read using GET or INKEY in the usual way.

MOUSE ON n

This causes the mouse pointer to be displayed, and determines the shape of the pointer depending on the value of 'n'. The standard pointer shapes available are as follows:
Code  Shape
0
1
2
3
130
131
132
133
134
136
137
138
MOUSE ON is equivalent to MOUSE ON 0. Note that MOUSE ON 137 and MOUSE ON 138 may not work on all Operating Systems.

MOUSE OFF

This causes the mouse pointer to be hidden (whilst it is within BASIC's output window).

MOUSE TO x,y

This moves the mouse pointer to the specified coordinates, in BBC BASIC graphics units. Note that if you move the mouse pointer this may affect all open applications and the desktop, not just BBC BASIC.

Some Operating Systems, with some settings, may prohibit moving the mouse pointer in this way. This is because the mouse pointer is a shared resource and, on those systems, it is possible for the administrator to withhold privileges which could adversely affect other programs.

MOUSE RECTANGLE l,b,w,h

(BBC BASIC for Windows only)
This confines the mouse pointer to remain within the specified bounding rectangle, in BBC BASIC graphics units (left, bottom, width, height in that order). Note that if you confine the mouse pointer this will affect all open applications and the desktop, not just BBC BASIC. If you exit your program with the rectangle still set, you may find it impossible to move the mouse where you need to!

Because the mouse pointer is a shared resource, and confining it could adversely affect other programs, this statement only works if you have the appropriate administrative privileges.

MOUSE RECTANGLE OFF

This clears the bounding rectangle so that the mouse pointer is no longer confined.

MOUSE is also used in the ON MOUSE statement.

Syntax

```MOUSE <n-var>,<n-var>,<n-var>
MOUSE ON [<numeric>]
MOUSE OFF
MOUSE TO <n-var>,<n-var>
MOUSE RECTANGLE <n-var>,<n-var>,<n-var>,<n-var>
MOUSE RECTANGLE OFF
```

Associated Keywords

INKEY, ON, OFF, ON MOUSE

MOVE

A statement which moves the graphics cursor without drawing a line. MOVE is followed by the X and Y coordinates to which the cursor should be moved; the optional qualifier BY indicates that the coordinates are relative (offsets from the current graphics cursor position) rather than absolute. The coordinates must be in the range −32768 to +32767.

The graphics origin (X=0, Y=0) is normally the bottom left of the 'screen' (BASIC's output window). The origin can be changed using the ORIGIN statement or the VDU 29 command.

```MOVE X,Y
MOVE 124,327
```
MOVE x,y is equivalent to PLOT 4,x,y.
MOVE BY x,y is equivalent to PLOT 0,x,y.

MOVE is also used in the ON MOVE statement.

Syntax

```MOVE <numeric>,<numeric>
MOVE BY <numeric>,<numeric>
```

Associated Keywords

BY, DRAW, MODE, GCOL, PLOT, ON MOVE

N.

A statement delimiting a FOR...NEXT loop. NEXT takes an optional control variable.
```NEXT
NEXT J
```
If the control variable is present then FOR....NEXT loops may be 'popped' automatically in an attempt to match the correct FOR statement (this should not be necessary). If a matching FOR statement cannot be found, a 'Can't match FOR' error will be reported.

Leaving out the control variable will make the program run quicker, but this is not to be encouraged.

See the keyword FOR for more details about the structure of FOR....NEXT loops.

Syntax

```NEXT [<n-var>{,<n-var>}]
```

FOR, TO, STEP

NOT

A function returning the bitwise or logical inversion of its argument. The argument is converted to a 4-byte integer before the operation.
```A=NOT 3
flag=NOT flag
flag=NOT(A=B)
```
NOT is most commonly used in an IF....THEN....ELSE statement to reverse the effect of the test.
```IF NOT(rate>5 AND TIME<100) THEN .....
IF NOT flag THEN .....
```
BBC BASIC does not have true boolean variables; it makes do with numeric variables. This can lead to confusion because the testable condition in an IF....THEN....ELSE statement is evaluated numerically and can result in something other than −1 (TRUE) or 0 (FALSE).

If you wish to use NOT to reverse the action of an IF statement it is important to ensure that the testable condition does actually evaluate to either 0 (FALSE) or −1 (TRUE).

If the testable condition evaluates to 1, for example, the test will be considered to have succeeded and the THEN part of the IF....THEN....ELSE statement would be carried out. However, using NOT in front of the testable condition would not reverse the action. NOT 1 evaluates to −2, which would also be considered to be success.

Syntax

```<n-var>=NOT<numeric>
```

AND, EOR, OR

OF

A keyword which is part of the CASE... ENDCASE clause. OF follows the name of the CASE variable, and must be the last item on the program line (not even followed by a REMark).
```CASE die% OF
WHEN 1,2,3 : bet\$ = "lose"
WHEN 4,5,6 : bet\$ = "win"
OTHERWISE bet\$ = "cheat"
ENDCASE
```

Syntax

```CASE <var> OF
```

Associated Keywords

CASE, ENDCASE, OTHERWISE, WHEN

OFF

A statement which hides the text cursor (which is normally a flashing underscore). The cursor can be switched on again with ON. OFF is equivalent to VDU 23,1,0;0;0;0;.

OFF is also used in the MOUSE OFF, MOUSE RECTANGLE OFF, ON CLOSE OFF, ON ERROR OFF, ON MOUSE OFF, ON MOVE OFF, ON SYS OFF, ON TIME OFF and TRACE OFF statements.

```OFF
```

MOUSE, ON, TRACE

ON

A statement controlling a multi-way switch. The destinations in the list may be line numbers (constants or calculated), labels or procedures, and the 'unwanted' ones are skipped without calculation. The ON statement is used in conjunction with three other keywords: GOTO, GOSUB and PROC (ON CLOSE, ON ERROR, ON MOUSE, ON MOVE, ON SYS and ON TIME are explained separately).
```ON option GOTO 1000,2000,3000,4000
ON action GOSUB label1,label2,label3,label4
```
The ON statement alters the path through your program by transferring control to one of a selection of line numbers, labels or procedures depending on the value of a variable. For example,
```ON number GOTO 1000,2000,500,100
```
would send your program to line 1000 if 'number' was 1, to line 2000 if 'number' was 2, to line 500 if 'number' was 3 and to line 100 if 'number' was 4.

If 'number' was less than 1 or greater than 4 the ON range error would result. You can trap this condition by using the ELSE statement delimiter:

```ON action GOTO 100,300,120 ELSE PRINT"Illegal"
```
If there is no statement after the ELSE, the program will 'drop through' to the following line if an exception occurs. In the following example, the program would drop through to the error handling part of the program if 'B−46' was less than one or more than 3.
```ON B-46 GOTO 100,200,(C/200) ELSE
PRINT "Illegal choice - try again"
```
You can use ON...GOTO, ON...GOSUB, and ON...PROC to execute the appropriate part of your program as the result of a menu selection. The following skeleton example offers a menu with three choices.
```CLS
PRINT "Select the action you wish to take:"
PRINT "1 Open a new data file"
PRINT "2 Add data to the file"
PRINT "3 Close the file and end"''
REPEAT
UNTIL choice>0 AND choice<4
.....etc
```

Enabling the text cursor

ON can also be used on its own to enable the text cursor (caret). ON is equivalent to VDU 23,1,1;0;0;0;.

Syntax

```ON <numeric> GOTO <l-num>{,<l-num>}
[ELSE <stmt>{:<stmt>}]
ON <numeric> GOSUB <l-num>{,<l-num>}
[ELSE <stmt>{:<stmt>}]
ON <numeric> PROC<name>[(<exp>{,<exp>})]
{,PROC<name>[(<exp>{,<exp>})]}
[ELSE <stmt>{:<stmt>}]
ON
```

Associated Keywords

ON CLOSE, ON ERROR, ON MOUSE, ON MOVE, ON SYS, ON TIME, ON ERROR LOCAL, GOTO, GOSUB, PROC

ON CLOSE

A statement which allows you to 'trap' the window being closed by the user. Normally, the window can be closed by clicking on the close button in the top right-hand corner or by pressing Alt-F4. However, in some circumstances it may be desirable to prevent the user doing this (for example, you may wish to prompt him to save some data first).

Once ON CLOSE has been executed, any attempt to close the window (other than by QUIT) will cause control to be transferred to the statement following ON CLOSE. The current program pointer will be saved on the stack, so that you can resume execution from where it left off using RETURN. In this respect, attempting to close the window acts as a sort of 'interrupt' to the BASIC program.

For example, the following program segment asks the user to confirm whether he or she really wants to quit:

```ON CLOSE PROCclose : RETURN
REPEAT
REM Do something useful here!
UNTIL FALSE
;
DEF PROCclose : LOCAL ans\$
REPEAT UNTIL INKEY(0) = -1
INPUT '"Do you really want to exit",ans\$
IF LEFT\$(ans\$,1) = "y" OR LEFT\$(ans\$,1) = "Y" THEN QUIT
ENDPROC
```
Note that the ON CLOSE 'interrupt' can only take place in between the execution of one BASIC statement and the next. If BBC BASIC is waiting in an INKEY, INPUT, GET, SOUND or WAIT statement, then the ON CLOSE procedure will not be called until the current statement has completed. If appropriate you can use the replacement routines in the NOWAIT library.

Be careful not to change anything within the ON CLOSE processing which could affect the operation of the rest of the program if the user chooses to continue. For example, PROCclose above ought really to save the current text cursor position and restore it before returning, and to ensure that the prompt and the user's response do not upset the display. See the notes on the use of interrupts for more details.

If you simply wish to disable the close button (and Alt-F4) you can use:

```ON CLOSE RETURN
```
Trapping the close operation can be cancelled using ON CLOSE OFF, although it is possible for a queued event to be processed by a previous ON CLOSE procedure even after the ON CLOSE OFF statement has been executed. Note that returning to immediate mode automatically cancels event trapping.

ON CLOSE LOCAL can be used inside a function or procedure. It has the same effect as ON CLOSE except that trapping set up by a previous ON CLOSE (if any) is saved, and restored on exit from the function or procedure.

Syntax

```ON CLOSE [LOCAL] <stmt>{:<stmt>}:RETURN
ON CLOSE [LOCAL] OFF
```

Associated Keywords

LOCAL, ON MOUSE, ON MOVE, ON SYS, ON TIME, RETURN, PROC

ON ERROR

A statement controlling error trapping. If an ON ERROR statement has been encountered, BBC BASIC will transfer control to it (without taking any reporting action) when an error is detected. This allows error reporting/recovery to be controlled by the program. However, the program control stack is still cleared when the error is detected and it is not possible to RETURN to the point where the error occurred.

ON ERROR OFF returns the control of error handling to BBC BASIC.

```ON ERROR PRINT"Suicide":END
ON ERROR GOTO 100
ON ERROR OFF
```
Error handling is explained more fully in the General Information section.

Syntax

```ON ERROR <stmt>{:<stmt>}
ON ERROR OFF
```

Associated Keywords

ON, ON ERROR LOCAL, GOTO, GOSUB, PROC

ON ERROR LOCAL

A statement controlling error trapping. If an ON ERROR LOCAL statement has been encountered, BBC BASIC will transfer control to it (without taking any reporting action) when an error is detected. This allows error reporting/recovery to be controlled by the program.

Unlike the ON ERROR statement, ON ERROR LOCAL prevents BBC BASIC clearing the program stack. By using this statement, you can trap errors within a FOR ... NEXT, REPEAT ... UNTIL or WHILE ... ENDWHILE, loop or a subroutine, function or procedure without BBC BASIC losing its place within the program structure.

ON ERROR OFF returns the control of error handling to BBC BASIC.

```ON ERROR LOCAL PRINT"Suicide":END
ON ERROR LOCAL ENDPROC
ON ERROR OFF
```
The following example program will continue after the inevitable 'Division by zero' error.
```FOR n=-5 TO 5
ok% = TRUE
ON ERROR LOCAL PRINT "Infinity" : ok% = FALSE
IF ok% PRINT "The reciprocal of ";n;" is ";1/n
NEXT n
```
If ON ERROR LOCAL is used within a procedure, function, or loop structure then the previous error-trapping status (which might be an earlier ON ERROR LOCAL) is automatically restored on exit from the structure. However, ON ERROR LOCAL can be used anywhere within a BBC BASIC program, not just in these structures. In this case you must explicitly restore the previous error-trapping status using RESTORE ERROR.

Error handling is explained more fully in the General Information section.

ON ERROR LOCAL OFF temporarily disables error trapping; the default error reporting mechanism will be used until the previous error-trapping status is restored.

Syntax

```ON ERROR LOCAL <stmt>{:<stmt>}
ON ERROR LOCAL OFF
ON ERROR OFF
```

Associated Keywords

ON, ON ERROR, GOTO, GOSUB, PROC, RESTORE

ON MOUSE

A statement which allows you to 'trap' the pressing of a mouse button. Although you can 'poll' the state of the mouse buttons using INKEY or MOUSE, it is sometimes more convenient if the pressing of a button causes an event which will 'interrupt' the program.

If the ON MOUSE statement has been executed, pressing any of the three mouse buttons will cause a transfer of control to the statement after ON MOUSE. The current program pointer will be saved on the stack, so that you can resume execution from where it left off using RETURN.

Once the interrupt has occurred, you can test which button(s) are pressed by examining the @wparam% system variable. Its value depends on the button(s) pressed as follows:

Button/keyValue
Left button1
Right button2
SHIFT key4
CTRL key8
Middle button16
(the values may be combined).

The position of the mouse pointer when the button was pressed can be discovered from the value of @lparam% as follows:

```xpos% = @lparam% AND &FFFF
ypos% = @lparam% >>> 16
```
The coordinates are returned in pixels from the top left-hand corner of the window. If you need the coordinates in BBC BASIC graphics units then use the following code:
```xpos% = (@lparam% AND &FFFF)*2 - @vdu.o.x%
ypos% = (@vdu%!212-1-(@lparam% >>> 16))*2 - @vdu.o.y%
```
You should use the values of @wparam% and/or @lparam% in the statement immediately following ON MOUSE (e.g. by making them parameters of a procedure call), otherwise they might have changed as the result of a subsequent interrupt:
```ON MOUSE PROCmouse(@wparam%,@lparam%) : RETURN
```
Note that the ON MOUSE 'interrupt' can only take place in between the execution of one BASIC statement and the next. If BBC BASIC is waiting in an INKEY, INPUT, GET, SOUND or WAIT statement, then the ON MOUSE procedure will not be called until the current statement has completed. If appropriate you can use the replacement routines in the NOWAIT library.

Be careful not to change anything within the ON MOUSE processing which could affect the operation of the rest of the program. See the notes on the use of interrupts for more details.

ON MOUSE OFF causes mouse-button events to be ignored, although it is possible for one or more queued events to be processed by a previous ON MOUSE procedure even after the ON MOUSE OFF statement has been executed. Note that returning to immediate mode automatically cancels event trapping.

ON MOUSE LOCAL can be used inside a function or procedure. It has the same effect as ON MOUSE except that trapping set up by a previous ON MOUSE (if any) is saved, and restored on exit from the function or procedure.

Syntax

```ON MOUSE [LOCAL] <stmt>{:<stmt>}:RETURN
ON MOUSE [LOCAL] OFF
```

Associated Keywords

ON CLOSE, ON MOVE, ON SYS, ON TIME, RETURN, MOUSE, PROC

ON MOVE

A statement which allows you to 'trap' manual moving or resizing of BASIC's output window. When a MODE statement is executed, the output window is set to a size dependent on the specified MODE. However, there is nothing to stop the user re-sizing the window, for example by dragging the corner to a different position. ON MOVE causes the BASIC program to be alerted to this change.

If the ON MOVE statement has been executed, moving or re-sizing the window will cause a transfer of control to the statement after ON MOVE. The current program pointer will be saved on the stack, so that you can resume execution from where it left off using RETURN.

Once the interrupt has occurred, you can take any action necessary to deal with the change in window size. For example, by issuing a VDU 26 command you can reset BASIC's text and graphics viewports to the new size:

```ON MOVE VDU 26 : RETURN
```
If you need to distinguish between moving or re-sizing the window you can examine the value of the @msg% system variable. This will have the value 3 for a move and 5 for a re-size. ON MOVE also lets you intercept scroll messages if a scroll bar has been created. In this case @msg% will have the value &114 for a horizontal scroll message and &115 for a vertical scroll message.

Following a change in the window size you might want to know what the new size actually is. Once you have checked that @msg% is 5 (signifying a re-size) you can discover the new size (in pixels) as follows:

```Width% = @lparam% AND &FFFF
Height% = @lparam% >>> 16
```
You should use the values of @msg% and @lparam%, as required, in the statement immediately following ON MOVE (e.g. by making them parameters of a procedure call), otherwise they might have changed as the result of a subsequent interrupt:
```ON MOVE PROCmove(@msg%,@lparam%) : RETURN
......
DEF PROCmove(M%,L%)
IF M%=5 Width%=L% AND &FFFF : Height%=L% >>> 16
ENDPROC
```
Note that the ON MOVE 'interrupt' can only take place in between the execution of one BASIC statement and the next. If BBC BASIC is waiting in an INKEY, INPUT, GET, SOUND or WAIT statement, then the ON MOVE procedure will not be called until the current statement has completed. If appropriate you can use the replacement routines in the NOWAIT library.

Be careful not to change anything within the ON MOVE processing which could affect the operation of the rest of the program. See the notes on the use of interrupts for more details.

ON MOVE OFF causes window-resizing or moving events to be ignored, although it is possible for one or more queued events to be processed by a previous ON MOVE procedure even after the ON MOVE OFF statement has been executed. Note that returning to immediate mode automatically cancels event trapping.

ON MOVE LOCAL can be used inside a function or procedure. It has the same effect as ON MOVE except that trapping set up by a previous ON MOVE (if any) is saved, and restored on exit from the function or procedure.

Syntax

```ON MOVE [LOCAL] <stmt>{:<stmt>}:RETURN
ON MOVE [LOCAL] OFF
```

Associated Keywords

ON CLOSE, ON MOUSE, ON SYS, ON TIME, RETURN, PROC

ON SYS

A statement which allows you to react to an Operating System event, not handled by the other ON interrupts. For example this may be clicking on a menu (in BBC BASIC for Windows) or a touch gesture (in BBC BASIC for SDL 2.0).

When the interrupt occurs, the WPARAM and LPARAM values associated with the event can be recovered from the system variables @wparam% and @lparam%. These should be immediately passed as parameters to a procedure or function call, to ensure that they are copied to conventional variables before another interrupt can occur:

```ON SYS PROCmenu(@wparam%,@lparam%) : RETURN
```
Note that the ON SYS 'interrupt' can only take place in between the execution of one BASIC statement and the next. If BBC BASIC is waiting in an INKEY, INPUT, GET, SOUND or WAIT statement, then the ON SYS procedure will not be called until the current statement has completed. If appropriate you can use the replacement routines in the NOWAIT library.

Be careful not to change anything within the ON SYS processing which could affect the operation of the rest of the program. See the notes on the use of interrupts for more details.

ON SYS OFF causes menu events to be ignored, although it is possible for one or more queued events to be processed by a previous ON SYS procedure even after the ON SYS OFF statement has been executed. Note that returning to immediate mode automatically cancels event trapping.

ON SYS LOCAL can be used inside a function or procedure. It has the same effect as ON SYS except that trapping set up by a previous ON SYS (if any) is saved, and restored on exit from the function or procedure.

Control over what events are intercepted by ON SYS is provided by the *SYS command.

Syntax

```ON SYS [LOCAL] <stmt>{:<stmt>}:RETURN
ON SYS [LOCAL] OFF
```

Associated Keywords

ON CLOSE, ON MOUSE, ON MOVE, ON TIME, RETURN, PROC

ON TIME

A statement which allows you to generate a periodic 'timer interrupt'. If the ON TIME statement has been executed, control will be transferred to the statement after ON TIME approximately four times every second (to change the rate see below). The current program pointer will be saved on the stack, so that you can resume execution from where it left off using RETURN.

ON TIME allows you to perform a 'background task' without the complication of having to 'poll' the timer from (potentially) many different points in your program. If necessary you can have more than one timer, either using the code listed below or by means of the TIMERLIB library.

Note that the ON TIME 'interrupt' can only take place in between the execution of one BASIC statement and the next. If BBC BASIC is waiting in an INKEY, INPUT, GET, SOUND or WAIT statement, then the ON TIME procedure will not be called until the current statement has completed. If appropriate you can use the replacement routines in the NOWAIT library.

Be careful not to change anything within the ON TIME processing which could affect the operation of the rest of the program. See the notes on the use of interrupts for more details.

ON TIME OFF causes timer interrupt events to be cancelled, although it is possible for one or more queued events to be processed by a previous ON TIME procedure even after the ON TIME OFF statement has been executed. Note that returning to immediate mode automatically cancels event trapping.

ON TIME LOCAL can be used inside a function or procedure. It has the same effect as ON TIME except that trapping set up by a previous ON TIME (if any) is saved, and restored on exit from the function or procedure.

Syntax

```ON TIME [LOCAL] <stmt>{:<stmt>}:RETURN
ON TIME [LOCAL] OFF
```

Associated Keywords

ON CLOSE, ON MOUSE, ON MOVE, ON SYS, RETURN, PROC

Changing the timer period

You can change the periodicity of the ON TIME interrupt using the *TIMER command:
```OSCLI "TIMER " + STR\$(period%)
```
where period% is the required timer period in milliseconds. Don't expect the rate to be very accurate, and note that the shortest period you can use is 10 ms. If you need a faster timer you may be able to utilise the TIMERLIB library.

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.

You can create additional timers using the TIMERLIB library.

Notes on the use of interrupts

The statements ON CLOSE, ON MOUSE, ON MOVE, ON SYS and ON TIME all have the effect of interrupting your program when the associated event occurs. Special care needs to be taken if unwanted side-effects are not to occur as a result.

The problem with interrupts is that they occur at unpredictable times, therefore the part of your program being executed at the time is also unpredictable. If this part of your program can be affected by some change made by the interrupt service routine, the result may be a malfunction. Since only a small part of your program may be affected in this way, it will fail only rarely and in an apparently random fashion. Such faults are very hard to trace.

Ideally the interrupt service routine should be arranged to have no effects on the rest of the program. The following techniques can be valuable in achieving this:

• Any 'private' variables used by the routine should be declared as LOCAL or PRIVATE, and where possible any other system parameters modified by the routine should be saved on entry and restored on exit.

• If the routine uses or alters the value of a global variable, but that same variable is declared as LOCAL or PRIVATE (or is used as a formal parameter) in a function or procedure, then a problem will arise if the interrupt occurs during execution of the function or procedure. In that case the local variable will be accessed instead of the global variable. To avoid this, ensure that any global variables used by interrupt routines are never declared as LOCAL or PRIVATE (or used as formal parameters of a procedure or function) anywhere in your program or libraries that it uses. The use of a strict naming convention (e.g. local variables being in lower-case and global variables starting with a capital letter) can be very helpful.

• If the routine outputs text you can save and restore the text cursor position as follows:
```DEF PROCinterrupt
LOCAL X%,Y%
X%=POS : Y%=VPOS
REM. Output some text here
PRINT TAB(X%,Y%);
ENDPROC
```

• If the routine performs a graphics operation you can save and restore the current 'VDU state' as follows:
```DEF PROCinterrupt
LOCAL vdusave{}
DIM vdusave{} = @vdu{}
vdusave{} = @vdu{}
REM. Output some text or graphics here
@vdu{} = vdusave{}
ENDPROC
```
If you don't do this the interrupt may adversely affect text or graphics output from the rest of the program. For example, when plotting a triangle, PLOT 85 takes the previous two points 'visited' as vertices of the triangle, and any interrupt which moves the graphics pointer in between will cause the triangle to be incorrectly plotted.

Beware of changing the current font and/or graphics viewport whilst the VDU state has been saved; special precautions are necessary in such cases.

If there is a danger that your interrupt service routine could be called re-entrantly, that is a second or subsequent interrupt occurs before the previous one has been completely processed, you must either write your code to be tolerant of that possibility or add a semaphore to cause the re-entrant interrupts to be ignored (if that is acceptable):

```DEF PROCserviceroutine(parameters)
PRIVATE semaphore%
IF semaphore% THEN ENDPROC
semaphore% = TRUE
REM. Do the interrupt processing here
semaphore% = FALSE
ENDPROC
```
The likelihood of re-entrant calls is greatly increased if your program performs any operations which can stall interrupts (for example a WAIT statement with a non-zero parameter). To minimise this possibility you can use the replacement functions in the NOWAIT library.

In general you should try to do as little as possible in the interrupt service routine, to minimise the chance of side-effects. Setting a flag within the interrupt routine, and performing the necessary action within your main code when the flag is found to be set, is generally preferable to performing the action within the interrupt routine itself. Ideally you should test and reset the interrupt flag within one non-interruptible unit, which can be done using the SWAP statement:

```interrupt_flag% = FALSE
......
ON TIME interrupt_flag% = TRUE : RETURN
......
REM. within polling loop:
temp% = FALSE
SWAP interrupt_flag%,temp%
IF temp% PROC_take_action
```
The SWAP statement both resets the interrupt flag and copies its previous value into temp% so it can be tested at leisure. If you need to know not only that the interrupt occurred, but also the associated @msg%, @wparam% and/or @lparam% values, you can extend the principle by using an array rather than a boolean flag:
```DIM click%(2), temp%(2)
......
ON SYS click%() = @msg%,@wparam%,@lparam% : RETURN
......
REM. within polling loop:
temp%() = FALSE
SWAP click%(),temp%()
IF temp%(0) PROC_click(temp%(0),temp%(1),temp%(2))
```
The SWAP both zeroes click%() and copies the old data into temp%(), so there is no danger of the data from two interrupts being mixed up. If you can guarantee to poll sufficiently often, this technique can eliminate many of the troublesome aspects of dealing with interrupts.

The LOCAL forms of event trapping (ON CLOSE LOCAL, ON MOUSE LOCAL, ON MOVE LOCAL, ON SYS LOCAL and ON TIME LOCAL) need special care. Because of the way events are queued it is possible that an event has occurred but has not yet been processed when the ON <event> LOCAL statement is executed. In that case the event may be processed by the previous ON <event> statement, if any. Similarly, a queued event may be processed by the ON <event> LOCAL statement even after the function or procedure in which it is contained has been exited. You should write your interrupt service routines to be tolerant of these possibilities.

OP.

A function which opens a file for reading and returns the 'channel number' of the file. This number must be used in subsequent references to the file with BGET#, INPUT#, EXT#, PTR#, EOF#, CLOSE# or GET\$#.

If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop. A returned value of zero signifies that the specified file was not found on the disk, or could not be opened for some other reason.

OPENIN may also be used to open a channel from an input device, such as COM1 (the first serial port) or COM2 (the second serial port). See the section Serial I/O for details.

```X=OPENIN "jim"
X=OPENIN A\$
X=OPENIN (A\$)
X=OPENIN ("FILE1")
```
The example below reads data from disk into an array. If the data file does not exist, an error message is printed and the program ends.
```DIM posn(10),name\$(10)
fnum=OPENIN(@usr\$+"TOPTEN.DAT")
IF fnum=0 THEN PRINT "No TOPTEN data": END
FOR i=1 TO 10
INPUT#fnum,posn(i),name\$(i)
NEXT
CLOSE#fnum
```
(BBC BASIC for Windows only)
If the supplied filename is an empty string, or contains a wildcard (? or *) character anywhere, an Open File dialogue box is displayed.

Syntax

```<n-var>=OPENIN(<string>)
```

Associated Keywords

OPENOUT, OPENUP, CLOSE#, PTR#, PRINT#, INPUT#, READ#, BGET#, BPUT#, EOF#, GET\$#

OPENOUT

A function which opens a file for writing and returns the 'channel number' of the file. This number must be used in subsequent references to the file with BPUT#, PRINT#, EXT#, PTR# or CLOSE#. If the specified file does not exist it is created. If the specified file already exists it is truncated to zero length and all the data in the file is lost.

If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop. A returned value of zero indicates that the specified file could not be created.

OPENOUT may also be used to open a channel to an output device, such as COM1 (the first serial port) or COM2 (the second serial port). See the section Serial I/O for details.

```X=OPENOUT(A\$)
X=OPENOUT("DATAFILE")
```
You can also read from a file which has been opened using OPENOUT. This is of little use until you have written some data to it. However, once you have done so, you can move around the file using PTR# and read back previously written data.

Data is not written to the file at the time it is opened. Consequently, it is possible to successfully open a file on a full disk. Under these circumstances, a 'Disk full' error would be reported when you tried to write data to the file for the first time.

The example below writes the contents of two arrays (tables) to a file called 'TOPTEN.DAT'.

```A=OPENOUT(@usr\$+"TOPTEN.DAT")
FOR Z=1 TO 10
PRINT#A,N(Z),N\$(Z)
NEXT
CLOSE#A
END
```
(BBC BASIC for Windows only)
If the supplied filename is an empty string, or contains a wildcard (? or *) character anywhere, an Open File dialogue box is displayed.

Syntax

```<n-var>=OPENOUT(<string>)
```

Associated Keywords

OPENIN, OPENUP, CLOSE#, PTR#, PRINT#, INPUT#, BGET#, BPUT#, EOF#

OPENUP

A function which opens a disk data file for update (reading and writing) and returns the 'channel number' of the file. This number must be used in subsequent references to the file with BGET#, BPUT#, INPUT#, PRINT#, EXT#, PTR#, EOF#, CLOSE# or GET\$#.

If the extension is omitted, .BBC is assumed. To specify a filename with no extension, add a final full-stop. A returned value of zero signifies that the specified file was not found on the disk, or could not be opened for some other reason.

```X=OPENUP "jim"
X=OPENUP A\$
X=OPENUP (A\$)
X=OPENUP ("FILE1")
```
See the random file examples in the Disk files section for examples of the use of OPENUP.

OPENUP is also used to open a communications port (e.g. a serial port) for access. See the Serial I/O section for details.

(BBC BASIC for Windows only)
If the supplied filename is an empty string, or contains a wildcard (? or *) character anywhere, an Open File dialogue box is displayed.

Syntax

```<n-var>=OPENUP(<string>)
```

Associated Keywords

OPENIN, OPENOUT, CLOSE#, PTR#, PRINT#, INPUT#, READ#, BGET#, BPUT#, EOF#, GET\$#

OPT

An assembler pseudo operation controlling the method of assembly (see the Assembler section for more details). OPT is followed by a numeric value with the following meanings:
OPT valueLimit checkCode stored at Errors reportedListing generated
0NoP% NoNo
1NoP% NoYes
2NoP% YesNo
3NoP% YesYes
4NoO% NoNo
5NoO% NoYes
6NoO% YesNo
7NoO% YesYes
8YesP% NoNo
9YesP% NoYes
10YesP% YesNo
11YesP% YesYes
12YesO% NoNo
13YesO% NoYes
14YesO% YesNo
15YesO% YesYes

Syntax

```OPT <numeric>
```

None

OR

An operator returning the bitwise or logical OR between two items. The two operands are internally converted to 4 byte integers before the OR operation. For each of the 32 bits OR uses the following truth-table:
Input AInput BOutput
000
011
101
111
You can use OR as a logical operator or as a 'bit-by-bit' (bitwise) operator. The operands can be boolean (logical) or numeric.
```IF A=2 OR B=3 THEN 110
X=B OR 4
```
BBC BASIC does not have true boolean variables; this can lead to confusion at times (see NOT for more details).

In the example below, the operands are boolean (logical). In other words, the result of the tests (IF) A=2 and (IF) B=3 is either TRUE or FALSE. The result of this example will be TRUE if A=2 or B=3.

```answer=(A=2 OR B=3)
```
The brackets are not necessary, they have been included to make the example easier to follow.

The last example, uses the OR in a similar fashion to the numeric operators (+, −, etc).

Suppose X was −20 in the following example,

```A=X OR 11
```
the OR operation would be:
```11111111 11111111 11111111 11101100
00000000 00000000 00000000 00001011
11111111 11111111 11111111 11101111  = -17
```

Syntax

```<n-var>=<numeric> OR <numeric>
<n-var>OR=<numeric>
```

AND, EOR, NOT

ORIGIN

A statement which sets the graphics origin. ORIGIN is followed by the X and Y coordinates of the new origin; subsequent graphics commands operate with respect to these coordinates. The coordinates must be in the range −32768 to +32767.

The graphics origin is reset to the bottom left-hand corner of the 'screen' (BASIC's output window) by a MODE statement or a VDU 26 command.

ORIGIN x,y is equivalent to VDU 29,x;y;

```ORIGIN 640,512
```

Syntax

```ORIGIN <numeric>,<numeric>
```

MODE, PLOT, VDU

OSCLI

A statement which allows a string expression to be interpreted as an 'operating system' command. It overcomes problems caused by the fact that 'star' commands cannot include variables. Using this statement, you can, for instance, erase and rename files whose names you only know at run-time.
```command\$="DEL PHONE.DTA"
OSCLI command\$

OSCLI command\$
```
OSCLI can issue both resident operating system commands and external commands. See the Operating System interface section for more details.

Syntax

```OSCLI <string>
```

None.

OTHERWISE

A keyword which is an optional part of the CASE ... ENDCASE clause. OTHERWISE precedes the statement(s) which should be executed if the CASE variable matches none of the values specified in a WHEN statement. OTHERWISE must be the first item on the program line.
```CASE die% OF
WHEN 1,2,3 : bet\$ = "lose"
WHEN 4,5,6 : bet\$ = "win"
OTHERWISE bet\$ = "cheat"
ENDCASE
```

Syntax

```OTHERWISE [<stmt>]{:<stmt>}
```

Associated Keywords

CASE, ENDCASE, OF, WHEN

PA.

A pseudo-variable controlling the starting address of the current BASIC program. When you CHAIN a program it is stored in memory at an address equal to the value of PAGE.
```PAGE = PAGE + &1000
PRINT ~PAGE
```
PAGE is automatically initialised by BBC BASIC to the lowest available address. Normally PAGE should be treated as a read-only variable; you can change PAGE, but if you make it less than its initial value or greater than the value of HIMEM (less a safety margin of at least a kilobyte), you are almost certain to crash BASIC. If this happens you will lose all your unsaved work.

With care, several programs can be left around in RAM, at different values of PAGE, without the need for saving them. However you are strongly advised not to try this!

Syntax

```PAGE=<numeric>
<n-var>=PAGE
```

Associated Keywords

TOP, LOMEM, HIMEM

PI

A function returning the ratio of a circle's circumference to its diameter, approximately 3.14159265.
```X=PI
```
You can use PI to calculate the circumference and area of a circle. The example below calculates the circumference and area of a circle of a given radius.
```CLS
END
```
PI can also be used to convert degrees to radians and radians to degrees.
```radians=PI/180*degrees
```
However, BBC BASIC has two functions (RAD and DEG) which perform these conversions to a higher accuracy.

Syntax

```<n-var>=PI
```

PL.

A multi-purpose drawing statement. Three numeric values follow the PLOT keyword: the first specifies the type of point, line, triangle, circle etc. to be drawn; the second and third give the X and Y coordinates to be used (in that order). The coordinates must be in the range −32768 to +32767.
```PLOT Mode,X,Y
```
The graphics origin (X=0, Y=0) is normally the bottom left of the 'screen' (BASIC's output window). The origin can be changed using the ORIGIN statement or the VDU 29 command.

The two most commonly used examples, PLOT 4 and PLOT 5, have the duplicate keywords MOVE and DRAW.

PLOT X,Y is synonymous with PLOT 69,X,Y
PLOT BY X,Y is synonymous with PLOT 65,X,Y
.

See the Plotting modes section for full details of the different PLOT commands.

Syntax

```PLOT <numeric>,<numeric>,<numeric>
PLOT <numeric>,<numeric>
PLOT BY <numeric>,<numeric>
```

Associated Keywords

BY, CIRCLE, CLG, DRAW, ELLIPSE, FILL, GCOL, MODE, MOVE, ORIGIN, POINT, RECTANGLE, VDU

POINT

A function which returns a number giving the logical colour of the screen at the coordinates specified. If the point is outside the graphics viewport, then −1 is returned.

There must not be a space between POINT and the opening bracket.

```colour=POINT(X,Y)
IF POINT(X,Y)=3 THEN 300
```
You can use POINT to find out the colour of the screen at the specified point and take action accordingly. In an adventure game, for example, the swamps may be marked in green. If the explorer ventured into a green area he must be in the swamp and 'swamp type demons' would be activated.

Beware that when your display is set to a 'true colour' mode (usually 32768 colours or more) POINT may not always produce the result you expect. Suppose you have set two or more logical colours to correspond to the same physical colour. You may know which logical colour you used to plot at a certain point, but BASIC only knows the physical colour. The value returned by POINT will depend upon which matching logical colour is found in the palette first. This problem doesn't arise with a 'paletted' display (usually 256 colours or fewer).

You can use TINT rather than POINT; this returns the physical (RGB) colour rather than the logical colour. Beware that in BBC BASIC for SDL 2.0 POINT and TINT are very slow.

Syntax

```<n-var>=POINT(<numeric>,<numeric>)
```

Associated Keywords

PLOT, DRAW, MOVE, GCOL, TINT

POS

A function returning the column number containing the text cursor (caret). POS returns the position of the cursor with respect to the text viewport. Column 0 is usually on the left, but this may be changed using VDU 23,16.
```X=POS
```
The difference between POS and COUNT is that POS always returns the true column number of the text cursor whereas COUNT returns the number of 'printing' characters output since the last carriage-return. These will often be the same, but may differ if direct cursor addressing (TAB(X,Y)) has been used, or if the cursor has 'wrapped around' at the end of the line.

See VPOS for an example of the use of POS and VPOS.

Syntax

```<n-var>=POS
```

COUNT, TAB, VPOS

P.

A statement which prints characters to the screen or printer (see the hardcopy output to a printer section for details).

The items following PRINT are called the print list. The print list may contain a sequence of string or numeric literals, variables and formatting instructions. The spacing between the items printed will vary depending on the punctuation used. If the print list does not end with a semi-colon, a new-line will be printed after all the items in the print list.

The 'screen' (BASIC's output window) is divided into zones (initially) 10 characters wide. By default, numeric quantities are printed right justified in the print zone and strings are printed just as they are (with no leading spaces). Numeric quantities can be printed left justified by preceding them with a semi-colon. In the examples the zone width is indicated as z10, z4 etc.

```                    z10
012345678901234567890123456789
PRINT 23.162        ,,,,23.162
PRINT "HELLO"       HELLO
PRINT ;23.162       23.162
```
Initially numeric items are printed in decimal. If a tilde (~) is encountered in the print list, the numeric items which follow it are printed in hexadecimal. If a comma or a semi-colon is encountered further down the print list, the format reverts to decimal.
```                    z10
012345678901234567890123456789
PRINT ~10 58,58     ,,,,,,,,,A,,,,,,,,3A,,,,,,,,58
```
A comma (,) causes the cursor to TAB to the beginning of the next print zone unless the cursor is already at the start of a print zone. A semi-colon causes the next and following items to be printed immediately after the previous item. This 'no-gap' printing continues until a comma (or the end of the print list) is encountered. An apostrophe (') will force a new line. TAB(X) and TAB(Y,Z) can also be used at any position in the print line to position the cursor.
```                    z10
012345678901234567890123456789
PRINT "HELLO",24.2  HELLO     ,,,,,,24.2
PRINT "HELLO";24.2  HELLO24.2
PRINT ;2 5 4.3,2    254.3     ,,,,,,,,,2
PRINT "HELLO"'2.45  HELLO
,,,,,,2.45
```
Unlike most other versions of BASIC, a comma at the end of the print list will not suppress the new line and advance the cursor to the next zone. If you wish to split a line over two or more PRINT statements, end the previous print list with a semicolon and start the following list with a comma or end the line with a comma followed by a semicolon.
```                    z10
012345678901234567890123456789
PRINT "HELLO" 12;   HELLO,,,,,,,,12,,,,,,,,,,23.67
PRINT ,23.67
```
or
```PRINT "HELLO" 12,;
PRINT 23.67
```
Printing a string followed by a numeric effectively moves the start of the print zones towards the right by the length of the string. This displacement continues until a comma is encountered.
```                    z10
012345678901234567890123456789
PRINT "HELLO"12 34  HELLO,,,,,,,,12,,,,,,,,34
PRINT "HELLO"12,34  HELLO,,,,,,,,12     ,,,,,,,,34
```

Print format control

The @% system variable

Although PRINT USING is not implemented in BBC BASIC (but see the FNusing library function for a substitute), similar control over the print format can be obtained. The overall width of the print zones and print field, the number of figures or decimal places and the print format may be controlled by setting the system variable @% to the appropriate value. @% comprises 4 bytes and each byte controls one aspect of the print format. @% can be set equal to a decimal integer, but it is easier to use hexadecimal, since each byte can then be considered separately.
```@%=&SSNNPPWW
```
Byte  Range   Default  Purpose
SS00-01 00STR\$ Format Control
NN00-C2  00Format Selection
PP??-?? 09Number of Digits Printed
WW00-0F 0A(10)Zone and Print Field Width

STR\$ format control - SS

Byte 3 affects the format of the string generated by the STR\$ function. If Byte 3 is 1 the string will be generated according to the format set by @%, otherwise the G9 format will be used.

Format selection - NN

Byte 2 selects the format as follows:
00  General Format (G).
01  Exponential Format (E).
02  Fixed Format (F).
Adding &80 (i.e. 80, 81 or 82) causes a comma to be output instead of a decimal point.
 G Format Numbers that are integers are printed as such. Numbers in the range 0.0001 to 1 will be printed as such. Numbers less than 0.0001 will be printed in E format. Numbers greater than the range set by Byte 1 will be printed in E format. In which case, the number of digits printed will still be controlled by Byte 1, but according to the E format rules. The earlier examples were all printed in G9 format. E Format Numbers are printed in the scientific (engineering) notation. F Format Numbers are printed with a fixed number of decimal places.
Adding &40 (i.e. 42 or C2) overrides the limit on the number of decimal places that may be output in Fixed Format (F) mode. Trailing zeros will be appended as necessary.

Number of digits - PP

Byte 1 controls the number of digits printed in the selected format. The number is rounded (NOT truncated) to this size before it is printed. If Byte 1 is set outside the range allowed for by the selected format, it is taken as 9. The effect of Byte 1 differs slightly with the various formats.

Format   Range   Control Function
G 01-14 The maximum number of digits which can be printed, excluding the decimal point, before changing to the E format.
```                    01234567890123456789
&030A - G3z10
(00'00'03'0A)
PRINT 1000.31       ,,,,,,,1E3
PRINT 1016.31       ,,,,1.02E3
PRINT 10.57         ,,,,,,10.6
```
E 01-FF The total number of digits to be printed excluding the decimal point and the digits after the E. Three characters or spaces are always printed after the E. If the number of significant figures called for is greater than 10, then trailing zeros will be printed.
```01030A - E3z10
(00'01'03'0A)
01234567890123456789
PRINT 10.57         ,,1.06E1

&010F0A - E15z10
(00'01'0F'0A)
01234567890123456789
PRINT 10.57         1.05700000000000E1
```
F 00-14 The number of digits to be printed after the decimal point.
```&02020A - F2z10
(00'02'02'0A)
01234567890123456789
PRINT 10.57         ,,,,,10.57
PRINT 100.5864      ,,,,100.59
PRINT .64862        ,,,,,,0.65
```

Zone width - WW

Byte 0 sets the width of the print zones and field.
```&020208 - F2z8
(00'00'02'08)
```
followed by
```&020206 - F2z6
(00'02'02'06)
01234567890123456789
PRINT 10.2,3.8      ,,,10.20,,,,3.80
PRINT 10.2,3.8      ,10.20,,3.80
```

Changing the Print Control Variable

It is possible to change the print control variable (@%) within a print list by using the function:
```DEF FN_pformat(N):@%=N:=""
```
Functions have to return an answer, but the value returned by this function is a null string. Consequently, its only effect is to change the print control variable. Thus the PRINT statement
```PRINT FN_pformat(&90A) x FN_pformat(&2020A) y
```
will print x in G9z10 format and y in F2z10 format. If you try to alter the zone width using this method the change will only take place at the next comma (if any) in the print list.

Examples

```G9z10                    G2z10
&00090A                  &00020A
012345678901234          012345678901234
1111.11111               ,,,,,1.1E3
13.7174211               ,,,,,,,,14
,1.5241579               ,,,,,,,1.5
1.88167642E-2            ,,,,1.9E-2
2.09975158E-3            ,,,,2.1E-3

F2z10                    E2z10
&02020A                  &0102A
012345678901234          012345678901234
,,,1111.11               ,,,1.1E3
,,,,,13.72               ,,,1.4E1
,,,,,,1.52               ,,,1.5E0
,,,,,,0.02               ,,,1.9E-2
,,,,,,0.00               ,,,2.1E-3
```
The results obtained by running the following example program show the effect of changing the zone width. The results for zone widths of 5 and 10 (&0A) illustrate what happens when the zone width is too small for the number to be printed properly. The example also illustrates what happens when the number is too large for the chosen precision.
```test=7.8123
FOR i=5 TO 25 STEP 5
PRINT
@%=&020200+i
PRINT "@%=&000";~@%
PRINT STRING\$(3,"0123456789")
FOR j=1 TO 10
PRINT test^j
NEXT
PRINT '
NEXT
@%=&90A

&00020205
012345678901234567890123456789
7.81
61.03
476.80
3724.91
29100.11
227338.75
1776038.54
13874945.89
1.083952398E8
8.46816132E8

&0002020A
012345678901234567890123456789
7.81
61.03
476.80
3724.91
29100.11
227338.75
1776038.54
13874945.89
1.083952398E8
8.46816132E8

&0002020F
012345678901234567890123456789
7.81
61.03
476.80
3724.91
29100.11
227338.75
1776038.54
13874945.89
1.083952398E8
8.46816132E8

&00020214
012345678901234567890123456789
7.81
61.03
476.80
3724.91
29100.11
227338.75
1776038.54
13874945.89
1.083952398E8
8.46816132E8

&00020219
012345678901234567890123456789
7.81
61.03
476.80
3724.91
29100.11
227338.75
1776038.54
13874945.89
1.083952398E8
8.46816132E8
```

Syntax

```PRINT {[TAB(<numeric>[,<numeric>])][SPC(<numeric>]
['][,][;][~][<string>|<numeric>]}
```

Associated Keywords

PRINT#, TAB, POS, STR\$, WIDTH, INPUT, VDU