CIDS

Products: CIDS
Developer(s): Mike Trivisonno
Date: 1985
Type: Program
Platform(s): TS 2068
Tags: Database

CIDS is a card-index flat-file database for the Spectrum and TS2068, storing up to 26 configurable records of 21 lines each in a single three-dimensional string array. A command-line interface dispatches 28 commands through a runtime lookup table, with commands chainable by comma on a single input line. Features include a two-mode full-screen text editor with EDIT and SCAN states, Shell sort on any field, four-zone numeric column summation, left/right/center text alignment, tape save and load of the entire database, delete with single-level undo, and a screen and file printer via COPY and LPRINT. An error handler at line 9995 produces context-sensitive messages with page references, indicating the program was distributed with a printed manual. Several commands — including the expression evaluator and the full-screen editor entry point — contain line-number errors that would cause runtime failures.


CIDS — a Card Index Data System. A full-featured flat-file database with an integrated full-screen text editor, tape save/load, sorting, text alignment, numeric zone summation, and a command-line interface with a dispatch table. This is one of the most architecturally sophisticated BASIC programs in the Sinclair ecosystem — an actual productivity application, not a game or demo.

Data structure:

The entire database lives in a single 3D string array:

f$(mf, ml, mc)   — mf files × ml lines × mc characters

Default dimensions: 26 files, 21 lines, 32 characters per line. These are reconfigurable at runtime via the modi command (line 8500), subject to a 16,800-character memory ceiling check. Supporting arrays:

  • r$(ml, mc) — single-file buffer holding the most recently deleted record for undo via rest
  • b$(ml, mc) — working copy of the current file during editing
  • d$(28, 8) — command dispatch table: 28 entries of the form NAME#### where the first 4 chars are the command name and chars 5–8 are a line number string

Command dispatch (lines 200–470):

The main loop (line 105) calls subroutine 200 to read the next word from a$ (or INPUT if a$ is empty), then subroutine 400 to dispatch. Line 410 searches d$() for a 4-character prefix match, then executes GO SUB VAL d$(x,5 TO ) — the line number is stored as a string and converted at runtime. Commands can be chained with commas (lines 465–470): after a GOSUB returns, if a$ begins with a comma the next token is consumed and dispatched, enabling compound command lines like find JONES, disp.

Full command table:

CommandLineFunction
find / loca500Search all files for name prefix match
next650Advance to next match from last find
prev6500Return to previously active file
disp680Display file contents with optional line range
make / crea1510Create new named file
dele / scra / remo1080Delete current file (animated, with confirmation)
name1200List all file names; current file shown in FLASH INK 2
adto5010Enter edit mode for current file
keys8750Swap a record row with row 1 to change the sort key
sort8600Shell sort all files on a specified row
copy1650Print screen (COPY) or current file (LPRINT)
save1540Save f$() to tape with named file
load1250Load f$() from tape
rest1760Restore last deleted file from r$()
move1900Copy a line range from current file into a new file
zone8000Sum numeric values in one of four 8-character column zones
eval150Evaluate an expression (partially implemented — see bugs)
left8300Justify text (see bugs)
righ8350Justify text (see bugs)
cent8400Center text in each line
adju7000Adjust PAPER/BORDER/INK colors interactively
modi8500Reconfigure database dimensions
help1506Display command list
clea1500Clear screen

Full-screen editor (lines 5150–6070):

The editor operates on working buffer b$(), a copy of the current file. It has two modes, switched by a variable main used as a computed GO TO target — an elegant function-pointer idiom in BASIC:

  • EDIT MODE (5150): Cursor keys (CHR$ 8–11) move by line and column. Characters are entered directly into b$(l,c). CHR$ 7 deletes (shifts remainder of line left). CHR$ 5 inserts (shifts right). ENTER advances to the next line. The status bar shows line and column numbers with INK 1/FLASH.
  • SCAN MODE (5500): Navigation via keys 5–8 (the Spectrum’s in-text cursor key characters). r restores the working buffer from f$() and writes back. CHR$ 7 switches to EDIT mode.

The bc/ec (begin/end column) variables implement horizontal scrolling for lines wider than the display, though at 32-character mc this is inactive by default.

