--- title: "Omni Template Rev. 1" id: 71993 type: "computer_media" slug: "omni-template-rev-1" url: "http://localhost/computer_media/omni-template-rev-1/" markdown_url: "http://localhost/computer_media/omni-template-rev-1.md" published_at: "2026-10-20T14:07:45+00:00" modified_at: "2026-10-20T14:14:06+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/10/FITPOINTS.png" excerpt: "A structured-programming template with named utility subroutines for titles, keypresses, number formatting, sorting and menus, plus three example programs built from it." 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: "Omni Technology" slug: "omni-technology" taxonomy: "post_tag" url: "http://localhost/tag/omni-technology/" - 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/" indiv: - name: "Mimi Cho" slug: "mimi-cho" taxonomy: "indiv" url: "http://localhost/indiv/mimi-cho/" genre: - name: "Programming" slug: "programming" taxonomy: "genre" url: "http://localhost/type/programming/" media_type: "Cassette" programmers: - name: "Mimi Cho" slug: "mimi-cho" taxonomy: "indiv" url: "http://localhost/indiv/mimi-cho/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Omni%20Template%20Rev%201%20%28198x%29%28Cho%2C%20Mimi%29%28TS1000%29%28US%29%28Cassette%29.zip" mediadate: "198x" producer_company: - id: 11147 title: "Omni Technology" type: "company" url: "http://localhost/company/omni-technology/" images: - url: "http://localhost/wp-content/uploads/2026/10/FITPOINTS.png" - url: "http://localhost/wp-content/uploads/2026/10/RACING0.png" - url: "http://localhost/wp-content/uploads/2026/10/CALCULATOR.png" - url: "http://localhost/wp-content/uploads/2026/10/OmniTemplate-scaled.png" - url: "http://localhost/wp-content/uploads/2026/10/Omni-Template-scaled.jpg" related_products: - id: 13470 title: "Omni Template" type: "product" url: "http://localhost/product/omni-template/" media_type_tags: "Programming" --- # Omni Template Rev. 1 Provides a skeleton for writing structured BASIC programs: a header block for the program name and description, a definition block for arrays and documented variables, a program block, a user-routine block and a library of utility subroutines. Each routine’s line number is stored in a named variable such as `TITLE`, `GETKEY` or `SORT`, so code calls them with `GOSUB TITLE` rather than a bare number. The utilities center a title, wait for a single keypress, format a number to a set of decimal places, sort a value array along with an index array, and show a numbered menu. Three example programs built from the template are on the tape: a formula calculator, a least-squares curve fitter and a lap-time ranking program. The printed cassette label reads “OMNI TEMPLATE REV. 1” with a handwritten “<135>”, and each program opens with the REM header “OMNI TEMPLATE REV.1 BY MIMI CHO”. A period advertisement from Omni Technology of Pittsburgh, Pennsylvania offered the tape for the ZX80 and ZX81 at $9.50 before September 1, 1982, with a listing and manual, and named RACING, INDEX-CARDS and FIT-POINTS as the example programs. This tape has a CALCULATOR example in place of INDEX-CARDS. The tape files are: - `TEMPLATE`: the blank template, with empty REM lines left in every block for the user to fill. - `CALCULATOR` (saved as `CACULATOR`): reads a formula as a string and evaluates it with `VAL`, printing the result. - `FITPOINTS`: takes up to 50 X,Y pairs and fits a straight line, a semi-log (`Y=A*EXP(B*X)`) or a log-log (`Y=A*X**B`) curve by least squares, reporting A, B, the correlation coefficient and standard error, then interpolates Y for entered X values. - `RACING`: takes IDs and three lap times for up to 20 participants and ranks them by any lap or by total time in a formatted table. ## Program Analysis ### Program Structure Line numbers are fixed by block: 5–45 header, 1000–1300 definitions (arrays at 1015, string variables A$–Z$ at 1050–1175, numerics after 1185), 1500–1700 routine-address assignments, 2000 main program, 3995 `STOP` as `END`, 4000 user routines, and 7000 onward the utilities (`TITLE` 7100, `GETKEY` 7200, `NUMFORMAT` 7300, `SORT` 7500, `MENU` 7700). The example programs fill in the REM placeholders, add their own named routines (for instance `GETDATA`, `CALC`, `OUTRESULT`, `INTERPOLATION`, `STRAIGHT`, `SEMILOG`, `LOGLOG` in FITPOINTS) and customize the menu text. ### Notable Techniques - Computed `GOSUB`/`GOTO` through long variable names (`GOSUB GETDATA`, `GOTO END`) makes the main program read like a list of procedure calls. - The `GETKEY` routine first waits for all keys to be released, then for a new key, avoiding auto-repeat from a held key. - `TITLE` centers a string with `PRINT AT 0,16-0.5*LEN T$`. - The sort carries an index array `I()` alongside the values `R()`, so RACING can rank records without moving the name and lap arrays. - FITPOINTS fits the curved models by taking `LN` of the data and reusing the linear least-squares routine, then converting A back with `EXP`. - Long data-entry loops clear the screen every few entries (`(I/9)-INT (I/9)`) to avoid the scroll prompt. - `FAST` around calculations and sorting, `SLOW` for display. ### Potential Issues - In the blank template the bubble sort compares `R(I)` with `(I+1)` rather than `R(I+1)`; RACING has the corrected line. - CALCULATOR’s sort routine is a different, Shell-style version that never ends its inner loop (`J` is incremented without a bound check). CALCULATOR does not call it. - `NUMFORMAT` reports a decimal point error when `DECIM` is 0 even though the next lines handle that case, computes the fraction as `INTNUM-INNUM` (negative), and its padding lines `LET V$=""+V$` add nothing. - In FITPOINTS the log-log result is labeled `Y=EXP (A)*X**B`, but A has already been converted with `EXP` before display. - RACING returns to the menu with `GOTO 2011`, a line that does not exist; the ZX81 continues at the next line, 2015, which is the intended effect. ## Source Code ``` 5 REM OMNI TEMPLATE REV.1 10 REM BY 15 REM MIMI CHO 20 REM ======================== 25 REM PROGRAM NAME: 30 REM PROGRAM DESCRIPTION: 35 REM 40 REM 45 REM 1000 REM ======================= 1005 REM DEFINITION BLOCK 1010 REM ----------------------- 1015 REM ARRAY 1020 REM 1025 REM 1030 REM 1035 REM 1040 REM ----------------------- 1045 REM STRING VARIABLES 1050 REM UTILITY 1055 REM B$= 1060 REM C$= 1065 REM D$= 1070 REM E$= 1075 REM F$= 1080 REM G$=INPUT FOR <GET KEY> 1085 REM H$= 1090 REM I$= 1095 REM J$= 1100 REM K$= 1105 REM L$= 1110 REM M$= 1115 REM N$= 1120 REM O$= 1125 REM P$= 1130 REM Q$= 1135 REM R$= 1140 REM S$= 1145 REM T$=TITLE FOR <TITLE> 1150 REM U$= 1155 REM V$=FORMATTED STRING FROM<NUMFORMAT> 1160 REM W$= 1165 REM X$= 1170 REM Y$= 1175 REM Z$= 1180 REM ----------------------- 1185 REM NUMERIC VARIABLES 1190 REM I=TEMP 1195 REM J= 1200 REM K= 1205 REM L= 1210 REM M= 1215 REM INTNUM <NUMFORMAT> 1220 REM SIZE <NUMFORMAT> 1225 REM PRTNUM <NUMFORMAY> 1230 REM SORTDIR <SORT> 1235 REM SORTFLAG<SORT> 1240 REM 1245 REM 1250 REM 1255 REM 1260 REM 1265 REM 1270 REM 1275 REM 1280 REM 1285 REM 1290 REM 1295 REM 1300 REM 1500 REM ----------------------- 1505 REM DEFINITION OF SUBROUTINES(MODULES) 1510 REM ----------- 1515 REM <TITLE> UTILITY 1520 REM CLEARS SCREEN THEN PUTS TITLE AT TOP CENTER 1525 LET TITLE=7100 1530 REM -------- 1535 REM <GETKEY> UTILITY 1540 REM GET SINGLE CHARACTER FROM KEYBOARD.RETURNS IN G$ 1545 LET GETKEY=7200 1550 REM ------- 1555 REM <NUMFORMAT> UTILITY 1560 REM FORMATS NUMBER WITH DECIMAL PLACES.RETURNS IN V$ 1565 LET NUMFORMAT=7300 1570 REM -------- 1575 REM <SORT> UTILITY 1580 REM SORTS IN SORTDIRECTION;+1:UPWARD 1585 REM -1:DOWNWARD 1590 REM UNSORTED R(N)AND I(N)=>SORTED R(N)AND I(N) 1595 LET SORT=7500 1600 REM ------- 1605 REM <MENU>UTILITY 1610 REM DISPLAYS A MENU AND SELECTION 1615 REM IS RETURNED BY G$<GETKEY> 1620 LET MENU=7700 1625 REM --------- 1630 REM <END> 1635 LET END=3995 1640 REM -------- 1645 REM <MAIN> 1650 LET MAIN=2000 1655 REM --------- 1660 REM 1665 REM 1670 REM 1675 REM 1680 REM 1685 REM 1690 REM 1695 REM 1700 REM 2000 REM ======================= 2005 REM PROGRAM BLOCK 2010 REM 2015 REM 2020 REM 2025 REM 2030 REM 2035 REM 2040 REM 2045 REM 2050 REM 2055 REM 2060 REM 2065 REM 2070 REM 2075 REM 2080 REM 2085 REM 2090 REM 3995 STOP 4000 REM ======================= 4005 REM USER ROUTINE BLOCK 4010 REM 4015 REM 4020 REM 4025 REM 4030 REM 4035 REM 4040 REM 4045 REM 4050 REM 4055 REM 4060 REM 4065 REM 4070 REM 4075 REM 4080 REM 4085 REM 4090 REM 4095 REM 4100 REM 7000 REM ======================= 7005 REM UTILITY ROUTINE BLOCK 7100 REM -------- 7105 REM <TITLE>ROUTINE (T$->CLS,SHOW T$) 7110 CLS 7115 IF LEN T$>32 THEN GOTO 7130 7120 PRINT AT 0,16-0.5*LEN T$;T$ 7125 GOTO 7135 7130 PRINT T$ 7135 RETURN 7200 REM --------- 7205 REM <GETKEY> ROUTINE(->G$) 7210 IF INKEY$ <>"" THEN GOTO 7210 7215 IF INKEY$ ="" THEN GOTO 7215 7220 LET G$=INKEY$ 7225 RETURN 7300 REM --------- 7310 LET V$="" 7315 IF DECIM>0 THEN GOTO 7330 7320 PRINT "DECIMAL POINT ERROR" 7325 GOTO 7395 7330 LET INTNUM=INT (INNUM) 7335 IF DECIM<>0 THEN GOTO 7350 7340 LET V$=STR$ (INTNUM) 7345 GOTO 7380 7350 LET FRTNUM=(INTNUM-INNUM)*10**DECIM 7355 LET V$=STR$ (FRTNUM) 7360 FOR I=1 TO DECIM-LEN (V$) 7365 LET V$=""+V$ 7370 NEXT I 7375 LET V$=STR$ (INTNUM)+"."+V$ 7380 FOR I=1 TO SIZE-LEN (V$) 7385 LET V$=""+V$ 7390 NEXT I 7395 RETURN 7500 REM --------- 7505 REM <SORT> UTILITY 7510 FAST 7515 IF SORTDIR=1 THEN GOTO 7525 7520 LET SORTDIR=-1 7525 LET SORTFLAG=0 7530 FOR I=1 TO N-1 7535 IF SORTDIR*R(I)<=SORTDIR*(I+1) THEN GOTO 7575 7540 LET T=R(I) 7545 LET R(I)=R(I+1) 7550 LET R(I+1)=T 7555 LET T=I(I) 7560 LET I(I)=I(I+1) 7565 LET I(I+1)=T 7570 LET SORTFLAG=1 7575 NEXT I 7580 IF SORTFLAG=1 THEN GOTO 7525 7585 SLOW 7590 RETURN 7700 REM ---------- 7705 REM <MENU>ROUTINE(->=>G$) 7710 REM TITLE 7715 LET T$="" 7720 GOSUB TITLE 7725 PRINT 7730 PRINT " 1. " 7735 PRINT " 2. " 7740 PRINT " 3. " 7745 PRINT " 4. " 7750 PRINT " 5. " 7755 PRINT " 6. " 7760 PRINT " 7. QUIT " 7765 PRINT 7770 PRINT " ENTER SELECTION >" 7775 GOSUB GETKEY 7780 IF (VAL (G$)>0) AND (VAL (G$)<8) THEN GOTO 7790 7785 GOTO 7775 7790 RETURN 7795 REM -------- 7800 REM ```