Amstrad Sprites: A DIY Job
Keith Hook shows readers how to create a Basic extension Although the Amstrad is a good machine in many respects, it's unfortunate that the Locomotive Basic doesn't support sprites. This is the first of two articles that'll show you how to create your own 'Basic extension'. Firstly, I shall use a mini sprite header, and in the final article I shall put the whole thing together to create a real-time game. A sprite must be able to move around the screen in all directions without destroying the background design (and if possible move over the background rather than on it). It is more or less impossible to PEEK the 464's screen, so our extension must have a routine that will overcome this problem so that collisions can be detected. Since space is at a premium, we shall limit our sprites to a single cell (8 x 8). It will not be beyond your capabilities to expand this package to allow 16 x 16 or even 32 x 32 sprites which will give your extension far more power. This article is devoted to the creation of an 8 x 8 sprite, and adding a new Basic command |PUT,N which will enable you to move the sprite over the screen, in any direction as specified by the parameter N. In the next article, I will expand on this by adding a command to read what is on the screen and compare it with a value given in one of the parameters, and expand the |PUT command to control move than one sprite. If you type in listing 3, you will be surprised to see that sprite movement is so fast that delay loops have to be used to slow the action down. The Program Amstrad Basic provides for the addition of Basic commands in the format:
|Command,parameter,parameter.....
The new command must always be prefixed with '|' which is the elongated version of the colon on the computer keyboard. You can test this by typing:
PUT (RETURN)
You will get a syntax error. Now type:
|PUT (RETURN)
and the Amstrad should respond:
UNKNOWN COMMAND
To make sure the Basic does not reject your new command, the resident ROM must be told that you intend to use the new keyword - this is taken care of in parts A & B of the source listing. To Log On a new command, the routine (see part A) must obey the following format: LD BC, Address to Jump Table LD HL, Address of a 4 byte buffer to be used by ROM CALL £BCD1 RET The Jump Table (see Part B) must be designed to conform with the following conventions: Jump table: DEFW, Address of New Basic Words JP, Basic routine 1 JP, Basic routine 2 etc ... New Basic words: DEFM "MOV" DEFB "E" + £80 DEFM "ROTAT" DEFB "E" + £80 DEFB £00; End of Table Marker. £80 sets bit 7 of the last character so that the resident ROM can recognise the end of the new Basic Keyword. Basic extensions can also take on parameters. The parameters are passed to the handling routine via the IX register in the form:- (IX + 00) points to the last parameter and (IX + n) points to the first parameter (See first line Part C). That's all there is to it! You can add as many new commands as you wish - within the capabilities of the memory. One final point on the setting up. The first line of your Basic program that will use the routine must have a MEMORY statement set at one byte less than your routine start address. In the Basic listing supplied, care has been taken to allow enough memory for the Matrix Table to be moved out of ROM. Your sprite command is |PUT, <DIRECTION> where the direction takes the following form:
3 2 4
1 5
8 6 7
So that |PUT,2 will move the sprite diagonally up and to the right. The source listing for the sprite handler is self-explanatory, but the following explanations will add to the clarity of how it works. Explanations £BB78 Get cursor position. H => column L => row This routine corrupts all flags. £BB75 Move cursor position. On entry: H => column L => row HL and AF corrupted on exit. £BB9F Change print mode. On entry: if A = 0 => opaque mode If A not 0 => transparent mode HL & AF corrupted on exit. £BB93 Put current ink into a register. £BB90 Set ink for writing to value in a register. HL & AF corrupted on exit. £BB5D Write a character contained in a reg to screen at current cursor position. HL, DE, BC, AF corrupted on exit. Cursor is moved to next locapon. £BB87 Check if current cursor position will make screen scroll., IF Carry Flag set => NO £BB60 Read a character from screen at current cursor position. Return with character in A. To Use To use the new extension type in the Basic loader and save it on tape. Load it back into memory by typing CTRL & Small Enter at the same time (normal run mode). The program will then automatically go into high memory. You can now load in the DEMO.BAS program and see how the sprite moves. Whenever you use the extension with another program you must observe the following rules:- POKE &A4EF with row and POKE &A4F0 with column of where you want the sprite to start. POKE &A4F8 with 0 (zero). POKE &A4F3 with the character number of sprite. POKE &A4F5 with the ink colour of the sprite. Make sure that the POKEs occur in the first lines of your Basic program - (just follow the format of the demo). After you have tried this program I am sure you will agree that the idea of adding new Basic commands opens up an exciting and new way of using your Amstrad. You'll get a further kick in the final part of this article.