--- title: "Inventory Control" id: 58400 type: "computer_media" slug: "inventory-control-2" url: "http://localhost/computer_media/inventory-control-2/" markdown_url: "http://localhost/computer_media/inventory-control-2.md" published_at: "2024-11-17T12:22:56+00:00" modified_at: "2026-04-03T07:58:03+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/11/inventory-control.png" excerpt: "A two-part stock management system that packs multi-field inventory records into string arrays and uses embedded machine code for fast sorted insert and delete operations." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "Mindware" slug: "mindware" taxonomy: "post_tag" url: "http://localhost/tag/mindware/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Business" slug: "business" taxonomy: "genre" url: "http://localhost/type/business/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Inventory%20Control%20%281982%29%28Mindware%29%28TS1000%29%28US%29%28Program%29.zip" mediadate: "1982" producer_company: - id: 11120 title: "Mindware, Inc." type: "company" url: "http://localhost/company/mindware/" images: - url: "http://localhost/wp-content/uploads/2024/11/inventory-control.png" - url: "http://localhost/wp-content/uploads/2024/11/STOCK2.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/STOCK1.jpeg" - url: "http://localhost/wp-content/uploads/2024/11/Tape-9.jpg" related_products: - id: 12953 title: "Inventory Control" type: "product" url: "http://localhost/product/inventory-control-3/" media_type_tags: "Business" --- Inventory Control is a two-program stock management suite. The first program (Stock Control I) maintains a sorted list of named stock items, each record storing a name string, supplier code, type code, stock level, re-order level, and unit value packed as multi-byte integers in a string array. It performs a binary search for fast lookup and uses RAND USR calls to machine code routines (at addresses 16517 and 16542) embedded in the REM statement at line 0 to insert and delete records by block-moving memory. The second program (Stock Control II) is a simpler numeric-keyed variant that tracks line numbers and stock quantities only, using a four-character string array and the same binary search and machine code insert/delete approach. Both programs support LPRINT for hard-copy stock listings, tape SAVE of data, and a configurable memory allocation routine that calculates the maximum number of records fitting in available RAM. *** ## Program Analysis ### Overview and Two-Program Structure The suite consists of two independent BASIC programs. **Stock Control I** is the full-featured inventory manager handling named stock lines with multiple data fields. **Stock Control II** is a stripped-down numeric-key variant that stores only line numbers and stock quantities. Both share the same architectural patterns: a sorted string array database, binary search, and machine code block-move routines for insertion and deletion. ### Data Storage Format In Stock Control I, each record occupies a fixed-length row of the string array `D$`. The row length is `FL = 9 + NL + ND`, where `NL` is the name-field length and `ND` is the text-field length. The field layout within each row is: | Byte(s) | Field | Encoding | | --- | --- | --- | | 1 | Supplier code | Single byte via `CHR$` | | 2 | Type code | Single byte via `CHR$` | | 3–4 | Stock level | 16-bit little-endian: low = byte 3, high = byte 4 | | 5–6 | Re-order level | 16-bit little-endian | | 7–9 | Unit value × 1000 | 24-bit little-endian (scaled by `FC=1000`) | | 10 to 9+NL | Item name | Left-justified plain text | | 10+NL onward | Free text | Plain text | In Stock Control II, records are only 4 bytes: bytes 1–2 hold the line number as a 16-bit little-endian integer, bytes 3–4 hold the stock quantity in the same format. ### Binary Search Both programs implement a binary search across the sorted array. Lines `1050`–`1160` set up `LO` and `HI` bounds, compute `N=INT(.50001*(LO+HI))`, and compare the key field of `D$(N,...)` against the search target. The small offset `0.50001` instead of `0.5` avoids a rounding edge case. When the search terminates without an exact match (lines `1200`–`1208`), the code resolves the insertion point by checking the `LO` and `HI` boundary records, then falls through to the new-record entry routine. ### Machine Code Insert and Delete The REM block at line `0` contains embedded Z80 machine code. Before calling it, subroutine `500` POKEs parameters into a fixed memory area (addresses `16536`–`16541`) as three 16-bit little-endian values representing byte counts and addresses: - `POKE 16536/16537` — byte count `A` - `POKE 16538/16539` — destination address `C` - `POKE 16540/16541` — source address `B` After POKEing, `RAND USR 16517` is called for insertion (block move to open a gap) and `RAND USR 16542` for deletion (block move to close a gap). The two entry points within the same REM correspond to forward and reverse block copies, matching the Z80 `LDIR` and `LDDR` instructions visible in the raw bytes (`\ED\B0` = LDIR, `\ED\B8` = LDDR). ### Address calculation for block moves The base address of the string array data is computed dynamically at lines `92` and `200`: - `AD = 8 + PEEK(16400) + 256*PEEK(16401)` — reads the system variable holding the D-file/variable area pointer and adds 8 bytes for the array header. - Record offsets are then `AD + FL*N - 1`, accounting for the 1-based BASIC string indexing. ### Initialization Routine (line 7000 block) The setup section (lines `7000`–`7300` in Stock Control I) prompts the user for name-field length and text-field length, then calculates the maximum number of records that will fit in free RAM using: ``` M = INT((PEEK(16386) - PEEK(16412) + 256*(PEEK(16387) - PEEK(16413)) - 2*(256+N+D)) / (9+N+D)) ``` The result is stored via POKE into a small scratchpad area (`16557`–`16560`), then read back after `CLEAR` to dimension `D$`. This survive-CLEAR trick exploits the fact that `CLEAR` resets most variables but not arbitrary memory locations below `RAMTOP`. Stock Control II’s initialization (lines `7000`–`7300`) is simpler: it hardcodes `FL=4` and computes `MAX = 62*(PEEK(16389)-89)` from the RAM size system variable, giving a capacity that scales with installed memory. ### Key BASIC Idioms - **Symbolic constants via variables:**`Q=256`, `W=1`, `O=0`, `T=21`, `FC=1000` are set once and used throughout, reducing token count and making expressions self-documenting. - **16-bit packing:** Values are stored as `CHR$(Z - Q*INT(Z/Q))` (low byte) and `CHR$(INT(Z/Q))` (high byte), equivalent to `Z MOD 256` and `Z \ 256` without using MOD or integer division keywords. - **PAUSE 4E4 / INKEY$ idiom:** Used consistently at menu prompts — `PAUSE 40000` followed by reading `INKEY$` gives a long wait for a keypress without blocking indefinitely. - **GOTO O (GOTO 0):** Used as a “return to master menu” idiom; since there is no line 0 in the executable portion, this causes BASIC to fall through to the first executable line after the REM blocks, which is line `2000` (the main menu). - **GOTO W (GOTO 1):** Similarly used as a shorthand for jumping to line 1, which is a REM, so execution falls to line 2 (`CLS`) and then the main menu. ### Printing and LPRINT All report output is mirrored to both screen (`PRINT`) and printer (`LPRINT`) in parallel. Subroutine `46` handles formatted columnar output with `TAB` stops at columns 13, 18/19, and 26. The listing mode is controlled by variable `L`: `L=0` prints supplier/type, `L=1` prints re-order level, and `L=2` prints the full text field via subroutine `60`. ### Integrity Check Line `16` in Stock Control I performs `IF PEEK R <> 232 THEN STOP` (where `R=16396`). This checks a system variable for an expected value to detect data corruption or unauthorized modification. Stock Control II uses `IF PEEK R <> 030 THEN STOP` for the same purpose with a different expected byte. ### Anomalies and Notes - Line `3520` in Stock Control I calls `GOSUB 43`, but subroutine `43` does not exist as a defined line. The nearest defined subroutine is `40`. Execution will fall through to line `40` as BASIC seeks the nearest line ≥ 43, which is line `45` (`RETURN`), meaning only the re-order and stock fields `C` and `D` are decoded — apparently intentional to avoid the overhead of decoding unused fields for the understocked check. - Line `7024` misspells “accommodate” as `"ACCOMODATE"` in the PRINT statement — a cosmetic issue only. - The variable `X` serves double duty in several sections: as a menu option code and as a line number in Stock Control II, relying on control flow to keep contexts separate. ## Source Code ``` 0 REM 757677ED4B9840ED5B9A40ED6B9C40EDB8C91B1B1B1B1D0425F255FED4B9840ED5B9A40ED6B9C40EDB0C955F2FF1B1B 1 REM STOCK CONTROL. (C) HILDERBAY LTD 1981 2 CLS 0 REM 75767710281102D2E31292A3727263E031392901D25241D 0 PRINT "% % % % % % % % % % %S%T%O%C%K% %C%O%N%T%R%O%L% % % % % % % % % %(%C%)% %H%I%L%D%E%R%B%A%Y% %1%9%8%1% % %0%1%-%4%8%5% %1%0%5%9% ",,,, 15 PRINT AT 20,0;"% % % %P%R%O%G%R%A%M% %H%A%S% %B%E%E%N% %C%O%R%R%U%P%T%E%D% % % %O%R% %D%A%T%A% %D%E%L%E%T%E%D%.% %L%O%A%D% %F%R%O%M% %T%A%P%E%." 16 IF PEEK R<>232 THEN STOP 17 PRINT AT 4,O;T$,,,, 29 GOTO 2000 30 FOR I=A TO T 32 PRINT AT I,O;O$ 34 NEXT I 36 RETURN 40 LET A=CODE D$(N,W) 41 LET B=CODE D$(N,2) 42 LET E=CODE D$(N,7)+Q*(CODE D$(N,8)+Q*CODE D$(N,9)) 43 LET C=CODE D$(N,3)+Q*CODE D$(N,4) 44 LET D=CODE D$(N,5)+Q*CODE D$(N,6) 45 RETURN 46 IF L=W+W THEN GOTO 60 50 PRINT D$(N,NS TO NE);TAB 13;C;TAB 18; 51 LPRINT D$(N,NS TO NE);TAB 13;C;TAB 18; 52 IF L THEN PRINT TAB 19;D; 53 IF L THEN LPRINT TAB 19;D; 54 IF NOT L THEN PRINT A;TAB T;B; 55 IF NOT L THEN LPRINT A;TAB T;B; 56 PRINT TAB 26;E/FC 57 LPRINT TAB 26;E/FC 58 RETURN 60 LET Q$=D$(N,NS TO NE)+" "+D$(N,NE+W TO )+" "+STR$ (E/FC) 61 PRINT Q$ 62 LPRINT Q$ 63 RETURN 90 IF NN>=MAX THEN GOTO 2500 91 IF N>NN THEN GOTO 130 92 LET AD=8+PEEK (16400)+Q*PEEK 16401 93 LET A=FL*(NN-N+W) 94 LET B=AD+FL*NN-W 96 LET C=AD+FL*(NN+W)-W 98 GOSUB 500 100 RAND USR 16517 130 LET D$(N)=E$ 140 LET NN=NN+W 150 GOTO 1300 200 LET AD=8+PEEK (16400)+Q*PEEK 16401 240 LET N=N-W 260 LET A=FL*(NN-N) 270 LET B=AD+FL*(N+W) 280 LET C=AD+(FL*N) 290 GOSUB 500 300 RAND USR 16542 310 LET NN=NN-W 350 GOTO O 500 POKE 16536,A-Q*INT (A/Q) 510 POKE 16537,INT (A/Q) 520 POKE 16538,C-Q*INT (C/Q) 530 POKE 16539,INT (C/Q) 540 POKE 16540,B-Q*INT (B/Q) 550 POKE 16541,INT (B/Q) 560 RETURN 600 CLS 610 PRINT "ENTER NAME FOR NEW TAPE FILE, START RECORDING, THEN % %E%N%T%E%R% ." 620 PRINT ,,"% %E%N%T%E%R% ONLY TO RETURN TO MENU." 630 INPUT Q$ 640 IF Q$<>"" THEN SAVE Q$ 650 GOTO O 1000 CLS 1010 PRINT AT 20,O;"ENTER LINE TO SEEK (UP TO ";NL,"CHARACTERS), OR % %E%N%T%E%R% ." 1020 INPUT Q$ 1030 IF Q$="" THEN GOTO W 1031 IF LEN Q$>NL THEN LET Q$=Q$(W TO NL) 1040 LET I=LEN Q$ 1045 IF NOT NN THEN GOTO 1210 1050 LET LO=W 1060 LET HI=NN 1070 LET N=INT (.50001*(LO+HI)) 1080 LET N$=D$(N,NS TO NS+I-W) 1090 IF N$=Q$ THEN GOTO 1300 1095 IF HI=LO OR HI=LO+W THEN GOTO 1200 1100 IF N$N$ THEN LET N=HI+W 1210 CLS 1211 PRINT "%Y=%R%E%T%U%R%N TO MASTER MENU.",,,"%(%O%T%H%E%R%): ENTER NEW LINE """;Q$;"""" 1212 PRINT AT T,O;"CHOOSE AN OPTION." 1213 PAUSE 4E4 1214 IF INKEY$="Y" THEN GOTO W 1215 CLS 1217 DIM E$(FL) 1219 LET E$(NS TO )=Q$ 1220 PRINT AT T,O;"UNIT PRICE ($)?" 1221 INPUT Z 1222 LET Z=FC*Z 1223 LET H=INT (Z/Q) 1224 LET E$(7)=CHR$ (Z-Q*H) 1225 LET Z=H 1226 LET H=INT (Z/Q) 1227 LET E$(8)=CHR$ (Z-Q*H) 1228 LET E$(9)=CHR$ H 1230 PRINT AT T,O;"SUPPLIER CODE? (OPTIONAL)" 1231 INPUT Q$ 1232 IF Q$<>"" THEN LET E$(W)=CHR$ VAL Q$ 1233 PRINT AT T,O;"TYPE CODE? " 1234 INPUT Q$ 1235 IF Q$<>"" THEN LET E$(2)=CHR$ VAL Q$ 1237 PRINT AT T,O;"STOCK LEVEL? " 1238 INPUT Q$ 1239 IF Q$="" THEN GOTO 1238 1241 LET Z=VAL Q$ 1242 LET H=INT (Z/Q) 1244 LET E$(3)=CHR$ (Z-Q*H) 1245 LET E$(4)=CHR$ H 1250 PRINT AT T,O;"RE-ORDER LEVEL? (OPTIONAL)" 1251 INPUT Q$ 1252 LET Z=O 1253 IF Q$<>"" THEN LET Z=VAL Q$ 1254 LET H=INT (Z/Q) 1255 LET E$(5)=CHR$ (Z-Q*H) 1256 LET E$(06)=CHR$ H 1257 IF NOT NN THEN GOTO 1260 1258 GOTO 90 1260 LET D$(W)=E$ 1265 LET NN=W 1270 LET N=W 1300 CLS 1310 PRINT "LINE: ";D$(N,NS TO NE);TAB 28;N 1320 PRINT D$(N,NE+W TO ) 1330 GOSUB 40 1370 PRINT ,,"SUPPLIER: ";A 1372 PRINT "TYPE: ";B 1374 PRINT "UNIT VALUE: ";E/FC 1376 PRINT "RE-ORDER LEVEL = ";D 1380 PRINT " %S%T%O%C%K% %= ";C; 1390 IF C"5" AND Q$<>"8" THEN GOTO W 1536 IF Q$="8" THEN LET N=N+W 1537 IF Q$="5" THEN LET N=N-W 1538 IF NNN THEN GOTO W 1539 GOTO 1300 1540 PRINT AT T,O;"CHANGE? (- TO REDUCE STOCK)" 1550 INPUT Z 1560 LET Z=C+Z 1570 LET H=INT (Z/Q) 1580 LET D$(N,3)=CHR$ (Z-Q*H) 1590 LET D$(N,4)=CHR$ H 1595 GOTO 1300 1600 PRINT AT T,O;"NEW RE-ORDER LEVEL?" 1610 INPUT Z 1620 LET H=INT (Z/Q) 1630 LET D$(N,5)=CHR$ (Z-Q*H) 1640 LET D$(N,6)=CHR$ H 1645 GOTO 1300 1650 PRINT AT T,O;"NEW UNIT VALUE ($)?" 1655 INPUT Z 1660 LET Z=Z*FC 1665 LET H=INT (Z/Q) 1670 LET D$(N,7)=CHR$ (Z-Q*H) 1671 LET Z=H 1672 LET H=INT (Z/Q) 1673 LET D$(N,8)=CHR$ (Z-Q*H) 1675 LET D$(N,9)=CHR$ H 1695 GOTO 1300 1700 PRINT AT T,O;"ENTER ""XXX % %E%N%T%E%R% "" TO DELETE." 1710 INPUT Q$ 1720 IF Q$<>"XXX" THEN GOTO W 1730 GOTO 200 1800 PRINT AT T,O;"ENTER NEW TEXT." 1810 INPUT Q$ 1820 LET Q$=Q$+D$(N,NE+W TO ) 1830 LET D$(N,NE+W TO )=Q$ 1840 GOTO 1300 2000 PRINT AT 6,O;"OPTIONS:",,,, 2010 PRINT "%1: FIND/ADD/DELETE A LINE." 2040 PRINT "%2: PRINT STOCK LIST." 2090 PRINT ,,"%0: SAVE DATA ON TAPE." 2100 PRINT AT T-W,O;O$;O$ 2110 PRINT AT T,O;"CHOOSE AN OPTION." 2120 PAUSE 4E4 2130 LET X=CODE INKEY$-28 2140 IF X3 THEN GOTO 2110 2150 IF X=O THEN GOTO 600 2160 IF X=W THEN GOTO 1000 2170 IF X=2 THEN GOTO 3000 2200 GOTO W 2500 CLS 2510 PRINT "LIST IS FULL (";MAX;"LINES)." 2520 PRINT AT T,O;"PRESS A KEY TO CONTINUE." 2530 PAUSE 4E4 2540 GOTO W 3000 CLS 3010 PRINT "THE LIST CAN INCLUDE:",,, 3020 PRINT "%1: SUPPLIER AND TYPE." 3030 PRINT "%2: RE-ORDER LEVEL." 3035 PRINT "%3: TEXT." 3036 PRINT ,,"%(%O%T%H%E%R%): RETURN TO MASTER MENU." 3040 PRINT AT T,O;"CHOOSE AN OPTION." 3050 PAUSE 4E4 3060 LET L=CODE INKEY$-29 3070 IF LW+W THEN GOTO W 3100 CLS 3110 PRINT " PRINT LIST :",,,, 3120 PRINT "%1: OF ALL LINES." 3130 PRINT "%2: FOR A SUPPLIER." 3140 PRINT "%3: FOR A GIVEN TYPE OF LINE." 3150 PRINT "%4: OF UNDERSTOCKED LINES." 3155 PRINT ,,"%(%O%T%H%E%R%): RETURN TO MASTER MENU." 3160 PRINT AT T,O;"CHOOSE AN OPTION." 3170 PAUSE 4E4 3180 LET X=CODE INKEY$-28 3181 IF X<=O OR X>4 THEN GOTO W 3182 CLS 3183 PRINT T$ 3184 LPRINT T$ 3185 LET Q$="LINE ST MIN VAL." 3186 IF NOT L THEN LET Q$(19 TO 24)="SU TY " 3187 IF L=W+W THEN LET Q$="" 3188 PRINT ,,Q$ 3189 LPRINT ,,Q$,,, 3190 LET V=O 3200 LET U=W 3201 LET Y=NN 3204 PRINT AT T,O;"START NO.? (OPTIONAL)" 3205 INPUT Q$ 3206 IF Q$<>"" THEN LET U=VAL Q$ 3208 PRINT AT T,O;"END " 3209 INPUT Q$ 3210 IF Q$<>"" THEN LET Y=VAL Q$ 3213 PRINT AT T,O;O$ 3214 PRINT AT 3,O 3215 IF X=2 THEN GOTO 3300 3216 IF X=3 THEN GOTO 3350 3217 IF X=4 THEN GOTO 3500 3218 FOR N=U TO Y 3219 GOSUB 40 3220 GOSUB 46 3225 LET V=V+C*E/FC 3230 NEXT N 3240 PRINT 3241 LPRINT 3242 LET Q$="TOTAL VALUE = $"+STR$ V 3243 PRINT Q$ 3245 LPRINT Q$ 3248 PRINT AT T,O;"PRESS A KEY TO CONTINUE." 3250 PAUSE 4E4 3290 GOTO O 3310 LET Q$="SUPPLIER" 3320 LET Z=W 3330 GOTO 3400 3350 LET Q$="TYPE" 3360 LET Z=2 3400 PRINT AT T,O;Q$;" CODE?" 3402 INPUT X 3404 PRINT AT T,O;O$ 3406 PRINT AT W,O;Q$;" ";X 3407 LPRINT Q$;" ";X,,,, 3408 PRINT AT 3,O 3420 FOR N=U TO Y 3430 IF CODE D$(N,Z)<>X THEN GOTO 3460 3440 GOSUB 40 3450 GOSUB 46 3455 LET V=V+C*E/FC 3460 NEXT N 3470 GOTO 3240 3500 CLS 3501 LET Q$="UNDERSTOCKED LINES." 3502 PRINT Q$,,,,, 3503 LPRINT Q$,,,,, 3510 FOR N=U TO Y 3520 GOSUB 43 3530 IF C>=D THEN GOTO 3560 3540 GOSUB 40 3550 GOSUB 46 3555 LET V=V+C*E/FC 3560 NEXT N 3570 GOTO 3240 7000 CLS 7001 PRINT "% % % %H%I%L%D%E%R%B%A%Y% %S%T%O%C%K% %C%O%N%T%R%O%L% %I% % % " 7002 POKE 22612,(PEEK 22612)+3 7003 FOR I=22613 TO 22621 7004 POKE I,0 7005 NEXT I 7007 PRINT AT T,O;"NAME LENGTH (CHARACTERS)?" 7008 INPUT N 7009 POKE 16557,N 7010 PRINT AT T,O;"TEXT" 7011 INPUT D 7012 POKE 16558,D 7013 LET M=INT ((PEEK (16386)-PEEK (16412)+Q*(PEEK (16387)-PEEK 16413)-2*(Q+N+D))/(9+N+D)) 7014 POKE 16559,M-Q*INT (M/Q) 7015 POKE 16560,INT (M/Q) 7017 CLS 7018 CLEAR 7020 DIM D$(PEEK (16559)+256*PEEK 16560,9+PEEK (16557)+PEEK 16558) 7021 LET MAX=PEEK (16559)+256*PEEK 16560 7022 LET NL=PEEK 16557 7023 LET ND=PEEK 16558 7024 PRINT ,,,,"LIST WILL ACCOMODATE ";MAX;" LINES" 7025 LET FL=9+NL+ND 7026 LET NN=0 7027 LET O=NN 7028 LET T=21 7075 PRINT AT T,O;"ENTER TITLE FOR NEW LIST " 7080 INPUT T$ 7086 DIM E$(FL) 7095 LET O$=" " 7096 LET Q=256 7097 LET W=1 7099 LET R=16396 7170 LET FC=1000 7180 LET NS=10 7190 LET NE=NS+NL-W 7200 LET NF=NE+ND 7300 GOTO W 0 REM 757677ED4B9840ED5B9A40ED6B9C40EDB8C91B1B1B1B804A524652ED4B9840ED5B9A40ED6B9C40EDB0C91B1B1B1B1B1B 1 REM STOCK CONTROL. (C) HILDERBAY LTD 1981 2 CLS 0 REM 75767710281102D2E31292A3727263E031392901D25241D 0 PRINT "% % % % % % % % % % %S%T%O%C%K% %C%O%N%T%R%O%L% % % % % % % % % %(%C%)% %H%I%L%D%E%R%B%A%Y% %1%9%8%1% % %0%1%-%4%8%5% %1%0%5%9% ",,,, 15 PRINT AT 20,0;"% % % %P%R%O%G%R%A%M% %H%A%S% %B%E%E%N% %C%O%R%R%U%P%T%E%D% % % %O%R% %D%A%T%A% %D%E%L%E%T%E%D%.% %L%O%A%D% %F%R%O%M% %T%A%P%E%." 16 IF PEEK R<>030 THEN STOP 17 PRINT AT 4,O;T$,,,, 29 GOTO 2000 30 FOR I=A TO T 32 PRINT AT I,O;O$ 34 NEXT I 36 RETURN 90 IF NN>=MAX THEN GOTO 4000 91 IF N>NN THEN GOTO 130 92 LET AD=8+PEEK (16400)+Q*PEEK 16401 93 LET A=FL*(NN-N+W) 94 LET B=AD+FL*NN-W 96 LET C=AD+FL*(NN+W)-W 98 GOSUB 500 100 RAND USR 16517 130 LET D$(N)=E$ 140 LET NN=NN+W 150 GOTO 1300 200 LET AD=8+PEEK (16400)+Q*PEEK 16401 240 LET N=N-W 260 LET A=FL*(NN-N) 270 LET B=AD+FL*(N+W) 280 LET C=AD+(FL*N) 290 GOSUB 500 300 RAND USR 16542 310 LET NN=NN-W 350 GOTO O 500 POKE 16536,A-Q*INT (A/Q) 510 POKE 16537,INT (A/Q) 520 POKE 16538,C-Q*INT (C/Q) 530 POKE 16539,INT (C/Q) 540 POKE 16540,B-Q*INT (B/Q) 550 POKE 16541,INT (B/Q) 560 RETURN 600 CLS 610 PRINT "ENTER NAME FOR NEW TAPE FILE, START RECORDING, THEN % %E%N%T%E%R% ." 620 PRINT ,,"% %E%N%T%E%R% ONLY TO RETURN TO MENU." 630 INPUT Q$ 640 IF Q$<>"" THEN SAVE Q$ 650 GOTO O 1000 CLS 1010 PRINT AT T,O;"ENTER LINE NUMBER." 1020 INPUT X 1045 IF NOT NN THEN GOTO 1210 1050 LET LO=W 1060 LET HI=NN 1070 LET N=INT (.50001*(LO+HI)) 1080 LET Z=CODE D$(N,W)+Q*CODE D$(N,2) 1090 IF Z=X THEN GOTO 1300 1095 IF HI=LO OR HI=LO+W THEN GOTO 1200 1100 IF ZZ THEN LET N=HI+W 1210 CLS 1211 PRINT "LINE ";X;" IS NOT IN THE LIST, AND WILL BE ADDED." 1215 LET H=INT (X/Q) 1217 LET E$(W)=CHR$ (X-Q*H) 1218 LET E$(2)=CHR$ H 1220 PRINT AT T,O;"LINE ";X;" STOCK?" 1225 INPUT C 1230 LET H=INT (C/Q) 1235 LET E$(3)=CHR$ (C-Q*H) 1240 LET E$(4)=CHR$ H 1242 IF NOT NN THEN GOTO 1260 1244 GOTO 90 1260 LET D$(W)=E$ 1265 LET NN=W 1270 LET N=W 1300 CLS 1310 PRINT "LINE ";X;TAB 28;N 1320 LET C=CODE D$(N,3)+Q*CODE D$(N,4) 1390 PRINT ,,"STOCK=";C 1430 PRINT AT 8,O;"OPTIONS:",,,,"%1: ENTER STOCK CHANGE." 1450 PRINT "%2: DELETE THIS LINE." 1455 PRINT ,,"%(%O%T%H%E%R%): RETURN TO MASTER MENU." 1460 PRINT AT T,O;"ENTER AN OPTION." 1470 PAUSE 4E4 1480 LET Z=CODE INKEY$-28 1490 IF Z<=O OR Z>2 THEN GOTO W 1500 IF NOT Z THEN GOTO W 1510 LET A=8 1520 GOSUB 30 1535 IF Z=2 THEN GOTO 1700 1540 PRINT AT T,O;"CHANGE? (- TO REDUCE STOCK)" 1550 INPUT Z 1560 LET C=C+Z 1570 LET H=INT (C/Q) 1580 LET D$(N,3)=CHR$ (C-Q*H) 1590 LET D$(N,4)=CHR$ H 1595 GOTO 1300 1700 PRINT AT T,O;"ENTER ""XXX % %E%N%T%E%R% "" TO DELETE." 1710 INPUT Q$ 1720 IF Q$<>"XXX" THEN GOTO W 1730 GOTO 200 2000 PRINT AT 6,O;"OPTIONS:",,,, 2010 PRINT "%1: FIND/ADD/DELETE A LINE." 2040 PRINT "%2: PRINT STOCK LIST." 2090 PRINT ,,"%0: SAVE DATA ON TAPE." 2100 PRINT AT T-W,O;O$;O$ 2110 PRINT AT T,O;"CHOOSE AN OPTION." 2120 PAUSE 4E4 2130 LET X=CODE INKEY$-28 2140 IF X<0 OR X>3 THEN GOTO 2110 2150 IF X=O THEN GOTO 600 2160 IF X=W THEN GOTO 1000 2170 IF X=2 THEN GOTO 3000 2200 GOTO W 3000 CLS 3010 PRINT AT T,O;"START NO.? (OPTIONAL)" 3020 LET A=W 3030 INPUT Q$ 3040 IF Q$<>"" THEN LET A=VAL Q$ 3050 PRINT AT T,O;"END " 3060 LET B=NN 3065 INPUT Q$ 3070 IF Q$<>"" THEN LET B=VAL Q$ 3074 PRINT AT T,O;O$ 3080 PRINT AT T,O;"HEADING?" 3090 INPUT Q$ 3095 LPRINT T$ 3100 CLS 3110 LPRINT ,,Q$ 3120 LPRINT 3190 LPRINT "LINE","STOCK" 3200 FOR N=A TO B 3220 PRINT CODE D$(N,W)+Q*CODE D$(N,2),CODE D$(N,3)+Q*CODE D$(N,4) 3221 LPRINT CODE D$(N,W)+Q*CODE D$(N,2),CODE D$(N,3)+Q*CODE D$(N,4) 3230 NEXT N 3248 PRINT AT T,O;"PRESS A KEY TO CONTINUE." 3250 PAUSE 4E4 3290 GOTO O 4000 CLS 4010 PRINT T$ 4020 PRINT "FILE ALREADY CONTAINS ";NN,"LINES - NO MORE ALLOWED." 4030 PRINT AT T,O;"PRESS A KEY TO CONTINUE." 4040 PAUSE 4E4 4050 GOTO W 7000 CLS 7002 PRINT "% % % %H%I%L%D%E%R%B%A%Y% %S%T%O%C%K% %C%O%N%T%R%O%L% %I%I% % % " 7004 POKE 19709,(PEEK 19709)+3 7005 FOR I=19710 TO 19719 7006 POKE I,0 7008 NEXT I 7017 CLEAR 7018 DIM D$(62*(PEEK (16389)-89),4) 7019 LET MAX=62*(PEEK (16389)-89) 7020 LET T=21 7030 LET O=0 7040 PRINT ,,"LIST OF ";MAX;" LINES IN ";INT (.25*PEEK (16389)-15.3);"K." 7075 PRINT AT T,O;"ENTER TITLE FOR LIST " 7080 INPUT T$ 7081 LET N=0 7084 LET FL=4 7090 DIM E$(FL) 7095 LET O$=" " 7096 LET Q=256 7097 LET W=1 7098 LET NN=O 7099 LET R=16396 7300 GOTO W ```