(from Your Spectrum 7, Sep.1984)



BASIC AT A STRETCH



Tired of using the same old commands? Well, saddle up your Interface 1

unit and let Gavin Smyth demonstrate the practice at adding up to 26

new commands to your Spectrum.





Sinclair Basic, for all its slowness, is fairly comprehensive. But as

with all things, the more you have, the more you want and a few extra

commands might certainly come in useful. How about, for instance, an

absolute draw. With Interface 1 attached, it's possible to add as many

extra commands as you like.



First, let's look at the extended interpreter and the individual

routines in detail.





NEW INTERPRETATIONS



When a line of Basic is entered, the original ROM checks its syntax;

if it fails to recognise the command, it passes control over to the

Interface 1 ROM. This scans the line checking for new words such as

'FORMAT'. If this test also fails, the processor jumps to the error

handling routine (at ERR6) via the vectored address at 23735. You can

alter this address and have further tests implemented to provide extra

commands.



This is what the extended interpreter does. It checks for the presence

of an asterisk at the beginning of a statement followed by a letter;

with this simple test, however, only 26 new commands can be invented.

If it finds no asterisk or letter it gives the usual syntax error. If

all is correct, it jumps to the actual routine via the table of

vectors. Note that unimplemented commands point to the error handler.

The individual command routines check the rest of the syntax and

contain the runtime routine.



For the interpreter to function properly, there must be at least one

space between the new command word and any following arguments. The

command word must start with an asterisk and a letter, followed by any

(or no) characters at all.





ABSOLUTE DRAW



The first new command is:



*DRAW x,y



Which draws to the point (x,y). It's much simpler to use than relative

co-ordinates (especially in graphs). Thus:



PLOT 100,100: DRAW 20,30



is equivalent to:



PLOT 100,100: *DRAW 120,130



First, the routine calls SPACE to get to the end of the first word (in

this case, *DRAW). Then it checks for the presence of two numeric

arguments separated by a comma; if there's something wrong it jumps to

the error handler. In syntax time - that is, when the line is first

entered into a program - the routine ends here; in runtime the rest is

executed. This part simply calculates the size of the relative

co-ordinates and calls the Basic ROM's DRAW subroutine.



When this subroutine is being executed, the Interface 1 ROM is paged

in. This allows routines in the Interface l's ROM, such as STEND, to

be simply CALLed; routines in the main ROM, such as FNDINT1, have to

be called via RST 10h followed by the starting address (this is true

for all the new command routines).





PRINTING PIXELS



The next routine allows a user-defined graphic character to be placed

anywhere on-screen. The reason for restricting it to UDGs is that it's

unlikely that anyone would want to print a lot of text like this

(since the routine handles only one character at a time) and, if

required, the UDGs may be re-defined as letters.



The syntax for the command is:



*PRINT x,y,c



Where (x,y) are the pixel co-ordinates of the top left corner of the

character (x lies between zero and 255, y between zero and 175) and c

is the number of the UDG (UDG A is zero, UDG B is one ... UDG U is

20). For example:



FOR x=0 TO 247: *PRINT x,100,0: NEXT x



The above will glide the first UDG (initially a capital 'A') across

the screen. This time the extended syntax checker looks for three

numbers separated by commas.



In the runtime routine, the data for the UDG is found and shifted

across to give the correct information for the screen memory; the

listing contains the code and full comments. The routine ends with the

attribute bytes being set to the permanent colours.





PIXEL SCROLL



The scroll command allows pixel scrolling of the entire screen. The

actual command is:



*SCROLL n



Where n is a numeric expression controlling the direction of the

scrolling (n must lie between zero and 255, but only the mod four

value is used):



n=0 (or 4,8,...) scrolls right one pixel

n=1 (or 5,9,...) scrolls up

n=2 scrolls left

n=3 scrolls down



For example, to scroll one whole character down, you could use:



FOR f=1 TO 8: *SCROLL 3: NEXT f



This moves the screen by eight pixel lines. The syntax checker this

time looks for only one numeric argument. Only the lower two bits are

used (giving a range of zero to three) and the routine jumps to each

