Manufacturing Control

Date: 1982
Type: Cassette
Platform(s): TS 1000
Tags: Business

Manufacturing Control is a bill-of-materials and shop-floor cost management system that stores up to 150 records in a 150×49 character string array. Each record packs part number, department, operation, labor cost, material cost, overhead cost, where-used linkage, quantity per assembly, scrap factor, hours per thousand, and part type (Detail or Assembly) into fixed-width substrings of a single row in R$. The program provides a nine-option menu covering record add, delete, file listing, total cost computation, per-part cost computation, bill-of-materials explosion (finding all components of a parent), and implosion (finding all parents of a component). Numeric fields are stored and retrieved as strings using STR$ and VAL, and the scrap factor is applied during cost rollups with the formula QX=(SC*(Q*NP))+(Q*NP).


Program Analysis

Program Structure

The program is organized as a dispatch loop: lines 20–180 initialize global variables, display a splash screen, and then repeatedly call the menu subroutine at line 1000, branching to one of nine functional subroutines based on the value of C. The main loop at line 999 (GOTO 90) re-enters the menu after each operation. Line 180 handles option 9 as a STOP.

Line RangeFunction
20–180Initialization, splash screen, dispatch loop
1000–1122Menu display and input
1500–1999Add record (calls 1520, 2000, 3000)
2000–2040Pad P$, D$, O$ to fixed widths
2500–2999Delete record (blank first byte)
3000–3499Write record into R$ array
3500–3999List file (all non-blank records)
4000–4010Assembly stub: zero M, fall into cost input at 1610
4500–4799Compute total costs across all records
5500–5999Compute costs for a specific part number
6000–6020Pause/continue subroutine (also supports ‘Q’ to return to menu)
6500–6699BOM explosion (find components of a parent)
7500–7799BOM implosion (find parents of a component)
8500–8600Save data to tape, restart

Data Storage Layout

All data is held in R$(150,49), a two-dimensional string array of 150 rows, each 49 characters wide. Fields are packed into fixed-width subcolumns using substring slicing. Numeric values are stored as strings via STR$ and decoded with VAL on retrieval. A record is considered deleted when its first byte is set to a space (R$(N,1 TO 1)=" ").

ColumnsWidthField
1–55Part number (P$)
6–94Department (D$)
10–134Operation (O$)
14–196Labor cost/hour (L)
20–256Material cost/1000 (M)
26–316Overhead cost/hour (H)
32–365Where-used parent part (W$)
37–382Quantity per assembly (NP)
39–435Scrap factor (SC)
44–485Hours per 1000 (HP)
491Type: D=Detail, A=Assembly (E$)

Key BASIC Idioms

  • Fixed-width string padding is applied in subroutine 2000: short inputs are extended with trailing spaces using concatenation, e.g. LET P$=P$+" ", ensuring substring slicing always works correctly.
  • The line 3040 LET R$(N,14 TO 19)=STR$ L illustrates the pattern of embedding numeric values in string records; all cost and quantity fields are stored this way.
  • Inverse-video text (e.g. "%M%E%N%U%") is used for headings, labels, and status messages throughout, giving a highlighted appearance on screen.
  • The SLOW/FAST mode switches are placed around computation-heavy loops to maximize performance during file scans and revert to display-quality mode for output.
  • The pause subroutine at line 6000 doubles as a menu-exit shortcut: entering “Q” triggers GOTO 90, returning to the main dispatch loop without unwinding the call stack normally.

Cost Computation

The scrap-adjusted quantity formula used in both total-cost (line 4528) and part-cost (line 5607) routines is:

QX = (SC * (Q * NP)) + (Q * NP)

This computes the gross quantity needed including scrap loss. Labor and overhead costs are then multiplied by hours per 1000 (HP) since the rates are expressed per hour. All costs are normalized to a base of 1000 parts, and the part-cost routine accepts an arbitrary quantity Q which is divided by 1000 at line 5555 before use.

BOM Explosion and Implosion

