Omni Template Rev. 1

Products: Omni Template
Developer(s): Mimi Cho
Date: 198x
Type: Cassette
Platform(s): TS 1000

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.

Related Products

Template program for developing other programs.

Image Gallery

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 <TITLE> 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

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