Line 6060 (rest within editor) commits b$() back to f$(g) with a visual animation scrolling through both color sets before confirming.


Shell sort (lines 8600–8710):

A proper Shell sort using the standard halving sequence, sorting all f files on a user-specified row number l. The swap step (line 8640) animates the exchange visually in PAPER 6 as each pair is swapped, making the sort progress visible. On completion, resets fl=0 (a flag used elsewhere to suppress some input prompts).

Zone summation (lines 8000–8070):

Divides each line of the current file into four 8-character zones (columns 1–8, 9–16, 17–24, 25–32). The selected zone is highlighted with OVER 1 INK 4 blocks as the program scans each row, summing any numeric values found. The running total is printed in a randomly colored INK on each update. This is essentially a single-column spreadsheet SUM function.

Text alignment (lines 8300–8460):

Three text-processing operations scan each line of the current file and rewrite it:

  • Line 8300 (left command): prepends spaces to push content rightward — right-justifies
  • Line 8350 (righ command): strips leading spaces — left-justifies
  • Line 8400 (cent command): calls 8300 first, then centers the result by prepending (mc - content_length) / 2 spaces

Error handler (lines 9995–9999):

A multi-line PRINT chain using the Sinclair BASIC string AND idiom to produce context-sensitive error messages and page references (e.g. "see pg.28", "name short", "operator required"). The page numbers strongly suggest this was distributed with a printed manual.

Appears On

A hand-labelled cassette of ten programs: a text adventure, a card index database, Richard Booth's numerical methods demos, a UDG designer, a script font and Golf patience.

Related Products

Completely Interactive Database System (CIDS). Full screen editor, more than 30 commands, 16K data storage, ability to learn new commands.

Related Articles

The concept of a Completely Interactive Database System (CIDS) that has been implemented on a micro-computer is interesting in that this type of environment Is normally only found on mainframe computers. What I hope to do is cover the various aspects of implementing just such a system in the next few issues.
In this installment of CIDS, we will develop six essential routines. The only routine that is not a command is the error report routine. Also, as all programs are prone to revisions and extensions, the error routine may not reflect future versions, since the error routine takes memory that could be used for another command.

Image Gallery

