Typewriter

Developer(s): Jack Dohany
Date: 198x
Type: Program
Platform(s): TS 2068

This program is a full-featured word processor. It stores the document as a single large string array `f$` dimensioned to a user-specified number of 32-character lines (up to 320 lines, 10,240 bytes). The editor supports cursor movement, word-wrap, tab stops, insert/delete of characters and lines, caps lock, a status bar on the lower screen, and cassette tape save/load of both the file and the program itself. Keyboard handling uses a two-level control scheme where Caps Shift keys dispatch to editing commands and a “Level Two” menu provides additional functions such as erasing the file, printing via LPRINT, and setting tab stops. Screen position tracking relies directly on system variables at addresses 23688 (column) and 23689 (row) rather than maintaining separate cursor variables.


Program Analysis

Program Structure

The program is organised into clearly labelled functional blocks separated by REM statements. Execution begins at line 15 with a GO TO 3000 for initialisation, then falls into the main edit loop at line 20. The broad structure is:

  1. Lines 20–99: Main edit loop — display, cursor rendering, key polling, character insertion, and word-wrap logic.
  2. Lines 100–290: Control-key dispatch table; each Caps Shift key (codes 1–28) jumps to 100+10*a, placing handlers at lines 100, 110, 120, …, 280.
  3. Lines 300–320: Symbol Shift and extended key handling.
  4. Lines 400–442: Delete-character routine with held-key repeat detection via IN 61438 / IN 65278.
  5. Lines 500–609: “Level Two” command menu, dispatching on digit keys to secondary functions.
  6. Lines 840–848: Jump-to-line function.
  7. Lines 1000–1044: Toggle switches (beep, status, word-wrap) and status-bar subroutine.
  8. Lines 1090–1177: Erase file, print via LPRINT, and tab-stop setup.
  9. Lines 1380–1389: STOP / exit to BASIC.
  10. Lines 2000–2098: Menu display (help screen).
  11. Lines 2100–2196: Save/Load menu with five options.
  12. Lines 3000–3098: Initialisation — prompts for file size, dimensions arrays, sets defaults.
  13. Lines 4000–5010: Stubs for 80-column print and spare control (both jump to non-existent line 350).

Document Storage Model

The entire document is held in a single string variable f$, dimensioned to bmax characters where bmax = 32 * lmax and lmax is the user-specified line count (1–320). Each 32-character slice of f$ corresponds to one screen line. The variable by is the logical byte-offset cursor into f$ (1-based). A blank-line buffer e$ is a 32-space string used for padding during insert/delete operations. The tab-stop map is held in t$(32), a one-character-per-column string where "1" marks a tab stop.

Key Polling and Auto-Repeat

The main loop at line 40 polls INKEY$ directly, rejecting codes below 4 (pure shift keys). A simple software auto-repeat mechanism uses variables a (last key code) and c (countdown): on a first press c is set to 12, and subsequent loops decrement it before accepting the key again, producing a short initial delay before repeat. The delete routine (line 400–442) uses a tighter hardware-level repeat: it reads the keyboard matrix ports IN 61438 (half-row containing 0) and IN 65278 (half-row containing Caps Shift) to detect whether both Delete keys are still held, with a small counter dcnt providing a secondary delay before rapid deletion begins. OUT 255,64 and OUT 255,0 bracket the delete loop, presumably driving an external device or the border.

System Variable Manipulation

Rather than tracking screen cursor position in BASIC variables, the program reads and writes the Spectrum system variables directly:

AddressSystem VariableUsage
23562ERR_SP / FLAGSSet to 1 (edit mode) or 5 (suppress error reports)
23658FLAGS2POKEd 8 to set caps-lock flag, 0 to clear
23684–23685DF_CC (display file cursor low/high byte)Direct cursor repositioning within the display file
23688S_POSN columnCurrent print column; used to compute horizontal offsets
23689S_POSN rowCurrent print row; used to detect screen boundaries
23560LAST_KRead directly for Level Two menu key detection after PAUSE 0
65528–65535RAM top areaPOKEd during init; likely clears UDG area or interrupt vector

