BETA BASIC 3.0 The full 48K code of this comprehensive Spectrum BASIC extension package is included with SPECULATOR by kind permission of the author, Dr. Andy Wright. BETA BASIC massively extends ZX BASIC to support structured programming, graphics scaling, much better editing, print formatting and debugging. It also speeds up the interpreter, especially at loops and trigonometry. It is worth using for the editing improvements alone, even if you do not use the new BASIC commands and functions. These notes are by former Crash Technical Editor Simon N Goodwin. The printed manual for BETA BASIC 3 runs to almost 100 detailed pages, and this is only the briefest summary, but it should help you get started, in conjunction with the example routines in the BETABASIC3 snapshot file. You can get the full package on disk or tape from BETASOFT, as noted later. BETA BASIC EDITING You can type keywords as normal, or spell words out in full by pressing a space, then typing the letters. The keyword EDIT calls up a given line; press 0 to get EDIT at the start of a new command line, then the number of the line you want. There's no need to LIST and BREAK. LIST lineA TO lineB lists a range of lines. You can now move the cursor up and down inside the line while editing. Up arrow jumps quickly to the end. EDIT can also be used within a program to edit variable values, so that EDIT ;n prints the value on N and allows editing and re-entry. The semicolon is needed to distinguish N from a line number. EDIT a$ works as expected. LIST lineA TO lineB lists a range of lines. You can now move the cursor up and down inside the line while editing. LIST FORMAT 1 or 2 gives formatted listing of single-statement lines with indentation of one or two spaces per structure. LIST FORMAT 0 is fastest for program editing. Type <> (Symbol Shift W) to split a line while editing. JOIN joins lines. DEF KEY lets you assign up to 36 user-defined strings or lines to keys: DEF KEY "1";"PRINT 65536-USR 7962" DEF KEY "x":PRINT "Copyright 1994": End the command with a colon to have the string automatically entered. The first string must be a single character letter or digit. Capitals and lower case are equivalent. Press Symbol Shift SPACE, then the character, to use the DEF KEY. LIST DEF KEY shows all current settings, stored above RAMTOP. KEYIN allows programs to type new lines into a program: KEYIN "100 DATA 0" You can use this to write self-modifying BASIC. Frankenstein here we come! RENUM renumber sall or a section of a program. Add * after a RENUM to copy (not move) a block of lines: RENUM * start TO end LINE new_start STEP step. Screen memory is temporarily used for the line tables as RENUM takes place. AUTO start,step gives automatic line numbers with a specified or default start and step. DELETE start TO end lets you delete a range of lines. DELETE can also be used to discard part (a slice) of a string or array. ALTER will search and replace inside your program. ALTER a$ TO b$ replaces the string variable name A$ with B$ wherever it is found. ALTER 42 to 21 does the same for numeric constants. ALTER "demo" TO "" removes the string "demo" wherever it is found in the program text. LIST VAL, LIST VAL$ and LIST DATA show the values of numeric, string or all variables in your program. LIST REF "item" prints the number of lines where "item" - be it string, number or variable - is found. REF is similar but calls up the editor for each matching line, in turn; press ENTER to go on. ENHANCED GRAPHICS BetaBASIC allows all graphics to be scaled and moved in accordance with the values of four BASIC variables - XOS and YOS, which set the origin, and XRG and YRG which set the X and Y range; the defaults are 0,0, 256 and 176. Alter these to scale graphics up or down or shift them around the screen. WINDOW lets you confine graphics and text to any one of up to 127 areas of the screen, or 'windows'. WINDOW ERASE gets rids of all WINDOW settings. WINDOW 1,128,16,128,160 defines window 1 between text lines 2 and 17 of the right-hand half of the screen. WINDOW 1 makes this the current window. The full-size default is WINDOW 0. CSIZE, INK, PAPER etc are stored separately for each window. CLS 1 clears window 1 and CLS 0 clears the whole screen. DRAW TO draws lines or curves to a specified point. ROLL and SCROLL can move all or part of the screen in any direction; try LIST:ROLL 5,8 or SCROLL 10. PLOT x,y;text$ allows TEXT$ characters to be printed at any pixel position. GET x$,x,y reads a character square from the screen into a string. To read more than one square at a time, add the sizes after X and Y, in units of 8 pixels (1 character). This reads a 16x22 character area: GET a$,0,0,16,22. Examples of GET are in the full manual and your BetaBASIC snapshot file. CSIZE allows any character size from 3 to 256 pixels in width. CSIZE 4,8 gives a Tasword-style 64 column display; CSIZE 6,8 gives 42 columns, 8,8 is the default, and 16,16 (or just CSIZE 16) gives double size. CSIZE will work as a local parameter of PRINT or PLOT: PLOT CSIZE 32;x,y;"HI". Big text can make editing difficult - press BREAK and select CSIZE 8, then continue. FILL x,y fills an area of PAPER with the current INK colour, or vice versa if you FILL PAPER p;x,y. The function FILLED counts the pixels FILL filled. OVER 2 is like OVER 1, but uses OR instead of XOR to mix graphics with the background. OVER 2 may be used anywhere that OVER is normally allowed. ALTER can be used to search and replace graphics attributes. For instance try ALTER INK 7 TO INK 4 or ALTER TO PAPER 2;FLASH 1 (for the whole screen). STRUCTURED PROGRAMMING BETA BASIC supports named procedures with parameters, LOCAL variables, and recursion. LIST PROC name displays the named procedure. DEFAULT gives a value to a parameter that was not set by the caller. Parameters are passed by value unless the name is preceeded by REF in the DEF PROC header: DEF PROC swap REF A$,REF B$ LOCAL T$ LET T$=A$,A$=B$,B$=T$ END PROC Notice how Beta BASIC allows several LETs to be combined! The local variable T$ is discarded when the PROC is finished, and the variable parameters A$ and B$ are passed out to the calling program. If REF is missing, parameters are passed by value, inwards but not out. If the name in DEF PROC is followed by DATA, any number of parameters are allowed and the procedure can process them one by one with READ! The ITEM() function returns the type of the next item; 0=none, 1=string, 2=numeric. ELSE can now be used after IF..THEN; it may be nested but must fit one line. To save lots of IFs, ON can select a statement or line for continuation: GO TO ON NUM;100,200,250,300 This continues at 100 if EXP=1, 200 if EXP=2, and so on. You may use GO SUB instead of GO TO, or a list of statements where NUM determines which runs: ON NUM:PRINT "One":PRINT "Two" : :PRINT "Four" ON ERROR may be followed by the line number of an error-handling subroutine or statements to be executed in the event of an error. The variables LINO STAT and ERROR record the line, statement and error code that was trapped. Code between DO and LOOP executes repeatedly. DO and LOOP may be followed by conditions, e.g. DO WHILE busy or LOOP UNTIL done, etc. You may exit from the middle of a DO..LOOP structure with the EXIT IF condition statement. NEW INTEGER FUNCTIONS The following functions work on unsigned integers in the range 0 to 65535: DPEEK reads two bytes as a word, least significant first (in Z80 order), so DPEEK x is the equivalent of PEEK x+PEEK(x+1)*256. DPOKE stores a word. X may be odd or even as the Z80 does not impose word alignment. HEX$, DEC and BIN$ convert numbers in hexadecimal or binary string notation: thus PRINT HEX$(260),BIN$(110) displays 0104 and 001101110; DEC(HEX$(x))=x. AND(a,b) returns the result of bitwise AND between A and B: PRINT AND(30,13) gives 12 (11110 AND 01101 = 01100). Likewise OR() and XOR() do the same for 16 bit OR and Exclusive OR functions. PRINT MEM() shows the amount of memory available to ZX/Beta BASIC. You have about 22K left for Beta BASIC programs/data on a 48K Spectrum or emulator. CHAR$(w) packs a value in W into a 2 byte string. NUMBER(w$) converts back. LENGTH works like VARPTR in other BASICs. LENGTH(0,"x$") returns the address of the first element of X$. LENGTH(1,"X$") returns the first DIM subscript, LENGTH(2,X$) the second - the length of each element in an array of strings or the width of a 2 dimensional numeric array. MOD(a,b) returns the remainder after dividing A by B. These functions use ZX BASIC DEF FNs, hidden in line 0 at the start of the program, to call their code. You can still use these names for your own DEF FN routines: A$, B, D$, E$, F$, G, G$, H, I$, J, J$, K, L$, N$, O$, P, P$, Q, Q$, R$, V$, W, W$, X, X$, Y, Y$. Other FN names are reserved. RNDM(N) returns a random integer (whole number) between 0 and N inclusive. FAST FLOATING POINT FUNCTIONS RNDM(0) is exactly like RND in ZX BASIC, but two or three times faster. COSE(X) and SINE(x) are speedy versions of the ZX COS and SIN functions, about six times quicker and usually accurate to four decimal places. ARRAY AND STRING FUNCTIONS INSTRING(start,a$,b$) returns the position of B$ in A$, starting at START. The character # is a wild-card that matches every possible character. INARRAY(string_array$,x$) looks for X$ in STRING_ARRAY$, which may have a slicer so that only part of the array or part of each element is searched. It returns zero or the array index number of the first string containing X$. JOIN and COPY can be used to extend strings and arrays; The difference between JOIN A$ TO B$ and COPY A$ TO B$ is that A$ is deleted after JOIN. MEMORY$() is a string function that can access any memory address from 1 to 65532, so LET a$=MEMORY$()(16384 TO 22527) reads the entire ZX screen RAM into a string. POKE now supports string as well as numbers, so you can restore the display afterwards with POKE 16384,a$. STRING$(n,x$) gives N repeats of X$. SHIFT$(n,k$) can change case, spell out keywords or suppress non-ASCII codes in K$, depending on the value of N. For example SHIFT$(1,"Speculator") gives "SPECULATOR", SHIFT$(2,"ZX")="zx". SCRN$ is an improved SCREEN$ that can recognise user-defined graphics as well as normal characters. It is limited to normal CSIZE 8,8 characters. TIME$ returns the time from the Spectrum's clock. This will tick slowly unless the interrupt rate is set to 50 Hertz, the same as a real Spectrum. At this rate, a slow computer may not have enough time to do anything else! CLOCK 1 turns on an interrupt-driven clock. CLOCK "10:25:00" sets the time to 10.25 am. CLOCK "a11:59" sets an alarm for 11.59 am. CLOCK 3 gives the display and an audible alarm; higher parameters can call a BASIC routine automatically when the alarm time is reached. THE FULL VERSION This is a summary, and incomplete there are quite a few other commands and functions in Beta BASIC 3, and lots more in later versions for bigger RAM. You can obtain the full printed manual for Beta BASIC 3, code for expanded Spectrum systems, and BETA BASIC 4, the upgrade for 128K Spectrums, from the publishers BETASOFT at 24 Wyche Avenue, Kings Heath, Birmingham B14 6LQ, UK. BETASOFT can also supply Master BASIC, a similar expansion package for the 'super-Spectrum' SAM computer, and back issues of the Beta BASIC newsletter, packed with example programs and background information about Beta BASIC. We thank BETASOFT and Doctor Andy for letting us share this great utility. Simon N Goodwin, July 1994.