Tag: Apple II BASIC

  • Word Processors in BASIC, Part 1

    Word Processors in BASIC, Part 1

    Quickwriter

    Found in June 1988 issue of Nibble magazine (Volume 9, Number 6).

    Archive.org link here.

    The project was alerted to the existence of a few text editors and word processors in Nibble magazine by someone on matrix.

    What we found was a great wealth of BASIC programs for the Apple II computer. We uncovered several particularly interesting BASIC word processors. Two that are of particular interest are Quickwriter and Nibblewriter.

    Both programs are quite long and involved, so instead of creating one enormous post, we decided to split the discussion up into two feature posts.

    diskM8 File Dump

    Please find an ASCII conversion of the BASIC dump obtained using the following commands:

    $ diskm8 -ingest /path/to/your/disk/images
    $ diskm8 -search "quickwriter"
    $ diskm8 -with-disk "your_disk_image.do" -file-extract "QUICKWRITER.BAS"

    Code Listing

    10  REM **********************
    20  REM *     TYPEWRITER     *
    30  REM *  BY JAMES D EVANS  *
    40  REM * COPYRIGHT (C) 1988 *
    50  REM * BY MICROSPARC, INC *
    60  REM * CONCORD, MA  01742 *
    70  REM **********************
    80  HIMEM: 38144:X =  FRE (0)
    90  ONERR  GOTO 2740
    100  GOSUB 2220
    110  GOTO 230
    120  REM **WARMSTART 80-COL CARD**
    130  ON  NOT PD GOTO 140: PRINT D$;"PR#A$C307": GOTO 150
    140  POKE 54,7: POKE 55,195: CALL 1002: PRINT 
    150  RETURN 
    160  REM **GET CHAR ROUTINE**
    170  POKE  - 16368,0: ON  NOT PLUS GOTO 180: PRINT  CHR$ (0);: GET A$: ON  NOT  LEN (A$) GOTO 170:B =  ASC (A$): GOTO 190
    180  INVERSE : PRINT " ";BS$;: NORMAL : WAIT  - 16384,128:B = ( PEEK ( - 16384) - 128):A$ =  CHR$ (B): POKE  - 16368,0: PRINT " ";BS$;: ON  NOT B GOTO 180
    190  RETURN 
    200  REM 
    210  REM ***MAIN PROGRAM***
    220  REM 
    230  FOR I = M TO M + 80: POKE I,160: NEXT 
    240  GOSUB 850: GOSUB 2050
    250 C = LM:LL = 0: POKE  - 16368,0
    260  VTAB 2: POKE H,C: INVERSE : PRINT  CHR$ ( PEEK (M + (C - LM)));: NORMAL : POKE H,C: PRINT  CHR$ (24);: ON  NOT PLUS GOTO 270: GET A$: GOTO 280
    270  WAIT  - 16384,128:A$ =  CHR$ ( PEEK ( - 16384) - 128): POKE  - 16368,0
    280  IF A$ < " " OR A$ =  CHR$ (127) THEN  GOSUB 330: GOTO 260
    290  PRINT A$: POKE M + C - LM, ASC (A$) + 128
    300 C = C + (C < RM - 1):LL = LL + (LL < RM - LM): POKE H,5: PRINT C + 1;" "
    310  GOTO 260
    320  REM **CTRL-CHAR EVALUATION**
    330  ON ( LEN (A$) = 0) GOTO 610: PRINT  CHR$ ( PEEK (M + (C - LM))); CHR$ (24)
    340  IF A$ =  CHR$ (127) THEN A$ =  CHR$ (4): ON C = LM GOTO 610:C = C - 1: POKE H,5: PRINT C + 1;" "
    350  IF A$ =  CHR$ (4) AND (LL + LM + 1) > C THEN LL = LL - 1: POKE M + RM - LM,160: FOR I = M + C - LM TO M + LL + 1: POKE I, PEEK (I + 1): NEXT : VTAB 2: POKE H,LM: POKE 8,RM - LM: CALL 768: PRINT : GOTO 610
    360  ON A$ <  >  CHR$ (15) OR C = (RM - 1) GOTO 370:LL = LL + (LL < (RM - LM - 1)): FOR I = M + LL TO M + C - LM STEP  - 1: POKE I, PEEK (I - 1): NEXT : POKE M + C - LM,160: VTAB 2: POKE H,LM: POKE 8,RM - LM: CALL 768: PRINT : GOTO 610
    370  IF A$ =  CHR$ (8) THEN C = C - (C > LM): POKE H,5: PRINT C + 1;" ": GOTO 610
    380  IF A$ =  CHR$ (21) THEN C = C + (C < RM - 1): POKE H,5: PRINT C + 1" ":LL = LL + ((C + 1 - LM) > LL): GOTO 610
    390  IF A$ =  CHR$ (9) THEN  GOSUB 940: GOTO 610
    400  IF A$ =  CHR$ (20) THEN TB(C + 1) =  NOT TB(C + 1):X = 160 * ( NOT TB(C + 1)) + 252 * (TB(C + 1)): PRINT : VTAB 4: POKE H,C: PRINT  CHR$ (X): GOTO 610
    410  IF A$ =  CHR$ (13) THEN  GOSUB 660: POP : GOTO 250
    420  IF A$ =  CHR$ (22) THEN RF = 1: VTAB 6: POKE H,20: PRINT "REVERSE LINEFEEDS ENABLED -- PRESS RETURN ";: GOSUB 170: PRINT : VTAB 6: PRINT LC$: GOTO 610
    430  IF A$ =  CHR$ (18) THEN A$ =  CHR$ (93): VTAB 2: POKE H,C: POP : GOTO 290
    440  IF A$ =  CHR$ (12) THEN A$ =  CHR$ (91): VTAB 2: POKE H,C: POP : GOTO 290
    450  IF A$ =  CHR$ (2) THEN A$ =  CHR$ (92):US = 1: VTAB 2: POKE H,C: PRINT A$: POKE M + C - LM,92: POP : GOTO 300
    460  IF A$ =  CHR$ (14) THEN A$ =  CHR$ (64): VTAB 2: POKE H,C: POP : GOTO 290
    470  IF A$ =  CHR$ (26) THEN  GOSUB 990: GOTO 610
    480  IF A$ =  CHR$ (7) THEN A$ =  CHR$ (95): VTAB 2: POKE H,C: POP : GOTO 290
    490  IF A$ =  CHR$ (24) THEN  GOSUB 1850
    500  IF A$ =  CHR$ (10) THEN  GOSUB 1260: POP : GOTO 260
    510  IF A$ =  CHR$ (19) THEN C = LM: PRINT : VTAB 3: POKE H,5: PRINT C + 1;" ": GOTO 610
    520  ON A$ <  >  CHR$ (5) GOTO 550: FOR I = M + (RM - LM - 1) TO M STEP  - 1: IF  PEEK (I) <  > 160 THEN C = LM + I - M + ((I - M) < (RM - LM - 1)):I = M: GOTO 540
    530  NEXT 
    540  PRINT : VTAB 3: POKE H,5: PRINT C + 1;" ": GOTO 610
    550  IF A$ =  CHR$ (23) THEN  GOSUB 1640: GOTO 610
    560  IF A$ =  CHR$ (6) THEN  GOSUB 1780: GOTO 610
    570  IF A$ =  CHR$ (16) THEN  GOSUB 1170: POP : GOTO 260
    580  IF A$ =  CHR$ (17) THEN  GOSUB 1340: GOTO 610
    590  IF A$ =  CHR$ (27) AND (C < (RM - 1)) THEN  GOSUB 1900: GOTO 610
    600  IF A$ =  CHR$ (30) THEN  GOSUB 2000
    610  RETURN 
    620  REM 
    630  REM ***UTILITY SUBROUTINES***
    640  REM 
    650  REM **PRINT LINE**
    660 X$ = "":X =  VAL (X$) +  PEEK (131) + 256 *  PEEK (132): POKE X,RM - LM: POKE X + 1,(M -  INT (M / 256) * 256): POKE X + 2, INT (M / 256):X$ =  MID$ (X$,1):AP$(R) = X$
    670  PRINT : PRINT D$;"PR#";SL
    680  PRINT  CHR$ (9);"80N";
    690  PRINT  TAB( LM);
    700  ON US GOTO 720
    710  PRINT AP$(R): GOTO 790
    720 J = 1
    730  FOR I = M TO M + LL
    740  ON  PEEK (I) <  > 92 GOTO 760:J =  NOT J: ON J GOTO 750: PRINT U1$;: GOTO 770
    750  PRINT U2$;: GOTO 770
    760  PRINT  CHR$ ( PEEK (I));
    770  NEXT 
    780  PRINT U2$
    790 R = R + 1:US = 0
    800  ON SP < 2 GOTO 810: PRINT : ON SP < 3 GOTO 810: PRINT : ON SP < 4 GOTO 810: PRINT 
    810  GOSUB 130
    820  GOSUB 870
    830  RETURN 
    840  REM **WINDOW**
    850  PRINT CL$
    860  FOR I = 1 TO LM: PRINT  CHR$ (255);: NEXT : POKE H,RM: FOR I = RM TO 79: PRINT  CHR$ (255);: NEXT 
    870  VTAB 1: POKE H,LM: POKE 8,RM - LM: CALL 768: PRINT 
    880  FOR I = M TO M + 80: POKE I,160: NEXT : VTAB 2: POKE H,LM: POKE 8,RM - LM: CALL 768: PRINT 
    890  VTAB 3: PRINT "COL: ";LM + 1;" "
    900  VTAB 5: PRINT "LINE:";R
    910  IF R > 300 THEN  VTAB 10: POKE H,19: PRINT  CHR$ (7);"NO MORE ROOM!  RESTART PROGRAM."
    920  RETURN 
    930  REM **TAB**
    940  FOR I = C + 1 + (C < RM - 1) TO RM - 1:C = I * TB(I) - 1: ON C > 0 GOTO 960: NEXT 
    950 C = RM - 1
    960 I = RM - 1: PRINT : VTAB 3: POKE H,5: PRINT C + 1: IF C + 1 > LL THEN LL = C + 1 - LM
    970  RETURN 
    980  REM **CENTER TEXT**
    990  PRINT : VTAB 6: POKE H,23: PRINT "CENTERING.....": PRINT : VTAB 2
    1000  FOR I = 0 TO LL
    1010  IF  PEEK (M + I) <  > 160 THEN X = I:I = LL: GOTO 1030
    1020  NEXT : GOTO 1140
    1030 Y = 0: FOR I = RM - LM - 1 TO 0 STEP  - 1
    1040 Y = Y + 1: IF  PEEK (M + I) <  > 160 THEN Y = Y - 1:I = 0: GOTO 1060
    1050  NEXT 
    1060 XL = RM - LM - X - Y: REM STRING LENGTH     
    1070 K = 0: FOR J = M + X TO M + X + XL - 1:K = K + ( PEEK (J) < 128): NEXT : REM HANDLE <ESC> AND UNDERLINE CODES
    1080 A = M + X:X$ = "":B =  VAL (X$) +  PEEK (131) + 256 *  PEEK (132): POKE B,XL: POKE B + 1,A -  INT (A / 256) * 256: POKE B + 2, INT (A / 256):X$ =  MID$ (X$,1)
    1090 J = 0:T =  INT ((RM - LM - XL - K) / 2) + K: IF (T + XL) > (RM - LM) THEN  PRINT : VTAB 6: POKE H,9: PRINT  CHR$ (7);"TOO MANY <ESC> CODES TO CENTER. PRESS RETURN TO RESUME TYPING ";: GOSUB 170: PRINT : VTAB 6: PRINT LC$: GOTO 1150
    1100  FOR I = M + X TO M + X + XL: POKE I,160: NEXT :
    1110  FOR I = M + T TO M + T + XL - 1:J = J + 1: POKE I, ASC ( MID$ (X$,J)): NEXT 
    1120  POKE H,LM: POKE 8,RM - LM: CALL 768
    1130 LL = T + XL:C = LM + T + XL: IF C >  = RM THEN C = C - 1
    1140  PRINT : VTAB 6: PRINT LC$: VTAB 3: POKE H,5: PRINT C + 1;" "
    1150  RETURN 
    1160  REM **PRINT TEST PATTERN**
    1170  PRINT : PRINT D$;"PR#";SL
    1180  PRINT  CHR$ (9);"80N";
    1190  PRINT  TAB( LM)"." TAB(  INT (((RM - LM) / 2) - 1))"." TAB(  INT (((RM - LM) / 2)))".";
    1200  IF  NOT RF THEN  PRINT : GOTO 1230
    1210  PRINT RF$
    1220  PRINT FF$
    1230  GOSUB 130
    1240  RETURN 
    1250  REM **ISSUE REVERSE LINEFEED**
    1260  ON  NOT RF GOTO 1320
    1270  PRINT : PRINT D$;"PR#";SL
    1280  PRINT  CHR$ (9);"80N";
    1290  PRINT RF$: PRINT RF$
    1300  PRINT FF$
    1310  GOSUB 130
    1320  RETURN 
    1330  REM **QUIT?**
    1340  PRINT : VTAB 8: POKE H,19: PRINT "Q)UIT   R)ESUME   S)TART ANEW": PRINT : HTAB 20: PRINT "PRESS Q, R, OR S:";: GOSUB 170:A$ =  CHR$ ( ASC (A$) - 32 * (A$ > "S"))
    1350  IF A$ = "Q" THEN  GOSUB 1390: PRINT CL$: END 
    1360  IF A$ = "R" THEN  PRINT : VTAB 8: PRINT LC$: VTAB 10: PRINT LC$: RETURN 
    1370  IF A$ = "S" THEN  GOSUB 1390: RUN 
    1380  GOTO 1340
    1390  PRINT : VTAB 8: PRINT LC$: VTAB 10: PRINT LC$;: POKE H,19: PRINT "SAVE THIS DOCUMENT? (Y/N)";: GOSUB 2870
    1400  IF A$ <  > "Y" AND A$ <  >  CHR$ (121) THEN 1620
    1410  PRINT : VTAB 10: PRINT LC$;: POKE H,19: PRINT "ENTER DOCUMENT NAME: ";: FOR I = 1 TO 15: PRINT "_";: NEXT 
    1420 HZ = 0:FL$ = "": POKE H,40
    1430  GOSUB 170: ON A$ >  CHR$ (31) GOTO 1480
    1440  ON A$ =  CHR$ (13) GOTO 1500
    1450  IF A$ =  CHR$ (8) AND (FL$ = "" OR  LEN (FL$) = 1) THEN 1410
    1460  IF A$ =  CHR$ (8) THEN HZ = HZ - 1: POKE H, PEEK (H) - 1:FL$ =  MID$ (FL$,1, LEN (FL$) - 1): GOTO 1430
    1470  ON A$ =  CHR$ (27) GOTO 1410: ON A$ < " " GOTO 1430
    1480  ON HZ = 15 GOTO 1430: IF A$ >  CHR$ (95) THEN A$ =  CHR$ ( ASC (A$) - 32)
    1490 FL$ = FL$ + A$: PRINT A$;:HZ = HZ + 1: GOTO 1430
    1500  ON FL$ = "" GOTO 1620
    1510  IF  MID$ (FL$,1,1) < "A" THEN  PRINT : VTAB 10: POKE H,19: PRINT LC$;"INVALID NAME -- PRESS RETURN TO REENTER ";: GOSUB 170: GOTO 1410
    1520  FOR I = 1 TO  LEN (FL$):X$ =  MID$ (FL$,I,1): IF X$ = " " THEN FL$ =  LEFT$ (FL$,I - 1) + "." +  RIGHT$ (FL$, LEN (FL$) - I): GOTO 1540
    1530  IF ((X$ < "0") AND (X$ <  > ".")) OR ((X$ > "9") AND (X$ < "A")) OR (X$ > "Z") THEN  PRINT : VTAB 10: POKE H,19: PRINT LC$;"INVALID NAME -- PRESS RETURN TO REENTER ";: GOSUB 170: GOTO 1410
    1540  NEXT 
    1550  PRINT : PRINT D$;"OPEN ";FL$;",D1"
    1560  PRINT D$;"CLOSE ";FL$
    1570  PRINT D$;"DELETE ";FL$;",D1"
    1580  PRINT D$;"OPEN "FL$;",D1"
    1590  PRINT D$;"WRITE ";FL$
    1600  FOR I = 1 TO R: PRINT AP$(I): NEXT 
    1610  PRINT D$;"CLOSE"
    1620  RETURN 
    1630  REM **SET MARGINS**
    1640  PRINT : VTAB 8: POKE H,19: PRINT "LEFT MARGIN...": VTAB 10: POKE H,19: PRINT "<-  ->    <RETURN> = ACCEPT"
    1650  PRINT : VTAB 3: POKE H,5: PRINT LM;" ": VTAB 2: POKE H,LM: PRINT  CHR$ (0);: GOSUB 170
    1660  IF A$ =  CHR$ (8) THEN LM = LM - (LM > 1): PRINT : VTAB 2: POKE H,LM: PRINT " "
    1670  IF A$ =  CHR$ (21) OR A$ =  CHR$ (32) THEN  IF LM < (RM - 2) THEN  PRINT : VTAB 2: POKE H,LM: PRINT  CHR$ (255):LM = LM + 1
    1680  IF A$ <  >  CHR$ (13) THEN 1650
    1690  PRINT : VTAB 8: POKE H,19: PRINT "RIGHT MARGIN..."
    1700  PRINT : VTAB 3: POKE H,5: PRINT RM;" ": VTAB 2: POKE H,RM - 1: PRINT  CHR$ (0);: GOSUB 170
    1710  IF A$ =  CHR$ (8) THEN RM = RM - (RM > LM + 2): PRINT : VTAB 2: POKE H,RM: PRINT  CHR$ (255)
    1720  IF A$ =  CHR$ (21) OR A$ =  CHR$ (32) THEN RM = RM + (RM < 79): PRINT : VTAB 2: POKE H,RM - 1: PRINT " "
    1730  IF A$ <  >  CHR$ (13) THEN 1700
    1740  PRINT : VTAB 8: PRINT LC$: VTAB 10: PRINT LC$
    1750 C = LM: PRINT : VTAB 3: POKE H,5: PRINT C + 1;" ": VTAB 2: POKE H,LM: POKE 8,RM - LM: CALL 768: PRINT 
    1760  RETURN 
    1770  REM **SELECT LINE SPACING**
    1780  PRINT : VTAB 10: POKE H,6: PRINT "ENTER NUMBER OF SPACES BETWEEN LINES (1-4):" SPC( 4)"(CURRENT=";SP;")";: POKE H,49: GOSUB 170
    1790  IF A$ =  CHR$ (13) THEN  GOTO 1820
    1800  IF A$ < "1" OR A$ > "4" THEN 1780
    1810 SP =  VAL (A$)
    1820  PRINT : VTAB 10: PRINT LC$
    1830  RETURN 
    1840  REM **TRUNCATE LINE**
    1850  VTAB 6: POKE H,14: PRINT "OKAY TO ERASE TEXT FROM CURSOR TO END OF LINE? (Y/N) ": VTAB 2: POKE H,C: GOSUB 170: ON (A$ = "N" OR A$ =  CHR$ (110)) GOTO 1870: IF A$ <  > "Y" AND A$ <  >  CHR$ (121) THEN 1850
    1860  FOR I = M + C - LM TO M + LL - 1: POKE I,160: NEXT : VTAB 2: POKE H,C: FOR I = 1 TO RM - C: PRINT " ";: NEXT :LL = C - LM: PRINT 
    1870  PRINT : VTAB 6: PRINT LC$
    1880  RETURN 
    1890  REM **ENTER <ESC> CODE**
    1900 A = C: VTAB 6: POKE H,13: PRINT "TYPE <ESC> CODE & PRESS <RETURN> TO RESUME TEXT ENTRY"
    1910  VTAB 2: POKE H,C: GOSUB 170: IF A$ =  CHR$ (13) THEN  PRINT : GOTO 1970
    1920  IF A$ =  CHR$ (8) THEN B =  PEEK (M + C - LM): POKE H,C: PRINT  CHR$ (B + 227 * (B = 27)):C = C - (C > A): POKE M + C - LM,160: VTAB 2: POKE H,C: PRINT " ": GOTO 1960
    1930  IF B < 27 THEN 1910
    1940  POKE M + C - LM,B:B = B + 227 * (B = 27): INVERSE : VTAB 2: POKE H,C: PRINT  CHR$ (B): NORMAL 
    1950 C = C + (C < RM - 1):LL = LL + (LL < C)
    1960  POKE H,5: PRINT C + 1;" ": GOTO 1910
    1970  VTAB 6: PRINT LC$
    1980  RETURN 
    1990  REM **CTRL-CODE TO PRINTER**
    2000  VTAB 6: POKE H,17: PRINT "TYPE CONTROL-CHARACTER TO BE SENT TO PRINTER: ";: GOSUB 170: ON ((B > 26) OR (B = 13)) GOTO 2020
    2010  PRINT : PRINT D$;"PR#";SL: PRINT  CHR$ (9);"80N";: PRINT A$;: GOSUB 130
    2020  PRINT : VTAB 6: PRINT LC$: IF B < 26 AND B <  > 13 THEN  VTAB 4: POKE H,79: INVERSE : PRINT  CHR$ (B + 64): NORMAL 
    2030  RETURN 
    2040  REM **HELP SCREEN**
    2050  PRINT : VTAB 11: FOR I = 1 TO 80: PRINT U$;: NEXT 
    2060  PRINT "<CTRL-B>: "; CHR$ (92);" (UNDERLINE TEXT)";: POKE H,39: PRINT V$ + " <CRTL-P>: PRINT TEST PATTERN"
    2070  PRINT "<CTRL-D>: CLOSE LINE (DELETE CHAR)";: POKE H,39: PRINT V$ + " <CTRL-Q>: QUIT OR START ANEW"
    2080  PRINT "<CTRL-E>: JUMP TO LAST CHARACTER";: POKE H,39: PRINT V$ + " <CTRL-R>: TYPE "; CHR$ (93)
    2090  PRINT "<CTRL-F>: SET PRINTER LINE SPACING";: POKE H,39: PRINT V$ + " <CTRL-S>: JUMP TO LINE START"
    2100  PRINT "<CTRL-G>: TYPE "; CHR$ (95);: POKE H,39: PRINT V$ + " <CTRL-T>: SET OR CLEAR TAB STOP"
    2110  PRINT "<CTRL-I>: TAB";: POKE H,39: PRINT V$ + " <CTRL-V>: ENABLE REVERSE LINEFEEDS"
    2120  PRINT "<CTRL-J>: REVERSE PRINTER LINEFEED";: POKE H,39: PRINT V$ + " <CTRL-W>: SET LINE WIDTH (MARGINS)"
    2130  PRINT "<CTRL-L>: TYPE "; CHR$ (91);: POKE H,39: PRINT V$ + " <CTRL-X>: ERASE TO END OF LINE "
    2140  PRINT "<CTRL-N>: TYPE "; CHR$ (64);: POKE H,39: PRINT V$ + " <CTRL-Z>: CENTER TEXT"
    2150  PRINT "<CTRL-O>: OPEN LINE";: POKE H,39: PRINT V$ + " <DELETE>: DESTRUCTIVE BACKSPACE"
    2160  PRINT "<CTRL-^>: SEND CONTROL CHAR TO PRINTER";: POKE H,39: PRINT V$ + " <ESC>   : EMBED PRINTER <ESC> CODES"
    2170  FOR I = 1 TO 80: PRINT U$;: NEXT 
    2180  RETURN 
    2190  REM 
    2200  REM ***GLOBAL SETUP***
    2210  REM 
    2220  TEXT : HOME 
    2230  DIM TB(80),AP$(300): REM TAB STOP AND TEXT STRING ARRAYS
    2240  REM **INSTALL BUFFER PRINTER**
    2250  FOR I = 768 TO 792: READ X: POKE I,X: NEXT 
    2260  DATA 169,149,133,7,160,0,132,6,177,6,201,27,208,2,169,126,32,7,195,200,196,8,208,240,96
    2270  REM **MACHINE AND DOS ID**
    2280 PLUS = ( PEEK (64435) = 234 OR  PEEK (64435) = 56):PD = ( PEEK (48640) = 76): REM IF PLUS THEN II OR II+; IF PD THEN PRODOS
    2290  REM ***PRINTER CODES***
    2300 U1$ =  CHR$ (27) +  CHR$ (88): REM ESC+X TURNS ON UNDERLINE
    2310 U2$ =  CHR$ (27) +  CHR$ (89): REM ESC+Y TURNS OFF UNDERLINE
    2320 FF$ =  CHR$ (27) +  CHR$ (102): REM ESC+LOWERCASE F ACTIVATES FORWARD LINEFEEDS
    2330 RF$ =  CHR$ (27) +  CHR$ (114): REM ESC+LOWERCASE R ACTIVATES REVERSE LINEFEEDS
    2340  REM **ALL-PURPOSE REALS**
    2350 I = 0:J = 0:K = 0:X = 0:Y = 0
    2360  REM **DEDICATED REALS**
    2370 SL = 1: REM PRINTER SLOT
    2380 RF = 0: REM REVERSE LINEFEED FLAG
    2390 R = 1: REM ROW
    2400 C = 1: REM COLUMN
    2410 LM = 5: REM LEFT MARGIN
    2420 RM = 75: REM RIGHT MARGIN
    2430 LL = 0: REM LINE LENGTH
    2440 M = 38144: REM START OF TEXT BUFFER
    2450 H = 1403: REM HORZ POSITION
    2460 SP = 1: REM DEFAULT LINE SPACING
    2470  REM **STRING EQUIVALENTS**
    2480 X$ = ""
    2490 V$ =  CHR$ (252)
    2500 U$ =  CHR$ (95)
    2510 D$ =  CHR$ (4)
    2520 CL$ =  CHR$ (12): REM CLEAR SCREEN
    2530 LC$ =  CHR$ (29): REM CLEAR LINE
    2540 BS$ =  CHR$ (8): REM BACKSPACE
    2550  REM   
    2560  REM ***TITLE***
    2570  REM   
    2580  VTAB 4: HTAB 9: PRINT "TURN ON PRINTER OR....": HTAB 6: PRINT "PRESS PRINTER 'SELECT' BUTTON."
    2590  PRINT D$;"PR#1": PRINT 
    2600  HOME : POKE 1912,0
    2610  PRINT D$;"PR#3": PRINT CL$
    2620 A$ = "TYPEWRITER"
    2630 CL =  - 16336: SPEED= 150
    2640  VTAB 6: POKE H,31: FOR I = 1 TO 10: PRINT  MID$ (A$,I,1) + " ";:X =  PEEK (CL) +  PEEK (CL) +  PEEK (CL) +  PEEK (CL) +  PEEK (CL): NEXT 
    2650  SPEED= 255
    2660  PRINT : VTAB 10: POKE H,32: PRINT "BY JAMES D EVANS"
    2670  VTAB 14: POKE H,24: PRINT "COPYRIGHT 1988 BY MICROSPARC, INC."
    2680  VTAB 16: POKE H,27: PRINT "* PRESS <RETURN> TO BEGIN *";
    2690  POKE  - 16368,0: WAIT  - 16384,128: POKE  - 16368,0
    2700  RETURN 
    2710  REM 
    2720  REM ***ERROR TRAP***
    2730  REM 
    2740  POKE 216,0:EC =  PEEK (222):LN =  PEEK (218) +  PEEK (219) * 256: CALL 54915
    2750  PRINT : VTAB 10
    2760  IF EC = 4 THEN  PRINT "DISK IS WRITE-PROTECTED -- PLEASE REMOVE TAB FROM NOTCH ";: GOTO 2830
    2770  IF EC = 8 THEN  PRINT "DISK I/O ERROR -- PLEASE CHECK DISK AND DRIVE ";: GOTO 2830
    2780  IF EC = 9 THEN  PRINT "DISK IS FULL -- PLEASE INSERT A DIFFERENT DISK ";: GOTO 2830
    2790  IF EC = 10 THEN  PRINT "FILE LOCKED -- PLEASE THINK OF A DIFFERENT FILE NAME ";: GOTO 2830
    2800  IF EC = 11 THEN  PRINT "ILLEGAL FILE NAME -- PLEASE THINK OF A DIFFERENT NAME ";: GOTO 2830
    2810  IF EC = 255 THEN  PRINT "<CTRL-C> IS NOT AN ACCEPTABLE KEYSTROKE -- PLEASE NOTE ";: GOTO 2830
    2820  PRINT "ERROR #";EC;" HAS OCCURRED IN LINE ";LN;" -- PLEASE NOTE ";
    2830  PRINT "AND HIT <RETURN> ->";
    2840  GOSUB 170: IF A$ <  >  CHR$ (13) THEN  GOTO 2840
    2850  PRINT : VTAB 10: PRINT LC$: ONERR  GOTO 2740
    2860  GOTO 260
    2870  GET A$: IF A$ <  > "Y" AND A$ <  > "N" AND A$ <  > "y" AND A$ <  > "n" THEN 2870
    2880  RETURN