This direct manipulation allows the program to reposition the print position after redrawing the screen without issuing a fresh PRINT AT, and to compute the cursor’s logical document position from by and the column/row registers.

Word-Wrap Algorithm

Word-wrap (lines 100–118) is triggered when the column counter (PEEK 23688) reaches 2 or below and the character being typed is not a space or hyphen. The routine scans backwards in f$ up to 20 characters for the last space or hyphen (line 112), then uses a string slice assignment to shuffle characters: f$(by-i TO by-1+i)=e$(1 TO i)+f$(by-i TO by-1) inserts i spaces at the split point to push the wrapped word to the next line. The system variable DF_CC and column register are then adjusted to match.

Level Two Command Dispatch

Pressing Caps Shift + key 1 (code 1) enters “Level Two” at line 500. The menu waits for a digit key 09 (ASCII 48–57) and dispatches via GO TO 600+k-48, producing jump targets at lines 600–609. Each of these is a single GO TO stub pointing to the real handler, creating a clean indirection table:

  • 600 → 152 (delete line)
  • 601 → 520 (exit level two)
  • 602 → 1170 (set tabs)
  • 603 → 1010 (status toggle)
  • 604 → 1000 (beep toggle)
  • 605 → 1020 (wrap toggle)
  • 606 → 2100 (tape save/load)
  • 607 → 1090 (erase file)
  • 608 → 1150 (print)
  • 609 → 141 (insert line)

ON ERR Usage

