QPC Keywords
Author: Martin Head
Date: 0101-01-01T00:00:00+00:00
Keywords: QPC Keywords; keywords; QL; SMSQ; SMSQ/E; SBASIC

QPC

Keywords

This Keyword Reference Guide lists all the QPC keywords in alphabetical order: A brief
explanation of the keywords function is given followed by loose definition of the syntax and
examples of usage.

This guide is a combination of the Sinclair QL manuals Keyword section, the (Super)Gold
card manual, the Toolkit 2 manual, the SMSQ/E manual, and the QPC manual.

© 1984 SINCLAIR RESEARCH LIMITED

© MIRACLE SYSTEMS

© 1994-2002 TONY TEBBY

© MARCEL KILGUS

Release V1.02

Contents

BLOCK ........................ 15

CHR$ .......................... 23

BORDER ..................... 16

CIRCLE ....................... 24

ABS ............................... 7

CACHE_OFF............... 16

CIRCLE_R .................. 24

ACOS ............................ 7

CACHE_ON ................ 16

ELLIPSE ..................... 24

ASIN .............................. 7

CALL ........................... 17

ELLIPSE_R ................. 24

ACOT............................. 7

CD_ALLTIME .............. 17

CKEYOFF ................... 25

ATAN ............................. 7

CD_CLOSE ................. 17

CKEYON ..................... 25

ADATE........................... 7

CD_EJECT .................. 17

CLCHP ........................ 25

ALARM .......................... 8

CD_FIRSTTRACK ....... 18

CLEAR ........................ 25

ALCHP........................... 8

CD_LASTTRACK ........ 18

CLOCK ........................ 26

RECHP .......................... 8

CD_HOUR................... 18

CLOSE ........................ 26

ALTKEY ......................... 8

CD_MINUTE ............... 18

CLS ............................. 27

AJOB ............................. 9

CD_SECOND .............. 18

CODE .......................... 27

ARC ............................... 9

CD_HSG2RED ............ 18

COLOUR_NATIVE ...... 27

ARC_R .......................... 9

CD_RED2HSG ............ 18

COLOUR_PAL ............ 27

AT ................................ 10

CD_INIT ...................... 19

COLOUR_QL .............. 27

AUTO........................... 10

CD_ISPLAYING .......... 19

COLOUR_24 ............... 27

BAUD........................... 11

CD_ISCLOSED ........... 19

CONTINUE ................. 28

BEEP ........................... 11

CD_ISINSERTED ........ 19

RETRY ........................ 28

BEEPING ..................... 12

CD_ISPAUSED ........... 19

COPY .......................... 29

BGCOLOUR_QL ......... 13

CD_LENGTH............... 19

COPY_N ..................... 29

BGCOLOUR_24 .......... 13

CD_PLAY .................... 20

COPY_O ..................... 29

BGET ........................... 13

CD_RESUME .............. 20

COPY_H ..................... 29

BPUT ........................... 13

CD_STOP ................... 20

WCOPY ...................... 29

WGET .......................... 13

CD_TRACK ................. 20

COS ............................ 32

WPUT .......................... 13

CD_TRACKLENGTH .. 21

COT ............................ 32

LGET ........................... 13

CD_TRACKTIME ........ 21

CSIZE ......................... 33

LPUT ........................... 13

CD_TRACKSTART ..... 21

CURSEN ..................... 33

UPUT ........................... 13

CHAR_DEF ................. 21

CURDIS ...................... 33

BGIMAGE .................... 14

CHAR_INC .................. 22

CURSOR .................... 34

BIN............................... 15

CHAR_USE ................. 23

DATA .......................... 35

BIN$............................. 15

CHK_HEAP ................. 23

READ .......................... 35

2

RESTORE ................... 35

DISP_BLANK .............. 47

ET ............................... 57

DATA$ ......................... 36

DISP_COLOUR ........... 48

EXEP .......................... 59

PROG$ ........................ 36

DISP_INVERSE .......... 48

EXIT ............................ 59

DESTD$ ...................... 36

DISP_RATE ................ 48

EXP ............................. 60

DATA_USE .................. 36

DISP_SIZE .................. 48

EXTRAS ...................... 60

DATE$ ......................... 37

DISP_TYPE................. 49

FEXP$ ......................... 60

DATE ........................... 37

DIV .............................. 49

FDEC$ ........................ 61

DAY$ ........................... 38

DLINE .......................... 49

IDEC$ ......................... 61

DDOWN ....................... 38

DLIST .......................... 50

CDEC$ ........................ 61

DUP ............................. 38

DMEDIUM_NAME$ ..... 50

FILL ............................. 62

DNEXT ........................ 38

DMEDIUM_DRIVE$ .... 50

FILL$ ........................... 62

DEFine......................... 39

DMEDIUM_RDONLY .. 50

FLASH ........................ 62

FuNction ...................... 39

DMEDIUM_REMOVE .. 50

FLEN ........................... 63

END DEFine ................ 39

DMEDIUM_DENSITY .. 50

FTYP ........................... 63

DEFine......................... 40

DMEDIUM_FORMAT .. 50

FDAT........................... 63

PROCedure ................. 40

DMEDIUM_TYPE ........ 50

FXTRA ........................ 63

END DEFine ................ 40

DMEDIUM_TOTAL ...... 50

FNAME$ ..................... 63

DEG ............................. 41

DMEDIUM_FREE ........ 50

FUPDT ........................ 63

DELETE....................... 42

DO ............................... 51

FBKDT ........................ 63

WDEL .......................... 42

DOS_USE ................... 52

FVERS ........................ 63

DEL_DEFB .................. 42

ED ............................... 52

FLP_DENSITY ............ 64

DEST_USE .................. 43

EDIT ............................ 52

FLP_SEC .................... 64

DEVTYPE .................... 43

EOF ............................. 55

FLP_START ................ 64

DEV_LIST .................... 44

EOFW ......................... 55

FLP_STEP .................. 64

DEV_USE$ .................. 44

EPROM_LOAD ........... 55

FLP_STEP .................. 65

DEV_NEXT$ ................ 44

ERLIN .......................... 56

FLP_TRACK ............... 65

DEV_NEXT .................. 44

ERNUM ....................... 56

FLP_USE .................... 65

DEV_USEN ................. 44

ERT ............................. 56

FLUSH ........................ 65

DEV_USE .................... 45

EX ............................... 57

FOPEN ........................ 66

DIM .............................. 46

EXEC .......................... 57

FOP_IN ....................... 66

DIMN ........................... 46

EW .............................. 57

FOP_NEW .................. 66

DIR .............................. 47

EXEC_W ..................... 57

FOP_OVER ................ 66

3

FOP_DIR ..................... 66

HOT_STUFF ............... 80

LINE_R ....................... 93

FOR ............................. 67

HOT_THING................ 80

LIST ............................ 94

END FOR .................... 67

HOT_THING1.............. 80

LOAD .......................... 94

FORMAT ..................... 68

HOT_TYPE ................. 81

QLOAD ....................... 94

FPOS ........................... 68

HOT_WAKE ................ 81

LN ............................... 95

FREE_MEM ................. 69

IF ................................. 82

LOG10 ........................ 95

FTEST ......................... 69

THEN .......................... 82

LOCal .......................... 95

GET ............................. 69

ELSE ........................... 82

LRESPR ...................... 96

PUT ............................. 69

END IF ........................ 82

LRUN .......................... 96

GOSUB........................ 71

INK .............................. 84

QLRUN ....................... 96

GOTO .......................... 71

INKEY$ ....................... 84

MACHINE ................... 96

HEX ............................. 71

INPUT ......................... 85

SMSQ/E ...................... 96

HEX$ ........................... 71

IO_PRIORITY.............. 86

MAKE_DIR .................. 97

HGET........................... 72

INSTR ......................... 86

FMAKE_DIR ............... 97

HPUT ........................... 72

INSTR_CASE .............. 87

MERGE ....................... 98

HOT_CHP ................... 72

INT .............................. 87

QMERGE .................... 98

HOT_CHP1 ................. 72

JOBS ........................... 87

MOD............................ 98

HOT_RES .................... 72

JOB$ ........................... 88

MODE ......................... 98

HOT_RES1 .................. 72

NXJOB ........................ 88

MOUSE_SPEED ......... 99

HOT_CMD ................... 74

OJOB .......................... 88

MOUSE_STUFF ......... 99

HOT_DO ...................... 75

PJOB ........................... 88

MOVE ......................... 99

HOT_GO ..................... 75

JOB_NAME ................. 89

MRUN ....................... 100

HOT_STOP ................. 75

KBD_TABLE................ 89

QMRUN .................... 100

HOT_KEY .................... 76

KEYROW .................... 89

NET ........................... 100

HOT_LIST ................... 76

KEYBOARD MATRIX

NEW.......................... 100

................................. 90

HOT_LOAD ................. 77

NEXT ........................ 100

LANGUAGE ................ 90

HOT_LOAD1 ............... 77

ON...GOTO ............... 101

LANGUAGE$ .............. 90

HOT_NAME$ ............... 78

ON...GOSUB ............. 101

LANG_USE ................. 91

HOT_OFF .................... 78

OPEN ........................ 102

LBYTES ...................... 92

HOT_SET .................... 78

OPEN_IN .................. 102

LEN ............................. 92

HOT_PICK ................... 79

OPEN_OVER ............ 102

LET .............................. 92

HOT_REMV ................. 79

OPEN_DIR ................ 102

LINE ............................ 93

4

OPEN_NEW .............. 102

POKE_W ................... 112

RAD .......................... 123

OUTLN ...................... 102

POKE_L .................... 112

RAM_USE ................. 123

OVER ........................ 103

POKES ...................... 114

RANDOMISE ............ 123

PALETTE_QL ............ 104

POKES_W................. 114

RECOL ...................... 124

PALETTE_8 ............... 104

POKES_L .................. 114

REMark ..................... 124

PAN ........................... 105

POKE$ ...................... 114

RENAME ................... 125

PAPER ...................... 105

POKES$ .................... 114

WREN ....................... 125

PARNAME$ ............... 106

PRINT ....................... 114

RENUM ..................... 125

PARSTR$ .................. 106

PRINT_USING .......... 115

REPeat ...................... 126

PARTYP .................... 107

PROCESSOR ........... 117

END REPeat ............. 126

PARUSE .................... 107

PROG_USE .............. 117

REPORT ................... 126

PAR_BUFF ................ 107

PROT_DATE ............. 118

RESET ...................... 127

PAR_CLEAR ............. 108

PROT_MEM .............. 118

RESPR ...................... 127

PAR_ABORT ............. 108

PRT_BUFF ................ 118

RETurn ...................... 127

PAR_PULSE ............. 108

PRT_CLEAR ............. 119

RJOB ........................ 128

PAR_USE .................. 108

PRT_ABORT ............. 119

RND .......................... 128

PAR_WAIT ................ 109

PRT_USE .................. 119

RUN .......................... 129

PAUSE ...................... 109

PRT_USE$ ................ 120

SAVE ........................ 129

PEEK ......................... 109

QPC_EXEC ............... 120

QSAVE ...................... 129

PEEK_W .................... 109

QPC_EXIT................. 120

SAVE_O .................... 129

PEEK_L ..................... 109

QPC_HOSTOS ......... 120

QSAVE_O ................. 129

PEEKS....................... 110

QPC ....................... 120

SBASIC ..................... 130

PEEKS_W ................. 110

QPC_MAXIMIZE ....... 121

SBYTES .................... 131

PEEKS_L ................... 110

QPC_MINIMIZE ........ 121

SBYTES_O ............... 131

PEEK$ ....................... 110

QPC_RESTORE ....... 121

SCALE ...................... 132

PEEKS$..................... 111

QPC ....................... 121

SCROLL .................... 132

PENUP ...................... 111

QPC_MSPEED ......... 121

SCR_BASE ............... 133

PENDOWN ................ 111

QPC_NETNAME$ ..... 121

SCR_LLEN ............... 133

PI ............................... 111

QPC_QLSCREMU .... 121

SCR_XLIM ................ 133

POINT........................ 112

QPC_SYNCSCRAP .. 122

SCR- YLIM ................ 133

POINT_R ................... 112

QPC_VER$ ............... 122

SDATE ...................... 133

POKE......................... 112

QUIT .......................... 123

SELect ...................... 134

5

END SELect .............. 134

STAT ......................... 143

ERR_NF ............ 149

SEND_EVENT ........... 135

STOP ........................ 143

ERR_IU .............. 149

SER_BUFF ................ 136

STRIP ........................ 143

ERR_DF ............ 149

SER_CDEOF ............. 136

TAN ........................... 143

ERR_TE ............. 149

SER_CLEAR ............. 136

TH_FIX ...................... 144

ERR_BP ............ 149

SER_ ABORT ............ 136

TK2_EXT ................... 144

ERR_XP ............ 149

SER_FLOW ............... 137

TRA ........................... 144

ERR_NI .............. 149

SER_PAUSE ............. 137

TRUNCATE ............... 145

ERR_BL ............. 149

SER_ROOM .............. 137

TURN ........................ 145

WIDTH ...................... 149

SER_USE .................. 138

TURNTO ................... 145

WINDOW .................. 150

SET_FUPDT .............. 138

UNDER ..................... 146

WIN_DRIVE .............. 150

SET_FBKDT .............. 138

VER$ ......................... 146

WIN_DRIVE$ ............ 150

SET_FVERS .............. 138

VIEW ......................... 147

WIN_FORMAT .......... 150

SEXEC ...................... 139

WAIT_EVENT ........... 147

WIN_REMV ............... 151

SEXEC_O .................. 139

WDIR ......................... 148

WIN_SLUG ............... 151

SIN............................. 140

WSTAT ...................... 148

WIN_START ............. 151

SLUG ......................... 140

WHEN ERROR ......... 148

WIN_STOP ............... 151

SPJOB ....................... 140

END WHEN ............... 148

WIN_USE .................. 152

SPL ............................ 141

ERROR functions .. 149

WIN_WP ................... 152

SPLF.......................... 141

ERR_NC ............ 149

WMON ...................... 152

SPL_USE .................. 142

ERR_OM ............ 149

WTV .......................... 152

SQRT......................... 142

ERR_BO ............ 149

6

ABS
maths functions

ABS returns the absolute value of the parameter. It will return the value of the parameter if the parameter is positive and will return zero minus the value of the parameter if the
parameter is negative.

syntax. ABS( numeric_expression)

example: i. PRINT ABS(0.5)

ii. PRINT ABS(a-b)

ACOS

ASIN

ACOT

ATAN
maths functions

ACOS and ASIN will compute the arc cosine and the arc sine respectively. ACOT will calculate the arc cotangent and ATAN will calculate the arc tangent. There is no effective limit to the size of the parameter.

ATAN will provide a 4 quadrant result by taking two parameters. If x is greater than 0,

ATAN (x,y) give the same results as ATAN (y/x). Otherwise it returns values in the other quadrants (>PI/2 and <-PI/2).

syntax:

angle:= nunieric_expression [in radians]

ACOS ( angle)

ACOT ( angle)

ASIN ( angle)

ATAN ( angle [, angle])

example: i. PRINT ATAN(angle)

ii. PRINT ASIN(1)

iii. PRINT ACOT(3.6574)

iv. PRINT ATAN(a-b)

ADATE
clock

ADATE allows the clock to be adjusted.

syntax: seconds:= numeric_expression

ADATE seconds

example: i. ADATE 3600 {will advance the clock 1 hour}

ii. ADATE -60 {will move the clock back 1 minute}

ALARM
timekeeping

ALARM is a procedure to set up an alarm using the QPC's system clock.

The time should be specified as two numbers: hours (24 hour clock) and minutes.

syntax:

time := numeric_expression , numeric_expression

ALARM time

example: ALARM 14,30

{alarm will sound at half past two}

ALCHP

RECHP
memory management

The function ALCHP will allocate the requested amount of memory form the ‘common
heap’ and return the base address of the space.

RECHP will return space allocated by ALCHP to the ‘common heap’

syntax:

number_of_bytes := numeric_expression

ALCHP ( number_of_bytes)

RECHP base_address

example: i. base = ALCHP (3000)

{allocate 3000 bytes from the heap}

ii. RECHP base

{return 3000 bytes allocated in i above}

ALTKEY

The ALTKEY command assigns a string to an 'ALT' keystroke (hold the ALT key down and
press another key). The string itself may contain newline characters, or, if more than one
string is given, then there will be an implicit newline between the strings. Thus a null string may be put at the end to add a newline to the string.

ALTKEY with just character alone will cancel the string associated with that character.

ALTKEY alone will cancel all ALTKEY strings.

syntax:

ALTKEY [ character, strings ]

8
example: i. ALTKEY 'r', 'RJOB "SPL"',''

{when ALT r is pressed, the
command

ii. ALTKEY 'r','RJOB "SPL"'&CHR$(10)

'RJOB "SPL"' will be executed}

iii. ALTKEY 'r'

{will cancel the ALTKEY string for 'r'}

iv. ALTKEY

{cancel all ALTKEY strings}

comment: ALTKEY is case dependent i.e. ALT r is not the same as ALT R.

AJOB

SMSQ/E

AJOB is used to re-activate jobs which have been suspended.

syntax:

job_identifier :=

| job_number , tag_number

| job_number + ( tag_number * 65536)

id := job_identifier

AJOB id | name , priority

example: i. AJOB demon,1

{start the Job called 'demon' with a priority of 1}

ii. AJOB 2,1,80

{start the job, Job number 2, Tag number 1 with a
priority of 80}

comment: If a name is given rather than a Job ID, then the procedure will search for the
first Job it can find with the given name.

ARC

ARC_R
graphics

ARC will draw an arc of a circle between two specified points in the window attached to the default or specified channel. The end points of the arc are specified using the graphics coordinate system. Multiple arcs can be drawn with a single ARC command.