Explosion (option 6, subroutine 6500) searches all records where the where-used field (R$(N,32 TO 36)) matches the entered parent part number, listing all immediate children. Implosion (option 7, subroutine 7500) does the reverse: it searches for records whose part number field (R$(N,1 TO 5)) matches the entered part, and displays which parent assembly it belongs to from its where-used field. Neither routine performs recursive multi-level traversal; they are single-level lookups only.

Notable Techniques and Anomalies

  • The LC counter (line counter) at lines 3522–3524, 6590–6592, and 7620–7622 tracks printed records and calls the pause subroutine after every 3 records to prevent screen scroll overflow. However, LC is not reset inside the listing loops themselves — it is only reset in the pause subroutine at line 6015. This means if the user does not press “Q” mid-listing, paging works correctly, but if the subroutine is called at the end of a listing with LC not equal to 3, the extra GOSUB 6000 at the end of each listing routine still provides a final pause.
  • The Assembly add path (option 1 with E$=”A”) skips the material cost input at line 1635 (IF E$="A" THEN GOTO 1670), leaving M=0 as set at line 4004. This is intentional: assemblies typically have no direct material cost.
  • The delete routine at line 2550 only blanks the first byte of a record (R$(N,1 TO 1)=" "), leaving the rest of the data in memory. This is a deliberate soft-delete: the file search routines treat any record with a blank first byte as an empty slot.
  • Line 1120 branches to 1090 on invalid menu input — an efficient re-prompt that redisplays from the “8=SAVE DATA” line rather than the full menu, saving screen redraws.
  • The SAVE S$ at line 8580 saves the entire program including the populated R$ array, providing a simple but effective data persistence mechanism without any separate data file handling.
  • The STR$ conversion at lines 3040–3090 does not guarantee fixed-width output — a short numeric result from STR$ will be left-aligned in its field with no padding. This can cause misalignment when VAL reads back a substring that contains part of an adjacent field’s data, though in practice the fixed-column slicing keeps fields isolated as long as numbers don’t exceed their allotted widths.

Content

Appears On

Related Products

Comprehensive manufacturing system that lets you analyze labor and material costs for up to 150 products. Ideal for small businesses...

Related Articles

Related Content

Image Gallery

Manufacturing Control