The program uses the TS2068 ON ERR keyword (displayed here as { per preprocessing rules — but written as ON ERR in the source) at several points: line 25 redirects tape errors and user breaks back to the main loop at line 40; line 1151 catches printer errors; line 2102 catches tape errors in the save/load section; and line 1388 calls RESET followed by STOP to cleanly exit. This confirms the program targets the TS2068, which has ON ERR as a native keyword.

Status Bar

The lower screen (stream #1) provides a persistent status bar. Subroutine 1030 draws a row of inverse-video spaces on row 0 and a blank line on row 1. Subroutine 1040/90 overlays live cursor position information: horizontal offset (34-PEEK 23688), vertical position (25-PEEK 23689), and logical line number (1+INT((by-1)/32)). Toggle states CAPS, BEEP, and WRAP are also displayed in fixed columns of the status line.

Tape Save/Load

The save/load section (lines 2100–2196) offers five options. Options 1 and 4 use SAVE/LOAD q$ DATA f$() to serialise or restore just the document array, allowing the program itself to remain in RAM. Option 2 uses SAVE q$ LINE 20 to save the whole program with auto-run at line 20, which also preserves the current f$ contents embedded in the saved file. Option 3 resets bmax=1 and re-dimensions f$(1) before saving, stripping the document to save tape space. Verify prompts follow each save operation.

Notable Anomalies and Observations

  • Lines 120, 130, 260, 270, 280, 290 all contain only GO TO 40; these are placeholder stubs for Caps Shift codes 2, 3, 6, 7, 8, and 9 that have real handlers elsewhere but are reached via the GO TO 100+10*a dispatch — code 2 (Caps Lock) is actually at 160, code 3 (TAB) at 140, etc., so lines 120/130 being simple pass-throughs is consistent.
  • Line 87 uses f$(x-95 TO x), which could produce a negative index if x is small; this path is only taken when x < bmax-32 but the guard on x being large enough for the 96-character back-window is implicit rather than explicit.
  • Lines 4000 and 5010 jump to line 350, which does not exist. These are declared stubs for “80-column print” and “spare control” features that were never implemented.
  • Line 522 and 1030 use \u escape sequences to print UDG character ‘u’ (char 157) filling the top status row — this is used as a solid inverse block to create the status-bar background.
  • The POKE 23562,1 at line 22 sets the error stack pointer flag to suppress the normal “0 OK” report, keeping the lower screen clean for the status bar.

Content

Appears On

One of a series of library tapes. Programs on these tapes were renamed to a number series. This tape contained

Related Products

Related Articles

Related Content

Image Gallery

Typewriter

Source Code

    1 REM ***TYPEWRITER***
    2 REM   VERSION: 841009
    5 REM A public-domain word-  processor written by Jack Dohany
    6 REM (415) 321-7684
   10 REM OK TO RUN
   15 GO TO 3000: REM INIT
   19 BORDER 0: PAPER 0: INK 7
   20 CLS : GO SUB 1030
   21 LET a=0: LET c=0
   22 POKE 23562,1
   25 ON ERR GO TO 40
   26 LET y=703: IF y>bmax THEN LET y=bmax
   27 LET by=1: PRINT f$(by TO y);AT 0,0;
   30 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;
   31 IF s=0 THEN GO TO 40
   32 GO SUB 90
   40 IF INKEY$="" THEN LET a=0: GO TO 40
   42 LET b=CODE INKEY$: IF b<4 THEN GO TO 40
   44 IF a<>b THEN LET a=b: LET c=12: GO TO 50
   49 IF c>0 THEN LET c=c-1: GO TO 40
   50 IF a<32 OR a>127 THEN GO TO 300
   60 IF beep=1 THEN BEEP .002,25
   70 IF by>=bmax-1 THEN GO TO 98
   80 LET f$(by)=CHR$ a: LET by=by+1
   81 IF wrap=1 THEN GO TO 100
   82 IF PEEK 23689<5 AND PEEK 23688<3 THEN GO TO 86
   84 PRINT CHR$ a;: GO TO 30
   86 CLS : LET x=32*INT ((by-1)/32)
   87 IF x<bmax-32 THEN BEEP .008,30: PRINT f$(x-95 TO x);: GO SUB 1030: GO TO 30
   88 PRINT f$(x-639 TO x);: GO TO 30
   90 PRINT #1;AT 1,7;34-PEEK 23688;" ";AT 1,11;25-PEEK 23689;" ";AT 1,15;1+INT ((by-1)/32);"  "
   92 RETURN 
   98 PRINT '"END OF FILE": GO TO 40
  100 REM WRAP?
  102 IF PEEK 23688>2 THEN GO TO 82
  104 IF CHR$ a=" " OR CHR$ a="-" THEN GO TO 82
  106 IF PEEK 23689<4 THEN GO TO 82
  110 REM WRAP!
  112 BEEP .02,27: FOR i=1 TO 20: IF f$(by-i-1)=" " OR f$(by-i-1)="-" THEN GO TO 116
  114 NEXT i: GO TO 82
  116 LET f$(by-i TO by-1+i)=e$(1 TO i)+f$(by-i TO by-1)
  117 POKE 23688,PEEK 23688+i-1: POKE 23684,PEEK 23684-i+1: PRINT f$(by-i TO by-1+i);: LET by=by+i
  118 GO TO 30
  120 GO TO 40
  130 GO TO 40
  140 GO TO 171: REM tab
  141 REM INSERT LINE
  142 LET x=PEEK 23688: LET y=PEEK 23689: LET f$(by+x-1 TO bmax)=e$+f$(by+x-1 TO bmax-32)
  143 PRINT 'f$(by+x-1 TO by+x-3+32*(y-3));: PRINT AT 24-y,33-x;
  144 GO TO 500
  150 GO TO 840: REM jump
  152 REM DELETE LINE
  154 LET by=1+(32*INT (by/32)): POKE 23684,PEEK 23684-(33-PEEK 23688): POKE 23688,33
  155 LET f$(by TO bmax)=f$(by+32 TO bmax)+e$
  156 LET s1=PEEK 23684: LET s2=PEEK 23685: LET s3=PEEK 23688: LET s4=PEEK 23689: PRINT f$(by TO by-1+32*(s4-2));
  157 POKE 23684,s1: POKE 23685,s2: POKE 23688,s3: POKE 23689,s4
  158 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;
  159 GO TO 500
  160 REM CAPS
  161 LET cs=1-cs
  162 IF cs=1 THEN POKE 23658,8
  163 IF cs=0 THEN POKE 23658,0
  164 PRINT #1;AT 1,0;"    "
  165 IF cs=1 THEN PRINT #1;AT 1,0;"CAPS"
  166 GO TO 40
  170 GO TO 500: REM command
  171 LET hp=34-PEEK 23688: REM  TAB
  172 IF hp>31 THEN GO TO 175
  173 FOR i=hp+1 TO 32: IF t$(i)="1" THEN GO TO 177
  174 NEXT i
  175 FOR i=1 TO hp-1: IF t$(i)="1" THEN GO TO 177
  176 NEXT i: GO TO 40
  177 LET tab=i-1: PRINT OVER 1; INVERSE 1;" ";CHR$ 8;
  178 POKE 23684,PEEK 23684-(33-PEEK 23688)+tab: POKE 23688,33-tab
  179 LET by=1+(32*INT (by/32))+tab: GO TO 30
  180 REM LEFT
  181 IF PEEK 23689>23 AND PEEK 23688>32 THEN GO TO 40
  182 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;CHR$ 8;: LET by=by-1
  186 GO TO 30
  190 REM RIGHT
  191 IF by>=bmax-1 OR (PEEK 23689<4 AND PEEK 23688<3) THEN GO TO 30
  192 PRINT OVER 1; INVERSE 1;" ";: LET by=by+1: GO TO 30
  200 REM DOWN
  201 IF PEEK 23689<4 THEN GO TO 205
  202 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;: POKE 23689,PEEK 23689-1
  203 IF PEEK 23689=16 OR PEEK 23689=8 THEN POKE 23684,33-PEEK 23688: POKE 23685,PEEK 23685+8: LET by=by+32: GO TO 30
  204 POKE 23684,PEEK 23684+32: LET by=by+32: GO TO 30
  205 IF by>(bmax-32) THEN GO TO 40
  206 LET s1=PEEK 23688: LET s2=PEEK 23689: LET s3=PEEK 23684: LET s4=PEEK 23685: LET by=by+32: LET x=1+(32*INT (by/32))
  207 CLS : PRINT f$(x-672 TO x+31);: POKE 23688,s1: POKE 23689,s2: POKE 23684,s3: POKE 23685,s4: PRINT ;: GO SUB 1030: GO TO 30
  210 REM UP
  211 IF PEEK 23689>23 THEN GO TO 215
  212 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;: POKE 23689,PEEK 23689+1
  213 IF PEEK 23689=17 OR PEEK 23689=9 THEN POKE 23684,PEEK 23684+224: POKE 23685,PEEK 23685-8: LET by=by-32: GO TO 30
  214 POKE 23684,PEEK 23684-32: LET by=by-32: GO TO 30
  215 IF by<33 THEN BEEP .02,20: GO TO 40
  216 LET s1=PEEK 23688: LET s2=PEEK 23689: LET s3=PEEK 23684: LET s4=PEEK 23685: LET by=by-32: LET x=1+(32*INT (by/32))
  217 CLS : PRINT f$(x TO x+703);: POKE 23688,s1: POKE 23689,s2: POKE 23684,s3: POKE 23685,s4: PRINT ;: GO SUB 1030: GO TO 30
  220 REM DELETE CH
  221 IF by<2 THEN GO TO 40
  222 GO TO 400
  230 REM ENTER
  231 LET x=32*INT ((by-1)/32): IF x>=bmax-32 THEN PRINT "FILE FULL": GO TO 40
  232 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;
  233 IF PEEK 23689<4 THEN GO TO 236
  235 PRINT CHR$ 13;: LET by=33+x: GO TO 30
  236 CLS : PRINT f$(x-639 TO x+31);AT 21,0;: LET by=33+x: GO SUB 1030: GO TO 30
  250 REM INSERT SP
  252 IF by>=bmax OR (PEEK 23689<4 AND PEEK 23688<4) THEN BEEP .01,20: GO TO 40
  254 LET by=by+1: PRINT " ";: LET s1=PEEK 23684: LET s2=PEEK 23685: LET s3=PEEK 23688: LET s4=PEEK 23689
  255 LET f$(by-1 TO by+s3-2)=" "+f$(by-1 TO by+s3-3)
  256 PRINT f$(by TO by+s3-2);: POKE 23684,s1: POKE 23685,s2: POKE 23688,s3: POKE 23689,s4: GO TO 30
  260 GO TO 40
  270 GO TO 40
  280 GO TO 40
  290 GO TO 40
  300 REM CS&SS KEYS
  301 IF a<32 THEN GO TO 100+10*a
  302 IF a=226 THEN GO TO 1380
  303 IF a=197 THEN LET a=164: GO TO 60: REM UNDERLINE
  304 IF a=199 THEN GO SUB 2000: GO TO 20
  305 IF a=195 THEN LET a=123: GO TO 60
  306 IF a=205 THEN LET a=125: GO TO 60
  307 IF a=201 THEN LET a=127: GO TO 60
  308 IF a=204 THEN LET a=91: GO TO 60
  309 IF a=200 THEN LET a=92: GO TO 60
  310 IF a=203 THEN LET a=93: GO TO 60
  320 GO TO 40
  400 REM DELETE
  402 OUT 255,64
  404 LET dcnt=10
  410 IF by<2 THEN OUT 255,0: GO TO 40
  414 LET by=by-1: PRINT OVER 1; INVERSE 1;" ";CHR$ 8;CHR$ 8;: LET s1=PEEK 23688: LET s2=PEEK 23689: LET s3=PEEK 23684: LET s4=PEEK 23685
  418 LET f$(by TO by+s1-1)=f$(by+1 TO by+s1-2)+" "
  424 PRINT f$(by TO by+s1-2);: POKE 23688,s1: POKE 23689,s2: POKE 23684,s3: POKE 23685,s4
  428 PRINT OVER 1; INVERSE 1;" ";CHR$ 8;
  429 IF s=1 THEN GO SUB 90
  430 IF IN 61438=30 AND IN 65278=30 THEN GO TO 440
  432 OUT 255,0: GO TO 31
  440 IF dcnt=0 THEN GO TO 410
  442 LET dcnt=dcnt-1: GO TO 430
  500 REM LEVEL TWO
  501 PRINT #1;AT 0,0;"          **LEVEL TWO**         "
  502 PAUSE 0: LET k=PEEK 23560
  506 IF k=13 THEN GO TO 520
  508 IF k<48 OR k>57 THEN GO TO 500
  510 BEEP .01,20
  512 GO TO 600+k-48
  520 REM exit edit-mode
  522 PRINT #1;AT 0,0;"\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u"
  524 GO TO 31
  600 GO TO 152: REM delete ln
  601 GO TO 520: REM exit
  602 GO TO 1170: REM set tabs
  603 GO TO 1010: REM status sw
  604 GO TO 1000: REM beep sw
  605 GO TO 1020: REM wrap sw
  606 GO TO 2100: REM tape
  607 GO TO 1090: REM erase
  608 GO TO 1150: REM print
  609 GO TO 141: REM insert ln
  840 REM JUMP
  841 INPUT ("JUMP TO LINE (1-";lmax;"): "); LINE q$: IF q$="" THEN GO TO 40
  842 LET fl=VAL q$
  843 LET by=1+(32*(fl-1))
  844 LET tb=by+703: IF tb>bmax THEN LET tb=bmax
  848 CLS : PRINT f$(by TO tb);AT 0,0;: LET cm=0: GO SUB 1030: GO TO 30
 1000 REM BEEP SW
 1002 LET beep=1-beep
 1004 PRINT #1;AT 1,20;"    "
 1006 IF beep=1 THEN PRINT #1;AT 1,20;"BEEP"
 1008 GO TO 502
 1010 REM STATUS SW
 1012 LET s=1-s
 1014 PRINT #1;AT 1,6;"            "
 1016 IF s=1 THEN GO SUB 1040
 1018 GO TO 502
 1020 REM WRAP SW
 1022 LET wrap=1-wrap
 1024 PRINT #1;AT 1,26;"    "
 1026 IF wrap=1 THEN PRINT #1;AT 1,26;"WRAP"
 1028 GO TO 502
 1030 PRINT #1;AT 0,0;"\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u\u";AT 1,0;e$(1 TO 31)
 1031 IF s=1 THEN GO SUB 1040
 1032 IF cs=1 THEN PRINT #1;AT 1,0;"CAPS"
 1034 IF beep=1 THEN PRINT #1;AT 1,20;"BEEP"
 1036 IF wrap=1 THEN PRINT #1;AT 1,26;"WRAP"
 1038 RETURN 
 1040 REM print status
 1042 PRINT #1;AT 1,6;"H";34-PEEK 23688;" ";AT 1,10;"V";25-PEEK 23689;" ";AT 1,14;"L";1+INT ((by-1)/32);"  "
 1044 RETURN 
 1090 REM ERASE FILE
 1092 INPUT "ERASE FILE? (Y=YES)"; LINE q$: IF q$="y" OR q$="Y" THEN DIM f$(bmax): GO TO 20
 1094 GO SUB 1030: GO TO 500
 1150 REM PRINT
 1151 ON ERR GO TO 1158
 1152 INPUT ("PRINT FROM LINE (1-";lmax;"): "); LINE q$: IF q$="" THEN GO TO 1158
 1153 LET fl=VAL q$: LET fb=1+(32*(fl-1)): IF fl>lmax THEN GO TO 1152
 1154 INPUT ("PRINT LINE ";fl;" TO:(";fl+1;"-";lmax;"): "); LINE q$
 1155 IF q$="" THEN LET tb=bmax: GO TO 1157
 1156 LET tb=32+(32*(VAL q$-1)): IF fb>=tb THEN GO TO 1152
 1157 LPRINT f$(fb TO tb)
 1158 BEEP .01,25: PAUSE 100: ON ERR GO TO 40: GO TO 20
 1170 REM SET TABS
 1171 INPUT "SET TABS (1-32)/ENT=done: "; LINE q$: IF q$="" THEN GO SUB 1030: GO TO 500
 1172 DIM t$(32)
 1173 LET tab=INT VAL q$: IF tab<1 OR tab>32 THEN GO TO 1176
 1174 LET t$(tab)="1"
 1176 INPUT "SET TABS (1-32)/ENT=done: "; LINE q$: IF q$="" THEN GO SUB 1030: GO TO 500
 1177 GO TO 1173
 1380 REM STOP
 1382 CLS : PRINT AT 10,0;"TO RETURN, GO TO 20."
 1384 POKE 23562,5
 1388 ON ERR RESET : STOP 
 1389 GO TO 20
 2000 REM MENU
 2010 CLS 
 2015 PRINT TAB 4;"(Caps Shift)";TAB 18;"(Unshifted)"
 2016 PRINT "KEY  LEVEL ONE";TAB 18;" LEVEL TWO"
 2020 PRINT "\u\u\u \u\u\u\u\u\u\u\u\u\u\u\u  \u\u\u\u\u\u\u\u\u\u\u"
 2022 PRINT " 1";TAB 4;"CHANGE LEVEL";TAB 18;"CHANGE LEVEL"
 2024 PRINT " 2  CAPS LOCK";TAB 18;"SET TABS 1-32"
 2026 PRINT " 3  TAB";TAB 18;"STATUS ON/OFF"
 2028 PRINT " 4  JUMP TO LINE";TAB 18;"BEEP ON/OFF"
 2030 PRINT " 5  LEFT";TAB 18;"WRAP ON/OFF"
 2032 PRINT '" 6  DOWN";TAB 18;"TAPE"
 2034 PRINT " 7  UP";TAB 18;"ERASE FILE"
 2036 PRINT " 8  RIGHT";TAB 18;"PRINT 2040"
 2038 PRINT " 9  INSERT SPACE";TAB 18;"INSERT LINE"
 2040 PRINT " 0  DELETE LEFT";TAB 18;"DELETE LINE"
 2042 PRINT '"KEY SYMBOL SHIFT";TAB 18;"-For fast key"'"\u\u\u \u\u\u\u\u\u\u\u\u\u\u\u";TAB 18;" response,"
 2044 PRINT " A  STOP";TAB 18;" turn off BEEP"
 2046 PRINT " Q  MENU";TAB 18;" and STATUS."
 2048 PRINT " U  UNDERLINE"
 2090 PRINT #1;AT 0,0;"COPY?"
 2092 PAUSE 0: IF INKEY$="y" THEN COPY : RETURN 
 2098 RETURN 
 2100 REM SAVE/LOAD
 2102 ON ERR GO TO 2170: POKE 23562,5
 2104 GO SUB 2190
 2110 PAUSE 0: LET a=PEEK 23560: PRINT AT 20,0;e$: IF a<49 OR a>53 THEN GO TO 2110
 2112 GO TO 2120+10*(a-49)
 2120 REM SAVE FILE
 2122 INPUT "FILE NAME: ";q$: IF q$="" THEN GO TO 2104
 2124 SAVE q$ DATA f$()
 2125 GO SUB 2190: PRINT AT 20,0;"VERIFY? (y/n) ": PAUSE 0: IF INKEY$="y" THEN PRINT "REWIND, then press PLAY": VERIFY q$ DATA f$(): GO SUB 2190: PRINT AT 20,0;"VERIFY OK.": GO TO 2110
 2126 GO TO 2110
 2130 REM SAVE PR & FL
 2132 INPUT " ENTER PROGRAM NAME: ";q$: IF q$="" THEN LET q$="TYPEWRITER"
 2134 SAVE q$ LINE 20
 2135 GO TO 2145
 2140 REM SAVE PROG
 2142 PRINT AT 20,0;"ARE YOU SURE?": PAUSE 0: IF INKEY$<>"y" THEN GO TO 2110
 2144 PRINT AT 20,0;e$: LET bmax=1: DIM f$(1): SAVE "TYPEWRITER"
 2145 GO SUB 2190: PRINT AT 20,0;"VERIFY? (y/n) ": PAUSE 0: IF INKEY$="y" THEN PRINT AT 20,0;"REWIND, then press PLAY": VERIFY "": GO SUB 2190: PRINT AT 20,0;"VERIFY OK.": GO TO 2110
 2146 GO TO 2110
 2147 GO TO 20
 2150 REM LOAD FILE
 2151 INPUT "Enter File Name: ";q$: PRINT AT 20,0;"LOADING ";q$
 2152 LOAD q$ DATA f$()
 2153 BEEP .01,25: LET bmax=LEN f$(): LET lmax=INT (bmax/32)
 2154 PRINT AT 20,0;e$;AT 20,0;q$;" LOADED.   ": GO TO 2110
 2160 REM RETURN
 2162 IF bmax<2 THEN GO TO 3000
 2164 GO TO 20
 2170 GO SUB 2190: PRINT AT 20,0;"TAPE ERROR...or BREAK pressed.": GO TO 2110
 2190 REM SL-MENU
 2192 CLS : PRINT AT 0,0;"     *** SAVE / LOAD ***"
 2194 PRINT ''"1: SAVE FILE"''"2: SAVE PROGRAM AND FILE"''"3: CLEAR FILE AND SAVE PROGRAM"''"4: CLEAR FILE AND LOAD FILE"''"5: RETURN"
 2196 RETURN 
 3000 REM INITIALIZATION
 3005 BORDER 0: PAPER 0: INK 7: CLS 
 3010 PRINT AT 0,5;"*** TYPEWRITER ***"
 3011 PRINT AT 10,0;"Greetings! You have no file."''"Please tell me how big"'"a file you need...that is,"'"how many lines maximum: from"'"1 to 320:"''"(A large file takes longer to"'"save on tape.)"
 3012 INPUT "FILE SIZE (1-320): ";lmax: LET lmax=INT lmax: IF lmax<1 OR lmax>320 THEN PRINT "Please Try again.": GO TO 3012
 3013 CLS 
 3015 DIM t$(32): LET wrap=1: LET cs=0: LET s=1: LET beep=1: LET e$="                                "
 3016 FOR i=1 TO 32 STEP 4: LET t$(i)="1": NEXT i
 3017 POKE 65528,255: FOR i=65529 TO 65535: POKE i,0: NEXT i
 3018 LET bmax=32*lmax: DIM f$(bmax): LET by=1
 3040 CLS : PRINT AT 10,0;"Your file has ";lmax;" lines."''"Would you like to see the menu?"
 3042 PAUSE 0: IF INKEY$="y" THEN GO SUB 2000: GO TO 20
 3098 GO TO 20
 4000 REM print 80-col
 4010 GO TO 350
 5000 REM spare control
 5010 GO TO 350

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

Scroll to Top