Inventory

This file is part of and Synchro-Sette December 1982. Download the collection to get this file.
Date: December 1982
Type: Program
Platform(s): TS 1000
Tags: Business

This program implements a stock inventory management system storing up to 100 items in a two-dimensional string array, with each record occupying a fixed 32-character row divided into named fields: item name (columns 1–8), part number (10–15), unit cost (17–22), items per unit (24–27), and units in stock (29–32). The main menu uses inverse-video characters for labels and an animated prompt loop at line 180 that flickers between inverse and normal text to attract attention. Field formatting is handled by subroutines at lines 8000–8230 that pad strings with leading spaces or append missing decimal places to ensure fixed-width storage. Navigation uses computed GOTO destinations (e.g. `GOTO 1000*VAL B$` and `GOTO (VAL B$*200)+2100`) to dispatch menu choices, a common ZX81/TS1000 space-saving technique. The program saves its data array to tape using a user-supplied filename and uses `RUN` at line 4020 to perform a full data clear.


Program Analysis

Program Structure

The program is organised into several functional regions, each entered via computed GOTO from a menu:

Line RangeFunction
10–260Initialisation and main menu (options 1–4)
1000–1540Enter / add inventory items
2000–2820View data sub-menu and sub-functions (total view, change stock, view item)
2900–2999Edit item data sub-function
3000–3080Save data to tape
4000–4020Clear all data (via RUN)
8000–8960Shared formatting and editing subroutines
9000–9030Scroll 10 lines subroutine
9800–9830“Press ENTER to continue” pause subroutine
9998–9999Save program with auto-run flag

Data Storage Layout

All inventory data is stored in the array A$, dimensioned at line 10 as DIM A$(100,32). Each of the 100 rows holds exactly one item record with fields packed at fixed character positions:

ColumnsFieldWidth
1–8Item name / description8
10–15Part / stock number6
17–22Unit cost (£/$ value)6
24–27Items per unit4
29–32Units in stock4

Columns 9, 16, 23, and 28 serve as implicit spacers between fields, being left at their initialised space characters. This means a raw PRINT A$(N) produces a readable formatted line matching the column header "NAME PART NO. COST IT/UN IN/S".

The counter R1 (initialised to 0 at line 11) tracks the number of records entered. It is updated at line 1520 (LET R1=N-1) when item entry ends, and used as the loop bound whenever all records are iterated.

Menu Navigation and Computed GOTO

Both the main menu (line 260) and the data sub-menu (line 2260) use computed GOTO to dispatch on a single keypress. The main menu uses GOTO 1000*VAL B$, mapping keys 1–4 to lines 1000, 2000, 3000, and 4000. The data sub-menu uses GOTO (VAL B$*200)+2100, mapping keys 1–4 to lines 2300, 2500, 2700, and 2900. In both cases only keys with CODE values 29–32 (the digits 1–4 in ZX81 character encoding) are accepted, checked at lines 220 and 2220.

The edit sub-menu at line 2975 uses GOTO 8500+(100*VAL B$), dispatching to the four field-edit routines at 8600, 8700, 8800, and 8900.

Formatting Subroutines

Three subroutines handle string padding and decimal normalisation to keep field widths exact:

  • Line 8000 – Currency format fix: if the last character before the final digit is "." (one decimal place), appends "0"; if the last three characters contain no "." at position −2, appends ".00". This ensures cost strings always carry two decimal places.
  • Line 8100 – Left-pads B$ with spaces to a total width of 6 (for the cost field).
  • Line 8200 – Left-pads B$ with spaces to a total width of 4 (for items-per-unit and units-in-stock fields).

The separator line Z$ is pre-built at line 12 as a 64-character string of alternating inverse and normal hyphens and spaces, used as a visual rule under column headers.

Screen Layout Technique

The background fill at lines 40–60 (main menu) and 2030–2050 (data menu) prints alternating inverse-space and normal-space characters by looping PRINT "% % % % % % % % "; (using % as the zmakebas escape for inverse space) to produce a chequerboard pattern across the entire screen. This is done in FAST mode before switching to SLOW for interactive use.