The end points of the are can be specified in absolute coordinates (relative to the graphics origin or in relative coordinates (relative to the graphics cursor). If the first point is omitted then the are is drawn from the graphics cursor to the specified point through the specified
angle.

ARC will always draw with absolute coordinates, while ARC_R will always draw relative to the graphics cursor.

syntax:

x:= numeric_expression

y:= numeric_expression

9

angle:= numeric_expression (in radians)

point:= x,y

parameter_2:= | TO point, angle

(1)

| , point TO point, angle

(2)

parameter_1:= | point TO point, angle

(1)

| TO point, angle

(2)

ARC [ channe l,] parameter_1 *[ parameter_2]*

ARC_R [ channel,] parameter_1 *[ parameter_2]*

where (1) will draw from the specified point to the next specified point turning
through the specified angle

(2) will draw from the the last point plotted to the specified

point turning through the specified angle

example: i. ARC 15,10 TO 40,40,PI/2

{draw an arc from 15,10 to 40,40 turning
through PI/2 radians}

ii. ARC TO 50,50,PI/2

{draw an arc from the last point plotted to

50,50 turning through PI/2 radians}

iii. ARC_R 10,10 TO 55,45,0.5

{draw an arc, starting 10,10 from the last
point plotted to 55,45 from the start of the
are, turning through 0.5 radians}

AT
windows

AT allows the print position to be modified on an imaginary row/column grid based on the current character size. AT uses a modified form of the pixel coordinate system where (row 0, column 0) is in the top left hand corner of the window. AT affects the print position in the window attached to the specified or default channel.

syntax:

line:= numeric_expression

column:= numeric_expression

AT [ channe l,] line , column

example: AT 10,20 : PRINT "This is at line 10 column 20"

AUTO

AUTO has been replaced by ED.

10

BAUD
communications

BAUD sets the baud rate for communication via the serial channels. The speed of the
channels be set independently by supplying an optional port number.

If no port number is supplied, then the command will default to SER1.

syntax:

rate:= numeric_expression

port:= numeric_expression

BAUD [ port,] rate

The value of the rate numeric expression must be one of the baud rates
supported by SMSQ/E on QPC:

300

600

1200

2400

4800

9600

19200

38400

57600

115200

If the selected baud rate is not supported, then an error will be generated.

example: i. BAUD 2,9600

{set SER2 to 9600 baud}

ii. BAUD print_speed

{set SER1 to ‘print_speed’ baud}

BEEP
sound

BEEP activates the inbuilt sound functions on the QL. BEEP can accept a variable number of parameters to give various levels of control over the sound produced. The minimum
specification requires only a duration and pitch to be specified. BEEP used with no
parameters will kill any sound being generated.

syntax:

duration:= numeric_expression

{range -32768..32767}

pitch:= numeric_expression

{range 0..255}

grad_x:= numeric_expression

{range -32768..32767}

11

grad_y:= numeric_expression

{range -8..7}

wrap:= numeric_expression

{range 0..15}

fuzzy:= numeric_expression

{range 0..15}

random:= numeric_expressian

{range 0..15}

BEEP [ duration, pitch

[, pitch_2, grad_x, grad_y

[, wrap

[, fuzzy

[, random ]]]]]

duration - specifies the duration of the sound in units of 72 microseconds. A
duration of zero will run the sound until terminated by another

BEEP command.

pitch -
specifies the pitch of the sound.A pitch of 1 is high and 255 is low.

Pitch_2 - specifies an second pitch level between which the sound will

'bounce'

grad_x -
defines the time interval between pitch steps.

grad_y -
defines the size of each step, grad_x and grad_y control the rate
at which the pitch bounces between levels.

wrap -
will force the sound to wrap around the specified number of times.

If wrap is equal to 15 the sound will wrap around forever:

fuzzy -
defines the amount of fuzziness to be added to the sound.

random - defines the amount of randomness to be added to the sound.

BEEPING
sound

BEEPING is a function which will return zero (false) if QPC is currently not beeping and a value of one (true) if it is beeping.

syntax:

BEEPING

example: 100 DEFine PROCedure be_ quiet

110 BEEP

120 END DEFine

130 IF BEEPING THEN be_ quiet

12

BGCOLOUR_QL

BGCOLOUR_24
graphics device 2

BGCOLOUR_QL and BGCOLOUR_24 set the screens background colour, the colour
behind any open window. To one of the QL compatible colours, or to a plain true colour.

syntax:

colour := numeric_expression

BGCOLOUR_QL colour

{range 0 … 255}

BGCOLOUR_24 colour

{range 0 … 16,777,215}

example: i. BGCOLOUR_QL 255

{set background to black / white check}

ii. BGCOLOUR_QL 0,7

{set background to black / white check}

iii. BGCOLOUR_QL 0,7,3

{set background to black / white check}

iv. BGCOLOUR_24 40

{set the background to deep blue}

comment: You can get stippled extended colours by cheating. Set two of the QL palette
entries (see PALETTE_QL) to the colours you require before calling

BGCOLOUR_QL.

BGET

BPUT

WGET

WPUT

LGET

LPUT

UPUT
byte input/output

BGET gets 0 or more bytes from the channel. BPUT puts 0 or more bytes into the channel.

For BGET, each item must be a floating point or integer variable; for each variable, a byte is fetched from the channel. BGET will accept a parameter that is a sub-string of a string array to get multiple bytes.

For BPUT, each item must evaluate to an integer between 0 and 255; for each item a byte
is sent to the output channel. BPUT will accept string parameters to put multiple bytes.

WGET, WPUT, LGET, and LPUT work like BGET and BPUT, but they always read a word or long word instead of a byte.

13

UPUT works as BPUT, but will never translate the character. Very useful to send
translated text to a channel which does use TRA, as well as sending printer control codes using UPUT to the same channel.

syntax:

BGET # channel\ [ position] , items

{get bytes from a file}

BPUT # channel\ [ position] , items

{put bytes onto a file}

WGET # channel\ [ position] , items

{get words from a file}

WPUT # channel\ [ position] , items

{put words onto a file}

LGET # channel\ [ position] , items

{get long words from a file}

LPUT # channel\ [ position] , items

{put long words onto a file}

UPUT # channel\ [ position] , items

{put bytes onto a file}

example: i. abcd=2.6 : zz%=243

BPUT #3,abcd+1,zz%

{will put the byte values 4 and 243 after the current
file position on the file open on #3}

ii. BPUT #3,27,'R1'

{put ESC R1 to channel #3}

iii. DIM a$(10): a$(10)=' '

BGET #3, a$(1 to 6)

{get 6 bytes from #3 into a$}

comment: Provided no attempt is made to set a file position, the direct I/O routines can be
used to send unformatted data to devices which are not part of the file system.

If, for
example, a channel is opened to an Epson compatible printer

(channel #3) then the printer may be put into condensed underline mode by
either

BPUT #3,15,27,45,1

or PRINT #3,chr$(15);chr$(27);'-';chr$(1); {Which is easier?}

BGIMAGE
graphics device 2

BGIMAGE will load an image to be used as a background behind any open windows.

syntax:

BGIMAGE filename

example: BGIMAGE win1_wallpaper

comment: Background images must be in the form of a screen snapshot. It is relatively
simple to create background images.

500 WINDOW SCR_XLIM, SCR_YLIM, 0, 0 : REMark whole screen window

510 …… draw the wallpaper on the screen

14

520 SBYTES_0 win1_wallpaper, SCR_BASE, SCR_LLEN * SCR_YSIZE

BIN

BIN$
conversion functions

BIN will convert the supplied binary string into a value. Any character in the string, whose ASCII value is even, is treated as 0, while any character, whose ASCII value is odd, is
treated as 1. e.g. BIN ('.#.#') returns the value 5.

The 'digits' '0' to '9' 'A' to 'F' and 'a' to 'f' have their conventional meanings.

BIN$ will return a string of sufficient length to represent the value of the specified number of bits of the least significant end of the value.

syntax:

number_of_bits := numeric_expression

BIN ( binary_string)

BIN$ ( value, number_of_bits)

example: PRINT BIN ( “1010”)

{will output 10}

PRINT BIN$ (9 , 8)

{will output “00001001”}

BLOCK
windows

BLOCK will fill a block of the specified size and shape, at the specified position relative to the origin of the window attached to the specified, or default channel.

BLOCK uses the pixel coordinate system.

syntax: width:=
numeric_expression

height:=
numeric_expression

x:=
numeric_expression
y:=
numeric_expression

BLOCK [ channel,] width, height, x, y, colour example: i. BLOCK 10,10,5,5,7

{10x10 pixel white block at 5,5}

ii. 100 REMark "bar chart"

110 CSIZE 3,1

120 PRINT "bar chart"

130 LET bottom =100 : size = 20 : left = 10

15

140 FOR bar =1 to 10

150 LET colour = RND(O TO 255)

160 LET height = RND(2 TO 20)

170 BLOCK size, height, Left+bar*size, bottom-height,0

180 BLOCK size-2, height-2, left+bar*size+1, bottom-height+l,colour

190 END FOR bar

BORDER
windows

BORDER will add a border to the window attached to the specified
channel, or default channel.

For all subsequent operations except BORDER the window size is reduced to allow space
for the BORDER. If another BORDER command is used then the full size of the original window is restored prior to the border being added; thus multiple BORDER commands
have the effect of changing the size and colour of a single border. Multiple borders are not
created unless specific action is taken.

If BORDER is used without specifying a colour then a transparent border of the specified width is created.

syntax:

width:= numeric_expression

BORDER [ channel,] size [, colour]

example: i. BORDER 10,0,7

{black and white stipple border}

ii. 100 REMark Lurid Borders

110 FOR thickness = 50 to 2 STEP -2

120 BORDER thickness, RND(0 TO 255)

130 END FOR thickness

140 BORDER 50

CACHE_OFF

CACHE_ON
memory management

There is a cache in QPC that can increase performance but it can cause problems with
programs that modify themselves during execution.

syntax:

CACHE_OFF

CACHE_OFF

16

comment: There is no way of knowing whether or not a program is self-modifying so try
each program first with the cache off, by typing: CACHE_OFF and then with the cache on,
by typing: CACHE_ON

If the program behaves differently with the cache on, other than going slightly
faster, it is a sign that it is self-modifying and should only be run with the cache off.

CALL

SMSQ/E

Machine code can be accessed directly from SBASIC by using the CALL command. CALL
can accept up to 13 long word parameters which will be placed into the 68010 data and
address registers (D1 to D7, AO to A5) in sequence.

No data is returned from CALL.

syntax:

address:= numeric_expression

data:= numeric_expression

CALL address, *[ data]*

{13 data parameters maximum}

example: i. CALL 262144,0,0,0

ii. CALL 262500,12,3,4,1212,6

warning: Address register A6 should not be used in routines called using this command.

To return to SBASIC use the instructions:

MOVEQ #0, D0

RTS

CD_ALLTIME
audio CD player

CD_ALLTIME will return the totally elapsed time of the CD.

syntax:

CD_ALLTIME

example: x=CD_ALLTIME

CD_CLOSE

CD_EJECT
audio CD player

CD_CLOSE will close the CD drive tray.

17

CD_EJECT will open the CD drive tray.

syntax:

CD_CLOSE

CD_EJECT

CD_FIRSTTRACK

CD_LASTTRACK
audio CD player

CD_FIRSTTRACK will return the number of the first track.

CD_LASTTRACK will return the number of the last track.

syntax:

CD_FIRSTTRACK

CD_LASTTRACK

example: i. x%=CD_FIRSTTRACK

ii. x%=CD_LASTTRACK

CD_HOUR

CD_MINUTE

CD_SECOND
audio CD player

Returns the hour, minute or second of a Redbook address.

syntax:

CD_HOUR numeric_expression

CD_MINUTE numeric_expression

CD_SECOND numeric_expression

example: i. h%=CD_HOUR redbook

ii. m%=CD_MINUTE redbook

iii. s%=CD_SECOND redbook

CD_HSG2RED

CD_RED2HSG
audio CD player

CD_HSG2RED will convert an HSG address to a Redbook addrress.

CD_RED2HSG will convert a Redbook address to an HSG address.

18
syntax:

CD_HSG2RED numeric_expression

CD_RED2HSG numeric_expression

example i. red=CD_HSG2RED hsg

ii. hsg=CD_RED2HSG red

CD_INIT
audio CD player

CD_INIT must be used before anything else in order to initialise the CD drive for SMSQ.

After the first call the command is ignored in all subsequent calls. The string parameter is
only there for compatibility with QPC1, it is ignored by QPC2.

syntax:

name := string_expression

CD_INIT [ name]

example: CD_INIT

CD_ISPLAYING

CD_ISCLOSED

CD_ISINSERTED

CD_ISPAUSED
audio CD player

These function return a binary value indicating the current status according to the keyword.

Please note that Windows cannot tell whether the tray is closed or not, therefore

CD_ISCLOSED always returns the same result as CD_ISINSERTED when used on

QPC2. An empty tray is obviously something the Microsoft geniuses could not imagine.

syntax:

CD_ISPLAYING

CD_ISCLOSED

CD_ISINSERTED

CD_ISPAUSED

example: i. x%=CD_ISPLAYING

ii. PRINT CD_ISCLOSED

iii. inserted%=CD_ISINSERTED

iv. playing%=CD_ISPAUSED

CD_LENGTH
audio CD player

CD_LENGTH will return the total length of the CD.

19

syntax:

CD_LENGTH

example: x=CD_LENGTH

CD_PLAY
audio CD player

CD_PLAY will begin playing the audio CD. Without parameters the whole CD is played.

An optional start and end track can be given. The command returns immediately when the

CD starts playing. The parameters are given in tracks (bit 31 clear) or in sector units (bit 31
set).

syntax:

start := numeric_expression

end := numeric_expression

CD_PLAY [ start[, end]]

example: i. CD_PLAY 3

{start playing from track 3}

CD_PLAY CD_TRACKSTART(3)+$80000000 {same as above}

CD_RESUME
audio CD player

CD_RESUME will resume the playing of a paused audio CD.

syntax:

CD_RESUME

CD_STOP
audio CD player

CD_STOP will pause playing. If the driver was already in pause mode, a complete stop is
performed (as if a new CD was inserted, restart from track 1 and so on)

syntax:

CD_STOP

CD_TRACK
audio CD player

CD_TRACK will return the number of the track which is currently being played.

syntax:

CD_TRACK

20
example: track%=CD_TRACK

CD_TRACKLENGTH
audio CD player

CD_TRACKLENGTH will return the length of a track.

syntax:

track := numeric_expression

CD_TRACKLENGTH track

example: x=CD_TRACKLENGTH track

comment: This is the only function that returns an HSG-number.

CD_TRACKTIME
audio CD player

CD_TRACKTIME will return the number of the track which is currently being played.

syntax:

CD_TRACKTIME

example: PRINT CD_TRACKTIME

CD_TRACKSTART
audio CD player

CD_TRACKSTART will return the beginning sector of a track.

syntax:

track := numeric_expression

CD_TRACKSTART track

example: x=CD_TRACKSTART track

CHAR_DEF
windows

The QPC display driver has two character founts built in. The first provides patterns for the
values 32 (space) to 127 (copyright), while the second provides patterns for the values 127

(undefined) to 191 (down arrow). For each character the display driver will use the
appropriate pattern from the first fount, if there is one, failing that, it will use the appropriate 21
pattern from the second fount, failing that, it will use the first defined pattern in the second fount.

The command CHAR_DEF is used to set or reset one or both character founts.

Setting a fount address to zero will force the built in founts to be used.

All windows which are opened after using CHAR_DEF now will use the new system fonts

(except if they define their own fonts, of course).

Channels already open will not use the new fonts automatically for various reasons: the
most obvious is, that if the font file did not contain any font data, you will not be able to
correct this as all characters printed will look like complete rubbish.

To change the fonts on channels already open use the CHAR_USE command.

syntax:

CHAR_DEF font1, font2

example: i. CHAR_DEF addr1, addr2 {use the substitute founts at, addr1 and addr2}

ii. CHAR_DEF 0, addr2

{the built in first fount will be used,

addr2 points to a substitute second

fount}

iii. CHAR_DEF 0,0

{reset both founts for window #1}

CHAR_INC
windows

CHAR_INC will set the character and line spacing for the specified or default window.

The QPC display driver assumes that all characters are 5 pixels wide by 9 pixels high.

Other sizes are obtained by doubling the pixels or by adding blank pixels between
characters. It is possible, to set any horizontal and vertical spacing. If the increment is set to less than the current character size (set by CSIZE) then extreme caution is required as it will be possible for the display driver to write characters (at the right hand side or bottom of the window) partly outside the window. The windows should not come closer to the bottom
or right hand edges of the screen than the amount by which the increment specified is
smaller than the character spacing set by CSIZE.

syntax:

x_inc := numeric_expression

y_inc := numeric_expression

CHAR_INC [ # channel, ] x_inc, y_inc

example: If there is a 3x6 character fount in a file called 'f3x6' (length 875 bytes), then a

127 column by 36 row screen can be set up:

22

10 WINDOW 512-2,256-3,0,0:REMark clear of edges of screen

20 CSIZE 0,0

:REMark spacing 6x10

30 CHAR_INC 4,7

:REMark spacing 4x7

:

70 fount = ALCHP (875)

:REMark reserve space for fount

80 LBYTES f3x6, fount

:REMark load fount

90 CHAR_USE fount,0

:REMark single fount only

comment: The character increments specified are cancelled by a CSIZE command.

CHAR_USE
windows

The QPC display driver has two character founts built in. The first provides patterns for the
values 32 (space) to 127 (copyright), while the second provides patterns for the values 127

(undefined) to 191 (down arrow). For each character the display driver will use the
appropriate pattern from the first fount, if there is one, failing that, it will use the appropriate pattern from the second fount, failing that, it will use the first defined pattern in the second fount.

The command CHAR_USE is used to set or reset one or both character founts.

Setting a fount address to zero will force the built in founts to be used.

syntax:

CHAR_USE [# channel, ] address1, address2

example: i. CHAR_USE #3, addr1, addr2 {the window attached to channel 3, will
use the substitute founts at, addr1 and
addr2}

ii. CHAR_USE #2, 0, addr2

{in window 2, the built in first fount will be
used, addr2 points to a substitute second
fount}

iii. CHAR_USE 0,0

{reset both founts for window #1}

CHK_HEAP

No information available on this command.

CHR$

BASIC

CHR$ is a function which will return the character whose value is specified as a parameter: CHR$ is the inverse of CODE.

23

syntax: CHR$( numeric_expressen)

example: i. PRINT CHRS(27)

{print ASCII escape character}

ii. PRINT CHR$(65)

{print A}

CIRCLE

CIRCLE_R

ELLIPSE

ELLIPSE_R
graphics

CIRCLE will draw a circle (or an ellipse at a specified angle) on the screen at a specified position and size. The circle will be drawn in the window attached to the specified or
default channel.

CIRCLE uses the graphics coordinate system and can use absolute coordinates (i.e.

relative to the graphics origin), and relative coordinates (i.e. relative to the graphics cursor).

For relative
coordinates use CIRCLE_R.

Multiple circles or ellipses can be plotted with a single call to CIRCLE. Each set of
parameters must be separated from each other with a semi colon (;)

The word ELLIPSE can be substituted for CIRCLE if required.

syntax: x:= numeric_expression

y:= numeric_expession

radius:= numeric_expression

eccentricity:= numeric_expression

angle:= numeric_expression

{range 0..2PI}

parameters:= | x, y,

(1)

| radius, eccentricity, angle (2)

where

(1) will draw a circle

(2) will draw an ellipse of specified eccentricity and angle

CIRCLE [ channel,] parameters*[; parameters]*

x - horizontal offset from the graphics origin or graphics cursor
y - vertical offset from the graphics origin or graphics cursor
radius - radius of the circle eccentricity the ratio between the major and minor
axes of an ellipse.

24

Angle - the orientation of the major axis of the ellipse relative to the screen
vertical. The angle must be specified in radians.

example: i. CIRCLE 50,50,20

{a circle at 50,50 radius 20}

ii. CIRCLE 50,50,20,0.5,0 {an ellipse at 50,50 major axis 20 eccentricity 0.5
and aligned with the vertical axis}

CKEYOFF

CKEYON
pointer interface

CKEYOFF will disable the use of the cursor keys to move the pointer around the screen.

CKEYON will re-enable the use of the cursor keys to move the pointer around the screen.

syntax:

CKEYOFF

CKEYON

CLCHP
memory management

CLCHP will release all space in the ‘common heap’ which has been allocated with ALCHP.

syntax:

CLCHP

comment: CLEAR and NEW will also release all space allocated in the common heap.

CLEAR

CLEAR will clear out the SBASIC variable area for the current program and will release the space for SMSQ/E.

syntax:

CLEAR

example: CLEAR

comment: CLEAR can be used to restore to a known state the SBASIC system. For
example, if a program is broken into (or stops due to an error) while it is in a
procedure then SBASIC is still in the procedure even after the program has
stopped. CLEAR will reset the SBASIC. {See CONTINUE, RETRY.}

25

CLOCK
timekeeping

CLOCK is a procedure to set up a resident digital clock using the QPC's system clock. If no window is specified, then a default window is set up in the top RHS of the monitor mode
default channel 0. This window is 60 by 20 pixels. The clock may be invoked to execute
within a window set up by SBASIC. In this case the clock job will be removed when the
window is closed.

syntax:

CLOCK [# channel,] [ string ]

The string is used to define the characters written to the clock window: any character may
be written except $ or %. If a dollar sign is found in the string then the next character is
checked and

$d or $D will insert the three characters of the day of week,

$m or $M will insert the three characters of the month.

If a percentage sign is found then

%y or %Y will insert the two digit year

%d or %D will insert the two digit day of month

%h or %H will insert the two digit hour

%m or %M will insert the two digit minute

%s or %S will insert the two digit second

The default string is '$d %d $m %h/%m/%s ' a newline should be forced by padding out a
line with spaces until the right hand margin of the window is reached.

example: 10 OPEN #6,'scr_156x10a32x16'

20 INK #6,0: PAPER #6,4

30 CLOCK #6,'QPC time %h:%m'

CLOSE
devices

CLOSE will close all channel numbers #3 and above, or the specified channels. Any window associated with the channel will be deactivated.

It will not report an error if a channel is not open.

syntax: channel:= numeric_expression

CLOSE [ * channel, * ]

example: i. CLOSE #4

26

ii. CLOSE #input_ channel

iii. CLOSE #3, #4, #7

{close channels #3, #4 and #7}

CLS
windows

Will clear the window attached to the specified or default channel to current PAPER colour, excluding the border if one has been specified. CLS will accept an optional parameter
which specifies if only a part of the window must be cleared.

syntax: part:= numeric_expression

CLS [ channel,] [ part]

where:

part = 0 - whole screen (default if no parameter)

part = 1 - top excluding the cursor line

part = 2 - bottom excluding the cursor line

part = 3 - whole of the cursor line

part = 4 - right end of cursor line including the cursor position

example: i. CLS

{the whole window}

ii. CLS 3

{clear the cursor line}

iii. CLS #2,2

{clear the bottom of the window on channel 2}

CODE

CODE is a function which returns the internal code used to represent the specified
character. If a string is specified then CODE will return the internal representation of the first character of the string.

CODE is the inverse of CHR$.

syntax:

CODE ( string_expression)

example: i. PRINT CODE("A")

{prints 65}

ii. PRINT CODE ("SBASIC")

{prints 83}

COLOUR_NATIVE

COLOUR_PAL

COLOUR_QL

COLOUR_24
graphics device 2

27

COLOUR_NATIVE, COLOUR_PAL, COLOUR_QL, and COLOUR_24 will select the colour definition used by INK, PAPER, STRIP, BORDER, BLOCK.

COLOUR_QL selects the standard QL colour definitions (the QL colours can be mapped
to colours other than the standard black, blue, red, magenta, green, cyan, yellow and
white).

This is the default colour scheme for SBASIC and it's daughter jobs.

COLOUR_PAL selects the 256 colour palette mapped definition.

COLOUR_24 selects the true colour (24 bit) definition.

COLOUR_NATIVE selects the native colour definition - the significance of the colour
numbers specified by INK, PAPER, etc. depends on the hardware.

syntax:

COLOUR_QL

COLOUR_PAL

COLOUR_24

COLOUR_NATIVE

example: 200 COLOUR_24

{select true colour mode}

210 BORDER 2, 128*65536 + 128*256 +128

{grey border}

220 BORDER 2,$808080 {grey border for hexadecimal hackers}

comment: The commands have no effect on any other programs executing. When an

SBASIC program starts executing, it is set to QL colour definition.

CONTINUE

RETRY
error handling

CONTINUE allows a program which has been halted to be continued. RETRY allows a
program statement which has reported an error to be re-executed.

As the RETRY and CONTINUE exit from an error clause without resetting the WHEN

ERROR, they can also be used to exit to a different part of the program via an optional line number.

syntax:

line_number := numeric_expression

CONTINUE [ line_number]

RETRY [ line_number]

example: CONTINUE

RETRY 1040

28

warning: A program can only continue if:

1. No new lines have been added to the program

2. No new variables have been added to the program

3. No lines have been changed

The value of variables may be set or changed.

COPY

COPY_N
devices

COPY will copy a file from an input device to an output device until an end of file marker is detected. COPY_N will not copy the header (if it exists) associated with a file and will allow Disk files to be correctly copied to another type of device.

Headers are associated with directory-type devices and should be removed using

COPY_N when copying to non-directory devices, e.g. flp1 is a directory device; ser1 is a non-directory device.

syntax:

COPY device TO device

COPY_N device TO device

It must be possible to input from the source device and it must be possible to
output to the destination device.

example: i. COPY flp1_data_file TO con_ {copy to default window}

ii. COPY neti_3 TO flp1_data {copy data from network station to
flp1_data.}

iii. COPY_N flp1_test_data TO ser1_ {copy mdvl_test_data to serial port 1
removing header information}

COPY_O

COPY_H

WCOPY
devices

Files in SMSQ/E have headers which provide useful information about the file that follows.

It depends on the circumstances whether it is a good idea to copy the header of a file when
the file is copied.

It is a good idea to copy the header when:

29

a) copying an executable program file so that the additional file information is
preserved,

b) copying a file over a pure byte serial link so that the communications
software will know in advance the length of the file.

It is a bad idea to copy the header when:

c) copying a text file to a printer because the header will be likely to have
control codes and spurious or unprintable characters.

The general rules used by the COPY procedures in SMSQ/E, are that the header is only
copied if there is additional information in the header. This caters for cases (a) and (c)

above. A COPY_N command is included for compatibility with the standard QL COPY_N: this never copies the header. A COPY_H command is included to copy a file with the
header to cater for case (b) above. (Note that the standard QL command COPY always
copies the header.) Neither COPY_N nor COPY_H need ever be used for file to file
copying.

A second general rule used by the COPY (as well as by the WREN) procedures is that if the destination file already exists, then the user will be asked to confirm that overwriting the old file is acceptable. The COPY_O (copy overwrite) and the spooler procedures do not
extend this courtesy to the user.

If the commands are given with two filenames then the data default directory is used for
both files. If, however, only one filename (or, in the case of the wild card procedures, no
name at all) is given then the destination will be derived from the destination default:

a) if the destination default is a directory (ending with ' _', set by DEST_USE)

then the destination file is the destination default followed by the name,

b) if the destination default is a device (not ending with ' _' , set by SPL_USE) then the destination is the destination default unmodified.

syntax:

COPY name TO name

{copy a file}

COPY_O name TO name

{copy a file (overwriting)}

COPY_N name TO name

{copy a file (without header)}

COPY_H name TO name

{copy a file (with header)}

These commands can be given with one or two names. The separator ' TO' is used for
clarity, you may use a comma instead.

To illustrate the use of the copy command, assume that the data default is FLP2_ and the destination default is FLP1_.

30
example: i. COPY fred TO old_fred

{copies flp2_fred to flp2_old_fred}

ii. COPY fred, ser

{copies flp2_fred to ser}

iii. COPY fred

{copies flp2_fred to flp1_fred}

iv. SPL_USE ser

....

COPY fred

{copies flp2_fred to ser}

The interactive copying procedure WCOPY is used for copying all or selected parts of
directories. The command may be given with both source and destination wild card names,
with one wild card name or with no wild card names at all. Giving the command with no
wild card names has the same effect as giving one null name:

WCOPY and WCOPY '' are the same.

If you get confused by the following rules about the derivation of the copy destination, just
use WCOPY intuitively and look carefully at the prompts.

If the destination is not the destination default device, then the actual destination file name for each copy operation is made up from the actual source file name and the destination
wild name. If a missing section of the source wild name is matched by a missing section of
the destination wild name, then that part of the actual source file name will be used as the
corresponding part of the actual destination name. Otherwise the actual destination file
name is taken from the destination wild name. If there are more sections in the destination
wild name than in the source wild name, then these extra sections will be inserted after the
drive name, and vice versa.

syntax:

WCOPY [# channel,] name TO name

The separator TO is used for clarity, you may use a comma instead.

If the channel is not given (i.e. most of the time), then the requests for confirmation will be sent to the command channel #0. Otherwise confirmation will be sent to the chosen
channel, and the user is requested to press one of:

Y (yes)

copy this file

N (no)

do not copy this file

A (all)

copy this and all the next matching files.

Q (quit)

do not copy this or any other files

If the destination file already exists, the user is requested to press one of:

Y (yes)

copy this file, overwriting the old file

N (no)

do not copy this file

A (all)

overwrite the old file, and overwrite any other files requested to be
copied.

Q (quit)

do not copy this or any other files

31

example: If the default data directory is flp2_, and the default destination is flp1_

i. WCOPY

{would copy all files on flp2_ to flp1_}

ii. WCOPY flp1_,flp2_

{would copy all files on flp1_ to flp2_}

iii. WCOPY fred

{would copy flp2_fred to flp1_fred

flp2_freda_list to flp1_freda_list}

iv. WCOPY fred,mog

{would copy flp2_fred to flp2_mog

flp2_freda_list to flp2_moga_list}

v. WCOPY _fred,_mog

{would copy flp2_fred to flp2_mog

flp2_freda_list to flp2_moga_list

flp2_old_fred to flp2_old_mog

flp2_old_freda_list to

flp2_old_moga_list}

vi. WCOPY _list,old__

{would copy flp2_jo_list to

flp2_old_jo_list

flp2_freda_list to

flp2_old_freda_list}

vii. WCOPY old__list,flp1__ {would copy flp2_old_jo_list to

flp1_jo_list

flp2_old_freda_list to flp1_freda_list}

COS
math functions

COS will compute the cosine of the specified argument.

syntax:

angle:= numeric_expression

{range -10000..10000 in radians}

COS ( angle)

example: i. PRINT COS(theta)

ii. PRINT C0S(3.141592654/2)

COT
maths functions

COT will compute the cotangent of the specified argument.

32
syntax:

angle:= numeric_expression

{range -30000..30000 in radians}

COT ( angle)

example: i. PRINT COT(3)

ii. PRINT C0T(3.141592654/2)

CSIZE
window

Sets a new character size for the window attached to the specified or default channel.

The standard size in 512 x 256 QL colour mode is, 0,0 in 512 mode and 2,0 in 256 mode.

In other screen resolutions the standard size 0,0.

Width defines the horizontal size of the character space. Height defines the vertical size of
the character space. The character size is adjusted to fill the space available.

Width
size

height
size

0

6 pixels

0

10 pixels

1

8 pixels

1

20 pixels

2

12 pixels

3

16 pixels

syntax:

width:= numeric_expression

{range 0..3}

height:= numeric_expression

{range 0..1}

CSIZE [ channel,] width, height

example: i. CSIZE 3,0

ii. CSIZE 3,1

CURSEN

CURDIS
windows

The function INKEY$ is designed so that keystrokes may be read from the keyboard
without enabling the cursor. Two procedures are supplied to enable and disable the cursor.

33

When the cursor is enabled, it will usually appear solid (inactive). The cursor will start to
flash (active) when the keyboard queue has been switched to the window with the cursor

(e.g. by an INKEY$).

syntax:

CURSEN # channel

{enable the cursor}

CURDIS # channel

{disable the cursor}

example: 10 CURSEN

{enable the cursor in window #1}

20 in$=INKEY$ (#1,250)

{wait for up to 5 seconds for a character from the
keyboard. If nothing is typed within the 5 seconds,
then in$ will be set to a null string ("")}

30 CURDIS

comment: Note that while CURSEN and CURDIS default to channel #1, like most I/O
commands, INKEY$ defaults to channel #0.

CURSOR
windows

CURSOR allows the screen cursor to be positioned anywhere in the window attached to
the specified or default channel.

CURSOR uses the pixel coordinate system relative to the window origin and defines the position for the top left hand corner of the cursor. The size of the cursor is dependent on
the character size in use.

If CURSOR is used with four parameters then the first pair is interpreted as graphics coordinates (using the graphics coordinate system) and the second pair as the position of
the cursor (in the pixel coordinate system) relative to the first point.This allows diagrams to be annotated relatively easily.

syntax:

x:= numeric_expression

y:= numeric_expression

CURSOR [ channel,] x, y [, x, y]

example: i. CURSOR 0,0

ii. CURSOR 20,30

iii. CURSOR 50,50,10,10

34

DATA

READ

RESTORE

BASIC

READ, DATA and RESTORE allow embedded data, contained in a SBASIC program, to be assigned to variables at run time.

DATA is used to mark and define the data, READ accesses the data and assigns it to variables and RESTORE allows specific data to be selected.

DATA
allows data to be defined within a program. The data can be read by a READ
statement and the data assigned to variables. A DATA statement is ignored by

SBASIC when it is encountered during normal processing.

syntax:

DATA *[ expression,]*

READ
reads data contained in DATA statements and assigns it to a list of variables.

Initially the data pointer is set to the first DATA statement in the program
and is incremented after each READ. Re-running the program will not reset the
data pointer and so in general a program should contain an explicit RESTORE.

An error is reported if a READ is attempted for which there is no DATA.

syntax:

READ *[ identifier,l*

RESTORE restores the data pointer, i.e. the position from which subsequent READs will read their data. If RESTORE is followed by a line number then the data
pointer is set to that line. If no parameter is specified then the data pointer is
reset to the start of the program.

syntax:

RESTORE [ line_number]

example: i. 100 REMark Data statement example

110 DIM weekdays$(7,4)

120 RESTORE

130 FOR count= 1 TO 7 : READ weekdays$(count)

140 PRINT weekday$

150 DATA "MON","TUE","WED","THUR","FRI"

160 DATA "SAT","SUN"

ii. 100 DIM month$(12,9)

110 RESTORE

120 REMark Data statement example

130 FOR count=1 TO 12 : READ month$(count)

140 PRINT month$

150 DATA "January", "February", "March"

35

160 DATA "April","May","June"

170 DATA "July","August","September"

180 DATA "October","November","December"

warning: An implicit RESTORE is not performed before running a program. This allows a single program to run with different sets of data. Either include a RESTORE in
the program or perform an explicit RESTORE or CLEAR before running the
program.

DATA$

PROG$

DESTD$
defaults functions

DATA$, PROG$, and DESTD$ are functions to find the current data, program, and
destination defaults.

syntax:

DATAD$

{find the data default}

PROGD$

{find the program default}

DESTD$

{find the destination default}

comment: The functions to find the individual defaults should be used without any
parameters.

example: i. IF DATAD$<>PROGD$: PRINT 'Separate directories'

ii. DEST$=DESTD$

IF DEST$ (LEN (DEST$))='_': PRINT 'Destination'! DEST$

DATA_USE
data default

DATA_USE is used to set a default, which is added to most of the filing system
commands. If you do not supply a complete SMSQ/E filename in the command, the

DATA_USE default will be added to the beginning of the supplied filename.

If the supplied filename is not found in the system, Then the DATA_USE default will be
added to the beginning of the supplied filename, and another attempt will be made to
execute the command.

syntax:

directory_name := device*[ subdirectory_]*

DATA_USE directory_name

36

example: 100 DATA_USE win1_programs_

110 DIR

{Gives a directory of “win1_programs_”}

120 LOAD draw

{Loads the program “win1_programs_draw}

comment: If the directory name supplied does not end with '_', '_' will be appended to the
directory name.

DATE$

DATE
clock

DATE$ is a function which will return the date and time contained in the QPC’s clock. The format of the string returned by DATE$ is:

" yyyy mmm dd hh: mm: ss"

where
yyyy is the year 1984, 1985, etc

mmm is the month Jan, Feb etc

dd
is the day 01 to 28, 29, 30, 31

hh
is the hour 00 to 23

mm
are the minutes 00 to 59

ss
are the seconds 00 to 59

DATE will return the date as a floating point number which can be used to store dates and times in a compact form.

If DATE$ is used with a numeric parameter then the parameter will be interpreted as a
date in floating point form and will be converted to a date string.

syntax:

DATE$

{get the time from the clock)

DATE$ ( numeric_expression)

{get time from supplied parameter}

DATE [ ( yyyy, m, d, h, m, s) ]

example: i. PRINT DATE$

{output the date and time}

ii. PRINT DATE$(234567)

{convert 234567 to a date}

iii. PRINT DATE

{output today’s date as a floating point
number}

iv. PRINT DATE (2002,7,23,10,32,15)

{output 23rd July 2002 at 10:32:15 as a
floating point number}

37

DAY$
clock

DAY$ is a function which will return the current day of the week. If a parameter is specified then DAY$ will interpret the parameter as a date and will return the corresponding day of the week.

syntax:

DAY$

{get day from clock}

DAY$ ( numeric_expression)

{get day from supplied parameter}

example: i. PRINT DAY$

{output the day}

ii. PRINT DAY$(234567)

{output the day represented by 234567

(seconds)}

DDOWN

DUP

DNEXT
directory navigation

These three commands are provided to move through a directory tree.

DDOWN moves down through the directory tree, DUP move up through the directory tree, and DNEXT moves up and then down a different branch of the tree.

It is not possible to move up beyond the drive name using the DUP command. At no time
is the default name length allowed to exceed 32 characters.

These commands operate on the data default directory. By appending directories onto the
end of , or stripping directories off of the end of the default. Under certain conditions they
may operate on the other defaults as well:

If the progam default is the same as the data default, then the two defaults are linked and
these commands will operate on the PROG_USE default as well.

If the destination default ends with ' _' (i.e. it is a default directory rather than a default device), then these commands will operate on the destination default.

syntax:

DDOWN name

DUP

DNEXT name

example:

defaults

data

program
destination
initial values
flp2_
flp1_
ser

38

DDOWN john
flp2_john_
flp1_
ser

DNEXT fred
flp2_fred_
flp1_
ser

PROG_USE flp2_fred flp2_fred_
flp2_fred_
ser

DNEXT john
flp2_john_
flp2_john_
ser

DUP

flp2_
flp2_
ser

DEST_USE flp1
flp2_
flp2_
flp1_

DDOWN john
flp2_john_
flp2_john_
flp1_john_

SPL_USE ser1c
flp2_john_
flp2_john_
ser1c

DEFine

FuNction

END DEFine
functions and procedures

DEFine FuNction defines a SBASIC function. The sequence of statements between the

DEFine function and the END DEFine constitute the function.

The function definition may also include a list of formal parameters which will supply data for the function. Both the formal and actual parameters must be enclosed in brackets. If the function requires no parameters then there is no need to specify an empty set of brackets.

Formal parameters take their type and characteristics from the corresponding actual parameters. The type of data returned by the function is indicated by the type appended to the function identifier. The type of the data returned in the RETURN statement must match.

An answer is returned from a function by appending an expression to a RETurn statement.

The type of the returned data is the same as type of this expression.

A function is activated by including its name in a SBASIC expression.

Function calls in SBASIC can be recursive; that is, a function may call itself directly or
indirectly via a sequence of other calls.

syntax:

formal_parameters= ( expression *[, expression]*)

actual_parameters:= ( expression *[, expression]*)

type:= | $

| %

|

DEF FuNction identifier type { formal_parameters}

[LOCal identifier *[, identifier]*]

statements

RETurn expression

END DEFine

39

RETurn can be at any position within the procedure body. LOCal statements
must preceed the first executable statement in the function.

example: 10 DEFine FuNction mean(a, b, c)

20 LOCaL answer

30 LET answer = (a + b + c)/3

40 RETurn answer

50 END DEFine

60 PRINT mean(1,2,3)

comment: To improve legibility of programs the name of the function can be appended to
the END DEFine statement. However, the name will not be checked by

SBASIC.

DEFine

PROCedure

END DEFine
functions and procedures

DEFine PROCedure defines a SBASIC procedure. The sequence of statements between
the DEFine PROCedure statement and the END DEFine statement constitutes the
procedure. The procedure definition may also include a list of formal parameters which will supply data for the procedure. The formal parameters must be enclosed in brackets for the procedure definition, but the brackets are not necessary when the procedure is called. If
the procedure requires no parameters then there is no need to include an empty set of
brackets in the procedure definition.

Formal parameters take their type and characteristics from the corresponding actual
parameters.

Variables may be defined to be LOCal to a procedure. Local variables have no effect on
similarly named variables outside the procedure. If required, local arrays should be
dimensioned within the LOCal statement.

The procedure is called by entering its name as the first item in a SBASIC statement
together with a list of actual parameters. Procedure calls in SBASIC are recursive that is, a
procedure may call itself directly or indirectly via a sequence of other calls.

It is possible to regard a procedure definition as a command definition in SBASIC; many of
the system commands are themselves defined as procedures.

syntax:

formal_parameter:= ( expression *[, expression]*)

actual_parameters:= expression *[, expression]*

40

DEFine PROCedure identifier [ formal_parameters]

[LOCal identifier *[, identifier]*]

statements

[RETurn]

END DEFine

RETURN can appear at any position within the procedure body. If present the

LOCal statement must be before the first executable statement in the
procedure. The END DEFine statement will act as an automatic return.

example: i. 100 DEFine PROCedure start_screen

110 WINDOW 100,100,10,10

120 PAPER 7 : INK O : CLS

130 BORDER 4,255

140 PRINT "Hello Everybody"

150 END DEFine

160 start_screen

ii. 100 DEFine PROCedure slow_scroll(scroll_limit)

110 LOCal count

120 FOR count =1 TO scroll

130 SCROLL 2

140 END FOR count

150 END DEFine

160 slow_scroll 20

comment: To improve legibility of programs the name of the procedure can be appended
to the END DEFine statement. However, the name will not be checked by

SBASIC.

DEG
maths functions

DEG is a function which will convert an angle expressed in radians to an angle expressed in degrees.

syntax:

DEG( numeric_expression)

example: PRINT DEG(PI/2)

{will print 90}

41

DELETE

WDEL
directory devices

DELETE will remove a file from the directory of the directory device specified.

WDEL will remove multiple files from the directory of the directory device specified, using wild card names.

No error is generated if the file is not found.

syntax:

DELETE name

{delete one file}

WDEL [# channel,] name

{delete files}

example: i. DELETE flp1_old_data

ii. DELETE win1_letter_file

For WDEL both the channel and the name are optional.

iii. WDEL

{delete files from current directory}

iv. WDEL _list

{delete all _list files from current directory}

comment: Unless a channel is specified, the wild card deletion procedures use the
command window #0 to request confirmation of deletion. There are four
possible replies:

Y

(yes) delete this file

N

(no)

do not delete this file

A

(all)

delete this and all the next matching files

Q

(quit) do not delete this or any of the next files

DEL_DEFB
memory management

DEL_DEFB will delete file definition blocks from common heap.

Making large allocations in the common heap and then accessing a drive for the first time.

Can cause a terrible heap disease called 'large scale fragmentation' where the drive
definition blocks become widely scattered in the heap leaving large holes that cease to be
available except as heap entries (i.e. you cannot load programs into them). A simple but
dangerous cure is to delete the drive definition blocks.

syntax:

DEL_DEFB

42
comment: Although there are precautions within the procedure DEL_DEFB to minimise
damage, care should be taken to avoid using this command while any directory
device is active.

DEST_USE
destination default

DEST_USE is used to set a default, which is used to find the destination filename when
the file copying and renaming commands (SPL, COPY, RENAME etc.) are used with only one filename.

If the supplied filename is not found in the system, Then the DEST_USE default will be
added to the beginning of the supplied filename, and another attempt will be made to
execute the command.

syntax:

directory_name := device*[ subdirectory_]*

DEST_USE directory_name

example: 100 DEST_USE win1_programs_

110 COPY flp1_john TO fred

{Copies the file “flp1_john” to the file

“win1_programs_fred”}

comment: There is a special form of the DEST_USE command which does not append '_'

to the name given. Notionally this provides the default destination device for the
spooler. See SPL_USE.

DEVTYPE
devices

DEVTYPE returns a value indicating whether the specified or default channel is open to a window, or to a file.

Only the most significant bit, and the two least significant bits should be tested. All other
bits are unidentified. The value returned is negative if the channel is not open. Bit 0
indicates that the channel is open to a window, Bit 1 indicates that the channel is open to a
file.

The values returned in the two least significant bits are –

0 - Purely serial device

1 - Window

2 - Direct access file

syntax:

DEVTYPE [ (# channel ) ]

43

example: i. PRINT DEVTYPE

ii. PRINT DEVTYPE (#4)

iii. PRINT 3 && DEVTYPE(#6)

iv. IF DEVTYPE(#4) < 0 then PRINT "Channel is closed"

DEV_LIST

DEV_USE$

DEV_NEXT$
devices

DEV_LIST is a command to list to the specified or default channel the DEV device
allocations.

DEV_USE$ returns the DEV device usage for the supplied DEV device number.

DEV_NEXT$ returns the next DEV in the chain after the supplied device number.

syntax:

device := numeric_expression

DEV_LIST [# channel]

DEV_USE$ ( device)

DEV_NEXT$ ( device)

example: i. DEV_LIST#3

{Lists current DEV’s to #3}

ii. PRINT DEV_USE$(3)

{Prints the usage for DEV3_}

iii. PRINT DEV_NEXT$(1)

{Prints the next DEV in the chain after
dev1_}

DEV_NEXT
directory devices

DEV_NEXT returns the next DEV after the specified DEV.

syntax:

DEV_NEXT ( numeric_expression )

example: PRINT DEV_NEXT(1)

{prints the next DEV In the chain after

DEV1}

DEV_USEN
directory devices

44

DEV_USEN allows renaming of the DEV device. Both DEV_USE or DEV_USEN with one parameter will rename the DEV device, DEV_USEN without parameter will reset the name
of DEV back to DEV.

syntax:

DEV_USEN [ name ]

example: i. DEV _USEN mdv

{DEV is now called MDV}

ii. DEV _USEN

{and now its name is DEV again}

DEV_USE
directory devices

DEV_USE allows you to attach a DEV device to a real directory.

There is a variation on the DEV_USE call which enables the setting up of default chains. If you put another number at the end of the DEV_USE command it will be taken as the DEV
to try if the open fails. This next DEV can also chain to another DEV. The DEV driver stops
chaining when all DEV’s in the chain have been tried.

syntax:

DEV_USE [ device_number , real_directory [ , chain ] | device ]

example: i. DEV_USE 1,ram1_

{dev1_ is equivalent to ram1_}

ii. DEV_USE 2,flp1_letters_

{dev2_ is equivalent to flp1_letters_}

iii. DEV_USE 3,win1_work_new_ {dev3_ is equivalent to win1_work_new}

iv. DEV_USE 4, ram2_,5

{dev4_ is equivalent to ram2_}

v. DEV_USE 5,flp1_latest_,6

{dev5_ is equivalent to flp1_latest_

vi. DEV_USE 6,win1_work_,4

{dev6_ is equivalent to win1_work_}

comment: Unlike PROG_USE and DATA_USE, the underscore at the end is significant.

Thus, entering the above commands:

OPEN#3,dev1_f1

Opens “ram1_f1”

OPEN#3,dev2_bankmanager Opens “flp1_letters_bankmanager”

OPEN#3,dev3_f1

Opens “win1_work_newf1”

DELETE dev3__junk

Deletes “win1_work_new_junk”

LOAD dev4_prog_bas

Tries “ram2_prog_bas”, then “flp1_latest_ prog_bas”, and
then finally “win1_work_prog_bas”

LOAD dev5_DiskCheck

Tries “flp1_latest_DiskCheck”, then

“win1_work_DiskCheck”, and finally “ram2_DiskCheck”

DELETE does not chain with DEV.

The DEV name can be changed by specifying a three letter name of string.

DEV_USE without any parameters will reset the name to DEV.

45

DEV_USE 1,flp2_myprogs_

“dev1_” is “myprogs_ “on drive 2}

DEV_USE 2,flp1_ex_,1

“dev2_” is “flp1_ex_”, or “flp2_myprogs_”

DEV_USE flp

“flp1_ “is now really “flp2_myprogs_and “flp2_“ is

“flp1_ex_”}

DEV_USE

“flp1_” is now “flp1_” again

DIM
arrays

Defines an array to SBASIC. String, integer and floating point arrays can be defined. String arrays handle fixed length strings and the final index is taken to be the string length.

Array indices run from 0 up to the maximum index specified in the DIM statement; thus

DIM will generate an array with one more element in each dimension than is actually
specified.

When an array is specified it is initialised to zero for a numeric array and zero length
strings for a string array.

syntax:

index:= numeric_expression

array:= indentifier( index *[, index]*)

DIM array *[, array] *

example: i. DIM string_array$(10,10,50)

ii. DIM matrix(100,100)

DIMN
arrays

DIMN is a function which will return the maximum size of a specified dimension of a
specified array. If a dimension is not specified then the first dimension is assumed. If the
specified dimension does not exist or the identifier is not an array then zero is returned.

syntax: array:= identifier

index:= numeric_expression

{1 for dimension 1, etc.}

DIMN( array [, dimension])

example: consider the array defined by: DIM a(2,3,4)

i. PRINT DIMN(A,1)

{will print 2}

ii. PRINT DIMN(A,Z)

{will print 3}

iii. PRINT DIMN(A,3)

{will print 4}

iv. PRINT DIMN(A)

{will print 2}

46

v. PRINT DIMN(A,4)

{will print 0}

DIR
directory devices

DIR will obtain and display in the window attached to the specified or default channel the directory of the disk drive in the specified directory device.

syntax: DIR device

The device specification must be a valid directory device

The directory format output by DIR is as follows:

format:=
disk format operating system QDOS or MSDOS

density:=
formatting density SD, DD, or HD

free_sectors:=
the number of free sectors

available_sectors:= the maximum number of sectors on this disk drive

file_name:=
a SBASIC file name

screen format:

Volume name format density
free_sectors | available_sectors

sectors

file_name

......

file_name

example: i. DIR flp1_

ii. DIR "dev2_ "

iii. DIR "win" & hard_drive_number$ & "_"

screen format: BASIC QDOS HD

183 / 221 sectors

demo_1

demo_1_old

demo_2

DISP_BLANK

DISP_BLANK has no effect in QPC.

47

DISP_COLOUR
graphics device 2

DISP_COLOUR specifies the colour depth to be used

0 for QL

1 for 4 bit

2 for 8 bit

3 for 16 bit

4 for 24 bit.

It is possible to specify the display size immediately after the colour depth.

The parameters from frame rate onwards may be specified, but appear to have no effect in

QPC.

syntax:

colour_depth := numeric_expression

xsize := numeric_expression

ysize := numeric_expression

DISP_COLOUR colour_depth [ ,xsize [ ,ysize ]]

example: DISP_COLOUR 3, 800, 600

{specifies an 800x600 16 bit display}

DISP_INVERSE

DISP_INVERSE has no effect in QPC.

DISP_RATE

DISP_RATE has no effect in QPC.

DISP_SIZE
graphics device 2

DISP_SIZE allows the screen resolution to be changed.

Its use is not recommended as it causes strange results, and only seems to work in a

Microsoft Windows, window (not in full screen mode).

The parameters from frame rate onwards may be specified, but appear to have no effect in

QPC.

48

syntax:

xsize := numeric_expression

ysize := numeric_expression

DISP_SIZE xsize [ ,ysize ]

DISP_TYPE
graphics device 2

DISP_TYPE will return a value indicating the type of display you are using.

syntax:

DISP_TYPE

example: PRINT DISP_TYPE

DIV
operator

DIV is an operator which will perform an integer divide.

syntax:

numeric_expression DIV numeric_expression

example: i. PRINT 5 DIV 2

{will output 2}

ii. PRINT -5 DIV 2

{will output -3}

DLINE

BASIC

DLINE will delete a single line or a range of lines from a SBASIC program.

syntax: range:=

| line_number TO line_number (1)

| line_number TO

(2)

| TO line_number

(3)

| line_number

(4)

DLINE range*[, range]*

where (1) will delete a range of lines

(2) will delete from the specified line to the end

(3) will delete from the start to the specified line

(4) will delete the specified line

example: i. DLINE 10 TO 70, 80, 200 TO 400

{will delete lines 10 to 70 inclusive, line 80 and lines 200 to 400 inclusive}

49

ii. DLINE

{will delete nothing}

DLIST
defaults functions

DLIST will display in the default, or specified window the three defaults (data, program, and
destination).

syntax:

DLIST [ channel]

DLIST \name

DMEDIUM_NAME$

DMEDIUM_DRIVE$

DMEDIUM_RDONLY

DMEDIUM_REMOVE

DMEDIUM_DENSITY

DMEDIUM_FORMAT

DMEDIUM_TYPE

DMEDIUM_TOTAL

DMEDIUM_FREE
directory devices

The DMEDIUM_XXX set of functions can be used to obtain information about a device
driver or a medium which is currently driven by this driver, which could not be obtained
easily in the past (or not at all).

DMEDIUM_NAME$

Returns the medium name of the specified device.

DMEDIUM_DRIVE$

Returns the real device name of the specified file or device. This is
the only way to check if the access is done to the device it is
intended to be done, as devices may be renamed using

RAM_USE, FLP _USE, WIN_USE etc. This function also allows
you to discover the "real" device which may be hidden behind

"DEV".

DMEDIUM_RDONLY Returns 1 if the medium is write-protected, otherwise 0. It checks
the various possibilities of write protection, even the software
write-protection which is possible for hard disks and removable
hard disks.

DMEDIUM_REMOVE Returns 1 if the specified device is a removable hard disk.

50

DMEDIUM_DENSITY Returns the density: 1=DD, 2=HD etc. RAM-Disks return -1, as
they have no density.

DMEDIUM_FORMAT Returns the logical format of the medium or partition:

1=QDOS/SMSQ, 2=DOS/TOS.

DMEDIUM_TYPE

Returns information about the physical drive: 0=RAM-Disk,

1=Floppy

Disk, 2=Harddisk, 3=CD-ROM.

DMEDIUM_TOTAL

Returns the total number of free sectors (in 512 bytes sectors).

DMEDIUM_FREE

Returns the number of free sectors (in 512 bytes sectors).

These functions should be used on directory devices (RAM, FLP, WIN etc.) only. The
parameter passed to these functions can either be a channel number (#channel) or a

\directory or \file.

syntax:

DMEDIUM_xxx ( # channel | \ directory | \ file ) example: i. 10 OPEN #3,flp1_boot

20 PRINT DMEDIUM_NAME$(#3)

{what's the name of the disk in
flp1_}

30 CLOSE #3

40 PRINT DMEDIUM_NAME$(\win1_) {returns the name of WIN 1_}

ii. 10 DEV_USE 1,win1_

{DEV1_ accesses WIN1_}

20 OPEN_NEW #3,dev1_test

{let's open a new file}

30 PRINT DMEDIUM_DRIVE$(#3)

{really, it's on WIN1_}

40 CLOSE #3

iii. PRINT DMEDIUM_RDONLY(\flp1_)

iv. PRINT DMEDIUM_REMOVE(\win2_)

v. PRINT DMEDIUM_DENSITY(#4)

vi. PRINT DMEDIUM_FORMAT(flp2_)

vii. PRINT DMEDIUM_TYPE(dev2_)

viii. PRINT DMEDIUM_TOTAL(#3)

ix. PRINT DEMDUIM_FREE(#3)

DO
program

DO will execute a series of SBASIC commands from file.

The commands should be 'direct': any lines with line numbers will be merged into the
current SBASIC program. The file should not contain any of the following commands.

RUN, LRUN, MRUN, MERGE, SAVE, SAVE_O, LOAD, STOP, NEW, CLEAR, CONTINUE, RETRY or GOTO.

51

A DO file should be able to invoke SBASIC procedures without harmful effect.

syntax:

DO name

comment: A DO file can contain in line clauses:

FOR i=1 to 20: PRINT 'This is a DO file'

If you try to RUN a BASIC program from a DO file, then the file will be left open.

Likewise, if you put direct commands in a file that is MERGED, then the file will
be left open.

DOS_USE
directory devices

DOS_USE allows renaming of the DOS device. DOS_USE without a parameter will reset the name of DOS back to DOS.

syntax:

DOS_USE [ name ]

example: i. DOS _USE win : LOAD win2_prog

{loads 'prog' from DOS2_ }

ii. DOS _USE

{and now its name is DOS again}

iii. DOS_USE ram : DIR ram1_

{displays directory of DOS1_}

ED

EDIT

ED is a window based editor for editing SBASIC programs which are already loaded into

QPC.

If no line number is given, the first part of the program is listed, otherwise the listing in the window will start at or after the given line number. If no channel number is given, the listing will appear in the normal SBASIC edit window #2. If a window is given, then it must be a

CONsole window, otherwise a 'bad parameter' error will be returned. The editor will use the current ink and paper colours for normal listing, while using white ink on black paper (or
vice versa if
the paper is already black or blue) for 'highlighting'. Please avoid using window #0 for the

ED.

The editor makes full use of its window. Within its window, it attempts to display complete
lines. If these lines are too long to fit within the width of the window, they are 'wrapped
around' to the next row in the window: these extra rows are indented to make this 'wrap
around' clear. For ease of use, however, the widest possible window should be used.

52

The ESC key is used to return to the SBASIC command mode.

After ED is invoked, the cursor in the edit window may be moved using the arrow keys to
select the line to be changed. In addition the up and down keys may be used with the ALT
key (press the ALT key and while holding it down, press the up or down key) to scroll the window while keeping the cursor in the same place, and the up and down keys may be
used with the SHIFT key to scroll through the program a 'page' at a time.

The editor has two modes of operation: insert and overwrite. To change between the two
modes use ' CTRL F4' (press CTRL and while holding it down press F4). There is no difference between the modes when adding characters to or deleting characters from the
end of a line. Within a line, however, insert mode implies that the right hand end of a line
will be moved to the right when a character is inserted, and to the left when a character is
deleted. No part of the line is moved in overwrite mode. Trailing spaces at the end of a line
are removed automatically.

If you press F10 while the cursor is over a program line, then this line is put (without line number) into the HOTKEY Buffer. It can easily be retrieved by pressing ALT SPACE in
any program where input is expected. In order to work, the HOTKEY System has to be
going (use HOT_GO to activate).

To insert a new line anywhere in the program, press ENTER. If there is no room between
the line the cursor is on and the next line in the program (e.g. the cursor is on line 100 and
the next line is 101) then the ENTER key will be ignored, otherwise a space is opened up below the current line, and a new line number is generated. If there is a difference of 20 or
more between the current line number and the next line number, the new line number will
be 10 on from the current line number, otherwise, the new line number will be half way
between them.

If a change is made to a line, the line is highlighted: this indicates that the line has been
extracted from the program. The editor will only replace the line in the program when

ENTER is pressed, the cursor is moved away from the line, or the window is scrolled. If the line is acceptable to SBASIC, it is rewritten without highlighting. If, however, there are
syntax errors, the message 'bad line' is sent to window #0, and the line remains
highlighted.

While a line is highlighted, ESC may be used to restore the original copy of the line,
ignoring all changes made to that line.

If a line number is changed, the old line remains and the new line is inserted in the correct
place in the program. This can be used to copy single lines from one part of the program to
another.

53

If all the visible characters in a line are deleted, or if all but the line number is deleted, then the line will be deleted from the program. An easier way to delete a line is to press CTRL
and ALT and then the left arrow as well.

The length of lines is limited to about 32766 bytes. Any attempt to edit longer lines may
cause undesirable side effects. If the length of a line is increased when it is changed, there
may be a brief pause while SBASIC moves its working space.

syntax:

line_number := numeric_ expression

ED [ channel,] [ line_number]

summary of Edit operations:

TAB
tab right (columns of 8)

SHIFT TAB
tab left (columns of 8)

ENTER
accept line and create a new line

ESC
escape - undo changes or return to SBASIC

up arrow
move cursor up a line

down arrow
move cursor down a line

ALT up arrow
scroll up a line (the screen moves down!)

ALT down arrow
scroll down a line (the screen moves up!)

SHIFT up arrow
scroll up one page

SHIFT down arrow
scroll down one page

left arrow
move cursor left one character

right arrow
move cursor right one character

SHIFT left arrow
move cursor left one word

SHIFT right arrow
move cursor right one word

ALT left arrow
move to start of line

ALT right arrow
move to end of line

CTRL left arrow
delete character to left of cursor

CTRL right arrow
delete character under cursor

CTRL SHIFT left arrow
delete word to left of cursor

CTRL SHIFT right arrow
delete word to right of cursor

CTRL ALT left arrow
delete line to left of cursor

CTRL ALT right arrow
delete line to right of cursor

54

CTRL down arrow
delete whole line

F9 or SHIFT F4
change between overwrite and insert mode

F10 or SHIFT F5
when the cursor is over a program line, then this
line is put (without line number) into the HOTKEY

Buffer. It can easily be retrieved by pressing ALT

SPACE in any program where input is expected. In
order to work, the HOTKEY System has to be
going (use HOT_GO to activate)

comment: ED must not be called from within a SBASIC program.

EOF
devices

EOF is a function which will determine if an end of file condition has been reached on a specified channel. If EOF is used without a channel specification then EOF will determine if the end of a program's embedded data statements has been reached.

syntax:

EOF [( channel)]

example: i. IF EOF(#6) THEN STOP

ii. IF EOF THEN PRINT "Out of data"

EOFW

Appears to be the same function as EOF

EPROM_LOAD

EPROM_LOAD will load an image of a QL EPROM cartridge. Most EPROM cartridges are
programmed so that the cartridge may be at any address.

Some require to be at exactly $C000, the QL ROM port address. The first time the
command is used after reset, the EPROM image will be loaded at address $C000.

Subsequent images may be loaded at any address. Fussy EPROM images must,
therefore, be loaded first.

An EPROM image file must not be longer than 16 kilobytes.

syntax:

EPROM_LOAD filename

55
example: EPROM_LOAD flp1_Qleprom

comment: To make an EPROM image, put the EPROM cartridge into a QL and turn on.

SBYTES the image to a suitable file with the magic numbers 49152 ($C000) for
the base address and 16384 (16 kilobytes) for the length. .

SBYTES flp1_eprom, 49152, 16384 {Save EPROM image}

In QPC copy the file to your boot diskette or disk and add the EPROM_LOAD
statement to your "boot" file.

EPROM_LOAD flp1_eprom

{Load EPROM image}

ERLIN

ERNUM
error handling

ERLIN is a function that will return the line number where an error has occurred.

ERNUM is a function that will return the error number.

ERLIN and ERNUM should only be used as direct commands from the keyboard, or within a WHEN ERROR clause.

syntax:

ERLIN

ERNUM

example: i. PRINT ERLIN

ii. last_error = ERNUM

ERT
hotkey system

ERT will report the error and stop if its parameter value is negative. If it is not negative then ERT will report nothing and continue processing the next statement.

As well as the Hotkey functions. ERT can be used with any function, which returns an error
code.

syntax:

ERT function

example: i. ERT HOT_LOAD ('x', flp1_program)

{report error if hotkey in use, or file
not found}

ii. ERT –9

{gives "in use" error}

56

EX

EXEC

EW

EXEC_W

ET

SMSQ/E

EX and EW will load a sequence of programs and execute them in parallel.

EX will return to the command processor after all processes have started execution, EW
will wait until all the processes have terminated before returning.

ET sets up the programs, but returns to SBASIC so that a debugger can be called to trace the execution.

EXEC is the same as EX, and EXEC_W is the same as EW.

syntax:

program := device

parameters := string_expression

file := filename, or channel_number

EX program [ *, file * ] [; parameters]

EX program [ *, file * ] [; parameters]

In this case the program in the file 'name' is loaded into the transient program
area, the string is pushed onto its stack and execution is initiated.

Finally it is possible for EX to open input and output files for a program as well as (or instead of) passing it parameters. If preferred, a SBASIC channel number may be used
instead of a filename. A channel used in this way must already be open.

example: The program UC converts a text file to upper case, the command:

EX uc, flp1_fred, #1

{load and initiate the program UC, with the file
flp1_fred as its input file, and the output being
sent to window #1.}

EX is designed to set up filters for processing streams of data.

Within the QPC it is possible to have a chain of co-operating jobs engaged in processing
the same data in a form of production line. When using a production line of this type, each
job performs a well-defined part of the total process. The first job takes the original data
and does its part of the process; the partially processed data is then passed on to the next

57
job which carries out its own part of the process; and so the data gradually passes through
all the processes. The data is passed from one Job to the next through a 'pipe'. The data
itself is termed a 'stream' and the Jobs processing the data are termed 'filters'.

the complete form of the EX command is

prog_spec := program [ *, file * ] [; parameters EX [# channel TO] prog_spec [ * TO prog_spec * ] [TO # channel]

Each TO separator creates a pipe between Jobs.

All the program names and the parameter string may be names, strings or string
expressions. The significance of the filenames is, to some extent, program dependent; but
there are two general rules which should be used by all filters:

the primary input of a filter is the pipe from the previous Job in the chain (if it
exists), or else the first data file,

the primary output of a filter is the pipe to the next job in the chain (if it exists) or
else the last data file.

Many filters will have only two I/O channels: the primary input and the primary output.

If the parameters of EX start with '#channel TO', then the corresponding SBASIC channel will be closed (if it was already open) and a new channel opened as a pipe to the first
program. Any data sent to this channel (e.g. by PRINTing to it) will be processed by the chain of Jobs. When the channel is CLOSEd, the chain of Jobs will be removed from QPC.

If the parameters of EX end with ' TO #channel', then the corresponding SBASIC channel will be closed (if it was already open) and a new channel opened as a pipe from the last
program.

Any data passing through the chain of Jobs will arrive in this channel and may be read

(e.g. by INPUTing from it). When all the data has passed, the Jobs will remove themselves and any further attempt to take input from this channel will get an 'end of file' error. The

EOF function may be used to test for this.

Example of Filter Processing

As an example of filter processing, the programs UC to convert a file to upper case, LNO
to line number a file, and PAGE to split a file onto pages with an optional heading are all
chained to process a single file:

EX uc, fred TO lno TO page,ser; 'File fred at '&date$

58

The filter UC takes the file 'fred' and after converting it to upper case, passes through a
pipe to LNO. LNO adds line numbers to each line and passes the file down a pipe to

PAGE. In its turn, PAGE splits the file onto pages with the heading (including in this case
the date) at the top of each page, before sending the file to the SER port. Note that the file
fred itself is not modified; the modified versions are purely transient.

EXEP
hotkey system

EXEP is a supplement the EXEC (or EX) command. It has all the options of the HOT_RES, HOT_CHP, HOT_LOAD and HOT_THING functions. It does not set up a Hotkey but executes a program directly, either from an Executable Thing, or from a file.

To persuade the HOTKEY system to execute a Job with Unlocked windows, you need to
add the single parameter "U" to the function parameter list. To provide a "Guardian"

window to preserve the whole area used by the Job, you need to add the single parameter

"G" to the function parameter list. Optionally, you may follow this by the window area (size, position) of the Guardian window as four numbers. Any attempt by a program to open or
redefine a window outside its Guardian will fail. To execute a Job so that it will be frozen
when its windows are buried, you add the single parameter "F" to the parameter list. To prevent the program from taking too much memory, you add the parameter "P", optionally followed by the amount of memory (in kilo bytes) the program may take.

Note that "U", "G", "P" or "F" can be used after the "I" option for impure programs which modify there own code.

syntax:

params := string

{list of parameters for individual programs}

options := [ I,] U

| G [ width, height, xorg, yorg ]

| P [ memory ]

{in kilobytes}

| F

EXEP filename [; params] [, jobname] [, options] )

EXEP thingname [; params] [, jobname] [, options] )

example: i. EXEP Quill,p,40

{execute Quill in 40 kbytes}

ii. EXEP Capsclock,u

{execute capslock in unlockable window}

EXIT
repetition

EXIT will continue processing after the END of the named FOR or REPeat structure.

syntax:

EXIT identifier

59

example: i. 100 REM start Looping

110 LET count = 0

120 REPeat Loop

130 LET count = count +1

140 PRINT count

150 IF count = 20 THEN EXIT Loop

160 END REPeat loop

{the loop will be exited when count becomes equal to 20}

ii. 100 FOR n =1 TO 1000

110 REM program statements

120 REM program statements

130 IF RND >.5 THEN EXIT n

140 END FOR n

{the loop will be exited when a random number greater
than 0.5 is generated}

EXP
maths functions

EXP will return the value of e raised to the power of the specified parameter.

syntax: EXP ( numeric_expression)

{range -500..500}

example: i. PRINT EXP(3)

ii. PRINT EXP(3.141592654)

EXTRAS

EXTRAS will output to the specified or default channel, a list of commands and functions available to SBASIC

syntax:

EXTRAS [# channel]

example: i. EXTRAS #3

{output list to #3}

ii. EXTRAS

{output list to default channel #1}

FEXP$
conversion functions

60

FEXP$ will convert a value to a string representing the value in exponent form.

The form has an optional sign and one digit before the decimal point, and 'ndp' digits after
the decimal point. The exponent is in the form of 'E' followed by a sign followed by 2 digits.

The field must be at least 7 greater than ndp.

syntax:

field := numeric_expression

{length of returned string}

ndp := numeric_expression

{number of decimal places}

FEXP$ ( value, field, ndp)

example: PRINT FEXP$ (1234.56,12,4)

{will print ' 1.2346E+03'}

FDEC$

IDEC$

CDEC$
conversion functions

These routines convert a value into a decimal number in a string. The number of decimal
places represented is fixed, and the exponent form of floating point number is not used.

The three routines are very similar. FDEC$ converts the value as it is, whereas IDEC$
assumes that the value given is an integral representation in units of the least significant
digit displayed. CDEC$ is the currency conversion which is similar to IDEC$, except that there are commas every 3 digits.

syntax:

field := numeric_expression

{length of returned string}

ndp := numeric_expression

{number of decimal places}

FDEC$ ( value, field, ndp)

IDEC$ ( value, field, ndp)

CDEC$ ( value, field, ndp)

example: i. PRINT FDEC$ (1234.56,9,2)

{will print ' 1234.56'}

ii. PRINT IDEC$ (123456,9,2)

{will print ' 1234.56'}

iii. PRINT CDEC$ (123456,9,2)

{will print ' 1,234.56'}

comment: If the number of characters is not large enough to hold the value, the string is
filled with '*'. The value should be between -2^31 and 2^31 (-2,000,000,000 to

+2,000,000,000) for IDEC$ and CDEC$, whereas for FDEC$ the value
multiplied by 10^ndp should be in this range.

61

FILL
graphics

FILL will turn graphics fill on or off. FILL will fill any non-re-entrant shape drawn with the graphics or turtle graphics procedures as the shape is being drawn. Re-entrant shapes must be split into smaller non-re-entrant shapes.

When you have finished filling, FILL 0 should be called.

syntax:

switch:= numeric_expression

{range 0..1}

FILL [ channel,] switch

example: i. FILL 1:LINE 10,10 TO 50,50 TO 30,90 TO 10,10:FILL 0

{will draw a filled triangle}

ii. FILL 1:CIRCLE 50,50,20:FILL 0

{will draw a filled circle}

FILL$
string arrays

FILL$ is a function which will return a string of a specified length filled with a repetition of one or two characters.

syntax:

FILL$ ( string_expression, numeric_expression)

The string expression supplied to FILL$ must be either one or two characters long.

example: i. PRINT FILL$("a",5)

{will print aaaaa}

ii. PRINT FILL$("oO",7)

{will print oOoOoOo}

iii. LET a$ = a$ & FILL$(" ",10)

FLASH
windows

FLASH turns the flash state on and off. FLASH is only effective in low resolution mode.

FLASH will be effective in the window attached to the specified or default channel.

syntax:

switch:= numeric_expression

{range 0..1}

FLASH [ channel,] switch

where: switch = 0 will turn the flash off

switch = 1 will turn the flash on

62

example:

100 PRINT "A ";

110 FLASH 1

120 PRINT "flashing ";

130 FLASH 0

140 PRINT "word"

warning: Writing over part of a flashing character can produce spurious results and
should be avoided.

FLEN

FTYP

FDAT

FXTRA

FNAME$

FUPDT

FBKDT

FVERS
file information

There are six functions to extract information from the header of a file.

FLEN
will return the length of the file.

FTYP
will return the file type. The file type is, 0 for ordinary files, 1 for executable
programs, and 2 for relocatable machine code.

FDAT
will return the files data space. Only valid results will be obtained from
executable programs.

FXTRA
will return the file extra information.

FNAME$ will return the filename.

FUPDT
will return the files update date

FBKDT
will return the backup date from the file.

FVERS
will return the files version number.

If a file is being extended, the file length can be found by using the FPOS function to find the current file position. (If necessary the file pointer can be set to the end of file by the
command GET \#n 999999.)

syntax:

FLEN (# channel)

FTYP (# channel)

FDAT (# channel)

FXTRA (# channel)

FNAME$ (# channel)

FUPDT (# channel)

63

example: PRINT FLEN (#3)

{print the length of the file open on channel #3}

comment: The file information functions can also be used with implicit channels. e.g.

PRINT FLEN (\fred)

{print the length of file fred}

FLP_DENSITY
directory devices

The SMSQ/E format routines will usually attempt to format a disk to the highest density
possible for a medium. The FLP_DENSITY command is used to specify a particular
recording density during format. The density codes are "S" for single sided (double
density), "D" for double density and "H" for high density.

syntax:

FLP_DENSITY [ S | D | H ]

example: i. FLP_DENSITY S

{Set the default format to single sided}

ii. FLP_DENSITY H

{Set the default format to high density}

iii. FLP_DENSITY

{Reset to automatic density selection}

comment: The same code letters may be added (after a *) to the end of the medium name
to force a particular density format. (For compatibility with older drivers, if the
code letter is omitted after the *, single sided format is assumed.

i. FORMAT ’FLP1_Disk23’

{Format at highest density or as specified
by FLP_DENSITY}

ii. FORMAT ’FLP1_Disk24*’

{Format single sided}

iii. FORMAT ’FLP1_Disk25*S’

{Format single sided}

iv. FORMAT ’FLP1_Disk25*D’

{Format double sided, double density}

FLP_SEC

FLP_START

FLP_STEP
directory devices

These commands are supplied for compatibility reasons. QPC has no influence over how
the Windows disk driver works, therefore these commands are ignored.

64

FLP_STEP
directory devices

FLP_STEP will set the step rate in milliseconds of floppy disk drives.

If only one parameter is given its value applies globally. If two parameters are given the
first is the drive number and the second the step rate.

syntax:

FLP_STEP [ drive, ] step_rate

example: FLP_STEP 12

{set step rate to 12 ms on all drives}

FLP_STEP 3,6

{set step rate to 6ms on drive 3}

FLP_TRACK
directory devices

FLP_TRACK sets the number of tracks to be formatted on a floppy disk.

syntax:

tracks := numeric_expression

FLP_TRACK tracks

example: 100 FLP_TRACK 40

{set number of tracks to 40}

110 FORMAT flp1_small

{only format 40 tracks of disk}

FLP_USE
directory devices

FLP_USE allows renaming of the FLP device. FLP_USE without a parameter will reset the name of FLP back to FLP.

syntax:

FLP_USE [ name ]

example: i. FLP _USE dos : LOAD dos2_prog

{loads 'prog' from FLP2_ }

ii. FLP _USE

{and now its name is FLP again}

iii. FLP_USE win : DIR win1_

{displays directory of FLP1_}

FLUSH
directory devices

SMSQ/E directory device drivers maintain as much of a file in RAM as possible. A power
failure or other accident could result in a file being left in an incomplete state. The FLUSH

65
command will ensure that a file is updated without closing it. Closing a file will always
cause the file to be flushed.

syntax:

FLUSH # channel

FOPEN

FOP_IN

FOP_NEW

FOP_OVER

FOP_DIR
devices

This is a set of functions for opening files. These functions differ from the OPEN
procedures in two ways. Firstly, if a file system error occurs (e.g. 'not found' or 'already
exists') these functions return the error code and continue. Secondly the functions may be
used to find a vacant hole in the channel table: if successful they return the channel
number.

When called with two parameters, these functions return the value zero for successful
completion, or a negative error code.

The #channel parameter is optional: if it is not given, the functions will search the channel
table for a vacant entry, and, if the open is successful, the channel number will be
returned. Note that
error codes are always negative, and channel numbers are positive.

syntax:

FOPEN ( [# channel,] name)

{open a file for read/write}

FOP_IN ( [# channel,] name)

{open a file for input only}

FOP_NEW ( [# channel,] name)

{open a new file}

FOP_OVER ( [# channel,] name)

{open a new file, if it exists it is
overwritten}

FOP_DIR ( [# channel,] name)

{open a directory}

example: i. A file may be opened for read only with an optional extension using the
following code:

ferr=FOP_IN (#3,name$&'_ASM')

:REMark try to open _ASM file

IF ferr=-7: ferr=FOP_IN (#3,name$)

:REMark ERR.NF, try no _ASM

ii. outch = FOP_NEW (fred)

:REMark open fred

if outch < 0: REPORT outch: STOP

:REMark ... oops

PRINT #outch, 'This is file Fred'

CLOSE #outch

66

FOR

END FOR
repetition

The FOR statement allows a group of SBASIC statements to be repeated a controlled
number of times. The FOR statement can be used in both a long and a short form.

NEXT and END FOR can be used together within the same FOR loop to provide a loop epilogue, ie. a group of SBASIC statements which will not be executed if a loop is exited via an EXIT statement but which will be executed if the FOR loop terminated normally.

define:

for_item:=

| numeric_expression

| numeric_exp TO numeric_exp

| numeric_exp TO numeric_exp STEP numeric_exp

for_list. =
for_item *[, for_item] *

SHORT: The FOR statement is followed on the same logical line by a sequence of

SBASIC statements. The sequence of statements is then repeatedly executed
under the control of the FOR statement.

When the FOR statement is exhausted, processing continues on the next line.

The FOR statement does not require its terminating NEXT or END FOR. Single
line FOR loops must not be nested.

syntax:

FOR variable = for_list : statement *[: statement]*

example:

i. FOR i = 1, 2, 3, 4 TO 7 STEP 2 : PRINT i

ii. FOR element = first TO last : LET buffer (element ) = 0

LONG:

The FOR statement is the last statement on the line. Subsequent lines contain
a series of SBASIC statements terminated by an END FOR statement. The
statements enclosed between the FOR statement and the END FOR are
processed under the control of the FOR statement.

syntax:

FOR variable = for_list

statements

END FOR variable

example:

100 INPUT "data please" ! x

110 LET factorial = 1

120 FOR value = x TO 1 STEP -1

130 LET factorial = factorial * value

140 PRINT x !!!! factorial

67

150 IF factorial>lE20 THEN

160 PRINT "Very Large number"

170 EXIT value

180 END IF

190 END FOR value

FORMAT
directory devices

FORMAT will format and make ready for use the directory device contained in the
specified drive.

syntax: FORMAT [ channel,] device

Device specifies the drive (physical or virtual) to be used for formatting and the identifier
part of the specification is used as the medium or volume name for floppy disks, The
number of sectors (512 bytes) for RAM disks, or the size in megabytes for WIN drives.

FORMAT will write the number of good sectors and the total number of sectors available
on the directory device on the default or on the specified channel.

A RAM disk may be removed by giving either a null name or zero sectors.

example: i. FORMAT flp1_data_disk

ii. FORMAT ram2_20

{Format RAM2_ to 10K bytes}

iii. FORMAT win1_40

{Format WIN1_ to 40M bytes}

iv. FORMAT ram1_0

{Remove RAM1_}

FORMAT can be used to reinitialise a used directory device. However all data contained
on that device will be lost.

FPOS
devices

FPOS will return the current file position for the specified channel.

The file pointer can be set by the commands BGET, BPUT, GET or PUT with no items to be got or put. If an attempt is made to put the file pointer beyond the end of file, the file
pointer will be set to the end of file and no error will be returned. Note that setting the file pointer does not mean that the required part of the file is actually in a buffer, but that the
required part of the file is being fetched. In this way, it is possible for an application to
control prefetch of parts of a file where the device driver is capable of prefetching.

syntax:

FPOS (# channel)

68
example: 10 PUT #4\102,value1,value2

20 ptr = FPOS (#4)

{set 'ptr' to 114 (=102+6+6)}

The file pointer can be set by the commands BGET, BPUT, GET or PUT with no items to be got or put. If an attempt is made to put the file pointer beyond the end of file, the file
pointer will be set to the end of file and no error will be returned. Note that setting the file pointer does not mean that the required part of the file is actually in a buffer, but that the
required part of the file is being fetched. In this way, it is possible for an application to
control prefetch of parts of a file where the device driver is capable of prefetching.

FREE_MEM
memory management

The function FREE_MEM will return the amount of free memory available in the ‘common
heap’.

syntax:

FREE_MEM

example: PRINT FREE_MEM

FTEST
devices

The function FTEST is used to determine the status of a file or device. It opens a file for input only and immediately closes it. If the file exists it will either return the value 0 or -9 (in use error code), if it does not exist, it will return -7 (not found error code). Other possible returns are -11 (bad name), -15 (bad parameter), -3 (out of memory) or -6 (no room in the
channel table).

syntax:

FTEST ( name)

example: The function can be used to check that a file does not exist:

IF FTEST (file$) <> -7: PRINT 'File '; file$; ' exists'

GET

PUT
unformatted I/O

It is possible to put or get values in their internal form. The PRINT and INPUT commands of SBASIC handle formatted IO, whereas the direct I/O routines GET and PUT handle unformatted I/O. For example, if the value 1.5 is PRINTed the byte values 49 ('1'), 46 ('.') 69
and 53 ('5') are sent to the output channel. Internally, however, the number 1.5 is
represented by 6 bytes (as are all other floating point numbers). These six bytes have the
value 08 01 60 00 00 00 (in hexadecimal). If the value is PUT, these 6 bytes are sent to the output channel.

The internal form of an integer is 2 bytes (most significant byte first). The internal form of a floating point number is a 2 byte exponent to base 2 (offset by hex 81F), followed by a 4
byte mantissa, normalised so that the most significant bits (bits 31 and 30) are different.

The internal form of a string is a 2 byte positive integer, holding the number of characters
in the string, followed by the characters.

GET gets data in internal format from the specified or default channel. PUT puts data in internal format into the specified or default channel. For GET, each item must be an
integer, floating point, or string variable. Each item should match the type of the next data
item from the channel. For PUT, the type of data put into the channel, is the type of the item in the parameter list.

syntax:

GET # channel\ [ position] , items

{get internal format data from a file}

PUT # channel\ [ position] , items

{put internal format data onto a file}

example: 10 fpoint=54

20 wally%=42: salary=78000: name$='Smith'

30 PUT #3\fpoint, wally%, salary, name$

position the file, open on #3, to the 54th byte, and put 2 bytes (integer 42), 6
bytes (floating point 78000), 2 bytes (integer 5) and the 5 characters 'Smith'.

Fpoint will be set to 69 (54+2+6+2+5).

comment: For variables or array elements the type is self evident, while for expressions
there are some tricks which can be used to force the type:

.... +0
will force floating point type;

.... &”

will force string type;

.... ||0
will force integer type.

xyz$='ab258.z'

...

PUT #3\37,xyz$(3 to 5)||0

will position the file opened on channel #3 to the 37th byte and then will put the
integer 258 on the file in the form of 2 bytes (value 1 and 2, i.e. 1*256+2).

70

GOSUB

For compatibility with other BASICs, SBASIC supports the GOSUB statement. GOSUB
transfers processing to the specified line number; a RETurn statement will transfer
processing back to the statement following GOSUB.

The line number specification can be an expression.

syntax:

GOSUB line_number

example: i. GOSUB 100

ii. GOSUB 4*select_variable

comment: The control structures available in SBASIC make the GOSUB statement
redundant.

GOTO

For compatibility with other BASICs, SBASIC supports the GOTO statement. GOTO will unconditionally transfer processing to the statement number specified. The statement
number specification can be an expression.

syntax:

GOTO line_number

example: i. GOTO program_start

ii. GOTO 9999

comment: The control structures available in SBASIC make the GOTO statement
redundant.

HEX

HEX$
conversion functions

HEX will convert the supplied hexadecimal string into a value. The 'digits' '0' to '9' 'A' to 'F'

and 'a' to 'f' have their conventional meanings. HEX will return an error if it encounters a non-recognised character.

HEX$ will return a string of sufficient length to represent the value of the specified number of bits of the least significant end of the value rounded up to the nearest multiple of 4.

syntax:

number_of_bits := numeric_expression

HEX ( hexadecimal_string)

71

HEX$ ( value, number_of_bits)

example: PRINT HEX ( “1AF6”)

{will output 6902}

PRINT HEX$ (32673 , 16)

{will output “7FA1”}

HGET

HPUT
formatted I/O

HGET and HPUT will read and write the first parts of a file header from the specified or default channel. Both commands accept up to 5 parameters, which are of the type floating
point. The first parameter is the file length (long), followed by the access byte (byte),
followed by the file type (byte), then comes the dataspace (long) and finally the extra-
information (long).

syntax:

length := numeric_expression

access := numeric_expression

type := numeric_expression

dataspace := numeric_expression

extra := numeric_expression

HGET [# channel,] length, access, type, dataspace, extra HPUT [# channel,] length, access, type, dataspace, extra example: OPEN#3,flp1_file

HGET#3, length, access, type, space, extra

HPUT#3,length, access,1 ,1024,extra

CLOSE#3

converts a file into an executable file with 1kByte dataspace.

HOT_CHP

HOT_CHP1

HOT_RES

HOT_RES1
hotkey system

HOT_CHP and HOT_RES will load a program into either the common heap, or the
resident procedure area, making it into an Executable Thing. This Thing can then be
executed very quickly when the Hotkey is pressed.

72

For frequently used programs, these two functions set up an Executable Thing to be
executed using a Hotkey. If you want to add a program temporarily that you may wish to
remove later, HOT_CHP should be used. Otherwise HOT_RES should be used, as this will often give faster execution. If the resident procedure area is not available, then HOT_RES
will use the common heap instead.

HOT_CHP1 and HOT_RES1 are the same as HOT_CHP and HOT_RES, except that they set up a Wake Hotkey. When you press the Hotkey, if there is already a Job of the same
name executing, then it will be Picked and Woken, otherwise a new copy will be executed.

Jobs may be identified by a name, which is normally the program name. This name is to be
found in the base area of a standard program. It is possible, however, to specify a different
name for a Job when you set up the Hotkey.

To persuade the HOTKEY system to execute a Job with Unlocked windows, you need to
add the single parameter "U" to the function parameter list. To provide a "Guardian"

window to preserve the whole area used by the Job, you need to add the single parameter

"G" to the function parameter list. Optionally, you may follow this by the window area (size, position) of the Guardian window as four numbers. Any attempt by a program to open or
redefine a window outside its Guardian will fail. To execute a Job so that it will be frozen
when its windows are buried, you add the single parameter "F" to the parameter list. To prevent the program from taking too much memory, you add the parameter "P", optionally followed by the amount of memory (in kilo bytes) the program may take.

Note that "U", "G", "P" or "F" can be used after the "I" option for impure programs which modify there own code.

The functions will return one of the following error codes:

0 - No error

-2 - No job

(file is not executable)

-3 - Out of memory

-7 - Not found

(file could not be found)

-9 - In use

(Hotkey is already being used for some

other operation)

-12- Bad name

(bad file name)

syntax:

key := character_string

{single character string in the

range 32 to 191}

params := string

{list of parameters for individual

programs}

options := [ I,] U

| G [ width, height, xorg, yorg ]

| P [ memory ]

| F

HOT_CHP ( key, filename [; params] [, jobname] [, options] ) 73

HOT_RES ( key, filename [; params] [, jobname] [, options] ) HOT_CHP1 ( key, filename [; params] [, jobname | ! wakename ] [, options] ) HOT_RES1 ( key, filename [; params] [, jobname | ! wakename ] [, options] ) example: i. ERT HOT_RES (' t', qtyp)

{set up QTYP using default drive}

ii. ERT HOT_RES1 (' t' , f lp1_qtyp)

{just one copy on the specified
drive}

iii. ERT HOT_RES (' t' ,' f lp1_qtyp' )

{or all between apostrophes}

iv. ERT HOT_CHP (' t' , qtyp)

{or so we can HOT_REMV it}

v. ERT HOT_RES ('=', qtyp_e, 'Editor Qtyp') {specifying a job name}

vi. ERT HOT_RES (c, capsclock, u)

{set up unlocked "capsclock" on

ALT C}

vii. ERT HOT_RES (x, terminal, g)

{set up Terminal on ALT X with

Guardian window covering the
whole screen}

viii ERT HOT_RES (r, rubbish, i, g, 124, 22, 388, 0) {setup '' rubbish'', an
impure program which requires a

Guardian of 124x22 pixels with its
origin at 388x0}

comment: Alternatively we can set up QTYP in a loop checking the error return for a not
found:

10 REPeat Iqtyp

20 herr = HOT_RES (' t', ' qtyp')

{try loading Qtyp}

30 IF NOT herr; EXIT Iqtyp

{..OK}

40 IF herr =-7

{not found?}

50 INPUT #0, 'Put Qtyp disk in drive 1 and press ENTER'

60 NEXT Iqtyp

{try again}

70 END IF

80 PRINT #0, ' Loading Qtyp';: ERT herr

{give up}

90 END REPeat Iqtyp

HOT_CMD
hotkey system

HOT_CMD allows one or more commands to be sent directly to the command console of

SBASIC. This is similar to HOT_KEY, but when the Hotkey is pressed, SBASIC is Picked
to the top, and each command is sent to the command console, followed by a newline

(ENTER).

This can be used to load and run SBASIC programs, or to execute simple command
sequences.

The function will return one of the following error codes:

74

0 - No error

-9 - In use

(Hotkey is already being used for some other operation)

syntax:

key := character_string

{single character string in the range 32 to

191}

HOT_CMD ( key, string *[ , string ]* )

example: i. ERT HOT_CMD (m,' LRUN flpl_mandel' ) {LRUN a BASIC program}

ii. ERT HOT_CMD (d,wdir)

{directory listing}

iii. ERT HOT_CMD (r, ' INPUT "Run> ";prg$' , ' LRUN prg$' )

{prompt for name of, and LRUN a program, note the use of

quotes within the string delimited by apostrophes}

HOT_DO
hotkey system

HOT_DO allows a previously defined Hotkey to be activated from SBASIC. The Hotkey
system interprets the HOT_DO command as if the Hotkey had been pressed.

syntax:

key := character_string

{single character string in the range 32 to

191}

HOT_DO key | name

example: 10 ERT HOP_CHP (q, Quill, p)

{set Quill on ALT-Q}

20 HOT_DO 'Quill'

{start Quill, without pressing ALT-Q}

HOT_GO

HOT_STOP
hotkey system

HOT_GO and HOT_STOP will start and stop the Hotkey system.

The Hotkey system is designed to remain dormant until all resident extensions have been
loaded. It is then activated by the HOT_GO command.

If, at any time, you wish to add more resident extensions to QPC, you can remove the

HOTKEY Job using the RJOB command or the HOT_STOP command.

Neither HOT_GO nor HOT_STOP have any parameters.

75
syntax:

HOT_GO

{start HOTKEY Job}

HOT_STOP

{stop HOTKEY Job}

HOT_KEY
hotkey system

The HOT_KEY function is used to set up Hotkeys to copy strings of keystrokes into the
current keyboard queue.

When the appropriate Hotkey is pressed, each of the strings is sent to the keyboard queue,
separated by a new line (Enter) character.

You can specify as many lines as you like. If you one or more new lines after the last

HOT_KEY string, you should put one of more empty (null) strings at the end of the list.

The function will return one of the following error codes:

0 - No error

-9 - In use

(Hotkey is already being used for some

other operation)

syntax:

key := character_string

{single character string in the range

32 to 191}

HOT_KEY ( key, string *[ , string ]* )

example: i. ERT HOT_KEY ("s" , "Dear Sir," , "" , "" )

{two new

lines at end}

ii. ERT HOT_KEY ("e" , "Yours sincerely" , "" , "" , " Joe Bloggs" ) iii. ERT HOT_KEY ("p" , CHR$(232) & "PD" , "NP" )

{print from
abacus}

comment: HOT_KEY is very similar to the ALTKEY command.

HOT_LIST
hotkey system

HOT_LIST will send to the specified or default channel , the current list of Hotkey
assignments.

syntax:

HOT_LIST [ # channel ]

HOT_LIST filename

example: i. HOT_LIST

{list Hotkeys to #1}

ii. HOT_LIST ram1_keys

{list to file "ram1_keys"}

76

HOT_LOAD

HOT_LOAD1
hotkey system

HOT_LOAD will set up a Hotkey to load and execute a program from disk, that is not
required frequently enough to justify making it resident. This is similar to the HOT_RES
and HOT_CHP, but the program is not loaded until required. It follows, of course, that the disk with the program file must be available at the time you press the Hotkey.

HOT_LOAD1 is the same as HOT_LOAD, except that it sets up a Wake Hotkey. When
you press the Hotkey, if there is already a Job of the same name executing, then it will be

Picked and Woken, otherwise a new copy will be executed.

Jobs may be identified by a name, which is normally the program name. This name is to be
found in the base area of a standard program. It is possible, however, to specify a different
name for a Job when you set up the Hotkey.

To persuade the HOTKEY system to execute a Job with Unlocked windows, you need to
add the single parameter "U" to the function parameter list. To provide a "Guardian"

window to preserve the whole area used by the Job, you need to add the single parameter

"G" to the function parameter list. Optionally, you may follow this by the window area (size, position) of the Guardian window as four numbers. Any attempt by a program to open or
redefine a window outside its Guardian will fail. To execute a Job so that it will be frozen
when its windows are buried, you add the single parameter "F" to the parameter list. To prevent the program from taking too much memory, you add the parameter "P", optionally followed by the amount of memory (in kilo bytes) the program may take.

Note that "U", "G", "P" or "F" can be used after the "I" option for impure programs which modify there own code.

The function will return one of the following error codes:

0 - No error

-9 - In use

(Hotkey is already being used for some

other operation)

syntax:

key := character_string

{single character string in

the range 32 to 191}

params := string

{list of parameters for

individual programs}

options := [ I,] U

| G [ width, height, xorg, yorg ]

| P [ memory ]

| F

HOT_LOAD ( key, filename [; params] [, jobname] [, options] ) HOT_LOAD ( key, filename [; params] [, jobname | ! wakename ] [, options] ) 77

example: ERT HOT_LOAD (f, qtyp_file)

{Load and execute Qtyp_File on ALT F}

HOT_NAME$
hotkey system

The HOT_NAME$ function will return the name associated with the supplied Hotkey.

The function will return a null (empty) string if the Hotkey is not defined.

syntax:

key := character_string

{single character string in the range 32 to

191}

HOT_NAME$ ( key )

example: PRINT HOT_NAME$ ( 'a' ) {display the name associated with the key ALT-a}

HOT_OFF

HOT_SET
hotkey system

HOT_OFF and HOT_SET will turn off and on, or change individual Hotkey operations.

The functions will return one of the following error codes:

0 - No error

-7 - Not found

(Old key or name cannot be found)

-9 - In use

(New key is already in use, HOT_SET only)

syntax:

key := character_string

{single character string in the range 32 to

191}

newkey := key

oldkey := key

HOT_OFF ( key | name )

HOT_SET ( key | name )

HOT_SET ( newkey, oldkey | name )

example: i. ERT HOT_OFF ('c')

{switch off ALT-c}

ii. ERT HOT_SET ('h','r')

{ALT-h now does

what ALT-r used to}

comment: The name is the program or Thing name for execute and Pick type Hotkeys, or
the string or command for HOT_KEY and HOT_CMD Hotkeys.

78

HOT_PICK
hotkey system

The HOT_PICK function sets up a Hotkey to Pick a Job of a particular name, so that you
may work with it.

The Job name is usually embedded at the start of the program file. For pure programs set
up by HOT_RES and HOT_CHP, this name is replaced if you specify a Job name. For

Psion programs, which do not have a name at the start, HOT_CHP, etc, will set the Job
name to be the same as the program file name.

You do not need to specify the complete Job name, just the first word in the name. This is
useful for programs which add extra information after the program name (e.g. the Files
menu of QPAC 2, which adds a directory name after the Job name). If there is more than
one Job with a matching name, each Job will be Picked in turn.

The function will return one of the following error codes:

0 - No error

-9 - In use

(Hotkey is already being used for some

other operation)

syntax:

key := character_string

{single character string in the range

32 to 191}

HOT_PICK ( key, jobname )

example: i. ERT HOT_PICK ( '1' , Quill)

{pick Quill on ALT 1}

ii. ERT HOT_PICK ( '2' , Abacus ) {pick Abacus on ALT 2}

HOT_REMV
hotkey system

The HOT_REMV function will turn the Hotkey off, and remove the definition as well.

If the Hotkey was set up using HOT_CHP, the Executable Thing and any Jobs using it are
removed.

HOT_REMV will usually need to be used to remove a Hotkey definition before re-using the
particular Hotkey. Unless HOT_KEY or HOT_CMD are being used to re-define a string or command respectively.

syntax:

key := character_string

{single character string in the

79

range 32 to 191}

HOT_REMV ( key | name )

example: 10 ERT HOT_CHP (q, Quill, p)

{Quill on ALT Q}

20 ERT HOT_OFF (q)

{ALT Q turned off}

30 ERT HOT_SET (q)

{ALT Q back on}

40 ERT HOT_SET (z,q)

{Quill now on ALT Z}

50 ERT HOT_REMV (Quill)

{Quill gone completely

HOT_STUFF
hotkey system

HOT_STUFF will place the supplied strings into the Stuffer Buffer. The first string is put in the buffer first, immediately followed by the second string (if present).

The next time you press ALT SPACE the strings will be copied into the current keyboard
queue as if you had just typed them.

syntax:

HOT_STUFF string1 [ , string2 ]

example: i. HOT_STUFF DATE$

{place time and date into Stuffer Buffer}

ii. HOT_STUFF "Dear Sir", CHR$(13)&CHR$(13)

{place 'Dear Sir' and the Enter key twice}

HOT_THING

HOT_THING1
hotkey system

HOT_THING will set up a Hotkey to execute an Executable Thing. The Thing need not
have been created at the time the Hotkey is set up. QPAC 2 is implemented as a collection
of (mostly) Executable Things. The HOT_RES and HOT_CHP functions create an

Executable Thing for each program set up on a Hotkey.

The HOTKEY system 2 is a non-executable Thing.

HOT_THING1 is the same as HOT_THING, except that it sets up a Wake Hotkey. When
you press the Hotkey, if there is already a Job of the same name executing, then it will be

Picked and Woken, otherwise a new copy will be executed.

Jobs may be identified by a name, which is normally the program name. This name is to be
found in the base area of a standard program. It is possible, however, to specify a different
name for a Job when you set up the Hotkey.

80

The function will return one of the following error codes:

0 - No error

-9 - In use

(Hotkey is already being used for some other operation)

syntax:

key := character_string

{single character string in the

range 32 to 191}

params := string

{list of parameters for

individual programs}

HOT_THING ( key, thingname [; params] [, jobname] )

HOT_THING1 ( key, thingname [; params] [, jobname | ! wakename ] ) example: ERT HOT_THING (' f , Files )

{Execute QPAC 2 Files Menu on ALT F}

HOT_TYPE
hotkey system

The HOT_TYPE function will return the type of action associated with the supplied Hotkey.

The types returned by HOT_TYPE are

-8
last line recall

-6
stuff keyboard queue with previous stuffer string

-4
stuff keyboard queue with current stuffer string

-2
stuff keyboard queue with defined string

0
pick SBASIC and stuff command

2
do code

4/5
execute Thing

6
execute file

8
pick Job

10/11
wake or execute Thing

12
wake / execute file

-7
not defined

syntax:

key := character_string

{single character string in the range 32 to 191}

HOT_TYPE ( key )

example: PRINT HOT_TYPE ( 'c' )

{display the Hotkey type of the key ALT-c}

HOT_WAKE
hotkey system

81

HOT_WAKE is a variation of HOT_PICK which will set up a Hotkey to Wake a Job when Picking it. Hotkeys set up by HOT_WAKE go a little further than this: if there is no Job of the required name executing at the time you press the Hotkey, then, if there is an

Executable Thing of the same name, this will be Executed.

Even if a program does not recognize a Wake Event, this Hotkey can still be used to Pick
or Execute the program.

This is most useful for accessing Executable Things that you will only ever want one copy
executing at a time. It is, for example, pointless having more than one copy of the QPAC 2

EXEC menu. If you set up a HOT_WAKE Hotkey for EXEC, the first time you use it you
will Execute the EXEC Thing. Until you remove the EXEC Job, every time you use this

Hotkey, the EXEC menu will be Picked and Woken.

The function will return one of the following error codes:

0 - No error

-9 - In use

(Hotkey is already being used for some
other operation)

syntax:

key := character_string

{single character string in the range 32 to

191}

params := string

{list of parameters for individual programs}

HOT_WAKE ( key, thingname [; params] [, jobname | ! wakename ] ) example: ERT HOT_WAKE ('x', 'Exec')

comment: For normal programs, the best way of using this function is to create an

Executable Thing using one of the HOT_RES or HOT_CHP functions, and then
define a second Hotkey to Wake the Thing. Quite a neat way of doing this is to
use a lower case Hotkey to Wake the program, and the corresponding upper
case Hotkey to create a new copy.

ERT HOT_RES (' D', ' QD')

{Set up QD to Execute on ALT D}

ERT HOT_WAKE (' d', ' QD')

{Set up to Wake or Execute on ALT d}

IF

THEN

ELSE

END IF

The IF statement allows conditions to be tested and the outcome of that test to control
subsequent program flow.

82

The IF statement can be used in both a long and a short form:

SHORT: The THEN keyword is followed on the same logical line by a sequence of

SBASIC keyword. This sequence of SBASIC statements may contain an ELSE
keyword. If the expression in the IF statement is true (evaluates to be non-
zero), then the statements between the THEN and the ELSE keywords are
processed. If the condition is false (evaluates to be zero) then the statements
between the ELSE and the end of the line are processed.

If the sequence of SBASIC statements does not contain an ELSE keyword and
if the expression in the IF statement is true, then the statements between the

THEN keyword and the end of the line are processed. If the expression is false
then processing continues at the next line.

syntax:

statements:= statement *[: statement]*

IF expression THEN statements [:ELSE statements]

example:

i. IF a=32 THEN PRINT "Limit" : ELSE PRINT "OK"

ii. IF test >maximum THEN LET maximum = test

iii. IF "1"+1=2 THEN PRINT "coercion OK"

LONG 1: The THEN keyword is the last entry on the logical line. A sequence of SBASIC
statements is written following the IF statements. The sequence is terminated
by the END IF statement. The sequence of SBASIC statements is executed if
the Expression contained in the IF statement evaluates to be non zero. The

ELSE keyword and second sequence of SBASIC statements are optional.

LONG 2: The THEN keyword is the last entry on the logical line. A Sequence of SBASIC
statements follows on subsequent lines, terminated by the ELSE keyword. If
the expression contained in the IF statement evaluates to be non zero then this
first sequence of SBASIC statements is processed. After the ELSE keyword a
second sequence of SBASIC statements is entered, terminated by the END IF
keyword. If the expression evaluated by the IF statement is zero then this
second sequence of SBASIC statements is processed.

syntax:

IF expression THEN

statements

[ELSE

statements]

END IF

example:

100 LET Limit =10

110 INPUT "Type in a number" ! number

120 IF number > limit THEN

83

130 PRINT "Range error"

140 ELSE

150 PRINT "Inside Limit"

160 END IF

comment:

In all three forms of the IF statement the THEN is optional. In the short form
it must be replaced by a colon to distinguish the end of the IF and the start
of the next statement. In the long form it can be removed completely.

nesting:

IF statements may be nested as deeply as the user requires (subject to
available memory). However, confusion may arise as to which ELSE, END

IF etc matches which IF. SBASIC will match nested ELSE statements etc to
the closest IF statement, for example:

100 IF a = b THEN

110 IF c = d THEN

120 PRINT "error"

130 ELSE

140 PRINT "no error"

150 END IF

160 ELSE

170 PRINT "not checked"

180 END IF

The ELSE at line 130 is matched to the second IF. The ELSE at line 160 is
matched with the first IF (at line 100).

INK
windows

This sets the current ink colour, i.e. the colour in which the output is written. INK will be effective for the window attached to the specified or default channel.

syntax:

INK [ channel,] colour

example: i. INK 5

ii. INK 6,2

iii. INK #2,255

INKEY$

INKEY$ is a function which returns a single character input from either the specified or default channel.

84

An optional timeout can be specified which can wait for a specified time before returning,
can return immediately or can wait forever. If no parameter is specified then INKEY$ will return immediately.

syntax:

INKEY$ [|( channe l)

|( channe l, time)

|( time)]

where: time = 1..32767 {wait for specified number of frames.

In the UK 50 Frames = 1 Second

In the US 60 Frames = 1 Second}

time = -1

{wait forever}

time = 0

{return immediately}

example: i. PRINT INKEY$

{input from the default channel}

ii. PRINT INKEY$(#4)

{input from channel 4}

iii. PRINT INKEY$(50)

{wait for 50 frames then return anyway}

iv. PRINT INKEY$(0)

{return immediatly (poll the keyboard)}

v. PRINT INKEY$(#3,100) {wait for 100 frames for an input from channel 3
then return anyway}

comment: If no character was available when INKEY$ times out, then a Null (CHR$(0)) will be returned.

INPUT

INPUT allows data to be entered into a SBASIC program directly from the PC’s keyboard
by the user. SBASIC halts the program until the specified amount of data has been input;
the program will then continue. Each item of data must be terminated by the ENTER key.

INPUT will input data from either the specified or the default channel.

If input is required from a particular console channel the cursor for the window connected
to that channel will appear and start to flash.

syntax:

separator:= | !

| ,

| \

| ;

| TO

prompt:= [ channel,] expression separator

INPUT [ prompt] [ channe l] variable *[, variable]*

85

example: i. INPUT ("Last guess "& guess & "New guess?") ! guess ii. INPUT "What is your guess?"; guess

iii. 100 INPUT "array size?" ! Limit

110 DIM array(limit-1)

120 FOR element = 0 to Limit-1

130 INPUT ("data for element" & element) array(element)

140 END FOR element

150 PRINT array

IO_PRIORITY

IO_PRIORITY sets the priority of the IO retry operations. In effect, this sets a limit on the time spent by the scheduler retrying IO operations.

A priority of one sets the IO retry scheduling policy to the same as QDOS, thus giving a
similar level of response but with a higher crude performance.

syntax:

level := numeric expression

IO_PRIORITY level

example: i. IO_PRIORITY 1

{QDOS levels of response, higher crude
performance}

ii. IO_PRIORITY 2

{QDOS levels of performance, better response
under load}

iii. IO_PRIORITY 10

{Much better response under load, degraded
performance}

iv. IO_PRIORITY 1000

{Maximum response, the performance depends on
the number of jobs waiting for input.}

INSTR
operator

INSTR is an operator which will determine if a given substring is contained within a
specified string. If the string is found then the substring's position is returned. If the string is not found then INSTR returns zero.

Zero can be interpreted as false, i.e. the substring was not contained in the given string. A
non zero value, the substrings position, can be intepreted as true, i.e. the substring was
contained in the specified string.

syntax: string_expression INSTR string expression

example: i. PRINT "a" INSTR "cat"

{will print 2}

86

ii. PRINT "CAT" INSTR "concatenate" {will print 4}

iii. PRINT "x" INSTR "eggs"

{will print 0}

INSTR_CASE

INSTR_CASE allows the type of string comparison to be used by INSTR to be set as
either case independent (default), or case dependent.

syntax:

INSTR_CASE 0 | 1

example: i. INSTR_CASE 0

{INSTR is now case independent. (SuperBASIC
compatible)}

ii. INSTR_CASE 1

{INSTR now does direct byte by byte comparisons

}

comment: The internal INSTR_CASE flag is cleared on NEW, LOAD, MERGE and RUN.

INT
maths functions

INT will return the integer part of the specified floating point expression.

syntax:

INT ( numeric_expression)

example: i. PRINT INT(X)

ii. PRINT INT(3.141592654/2)

JOBS

SMSQ/E

JOBS is a command to list to the window attached to the specified or default channel, all the Jobs running in QPC at the time. If there are more Jobs in the machine than can be
listed in the output window, the procedure will freeze the screen (CTRL F5) when it is full.

The procedure may fail if Jobs are removed from the QL while the procedure is listing
them.

syntax:

JOBS [# channel]

{list current Jobs}

JOBS \ device

{list Jobs to 'device'}

The following information is given for each Job

87

The Job number

The Job tag

The Job's owner Job number

A flag 'S' if the Job is suspended

The Job priority

The Job (or program) name.

JOB$

NXJOB

OJOB

PJOB

SMSQ/E

JOB$, NXJOB, OJOB, and PJOB are Job status functions provided to enable an SBASIC
program to scan the Job tree and carry out complex Job control procedures.

JOB$ will return as a string the name of the Job.

NXJOB is a rather complex function. The first parameter is the id of the Job currently being examined, the second is the id of the Job at the top of the tree. If the first id passed to

NXJOB is the last Job owned, directly or indirectly, by the 'top Job', then NXJOB will return the value 0, otherwise it will return the id of the next Job in the tree.

OJOB will return Job identifier of the owner of the Job.

PJOB will return priority of the job.

syntax:

job_identifier :=

| job_number , tag_number

| job_number + ( tag_number * 65536)

id := job_identifier

JOB$ ( id | name)

NXJOB ( id | name)

OJOB ( id | name)

PJOB ( id | name , top_job_id)

example: i. PRINT JOB$ (3,8)

{will output name of Job}

ii. PRINT OJOB (demon)

{will output the id of the owner of Job

‘demon’}

iii. PRINT PJOB (2,1)

{will output the priority of the Job}

comment: Job 0 always exists and owns directly or indirectly all other Jobs in QPC. Thus
a scan starting with id = 0 and top Job id = 0 will scan all Jobs in QPC.

88

It is possible that, during a scan of the tree, a Job may terminate. As a
precaution against this happening, the Job status functions return the following
values if called with an invalid Job id:

PJOB=0 OJOB=0 JOB$='' NXJOB=-1

JOB_NAME

SMSQ/E

JOB_NAME can be used to give a name to an SBASIC Job. It may appear anywhere
within a program and may be used to reset the name whenever required. This command
has no effect on compiled BASIC programs or Job 0.

syntax:

JOB_NAME string_expression

example: i. JOB_NAME Killer

{sets the Job name to "Killer"}

ii. JOB_NAME "My little Job"

{sets the Job name to "My little Job"}

KBD_TABLE

KBD_TABLE will set the keyboard layout to be used.

syntax:

lang := language_code | registration

KBD_TABLE lang

example: i. KBD_TABLE GB

{keyboard table set to English}

ii. KBD- TABLE 33

{keyboard table set to French}

comment: Private keyboard tables may also be loaded.

i= RESPR (512): LBYTES "kt",i: KBD_TABLE i

{keyboard table set to table in "kt"}

For compatibility with older drivers, a "private" keyboard table loaded in this way
should not be prefaced by flag word.

KEYROW

KEYROW is a function which looks at the instantaneous state of a row of keys (the table
below shows how the keys are mapped onto a matrix of 8 rows by 8 columns). KEYROW
takes one parameter, which must be an integer in the range 0 to 7: this number selects
which row is to be looked at. The value returned by KEYROW is an integer between 0 and

255 which gives a binary representation indicating which keys have been depressed in the
selected row.

89

Since KEYROW is used as an alternative to the normal keyboard input mechanism using

INKEY$ or INPUT, any character in the keyboard type-ahead buffer are cleared by

KEYROW: thus key depressions which have been made before a call to KEYROW will not be read by a subsequent INKEY$ or INPUT.

Note that multiple key depressions can cause surprising results. In particular, if three keys
at the corner of a rectangle in the matrix are depressed simultaneously, it will appear as if
the key at the fourth corner has also been depressed. The three special keys CTRL,

SHIFT and ALT are an exception to this rule, and do not interact with other keys in this way.

syntax: row:= numeric_expression {range 0..7}

KEYROW ( row)

example: 100 REMark run this program and press a few keys

110 REPeat loop

120 CURSOR 0,0

130 FOR row = 0 to 7

140 PRINT row !!! KEYROW(row) ;" "

150 END FOR row

160 END REPeat loop

KEYBOARD MATRIX

COLUMN

ROW

1

2

4

8

16

32

64

128

7 I

SHIFT CTRL

ALT X

V

/

N

,

6 |

8

2

6

Q

E

0

T

U

5 |

9

W

I

TAB

R

-

Y

O

4 |

L

3

H

1

A

P

D

J

3 |

[

CAPS

K

S

F

=

G

;

2 |

]

Z

.

C

B

`

M

‘

1 |

C/R
left
up

ESC
right

SPC down

0 |

F4

F1

5

F2

F3

F5

4

7

LANGUAGE

LANGUAGE$

LANGUAGE and LANGUAGE$ will return the currently set language, or to find the
language that would be used if a particular language were requested. They can also be
used to convert the language (dialling code ) into a car registration and vice versa.

Language Code

Car Registration

Language and Country

33

F

French (in France)

90

44

GB

English (in England)

49

D

German (in Germany)

1

USA

USA (in USA)

LANGUAGE will return the language code, and LANGUAGE$ will return the car
registration.

syntax:

lang := language_code | registration

LANGUAGE [ ( lang) ]

LANGUAGE$ [ ( lang) ]

example: i. PRINT LANGUAGE

{returns the current language}

ii. PRINT LANGUAGE$

{the car registration of the current
language}

iii. PRINT LANGUAGE (F)

{the language corresponding to F}

iv. PRINT LANGUAGE$ (45)

{the car registration corresponding to 4}

v. PRINT LANGUAGE (977)

{the language that would be used for

Nepal}

LANG_USE

LANG_USE will set the language used by the system messages. This sets the Operating

System language word, and then scans the language dependent module list selecting
modules and filling in the message table.

A language may be specified either by an international dialling code or an international car
registration code. These codes may be modified by the addition of a digit where a country
has more than one language.

Language Code

Car Registration

Language and Country

33

F

French (in France)

44

GB

English (in England)

49

D

German (in Germany)

1

USA

USA (in USA)

syntax:

lang := language_code | registration

LANG_USE lang

example: i. LANG_USE 33

{set language to French}

ii. LANG_USE D

{set language to German}

iii. LANG_USE 'g'&'b'

{set language to English}

91

warning: if you assign a value to a variable, then you will not be able to use that variable name to specify the car registration letters.

D=33: LANG_USE D

{set language to French (dialing code 33)

rather than German (car registration D)}

LBYTES
devices, directory devices

LBYTES will load a data file into memory at the specified start address.

If a channel number of an open channel is supplied in place of a filename, then LBYTES
will attempt to load the file from the channel.

syntax:

start_address:= numeric_expression

device := filename | channel

LBYTES device , start_address

example: i. LBYTES flp1_screen, SCR_BASE

{load a screen image}

ii. LBYTES win1_program, start_address

{load a program at a specified address}

iii. 10 OPEN#5,flp1_data

{open a channel}

20 address = ALCHP(FLEN(#5))

{get file length and allocate space}

30 LBYTES#5,address

{load the file}

40 CLOSE#5

{close the channel}

LEN
string arrays

LEN is a function which will return the length of the specified string expression.

syntax:

LEN( string_expression)

example: i. PRINT LEN( "LEN will find the length of this string")

ii. PRINT LEN(output_string$)

LET

LET starts a SBASIC assignment statement. The use of the LET keyword is optional. The assignment may be used for both string and numeric assignments. SBASIC will
automatically convert unsuitable data types to a suitable form wherever possible.

92

syntax:

[LET] variable = expression

example: i. LET a = 1 + 2

ii. LET a$ = "12345"

iii. LET a$ = 6789

iv. b$ = test_data

LINE

LINE_R

LINE allows a straight line to be drawn between two points in the window attached to the default or specified channel. The ends of the line are specified using the graphics
coordinate system.

Multiple lines can be drawn with a single LINE command.

The normal specification requires specifying the two end points for a line. These end points
can be specified either in absolute coordinates (relative to the graphics origin) or in relative coordinates (relative to the graphics cursor). If the first point is omitted then a line is drawn from the graphics cursor to the specified point. If the second point is omitted then the
graphics cursor is moved but no line is drawn.

LINE will always draw with absolute coordinates, i.e. relative to the graphics origin, while LINE_R will always draw relative to the graphics cursor.

syntax: x:= numeric_expression
y:= numeric_expression

point:= x, y

parameter_2:= | TO point

(1)

| , point TO point (2)

parameter_1:= | TO point, angle (1)

| TO point

(2)

| point

(3)

LINE [ channel,] parameter_1 *[, parameter_2]*

LINE_R [ channel,] parameter_1 *[, parameter_2]*

Where

(1) will draw from the specified point to the next

specified point

(2) will draw from the the last point plotted to the

specified point

(3) will move to the specified point - no line will be

drawn

93

example: i. LINE 0,0 TO 0, 50 TO 50,0 TO 50,0 TO 0,0

{a square}

ii. LINE TO 0.75, 0.5

{a line}

iii. LINE 25,25

{move the graphics cursor}

LIST

LIST allows a SBASIC line or group of lines to be listed on a specific or default channel.

syntax:

line:= | line_number TO line_number

(1)

| line_number TO

(2)

| TO line_number

(3)

| line_number

(4)

|

(5)

LIST [ channel,] line*[, line]*

where

(1) will list from the specified line to the specified line

(2) will list from the specified line to the end

(3) will list from the start to the specified line

(4) will list the specified line

(5) will list the whole program

example: i. LIST

{list all lines}

ii. LIST 10 TO 300

{list lines 10 to 300}

iii. LIST 12,20,50

{list lines 12,20 and 50 only}

If LIST output is directed to a channel opened as a printer channel then LIST will provide hard copy.

LOAD

QLOAD
devices, directory devices

LOAD will load a SBASIC program from any QPC device. LOAD automatically performs a NEW before loading another program, and so any previously loaded program will be
cleared by LOAD.

QLOAD will load an SBASIC program which has been saved by QSAVE or QSAVE_O
and has a _SAV at the end of the filename.

If a line input during a load has incorrect SBASIC syntax, the word MISTAKE is inserted
between the line number and the body of the line. Upon execution, a line of this sort will
generate an error

94

syntax: LOAD device

QLOAD device

example: i. LOAD "flp2_test_program"

ii. LOAD ram1_guess

iii. QLOAD flp1_program

iv. LOAD ser1_e

v. QLOAD dev1_program_sav

LN

LOG10
maths functions

LN will return the natural logarithm of the specified argument. LOG10 will return the common logarithm. There is no upper limit on the parameter other than the maximum
number the computer can store.

syntax:

LOG10 ( numenic_expression)

{range greater than zero}

LN ( numeric_expression)

{range greater than zero}

example: i. PRINT LOG10(20)

ii. PRINT LN(3.141592654)

LOCal
functions and procedures

LOCal allows identifiers to be defined to be LOCal to a function or procedure. Local identifiers only exist within the function or procedure in which they are defined, or in
procedures and functions called from the function or procedure in which they are defined.

They are lost when the function or procedure terminates. Local identifiers are independent
of similarly named identifiers outside the defining function or procedure. Arrays can be defined to be local by dimensioning them within the LOCal statement.

The LOCal statement must precede the first executable statement in the function or
procedure in which it is used.

syntax:

LOCal identifier *[, identifier]*

example: i. LOCal a,b,c(10,10)

ii. LOCal temp_data

95
comment: Defining variables to be LOCal allows variable names to be used within
functions and procedures without corrupting meaningful variables of the same
name outside the function or procedure.

LRESPR

SMSQ/E

LRESPR opens the load file and finds the length of the file, then reserves space for the file in the resident procedure area before loading the file. Finally a CALL is made to the start of the file.

syntax:

LRESPR name

example: LRESPR win1_basic_ext

{load and call the SBASIC extensions

Win1_basic_ext}

LRUN

QLRUN
devices, directory devices

LRUN will load and run a SBASIC program from a specified device. LRUN will perform NEW before loading another program and so any previously stored SBASIC program will
be cleared by LRUN.

QLRUN will load an SBASIC program which has been saved by QSAVE or QSAVE_O and has a _SAV at the end of the filename.

If a line input during a loading has incorrect SBASIC syntax, the word MISTAKE is inserted between the line number and the body of the line. Upon execution, a line of this sort will
generate an error.

syntax:

LRUN device

QLRUN device

example: i. LRUN flp2_TEST

ii. LRUN ram1_game

iii. QLRUN win1_applications_editor

MACHINE

SMSQ/E

MACHINE will return the machine type that SMSQ/E is running on

syntax:

MACHINE

96
example: PRINT MACHINE

comment: MACHINE will return 30 for QPC.

MAKE_DIR

FMAKE_DIR
directory devices

The command MAKE_DIR is used to create a new subdirectory. It takes one parameter:

the subdirectory filename.

FMAKE_DIR is a function to perform the same operation as MAKE_DIR. But will return a value of zero for no error, or a negative number if an error occurs.

Error code -7
not found

Medium or drive is

not available

-8
already exists

Already directory/file

of that name

-9
in use

Already directory/file

of that name

-15
bad parameter

Device cannot

handle subdirectories

syntax:

MAKE_DIR filename

ferr = FMAKE_DIR ( filename)

example: i. MAKE_DIR flp2_letters_

ii. error_code = FMAKE_DIR (“dev1_files_”)

comment: If there are any files which, by virtue of their names, would belong in the
directory being made, then these files will be transferred to the new directory,
even if they are open.

To remove a subdirectory, firstly delete it’s contents then delete the
subdirectory Itself. COPY and WCOPY deal only with files at the specified
directory level. Subdirectories can also be applied to RAM disks.

97

MERGE

QMERGE
devices, directory devices

MERGE will load a file from the specified device and interpret it as a SBASIC program. If the new file contains a line number which doesn't appear in the program already in QPC
then the line will be added. If the new file contains a replacement line for one that already
exists then the line will be replaced. All other old program lines are left undisturbed.

QMERGE will load an SBASIC program which has been saved by QSAVE or QSAVE_O
and has a _SAV at the end of the filename.

If a line input during a MERGE has incorrect SBASIC syntax, the word MISTAKE is
inserted between the line number and the body of the line. Upon execution, a line of this
sort will generate an error.

syntax:

MERGE device

QMERGE device

example: i. MERGE win1_overlay_program

ii. QMERGE flp1_new_data

MOD
operators

MOD is an operator which gives the modulus, or remainder; when one integer is divided by another.

syntax:

numeric_expression MOD numeric_expression

example: i. PRINT 5 MOD 2 {will print 1}

ii. PRINT 5 MOD 3 {will print 2}

MODE
windows

MODE sets the resolution of the screen and the number of solid colours which it can
display. MODE will clear all windows currently on the screen, but will preserve their position and shape. Changing to low resolution mode (8 colour) will set the minimum
character size to 2,0.

MODE now only seems to have any effect in 512 x 256 QL colour mode.

syntax:

MODE numeric_expression

98

where:

8 or 256 will select low resolution mode

4 or 512 will select high resolution mode

example: i. MODE 256

ii. MODE 4

MOUSE_SPEED

MOUSE_SPEED adjusts the mouse acceleration and wake up factor for the specified or
default channel. From QPC2 version 2 on the acceleration is of no more use as the mouse
position is adapted from Windows. The wakeup factor however is still valid and ranges
from 1 to 9 with 1 being the most sensitive one.

syntax:

acceleration := numeric_expression

wakeup := numeric_expression

MOUSE_SPEED [# channel, ] acceleration, wakeup

MOUSE_STUFF

MOUSE_STUFF adjusts the string that is stuffed into the keyboard queue of the specified
or default if the middle mouse button is pressed. The string cannot be longer than 2
characters, but this is enough to trigger any hotkey, which can in turn do almost everything.

syntax:

MOUSE_STUFF [# channel, ] string

example: i. MOUSE_STUFF ‘.’

{Generates a dot if middle mouse button is
pressed}

ii. MOUSE_STUFF CHR$(255)&’.’ {Generates hotkey Alt +}

MOVE
turtle graphics

MOVE will move the graphics turtle in the window attached to the default or specified channel a specified distance in the current direction. The direction can be specified using the TURN and TURNTO commands. The graphics scale factor is used in determining how far the turtle actually moves. Specifying a negative distance will move the turtle backwards.

The turtle is moved in the window attached to the specified or default channel.

syntax:

distance:= numeric_expression

MOVE [ channel,] distance

99
example: i. MOVE #2,20

{move the turtle in channel 2 20 units forwards}

ii. MOVE -50

{move the turtle in the default channel 50 units backwards}

MRUN

QMRUN
devices, directory devices

MRUN will interpret a file as a SBASIC program and merge it with the currently loaded program. If used as direct command MRUN will run the new program from the start. If used as a program statement MRUN will continue processing on the line following MRUN.

QMRUN will load an SBASIC program which has been saved by QSAVE or QSAVE_O
and has a _SAV at the end of the filename.

If a line input during a merge has incorrect SBASIC syntax, the word MISTAKE is inserted between the line number and the body of the line. Upon execution, a line of this sort will
generate an error.

syntax:

MRUN device

QMRUN device

example: i. MRUN flp1_chain_program

ii. QMRUN flp2_new_data

NET
network

NET originally allowed the network station number to be set. The NET device is not
available in QPC. This keyword is provided for compatibility purposes only.

NEW

NEW will clear out the old program, variables and channels other than 0,1 and 2.

syntax: NEW

example: NEW

NEXT
repetition

NEXT is used to terminate, or create a loop epilogue in, REPeat and FOR loops.

syntax: NEXT identifier

100

The identifier must match that of the loop which the NEXT is to control

example: i. 10 REMark this loop must repeat forever

11 REPeat infinite_ loop

12 PRINT "still looping"

13 NEXT infinite_ loop

ii. 10 REMark this loop will repeat 20 times

11 LET limit = 20

12 FOR index=1 TO Limit

13 PRINT index

14 NEXT index

iii. 10 REMark this Loop will tell you when a 30 is found

11 REPeat Loop

12 LET number = RND(1 TO 100)

13 IF number = 30 THEN NEXT Loop

14 PRINT number; " is 30"

15 EXIT LOOP

16 END REPeat loop

in REPeat:

If NEXT is used inside a REPeat - END REPeat construct it will force
processing to continue at the statement following the matching REPeat
statement.

In FOR:

The NEXT statement can be used to repeat the FOR loop with the control
variable set at its next value. If the FOR loop is exhausted then processing
will continue at the statement following the NEXT; otherwise processing will
continue at the statement after the FOR.

ON...GOTO

ON...GOSUB

To provide compatibility with other BASICs, SBASIC supports the ON GOTO and ON

GOSUB statements. These statements allow a variable to select from a list of possible line numbers a line to process in a GOTO or GOSUB statement. If too few line numbers are specified in the list then an error is generated.

syntax:

ON variable GOTO expression *[, expression]*

ON variable GOSUB expression *[, expression]*

example: i. ON x GOTO 10, 20, 30, 40

ii. ON select_variable GOSUB 1000,2000,3000,4000

comment: SELect can be used to replace these two BASIC commands.

101

OPEN

OPEN_IN

OPEN_OVER

OPEN_DIR

OPEN_NEW
devices, directory devices

OPEN allows the user to link a logical channel to a physical QPC device for I/O purposes.

OPEN_OVER will open a new directory device file overwriting the old file if it already
exists.

OPEN_DIR will open the directory of a directory device.

If the channel is to a directory device then the directory device file can be an existing file or a new file. In which case OPEN_IN will open an already existing directory device file for input and OPEN_NEW will create a new directory device file for output.

syntax: channel:= # numeric_expressicn

OPEN channel, device

OPEN_IN channel, device

OPEN_OVER channel, device

OPEN_DIR channel, device

OPEN_NEW channel, device

example: i. OPEN #5, f_name$

ii OPEN_IN #9,"flp1_filename"

{open file mdvl_file__name}

iii OPEN_NEW #7,win1_datafile

{open file mdvl_datafile}

iv. OPEN #6,con_10x20a20x2032

{Open channel 6 to the console device creating a window size 10x20 pixels
at position 20,20 with a 32 byte keyboard type ahead buffer.}

v. OPEN #8,dev1_read_write_file.

OUTLN
windows

OUTLN is used when writing SBASIC programs for the Pointer Interface, it signals that the window is managed. Only managed windows with managed primaries may be used for
pointer input: SBASIC's primary window is usually #0.

102

The three optional parameters default to zero, but you can specify the move key, the
shadow widths or both if you wish. The shadow will appear to the right or bottom if xshad
or yshad are positive. The move key will discard the current window contents if it is zero, or
move them to the new position if it is set to 1 (you must keep the x and y sizes the same
for this to work).

If you set the outline of a secondary window, then the area underneath it will be saved, and
restored when the outline is set again: this allows you to implement pull-down windows
without having to do the saves and restores yourself.

If OUTLN is used without parameters, then it will declare the smallest area which outlines all windows currently opened for the job, to be the outline for that job, without changing the
primary window.

syntax:

xsize := numeric_expression

ysize := numeric_expression

xorg := numeric_expression

yorg := numeric_expression

xshad := numeric_expression

yshad := numeric_expression

move := numeric_expression

OUTLN [ # channel, ] xsize, ysize, xorg, yorg [ , xshad, yshad ] [ , move ]

OUTLN

example: i. OUTLN #4, 150,100,30,20,2,2

{set outline of #4 to a window 150 x 100,
at 30, 20 with a 2 pixel shading}

ii. OUTLN 512,256

{set outline of #0 to 512 x 256}

OVER
windows

OVER selects the type of over printing required in the window attached to the specified or default channel. The selected type remains in effect until the next use of OVER.

syntax:

switch:= numeric_expression

{range -1..1}

OVER [ channel,] switch

where
switch = 0 - print ink on strip

switch = 1 - print in ink on transparent strip

switch = -1 - XORs the data on the screen

example: i. OVER 1 {set "overprinting")

103

ii. 10 REMark Shadow Writing

11 PAPER 7 : INK 0 : OVER 1 : CLS

12 CSIZE 3,1

13 FOR i = 0 TO 10

14 CURSOR i,i

15 IF i=10 THEN INK 2

16 PRINT "Shadow"

17 END FOR i

PALETTE_QL

PALETTE_8
graphics device 2

PALETTE_QL allows you to change the displayed colours of the standard QL compatible
colours 0 to 7.

PALETTE_8 allows you to change the displayed colours of the 256 colour (8 bit) mode.

On hardware that does not have a true palette map, palette map changes do not affect the
information already drawn on screen.

syntax:

start := numeric_expression

true_colour := numeric_expression

{in the range 0 to 16,777,215}

PALETTE_QL start * , true_colour *

{up to 8 true colours}

PALETTE_8 start * , true_colour *

{up to 256 true colours}

example: i. 100 red = 255 * 65536

110 green = 255 * 256

120 blue = 255

130 magenta = 255 * 65536 + 255

140 yellow = 255 * 65536 + 255 * 256

150 cyan = 255 * 256 + 255

160 PALETTE_QL 0,0,yellow,cyan,green,magenta,red,blue

comment: There is a practical reason for changing the QL palette map entries. Many
programs
define some of the colours displayed as "white-colour" on a 4
colour QL display, white-red appears as green. White-red, however, is really
cyan, not green. As a result, many QL mode 4 programs take on rainbow hues
when displayed on a 256, 65536 or full colour display.

This can be "fixed" by redefining the colours so that colour 2 is a bright crimson
and colour 4 is a bright sea green. This will ensure that colour 2 + colour 4 =

104
colour 7. We also need to ensure that colour 0 = colour 1, colour 2 = colour 3,
etc.

600 crimson = 255 * 65536 + 100 : REMark crimson is red + a bit of blue

610 sea = 255 * 256 + 155 : REMark: sea green is green + the rest of
blue

620 white = crimson + sea

630 PALETTE_QL 0, 0, 0, crimson, crimson, sea, sea, white, white :

REMark set 8 colours

PAN
windows

PAN the entire current window the specified number of pixels to the left or the right.

PAPER is scrolled in to fill the clear area. An optional second parameter can be specified which will allow only part of the screen to be panned.

syntax:

distance:= numeric_expression

part::= numeric_expression

PAN [ channel,] distance [, part]

where
part = 0 - whole screen (or no parameter)

part = 3 - whole of the cursor line

part = 4 - right end of cursor line including the

cursor position

If the expression evaluates to a positive value then the contents of the screen
will be shifted to the right.

example: i. PAN #2,50

{pan left 50 pixels}

ii. PAN -100

{pan right 100 pixels}

iii. PAN 50.3

{pan the whole of the current cursor line

50 pixels to the right}

warning: If stipples are being used or the screen is in low resolution mode then, to maintain the stipple pattern, the screen must be panned in multiples of two
pixels.

PAPER
windows

PAPER sets a new paper colour (ie. the colour which will be used by CLS, PAN, SCROLL, etc). The selected paper colour remains in effect until the next use of PAPER. PAPER will also set the STRIP colour

105

PAPER will change the paper colour in the window attached to the specified or default channel.

syntax:

PAPER [ channel,] colour

example: i. PAPER #3,7 {White paper on channel 3}

ii. PAPER 7,2

{White and red stipple}

iii. PAPER 255

{Black and white stipple}

iv. 10 REMark Show colours and stipples

11 FOR colour = 0 TO 7

12 FOR contrast = 0 TO 7

13 FOR stipple = 0 TO 3

14 PAPER colour, contrast, stipple

15 SCROLL 6

16 END FOR stipple

17 END FOR contrast

18 END FOR colour

PARNAME$
procedures

The function PARNAME$ when used in a procedure will return the name of the parameter
number.

syntax:

parameter_number := numeric_expression

PARNAM$ ( parameter_number)

example: 10 pname fred, joe, 'mary'

....

70 DEF PROC pname (n1,n2,n3)

80 PRINT PARNAM$(1), PARNAM$(2), PARNAM$(3)

90 END DEF pname

would print 'fred joe ' (the expression has no name).

PARSTR$
procedures

The function PARSTR$ when used in a procedure will if parameter 'name' is a string,
return the value the string, else find the name of the parameter number.

syntax:

parameter_number := numeric_expression

PARSTR$ ( name, parameter_number)

106

example: 10 pstring fred, joe, 'mary'

....

70 DEF PROC pstring (n1,n2,n3)

80 PRINT PARSTR$(n1,1), PARSTR$(n2,2), PARSTR$(n3,3)

90 END DEF pstring

would print 'fred joe mary'.

PARTYP

PARUSE
procedures

The function PARTYP when used in a procedure will return the type of the named
parameter.

The type returned is:

0 for null

1 for string

2 for floating point

3 for integer

The function PARUSE when used in a procedure will return the usage of the named
parameter.

The usage returned is: 0 for unset

1 for variable

2 for array

syntax:

PARTYP ( name)

PARUSE ( name)

PAR_BUFF
devices

PAR_BUFF specifies the output buffer size. The output buffer should be at least 5 bytes to avoid confusion with the port number. If the output buffer is specified as zero length, a
dynamic buffer is used.

syntax:

port := numeric_expression

output_buff := numeric_expression

PAR_BUFF port, output_buff

example: i. PAR_BUFF 1,200

{200 byte output buffer on PAR1}

107

ii. PAR_BUFF 2,0

{dynamic output buffer on PAR2}

PAR_CLEAR

PAR_ABORT
devices

PAR_CLEAR and PAR_ABORT clear the output buffers of any closed channels to the
port. Channels still open are not affected. PAR_ABORT also sends the "ABORTED"

message to the port.

syntax:

port := numeric_expression

PAR_CLEAR port

PAR_ABORT port

example: i. PAR_CLEAR 1

{clear output to PAR1}

ii. PAR_ABORT 3

{abort output to PAR3}

PAR_PULSE

Not used in QPC. Sets the length of the strobe pulse of the parallel port.

PAR_USE
redirection

The PAR_USE command allows the parallel port to be used with software that only allows
output to SER1 or SER2.

syntax:

PAR_USE string_expression

example: 10 PAR_USE "ser"

20 COPY_N "flp1_myfile" TO "ser2"

{will send the file to PAR}

30 COPY_N "flp1_ myfile" TO "ser1f"

{ will print the file to PAR ending
with

a form feed}

comment: To print a file using the parallel port using free memory as a buffer enter the

following:

10 PAR_USE "lpt"

20 PRT_USE "par","lpt"

30 COPY_N "flp1_myfile" TO "par"

108

PAR_WAIT

No information available on this command.

PAUSE

PAUSE will cause a program to wait a specified period of time. Delays are specified in
units of 20ms in the UK only, otherwise 16.67ms. If no delay is specified then the program
will pause indefinitely. Keyboard input will terminate the PAUSE and restart program
execution.

syntax: delay:= numeric_expression

PAUSE [ delay]

example: i. PAUSE 50

{wait 1 second}

ii. PAUSE 500

{wait 10 seconds}

PEEK

PEEK_W

PEEK_L

BASIC

PEEK is a function which returns the contents of the specified memory location. PEEK has three forms which will access a byte (8 bits), a word (16 bits), or a long word (32 bits).

PEEK may be referenced form the system variables if the first parameter of PEEK is preceded by an exclamation mark, then the address of the peek is in the system variables
or referenced via the system variables. There are two variations: direct and indirect
references.

For direct references, the exclamation mark is followed by another exclamation mark and
an offset within the system variables.

For indirect references, the exclamation mark is followed by the offset of a pointer within
the system variables, another exclamation mark and an offset from that pointer.

PEEK may also be referenced from the SBASIC variables if the first parameter of PEEK is preceded by a backslash, then the address of the peek is in the SBASIC variables or
referenced via the SBASIC variables. There are two variations: direct and indirect
references.

109

For direct references, the backslash is followed by another backslash and an offset within
the SBASIC variables.

For indirect references, the backslash is followed by the offset of a pointer within the

SBASIC variables, another backslash and an offset from that pointer.

syntax:

address:= numeric_expression

| !! numeric_expression

| ! numeric_expression ! numeric_expression

| \\ numeric_expression

| \ numeric_expressionI \ numeric_expression

PEEK( address)

{byte access}

PEEK_W( address)

{word access}

PEEK_L( address)

{long word access}

example: i. PRINT PEEK(12245)

{byte contents of location 12245}

ii. PRINT PEEK_W(12)

{word contents of locations 12 and 13}

iii. PRINT PEEK_L(1000) {long word contents of location 1000}

iv. ramt = PEEK_L (! !$20) {find the top of RAM $20 bytes on from the base of

the system variables}

v. job1 = PEEK_L (!$68!4) {find the base address of Job 1 (4 bytes on from
base of Job table)}

vi. dal = PEEK_W (\\$94) {find the current data line number

vii. n6 = PEEK_W (\$18\2+6*8)

{find the name pointer for the 6th name in
the name table}

viii. nl6 = PEEK (\$20\n6)

{...and the length of the name}

ix. n6$ = PEEK$ (\$20\n6+1, nl6)

{...and the name itself}

warning: For word and long word access the specified address must be an even
address.

PEEKS

PEEKS_W

PEEKS_L

BASIC

Supervisor mode access to I/O hardware in Atari emulator, not used in QPC.

PEEK$

BASIC

110

PEEK$ will return a string with the number of supplied bytes starting from the supplied
address. The bytes need not, of course, be text.

syntax:

start_address := numeric_expression

number_of_bytes := numeric_expression

PEEK$ ( start_address, number_of_bytes)

example: PRINT PEEK$(123456,20)

{will display the 20 bytes from address

123456}

PEEKS$

BASIC

Supervisor mode access to I/O hardware in Atari emulator, not used in QPC.

PENUP

PENDOWN
turtle graphics

Operates the 'pen' in turtle graphics. If the pen is up then nothing will be drawn. If the pen
is down then lines will be drawn as the turtle moves across the screen.

The line will be drawn in the window attached to the specified or default channel. The line will be drawn in the current ink colour for the channel to which the output is directed.

syntax:

PENUP [ channel]

PENDOWN [ channel]

example: i. PENUP

{will raise the pen in the default channel}

ii. PENDOWN #2 {will lower the pen in the window attached to channel 2}

PI
maths function

PI is a function which returns the value of .

syntax:

PI

example: PRINT PI

111

POINT

POINT_R
graphics

POINT plots a point at the specified position in the window attached to the specified or default channel. The point is plotted using the graphics coordinates system relative to the graphics origin. If POINT_R is used then all points are specified relative to the graphics cursor and are plotted relative to each other.

Multiple points can be plotted with a single call to POINT.

syntax: x:= numeric_expression
y:= numeric_expression

parameters:= x, y

POINT [ channel,] parameters* [, parameters]*

example: i. POINT 256,128

{plot a point at (256,128)}

ii. POINT x,x*x

{plot a point at (x,x*x)}

iii. 10 REPeat example

20 INK RND(255)

30 POINT RND(100),RND(100)

40 END REPeat example

POKE

POKE_W

POKE_L

BASIC

POKE allows a memory location to be changed. For word and long word accesses the
specified address must be an even address.

POKE has three forms which will access a byte (8 bits), a word (16 bits), a long word (32
bits).

POKE may be referenced form the system variables if the first parameter of POKE is preceded by an exclamation mark, then the address of the poke is in the system variables
or referenced via the system variables. There are two variations: direct and indirect
references.

For direct references, the exclamation mark is followed by another exclamation mark and
an offset within the system variables.

112

For indirect references, the exclamation mark is followed by the offset of a pointer within
the system variables, another exclamation mark and an offset from that pointer.

POKE may also be referenced from the SBASIC variables if the first parameter of POKE is preceded by a backslash, then the address of the poke is in the SBASIC variables or
referenced via the SBASIC variables. There are two variations: direct and indirect
references.

For direct references, the backslash is followed by another backslash and an offset within
the SBASIC variables.

For indirect references, the backslash is followed by the offset of a pointer within the

SBASIC variables, another backslash and an offset from that pointer.

POKE allows more than one value to be POKEd at a time. For POKE_W and POKE_L, the address may be followed by a number of values to poke in succession. For POKE the
address may be followed by a number of values to poke in succession and the list of
values may include strings. If a string is given, all the bytes in the string are POKEd in order. The length is not POKEd.

syntax:

address:= numeric_expression

| !! numeric_expression

| ! numeric_expression ! numeric_expression

| \\ numeric_expression

| \ numeric_expressionI \ numeric_expression

data:= numeric_expression

POKE address, data [ * , data | string * ]

{byte access}

POKE_W address, data [ * , data * ]

{word access}

POKE_L address, data [ * , data * ]

{long word access}

example: i. POKE 12235,0

{set byte at 12235 to 0}

ii. POKE_L 131072,12345 {set long word at 131072 to 12345}

iii. POKE_W ! !$8E,3

{set the auto-repeat speed to 3}

iv. POKE !$B0!2, 'WIN'

{change the first three characters of DATA_USE to

WIN}

warning: Poking data into areas of memory used by SMSQ/E can cause the system to
crash and data to be lost. Poking into such areas is not recommended.

113

POKES

POKES_W

POKES_L

BASIC

Supervisor mode access to I/O hardware in Atari emulator, not used in QPC.

POKE$

BASIC

POKE$ will pokes the supplied string of bytes into memory, starting from the supplied
address.

syntax:

start_address := numeric_expression

POKE$ ( start_address, string)

POKE$ ( start_address, string)

example: POKE$(131072,"hello")

{will put the string "hello" into address

131072}

comment: PEEK$ and POKE$ can accept all the extended addressing facilities of PEEK
and POKE. Indeed, POKE$ is identical to POKE which can now accept string
parameters.

POKES$

BASIC

Supervisor mode access to I/O hardware in Atari emulator, not used in QPC.

PRINT
devices, directory devices

Allows output to be sent to the specified or default channel. The normal use of PRINT is to send data to the QPC screen.

syntax:

separator:= | !

| ,

| \

| ;

| TO numeric_expression

item:= | expression

| channel

114

| separator

PRINT *[ item]*

Multiple print separators are allowed. At least one separator must separate
channel specifications and expressions.

example: i. PRINT "Hello World"

{will output Hello World on the default output device (channel 1)}

ii. PRINT #5,"data",1,2,3,4

{will output the supplied data to channel 5 (which must have been previously
opened)}

iii. PRINT TO 20; "This is in column 20"

!

Normal action is to insert a space between items output on the screen. If the
item will not fit on the current line a line feed will be generated. If the current
print position is at the start of a line then a space will not be output. ! affects
the next item to be printed and therefore must be placed in front of the print
item being printed. Also a ; or a ! must be placed at the end of a print list if the spacing is to be continued over a series of PRINT statements.

,

Normal separator, SBASIC will tabulate output every 8 columns.

\

Will force a new line.

;

Will leave the print position immediately after the last item to be printed. Output
will be printed in one continuous stream.

TO Will perform a tabbing operation. TO followed by a numeric_expression
will advance the print position to the column specified by the
numeric_expression. If the requested column is meaningless or the current
print position is beyond the specified

position then no action will be taken.

PRINT_USING
devices, directory devices

PRINT_USING is a fixed format version of the PRINT command:

The 'format' is a string or string expression containing a template or 'image' of the required
output. Within the format string the characters + - # *, . ! \ ' " $ and @ all have special meaning. When called, the procedure scans the format string, writing out the characters of
the string, until a special character is found.

If the @ character is found, then the next character is written out, even if it is a special
character.

115

If the character is a " or ' , then all the following characters are written out until the next " or

' .

If the \ character is found, then a newline is written out.

All the other special characters appear in format 'fields'. For each field an item is taken
from the list, and formatted according to the form of the field and written out.

The field determines not only the format of the item, but also the width of the item (equal to
the width of the field). The field widths in the examples below are arbitrary.

field

format

#####
if item is string, write string left justified or truncated

otherwise write integer right justified

*****
write integer right justified empty part of field filled with *

(e.g. ***12)

####.##
fixed point decimal (e.g. 12.67)

****.**
fixed point decimal, * filled (e.g. **12.67)

##,###.##
fixed point decimal, thousands separated

**,***.**
by commas (e.g 1,234.56 or *1,234.56)

-#.####!!!!

exponent form (e.g. 2.9979E+08) optional sign

+#.####!!!!

exponent form always includes sign

###.>>
fixed point decimal, scaled (i.e. if you calculate in pennies)

The exponent field must start with a sign, one #, and a decimal point (comma or full stop).

It must end with four !s.

Any decimal field may be prefixed or postfixed with a + or -, or enclosed in parentheses. If
a field is enclosed in parentheses, then negative values will be written out enclosed in
parentheses. If a – is used then the sign is only written out if the value is negative; if a + is used, then the sign is always written out. If the sign is at the end of the field, then the sign will follow the value.

Numbers can be written out with either a comma or a full stop as the decimal point. If the
field includes only one comma or full stop, then that is the character used as the decimal
point. If there is more than one in the field, the last decimal point found (comma or full stop) will be used as the decimal point, the other is used as the thousands separator.

116

If the decimal point comes at the end of the field, then it will not be printed. This allows
currencies to be printed with the thousands separated, but with no decimal point (e.g

1,234).

Floating currency symbols are inserted into fields using the $ character. The currency
symbols are inserted between the $ and the first # in the field (e.g. $Dm#.###,## or

+$$##,###.##). When the value is converted, the currency symbols are 'floated' to the right
to meet the value.

syntax:

PRINT_USING # channel, format, * items *

example: 10 fmt$='@$ Charges *******.** : ($$Kr##.###,##) : ##,###.##+\'

20 PRINT_USING fmt$, 123.45, 123.45, 123.45

30 PRINT_USING fmt$, -12345.67, -12345.67, -12345.67

40 PRINT_USING '-#.###!!!!\', 1234567

will print

$ Charges ****123.45 : SKr123,45 :

123.45+

$ Charges *-12345.67 : (SKr12.345,67) : 12,345.67-1.235E+06

PROCESSOR

SMSQ/E

PROCESSOR will return the Motorola MC680x0 family type.

syntax:

PROCESSOR

example: PRINT PROCESSOR

comment: PROCESSOR will return 10 for QPC.

PROG_USE
program default

The PROG_USE default is used only for finding the program
files for the EX/EXEC commands,

PROG_USE is used to set a default, which is used only for finding the program files for the EX/EXEC commands, If you do not supply a complete SMSQ/E filename in the command,
the PROG_USE default will be added to the beginning of the supplied filename.

117

If the supplied filename is not found in the system, Then the PROG_USE default will be
added to the beginning of the supplied filename, and another attempt will be made to
execute the command.

syntax:

directory_name := device*[ subdirectory_]*

PROG_USE directory_name

example: 100 PROG_USE win1_programs_

110 EXEC editor

{Starts the executable program “win1_programs_editor}

comment: If the directory name supplied does not end with '_', '_' will be appended to the
directory name.

PROT_DATE
clock

PROT_DATE is used to protect or unprotect the real time clock. If the real time clock is protected, setting the date affects only SMSQ's own clock, the real time will be restored
then next time the computer is reset.

Where the system has a separate battery backed real time clock. The date is read from the
clock when the system is reset. Thereafter, the clock is kept up to date by the SMSQ timer.

In general, the system real time clock is updated whenever you adjust or set the date. As
some QL software writers could not resist the temptation of setting the date to their
birthday (or other inconvenient date) this can play havoc with your file date stamps etc.

syntax:

PROT_DATE numeric_expression

{0 or 1}

example: i. PROT_DATE 0

{date is not protected}

ii. PROT_DATE 1

{date is protected}

PROT_MEM

Not used in QPC. Set the memory protection level in Atari emulators.

PRT_BUFF
devices

118

PRT_BUFF specifies the output buffer size. The output buffer should be at least 5 bytes to avoid confusion with the port number. If the output buffer is specified as zero length, a
dynamic buffer is used.

syntax:

port := numeric_expression

output_buff := numeric_expression

PRT_BUFF port, output_buff

example: i. PRT_BUFF 1,200

{200 byte output buffer on PRT1}

ii. PRT_BUFF 2,0

{dynamic output buffer on PRT2}

PRT_CLEAR

PRT_ABORT
devices

PRT_CLEAR and PRT_ABORT clear the output buffers of any closed channels to the
port. Channels still open are not affected. PRT_ABORT also sends the "ABORTED"

message to the port.

syntax:

port := numeric_expression

PRT_CLEAR port

PRT_ABORT port

example: i. PRT_CLEAR 1

{clear output to PRT1}

ii. PRT_ABORT 3

{abort output to PRT3}

PRT_USE
devices

PRT_USE originally specified a name for the dynamic print buffer. However as all output
ports now incorporate dynamic buffering, an "add-on" printer buffer is not required.

The SMSQ/E version of PRT_USE is identical to that of the Atari ST drivers for QDOS. It
merely specifies which port will be opened if you open the device PRT.

syntax:

PRT_USE [ name ]

example: i. PRT_USE PAR : COPY fred to PRT

{copy fred to PAR}

ii. PRT_USE SER4XA : OPEN #5,PRT

{open a channel to SER4 with

XON/XOFF and <CR><LF>}

119

PRT_USE$

Do not use. The PRT_USE$ function appears to crash QPC.

QPC_EXEC

QPC

QPC_EXEC will call an external DOS or Windows program. The name of the executable
file is
given in the first parameter. Optionally you can also supply the command line arguments
with the second parameter.

Furthermore you can supply a data file as first parameter, in this case the default Windows
viewer for this type of file is executed.

syntax:

program := string_expression

parameters := string_expression

QPC_EXEC program [, parameter ]

example: i. QPC_EXEC ’notepad’,’c:\text.txt’

{Start notepad and load the c:\text
file}

ii. QPC_EXEC ’c:\text.txt’

{Start the default viewer for .TXT
files}

QPC_EXIT

QPC

QPC_EXIT will quit QPC and returns to Windows.

syntax:

QPC_EXIT

QPC_HOSTOS

QPC

QPC_HOSTOS will return the host operating system under which QPC was started.

Possible return codes are:

0 = DOS (QPC1)

1 = Win9x/ME (QPC2)

2 = WinNT/2000/XP (QPC2)

120
syntax:

QPC_HOSTOS

example: system% = QPC_HOSTOS

QPC_MAXIMIZE

QPC_MINIMIZE

QPC_RESTORE

QPC

QPC_MAXIMIZE, QPC_MINIMIZE, and QPC_RESTORE will maximise, minimises or
restore the QPC window.

syntax: QPC_MAXIMIZE

QPC_MINIMIZE

QPC_RESTORE

QPC_MSPEED

QPC

This command is supplied for compatibility reasons. It is used on QPC1 to change the
mouse acceleration. It has no effect on QPC2.

QPC_NETNAME$

QPC

QPC_NETNAME$ will return the current network name of your PC (the one you supplied
upon installation of Windows). This command can be used to distinguish between different

PCs (e.g. in the BOOT program).

QPC_QLSCREMU

QPC

QPC_QLSCREMU will enable or disable the original QL screen emulation. When
emulating the original screen, all memory write accesses to the area $20000-$207FFF are
intercepted and translated into writes to the first 512x256 pixels of the big screen area. If
the screen is in high colour mode, additional colour conversion is done.

Possible values are:

-1: automatic mode

0: disabled (default)

4: force to 4 colour mode

121

8: force to 8 colour mode

When in QL colour mode the emulation just transfers the written bytes to the larger screen
memory, i.e. when the big mode is in 4 colour mode, the original screen area is also
treated as 4 colour mode. In high colour mode however the colour conversion can do both
modes. In this case you can pre-select the emulated mode (4, 8 as parameter) or let the
last issued MODE call decide (automatic mode). Please note that that the automatic mode
does not work on a per-job basis, so any job which issues a MODE command changes the
behaviour globally.

Please also note that this transition is one-way only, i.e. bytes written legally to the first

512x256 pixels are not transferred back to the original QL screen (in case of a high colours
screen this would hardly be possible anyway). Unfortunately this also means that not all
old programs run perfectly with this type of emulation. If you experience problems, start the
misbehaving application in 512x256 mode.

syntax:

value := numeric_expression

QPC_QLSCREMU value

example: QPC_SCREMU 4

{force 4 colour mode}

QPC_SYNCSCRAP

QPC

In order to quickly exchange text passages between Windows and SMSQ the syncscrap
functionality was introduced. The equivalent of the Windows clipboard is the scrap
extension of the menu extensions. After loading the menu extensions you can call this
command which creates a job that periodically checks for changes in either the scrap or
the Windows clipboard and synchronises their contents if necessary. Please note that only
text contents is supported. The character conversion between the QL character set and the

Windows ANSI set is done automatically. The line terminators (LF/CR, LF alone) are
converted, too.

syntax:

QPC_SYNCSCRAP

QPC_VER$

QPC

QPC_VER$ will return the current QPC version.

syntax:

QPC_VER$

example: v$ = QPC_VER$

comment: QPC_VER$ will return 3.00 or higher.

122

QUIT
basic

QUIT will end any SBASIC daughter jobs whether it has been created by the SBASIC
command, EX or any other means.

syntax:

QUIT

comment: QUIT will not end the primary SBASIC job (job 0). To quit from this job, use

QPC_QUIT.

RAD
maths functions

RAD is a function which will convert an angle specified in degrees to an angle specified in radians.

syntax:

RAD ( numeric_expression)

example: PRINT RAD(180)

{will print 3.141593}

RAM_USE
directory devices

RAM_USE allows renaming of the RAM device. RAM_USE without a parameter will reset the name of RAM back to RAM.

syntax:

RAM_USE [ name ]

example: i. RAM _USE flp : LOAD flp2_prog

{loads 'prog' from RAM2_ }

ii. RAM _USE

{and now its name is RAM again}

iii. RAM_USE win : DIR win1_

{displays directory of RAM1_}

RANDOMISE
maths functions

RANDOMISE allows the random number generator to be reseeded. If a parameter is
specified the parameter is taken to be the new seed. If no parameter is specified then the
generator is reseeded from internal information.

syntax:

RANDOMISE [ numeric_expression]

example: i. RANDOMISE

{set seed to internal data}

123

ii. RANDOMISE 3.2235

{set seed to 3.2235}

RECOL
windows

RECOL will recolour individual pixels in the window attached to the specified or default channel according to some pre-set pattern. Each parameter is assumed to specify, in
order, the colour in which each pixel is recoloured, i.e. the first parameter specifies the
colour with which to recolour all black pixels, the second parameter blue pixels, etc.

The colour specification must be a solid colour, i.e. it must be in the range 0 to 7.

RECOL only works as specified in 512 x 256 QL colour mode. Using it in other screen
modes gives unpredictable effects.

syntax:

c0:= new colour for black

c1:= new colour for blue

c2:= new colour for red

c3:= new colour for magenta

c4:= new colour for green

c5:= new colour for cyan

c6:= new colour for yellow

c7:= new colour for white

RECOL [ channel ,] c0, c1, c2, c3, c4, c5, c6, c7

example: RECOL 2,3,4,5,6,7,1,0

{recolour blue to magenta, red to green, magenta
to cyan etc.}

REMark

REMark allows explanatory text to be inserted into a program. The remainder of the line is ignored by SBASIC.

syntax:

REMark text

example: REMark This is a comment in a program

comment: REMark is used to add comments to a program to aid clarity.

124

RENAME

WREN
directory devices

RENAME and WREN (wild card renaming) is a process similar to COPYing a file, but the file itself is neither moved nor duplicated, only the directory name is changed. The
commands, however, are exactly the same in use as the equivalent COPY commands.

syntax:

RENAME name TO name

WREN [# channel,] name TO name

RENUM

RENUM allows a group or a series of groups of SBASIC line numbers to be changed. If no
parameters are specified then RENUM will renumber the entire program. The new listing
will begin at line 100 and proceed in steps of 10.

If a start line is specified then line numbers prior to the start line will be unchanged. If an end line is specified then line numbers following the end line will be unchanged.

If a start number and stop are specified then the lines to be renumbered will be numbered
from the start number and proceed in steps of the specified size.

If a GOTO or GOSUB statement contains an expression starting with a number then this
number is treated as a line number and is renumbered.

syntax:

startline:=
numeric_expression

{start renumber}

end_line:=
numeric_expression

{stop renumber}

start_number:=
numeric_expression

{base line number}

step:=

numeric_expression

{step}

RENUM [ start_line [TO end_line];] [ startnumber] [, step]

example: i. RENUM

{renumber whole program from 100 by 10}

ii. RENUM 100 TO 200

{renumber from 100 to 200 by 10}

warning: No attempt must be made to use RENUM to renumber program lines out of
sequence, ie to move lines about the program. RENUM should not be used in a
program.

125

REPeat

END REPeat
repetition

REPeat allows general repeat loops to be constructed. REPeat should be used with EXIT
for maximum effect. REPeat can be used in both long and short forms:

short:

The REPeat keyword and loop identifer are followed on the same logical line by
a colon and a sequence of SBASIC statements. EXIT will resume normal
processing at the next logical line.

syntax:

REPeat identifier : statements

example:

REPeat wait : IF INKEY$ = "" THEN EXIT wait

long:

The REPeat keyword and the loop identifier are the only statements on the
logical line. Subsequent lines contain a series of SBASIC statements
terminated by an END REPeat statement.

The statements between the REPeat and the END REPeat are repeatedly
processed by SBASIC.

syntax:

REPeat identifier

statements

END REPeat identifier

example:

10 LET number = RND(1 TO 50)

11 REPeat guess

12 INPUT "What is your guess?", guess

13 IF guess = number THEN

14 PRINT "You have guessed correctly"

15 EXIT guess

16 ELSE

17 PRINT "You have guessed incorrectly"

18 END IF

19 END REPeat guess

comment: Normally at least one statement in a REPeat loop will be an EXIT statement.

REPORT
error handling

REPORT will report the description of the last error encountered to the specified of default
channel. An optional error number may be supplied. if so, the error message for this
number will be reported.

126
syntax:

error_number := numeric_expression

REPORT [# channel, ] [ error_ number]

comment: The default channel is #0

RESET

RESET will reset the computer. Using this command could result in loss of data (e.g. when you RESET while sectors are being written to your floppy disk or hard disk), therefore
much care should be taken if this command is used without the control of the user.

syntax:

RESET

RESPR

SMSQ/E

RESPR is a function which will reserve some of the resident procedure space. (For
example to expand the SBASIC procedure list.)

syntax:

space:= numeric_expression

RESPR ( space)

example: PRINT RESPR(1024)

{will print the base address of a 1024 byte block}

RETurn
functions and procedures

RETurn is used to force a function or procedure to terminate and resume processing at the statement after the procedure or function call. When used within a function definition the

RETurn statement is used to return the function's value.

syntax:

RETern [ expression]

example: i. 100 PRINT ack (3,3)

110 DEFine FuNction ack(m,n)

120 IF m=0 THEN RETurn n+l

130 IF n=0 THEN RETurn ack (m-l,l)

140 RETern a c k (m-l ,a c k (m, n-l ) )

150 END DEFine

ii. 10 LET warning_flag =1

11 LET error_number = RND(0 TO 10)

12 warning error_number

13 DEFine PROCedure warning(n)

14 IF warning_flag THEN

127

15 PRINT "WARNING:";

16 SELect ON n

17 ON n =1

18 PRINT "Microdrive full"

19 ON n = 2

20 PRINT "Data space full"

21 ON n = REMAINDER

22 PRINT "Program error"

23 END SELect

24 ELSE

25 RETurn

26 END IF

27 END DEFine

comment:

It is not compulsory to have a RETurn in a procedure. If processing reaches
the END DEFine of a procedure then the procedure will return automatically.

RETurn by itself is used to return from a GOSUB.

RJOB

SMSQ/E

RJOB is a command to remove a job from SMSQ/E.

syntax:

job_identifier :=

| job_number , tag_number

| job_number + ( tag_number * 65536)

id := job_identifier

RJOB id | name , error_code

example: i. RJOB 3,8,-1

{remove Job 3, tag 8 with error –1}

ii. RJOB 524291,-1

{Same as above}

comment: If a name is given rather than a Job ID, then the procedure will search for the
first Job it can find with the given name.

RND
maths function

RND generates a random number. Up to two parameters may be specified for RND. If no parameters are specified then RND returns a pseudo random floating point number in the exclusive range 0 to 1. If a single parameter is specified then RND returns an integer in the inclusive range 0 to the specified parameter. If two parameters are specified then RND
returns an integer in the inclusive range specified by the two parameters.

128

syntax:

RND( [ numeric_expression] [TO numeric_expression])

example: i. PRINT RND

{floating point number between 0 and 1}

ii. PRINT RND(10 TO 20) {integer between 10 and 20}

iii. PRINT RND(1 TO 6)

{integer between 1 and 6}

iv. PRINT RND(10)

{integer between 0 and 10}

RUN
program

RUN allows an SBASIC program to be started. If a line number is specified in the RUN
command then the program will be started at that point, otherwise the program will start at
the lowest line number.

syntax:

RUN [ numeric_expression]

example: i. RUN

{run from start}

ii. RUN 10

{run from line 10}

iii. RUN 2*20

{run from line 40}

comment: Although RUN can be used within a program its normal use is to start program

execution by typing it in as a direct command.

SAVE

QSAVE

SAVE_O

QSAVE_O
devices, directory devices

SAVE will save a SBASIC program onto any QPC device.

QSAVE will save an SBASIC program, overwriting it if it already exists.

QSAVE and QSAVE_O will save an SBASIC program in the quick load format with a

_SAV at the end of the filename.

syntax:

line:= | numeric_expression TO numeric_expression

(1)

| numeric_expression TO

(2)

| TO numeric_expression

(3)

| numeric_expression

(4)

|

(5)

129

SAVE device *[, line]*

QSAVE device *[, line]*

SAVE_O device *[, line]*

QSAVE_O device *[, line]*

where

(1) will save from the specified line to the specified line

(2) will save from the specified line to the end

(3) will save from the start to the specified line

(4) will save the specified line

(5) will save the whole program

example: i. SAVE win1_program,20 TO 70

{save lines 20 to 70 on win1_program}

ii. QSAVE flp2_test_program,10,20,40

{quick save lines 10,20,40 on flp1_test_program}

iii. SAVE_O dev1_program

{save the entire program to dev1_program, overwriting if it exists}

iv. SAVE ser1

{save the entire program on serial channel }

SBASIC

BASIC

SBASIC will create a daughter SBASIC job.

Having a number of SBASIC jobs which completely cover each other may not be very
useful. SBASIC daughter jobs may, therefore, either be created either with the full set of
standard windows (in which case they all overlap) or they may be created with only one
small window (#0).

The SBASIC command, has an optional parameter: the x and y positions of window #0 in a
one or two digit number (or string).

If no parameters are given, the full set of standard windows will be opened. Otherwise,
only window #0 will be opened: 6 rows high and 42 mode 4 characters wide within a 1 pixel
wide border (total 62x256 pixels).

If only one digit is given, this is the SBASIC "row" number: row 0 is at the top, row 1 starts at screen line 64, row 4 is just below the standard window #0.

If two digits are given, this is the SBASIC "column, row" (x,y) position: column 0 is at the left, column 1 starts at 256 pixel in from the left.

syntax:

row := numeric_expression

130

columnrow := numeric_expression

SBASIC [ row | columnrow ]

example: i. SBASIC

{create an SBASIC daughter with the 3 standard windows}

ii. SBASIC 1

{create an SBASIC daughter with just channel #0 in row 1}

iii. SBASIC 24

{create an SBASIC daughter to the right of and below the
standard windows (an 800x600 display is required)}

comment: Because it is quite normal for an SBASIC job to have only #0 open, all the
standard commands which default to window #1 (PRINT, CLS etc.) or window

#2 (ED, LIST etc.) will default to window #0 if channel #1 or channel #2 is not
open. This may not apply to extension commands.

SBYTES

SBYTES_O
devices, directory devices

SBYTES allows areas of QPC memory to be saved on a QPC device.

SBYTES_O as SBYTES but overwrites the file if it exists.

If a channel number of an open channel is supplied in place of a filename, then SBYTES
will attempt to save the file to the channel.

syntax:

start_address:= numeric_expression
length:=
numeric_expression

device := filename | channel

SBYTES device, start_address, length

SBYTES_O device, start_address, length

example: i. SBYTES flp1_screendata,SCR_BASE,SCR_LLEN* SCR_YLIM

{save screen image on flp1_test_program}

ii. SBYTES_O ram1_test_program,50000,1000

{save memory 50000 length 1000 bytes on ram1_test_program
overwriting if it already exists}

iii. SBYTES neto_3,32768,32678

{save memory 32768 length 32768 bytes on the network}

iv. SBYTES ser1,0,32768

{save memory 0 length 32768 bytes on serial channel 1}

v. 10 OPEN#5,ram1_data

{open channel}

20 SBYTES#5,50000,1000

{save 1000 bytes from address 50000}

30 CLOSE#5

{close channel}

131

SCALE
graphics

SCALE allows the scale factor used by the graphics procedures to be altered. A scale of 'x'

implies that a vertical line of length 'x' will fill the vertical axis of the window in which the figure is drawn. A scale of 100 is the default. SCALE also allows the origin of the
coordinate system to be specified. This effectively allows the window being used for the
graphics to be moved around a much larger graphics space.

syntax:

x:= numeric_expression

y:= numeric_expression

origin:= x, y

scale:= numeric_expression

SCALE [ channel,] scale, origin

example: i. SCALE 0.5,0.1,0.1

{set scale to 0.5 with the origin at 0.1,0.1}

ii. SCALE 10,0,0

{set scale to 10 with the origin at 0,0}

iii. SCALE 100,50,50

{set scale to 100 with the origin at 50,50}

SCROLL
windows

SCROLL scrolls the window attached to the specified or default channel up or down by the given number of pixels. Paper is scrolled in at the top or the bottom to fill the clear space.

An optional third parameter can be specified to obtain a part screen scroll.

syntax:

part:=
numeric_expression

distance:= numeric_expression

where
part = 0 - whole screen (default is no parameter)

part = 1 - top excluding the cursor line

part = 2 - bottom excluding the cursor line

SCROLL [ channel,] distance [, part]

If the distance is positive then the contents of the screen will be shifted down.

example: i. SCROLL 10

{scroll down 10 pixels}

ii. SCROLL -70

{scroll up 70 pixels}

iii. SCROLL -10,2 {scroll the lower part of the window up 10 pixels}

132

SCR_BASE

SCR_LLEN
windows

SCR_BASE will return the base address of the screen attached to the specified or default
channel.

SCR_LLEN will return the line length in bytes of the screen attached to the specified or
default channel.

syntax:

SCR_BASE [# channel]

SCR_LLEN [# channel]

example: i. PRINT SCR_BASE

ii. PRINT SCR_LLEN #1

comment: In current versions, the values returned are the same for all screen channels.

SCR_XLIM

SCR- YLIM
windows

SCR_XLIM will return the maximum number of pixels across the screen (+1), available for
the screen attached to the specified, or default channel.

SCR_YLIM will return the maximum number of pixels down the screen (+1), available for
the screen attached to the specified, or default channel.

syntax:

SCR_XLIM [# channel]

SCR_YLIM [# channel]

example: i. PRINT SCR_XLIM

ii. PRINT SCR_YLIM #1

comment: The values returned are not the same as the current window size, but they
defines the maximum size that a window can be. SCR_XLIM and SCR_YLIM
should only be called for a primary window, usually #0 the default channel, for
an SBASIC job.

SDATE
clock

The SDATE command allows QPC’s clock to be reset.

133

syntax:

year:=
numeric_expression

month:=
numeric_expression
day:=
numeric_expression

hours:=
numenc_expression

minutes:= numeric_expression

seconds:= numeric_expression

SDATE year, month, day, hours, minutes, seconds example: i. SDATE 1984,4,2,0,0,0

ii. SDATE 1984,1,12,9,30,0

iii. SDATE 1984,3,21,0,0,0

SELect

END SELect
conditions

SELect allows various courses of action to be taken depending on the value of a variable.

define:

select_variable:= numeric_variable
select_item:= | expression

| expression TO expression
select_list:= | select_item *[, select_item]*

long:

Allows multiple actions to be selected depending on the value of a
select_variable. The select variable is the last item on the logical line. A series
of SBASIC statements follows, which is terminated by the next ON statement or
by the END SELect statement. If the select item is an expression then a check
is made within approximately 1 part in 10-7, otherwise for expression TO
expression the range is tested exactly and is inclusive. The ON REMAINDER
statement allows a, "catch-all" which will respond if no other select conditions
are satisfied.

syntax:

SELect ON select_variable

*[[ON select_variable] = select_list

statements] *

[ON selectvariable] = REMAINDER

statements

END SELect

example:

100 LET error number = RND(1 TO 10)

110 SELect ON error_number

120 ON error_number =1

130 PRINT "Divide by zero"

134

140 LET error_number = 0

150 ON error_number = 2

160 PRINT "File not found"

170 LET error_number = 0

180 ON error_number = 3 TO 5

190 PRINT "Microdrive file not found"

200 LET error_number = 0

210 ON error_number = REMAINDER

220 PRINT "Unknown error"

230 END SELect

If the select variable is used in the body of the SELect statement then it must
match the select variable given in the select header.

Short:

The short form of the SELect statement allows simple single line selections to
be made. A sequence of SBASIC statements follows on the same logical line
as the SELect statement. If the condition defined in the select statement is
satisfied then the sequence of SBASIC statements is processed.

syntax:

SELect ON select_variable = select_list : statement *[: statement]

*

example:

i. SELect ON test data =1 TO 10 :

PRINT "Answer within range"

ii SELect ON answer = 0.00001 TO 0.00005 :

PRINT "Accuracy OK"

iii. SELect ON a =1 TO 10 : PRINT a ! "in range"

comment: The short form of the SELect statement allows ranges to be tested more easily
than with an IF statement. Compare example ii. above with the corresponding

IF statement.

SEND_EVENT

SEND_EVENT event procedure is used to notify events to another job. The job ID can be
the whole number, the job number and tag or the job name.

syntax:

jobID := numeric_expression

| job_number , job_tag

| job_name

event := numeric_expression

{in the range 1 to 256}

SEND_EVENT jobID, event

example: i. SEND_EVENT 'fred',9

{Send events 1 and 8 (1 +8=9) to job fred}

135

ii. SEND_EVENT 20,4,8

{Send event 8 to job 20, tag 4}

iii. SEND_EVENT OJOB(-1),2

{Send event 2 to my owner}

SER_BUFF
devices

SER_BUFF specifies the output buffer size and, optionally, the input buffer size. The
output buffer should be at least 5 bytes to avoid confusion with the port number. If the
output buffer is specified as zero length, a dynamic buffer is used.

syntax:

port := numeric_expression

input_buff := numeric_expression

output_buff := numeric_expression

SER_BUFF port, output_buff, input_buff

example: i. SER_BUFF 200

{200 byte output buffer on SER1}

ii. SER_BUFF 4,0,80

{dynamic output buffer, 80 byte input buffer on

SER4}

SER_CDEOF
devices

SER_CDEOF specifies a timeout from the CD line being negated to the channel returning
an end of file. The timeout should be at least 5 ticks to avoid confusion with the port
number. If the timeout is zero, the CD line is ignored.

syntax:

port := numeric_expression

ticks := numeric_expression

SER_CDEOF port, ticks

example: SER_CDEOF 2,100

{wait 100 ticks before timing out}

SER_CLEAR

SER_ ABORT
devices

SER_CLEAR and SER_ABORT clear the output buffers of any closed channels to the
port. Channels still open are not affected. SER_ABORT also sends the " ABORTED"

message to the port.

136
syntax:

port := numeric_expression

SER_CLEAR port

SER_ABORT port

example: i. SER_CLEAR 1

{clear output to SER1}

ii. SER_ABORT 3

{abort output to SER3}

SER_FLOW
devices

SER_FLOW specifies the flow control for the port: "Hardware", "XON/XOFF" or "Ignored".

It usually takes effect immediately.

If, however, the current flow is "Hardware" and handshake line CTS is negated and there is a byte waiting to be transmitted, the change will not take effect until either the handshake
is asserted, or there is an output operation to that port

The default flow control is hardware unless the port does not have any handshake
connections, in which case XON/XOFF is the default.

The flow control for a port is reset if a channel is opened to that port with a specific
handshaking (H, X or I) option.

syntax:

port := numeric_expression

hand_shake := H | X | I

{Hardware, XON/XOFF, or Ignore}

SER_FLOW port, hand_shake

example: i. SER_FLOW X

{XON/XOFF on SER1}

ii. SER=FLOW 2,H

{Hardware (default) handshaking on SER2}

SER_PAUSE

Not used in QPC. Sets the length of the stop bits on the serial ports.

SER_ROOM
devices

SER_ROOM specifies the minimum level for the spare room in the input buffer. When the
input buffer is filled beyond this level, the handshake (hardware or XOFF as specified by

SER_FLOW) is negated to stop the flow of data into the port Some spare room is required
to handle overruns (not all operating systems can respond as quickly as SMSQ).

137

For hardware handshaking, a few spare bytes are all that is required. For connection to a
dinosaur using XON/XOFF handshaking, up to 1000 spare bytes may be required.

syntax:

port := numeric_expression

room := numeric_expression

SER_ROOM port, room

example: i. SER_FLOW 2,X : SER_ROOM 2,1000 {connect SER2 to a UNIX system}

ii. SER_FLOW 1,H : SER_ROOM 1,4

{hardware handshaking on SER1]

comment: SER_ROOM will not usually be required as SER_BUFF also sets SER_ROOM
to one quarter of the buffer size. You will not succeed in setting SER_ROOM to
greater than SER_BUFF, however, as SER_ROOM will always ensure that the
buffer is at least twice the size of the spare room.

SER_USE
devices

SER_USE specifies a name for the serial ports. The name can be SER or PAR. SER_USE
is provided for compatibility , its use is not recommended.

syntax:

SER_USE [ name ]

example: i. SER_USE PAR

{From now on, when you open PAR, you open a
serial port}

ii. SER_USE SER

{Sets you back to normal}

iii. SER_USE

{ ..as does this}

SET_FUPDT

SET_FBKDT

SET_FVERS
directory devices

These three commands are used to set the update date, the backup date, and the version
number of a file.

SET_FUPDT will set the update date in the specified file, or the file connected to the
specified or default channel, to the current or specified date and time.

SET_FBKDT will set the backup date in the specified file, or the file connected to the
specified or default channel, to the current or specified date and time.

138

SET_FVERS will set the version number of the specified file, or the file connected to the specified or default channel, to the specified version number.

syntax:

SET_FUPDT [ \ filename , ] | [ channel, ] [ date]

SET_FBKDT [ \ filename , ] | [ channel, ] [ date]

SET_FVERS [ \ filename , ] | [ channel, ] [ numeric_expression]

example: i. SET_FUPDT #5

{set update date to now}

ii. SET_FUPDT \flp1_fred,DATE–24*60*60 {set update of flp1_fred to 24
hours ago}

iii. SET_FBKDT \flp1_fred

{set backup date of flp1_fred to
now}

iv. SET_FBKDT #4,DATE(2002,7,10,13,32,15) {set backup date to 10th July

2002 1:32 PM and 15 seconds}

v. SET_FVERS #5

{do not increment version number}

vi. SET_FVERS #5,1

{set version number to 1}

vii. SET_FVERS \flp1_fred,2

{set version number of flp1_fred to

2}

comment: A date or a version number of 0 will have the same effect as omitting it. A date
of a version number of –1 will have no effect on the file. If the update date has
been set it will not be reset when the file is closed. If the version number has
been set it will not be incremented when the file is closed.

SEXEC

SEXEC_O

SMSQ/E

Will save an area of memory in a form which is suitable for loading and executing with the

EXEC command.

SEXEC_O is the same as SEXEC, but will overwrite the file if it already exists.

The data saved should constitute a machine code program.

If a channel number of an open channel is supplied in place of a filename, then SBYTES
will attempt to save the file to the channel.

syntax:

device := filename | channel

start_address:= numeric_expression {start of area}

length:= numeric_expression

{length of area}

data_space:= numeric_expression {length of data area which will be required
by the program}

139

SEXEC device, start_address, length, data_space

SEXEC_O device, start_address, length, data_space

example: i. SEXEC flp1_program,262144,3000,500

ii. 10 OPEN#5,flp1_program

{open channel}

20 SEXEC_O#5,50000,1000

{save 1000 bytes from address

50000}

30 CLOSE#5

{close channel}

The QDOS, SMSQ/E system documentation should be read before attempting to use this
command.

SIN
maths function

SIN will compute the sine of the specified parameter.

syntax:

angle:= numeric_expression {range -10000..10000 in radians}

SIN( angle)

example: i. PRINT SIN(3)

ii. PRINT SIN(3.141592654/2)

SLUG

SLUG will delay all subsequent reads of the keyboard by a supplied amount in
thousandths of a second (milliseconds). This is to allow some programs which too fast in

QPC to be slowed down.

syntax:

SLUG numeric_expression

example: SLUG 15

{add a 15 thousandths of a second delay}

SPJOB

SMSQ/E

SPJOB is a command to set a jobs priority.

syntax:

job_identifier :=

| job_number , tag_number

| job_number + ( tag_number * 65536)

id := job_identifier

SPJOB id | name , priority

140

example: i. SPJOB demon,1

{set the priority of the Job called 'demon' to 1}

ii. SPJOB 2,1,80

{set the priority of the Job number 2, Tag number

1

to 80}

comment: If a name is given rather than a Job ID, then the procedure will search for the
first Job it can find with the given name.

Setting a jobs priority to zero will suspend the job.

SPL

SPLF
devices

SPL and SPLF will copy files in the background in the same way as COPY_O, but is primarily intended for copying files to a printer. As an option, a form feed (ASCII <FF>) can be sent to the printer at the end of file.

syntax:

SPL name TO name

{spool a file}

SPLF name TO name

{spool a file, <FF> at end}

The separator TO is used for clarity, you may use a comma instead.

A variation on the SPL and SPLF commands is to use SBASIC channels in place of the filenames. These channels should be opened before the spooler is invoked:

syntax:

SPL # channel3 TO # channel2

Where channel3 must have been opened for input and channel2 must have been opened
for output.

The normal use of this command is with one name only:

example: i. SPL win1_doc_text TO par

{spool win1_doc_text to par}

ii. SPL_USE ser

{set spooler default}

.....

SPLF fred

{spool fred to ser, adding a form feed to
the file}

comment: When used in this way, if the default device is in use, the Job will be suspended
until the device is available. This means that many files can be spooled to a
printer at once.

141

SPL_USE

SPL_USE is used to set a default, which is used to find the destination filename or device for background spooling.

If the supplied device and filename is not found in the system, Then the SPL_USE default will be added to the beginning of the supplied filename, and another attempt will be made
to execute the command.

syntax:

directory_name := device*[ subdirectory_]*

SPL_USE device_name

example i. DEST_USE flp2_old

{default is FLP2_OLD_}

----

SPL fred

ii. SPL_USE flp2_old_

{default is FLP2_OLD_}

----

SPL fred

Both of these examples will spool FRED to FLP2_OLD_FRED. Whereas if

SPL_USE is used with a name without a trailing '_' (i.e. not a directory name)

as follows

SPL_USE ser

{default is SER}

----

SPL fred

then FRED will be spooled to SER (not SER_FRED).

Note that SPL_USE overwrites the DEST_USE default and vice versa

SQRT
maths function
will compute the square root of the specified argument. The argument must be greater
than or equal to zero.

syntax:

SQRT ( numeric_expression) {range >= 0}

example: i. PRINT SQRT(3)

{print square root of 3}

ii. LET C = SQRT(a^2+b^2) {let c become equal to the square root of a^2 +
b^2}

142

STAT
directory devices

STAT will obtain and display in the window attached to the specified or default channel the directory device statistics for that drive.

syntax:

STAT [# channel,] name

STAT \ name1, name2

comment: Both the channel and the name are optional

STOP

BASIC

STOP will terminate execution of a program and will return SBASIC to the command
interpreter.

syntax:

STOP

example: i. STOP

ii. IF n =100 THEN STOP

You may CONTINUE after STOP.

comment: The last executable line of a program will act as an automatic stop.

STRIP
windows

STRIP will set the current strip colour in the window attached to the specified or default channel. The strip colour is the background colour which is used when OVER 1 is
selected. Setting PAPER will automatically set the strip colour to the new PAPER colour.

syntax:

STRIP [ channel,] colour

example: i. STRIP 7

{set a white strip}

ii. STRIP 0,4,2

{set a black and green stipple strip}

comment: The effect of STRIP is rather like using a highlighting pen.

TAN
maths functions

143

TAN will compute the tangent of the specified argument. The argument must be in the
range -30000 to 30000 and must be specified in radians.

syntax:

TAN ( numeric_expression) {range -30000..30000}

example: i. TAN(3)

{print tan 3}

ii. TAN(3.141592654/2)

{print tan PI/2}

TH_FIX

No information available on this command.

TK2_EXT

If, for any reason, some of the SBASIC extensions have been re-defined, TK2_EXT will
reassert the common commands and functions .

syntax:

TK2_EXT

TRA

TRA allows you to set up a translation table for a printer.

The SBASIC TRA command differs very slightly in use from the QL JS and MG TRA. The differences are quite deliberate and have been made to avoid the unfortunate interactions
between functions of setting the Operating System message table and setting the printer
translate tables. If you only wish to set the printer translate tables, the only difference is
that TRA 0 and TRA 1 merely activate and deactivate the translate. They do not smash the pointer to the translate tables if you have previously set it with a TRA address command.

If you wish to change the system message tables, then the best way is to introduce a new
language: this is done by. LRESPRing suitable message tables.

Language dependent printer translate tables are selected by the TRA 1,lang command. If
no language code or car registration code is given, the currently defined language is used.

Language independent translate tables are set by the TRA n command where n is a small
odd number.

Private translate tables are set by the TRA addr command where addr is the address of a
table with the special language code $4AFB.

syntax:

lang := language_code | registration

address := numeric_expression

144

TRA [ lang | address ]

example: i. TRA 0

{translate off, table unchanged}

ii. TRA 0, 44

{translate off, table set to English}

iii. TRA 0, F

{translate off, table set to French}

iv. TRA 1

{translate on, table unchanged}

v. TRA 1, GB

{translate on, table set to English}

vi. TRA 1, 33

{translate on, table set to French}

vii. TRA 3

{translate on, table set to IBM graphics}

viii. TRA 5

{translate on, table set to GEM VDI}

A = RESPR (512): LBYTES "tratab",A: TRA A

{translate on, table set to
table in "tratab"}

comment: To use the language independent tables, your printer should be set to USA (to
ensure that you have all the # $ @ [ ] { } \ |^~ symbols which tend to go missing
if you use one of the special country codes (thank you ANSI)), and select IBM
graphics or GEM character codes as appropriate.

For the IBM tables, QDOS codes $C0 to $DF are passed through directly and

QDOS codes $E0 to $EF are translated to $B0 to $BF to give you all the
graphic characters in the range $B0 to $DF. QDOS codes $F0 to $FF are
passed though directly to give access to the odd characters at the top of the

IBM set. For the GEM tables, QDOS codes $C0 to $FF are passed through
directly.

TRUNCATE

TRUNCATE will delete the contents of the file connected to the specified or default
channel, from the current or specified position to the end of the file.

syntax:

TRUNCATE # channel\ position

example: TRUNCATE #dbchan

{truncate the file open on channel dbchan}

comment: If the position is not given, the file will be truncated to the current position

TURN

TURNTO
turtle graphics

TURN allows the heading of the 'turtle' to be turned through a specified angle while

TURNTO allows the turtle to be turned to a specific heading.

145

The turtle is turned in the window attached to the specified or default channel.

The angle is specified in degrees. A positive number of degrees will turn the turtle anti-
clockwise and a negative number will turn it clockwise.

Initially the turtle is pointing at 00 , that is to the right hand side of the window.

syntax:

angle:= numeric_expression {angle in degrees}

TURN [ channel,] angle

TURNTO [ channel,] angle

example: i. TURN 90

{turn through 900 }

ii. TURNTO 0

{turn to heading 00 }

UNDER
windows

Turns underline either on or off for subsequent output lines. Underlining is in the current

INK colour in the window attached to the specified or default channel.

syntax:

switch:= numeric_expression

{range 0..1}

UNDER [ channel,] switch

example: i. UNDER 1

{underlining on}

ii. UNDER 0

{underlining off}

VER$

SBASIC

VER$ will return system version information.

VER$ without parameters, or with a parameter of 0 will return the SBASIC version.

A parameter of 1 will return the SMSQ version number, a parameter of –1 will return the
job ID, and a parameter of –2 will return the address of the system variables.

syntax:

VER$ [ ( numeric_expression ) ]

example: i. PRINT ver$

{prints HBA (or later SBASIC version ID)}

ii. PRINT ver$(0)

{also prints HBA (or later SBASIC version ID)}

iii. PRINT ver$(1)

{prints 2.22 (or later SMSQ version number)}

iv. PRINT ver$(-1)

{print the Job ID (0 for initial SBASIC)}

146

v. PRINT ver$(-2)

{prints the address of the system variables

(163840)}

VIEW

VIEW allows a file to be examined in a window on the QPC display. The default window is

#1.

VIEW truncates lines to fit the width of the window. When the window is full, CTRL F5 is generated. If the output device (or file) is not a console, then lines are truncated to 80
characters.

syntax:

VIEW [ channel,] device

VIEW \ device, device

example: i. VIEW win1_boot

{View file 'win1_boot' in window #1

ii. VIEW #3, flp1_readme_text

{View file 'flp1_readme_text' in window

#3}

iii. VIEW \ser1,win1_boot

{Send file 'win1_boot' to serial port 1}

WAIT_EVENT

The WAIT_EVENT function is used to wait for one or more events. 8 events are defined;
they are numbered 1, 2, 4, 8 ...256. The timeout is an optional 9th event .

The function returns the event or events that have occurred. The events that are returned
are removed from the job's "event accumulator". Note that, if WAIT_EVENT is called to wait for events 2 or 4 and events 2 and 8 have occurred, only event 2 is returned: event 8
remains pending and can be checked on another call.

If a timeout is specified, then, if no event of interest has occurred before the end of the
timeout, the call will return the value 0 (no events). A timeout 0 can be used to check for
events.

syntax:

event_mask := numeric_expression

{in range 1 to 256}

timeout := numeric_expression

WAIT_EVENT ( event_mask, [ timeout ] )

example: i. evt = WAIT _EVENT (6)

{Wait for event 2 or 4 (2-+4=6) Events 2
and 8 are notified by another job so the
wait is terminated and evt is set}

ii. PRINT evt

{Prints 2}

147

iii. PRINT WAIT_EVENT (15)

{Wait for event 1,2,3,4, or 8, prints 8 as
event 8 is pending}

iv. PRINT WAIT_EVENT (15)

{Wait for event 1,2,3,4, or8, wait as no
events now pending}

v. evt = WAIT _EVENT (6,50)

{Wait for event 2 or 4 (2-+4=6) for no more
than 1 second No events are notified by
another job so the wait is terminated after
one second and evt is set to 0}

vi. PRINT evt

{Prints 0}

vii. PRINT WAIT_EVENT (3,0)

{Test for event 1 or2 without waiting}

WDIR

WSTAT
directory devices

WDIR will obtain and display in the window attached to the specified or default channel the directory of the device using wild card names (Add WDIR to DIR)

WSTAT will obtain and display in the window attached to the specified or default channel the directory of the device together with file size and
update date. Using wild card
names

syntax:

WDIR [# channel,] name

{list of files}

WSTAT [# channel,] name

{list of files and their Statistics}

example: i. WDIR
list current directory to #1

ii. WDIR #channel
list current directory to #channel

iii. WDIR \par
list current directory to the parallel port

iv. WDIR win1_data_
list directory “win1_data_” to #1

v. WSTAT #4, flp2_
list directory statistics of flp2_ to channel 4

vi. WDIR \name1, name2 list directory 'name2' to 'name1'

vii. WDIR \ser, _asm
list all _asm files in current directory to SER

viii. WSTAT flp1_
list all file statistics on FLP1_ in window #1

ix. WDIR #3
list all files in current directory to channel #3

WHEN ERROR

END WHEN
error handling

Error handling is invoked by a WHEN ERROR clause. Unlike procedure and function
definitions, these clauses are static. The error handling within a WHEN ERROR clause is
set up when the clause is executed, but is only actioned WHEN an ERROR occurs. This means that a program may have more than one WHEN ERROR clause. As each one is

148
executed, the error processing within that clause replaces the previously defined error
processing.

The clause is opened with a WHEN ERROR statement, and closed with an END WHEN
statement. Within the clause there may be any normal type of statement. (Although it might
be better to avoid calling SBASIC functions or procedures!) A WHEN ERROR clause is
exited by a STOP, CONTINUE, RETRY, RUN, LOAD or LRUN command. Furthermore RUN, NEW, CLEAR, LOAD, LRUN, MERGE and MRUN will reset the error processing.

syntax:

WHEN ERROR

There are some additional facilities intended for use within WHEN ERROR clauses.

ERROR functions

These functions correspond to each of the system error codes

ERR_NC

Not Complete,

ERR_NJ

Invalid Job,

ERR_OM

Out of Memory,

ERR_OR

Out of Range,

ERR_BO

Buffer Full,

ERR_NO

Channel not Open,

ERR_NF

Not Found,

ERR_EX

Already Exists,

ERR_IU

In Use,

ERR_EF

End of File,

ERR_DF

Drive Full,

ERR_BN

Bad Name,

ERR_TE

Transmit Error,

ERR_FF

Format Failed,

ERR_BP

Bad Parameter,

ERR_FE

Bad or Changed

Medium,

ERR_XP

Error in Expression,

ERR_OV

Overflow,

ERR_NI

Not Implemented,

ERR_RO

Read Only,

ERR_BL

Bad line

and return the value TRUE if the error, which caused the WHEN ERROR clause to be
invoked, is of that type.

example: 10 WHEN ERROR

20 IF ERR_BP THEN PRINT “Bad Parameter error”

30 IF ERR_OV THEN PRINT “An Overflow has occurred”

40 IF ERR_NO THEN PRINT “Channel is not open”

50 END WHEN

WIDTH
devices

WIDTH allows the default width for non-console based devices to be specified, for example printers.

149
syntax:

line_width:= numeric_expression

WIDTH [ channel,] line_width

example: i. WIDTH 80

{set the device width to 80}

ii. WIDTH #6,72

{set the width of the device attached to channel 6 to 72}

WINDOW
windows

Allows the user to change the position and size of the window attached to the specified or default channel. Any borders are removed when the window is redefined.

Coordinates are specified using the pixel system relative to the screen origin.

syntax:

width:= numeric_expression

depth:= numeric_expression
x:= numeric_expression
y:= numeric_expression

WINDOW [ channel,] width, depth, x, y

example: WINDOW 30, 40, 10, 10

{window 30x40 pixels at 10,10}

WIN_DRIVE

WIN_DRIVE$

WIN_DRIVE allows you define the DOS path and filename for the WIN directory devices.

WIN_DRIVE$ is a function to return the currently defined DOS path and filename of WIN
directory devices.

syntax:

WIN_DRIVE drive_number, filename

WIN_DRIVE$ ( drive_number)

example: i. WIN_DRIVE 2,"D:\QPC.WIN"

{WIN2_ is assigned to the WIN file

QPC.WIN}

ii. PRINT WIN_DRIVE$(2)

{will tell you the current filename}

WIN_FORMAT

Before you can issue the FORMAT command for a WIN device, you have to allow the
drive to be formatted. SMSQ/E has a two-level protection scheme, to make sure you (or

150
somebody else) cannot format your hard disk accidentally. All drives are protected by
default, so you have to declare them to be formattable before you issue the FORMAT
command.

FORMAT will fail if there is not sufficient space left on the specified drive, if the medium is write-protected, or if the file *.WIN already exists and contains invalid information (e.g. a

DOS-subdirectory).

syntax:

switch := 0 | 1

WIN_FORMAT drive [ , switch ]

example: WIN_FORMAT 1

{Allow WIN1_ to be formatted}

FORMAT WIN1_10

{Create a 10 Megabyte WIN device on… you have
to echo the two characters displayed ...

WIN_FORMAT 1,0

{protect WIN1_ again against unwanted
formatting}

WIN_REMV

WIN_REMV allows support for removable drives, like ZIP or SyQuest. It allows you to
declare a WIN device to be removable.

When a drive is declared removable the .WIN file is closed after all SMSQ files on it are
closed. This can also be used to share a single .WIN file over a network (files on a remote
computer are automatically set to removable). Just as long as one QPC instance has any
open files on the drive, all others cannot access it.

syntax:

switch := 0 | 1

WIN_REMV drive_number, switch

example: i. WIN_REMV 2

{declares WIN2_ to be a removable}

ii. WIN_REMV 2,1

{does the same to WIN2_}

iii. WIN_REMV 2,0

{declares WIN2_ is not a removable}

WIN_SLUG

WIN_START

WIN_STOP

No information available on these commands.

151

WIN_USE
directory devices

WIN_USE allows renaming of the WIN device. WIN_USE without a parameter will reset the name of WIN back to WIN.

syntax:

WIN_USE [ name ]

example: i. WIN _USE dos : LOAD dos2_prog

{loads 'prog' from WIN2_ }

ii. WIN _USE

{and now its name is WIN again}

iii. WIN_USE ram : DIR ram1_

{displays directory of WIN1_}

WIN_WP

No information available on this command.

WMON

WTV
windows

There are two commands for resetting the windows to the turn-on state.

WMON will reset the windows #0, #1, and #2 into ‘Monitor’ mode.

WTV will reset the windows #0, #1, and #2 into ‘TV’ mode.

A border has been added to window #0 to make it clearer where an SBASIC Job is on the
screen.

Only the window sizes, positions and borders are reset by these commands, the paper
strip and ink colours remain unchanged.

If you have a screen larger than 512x256 pixels, it is useful to be able to re-position the

SBASIC windows. The WMON and WTV commands may take an extra pair of parameters:

the pixel position of the top left hand comer of the windows. If only one extra parameter is
given, this is taken to be both the x and y pixel positions.

If the mode is omitted, the mode is not changed, and, if possible, the contents are
preserved and the outline (if defined) is moved.

syntax:

mode := numeric_expression

xpos := numeric_expression

ypos := numeric_expression

152

WMON mode [ , xpos, ypos ]

WTV mode [ , xpos, ypos ]

example: i. WMON 4,50

{reset windows to standard monitor layout displaced 50
pixels to the right and 50 pixels down}

ii. WMON ,80,40 {reset windows to standard monitor layout displaced 80
pixels to the right and 40 pixels down, preserving the
contents}

153

Table of Contents

- BLOCK ........................ 15
- CHR$ .......................... 23
- BORDER ..................... 16
- CIRCLE ....................... 24
- ABS ............................... 7
- CALL ........................... 17
- CKEYOFF ................... 25
- ALARM .......................... 8
- CD_FIRSTTRACK ....... 18
- CLOCK ........................ 26
- CLS ............................. 27
- AJOB ............................. 9
- AT ................................ 10
- CD_INIT ...................... 19
- BAUD........................... 11
- CONTINUE ................. 28
- BEEPING ..................... 12
- COPY .......................... 29
- BGCOLOUR_QL ......... 13
- CD_PLAY .................... 20
- COS ............................ 32
- CD_TRACKLENGTH .. 21
- CSIZE ......................... 33
- BGIMAGE .................... 14
- CHAR_INC .................. 22
- CURSOR .................... 34
- DATA .......................... 35
- DISP_BLANK .............. 47
- ET ............................... 57
- DATA$ ......................... 36
- DISP_COLOUR ........... 48
- EXEP .......................... 59
- EXP ............................. 60
- DATE$ ......................... 37
- DISP_TYPE................. 49
- FDEC$ ........................ 61
- DAY$ ........................... 38
- DLIST .......................... 50
- FILL ............................. 62
- DEFine......................... 39
- FLEN ........................... 63
- DEFine......................... 40
- DEG ............................. 41
- DELETE....................... 42
- DO ............................... 51
- DOS_USE ................... 52
- FLP_DENSITY ............ 64
- DEST_USE .................. 43
- EOF ............................. 55
- DEV_LIST .................... 44