separate scrolling routine. The left and right scrolls are fairly

simple - they just shift each line of 32 bytes by one bit. The up and

down scrolls are complicated by the layout of the screen memory, but

all they do is move each line into the one above or below, clearing

the final one.



The colour attributes are not affected at all, since they have only

character block and not pixel resolution.





SIMPLE SOUNDS



The final routine is a simple sound effects generator - useful for

games if nothing else. The command syntax is:



*ZAP n



Where n, between zero and two [sic], specifies the type of sound:



n=0 gives an explosion noise

n=1 gives a falling tone

n=2 gives a rising tone



For example:



FOR f=1 TO 100: *ZAP INT(RND*3): NEXT f



The above will give several seconds of 'exciting' sounds (well, more

exciting than BEEP!). The computer again looks for a single argument

and checks its value; if it's out of range, it gives an error,

otherwise it jumps to the specific routine. The rising and falling

tones are produced by short beeps of changing frequencies, while the

explosion is produced by sending 'random' data from the ROM to the

speaker port.





A COMMANDING LEAD



You can check from the assembler listing several important points

about adding new commands:



1. First, the syntax is checked - using EXPT1NM for numeric

expressions and CP "," to check for separating commas. This section

ends with CALL STEND.



2. Next comes the runtime routine and, since the values of the

arguments are on the calculator stack, these can be pulled off into

the A register with FNDINT1.



3. The runtime code ends with a jump to END1.



4. Any subroutine in the Basic ROM must be called via RST 10h. Note

that all registers are preserved while the ROMs are paged.



5. Before the code will run, the vector at 23735 must point to the

beginning, with a jump back to ERR6 at the end to trap genuine syntax

errors.



The code may be entered using either an assembler or the Basic program

provided which will relocate the 559 bytes of machine code anywhere in

memory; it should run on a 16K Spectrum, so long as Interface 1 is

connected.



To use it, set lines 10 and 20 to the desired starting address (for

example, 31000 in a 16K machine and 64700 in a 48K model). Next SAVE

the program in case there is a mistake (which is usually fatal in

machine code). Now, RUN the program and after a few minutes a message

will appear on the screen; the code has been located in memory but

will have no effect since the vector at 23735 has not been altered. To

use the extra commands enter the line in the message - as a single

line rather than two separate POKEs, otherwise the machine may crash.



If NEW is entered the vector is reset; however, the code is still in

memory, so repeat the two POKEs to allow the commands to be used.

We've seen a simple interpreter that will allow up to 26 new commands,

but with only four examples; there are 22 more possible words, so get

working!





ASSEMBLER NOTES



The assembler used was the Artic version which, in fact, is slightly

non-standard. The main differences between it and a standard assembler

are:



EQU is replaced by the '=' sign.



All numbers are in hexadecimal unless preceded by '+' or '-', in which

case they are in decimal.



DEFB, DEFW, and so on do not exist; the number or label is simply

placed in the source text where the DEFB would occur, and EX AF,AF' is

entered as EX AF.







This is the machine code disassembly of a series of extended Basic

routines which expand Sinclair Basic by up to 26 new commands, of the

form '*name'; ie. commencing with an asterisk, followed by a letter

(upper or lower case) or word and any necessary parameters. (Note that

this program only works with Interface 1 attached, and the system

variable vector at 23735 and 23736 should be set to point to START.)



The table of vectors to the specific routines.



This routine provides the command to carry out absolute drawing. It is

used in the form *DRAW x,y (or *d x,y), where x and y are the

co-ordinates of the point to be drawn to.



You can print a UDG anywhere on the screen using the routine below.

You access this ability using the command *PRINT x,y,c (or *p x,y,c),

where (x,y) is the pixel co-ordinate of the top left of the character

and c is the number of the UDG (A is '0', B is '1', and so on).



This part of the program provides a pixel scroll in any of four

directions; the command is used in the form *SCROLL n (or *s n), where

n specifies the direction.



This last routine provides better sound effects. The command is used

in the form *ZAP n (or *z n), where n specifies whether you require an

explosion, a falling tone or a rising tone.

