Linear Search

Products: Linear Search
Developer(s): Thomas B. Woods
Date: 1983
Type: Program
Platform(s): TS 2068
Tags: Database

Linear Search is a file-management and search utility that stores records as raw character data in a fixed memory region starting at address 29658, using POKE and PEEK operations to read and write entries directly to RAM. The program embeds a machine code routine called via USR 29552 that performs the actual string search, with the search target written into memory at address 29513 and a result pointer passed back through PEEK 23748/23749. Records are delimited by quote characters (ASCII 34) and asterisks (ASCII 42), which the BASIC display loop interprets as field and record separators respectively. Data is persisted across sessions using a two-part SAVE: the BASIC program itself is saved with an auto-run line, and the raw data block starting at 29552 is saved as a separate CODE file with a length calculated from the current record pointer p.


Program Structure

The program is organized into four functional blocks. Lines 5–35 handle startup, menu display, and routing. Lines 45–250 implement the search and results-display loop. Lines 500–660 implement the record-entry (“Add/File”) routine. Lines 9000–9999 handle saving and reloading the data store.

A persistent variable p (initialized at line 5) acts as a byte-offset pointer into the raw data area beginning at address 29658. Every added record advances p by the number of characters stored, so p always reflects how many bytes of data have been written.

Machine Code Integration

The heart of the search engine is a machine code routine loaded separately at address 29552. Before calling it, the BASIC program prepares its input in memory:

  • The search string (with a sentinel \::█ character appended) is POKEd byte-by-byte into addresses 29513 onward (lines 45–70).
  • The current data-end pointer p is stored little-endian at addresses 29606–29607 (lines 80–90).
  • Addresses 29604–29605 are set to 218, 115, forming the little-endian 16-bit value 29658 — the start of the data block (lines 100–110).

The routine is invoked with LET b= USR 29552 at line 122. The result pointer for the found match is read back from the system variables at addresses 23748–23749 (line 130), giving a 16-bit address into the data block where the match was found.

Record Format and Display Logic

