/*
Sheet for Nascom Basic
v1.0, tfurrows@sdf.org, tfurrows@grex.org
A simple "spreadsheet" of sorts, for manipulating numbers on a nascom basic
machine. Written on Grant's simple z80. This is not excel, or even visicalc
or sc; instead, this is just a way to enter, save, visualize, and perform a few
functions on tabular numbers.
Notes:
- The basic.asm from Grant Searle's simple z80 sets the columns byte in memory
to 28, giving 3 columns. You can set this by poking 14*(n-1) to 8328, where n
is the number of columns you want. This program uses 5 columns to maintain
compatibility with my 80 col terminal. A few variables must also be changed
if you want to change the number of columns.
- 100 rows max. Grant's 56k z80 could handle a lot more I believe.
- CLS doesn't clear my term, though it works on my virtual term. I use the
escape sequence instead.
- Command prompt:
? - help
l - load from tape
s - save to tape
r - review sheet (full)
rr - review row
rc - review col
e - edit value (col,row)
f - functions sub-menu
- Functions prompt:
? - context specific help
- Variable list (most, I think):
CR - col/row array of data
CM$ - command prompt input (string)
HR$ - horizontal line
PV$ - name/version string
LI$ - line input
IC - input column
IR - input row
V - value
SF - free string space
RF - RAM free
MR - max row (last row with user input data)
N, N1, N2, etc - number, for/next iterator, misc use
I - number, for counting/breaks, general use
BC - bottom right column input
BR - bottom right row input
A, A1, A2, etc - answer(s) of function
- Subroutines:
PRINTROW - print a row, N must be set
COLHEAD - print the column headers
- Memory:
Some (512b) string space reserved, not sure what for
10 REM Column test, to see if CL columns fit on a terminal
11 REM pokes to default 3 col at run, draws 3 rows for each
15 POKE 8328,28
19 PRINT "3 rows of 3 columns"
20 FOR N=1 to 9
25 PRINT "[***********]",
30 NEXT N
35 CL=5
40 POKE 8328,14*(CL-1)
45 PRINT:PRINT "3 rows of";CL;"columns"
50 FOR N=1 to CL*3
55 PRINT "[***********]",
60 NEXT N
*/
PRINT CHR$(27);"[2J"
CLEAR 512
WIDTH 79
POKE 8328,56
DIM CR(5,100)
PV$="NB Sheet 1.0"
HR$="=========="
SF=FRE("")
MR=0
PRINT PV$
PRINT "? for help."
REM [MAIN]
PRINT HR$
CM$=""
INPUT "Command";CM$
IF CM$="e" THEN GOTO [EDIT VALUE]
IF CM$="f" THEN GOTO [FUNCTIONS]
IF CM$="r" THEN GOTO [REVIEW SHEET]
IF CM$="rr" THEN GOTO [REVIEW ROW]
IF CM$="rc" THEN GOTO [REVIEW COL]
IF CM$="l" THEN GOTO [LOAD]
IF CM$="s" THEN GOTO [SAVE]
IF CM$="?" THEN GOTO [HELP]
IF CM$="q" THEN GOTO [QUIT]
GOTO [MAIN]
REM [EDIT VALUE]
PRINT "[Edit Value]"
IC=0:IR=0
INPUT "Which Column,Row";IC,IR
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [MAIN]
IF IR<1 OR IR>100 THEN PRINT "!) Invalid row":GOTO [MAIN]
PRINT "Current: ";CR(IC,IR)
INPUT "New Value";CR(IC,IR)
IF IR>MR THEN MR=IR
GOTO [MAIN]
REM [REVIEW SHEET]
PRINT "[Review Sheet]"
IF MR=0 THEN PRINT "!) No values entered":GOTO [MAIN]
GOSUB [COLHEAD]
I=0:CM$=""
FOR N=1 to MR
PRINT N;CHR$(8);"]";
GOSUB [PRINTROW]
I=I+1
IF I=20 THEN I=0:INPUT "Continue (Y/n/c)";CM$
IF CM$="n" THEN GOTO [MAIN]
IF CM$="c" THEN I=21
NEXT N
GOTO [MAIN]
REM [REVIEW ROW]
PRINT "[Review Row]"
IF MR=0 THEN PRINT "!) No values entered":GOTO [MAIN]
N=0
INPUT "Which row";N
IF N<1 OR N>MR THEN PRINT "!) Invalid row":GOTO [MAIN]
GOSUB [COLHEAD]
PRINT N;CHR$(8);"]";
GOSUB [PRINTROW]
GOTO [MAIN]
REM [REVIEW COL]
PRINT "[Review Row]"
IF MR=0 THEN PRINT "!) No values entered":GOTO [MAIN]
IC=0
INPUT "Which column";IC
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [MAIN]
PRINT ,"[";IC;"]"
FOR N=1 to MR
PRINT N;CHR$(8);"]",
PRINT CR(IC,N)
I=I+1
IF I=20 THEN I=0:INPUT "Continue (Y/n/c)";CM$
IF CM$="n" THEN GOTO [MAIN]
IF CM$="c" THEN I=21
NEXT N
GOTO [MAIN]
REM [LOAD]
PRINT "[LOAD]"
IR=0
INPUT "Start loading into which row";IR
IF IR<1 OR IR>100 THEN PRINT "!) Invalid row":GOTO [MAIN]
PRINT "Type, paste, or PLAY values"
PRINT "Each line must have 4 commas"
PRINT "255,0,1,0,255 on a line to end."
PRINT HT$
REM [LOADPOINT]
IF IR>100 THEN PRINT "!) All rows full":GOTO [MAIN]
N=0:N1=0:N2=0:N3=0:N4=0
PRINT "Row";IR;CHR$(8);"]";
INPUT N,N1,N2,N3,N4
IF N=255 AND N1=0 AND N2=1 AND N3=0 AND N4=255 THEN GOTO [MAIN]
IF IR>MR THEN MR=IR
CR(1,IR)=N:CR(2,IR)=N1:CR(3,IR)=N2:CR(4,IR)=N3:CR(5,IR)=N4
IR=IR+1
GOTO [LOADPOINT]
REM [SAVE]
PRINT "[SAVE]"
IF MR=0 THEN PRINT "!) No values entered.":GOTO [MAIN]
CM$=""
PRINT "RECORD and then ENTER to list."
PRINT "When done, ENTER after stopping tape."
INPUT CM$
FOR N=1 to MR
PRINT CR(1,N);",";CR(2,N);",";CR(3,N);",";CR(4,N);",";CR(5,N)
FOR D=1 to 1000:NEXT D
NEXT N
PRINT " 255 , 0 , 1 , 0 , 255"
INPUT CM$
GOTO [MAIN]
REM [HELP]
RF=FRE(0):IF RF<0 THEN RF=65536+RF
PRINT HR$
PRINT PV$
PRINT
PRINT " Free Ram:";RF;"b / 56958 b"
PRINT " Free Str:";FRE("");"b /";SF;"b"
PRINT
PRINT "e) edit value f) functions sub-menu"
PRINT "r) review sheet rr) review row rc) review column"
PRINT "l) load s) save"
PRINT "q) quit"
PRINT
GOTO [MAIN]
REM [QUIT]
CM$=""
INPUT "Quit (y/N)";CM$
IF CM$="y" THEN END
GOTO [MAIN]
REM [FUNCTIONS]
IF MR=0 THEN PRINT "!) No values entered":GOTO [MAIN]
PRINT HR$
CM$=""
INPUT "Function";CM$
IF CM$="s" THEN GOTO [FSUM]
IF CM$="a" THEN GOTO [FAVG]
IF CM$="+" THEN GOTO [FMAX]
IF CM$="-" THEN GOTO [FMIN]
IF CM$="q" THEN GOTO [MAIN]
IF CM$="?" THEN GOTO [FHELP]
GOTO [FUNCTIONS]
REM [FSUM]
PRINT "[Func: Sum]"
IC=0:IR=0
INPUT "Top-left column,row";IC,IR
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
BC=0:BR=0
INPUT "Bottom-right column,row";BC,BR
IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
A=0
FOR N=IC TO BC
FOR N1=IR TO BR
A=A+CR(N,N1)
NEXT N1
NEXT N
PRINT
PRINT "Sum of [";IC;",";IR;"] to [";BC;",";BR;"] =";A
GOTO [FUNCTIONS]
REM [FAVG]
PRINT "[Func: Average]"
IC=0:IR=0
INPUT "Top-left column,row";IC,IR
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
BC=0:BR=0
INPUT "Bottom-right column,row";BC,BR
IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
A=0:A1=0
FOR N=IC TO BC
FOR N1=IR TO BR
A=A+CR(N,N1)
A1=A1+1
NEXT N1
NEXT N
PRINT
PRINT "Average of [";IC;",";IR;"] to [";BC;",";BR;"] =";A/A1
GOTO [FUNCTIONS]
REM [FMAX]
PRINT "[Func: Max]"
IC=0:IR=0
INPUT "Top-left column,row";IC,IR
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
BC=0:BR=0
INPUT "Bottom-right column,row";BC,BR
IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
A=0:A1=0:A2=0
FOR N=IC TO BC
FOR N1=IR TO BR
IF CR(N,N1)>A THEN A=CR(N,N1):A1=N:A2=N1
NEXT N1
NEXT N
PRINT
PRINT "Max val is [";A;"] in [";A1;",";A2;"]"
GOTO [FUNCTIONS]
REM [FMIN]
PRINT "[Func: Min]"
IC=0:IR=0
INPUT "Top-left column,row";IC,IR
IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
BC=0:BR=0
INPUT "Bottom-right column,row";BC,BR
IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO [FUNCTIONS]
IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO [FUNCTIONS]
A=CR(IC,IR):A1=IC:A2=IR
FOR N=IC TO BC
FOR N1=IR TO BR
IF CR(N,N1)5 THEN PRINT "!) Invalid column":GOTO 140
340 IF IR<1 OR IR>100 THEN PRINT "!) Invalid row":GOTO 140
350 PRINT "Current: ";CR(IC,IR)
360 INPUT "New Value";CR(IC,IR)
370 IF IR>MR THEN MR=IR
380 GOTO 140
400 REM [REVIEW SHEET]
410 PRINT "[Review Sheet]"
420 IF MR=0 THEN PRINT "!) No values entered":GOTO 140
430 GOSUB 2070
440 I=0:CM$=""
450 FOR N=1 to MR
460 PRINT N;CHR$(8);"]";
470 GOSUB 2074
480 I=I+1
490 IF I=20 THEN I=0:INPUT "Continue (Y/n/c)";CM$
500 IF CM$="n" THEN GOTO 140
510 IF CM$="c" THEN I=21
520 NEXT N
530 GOTO 140
550 REM [REVIEW ROW]
560 PRINT "[Review Row]"
570 IF MR=0 THEN PRINT "!) No values entered":GOTO 140
580 N=0
590 INPUT "Which row";N
600 IF N<1 OR N>MR THEN PRINT "!) Invalid row":GOTO 140
610 GOSUB 2070
620 PRINT N;CHR$(8);"]";
630 GOSUB 2074
640 GOTO 140
660 REM [REVIEW COL]
670 PRINT "[Review Row]"
680 IF MR=0 THEN PRINT "!) No values entered":GOTO 140
690 IC=0
700 INPUT "Which column";IC
710 IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO 140
720 PRINT ,"[";IC;"]"
730 FOR N=1 to MR
740 PRINT N;CHR$(8);"]",
750 PRINT CR(IC,N)
760 I=I+1
770 IF I=20 THEN I=0:INPUT "Continue (Y/n/c)";CM$
780 IF CM$="n" THEN GOTO 140
790 IF CM$="c" THEN I=21
800 NEXT N
810 GOTO 140
830 REM [LOAD]
840 PRINT "[LOAD]"
850 IR=0
860 INPUT "Start loading into which row";IR
870 IF IR<1 OR IR>100 THEN PRINT "!) Invalid row":GOTO 140
880 PRINT "Type, paste, or PLAY values"
890 PRINT "Each line must have 4 commas"
900 PRINT "255,0,1,0,255 on a line to end."
910 PRINT HT$
920 REM [LOADPOINT]
930 IF IR>100 THEN PRINT "!) All rows full":GOTO 140
940 N=0:N1=0:N2=0:N3=0:N4=0
950 PRINT "Row";IR;CHR$(8);"]";
960 INPUT N,N1,N2,N3,N4
970 IF N=255 AND N1=0 AND N2=1 AND N3=0 AND N4=255 THEN GOTO 140
980 IF IR>MR THEN MR=IR
990 CR(1,IR)=N:CR(2,IR)=N1:CR(3,IR)=N2:CR(4,IR)=N3:CR(5,IR)=N4
1000 IR=IR+1
1010 GOTO 920
1030 REM [SAVE]
1040 PRINT "[SAVE]"
1050 IF MR=0 THEN PRINT "!) No values entered.":GOTO 140
1060 CM$=""
1070 PRINT "RECORD and then ENTER to list."
1080 PRINT "When done, ENTER after stopping tape."
1090 INPUT CM$
1100 FOR N=1 to MR
1110 PRINT CR(1,N);",";CR(2,N);",";CR(3,N);",";CR(4,N);",";CR(5,N)
1115 FOR D=1 TO 1000:NEXT D
1120 NEXT N
1130 PRINT " 255 , 0 , 1 , 0 , 255"
1140 INPUT CM$
1150 GOTO 140
1170 REM [HELP]
1175 RF=FRE(0):IF RF<0 THEN RF=65536+RF
1180 PRINT HR$
1190 PRINT PV$
1200 PRINT
1210 PRINT " Free Ram:";RF;"b / 56958 b"
1220 PRINT " Free Str:";FRE("");"b /";SF;"b"
1230 PRINT
1240 PRINT "e) edit value f) functions sub-menu"
1250 PRINT "r) review sheet rr) review row rc) review column"
1260 PRINT "l) load s) save"
1270 PRINT "q) quit"
1280 PRINT
1290 GOTO 140
1310 REM [QUIT]
1320 CM$=""
1330 INPUT "Quit (y/N)";CM$
1340 IF CM$="y" THEN END
1350 GOTO 140
1390 REM [FUNCTIONS]
1400 IF MR=0 THEN PRINT "!) No values entered":GOTO [MAIN]
1410 PRINT HR$
1420 CM$=""
1430 INPUT "Function";CM$
1440 IF CM$="s" THEN GOTO 1520
1450 IF CM$="a" THEN GOTO 1720
1460 IF CM$="+" THEN GOTO 1930
1470 IF CM$="-" THEN GOTO 2040
1480 IF CM$="q" THEN GOTO 140
1490 IF CM$="?" THEN GOTO 2060
1500 GOTO 1390
1520 REM [FSUM]
1530 PRINT "[Func: Sum]"
1540 IC=0:IR=0
1550 INPUT "Top-left column,row";IC,IR
1560 IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO 1390
1570 IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO 1390
1580 BC=0:BR=0
1590 INPUT "Bottom-right column,row";BC,BR
1600 IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO 1390
1610 IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO 1390
1620 A=0
1630 FOR N=IC TO BC
1640 FOR N1=IR TO BR
1650 A=A+CR(N,N1)
1660 NEXT N1
1670 NEXT N
1680 PRINT
1690 PRINT "Sum of [";IC;",";IR;"] to [";BC;",";BR;"] =";A
1700 GOTO 1390
1720 REM [FAVG]
1730 PRINT "[Func: Average]"
1740 IC=0:IR=0
1750 INPUT "Top-left column,row";IC,IR
1760 IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO 1390
1770 IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO 1390
1780 BC=0:BR=0
1790 INPUT "Bottom-right column,row";BC,BR
1800 IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO 1390
1810 IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO 1390
1820 A=0:A1=0
1830 FOR N=IC TO BC
1840 FOR N1=IR TO BR
1850 A=A+CR(N,N1)
1860 A1=A1+1
1870 NEXT N1
1880 NEXT N
1890 PRINT
1900 PRINT "Average of [";IC;",";IR;"] to [";BC;",";BR;"] =";A/A1
1910 GOTO 1390
1930 REM [FMAX]
1940 PRINT "[Func: Max]"
1950 IC=0:IR=0
1960 INPUT "Top-left column,row";IC,IR
1970 IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO 1390
1980 IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO 1390
1990 BC=0:BR=0
2000 INPUT "Bottom-right column,row";BC,BR
2010 IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO 1390
2020 IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO 1390
2030 A=0:A1=0:A2=0
2031 FOR N=IC TO BC
2032 FOR N1=IR TO BR
2033 IF CR(N,N1)>A THEN A=CR(N,N1):A1=N:A2=N1
2034 NEXT N1
2035 NEXT N
2036 PRINT
2037 PRINT "Max val is [";A;"] in [";A1;",";A2;"]"
2038 GOTO 1390
2040 REM [FMIN]
2041 PRINT "[Func: Min]"
2042 IC=0:IR=0
2043 INPUT "Top-left column,row";IC,IR
2044 IF IC<1 OR IC>5 THEN PRINT "!) Invalid column":GOTO 1390
2045 IF IR<1 OR IR>MR THEN PRINT "!) Invalid row":GOTO 1390
2046 BC=0:BR=0
2047 INPUT "Bottom-right column,row";BC,BR
2048 IF BC<1 OR BC>5 THEN PRINT "!) Invalid column":GOTO 1390
2049 IF BR<1 OR BR>MR THEN PRINT "!) Invalid row":GOTO 1390
2050 A=CR(IC,IR):A1=IC:A2=IR
2051 FOR N=IC TO BC
2052 FOR N1=IR TO BR
2053 IF CR(N,N1)