Typewriter 64

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

This program is a full-featured word processor designed specifically for use with the OS-64 cartridge, which extends the display to 64 columns. It maintains a flat string array (f$) as the document buffer, sized by the user at startup from 1 to 150 lines of 64 characters each (up to 9,600 bytes). The editor supports cursor movement, word-wrap, tab stops, line insertion and deletion, jump-to-line navigation, and both SAVE/LOAD of the file data and the program itself to tape. A two-level key command system (Level One for direct editing, Level Two accessed by a shifted key) provides additional functions including a print routine using LPRINT, an erase command, and a soft caps-lock implemented by POKEing system variable 23658. Status information including horizontal position, vertical position, and current line number is displayed in the lower border area using stream #1.


Program Analysis

Program Structure

The program is organized into clearly commented functional blocks, with a dispatch table driven by computed GO TO targets. Initialization runs once at line 3000, then control passes to the main editor loop at line 20. The overall flow is:

  1. Lines 3000–3098: Initialization — prompts for file size, allocates f$(bmax), sets defaults.
  2. Lines 20–98: Main display refresh and entry into the keypress loop.
  3. Lines 40–49: Key debounce and auto-repeat throttle loop.
  4. Lines 50–130: Printable character handler, word-wrap logic.
  5. Lines 140–290: Sparse jump table for control codes (computed GO TO 100+10*a).
  6. Lines 300–320: Caps-Shift / Symbol-Shift key dispatcher.
  7. Lines 400–442: Delete character with held-key repeat support.
  8. Lines 500–609: Level Two command menu — waits for a digit key and dispatches via GO TO 600+k-48.
  9. Lines 840–848: Jump-to-line function.
  10. Lines 1000–1044: Toggle switches (BEEP, STATUS, WRAP) and status-bar subroutine.
  11. Lines 1090–1094: Erase file command.
  12. Lines 1150–1158: LPRINT file or range to printer.
  13. Lines 1170–1177: Tab-stop setup.
  14. Lines 1380–1389: STOP / return-to-BASIC handler.
  15. Lines 2000–2098: Help menu with optional screen copy to printer.
  16. Lines 2100–2196: SAVE / LOAD tape menu.
  17. Lines 4000–4040: 80-column screen copy via LPRINT SCREEN$.
  18. Lines 5000–5010: Spare/unused control stub.

Document Buffer Design

The entire document is stored as a single flat string f$ dimensioned to bmax characters, where bmax = 64 * lmax. Each logical line occupies exactly 64 characters (matching the OS-64 cartridge column width), making line arithmetic trivial: line n starts at 1 + 64*(n-1). The cursor position within the buffer is tracked solely by the integer variable by. A 64-character blank string e$ is used as a fill/shift register throughout insert and delete operations.

OS-64 Cartridge Integration

The program explicitly targets the OS-64 cartridge, which remaps the display to 64 columns. All column arithmetic uses 64 as the line width, and screen position is read back from the cartridge’s system variables rather than the standard ones. POKEs to addresses around 63416–63423 at line 3017 appear to configure cartridge hardware or workspace. The status bar is written to stream #1 (the lower two-line area), keeping it separate from the main 22-line editing area.

System Variable Usage

The program makes heavy use of POKEs and PEEKs to system variables to read and restore the current print position, enabling it to save cursor coordinates, perform screen output, and then restore the cursor exactly:

AddressStandard meaningUse in program
23560Last key pressed (LAST K)Read after PAUSE 0 for menu keypresses
23562REPDEL / FLAGS2Set to 1 (enable key repeat) or 5 (disable)
23658FLAGS (caps/shift)POKEd to 8 to enable caps lock, 0 to clear
23684–23685Display file / print position high bytesSaved and restored around screen writes
23688Column of print position (S_POSN)Extensively read for horizontal cursor position
23689Row of print position (S_POSN)Extensively read for vertical cursor position

Saving and restoring s1s4 from these addresses before and after print operations (e.g. lines 414–424, 254–256) is the core technique used to keep the logical cursor position independent of any side-effects of PRINT.

Key Input and Debounce

The main input loop at lines 40–49 implements a software debounce and auto-repeat throttle. When a new key is detected (a<>b), a counter c is set to 12; subsequent loops decrement c before accepting another event, preventing accidental repeats. The variable a holds the last accepted key code. Fast-repeat for the delete key (lines 430–442) uses a secondary counter dcnt and polls hardware ports directly with IN 61438 and IN 65278 to detect the key combination being held.

Control-Code Dispatch Table

At line 301, control characters (codes 1–31) are dispatched with the idiom GO TO 100+10*a, mapping each code to a decade of line numbers:

Code (a)Target lineFunction
4140TAB
5150JUMP
6160CAPS LOCK toggle
7170Level Two command mode
8180LEFT
9190RIGHT
10200DOWN
11210UP
12220DELETE character
13230ENTER / newline
15250INSERT SPACE
others260–290GO TO 40 (ignored)

Word-Wrap Algorithm

When word-wrap is enabled (wrap=1), after a character is typed near the right margin (column ≤ 2, line ≥ 5 from bottom), the program scans backwards up to 20 characters for a space or hyphen (lines 112–114). If found, it shifts the tail of the word onto the next line by splicing e$(1 TO i) (spaces) in front of it in the buffer (line 116) and reprints the affected region.

Cursor Rendering

The text cursor is rendered in software using PRINT OVER 1; INVERSE 1;" ";CHR$ 8;. The OVER 1 attribute causes the cursor block to XOR with the character beneath it, making it visible on any background. CHR$ 8 (backspace) moves the print position back so the cursor remains under the current by position. This cursor is redrawn after virtually every editing operation.

Tape Save/Load

