You can now run the computer language used in schools throughout the land on your 464 with discs, 6128, PCW or PC. Richard Sargent looks at whether you'd want to.
When the BBC decided to launch a computer literacy project a team of experts was put together to decide what was needed. They wanted a Comal-like language, Z80 CPU, Teletext, CP/M, and Sin discs. The target price was £100. The BBC Micro ended up being nothing like the machine they wanted, and Sir Clive, who could have done the job, was suitably miffed. Still every cloud has a silver lining and now the world is richer to the tune of a new Basic - BBC Basic.
Owners of disc-based Amstrads have a good choice of Basics for their program development now that BBC Basic is available for all Amstrads running CP/M 2.2 or CP/M +. For CPC users it is of course Locomotive Basic which takes pride of place in their machine, but some may have abandoned Locomotive, perhaps only temporarily, in favour of Mallard Basic or MBasic, both of which are available for these computers on 3in disc running under CP/M.
Now the chance to sample the language which launched the BBC's Computer Literacy Project is open to most Amstrad users - and at £29 for the privilege there are likely to be a lot of takers.
BBC Basic is undoubtedly one of the superior variants. It supports procedures, so it's more structured than Locomotive, and it has good file-handling commands, including the ability to support random access files. These attributes make it suitable for use in schools and businesses.
Further, it has a generous range of mathematical functions and a built-in assembler, which makes it a Basic which can hold its own against other more specialised languages and has found favour at higher education levels too.
So, how has BBC Basic found its way on to Amstrads? The brief answer is that Acorn don't own the language, and that the BBC always intended that it should be widely available.
The reason why there aren't a vast number of non-Acorn computers running BBC Basic is that it requires a fair amount of programming skill to write a BBC Basic interpreter, the end result has to be good (who would want an inferior version?), and the BBC has to approve it (they set the original specification, and can veto nonstandard versions).
Having said that much, it is almost a foregone conclusion that BBC Basic for the Amstrad, written by software house M-TEC, is good, because Auntie has officially approved it.
The preview disc under review here unfortunately had no manual because they were still at the printers, but the whole bag of tricks will be available by the time you read this. The testing was done on a CPC 6128 which has CP/M +, but the disc will also run under the CP/M 2.2 of an upgraded CPC464. Armed with the Help file from the disc (which lists all the BBC Basic commands) and a real BBC Basic manual (as supplied with the genuine BBC computer) I put my Amstrad in BBC mode . . .
Ix>ading BBC Basic is simple. First select CP/M using the Amstrad's CP/M system disc, and then load the 17k file BBC Basic.COM. You are now running BBC Basic. Later you can put CP/M and BBC Basic on the same disc, together with some goodies to make it simple to get into BBC Basic as soon as you switch on your computer.
Once in BBC Basic, tread carefully -the finer details which make the language a pleasure to use represent stumbling blocks for unwary Locomotive freaks. Dir will give you a CATalogue, but will only list programs with .BBC extensions. There are plenty of these, so you could start by loading the benchmark timing program contained on the demo disc. This will tell you how fast BBC Basic runs. CHAIN "bench" does the trick. If you type chain "bench" you will be told, politely, that you are WRONG. BBC Basic likes its commands in upper case please. *dir was a disc-based command, not a true BBC Basic command, so there is no need for it to be in capitals while "bench" is a file name and so also doesn't require upper case treatment -you'll get to know and love these foibles.
BBC Basic accepts abbreviated keywords too, so CH."bench" will run the official benchmark programs, and report that BBC Basic scores 19 seconds - about 7 seconds slower than the real BBC Basic and 5 seconds slower than Locomotive Basic.
Although BBC Basic is loaded from disc, and therefore occupies about 17k of RAM, there is plenty of free space left for user programs, particularly on the CPC 6128. On this machine Locomotive Basic's FRE(O) returns around 41000 bytes. The BBC Basic equivalent command is HIMEM-PAGE which returns 40448. Moreover, opening a channel doesn't reduce this figure, whereas it does eat into Loco's 41000 by about 4k
Listing I: Creates DISC.BAS which is the CPC's auto run file
10 PRINT 'Press CAPS-LOCK, then '8' or '4' for 80/40 cols"
20 IF GET$='4' THEN MODE 1:NEW
Listing II: Creates the screen-choice file M.BBC
10 X=OPENOUT 'PROFILE.SUB'
20 PRINT #X,'PALETTE 59,0'
25 PRINT #X,'SETKEYS KEYS.BBB'
30 PRINT #X,'BBC Basic N.BBC"
40 CLOSE #X
50 X=OPENOUT 'KEYS.BBB'
60 PRINT #X,'15 N S C ';CHR$(34);CHR$(126);CHR$(34)
70 CLOSE #X
80 REM This progran has now done its task
90 REM and can be discarded.
Listing III: Creates the initialisation files PROFILE.SUB and KEYS.BBB
BBC Basic is here benefiting from CP'M +, which makes the most of the CPC 6128's paged memory. On CP/M 2 2 Amstrads there is less space for user programs under BBC Basic, but Locomotive Basic's situation remains the same
With this generous amount of memory at your disposal, spare a thought for BBC Model B owners - in graphics mode they have 4352 bytes free and in 80 column text mode 8448 bytes. The original Acorn design - the Proton which begat the BBC Micro had a 2k character mode. The BBC wanted teletext instead.
The BBC Basic commands are shown in Table I Structured programming commands are represented by Procedures 'DEF PROCname) and by the useful ON . GOSUB . . . ELSE (Amstrad's ON . GOSUB doesn't support the ELSE). Locomotive's WHILE . WEND is missing but is replaced by REPEAT . .UNTIL. BBC Basic is wnrth buying just for the procedure calls alone, but there are more goodies lurking in the interpreter, not least of which is the in-line Z80 assembler
Table II shows the impressive list of functions, and you will note that maths functions feature largely.
"Indirection" is the process which is provided by PEEK and POKE in most dialects of Basic, including the Amstrad Basics BBC Basic has three indirection operators, the query (?) which performs PEEKs and POKEs, the pling (!) which does the same as POKE but transfers four bytes at a time, and the dollar ($) which transfers strings to memory. The latter may affect as many as 255 bytes, which is the maximum string size permitted. For example:
Y=PEEK(X) is equivalent to Y=?X
POKE X,Y is equivalent to ?X-Y
!M=& 12345678 would load &78 into address M, &56 into address M +1, &34 into address M+2 and &12 into address M + 3.
$M="ABCDEF" will place the Ascii characters A to F in locations M to M+5 and will load a carriage return (&0D) into address M+6.
Query and pling can also be used as binary operators so that, for example, M?3 means "the contents of memory location M+3". The left hand operand must be a variable, not a constant.
M is auto-incremented by the indirection operators, so a memory-investigation program can be performed in just a few lines. Here is a one-liner to examine 32 bytes of memory from address M onwards:
FOR X=0 TO 31:PRINT ^N+X, ^M?X:NEXT
The tilde " performs the same task as Locomotive Basic's HEX$ but suffers the disadvantage of not being on the Amstrad keyboard. Use CP/M's SETKEYS command file to program function key f0 to produce the tilde, ASCII code 126.
BBC Basic includes a Z80 assembler which loads its object code directly into the target memory area; the static variable P% is the program counter. The usual two-pass assembly is done by placing the source code in a FOR. . . NEXT loop.
All Z80 op-codes are supported, together with pseudo-ops DEFB, DEFW and DEFM; these write an 8 bit byte, a 16-bit word and a multicharacter string respectively. Error reporting and listing are controlled by the pseudo-op OPT.
All is explained in the manual, and there are even examples of in-line assembly on the demonstration side of the BBC Basic disc.
The USR function and the CALL statement provide the interface between Basic and machine code. Both USR and CALL communicate with the Z80's registers via reserved variables of the same name - so register A is loaded from Basic variable A%, B from B% and so on. Lists of parameters may also be passed in a way which is reasonably similar to that used by Locomotive's CALL statement.
- AUTO Generate line numbers.
- DELETE Delete program lines.
- EDIT Edit a program line.
- LIST List all or part of program.
- LISTO Control indentation in LIST.
- LOAD Load a program into memory.
- NEW Delete current program & variables.
- OLD Recover a program deleted by NEW.
- RENUMBER Renumber the program lines.
- SAVE Save the current program to disk.
- CALL Call assembly language routine.
- CHAIN Load and run a program.
- CLEAR Clear dynamic variables.
- CLS Clear the screen.
- DEF Define a function.
- DEF PROC Define a procedure.
- DIM Dimension one or more arrays.
- END Terminate program and close files.
- ENDPROC Return from a procedure.
- FOR Begin a FOR . . . NEXT loop.
- GOSUB Call a Basic subroutine.
- GOTO Branch to specified line.
- IF..THEN Do statement(s) if exp non-zero.
- LET Assignment.
- LOCAL Declare variables local to procedure.
- NEXT End FOR . . . NEXT loop.
- ON..GOTO Computed GOTO.
- ON..GOSUB Computed GOSUB.
- ON ERROR Do statements) on error.
- PROC Call a procedure.
- REM Remark
- REPEAT Begin a REPEAT . . . UNTIL loop.
- REPORT Print error message for last error.
- RESTORE Reset data pointer.
- RETURN Return from subroutine.
- RUN Run the current program.
- STOP Stop program and print message.
- TRACE ON Start trace mode.
- TRACE OFF End trace mode.
- UNTIL Terminate loop if exp is non-zero.
- WIDTH Set terminal width.
- BPUT Write LS byte of exp to disk file.
- CLOSE Close disc file.
- DATA Data for READ statement.
- INPUT Request input from user.
- INPUT LINE As INPUT but accept whole line.
- INPUT# Read data from disk file.
- OSCLI Pass string to "operating system".
- PRINT Print data to console.
- PRINT# Write data to disc file.
- READ Read data from DATA statements).
- VDU Send LS byte of exp to console.
Table I: Commands
Converting any dialect of Basic to any other is never a five minute job and any Basic listing containing PEEKs, POKEs and machine code CALLs is probably not worth converting - life is too short. However, straightforward programs in BBC Basic/Locomotive Basic can be translated by paper and pencil method, or, more ambitiously, by performing surgery on the listing after loading it into a word processor. (Both BBC Basic and Locomotive Basic can produce the pure Ascii text files required by a word processor).
Expect to interchange commands such as VDU X and CHR$(X); LOCATE X,Y and TAB(X,Y) and so on, and be prepared to change parameters following commands such as RND and SOUND. Having both the BBC Basic and the Locomotive Basic manuals open on the desk at this time is virtually compulsory! Dedicated converters wiil probably want to consult the "real" BBC Basic handbook too.
100 REM Update a record in a file cal led 'phones'
110 R=203 : REN record number
120 L=40: : REM length of record
130 N=123456 :: REM sone new numeric data
140 N$='Brentwood': REM some new string data
150 file=OPEMOUT ("phones")
170 PRINT #file,N ,N$
180 CLOSE #file
Listing IV: An example of BBC Basic's random access filing
Tests made in transferring programs between BBC Basic, Locomotive Basic and the Protext word processor proved to be perfect in the BBC Basic to Locomotive/Protext direction and satis-factory in the reverse direction. Locomotive Basic and Protext users will already know how to read and write pure Ascii files, but it is at the BBC Basic end that a slight hiccup exists. BBC Basic uses the cumbersome but reliable *SPOOL sequence to create an Ascii file, for example:
- SPOOL Give the Ascii file a "myprog.asc" name
LIST LIST the Basic program to the disc
- SPOOL Terminate the disc operation
and myprog.asc can be read by Locomotive Basic and Protext. However, to load an Ascii file into BBC Basic requires the • EXEC command: *EXEC amstrad.asc
Function / Action
- ABS(exp) Absolute value of expression.
- ACS(exp) Arc-cosine of expression, in radians.
- ASN(exp) Arc-sine of expression, in radians.
- ATN(exp) Arc-tangent of expression, in radians.
- COS(exp) Cosine of radian expression.
- DEG(exp) Value in degrees of radian expression.
- EXP(exp) e raised to the power of expression.
- INT(exp) Largest integer less than expression.
- LN(exp) Natural logarithm of expression.
- LOG(exp) Base-ten logarithm of expression.
- PI Returns 3.14159265.
- RAD(exp) Radian value of expression in degrees.
- RND[(exp)l RND returns random 32-bit integer.
- RND(-n) Seeds sequence.
- RND(0) Repeats last value in RND(1) form.
- RND(1) Returns number between 0 and 0.999999999
- RND(n) Returns random integer between 1 and n.
- SGN(exp) 1 if exp>0, 0 if exp=0, -1 if exp<0.
- SIN(exp) Sine of radian expression.
- SQR(exp) Square root of expression.
- TAN(exp) Tangent of radian expression.
- ASC(str) Returns ASCII value of first char of string.
- CHR$(exp) Returns one-char ASCII string of exp.
- EVAL(str) Evaluates str as an expression and returns resulting number or string.
- GET Waits for keypress and returns ASCII value.
- GET$ Waits for keypress and returns one-char string.
- INKEY(exp) Waits exp centiseconds for keypress and returns Ascii value.
- INKEY$(exp) Waits exp centiseconds for keypress and returns one-character string.
- INSTR(r,s(,nl) Returns position of string s in string r, optionally starting at position n.
- LEFT$(str,exp) Returns leftmost exp characters of string.
- LEN(str) Returns length of string (0-255).
- MID$(str,m[,n]) Returns sub-string from position m, of length n or to end.
- RIGHT$(str,exp) Returns rightmost exp characters of string.
- STR$(exp) Returns string representation of exp in decimal (or hex).
- STRING$(n,str) Returns a string consisting of n copies of str.
- VAL(str) Returns numeric value of str.
- BGET#chan Returns a single byte from a disc file.
- COUNT Number of characters printed since last new line.
- EOF#chan Returns TRUE if disc file is at its end.
- ERL Line number of last error.
- ERR Code of last error.
- EXT#chan Returns virtual length of disk file.
- FALSE Returns zero.
- FNname User-defined numeric or string [(parameter list)] function.
- GET(port) Returns contents of Z80 port.
- OPENIN(str) Opens file for input/update and returns channel number.
- OPENOUT(str) Opens file for output and returns channel number.
- OPENUP(str) Same as OPENIN.
- POS Returns current cursor column (LHS=0).
- TOP Returns first address after end of user's program.
- TRUE Returns-1.
- USR(address) Calls machine-code routine and returns integer.
- VPOS Returns current cursor line (top line=0).
- PAGE Memory address of current user's program.
- PTR#chan File character pointer. Allows random access.
- HIMEM Top of memory used by Basic.
- LOMEM Start address of dynamic variable storage.
- TIME Elapsed time clock, counts in
Table II: Fonctions
***Note: This listing is not referred to in the text
AN EXAMPLE OF BBC Basic's IN-LINE ASS EMBLER (Listing 5)
100 DIM mcroutine 30 ; reserve space for mcroutine
110 FOR pass=0 TO 1 ; standard 2-pass assembly
120 P%=mcroutine ; set P% to start of mcroutines area
130 [OPT pass*2 ; OPT=0 on 1st pass; =2 on 2nd pass
140 LD A,(IX):DEC A:JP NZ,label ; some code & a branch
150 RET ; is one end of the routine
160 .label ; branch destination
170 ADD A,8:RET:] ; nore code & an other RET end
180 NEXT pass ; 3 ended the source code
190 CALL mcroutine ; Call the nachine code routine
Listing V: An example of BBC Basic's in-line assembler
This was duly tried, and 99 percent of amstrad.asc loaded into BBC Basic one spurious line number crept in the last second of transfer and had to be removed manually.
What is happening is that BBC Basic's *EXEC is reading the disc up to the physical end-of-file, which is at the end of the sector. Locomotive Basic ends its files with Control-Z and leaves any space between the Control-Z and the end of the sector holding junk bytes from previous disc use.
BBC Basic cannot help but read this junk which it might occasionally read as a spurious program line. Use clean disc to avoid this problem. It is at least reassuring that software transfer between the two languages is possible on the Amstrad computers.
The Amstrad CPC manual will tell you how to create a blank CP/M-format disc and how to PIP the files BBC Basic.COM, AMSDOS.COM, PALETTE.COM, SETKEYS.COM, SUBMIT.COM, KEYS.CCP and C10CP/M3.EMS onto it. (Note that C10CP/M3.EMS may be called something else on Amstrads other than the CPC 6128).
Listings one and two, given in this article, will allow you to put three files called M.BBC, PROFILE.SUB and KEYS.BBB on to the same disc, and these will let you start up BBC Basic very simply when you first switch on your computer, as well as providing the tilde character on key f0).
M-TEC can't do all the work for you since they cannot supply BBC Basic on a 3in CP/M disc for copyright reasons.
It is impossible to fault the implementation of BBC Basic on the Amstrad. It's fast and has tons of memory. Don't expect masses of software to be written specifically for it though - its a language which you either use from scratch or else do the converting from Beeb-type BBC Basic yourself.
More features could only be introduced by increasing the size of the interpreter - thus leaving less room for programs - and at the expense of slowing it down (due to the time-wasting routines which would need to be included to force the Amstrad to perform all the twiddly bits which the Beeb can manage).
Even if you choose not to use the "Basic" part of BBC Basic very often, you still have the Z80 in-line assembler which can be used to explore the MOS (machine operating system) at the heart of CP/M. However, most people warm to BBC Basic in its own right, and it's probably the best Basic you can have sitting above that unfriendly