The flicker prompt at line 180 (and 2180) prints the same screen position three times in succession: first inverse, then normal, then inverse again, creating a brief visual flash to draw attention to the prompt area without requiring a timing loop.

POKE 16418,0 (lines 30 and 2020) sets the system variable FRAMES low byte, and POKE 16418,2 (lines 240 and 2240) restores it; this is used here to control display timing rather than machine code.

Stock Search Logic

Part-number searches (lines 2520–2540, 2730–2740, 2930–2940) use a partial-match technique: IF A$(N,10 TO 9+LEN B$)=B$. This compares only as many characters as the user typed, allowing prefix searches. The loop exits on the first match; if no match is found, the program falls through to an error message.

At line 2560 the search loop jumps to line 2560 on a match, but that line does not exist in the listing — the execution will fall through to line 2660 instead, which is the intended display-and-confirm block. This is the well-known technique of targeting a non-existent line to land on the next available line.

Stock Adjustment (Lines 8400–8540)

The change-inventory routine uses a variable named AT for both the menu choice (add=1, take=2) and subsequently for the quantity to add or subtract, reusing the same variable for two different purposes within the same routine. After the operation, the numeric result is converted back to a string via STR$, padded to 4 characters if necessary, and written directly back into A$(N,29 TO 32).

Notable Bugs and Anomalies

  • At line 8010, the decimal-format check IF B$(LEN B$-2)<>"." will cause a subscript error if B$ has fewer than three characters (e.g. a single-digit cost like "5"), because LEN B$-2 would be zero or negative. This could crash the program on very short cost strings.
  • Line 2560 does not exist; the search GOSUBs jump there but execution continues at line 2660. This is intentional (a non-existent target line trick) and works correctly.
  • At line 1145, after a part number is entered that is too long, the program GOTOs line 1135 (the SLOW statement before the INPUT), which is correct but relies on the SLOW/INPUT pair being adjacent.
  • The SAVE C$ at line 3050 saves only the program, not the A$ data array. To preserve inventory data across sessions, the user would need to rely on the auto-run save at line 9998 (SAVE "INVENTOR%Y") which also only saves the program; the array data would be lost on reload. There is no SAVE DATA or equivalent for the array.
  • The edit sub-menu at line 2965 only offers four options (name, stock no., cost, items/unit) — there is no option to edit units in stock via this path; that is only accessible through the change-inventory flow.

Content

Appears On

Cassette to accompany the December 1982 issue of Synchro-Sette.

Related Products

Related Articles

Related Content

Image Gallery