Source Code

  20 DIM R$(150,49)
  22 LET XJ=150
  25 LET TL=0
  27 LET TM=0
  28 LET TH=0
  30 LET LC=0
  40 SLOW 
  50 PRINT AT 10,10;"TS1000"
  60 PRINT AT 11,7;"MANUFACTURING"
  70 PRINT AT 12,7;"CONTROL SYSTEM"
  80 GOSUB 6000
  90 GOSUB 1000
 100 IF C=1 THEN GOSUB 1500
 110 IF C=2 THEN GOSUB 2500
 120 IF C=3 THEN GOSUB 3500
 130 IF C=4 THEN GOSUB 4500
 140 IF C=5 THEN GOSUB 5500
 150 IF C=6 THEN GOSUB 6500
 160 IF C=7 THEN GOSUB 7500
 170 IF C=8 THEN GOSUB 8500
 180 IF C=9 THEN STOP 
 999 GOTO 90
 1000 REM MENU
 1010 CLS 
 1020 PRINT AT 2,0;"%M%E%N%U% %S%E%L%E%C%T%I%O%N% %P%A%N%E%L"
 1030 PRINT AT 4,4;"1=ADD PART/DEPT/OPER"
 1040 PRINT AT 6,4;"2=DELETE PART/DEPT/OPER"
 1050 PRINT AT 8,4;"3=LIST FILE"
 1060 PRINT AT 10,4;"4=COMPUTE TOTAL COSTS"
 1070 PRINT AT 12,4;"5=COMPUTE PART COST"
 1080 PRINT AT 14,4;"6=EXPLODE PART"
 1085 PRINT AT 16,4;"7=IMPLODE PART"
 1090 PRINT AT 18,4;"8=SAVE DATA"
 1095 PRINT AT 20,4;"9=QUIT"
 1100 PRINT "%E%N%T%E%R% %O%P%T%I%O%N% %C%O%D%E"
 1110 INPUT C
 1115 PRINT AT 21,20;C
 1120 IF C<1 OR C>9 THEN GOTO 1090
 1122 RETURN 
 1500 REM ADD
 1510 CLS 
 1515 GOSUB 1520
 1517 GOTO 1744
 1520 PRINT "ENTER PART NO. 5 DIGITS"
 1530 INPUT P$
 1540 PRINT P$
 1550 PRINT "ENTER DEPT  4 DIGITS"
 1560 INPUT D$
 1570 PRINT D$
 1580 PRINT "ENTER OPERATION  4 DIGITS"
 1590 INPUT O$
 1600 PRINT O$
 1602 GOSUB 2000
 1605 RETURN 
 1610 PRINT "I/P LABOR COST/HOUR--6 DIGITS"
 1620 INPUT L
 1630 PRINT L
 1635 IF E$="A" THEN GOTO 1670
 1640 PRINT "I/P MATERIAL COST/1000--6 DIGITS"
 1650 INPUT M
 1660 PRINT M
 1670 PRINT "I/P OVERHEAD COST/HOUR--6 DIGITS"
 1682 INPUT H
 1684 PRINT H
 1686 PRINT "I/P SCRAP FACTOR--3 DEC. DIGITS"
 1687 INPUT SC
 1688 PRINT SC
 1690 PRINT "I/P HOURS/1000 - 5 DIGITS"
 1692 INPUT HP
 1694 PRINT HP
 1700 PRINT "ENTER WHERE USED 5 DIGITS"
 1710 INPUT W$
 1720 PRINT W$
 1722 LET W=LEN W$
 1725 IF W<5 THEN LET W$=W$+"           "
 1730 PRINT "ENTER NO. PER ASSY"
 1740 INPUT NP
 1742 PRINT NP
 1743 GOTO 1752
 1744 PRINT "ENTER D = DETAIL OR A = ASSY"
 1746 INPUT E$
 1748 PRINT E$
 1749 IF E$="D" THEN GOTO 1610
 1750 GOTO 4000
 1752 FAST 
 1753 CLS 
 1760 FOR N=1 TO XJ
 1765 IF P$(1 TO 5)=R$(N,1 TO 5) AND D$(1 TO 4)=R$(N,6 TO 9) AND O$(1 TO 4)=R$(N,10 TO 13) THEN GOTO 1800
 1770 NEXT N
 1790 PRINT "%R%E%C%O%R%D% %A%D%D%E%D"
 1792 GOSUB 3000
 1796 GOTO 1998
 1800 SLOW 
 1810 PRINT "%R%E%C%O%R%D ALREADY EXISTS"
 1820 PRINT 
 1830 PRINT "YOU MADE AN ERROR"
 1840 PRINT 
 1842 PRINT "PRESS %E%N%T%E%R"
 1850 INPUT Y$
 1998 SLOW 
 1999 RETURN 
 2000 REM 
 2002 LET P=LEN P$
 2010 IF P<5 THEN LET P$=P$+"           "
 2012 LET D=LEN D$
 2020 IF D<4 THEN LET D$=D$+"    "
 2025 LET O=LEN O$
 2030 IF O<4 THEN LET O$=O$+"    "
 2040 RETURN 
 2500 REM DEL
 2505 CLS 
 2510 GOSUB 1520
 2515 FAST 
 2520 FOR N=1 TO XJ
 2530 IF P$(1 TO 5)=R$(N,1 TO 5) AND D$(1 TO 4)=R$(N,6 TO 9) AND O$(1 TO 4)=R$(N,10 TO 13) THEN GOTO 2550
 2540 NEXT N
 2550 CLS 
 2555 LET R$(N,1 TO 1)=" "
 2560 PRINT "RECORD DELETED"
 2565 SLOW 
 2570 GOSUB 6000
 2580 GOTO 2999
 2999 RETURN 
 3000 REM 
 3002 FOR N=1 TO XJ
 3004 IF R$(N,1 TO 1)=" " THEN GOTO 3010
 3006 NEXT N
 3008 PRINT "SORRY-FILE FULL"
 3009 GOTO 3100
 3010 LET R$(N,1 TO 5)=P$
 3020 LET R$(N,6 TO 9)=D$
 3030 LET R$(N,10 TO 13)=O$
 3040 LET R$(N,14 TO 19)=STR$ L
 3050 LET R$(N,20 TO 25)=STR$ M
 3052 LET R$(N,26 TO 31)=STR$ H
 3060 LET R$(N,32 TO 36)=W$
 3070 LET R$(N,37 TO 38)=STR$ NP
 3080 LET R$(N,39 TO 43)=STR$ SC
 3090 LET R$(N,44 TO 48)=STR$ HP
 3092 LET R$(N,49 TO 49)=E$
 3100 GOSUB 6000
 3499 RETURN 
 3500 REM CHANGE
 3504 FAST 
 3505 CLS 
 3506 FOR N=1 TO XJ
 3508 IF R$(N,1 TO 1)=" " THEN GOTO 3600
 3509 PRINT "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
 3510 PRINT "%P%A%R%T ";R$(N,1 TO 5);" %D%E%P%T ";R$(N,6 TO 9)
 3512 PRINT "%O%P%E%R ";R$(N,10 TO 13);" %L%A%B%O%R ";R$(N,14 TO 19)
 3514 PRINT "%M%A%T%L ";R$(N,20 TO 25);" %O%V%H%D ";R$(N,26 TO 31)
 3515 PRINT "%U%S%E%D ";R$(N,32 TO 36);" %Q%T%Y%/%P%E%R ";R$(N,37 TO 38)
 3517 PRINT "%S%C%R%A%P ";R$(N,39 TO 43);" %H%O%U%R%S ";R$(N,44 TO 48)
 3519 PRINT "%T%Y%P%E ";R$(N,49 TO 49)
 3522 LET LC=LC+1
 3524 IF LC=3 THEN GOSUB 6000
 3600 NEXT N
 3610 SLOW 
 3700 GOSUB 6000
 3999 RETURN 
 4000 REM 
 4004 LET M=0
 4010 GOTO 1610
 4500 REM 
 4501 LET TT=0
 4502 LET TL=0
 4503 LET TM=0
 4504 LET TH=0
 4505 FAST 
 4507 LET Q=1
 4510 FOR N=1 TO XJ
 4520 IF R$(N,1 TO 1)=" " THEN GOTO 4700
 4525 LET SC=VAL R$(N,39 TO 43)
 4527 LET NP=VAL R$(N,37 TO 38)
 4528 LET QX=(SC*(Q*NP)+(Q*NP))
 4530 LET TL=TL+(QX*(VAL R$(N,14 TO 19)*VAL R$(N,44 TO 48)))
 4540 LET TM=TM+(QX*VAL R$(N,20 TO 25))
 4550 LET TH=TH+(QX*(VAL R$(N,26 TO 31)*VAL R$(N,44 TO 48)))
 4560 LET TT=TT+(QX*VAL R$(N,44 TO 48))
 4700 NEXT N
 4710 CLS 
 4712 SLOW 
 4720 PRINT 
 4730 PRINT "%T%O%T%A%L% %L%A%B%O%R = ";TL
 4740 PRINT "%T%O%T%A%L% %M%A%T%E%R%I%A%L = ";TM
 4744 PRINT "%T%O%T%A%L% %O%V%E%R%H%E%A%D = ";TH
 4746 PRINT "%T%O%T%A%L% %H%O%U%R%S = ";TT
 4748 PRINT 
 4749 PRINT "ALL ABOVE BASED ON 1000 PARTS"
 4750 GOSUB 6000
 4799 RETURN 
 5500 REM 
 5502 LET TL=0
 5504 LET TM=0
 5505 LET TT=0
 5506 LET TH=0
 5510 CLS 
 5520 PRINT "ENTER QTY TO BE MADE"
 5530 INPUT Q
 5540 PRINT Q
 5550 PRINT 
 5555 LET Q=Q/1000
 5560 PRINT "ENTER PART NO."
 5570 INPUT P$
 5580 PRINT P$
 5581 FAST 
 5582 GOSUB 2000
 5585 FOR N=1 TO XJ
 5600 IF P$(1 TO 5)<>R$(N,1 TO 5) AND P$(1 TO 5)<>R$(N,32 TO 36) THEN GOTO 5700
 5605 LET SC=VAL R$(N,39 TO 43)
 5606 LET NP=VAL R$(N,37 TO 38)
 5607 LET QX=(SC*Q*NP)+Q*NP
 5610 LET TL=TL+(QX*(VAL R$(N,14 TO 19)*VAL R$(N,44 TO 48)))
 5620 LET TM=TM+(QX*VAL R$(N,20 TO 25))
 5630 LET TH=TH+(QX*(VAL R$(N,26 TO 31)*VAL R$(N,44 TO 48)))
 5632 LET TT=TT+(QX*VAL R$(N,44 TO 48))
 5700 NEXT N
 5710 SLOW 
 5740 PRINT "%T%O%T%A%L% %E%X%T%.% %L%A%B%O%R =";TL
 5750 PRINT "%T%O%T%A%L% %E%X%T%.% %M%A%T%L =";TM
 5760 PRINT "%T%O%T%A%L% %E%X%T%.% %O%V%H%D =";TH
 5762 PRINT "%T%O%T%A%L% %E%X%T%.% %H%O%U%R%S =";TT
 5780 GOSUB 6000
 5999 RETURN 
 6000 PRINT AT 21,0;"%P%R%E%S%S% %E%N%T%E%R% OR ENTER A Q"
 6010 INPUT Y$
 6011 IF Y$="Q" THEN SLOW 
 6012 IF Y$="Q" THEN GOTO 90
 6015 LET LC=0
 6017 CLS 
 6020 RETURN 
 6500 REM 
 6510 CLS 
 6520 PRINT "ENTER PART TO BE EXPLODED"
 6530 INPUT W$
 6535 PRINT W$
 6536 LET W=LEN W$
 6538 IF W<5 THEN LET W$=W$+"          "
 6540 FAST 
 6550 FOR N=1 TO XJ
 6560 IF R$(N,1 TO 1)=" " THEN GOTO 6600
 6570 IF W$(1 TO 5)<>R$(N,32 TO 36) THEN GOTO 6600
 6575 PRINT "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
 6580 PRINT R$(N,32 TO 36);"---";"%P%A%R%T ";R$(N,1 TO 5)
 6582 PRINT "%D%E%P%T ";R$(N,6 TO 9)
 6584 PRINT "%O%P%E%R ";R$(N,10 TO 13)
 6586 PRINT "%Q%T%Y%/%P%E%R ";R$(N,37 TO 38)
 6588 PRINT "%T%Y%P%E ";R$(N,49 TO 49)
 6590 LET LC=LC+1
 6592 IF LC=3 THEN GOSUB 6000
 6600 NEXT N
 6605 SLOW 
 6610 GOSUB 6000
 6699 RETURN 
 7500 REM 
 7510 CLS 
 7520 PRINT "ENTER PART TO BE IMPLODED"
 7530 INPUT P$
 7540 PRINT P$
 7550 GOSUB 2000
 7555 FAST 
 7560 FOR N=1 TO XJ
 7570 IF P$(1 TO 5)<>R$(N,1 TO 5) THEN GOTO 7700
 7580 PRINT "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"
 7590 PRINT R$(N,1 TO 5);"---";" %U%S%E%D ";R$(N,32 TO 36)
 7600 PRINT "%D%E%P%T ";R$(N,6 TO 9)
 7610 PRINT "%O%P%E%R ";R$(N,10 TO 13)
 7612 PRINT "%Q%T%Y%/%P%E%R  ";R$(N,37 TO 38)
 7614 PRINT "%T%Y%P%E ";R$(N,49 TO 49)
 7620 LET LC=LC+1
 7622 IF LC=3 THEN GOSUB 6000
 7700 NEXT N
 7705 SLOW 
 7710 GOSUB 6000
 7799 RETURN 
 8500 REM 
 8510 CLS 
 8520 PRINT "ENTER NAME OF FILE"
 8530 INPUT S$
 8540 PRINT S$
 8550 PRINT "SET RECORDER FOR SAVE MODE"
 8560 PRINT "PRESS ENTER WHEN READY"
 8570 INPUT Y$
 8580 SAVE S$
 8590 CLS 
 8600 GOTO 40

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

People

No people associated with this content.

Scroll to Top