★ APPLICATIONS ★ DIVERS ★ Rem Stripper ★ |
Rem Stripper (Computing With the Amstrad) | Applications Divers |
DUDLEY BROOKE shows how to strip out those space-grabbing REMs after they have done their job ONE of the nice things about listings in Computing with the Amstrad is the generous use of REM statements. These are an invaluable aid to the programmer. Unfortunately as far as the Amstrad itself is concerned they are a waste of time and space. In fact a REM takes longer to be ignored than it takes a GOTO to be executed. If you want to prove it you'll be glad to know that you can time any command using Program I by inserting the command in line 40 and running it. The time given will be for a single execution of the command. What is really required is a method of removing REMs after a program has been typed in and fully debugged. Unfortunately it is almost impossible to use Basic for this task as the program would be modifying itself. The results of doing this are unpredictable and potentially disastrous. So to have an independent program in memory and in the interests of speed we have to resort to machine code. To discover how best to write REM Stripper I looked at the tokens used by Basic to store commands after they have been typed into a program. For further information on tokens I would recommend John Hughes' article published in the November and December 1985 issues of Computing with the Amstrad. Briefly though, Basic translates each command in the program into a single byte code. A large part of a Basic program's work is jumping from line to line by means of such commands as GOTO, GOSUB and RUN. In most computers when you type a command with a line number, for example GOTO 20, the computer will store this as a token and the two bytes following will be the line number, as shown in Figure I. When the program is running the interpreter finds the GOTO token and then picks up the line number which follows it. It then has to start at the bottom of the program and work up until it finds the relevent line.
Figure IV: Line 10 after execution This is very inefficient. Tutorials written for other computers recommend that the most used parts of the program are placed at the beginning and DATA statements, instructions and the such like are at the end. This type of structure is frequently seen on the CPC range of computers, but it is unnecessary and can even slow a program down when DATA statements are used frequently. Look at Program II and then compare this with the representation of line 10 in memory- Figure III. Note the extra byte (&1E) between the GOTO token and the line number which is the form of the command prior to running the program. In Figure IV we see the command after it has been run - the extra byte has changed to &1D and the destination has changed to &0179. This number is the memory address of line 20 and the advantage of this is that the interpreter can now jump directly to the destination of the jump. Amazingly the GOTO in this form will now execute more quickly than a REM statement. Some line dependent commands do not take advantage of this system, for example RESTORE. To allow you to investigate this further type in Program III and save it. It displays the bytes that make up line 10, the first line of the program. You can alter this as you wish. 464 owners might be alarmed at the DEC$ command. This is available but you must use an extra opening bracket, for example DEC$((n,'##" ) in line 110. It operates perfectly otherwise and makes formatting numbers very easy. To make the program easier to use I have redefined some keys on the keypad:
When run you will see at the top of the screen the words Line Specifier and underneath some numbers. The numbers in red are the addresses in memory, those in light blue are the values at that address in hex and in decimal. Finally there are some symbols corresponding to character values. Beneath these four bytes there is the word. Tokens and more output in the same format - these numbers are the tokens and data used by the interpreter. This aspect of Basic's operation contributes greatly to its speed but it is not the entire story. It is a fairly simple matter to identify and remove a REM or ' and then move the rest of the program down in memory to fill the gap. However it's not as simple as that because the REM might be the target of a line dependent command such as GOTO 90, RUN 50 or RESTORE 300. These then must be retargeted to point to the next non-REM line. Program IV will eliminate all REM and ' statements and redirect all relevant commands with the exception of Delete as it seems pointless to retarget this if a line is already deleted. It takes approximately 30 seconds for Rem Stripper to deREM a 10k program, depending on the number of REMs present. It is stored starting at location 30000 in memory and is 403 bytes long, including workspace. This should give ample space below for any Basic program and give plenty of room above for extension ROMs and RSXs. To use Rem Stripper type in Program IV and run it. If you have incorrectly entered any of the data the program will inform you at which line this occurred and stop. Once the listing is correct you will be given the option to save or continue. If you choose the save option it will save a loader program followed by the machine code as a binary file. The program will then return to the options. If you select the continue option the full stop on the key pad will be redefined to call the machine code when pressed, stripping all REMs. My advice when using the program is to keep a master copy of the subject program containing the REMs in case any problems occur or you wish to go back and modify it at a later date. You'll find the original REMs invaluable.
|