Source Code

  10 DIM A$(100,32)
  11 LET R1=0
  12 LET Z$="%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-%-"
  20 FAST 
  25 CLS 
  30 POKE 16418,0
  40 FOR N=1 TO 96
  50 PRINT "% % % % % % % % ";
  60 NEXT N
  70 PRINT AT 2,6;" INVENTORY PROGRAM "
  80 PRINT AT 5,1;"%T%O% %E%N%T%E%R% %I%T%E%M%S";TAB 26;"%-% %1"
  90 PRINT AT 7,1;"%T%O% %S%E%E% %A%L%L% %D%A%T%A";TAB 26;"%-% %2"
 100 PRINT AT 9,1;"%T%O% %S%A%V%E% %D%A%T%A% %O%N% %T%A%P%E";TAB 26;"%-% %3"
 110 PRINT AT 11,1;"%T%O% %C%L%E%A%R% %A%L%L% %D%A%T%A";AT 11,26;"%-% %4"
 180 PRINT AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:";AT 22,4;"ENTER ONE OF ABOVE :::";AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:"
 190 SLOW 
 200 LET B$=INKEY$
 210 IF B$="" THEN GOTO 180
 220 IF CODE B$<29 OR CODE B$>32 THEN GOTO 180
 230 FAST 
 240 POKE 16418,2
 250 CLS 
 260 GOTO 1000*VAL B$
 1000 FOR N=R1+1 TO 100
 1010 GOSUB 9000
 1020 PRINT "WHAT IS THE NAME OR DESCRIPTION"
 1030 SCROLL 
 1040 PRINT "OF ITEM NO. ";N;" (8 CHAR. MAX.)"
 1050 SCROLL 
 1055 SLOW 
 1060 INPUT B$
 1065 FAST 
 1070 IF B$="" THEN GOTO 1500
 1080 LET A$(N, TO 8)=B$
 1090 PRINT A$(N)
 1100 GOSUB 9000
 1110 SCROLL 
 1120 PRINT "WHAT IS THE PART NO. (6 CHAR MAX"
 1130 SCROLL 
 1135 SLOW 
 1140 INPUT B$
 1142 FAST 
 1145 IF LEN B$>6 THEN GOTO 1135
 1150 LET A$(N,10 TO 15)=B$
 1160 PRINT A$(N)
 1170 GOSUB 9000
 1190 PRINT "COST PER UNIT?"
 1200 SCROLL 
 1205 SLOW 
 1210 INPUT B$
 1212 FAST 
 1214 IF VAL B$>999.99 THEN GOTO 8300
 1216 GOSUB 8000
 1218 IF LEN B$<6 THEN GOSUB 8100
 1220 SCROLL 
 1230 LET A$(N,17 TO 22)=B$
 1240 PRINT A$(N)
 1250 GOSUB 9000
 1260 PRINT "ITEMS PER UNIT?"
 1270 SCROLL 
 1275 SLOW 
 1280 INPUT B$
 1285 FAST 
 1290 IF LEN B$>4 THEN GOTO 1275
 1300 SCROLL 
 1310 IF LEN B$<4 THEN GOSUB 8200
 1320 LET A$(N,24 TO 27)=B$
 1330 PRINT A$(N)
 1340 GOSUB 9000
 1350 PRINT "UNITS IN STOCK?"
 1355 SLOW 
 1360 INPUT B$
 1365 FAST 
 1370 IF LEN B$>4 THEN GOTO 1355
 1374 IF LEN B$=4 THEN GOTO 1390
 1376 FOR I=1 TO 4-LEN B$
 1380 LET B$=" "+B$
 1385 NEXT I
 1390 SCROLL 
 1400 LET A$(N,29 TO 32)=B$
 1410 PRINT A$(N)
 1420 NEXT N
 1500 FAST 
 1510 CLS 
 1520 LET R1=N-1
 1530 SLOW 
 1540 GOTO 20
 1999 STOP 
 2000 FAST 
 2010 CLS 
 2020 POKE 16418,0
 2030 FOR N=1 TO 192
 2040 PRINT "% % % % ";
 2050 NEXT N
 2060 PRINT AT 2,7;" INVENTORY DATA "
 2070 PRINT AT 5,1;"%T%O% %S%E%E% %T%O%T%A%L% %I%N%V%E%N%T%O%R%Y";TAB 28;"%-% %1"
 2080 PRINT AT 7,1;"%T%O% %C%H%A%N%G%E% %I%N%V%E%N%T%O%R%Y";TAB 28;"%-% %2"
 2090 PRINT AT 9,1;"%T%O% %S%E%E% %I%T%E%M% %D%A%T%A";TAB 28;"%-% %3"
 2100 PRINT AT 11,1;"%T%O% %E%D%I%T% %D%A%T%A% %I%T%E%M%S";TAB 28;"%-% %4"
 2180 PRINT AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:";AT 22,4;"ENTER ONE OF ABOVE :::";AT 22,4;"%E%N%T%E%R% %O%N%E% %O%F% %A%B%O%V%E% %:%:%:"
 2190 SLOW 
 2200 LET B$=INKEY$
 2210 IF B$="" THEN GOTO 2180
 2220 IF CODE B$<29 OR CODE B$>32 THEN GOTO 2180
 2230 FAST 
 2240 POKE 16418,2
 2250 CLS 
 2260 GOTO (VAL B$*200)+2100
 2300 SLOW 
 2310 FOR N=1 TO R1
 2320 SCROLL 
 2340 SCROLL 
 2350 PRINT "NAME    PART NO. COST IT/UN IN/S" 
 2360 SCROLL 
 2365 PRINT Z$
 2370 SCROLL 
 2380 PRINT A$(N)
 2382 SCROLL 
 2384 SCROLL 
 2386 SCROLL 
 2388 NEXT N
 2390 PRINT "PRESS ENTER TO CONTINUE :::"
 2392 INPUT B$
 2395 GOTO 20
 2500 PRINT AT 10,0;"WHAT IS THE STOCK NO. OF ITEM?"
 2505 SLOW 
 2510 INPUT B$
 2515 FAST 
 2520 FOR N=1 TO R1
 2525 FAST 
 2530 IF A$(N,10 TO 9+LEN B$)=B$ THEN GOTO 2560
 2540 NEXT N
 2542 CLS 
 2544 GOSUB 9000
 2546 PRINT "STOCK NO. NOT IN FILE :::"
 2547 GOSUB 9000
 2548 GOSUB 9800
 2550 GOTO 20
 2660 FAST 
 2662 CLS 
 2664 GOSUB 9000
 2666 PRINT "NAME    PART NO. COST IT/UN IN/S" 
 2668 SCROLL 
 2670 PRINT Z$
 2672 SCROLL 
 2674 PRINT A$(N)
 2676 GOSUB 9000
 2678 PRINT AT 21,0;"IS THIS THE CORRECT STOCK NO.?"
 2679 SLOW 
 2680 INPUT Y$
 2682 FAST 
 2683 IF Y$(1)="N" THEN GOTO 2540
 2684 SCROLL 
 2685 SCROLL 
 2686 PRINT "ADD TO (1) OR TAKE FROM (2)?"
 2687 SLOW 
 2688 INPUT AT
 2689 FAST 
 2690 IF AT>2 OR AT<1 THEN GOTO 2687
 2695 GOTO 8400
 2700 CLS 
 2705 PRINT AT 10,1;"WHAT IS THE STOCK NO.?"
 2710 SLOW 
 2715 INPUT B$
 2720 FAST 
 2725 IF LEN B$>6 THEN GOTO 2710
 2730 FOR N=1 TO R1
 2735 IF A$(N,10 TO 9+LEN B$)=B$ THEN GOTO 2760
 2740 NEXT N
 2745 SCROLL 
 2750 PRINT TAB 16-((LEN B$)/2);B$
 2755 GOTO 2544
 2760 CLS 
 2765 PRINT ,,"STOCK NAME -";TAB 24;A$(N, TO 8)
 2770 PRINT ,,"STOCK NO. -";TAB 26;A$(N,10 TO 15)
 2775 PRINT ,,"UNIT COST -";TAB 26;A$(N,17 TO 22)
 2780 PRINT ,,"ITEMS/UNIT -";TAB 28;A$(N,24 TO 27)
 2785 PRINT ,,"UNITS IN STOCK -";TAB 28;A$(N,29 TO 32)
 2790 PRINT ,,"COST OF TOTAL UNITS - $";
 2795 LET B=(VAL A$(N,17 TO 22)*VAL A$(N,29 TO 32))
 2800 LET B$=STR$ B
 2805 GOSUB 8000
 2810 PRINT B$
 2815 GOSUB 9800
 2820 GOTO 20
 2900 CLS 
 2905 PRINT AT 10,1;"WHAT IS THE STOCK NO.?"
 2910 SLOW 
 2915 INPUT B$
 2920 FAST 
 2925 IF LEN B$>6 THEN GOTO 2910
 2930 FOR N=1 TO R1
 2935 IF A$(N,10 TO 9+LEN B$)=B$ THEN GOTO 2950
 2940 NEXT N
 2945 GOTO 2745
 2950 CLS 
 2955 PRINT ,,"NAME    PART NO. COST IT/UN IN/S" 
 2960 PRINT Z$;A$(N)
 2965 PRINT ,,,,"<1> NAME","<3> COST","<2> STK. NO.","<4> ITEMS/UNIT",,,,"CHOOSE ONE?"
 2967 SLOW 
 2970 INPUT B$
 2972 FAST 
 2974 IF CODE B$<29 OR CODE B$>32 THEN GOTO 2967
 2975 GOTO 8500+(100*VAL B$)
 2999 GOTO 2999
 3000 FAST 
 3002 CLS 
 3006 PRINT AT 10,10;"FILE NAME?"
 3010 SLOW 
 3020 INPUT C$
 3030 PRINT AT 12,0;"PREPARE THE RECORDER AND THEN   PRESS ENTER :::"
 3040 INPUT B$
 3050 SAVE C$
 3060 FAST 
 3070 CLS 
 3080 GOTO 20
 4000 FAST 
 4010 CLS 
 4020 RUN 
 8000 IF B$(LEN B$-1)="." THEN LET B$=B$+"0"
 8010 IF B$(LEN B$-2)<>"." THEN LET B$=B$+".00"
 8020 RETURN 
 8100 FOR I=1 TO 6-LEN B$
 8110 LET B$=" "+B$
 8120 NEXT I
 8130 RETURN 
 8200 FOR I=1 TO 4-LEN B$
 8210 LET B$=" "+B$
 8220 NEXT I
 8230 RETURN 
 8300 SCROLL 
 8310 SCROLL 
 8320 PRINT "COST CANNOT EXCEED 999.00"
 8340 SCROLL 
 8350 GOTO 1170
 8400 SCROLL 
 8410 SCROLL 
 8420 IF AT=1 THEN GOTO 8500
 8430 PRINT "HOW MANY TO BE TAKEN AWAY?"
 8435 SLOW 
 8440 INPUT AT
 8445 FAST 
 8450 LET TA=VAL A$(N,29 TO 32)
 8455 LET TA=TA-AT
 8460 LET B$=STR$ TA
 8470 IF LEN B$<4 THEN GOSUB 8200
 8472 LET A$(N,29 TO 32)=B$
 8475 SCROLL 
 8480 SCROLL 
 8481 PRINT "NAME    PART NO. COST IT/UN IN/S" 
 8482 SCROLL 
 8483 PRINT Z$
 8484 SCROLL 
 8485 PRINT A$(N)
 8486 GOSUB 9000
 8487 GOTO 2390
 8500 PRINT "HOW MANY TO BE ADDED?"
 8510 SLOW 
 8520 INPUT AT
 8525 FAST 
 8530 LET TA=VAL A$(N,29 TO 32)
 8535 LET TA=TA+AT
 8540 GOTO 8460
 8600 PRINT ,,"WHAT IS THE NEW NAME?"
 8610 SLOW 
 8620 INPUT B$
 8630 FAST 
 8640 IF LEN B$>8 THEN GOTO 8610
 8650 LET A$(N, TO 8)=B$
 8660 PRINT ,,"NAME    PART NO. COST IT/UN IN/S";Z$;A$(N) 
 8670 GOSUB 9800
 8680 GOTO 20
 8700 PRINT ,,"WHAT IS THE NEW STOCK NO.?"
 8710 SLOW 
 8720 INPUT B$
 8730 FAST 
 8740 IF LEN B$>6 THEN GOTO 8710
 8750 LET A$(N,10 TO 15)=B$
 8760 GOTO 8660
 8800 PRINT ,,"WHAT IS THE NEW COST?"
 8810 SLOW 
 8820 INPUT B$
 8830 FAST 
 8840 IF LEN B$>6 THEN GOTO 8810
 8842 GOSUB 8000
 8844 IF LEN B$<6 THEN GOSUB 8100
 8850 LET A$(N,17 TO 22)=B$
 8860 GOTO 8660
 8900 PRINT ,,"WHAT IS THE NEW AMOUNT OF ITEMS PER UNIT?"
 8910 SLOW 
 8920 INPUT B$
 8930 FAST 
 8940 IF LEN B$>4 THEN GOTO 8910
 8945 IF LEN B$<4 THEN GOSUB 8200
 8950 LET A$(N,24 TO 27)=B$
 8960 GOTO 8660
 9000 FOR I=1 TO 10
 9010 SCROLL 
 9020 NEXT I
 9030 RETURN 
 9800 PRINT AT 21,0;"PRESS ENTER TO CONTINUE :::"
 9810 INPUT B$
 9820 CLS 
 9830 RETURN 
 9998 SAVE "INVENTOR%Y"
 9999 RUN 

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

People

No people associated with this content.

Scroll to Top