Atari BASIC Search And Display
Bruce Fenster
Quickly search through a BASIC program for any string of characters with this short routine for Atari 400/800/XL/XE computers.
It's easy to lose track of where you used a certain variable or referenced a certain line number when you write BASIC programs. By helping you to find all references to any string of characters in your programs, "Atari BASIC Search and Display" will make you a more effective programmer.
Suppose you are modifying a program. You want to delete or change a line number, but you are not sure if the line is referenced by other statements. With Search and Display, all you simply need to do is search for the line number in question. All statements that reference the line (including GOTOs, GOSUBs, and RESTOREs) are displayed. You can then make any required changes right on the screen.
Because Atari BASIC is so heavily tokenized (keywords, variables, and numbers are all coded into tokens—they are not stored as ASCII characters), searches are not easy to program. This routine uses machine language to rapidly scan a BASIC program in memory.
Program Creation
Using the Atari Proofreader program found elsewhere in this issue, type in the program and save a copy to disk or tape. Be sure that you save a copy before you try to run it—the program modifies itself the first time it is run, moving a machine language routine from DATA statements into a string. Now load the program and type RUN. The resulting program is the one that you will be using to search BASIC programs. To make it easy to merge this program with the programs you will be searching, LIST Search and Display to disk or tape with a statement of the form LIST "D:SEARCH" or (for tape users) LIST"C:".
Using The Routine
Here are the steps necessary to use Search and Display:
- Load the BASIC program to be searched into memory.
- Use an ENTER command to retrieve the final version of the Search and Display routine from disk or tape. This brings it into memory without disturbing the BASIC program.
- To activate the routine, type GOTO 32700 and press RETURN.
You are prompted to enter a string of characters or to press RETURN for a menu. For now, just press RETURN. You'll see a menu at the bottom of the screen. There are three options:
- 1. Press START to run the routine. This returns to the search string prompt.
- 2. Press SELECT to quit. This returns to the Atari screen editor. Statements that were found by a search will be on the screen for you to examine or change.
- 3. Press OPTION to erase the Search and Display routine from memory. Use this prior to saving your BASIC program. If you forget, the routine will be appended to your program.
As a test, press START, then enter any string of characters that you know to be contained within your BASIC program (the maximum size of the search string is 20 characters). Press RETURN. Near the bottom of the screen, you'll notice program statements flashing by (this is your BASIC program being scanned). All lines which contain a matching string will be displayed at the top of the screen. When the entire program has been searched, the menu reappears.
You should be aware that the search is case sensitive. For example, if you specify ENTER as your search string, the program won't find occurrences of Enter or enter if those appear in the program. This is especially important to remember when searching for text in PRINT statements.
You can terminate a search at any time by pressing the space bar. The menu will reappear without disturbing any statements that are displayed. You can temporarily halt a search by pressing CONTROL-1. Press CONTROL-1 again to resume the search.
As the screen fills with statements, they will begin scrolling off the top to make room for those near the bottom. This presents a minor problem if you intended to make changes. The best way to deal with this situation is to let the routine run to completion, then press SELECT and change the statements that are still on the screen. Next, reactivate the routine by typing GOTO 32700 and do the search again. When the missing statements appear on the screen, press space to terminate the search.
Routine Logic
One of the problems in writing this routine developed because BASIC statements are stored in memory as tokens. This is why many similar utilities display only various components of tokenized statements, but not strings of characters. For example, some utilities let you search for the string PRINT or the string A, but not the string PRINT A.
When I wrote this routine, I decided to let the BASIC interpreter do the most difficult work. When you LIST statements on the screen, BASIC untokenizes each one before displaying it. The Search and Display routine then must simply scan the resulting line of ASCII characters. Here's how it works: A statement is displayed at the bottom of the screen (lines 32708-32710). Then, a machine language routine is called to search for the string (line 32711). It scans the bottom of screen memory where the statement was listed. If the string is found, it returns to BASIC with a value of 1, otherwise it returns with a value of 0. If the value returned is a 1, the statement is listed to the upper portion of the screen (lines 32712-32716). The process begins again with the next statement. When line number 32700 is encountered, the routine goes to line 32717 to display the menu.
Technical Notes
The Atari forced read mode (similar to the dynamic keyboard technique used by other computers) is used by the erase option. It is also used when creating the final version of this routine (converting the DATA statements to a string). In effect, the computer pushes its own RETURN key.
The machine language routine does not check the line number of each program line when testing for matches. This enables you to search for line references without having the line itself listed in the search. If the line refers to itself (as in 100 GOTO 100) and you search for the line number, it will be listed.
When you press SELECT (to quit), you'll notice the screen is cleared and then repainted with any statements that were found. This is not wasted effort. The Atari logical line bitmap (locations 690-693) is destroyed by the search and this corrects it.
Atari BASIC Search And Display
For instructions on entering this program, please refer to "COMPUTEI's Guide to Typing in Programs" elsewhere in this issue.
JO 10 GRAPHICS 0 : POSITION 2, 2 : ? "32701 ML$(LEN (ML $) + 1) = " ; CHR$(34); BC 11 FOR I = 1 TO 87 : READ X : ? CHR$(X) ; : NEXT I : ? CHR $ (34) KH 12 ? "32702 ML$ (LEN(ML$) + 1) = " ; CHR$(34) ; IA 13 FOR I = 88 TO 174 : READ X : ? CHR$(X) ; : NEXT I : ? C HR$(34) PN 14 FOR I = 10 TO 14 : ? I : NEXT I : FOR I = 32725 TO 32731 : ? I = NEXT I : ? "POKE 842, 12" : POKE 842, 13 : POSITION 2, 0 : STOP LK 32699 REM COPYRIGHT 1987 COMPUTE! PUBLICATIONS, INC. ALL RIGHTS RESERVED. NM 32700 CLR : DIM S$(20), ML$(174), CP(20), LN(20) CE 32701 RESTORE 32725 AM 32702 FOR I = 1 TO 174 : READ B : ML$(I, I) = CHR$(B) : NEXT I BN 32703 STMTAB = PEEK(136) + PEEK(137)*256 : X = 0 : X1 = 1 : SWT = 0 : LN(1) = 0 : GRAPHICS 0 AH 32704 ? "{CLEAR} COPYRIGHT 1987" : ? "COMPUTE! PUBLICATIONS, INC." : ? "ALL RIGHTS RESERVED" : ? "{DOWN} Press SPACE to stop search" CD 32705 ? : ? "ENTER STRING : (Press RETURN for menu)" : INPUT S$ POKE 16, 112 : POKE 53774, 112 : POKE 752, 1 OD 32706 ? CHR$(125) : IF LEN(S$) = 0 THEN LINE = PEEK (STMTAB) + PEEK(STMTAB + 1) * 256 : GOTO 32717 P1 32707 POKE 82, 0 PM 32708 LINE = PEEK (STMTAB) + PEEK (STMTAB + 1) * 256 : IF LINE = 32700 OR PEEK (764) = 33 THEN POKE 764, 255 : GOTO 32717 KB 32709 STMTAB = STMTAB + PEEK (STMTAB + 2) NH 32710 POSITION 2, 18 : LIST LINE 6J 32711 INSTR = USR (ADR(ML$), ADR(S$), LEN(S$), SWT) : SWT = 1 LO 32712 IF INSTR = 0 THEN 327 08 PH 32713 POKE 82, 2 KJ 32714 IF X < 16 THEN POSITION 2, X : LIST LINE : CP (X1) = PEEK (84) - X - 1 : LN(X1) = LINE : X = PEEK(84) - 1 : X1 = X1 + 1 : GOTO 32707 LP 32715 FOR I = 1 TO CP (1) : POSITION 2, 1 : ? CHR$(156) : NEXT I LL 32716 X = X - CP(1) : X1 = X1 - 1 : FOR I = 1 TO X1 : CP(I) = CP(I + 1) : LN(I) = LN(I + 1) : NEXT I : GOTO 32714 CF 32717 POSITION 2, 21 : ? "START = RUN SELECT = Quit OPTION = Erase" : POKE 53279, 8 : POKE 82, 2 DA 32718 POKE 764, 255 : K = PEEK (53279) : IF K = 6 THEN ? CHR$(125) : GOTO 3 2703 MB 32719 IF K = 5 AND X = 0 THEN GRAPHICS 0 : CLR : END HE 32720 IF K = 5 THEN GRAPHICS 0 : FOR I = 1 TO X1 - 1 : LIST LN(I) : POKE 84, PEEK (B4) - 1 : NEXT I : POKE 84, PEEK(84) + 1 : CLR : END LK 32721 IF K < > 3 THEN 32718 IB 32722 GRAPHICS 0 : POSITION 2, 2 : FOR I = 32700 TO 32712 : ? I : NEXT I : ? "GOTO 32724" BL 32723 POKE 842, 13 : POSITION 2, 0 : STOP NA 32724 POKE 842, 12 : GRAPHICS 0 : POSITION 2, 2 : FOR I = 32713 TO 32724 : ? I : NEXT I : ? "POKE 842, 12" : CLR : GOTO 32723 EL 32725 DATA 216, 104, 104, 133, 207, 104, 133, 206, 104, 104, 133, 208, 104, 104, 208, 57, 166, 208, 177, 206, 201, 32, 176, 11, 24 DF 32726 DATA 105, 64, 145, 206, 200, 202, 208, 241, 240, 25, 201, 96, 176, 5, 56, 233, 32, 16, 239, 201, 128, 176, 2, 144, 233 MN 32727 DATA 201, 160, 176, 2, 144, 224, 201, 224, 144, 235, 24, 169, 248, 101, 88, 133, 203, 169, 2, 101, 89, 133, 204, 165, 203 HN 32728 DATA 72, 165, 204, 72, 160, 0, 177, 203, 230, 203, 208, 2, 230, 204, 201, 0, 208, 244, 169, 124, 133, 205, 132, 212, 132 JG 32729 DATA 213, 177, 203, 209, 206, 240, 12, 198, 205, 240, 32, 230, 203, 208, 242, 230, 204, 208, 238, 166, 208, 198, 208, 240, 13 DL 32730 DATA 200, 177, 203, 209, 206, 240, 245, 134, 208, 160, 0, 240, 225, 169, 1, 133, 212, 234, 104, 133, 204, 104, 133, 203, 160 EK 32731 DATA 0, 169, 0, 145, 203, 200, 192, 124, 208, 249, 9, 15, 9, 240, 141, 178, 2, 141, 179, 2, 141, 180, 2, 96