Authors
Publication
Publication Details
Volume: 4 Issue: 6
Date
Pages
Now we’ll return to the interrupt driven sprite program. When you type RANDOMIZE USR 64776 to start the program, the little sprite will bounce happily around the screen, and will keep bouncing, even while you type in your own BASIC programs and run them. While you run a BEEP command or do I/O to the cassette or T/S 2040 printer, he stops, producing a visual indication of whether or not the interrupt is enabled.
There’s nothing unusual about the BASIC program. It mostly just inserts the necessary machine code. Lines 40 and 50 install the standard “kludge block” and JP instructions we’ve been using since the beginning.
Whenever the interrupt occurs, it’s diverted from its intended task of reading the keyboard. Instead, we figure out where the sprite should be moved to, move it, and then we allow the computer to read the keyboard and get back to its real business.
Moving the sprite is fairly easy. Before we ever write the sprite to the screen, we save whatever is already there. When it comes time to move the sprite, we replace the old information, figure out where the new sprite should be, save the character at the new location, and then write the sprite. As such, the sprite passes through an area, leaving everything as it found it.
Well, almost. Let’s supposed that, after writing the sprite in a certain spot, the “foreground” program writes another new character on that same spot. If we moved the sprite exactly as described, it would replace the old character rather than the new one when the sprite moved on. This would never do.
To fix this, the program doesn’t replace the old character until it first checks the supposed location of the sprite. If it doesn’t find the sprite character there, then it assumes your own program has already changed that location and doesn’t change it back. Note that all 8 bytes of the screen character must match all 8 bytes of the sprite character. As long as you’re only writing text to the screen, this is ok.
But if you’re PLOTting individual pixels, and just happen to put or clear a pixel on the sprite character, the 8 bytes will no longer match up, and a stationary “son of sprite” will be left on the screen. Worse, if you do a CLS, lots of pieces of sprite will remain on the otherwise clear screen. These “spritelets” remain because the screen lines are cleared in the same odd order that you see them filled when you LOAD a SCREEN$. AS the sprite moves from space to space, it has lots of chances to get a line or two erased from itself. This modified sprite then stays for good.
As explained in the original article, before you do a CLS or a PLOT, or draw LINE or CIRCLE, you should first disable the sprite with POKE 64898,1. When you’re done you can restart the sprite with RAND USR 64776.
But, to be practical, it’s probably best just to ignore this little problem. This program is just a demonstrator. It proves its point with the smallest amount of code. It gives an example of how the job is done and how you can use it or something like it in your own programs. A quick look at the code will show how. Here’s a quick description of each part of the program.
FD00 STOR8 Temporary storage for the 8 bytes “wiped out” by the sprite
FD08 START Setup routine that starts up the sprite
FD18 SRVINT Interrupt service. If the FLG byte contains 0, it moves the sprite and runs the keyboard routine. Otherwise, it shuts off the sprite.
FD40 NEWBUG Places the 8 bytes at BUG1 into the display file location defined by LOCS.
FD4E UPDATE Computes new location and direction.
FD7E LOCS The row and column location of the sprite.
FD80 DIRS The x and y directions of the sprite.
FD82 FLG Tells SRVINT whether or not to continue running the sprite.
FD83 BUG1 The 8 bytes that make up the sprite.
FD8B OLDBLK Replaces the old character on top of the sprite, provided that the sprite is still there.
FDA5 GETDIS Gets the display file address of a character. Input D=line, E=column. Output HL=address.
FDB4 GET8 Puts bytes from 8 consecutive locations at (BC) into the display file character at (HL).
FDBE SAVE8 Puts bytes for 1 character at display file location (HL) into 8 consecutive locations at (BC).
FDCB COMP8 Compare the bytes for 1 character at display file location (HL) with 8 consecutive bytes at (BC). Return with Z=1 if all 8 are equal.
FDD3 SAVCHR Saves the character at (LOCS) into STOR8.
The block STOR8 is the 8-byte space where the screen character is stored while the sprite is “borrowing” its space. BUG1 contains the character patterns for the sprite and you can change it to suit your mood. LOCS is the row and column location of the sprite, and DIRS contains the directions in which it happens to be moving. FLG is the byte you can poke when you want the sprite to go away. When the main program sees a “1” here, then after it replaces the old character, it goes back to IN1, putting an end to all this spritely business.
The code contains four relocatable routines that have to do with display file tricks, and you can copy them to your code for your own use. If you’re familiar with the unusual layout of the display file, you may appreciate some code to make it more manageable.
The first relocatable routine, GET8, puts bytes from 8 consecutive locations at (BC) into the display file character at (HL). As such, it moves data from the sequential order we like to use into the non-sequential order of the display file. The relocatable routine SAVE8 does it backwards, moving the 8 non-sequential character bytes at display file address (HL) into 8 consecutive locations at (BC).
The last relocatable routine is COMP8, which compares the 8 sequential bytes at (BC) to the 8 non-sequential bytes in the display file at locations (HL). We exit the program with Z=1 only if both characters match exactly.
Each routine has been kept deliberately small, so that they’d be easy for you to follow and modify. With a little work, you should be writing your own more elaborate sprite programs in no time!