Source Code

   10 GO SUB 9010: GO SUB 1506: GO TO 105
   50 FOR v=2 TO ml
   52 IF f$(g,v,1)=" " THEN GO TO 80
   54 NEXT v
   80 RETURN 
  105 GO SUB 200: GO SUB 400: BEEP .025,40: GO TO 105
  150 GO SUB 240: IF w$="    " THEN GO TO 160
  155 PRINT "RESULT ";VAL w$: RETURN 
  156 GO SUB 8020: LET w$=w$+STR$ s: RETURN 
  160 LET w$="eval": GO TO 9995
  200 IF a$<>"" THEN GO TO 240
  210 INPUT "READY>> "; LINE a$: PRINT ">===> ";a$
  220 IF a$="" THEN GO TO 210
  240 FOR l=1 TO LEN a$
  250 IF a$(l)<>" " THEN NEXT l
  260 LET w$=a$( TO l-1): LET a$=a$(l+1 TO )
  261 IF fl=1 THEN RETURN 
  270 IF w$="thanks" THEN PRINT "Your welcome."
  280 IF w$=" " THEN GO TO 200
  285 IF LEN w$<4 THEN LET w$=w$+"    "
  290 RETURN 
  300 FOR w=1 TO 21: PRINT PAPER x;"                                ": NEXT w: RETURN 
  410 FOR x=1 TO 28: IF d$(x, TO 4)=w$( TO 4) THEN GO TO 450
  420 NEXT x
  430 RETURN 
  450 LET w$=w$( TO 4)
  455 GO SUB VAL d$(x,5 TO ): IF a$<>"" THEN GO TO 465
  460 RETURN 
  465 IF a$(1)<>"," THEN GO TO 460
  470 LET a$=a$(3 TO ): GO TO 455
  500 IF LEN a$<5 THEN GO TO 9995
  505 GO SUB 240: IF LEN w$<5 THEN GO TO 9995
  515 LET s$=w$
  530 FOR g=1 TO f: IF f$(g,1, TO LEN s$)=s$ THEN GO TO 555
  540 NEXT g
  541 LET g=prev
  545 PRINT s$;" <NOT THERE>": RETURN 
  555 PRINT s$;" >--FOUND--<": RETURN 
  650 IF s$="" THEN GO TO 9995
  655 LET prev=g: GO SUB 540
  660 RETURN 
  680 IF g=0 THEN LET w$="display"
  681 IF g>f THEN LET g=f
  682 GO SUB 750: IF h<0 OR h>ml OR i<0 OR i>ml THEN GO TO 9995
  685 IF g=0 THEN GO TO 9995
  686 CLS : LET x=3: INK 7: GO SUB 300: PRINT AT 0,0;: LET x=1: INK 7: GO SUB 300: PRINT AT 0,0;"Display file"
  710 FOR v=h TO i
  712 PRINT PAPER x; INK 7;f$(g,v)
  715 NEXT v: LET h=1: RETURN 
  720 GO SUB 870
  730 INK o: RETURN 
  750 IF LEN a$<6 THEN RETURN 
  755 IF a$(1)>"0" OR a$(1)>"1" THEN RETURN 
  765 LET h=VAL a$(1 TO 2): LET i=VAL a$(7 TO 8): LET a$=a$(9 TO ): RETURN 
  850 LET f$(g,v)=b$: LET v=v+1: RETURN 
  870 LET a$="make "+s$: GO SUB 240: GO SUB 400: LET v=2: LET g=f: RETURN 
 1080 IF g=0 THEN GO TO 9995
 1090 CLS : PRINT AT 0,0;"Delete file  ";f$(g,1, TO 18): LET x=2: INK 7: GO SUB 300: INPUT "Are you sure?  "; LINE y$
 1091 IF y$="y" THEN GO TO 1094
 1092 IF y$<>"n" THEN GO TO 1090
 1093 RETURN 
 1094 FOR s=1 TO ml: LET r$(s)=f$(g,s): NEXT s
 1100 FOR s=g TO f: PRINT AT 1,0;
 1105 FOR t=1 TO ml
 1110 PRINT AT t,0;f$(s,t): LET f$(s,t)=f$(s+1,t): PRINT AT t,0; PAPER 2; INK 0;f$(s+1,t)
 1115 NEXT t: BEEP .01,40: NEXT s: LET f=f-1: LET x=0: INK o: CLS : GO SUB 300: PRINT AT 0,0;s$;" >--DELETED--<": LET g=0: RETURN 
 1200 CLS : LET x=1: INK 7: GO SUB 300: PRINT AT 0,0;"Names of files": FOR t=1 TO f
 1205 IF t=g THEN PRINT FLASH 1; INK 2;f$(t,1)
 1206 IF t=g THEN GO TO 1220
 1207 PRINT PAPER x; INK 7;f$(t,1)
 1210 IF t=g THEN PRINT INK 4;"^ current file"
 1220 NEXT t: RETURN 
 1250 CLS : LET x=6: GO SUB 300: PRINT AT 0,0;"Load a file"''': INPUT "FILENAME >--> "; LINE s$
 1260 PRINT "PUT DATA TAPE INTO DRIVE AND"'"HIT "; FLASH 1; INK 2;"ENTER"; FLASH 0; INK 7;".                  "
 1270 PAUSE 0: IF INKEY$<>CHR$ 13 THEN GO TO 1270
 1280 PRINT ;''"START TAPE AND HIT "; FLASH 1; INK 2;"ENTER"; FLASH 0; INK 7;".   "
 1290 PAUSE 0: IF INKEY$<>CHR$ 13 THEN GO TO 1290
 1300 PRINT ''">--LOADING--< ";s$
 1310 LOAD s$ DATA f$()
 1320 PRINT ''"DATAFILE ";s$;" IS LOADED."'; FLASH 1; INK 3;''"STOP TAPE"
 1330 FOR g=1 TO mf
 1340 LET f=f+1
 1350 IF f$(f,1,1)=" " THEN GO TO 1370
 1360 NEXT g
 1370 LET g=0: LET f=f-1: RETURN 
 1500 CLS : RETURN 
 1506 CLS : LET x=3: INK 7: GO SUB 300: PRINT AT 0,7;"COMMANDS AVAILABLE": FOR t=1 TO 28: PRINT d$(t, TO 4); PAPER x;"████";: BEEP .01,50: NEXT t: INK 7: RETURN 
 1510 IF LEN a$<5 THEN GO TO 9995
 1512 GO SUB 240
 1513 IF LEN w$<5 THEN GO TO 9995
 1517 IF f=mf THEN PRINT ">--CAPACITY REACHED--<"
 1518 IF f=25 THEN GO TO 9995
 1519 LET s$=w$
 1520 LET f=f+1: LET f$(f,1)=s$: PRINT s$;" >--MADE--<"
 1535 RETURN 
 1540 LET x=1: BRIGHT 1: CLS : GO SUB 300: PRINT AT 0,0;"Save database": INPUT "FILENAME PLEASE >--> "; LINE c$: PRINT '''"Start tape and hit "; FLASH 1; INK 2;"ENTER"; FLASH 0; INK 7;"."
 1550 PAUSE 0: IF INKEY$<>CHR$ 13 THEN GO TO 1550
 1555 PRINT '''"Saving ";c$
 1560 SAVE c$ DATA f$()
 1565 PRINT '''c$;" has been saved.": BRIGHT 0: RETURN 
 1650 IF f=0 OR g=0 THEN GO TO 9995
 1655 INPUT "COPY screen or file? (s/f) ";b$
 1660 IF b$="f" THEN GO TO 1690
 1670 IF b$<>"s" THEN GO TO 1650
 1680 COPY : RETURN 
 1690 FOR v=1 TO ml
 1700 LPRINT f$(g,v)
 1710 NEXT v
 1720 RETURN 
 1760 LET x=7: INK 0: CLS : GO SUB 300: PRINT AT 0,0; INK 7; PAPER 0;"Restoring file": IF f=mf THEN GO TO 9995
 1770 LET f=f+1: FOR s=1 TO ml: LET f$(f,s)=r$(s): PRINT INK 0; PAPER 7;r$(s): NEXT s: LET g=f: PRINT AT 0,0;"restored -----": RETURN 
 1900 IF g=0 OR f=0 THEN GO TO 9995
 1905 INPUT "Starting at line >> "; LINE i$: PRINT ">";i$
 1910 INPUT "To line >> "; LINE c$: PRINT ">";c$
 2200 LET s$=f$(g,1): LET w$=s$: LET prev=g: GO SUB 1517: LET g=f
 2210 LET v=VAL i$
 2215 LET f$(g,1)=f$(prev,1)
 2220 LET f$(g,v)=f$(prev,v): LET v=v+1
 2230 IF v>=VAL c$ THEN GO TO 2250
 2240 GO TO 2220
 2250 PRINT ">--->move completed"
 2260 RETURN 
 4010 RETURN 
 5010 IF g=0 THEN GO TO 9995
 5015 CLS : PRINT AT 0,0; INK 6; FLASH 1;"SETTING": GO SUB 6000: PRINT AT 0,0; FLASH 0;"       "
 5020 GO SUB main
 5025 RETURN 
 5030 PRINT AT 0,0;"l ";l;"  chr ";c
 5040 PRINT AT x,y; INVERSE 0;b$(l,c): LET x=x+1: IF x>ml THEN LET x=ml
 5042 LET l=l+1: IF l>ml THEN LET l=ml
 5046 GO TO main
 5060 PRINT AT x,y; INVERSE 0;b$(l,c): LET x=x-1: IF x<1 THEN LET x=1
 5062 LET l=l-1: IF l<1 THEN LET l=1
 5066 GO TO main
 5070 PRINT AT x,y; INVERSE 0;b$(l,c): LET y=y+1
 5072 LET c=c+1: IF y>(mc-1) THEN LET y=(mc-1)
 5076 IF c>mc THEN LET c=mc: GO TO main
 5078 GO TO main
 5080 PRINT AT x,y; INVERSE 0;b$(l,c): LET y=y-1: IF y<0 THEN LET y=0
 5082 LET c=c-1: IF c<1 THEN LET c=1
 5086 GO TO main
 5088 PRINT AT 0,0;"EDIT MODE"
 5090 LET e$=INKEY$
 5091 IF INKEY$=CHR$ (7) THEN GO TO 1000
 5092 IF e$="" THEN GO TO 91
 5093 LET b$(l,c)=e$
 5094 PRINT AT x,y;b$(l,c)
 5095 GO TO 90
 5096 PRINT AT 0,0;"         ": GO TO main
 5098 PRINT AT x,y;b$(l,c): LET x=1: LET y=0: LET l=1: LET c=1: LET pl=1: LET pc=1: LET bc=1: LET ec=32: GO TO main
 5100 LET ec=ec+1: IF ec>80 THEN LET ec=80
 5102 LET bc=bc+1: LET y=31: IF c>80 THEN LET c=80
 5104 GO TO main
 5120 LET bc=bc-1: IF bc<1 THEN LET bc=1
 5122 LET ec=ec-1: LET y=0: IF c<1 THEN LET c=1
 5124 IF ec<mc THEN LET ec=mc
 5125 LET c=c-1: IF c<1 THEN LET c=1
 5126 GO TO main
 5150 LET main=5154: PRINT AT 0,0; INK 1; FLASH 1;"EDIT MODE"; FLASH 0
 5154 IF x=0 THEN LET x=1
 5155 PRINT AT x,0;b$(l,bc TO ec);AT x,y; INVERSE 1; INK 2; PAPER 7;b$(l,c);AT 0,18; PAPER 0; INK 1;"ln "; INK 6;l;"██";AT 0,26; INK 1;"ch "; INK 6;c; INK 1;"█"
 5156 LET c$=INKEY$: IF c$="" THEN GO TO 5156
 5157 LET v=CODE c$: IF v>13 AND v<32 THEN GO TO 5155
 5158 IF v>143 THEN GO TO 5155
 5159 IF v=13 THEN GO TO 5400
 5160 IF v=10 THEN GO TO 5040
 5170 IF v=11 THEN GO TO 5060
 5180 IF v=9 THEN GO TO 5070
 5190 IF v=8 THEN GO TO 5080
 5195 IF v=7 THEN GO TO 5300
 5196 IF v=12 THEN GO TO 5310
 5197 IF v=5 THEN GO TO 5430
 5198 GO TO 5201
 5200 GO TO main
 5201 LET b$(l,c)=c$: PRINT AT x,y;c$: LET c=c+1: IF c>mc THEN LET c=1
 5202 LET y=y+1: IF y>(mc-1) THEN GO TO 5245
 5219 GO TO main
 5220 LET y=1: GO TO main
 5230 LET bc=bc+1:: LET ec=ec+1: IF ec>(mc-1) THEN GO TO 5245
 5240 GO TO main
 5245 LET c=1: LET ec=31: LET bc=1: LET l=l+1: IF l>ml THEN LET l=ml
 5250 LET x=l: LET y=0: GO TO main
 5300 PAUSE 20: LET main=5500: PRINT AT 0,0;"                  ": GO TO main
 5312 LET b$(l,c TO )=b$(l,c+1 TO ): GO TO main
 5313 LET b$(l,c TO )=" "+b$(l,c TO ): GO TO main
 5314 LET y=y-1: IF y<0 THEN LET y=0
 5318 GO TO main
 5400 PRINT AT x,y;f$(g,l,c): LET l=l+1: IF l>ml THEN LET l=ml
 5410 LET c=1: LET y=0: LET bc=1: LET ec=mc: LET x=x+1: IF x>ml THEN LET x=ml
 5420 GO TO main
 5430 LET b$(l,c TO )=" "+b$(l,c TO ): GO TO main
 5500 PRINT AT 0,0; FLASH 1; INK 5;"SCAN MODE"
 5501 PRINT AT x,0;b$(l,bc TO ec);AT x,y; INVERSE 1; INK 4;b$(l,c);AT 0,18; INK 3;"ln "; INK 5;l;"██";AT 0,26; INK 3;"ch "; INK 5;c; INK 3;"█"
 5510 LET c$=INKEY$: IF c$="" THEN GO TO 5510
 5520 IF c$="6" THEN GO TO 5040
 5530 IF c$="7" THEN GO TO 5060
 5540 IF c$="8" THEN GO TO 5070
 5550 IF c$="5" THEN GO TO 5080
 5560 IF c$=CHR$ (7) THEN GO TO 5150
 5570 IF c$="h" THEN GO TO 5098
 5575 IF c$="r" THEN GO TO 6060
 5580 GO TO main
 6000 LET main=5500: LET text=5201: LET a$="": DIM b$(21,32): LET x=1: LET y=0: LET l=1: LET c=1: LET pl=1: LET pc=1
 6030 LET bc=1: LET ec=mc:
 6040 FOR w=1 TO ml: LET b$(w)=f$(g,w): NEXT w
 6045 FOR w=1 TO ml: PRINT INK 4; INVERSE 1;b$(w): NEXT w: FOR w=21 TO 1 STEP -1: PRINT AT w,0; INK 1; INVERSE 1;b$(w): NEXT w: PRINT AT 1,0;: FOR w=1 TO ml: PRINT b$(w): NEXT w: RETURN 
 6060 PRINT AT 0,0; FLASH 1; INK 4;"RESTORING": FOR w=1 TO ml: LET f$(g,w)=b$(w): NEXT w
 6070 FOR w=1 TO 21: PRINT INK 3; INVERSE 1;b$(w): NEXT w: FOR w=21 TO 1 STEP -1: PRINT AT w,0; INK 5; INVERSE 1;b$(w): NEXT w: PRINT AT 1,0;: FOR w=1 TO 21: PRINT b$(w): NEXT w: PRINT AT 0,0; INK 4;"Ok --------": RETURN 
 6500 LET w$="prev": IF prev=0 THEN GO TO 9995
 6510 LET g=prev: PRINT ">--PREVIOUS FILE FOUND--<": BEEP .02,20: RETURN 
 7000 CLS : LET x=5: PRINT PAPER x; INK 0;"Adjust Screen":
 7010 INPUT a$
 7015 IF a$="r" THEN GO TO 7090
 7020 IF LEN a$<>2 THEN GO TO 7010
 7025 IF a$(2)<"0" OR a$(2)>"7" THEN GO TO 7010
 7030 IF a$(1)="p" THEN GO TO 7050
 7035 IF a$(1)="b" THEN GO TO 7055
 7040 IF a$(1)="i" THEN GO TO 7060
 7045 GO TO 7010
 7050 PAPER VAL a$(2): GO TO 7010
 7055 BORDER VAL a$(2): GO TO 7010
 7060 INK VAL a$(2): LET o=VAL a$(2): GO TO 7010
 7090 LET fl=0: LET a$="": RETURN 
 8000 REM GO SUB 240
 8010 IF w$="" THEN GO TO 8150
 8025 IF g=0 THEN GO TO 8170
 8026 REM IF mc<32 THEN GO TO 8165
 8027 GO SUB 240
 8028 IF W$="" OR w$(1)=" " THEN GO TO 8150
 8029 IF VAL w$<1 OR VAL w$>4 OR CODE w$(1)<48 OR CODE w$(1)>57 THEN GO TO 8160
 8030 LET s=0: LET x=0: LET y=0: GO SUB 8070
 8035 GO SUB 8070
 8036 LET w$=w$(1): GO SUB 680: PRINT AT 0,0; INK 4;"Zone file   ";
 8040 FOR l=2 TO 21: PRINT AT l,x-1; INK 4; PAPER 0; OVER 1;"████████": BEEP .025,50
 8041 GO SUB 8070: IF CODE f$(g,l,x)<48 OR CODE f$(g,l,x)>57 OR f$(g,l,x)="/" OR f$(g,l,x)=" " THEN GO TO 8060
 8050 LET s=s+VAL f$(g,l,x TO y): PRINT AT 0,21;"           ";AT 0,21; INK (RND*6)+1;s
 8060 NEXT l
 8062 PRINT AT 0,14;"zone ";w$;"=";s
 8064 RETURN 
 8070 LET x=(1 AND w$="1")+(9 AND w$="2")+(17 AND w$="3")+(25 AND w$="4"): LET y=(8 AND w$="1")+(16 AND w$="2")+(24 AND w$="3")+(32 AND w$="4"): RETURN 
 8150 LET w$="zone": GO TO 9995
 8160 LET w$="zone1": GO TO 9995
 8165 LET w$="zone4": GO TO 9995
 8170 LET w$="zone2": GO TO 9995
 8200 FOR k=x TO y: IF CODE f$(g,l,k)<46 OR CODE f$(g,l,k)>57 THEN GO TO 8060
 8210 NEXT k: RETURN 
 8250 PRINT AT 0,0;: FOR w=1 TO 32: PRINT f$(g,1,w);: NEXT w: FOR w=0 TO 31: PRINT AT 21,0;" ": NEXT w: RETURN 
 8300 IF g=0 THEN GO TO 9995
 8302 CLS : FOR w=1 TO 21: PRINT INK 0; PAPER 4;f$(g,w): NEXT w: PRINT AT 0,0
 8305 FOR s=2 TO ml
 8310 FOR t=mc TO 1 STEP -1
 8315 IF f$(g,s)="                                " THEN GO TO 8341
 8320 IF f$(g,s,t)<>" " THEN GO TO 8345
 8335 NEXT t
 8340 NEXT s: GO SUB 8250: RETURN 
 8341 PRINT f$(g,s): GO TO 8340
 8345 LET y$=f$(g,s): LET y$="                                "( TO mc-t)+y$: LET f$(g,s)=y$: PRINT INK 7; PAPER 0;f$(g,s): GO TO 8340
 8350 IF g=0 THEN GO TO 9995
 8352 CLS : FOR s=1 TO ml: PRINT PAPER 1; INK 0;f$(g,s): NEXT s: PRINT AT 1,0;
 8355 FOR s=2 TO ml
 8360 FOR t=1 TO (mc-1)
 8362 IF f$(g,s)="                                " THEN GO TO 8377
 8365 IF f$(g,s,t)<>" " THEN GO TO 8380
 8370 NEXT t
 8375 NEXT s
 8376 GO SUB 8250: RETURN 
 8377 PRINT f$(g,s): GO TO 8375
 8380 LET f$(g,s)=f$(g,s,t TO ): PRINT f$(g,s): GO TO 8375
 8400 IF g=0 THEN GO TO 9995
 8405 GO SUB 8300
 8410 CLS : FOR s=1 TO ml: PRINT INK 0; PAPER 5;f$(g,s): NEXT s: PRINT AT 1,0;
 8445 FOR s=2 TO ml
 8446 FOR t=1 TO (mc-1)
 8447 IF f$(g,s)="                                " THEN GO TO 8456
 8450 IF f$(g,s,t)<>" " THEN GO TO 8460
 8452 NEXT t
 8455 NEXT s: GO SUB 8250: RETURN 
 8456 PRINT f$(g,s): GO TO 8455
 8460 LET y$=f$(g,s,t TO ): LET y$="                                "( TO (mc-LEN y$)/2)+y$: LET f$(g,s)=y$: PRINT f$(g,s): GO TO 8455
 8500 PRINT "Number of files. ";
 8510 INPUT mf
 8520 PRINT mf
 8530 PRINT "Number of lines. (max. 21) ";
 8540 INPUT ml: IF ml>21 THEN GO TO 8540
 8545 PRINT ml
 8560 PRINT "Number of characters per line.  (max. 32) ";
 8570 INPUT mc: IF mc>32 THEN GO TO 8570
 8575 PRINT mc
 8577 IF (mf*ml)*mc>16800 THEN GO TO 8595
 8580 LET f=0: LET g=0: LET i=ml: DIM f$(mf+1,ml,mc): PRINT "CIDS has been reconfigured."
 8590 RETURN 
 8595 PRINT ">--EXCEEDS MEMORY AVAILABLE--<": GO TO 8500
 8600 IF f<=1 THEN GO TO 9995
 8601 PRINT "On what record?": INPUT l: IF l>ml THEN GO TO 8600
 8602 LET x=6: INK 0: GO SUB 300: LET s=1: DIM b$(ml,mc): PRINT AT 0,0; PAPER 0; INK 7;"Sorting on record ";l
 8603 LET s=s*2
 8605 IF s<=f THEN GO TO 8603
 8610 LET s=INT (s/2)
 8612 IF s=0 THEN GO TO 8710
 8615 FOR t=1 TO f-s
 8620 LET y=t
 8625 LET fl=y+s
 8630 IF f$(y,l)<=f$(fl,l) THEN GO TO 8660
 8640 PAPER 6: INK 0: FOR i=1 TO ml: LET b$(i)=f$(y,i): PRINT AT i,0;b$(i): NEXT i: FOR i=1 TO ml: LET f$(y,i)=f$(fl,i): PRINT AT i,0;f$(y,i): NEXT i: FOR i=1 TO ml: LET f$(fl,i)=b$(i): PRINT AT i,0;f$(fl,i): NEXT i
 8645 LET y=y-s
 8650 IF y>0 THEN GO TO 8625
 8660 NEXT t
 8670 GO TO 8610
 8710 PRINT AT 0,0;"Sort done ---------": LET i=ml: LET fl=0: INK 7: PAPER 0: RETURN 
 8715 PRINT "Wich record do you want to      become the new key?": INPUT s
 8720 IF s>ml OR s<=0 THEN GO TO 8715
 8750 PRINT ">--Change keys--<"
 8780 FOR t=1 TO f: LET y$=f$(t,1): LET f$(t,1)=f$(t,s): LET f$(t,s)=y$: NEXT t: PRINT ">--Key has been changed.--<"
 8785 RETURN 
 9000 STOP : RETURN 
 9010 LET o=7: POKE 23609,6: LET mf=26: LET ml=21: LET mc=32: LET fl=0: DIM f$(mf,ml,mc): DIM r$(ml,mc): LET g=0: LET f=0: DIM d$(28,8): LET h=1: LET i=21: LET s$="": LET prev=0
 9020 LET d$(14)="prev6500": LET d$(4)="clea1500": LET d$(17)="help1506": LET d$(3)="make1510": LET d$(1)="find500": LET d$(5)="next650": LET d$(6)="disp680": LET d$(7)="adto5000": LET d$(8)="keys8750": LET d$(9)="sort8600": LET d$(10)="dele1080": LET d$(16)="name1200"
 9025 LET d$(21)="scra1080": LET d$(22)="loca500": LET d$(23)="crea1510": LET d$(24)="remo1080": LET d$(25)="left8300": LET d$(26)="righ8350": LET d$(27)="cent8400": LET d$(28)="modi8500"
 9030 LET d$(13)="adju7000": LET d$(2)="eval150": LET d$(15)="copy1650": LET d$(19)="rest1760": LET d$(18)="save1540": LET d$(20)="load1250": LET d$(11)="zone8000": LET d$(12)="move1900": LET a$=""
 9040 POKE 23692,255: PAPER 0: CLS : RETURN 
 9995 PRINT "**ERROR** ";w$( TO 4);">";
 9996 PRINT ("no file" AND w$="right")+("no file" AND w$="left")+("no file" AND w$="cent")+("no fie" AND w$="copy")+("no file" AND w$="move")+("no file" AND w$="zone2")+("no file" AND w$="edit1")+("no file" AND w$="bloc1")+("no file" AND w$="adto")+("out of range" AND w$="zone1")+("no file" AND w$="dele")+("no file" AND w$="display");
 9997 PRINT ("see pg.28" AND w$="zone4")+("no file" AND w$="grap")+("no previous file" AND w$="prev")+("column?" AND w$="zone")+("next before find" AND w$="next")+("out of range" AND w$="disp")+("operator required" AND w$="eval")+("name short" AND w$="find")+("name short" AND w$="make");
 9998 PRINT " pg.";(18 AND w$="disp")+(25 AND w$="left")+(27 AND w$="righ")+(27 AND w$="cent")+(12 AND w$="make")+(13 AND w$="find")+(14 AND w$="adto")+(16 AND w$="dele")+(18 AND w$="display")+(19 AND w$="next")+(20 AND w$="prev")+(22 AND w$="move")+(30 AND w$="zone")+(32 AND w$="eval")+(29 AND w$="sort")
 9999 PRINT : RETURN 

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