By Jerry White
While developing commercial software I've often wished I could make a faster string search in an ATARI BASIC program. In one case, I had to search through a long string of eight character records, for one specific record. The ATARI BASIC routine I wrote was much too slow. If I used BASIC A +, the FIND command would do the trick, but I needed to use ATARI BASIC. The only alternative was to write an Assembler subroutine to do the job.
As you can see, I put lots of comments in the Assembler Source Code for my fellow Assembler hackers. The Assembler routine is included in my BASIC demo program, so you won't need an Assembler Cartridge. Type in the little BASIC program now, but SAVE IT BEFORE YOU RUN IT!
The BASIC program begins by setting Graphics Mode 0, the margins at their default values, and the print tab width at 8.
In line 120, we dimension three strings. SS$ will be used to store our machine language routine. DSTR$ is our Data STRing which will store the data we wish to search FOR. SSTR$ is our Search STRing which is dimensioned to 8,000 characters. Think of it as 1,000 eight-character words, with each word representing one record. The idea is to find one specific word. That word is the one stored in DSTR$.
My search routine is stored in DATA statements. At line 200, we read the data and put it into the string SS$. At line 210, we store 8,000 spaces in SSTR$, we put the word "FINDTHIS" into DSTR$, and set COUNT equal to 1,000. COUNT is our total number of records. At this time, SSTR$ contains 1,000 (COUNT) records.
At line 240, we ask the user to enter a number from 1 to 1000, and store it as RN (Record Number). Line 250 puts DSTR$ or "FINDTHIS" into SSTR$ as the record number specified by the user. For our initial test, enter the number 1000 and press RETURN. !We are looking for a numeric value, so DO NOT enter 1,000. No comma please!
Press the START key to execute the string search. The program will search through 999 records before it finds "FINDTHIS". It will then tell you that "DSTR$ MATCHES RECORD 1000 in SSTR$, and END with the message BASIC IS READY. If you don't see this message, go back and check your typing and make sure you followed directions.
If all went well, you saw these messages almost immediately after you pressed the START key. That's the advantage of assembly language, speed!
Now let's change things so that the search is unsuccessful. But first, make sure you have saved the program. Then change line 250 to SSTR$ (RN*87,RN* 8) = "FINDTHAT". The search will look for "FINDTHIS". When we reach line 310, FIND will be equal to zero and we will heave proved that the routine works.
Look at line 300. This is where we call the machine language subroutine. We must pass along the address of our Assembler program, the COUNT (number of records to search through), the address of the string to be searched, and the address of the string to search for. Be sure to enter this data properly, and in this specific order. The Assembler program does no error checking.
Now let's make a comparison between this routine, and a similar routine in BASIC. Before we do this, change line 250 back to SSTR$ (RN ~ 8-7,RN 8 ) = DSTR$. Change line 330 to STOP. Now RUN this program again and be sure to specify record number 1000. If all went well, you now see the message "STOPPED AT LINE 330" near the bottom of your screen.
Since the program did not END, our strings are still usable. To demonstrate the same search in BASIC, we will add 2 lines to our program. Add these lines:
1 FOR RN = 1 TO 1000:REC = RN * 8 :IF DSTR$ = SSTR$(REC-7,REC) THEN ?RN:STOP
2 NEXT RN:STOP
To execute this routine, type GOTO 1 and press RETURN. BASIC will find our match in approximately 17 seconds.
If you wish to use this routine, but your record length is not eight positions, you can change bytes 30 and 38 to any integer from 1 to 255. If you make any changes that might increase the value of this routine, let us know so that we might all benefit from your experience.