Records are stored as flat byte sequences in memory with two delimiter conventions:

  • ASCII 34 (") separates fields within a record.
  • ASCII 42 (*) marks the end of a record.

The display loop (lines 135–210) walks from the match address x through x+p, printing each non-quote byte. When it encounters a quote or asterisk at PEEK (y+1), it either issues a newline (line 200) or jumps to line 220 (end-of-record, via GO TO 200+(20*(PEEK (y+1)=42))) — a compact computed GO TO that selects between line 200 and line 220 using Boolean arithmetic.

Add/File Routine

Lines 500–660 collect exactly four lines of input from the user. The first field is prefixed with * (an asterisk and space) to mark the record start; subsequent fields are concatenated with leading quote characters into the string a$. After confirmation, the string is written byte-by-byte into the data area via POKE (lines 600–630), p is incremented for each byte, and a terminating ASCII 42 (*) is appended at line 635. A rudimentary overflow check at line 625 flashes “OUT OF MEMORY” if p exceeds 35600.

Search Navigation

After displaying a match, lines 220–250 prompt the user for three actions:

  • ENTER — re-enters the machine code search from the current position to find the next match (line 231 → line 120, re-calling USR).
  • R — jumps to line 80 to reissue the USR call with an adjusted pointer, intended to step backward through results.
  • N — returns to the main menu at line 14 (a non-existent line, causing a clean fall-through to line 28).

Line 240 contains an apparent debugging remnant: PRINT "line 240b=";b prints the return value of the machine code call unconditionally, followed by a conditional that is never true in normal operation (IF B AND Y$=""). This was likely left in during development and not removed before publication.

Persistence

Line 9000 saves the BASIC program, then saves the combined machine code and data block as a separate CODE file. The length of the CODE save is computed as 107+p, covering the 107-byte machine code routine at 29552 plus all data bytes accumulated at 29658 onward. On next run, line 9999 reloads the CODE file back to its original address and jumps to line 14 to restart.

Notable Idioms and Anomalies

  • POKE 23658,8 (line 30) sets the TS2068 system variable to enable lowercase input.
  • Line 33 routes an empty INPUT directly to GO TO 20, a non-existent line, which silently falls through to line 27 — a deliberate technique to skip re-displaying the header REM blocks.
  • The GO TO 200+(20*(PEEK (y+1)=42)) expression (line 150) is a concise way to branch to either line 200 or line 220 based on a Boolean result, avoiding a separate IF statement.
  • Lines 227–228 implement a key-wait idiom: y$ is set by INKEY$, then a second INKEY$ loop waits for key release before proceeding, preventing key repeat from triggering multiple actions.
  • The sentinel character appended to the search string at line 45 (\::█, a block graphic) acts as an end-of-string marker for the machine code routine, since it is unlikely to appear in user data.

Content

Appears On

Related Products

In-depth treatise on machine language technique for searching data. Construct a fast and highly personalized data base program. 16K.

Related Articles

Do you want to store and retrieve information with your computer? This program uses a machine language search routine that is so fast you can blitz through a full 13000 bytes of files to find the one you want in less than a second!

Related Content

Image Gallery

Source Code

    5 LET p=0
   10 REM       LINEAR SEARCH
   11 REM       \''\''\''\''\''\''\''\''\''\''\''\''\''
   12 REM     A program from the              Nov/Dec 1983 issue               of SYNC magazine
   13 REM 
   14 REM       Adapted for the                   TIMEX  2068
   15 REM 
   16 REM       by G.F.Chambers
   17 REM           in 1984
   18 REM 
   27 REM 
   28 CLS 
   30 POKE 23658,8
   31 PRINT "       TIMEX File/Finder"''" Enter a SEARCH STRING, or"''" type  ""A"" to add a new file"''" or ""S"" to save this program"
   32 INPUT x$
   33 IF x$="" THEN GO TO 20
   34 IF x$="A" THEN GO TO 500
   35 IF x$="S" THEN GO TO 9000
   45 LET x$=x$+"\::"
   50 FOR x=1 TO LEN x$
   60 POKE 29513+x, CODE x$(x)
   70 NEXT x
   80 POKE 29606,p-256* INT (p/256)
   90 POKE 29607, INT (p/256)
  100 POKE 29604,218
  110 POKE 29605,115
  120 CLS 
  122 LET b= USR 29552
  125 PRINT x$( TO LEN x$-1); TAB 0;"File/Search"
  130 LET x= PEEK 23748+256* PEEK 23749
  133 PRINT AT 7,0;
  135 FOR y=x TO x+p
  140 IF PEEK y <>34 THEN PRINT CHR$ PEEK y;
  150 IF PEEK (y+1)=34 OR PEEK (y+1)=42 THEN GO TO 200+(20*(PEEK (y+1)=42))
  170 NEXT y
  180 GO TO 220
  200 PRINT 
  210 NEXT y
  220 PRINT AT 16,0;"Press ENTER  to continue search,",,"""R"" to return to previous files,",,"or ""N"" to begin new file search."
  225 LET y$=""
  227 LET y$= INKEY$
  228 IF INKEY$="" THEN GO TO 228
  231 IF CODE y$=13 THEN GO TO 120
  232 IF y$ <>"N" AND y$ <>"R" THEN GO TO 225
  235 IF y$="R" THEN GO TO 80
  240 PRINT "line 240b=";b:IF B AND Y$="" THEN GO TO 120
  250 GO TO 14
  500 PRINT AT 8,5;"Add/File"
  510 FOR x=1 TO 4
  520 PRINT AT 8,14;"Input line ";x
  530 INPUT x$
  540 IF x=1 THEN LET a$="* "+x$
  550 IF x>1 THEN LET a$=a$+""""+x$
  560 PRINT AT 9+x,0;x$
  570 NEXT x
  580 PRINT AT 17,0;"Press ENTER to log this listing,",,"or ""C"" to correct it."
  585 INPUT x$
  590 CLS 
  595 IF x$="C" THEN GO TO 500
  600 FOR x=1 TO LEN a$
  610 POKE 29658+p, CODE a$(x)
  620 LET p=p+1
  625 IF p>35600 THEN PRINT AT 10,8; FLASH 1;"OUT OF MEMORY"
  630 NEXT x
  635 POKE 29658+p,42
  660 GO TO 14
 9000 SAVE "Search" LINE 9999:BEEP .4,15:SAVE "search C"CODE 29552,(107+p):STOP 
 9999 PRINT AT 10,3;"Now loading 'search' data.":LOAD "search C"CODE :GO TO 14

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

Scroll to Top