SPECTRUM EXTENDED BASIC (ZX Computing, November 1986) [NOTE: The assembly listing mentioned in the text] [was not printed in the magazine. JimG] Interface One owners can add some new commands to Sinclair Basic, with this program. By Paul Matthews Any Spectrum user with Interface I will know that it allows the use of microdrives, RS232 devices, and the ZX net. However, a less well known feature is the facility to extend Spectrum BASIC by changing the syntax of certain keywords. This feature is used by my routine to provide the Spectrum user with six extra commands. They are:- PLOT *x,y which will PLOT anywhere on the screen. Co-ordinates (0,0) are in the very bottom left-hand corner, where it is not usually possible to PLOT. So the normal PLOT 0,0 becomes PLOT *0,16 and PLOT 0,175 becomes PLOT *0,191. POKE *a,b where b is a number from 0-65535. This means that a 16-bit number can be POKEd with the low order byte going into location a and the high order byte going into the location (a+1), ie. POKE *23735,64900 is equivalent to POKE 23735,132 and POKE 23736,253. POKE AT a,a$ which will POKE a hexadecimal value held in a$ into location a; e.g. POKE AT 23296,"C9" will put C9 (201 dec) into location 23296. If there is more than one hexadecimal number (which can be separated by spaces) then they are put into the locations following a; e.g. POKE AT 23296, "3EFEC9" and POKE AT 23296,"3E FE C9" are both possible and will POKE 3E (62 dec) into location 23296, FE (254) into 23297 and C9 (201) into 23298. Therefore, this command could be used to enter machine-code easily and quickly. ATTR f,p,i TO nf,np,ni which will search out specified attributes and replace part or all of each found, with a new attribute. f is the flash and brightness intensities to be changed (0=none, 1=bright only, 2=flash only, 3=both, 8=any combination). p and i are the PAPER and INK colours to be changed (0-7=Black-White, 8=all colours). nf is the new flash and brightness intensities (0=neither, 1=bright, 2=flash, 3=both, 8=leave as they are). Finally, np and ni are the new PAPER and INK colours (0-7=Black-White, 8=leave as it is, 9=contrast). ATTR 1,0,6 TO 1,7,1 will change all characters which are bright yellow INK on black PAPER to bright blue INK on white PAPER. ATTR 8,8,0 TO 1,8,9 will change all characters with black INK (no matter the PAPER colour and flash or brightness intensities) to bright contrast INK (either black or white) on the original PAPER colour. Note: one of the powerful features of this command is that the whole screen can be changed by setting the first three numbers to '8'; e.g. ATTR 8,8,8 TO 8,1,8 will change the entire screen to blue PAPER. INVERSE which swaps over the PAPER and INK colours in the attribute file, without altering the flash and brightness intensities. SIN which stands for "Screen INvert" and will invert all the characters on the screen. NOTE: INVERSE and SIN have the same visual effect but INVERSE affects ATTR (as bits 0,1 & 2 and bits 3, 4 & 5 of each attribute are swapped over) but does not affect POINT whilst SIN affects POINT (as all pixels set are reset and vice-versa) but not ATTR. New Vector The key to extending the BASIC is the "new" system variable VECTOR. Whenever a syntax error occurs, the "shadow" ROM (i.e. that in Interface 1) is paged in and checks the syntax to see if it's one of the Micro-drive commands; if not, it jumps to the location pointed to by VECTOR. Therefore, to add commands you need only change VECTOR to point to the beginning of your own machine-code routine. This is done in the set-up routine (lines 210-240 of the assembly listing; lines 210-20 [sic] set up the "new" system variables, as these are not usually set up until an error occurs). Before you can use the extra commands the set-up routine must be called by a line such as LET a=USR 64900 (64900 is where I placed the routine in memory. However, if you assemble it, you can put it anywhere you want by changing Lines 10 and 20. Once assembled, though, the routine cannot be moved.) When a non-standard command is found, the routine will be called. However, the "shadow" ROM will be paged in which means that if you want to use any of the "main" ROM routines you cannot use CALL as that would CALL a "shadow" routine. Instead, you have to use an RST #0010 instruction (# denotes hex) followed by the address of the "main" routine. This "shadow" routine pages in the "main" ROM, calls the required "main" routine and then pages out the "main" ROM. In this article, the restart routine has been given the name CALBAS. On entry to the routine pointed to by VECTOR, another system variable CH-ADD will be pointing to the command of the error statement. To find out what command this is, the "main" routine GET CHAR (#0018) is used. This puts the character pointed to by CH-ADD into the A register. The next characters in the statement can then be found by using NEXT CHAR (#0020) which increases CH-ADD by one and puts the character now pointed to, into the A register. Keywords I have used five different keywords and, as you can see, they do not all have to be common commands; e.g. ATTR (a function) is being used. Also note that if the syntax of your new command is the same as that of the original (e.g. PLOT and POKE in this article) another character (e.g. an asterisk) has to be placed after the keyword or the ROM will not recognise it. However, if you do not like the present keywords, you can make your own up' e.g. *Renum or *Delete, but these have to be typed out in full and each letter must be checked by increasing CH-ADD and then comparing the character. The asterisk, which could be any shifted symbol, is necessary to get the cursor out of K mode. It can be seen (in lines 270-380) that the first thing to be done, once called by the ROM, is to get the code of the error command into A, and then check this against the five new commands (not six, POKE is used twice). If one of these commands is found the appropriate routine is called, otherwise the normal error routine (*01F0) is called instead, which produces either a flashing question mark or "nonsense in BASIC". Interesting points to note in my routine include the fact that POKE is used twice. This is done by jumping to the second routine when the asterisk after the POKE fails. Only if the character also fails to be an "AT" sign is the error routine called. Another thing to be noted is that the ATTR scanning routine (ie. when it actually looks at the screen) is really only four lines in length. However, this is increased by also allowing ATTR to have new INK and PAPER colours 9 which cannot be easily changed in the same way. I hope my routine provides useful commands and that this article will help you to write your own commands. For further information, I advise you get Ian Logan's "Spectrum Microdrive Book", and "The Complete Spectrum ROM Disassembly" by Ian Logan and Frank O'Hara.