The tape menu (lines 2100–2196) offers five options. Option 1 saves only the file array with SAVE q$ DATA f$(). Option 2 saves the program with the file embedded using SAVE q$ LINE 20 (auto-start at line 20). Option 3 reduces bmax to 1 and re-dimensions f$ before saving, producing a compact program-only save. Option 4 loads a previously saved file array. A verify step is offered after each save. Error handling uses ON ERR GO TO to catch tape errors.

Notable Techniques and Anomalies

  • Line 26 clamps y to bmax on every display refresh, preventing out-of-bounds string slices when the buffer is small.
  • Line 87 uses a negative-offset slice f$(x-191 TO x) to display the preceding three lines when scrolling right — the offset of 191 is 3×64 minus 1, aligning to the 64-column grid.
  • Line 522 and line 1030 fill the status bar row with a string of \u UDG characters, which are presumably defined elsewhere (likely by the OS-64 cartridge) as a horizontal rule or separator graphic.
  • The ON ERR GO TO 40 at line 25 provides a global safety net, catching string-range errors that could occur if by reaches the buffer boundary.
  • The lmax variable is set to INT (bmax/32) after a file load (line 2153) — this is half the actual line count (since lines are 64 chars wide), suggesting a possible off-by-factor-of-two bug in the line count display after loading.
  • Lines 140 and 150 use bare GO TO to enter TAB and JUMP handlers; these lines are reachable only from the control-code dispatch table, making the REM comments on lines 140 and 150 serve as the only documentation of their entry points.
  • Line 5010 jumps to line 350, which does not exist in the listing — a placeholder for future expansion.

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 64

Source Code

    1 REM ***TYPEWRITER***FOR USE WITH OS-64 CARTRIDGE
    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
   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=1407: 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=64*INT ((by-1)/64)
   87 IF x<bmax-64 THEN BEEP .008,30: PRINT f$(x-191 TO x);: GO SUB 1030: GO TO 30
   88 PRINT f$(x-1279 TO x);: GO TO 30
   90 PRINT #1;AT 1,7;66-PEEK 23688;" ";AT 1,11;25-PEEK 23689;" ";AT 1,15;1+INT ((by-1)/64);"  "
   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<5 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 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-64)
  143 PRINT 'f$(by+x-1 TO by+x-3+64*(y-3));: PRINT AT 24-y,65-x;
  144 GO TO 500
  150 GO TO 840: REM jump
  152 REM DELETE LINE
  154 LET by=1+(64*INT (by/64)): POKE 23684,PEEK 23684-(65-PEEK 23688): POKE 23688,65
  155 LET f$(by TO bmax)=f$(by+64 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+64*(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=66-PEEK 23688: REM  TAB
  172 IF hp>63 THEN GO TO 175
  173 FOR i=hp+1 TO 64: 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 FOR i=66-PEEK 23688 TO tab: PRINT OVER 1;" ";: NEXT i
  179 LET by=1+(64*INT (by/64))+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,PEEK 23684-224: POKE 23685,PEEK 23685+8: LET by=by+64: GO TO 30
  204 POKE 23684,PEEK 23684+32: LET by=by+64: GO TO 30
  205 IF by>(bmax-64) THEN GO TO 40
  206 LET s1=PEEK 23688: LET s2=PEEK 23689: LET s3=PEEK 23684: LET s4=PEEK 23685: LET by=by+64: LET x=1+(64*INT (by/64))
  207 CLS : PRINT f$(x-1344 TO x+63);: 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-64: GO TO 30
  214 POKE 23684,PEEK 23684-32: LET by=by-64: GO TO 30
  215 IF by<65 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-64: LET x=1+(64*INT (by/64))
  217 CLS : PRINT f$(x TO x+1407);: 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=64*INT ((by-1)/64): IF x>=bmax-64 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=65+x: GO TO 30
  236 CLS : PRINT f$(x-1279 TO x+64);AT 21,0;: LET by=65+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
  404 LET dcnt=10
  410 IF by<2 THEN 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 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\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+(64*(fl-1))
  844 LET tb=by+1407: 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\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";66-PEEK 23688;" ";AT 1,10;"V";25-PEEK 23689;" ";AT 1,14;"L";1+INT ((by-1)/64);"  "
 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+(64*(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=64+(64*(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-64)/ENT=done: "; LINE q$: IF q$="" THEN GO SUB 1030: GO TO 500
 1172 DIM t$(64)
 1173 LET tab=INT VAL q$: IF tab<1 OR tab>64 THEN GO TO 1176
 1174 LET t$(tab)="1"
 1176 INPUT "SET TABS (1-64)/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-64"
 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 FILE"
 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 GO SUB 4000: 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 PAPER 7: CLS 
 3008 PRINT AT 0,15;"*** T Y P E W R I T E R  ***"
 3010 PRINT AT 1,11;"*** FOR USE WITH OS-64 CARTRIDGE ***"
 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 150: (A large file takes longer to"'"save on tape.)"
 3012 INPUT "FILE SIZE (1-150): ";lmax: LET lmax=INT lmax: IF lmax<1 OR lmax>150 THEN PRINT "Please Try again.": GO TO 3012
 3013 CLS 
 3015 DIM t$(64): LET wrap=1: LET cs=0: LET s=1: LET beep=1: LET e$="                                                                "
 3016 FOR i=1 TO 64 STEP 4: LET t$(i)="1": NEXT i
 3017 POKE 63416,255: FOR i=63417 TO 63423: POKE i,0: NEXT i
 3018 LET bmax=64*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 COPY 80-col
 4010 FOR x=0 TO 21: FOR y=0 TO 63
 4020 LPRINT SCREEN$ (x,y);
 4030 NEXT y: LPRINT : NEXT x
 4040 RETURN 
 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