Classic Computer Magazine Archive A.N.A.L.O.G. ISSUE 64 / SEPTEMBER 1988 / PAGE 23

Joytype
by John Pilge

Joytype is a replacement for the typewriter and is not a word processor. It is designed for people who cannot use a typewriter because of limited movement caused by stroke, cerebral palsy or injury. While you may not have a need to use it yourself, you may want to type it in for a friend or charity.

    You can also use some of the routines for later programs of your own (directory, printing, scrolling, etc.).
    The first step is to get a joystick the handicapped can use. Many prefer joysticks by Wico.

Instructions
    The first menu lets you choose the drive on which you will store files. Should you change your mind after making this selection, you return to this menu when you choose to erase a letter from the option menu.
    Typing is simple. Move the joystick (or trackball) to the letter of choice. Select the letter for printing by pressing the firebutton. Each space between the letters on the header can be used as a space (just like pressing the spacebar on a typewriter.)
    Special functions are on the bottom right of the header. Selecting either D or L is delete. C or R is a carriage return. E is an escape character. O, P or T changes the screen to the option menu. The triangle is a backspace. Backspace would usually be used for forming special characters (using "c" and "/" to make a cents marker) or underlining (if you don't know the escape commands for your printer).
    The option menu has functions to save a file, delete a file, load a file, print, type (returns you to the typing screen), erase the current letter and format a disk.
    To avoid mistakes, "FORMAT" doesn't work. If the person who uses the program has enough control and confidence to risk using FORMAT, merely delete Line 810 of the program, and FORMAT will work.
    The first command of the Option menu is "O.NOTHING" This is to prevent an accident in case the user still has the firebutton pressed at the time the screen is displayed.
    While directory will show all the files on disk, you cannot access any files with an extension (or any filename with a period). This is to prevent accidental deletion or loading of the DOS.SYS program or the JOYTYPE.BAS program (and the AUTORUN.SYS, if you have the program autoloaded).
    To select files for loading, savings, etc., a menu appears with the alphabet (uppercase only), a space on either side of the alphabet, an M to return to the Option menu and a DL to delete errors.
    Files can have up to eight letters in the filename. If a filename has less than eight letters, use spaces to make eight characters. A filename cannot start with a space. After eight characters have been selected, the file is acted on in accordance with your choice.
    Once the user has worked with the program, it may seem to be too slow. Line 1820 has the variable DLAY that controls the speed of some movements. You can change that number to as low as one or as high (slow) as needed.
    The left margin for printing is set on Line 1820 as the variable MRG$. You can set this in accordance to the needs of your printer. The printer line length is set by PLL on Line 1820.
    Joytype files can be checked with most spelling checker programs and can be read by most other word processors. There is a difference between return markers, but not text.

Who gets the program
    Just because you spent all night typing the program doesn't mean everyone will want it. You needed patience to type in the program, and you are going to need more patience finding someone to use it.
    You will find a lot of charities unable to use the program or willing to make it available to people who need it.
    Some charities are only able to deal with donations of money. Some only handle specific needs (such as raising money). Some can only accept programs on Apple or IBM no matter how inexpensive an Atari costs. You will learn a lot about the handicapped services of your community by trying to pass along this program. I have a letter from one local "charity" that doesn't want the program unless it is protected, and they can sell it.
    But at least you can make it known that the programs exists and is available to work on a sturdy and inexpensive Atari.
    You might be called on to modify the program. Larger characters on the screen is a popular request.. There is an easier fix than to rewrite the program. The characters get larger as the TV screen gets larger.
    If more than one letter appears as the fire button is pressed, try another joystick. Some joysticks have a rapid-fire ability that speeds up the response of the button. You could also move the button commands (STRIG) after the DLAY loops or make the DLAY value a higher number (slower). For any additions larger than 4K you may have to shorten the string length of LINE$, or you run out of memory.
    I would like to thank Jimmy Montoya, it'. (know locally as the "Wizard of OS" ) for his suggestions, and the Cabrillo College Stroke Center for their encouragement.

    John Pilge is your typical, fun-loving Atari computer owner who gets a thrill finding new uses for the Atari. He is known in Santa Cruz County as J.P. or Bladeruuner.

LISTING 1: BASIC
blue indicates inverse characters
QJ 0 REM *****************************
UL 1 REM *          JOYTYPE          *
CL 2 REM *       BY JOHN PILGE       *
GK 3 REM *                           *
ZZ 4 REM *    PUBLISHED IN ANALOG    *
SU 5 REM *    COMPUTING, SEPT. 88    *
QP 6 REM *****************************
GT 10 POKE 566,PEEK(5667+12
AP 20 REM LINE 1820 HAS DELAY, MARGIN AND
    PRINTER LINE LENGTH VARIABLES.
GL 40 REM POKES:77 15 ATTRACT MODE,84-85
   IS CURSOR POSITION,88-89 IS SCREEN MEM
   ORY
RS 50 TRAP 1930:GOTO 1800
XG 60 X=129:SCREEN=PEEK(88)+PEEK(89)*256
SA 70 FOR I=2 TO 38 STEP 2:POKE SCREEN+I,
   X:POKE SCREEN+(I+1),128:X=X+1:NEXT I
NR 80 FOR I=42 TO 65 STEP 2:POKE SCREEN+I
   ,X:POKE SCREEN+(I+1),128:X=X+I:NEXT I
UG 90 X=X+1:FOR I=66 TO 79 STEP 2:POKE SC
   REEK+I,X:POKE SCREEN+(I+1),128:X=X+1:N
   EXT I
LL 100 FOR I=82 TO 119 STEP 2:POKE SCREEN
   +I,X:POKE SCREEN+(I+1),128:X=X+1:NEXT
   I
IU 110 X=187:FOR I=122 TO 128 STEP 2:POKE
    SCREEN+I,H:POKE SCREEN+I+1,128:X=X+1:
   NEXT I
FJ 120 POKE SCREEN+130,191:POKE SCREEN+13
   1,128
PI 130 X=225:FOR I=132 TO 158 STEP 2:POKE
    SCREEN+I,X:POKE SCREEN+(I+1),128:X=X+
   1:NEXT I
MO 140 FOR I=162 TO 184 STEP 2:POKE SCREE
   N+I,X:POKE SCREEN+(I+1),128:X=X+1:NEXT
    I
DQ 150 POKE SCREEN+186,37
ZZ 160 POKE SCREEN+187,128:POKE SCREEN+18
   8,47:POKE SCREEN+189,48:POKE SCREEN+19
   0,52:POKE SCREEN+191,128
LH 170 POKE SCREEN+192,36:POKE SCREEN+193
   ,44:POKE SCREEN+194,128
FY 180 POKE SCREEN+195,128:POKE SCREEN+19
   6,126:POKE SCREEN+197,128
ME 190 POKE SCREEN+198,35:POKE SCREEN+199
   ,50
HD 200 POKE SCREEN+2,1:SPT=2:F=129
UA 210 FOR I=1 TO 4:POSITION 2,7:PRINT CH
   R$(156);:NEXT I:RETURN
EE 220 X=STICK(0):Y=STRIG(0):IF Y=0 THEN
   GOSUB 490
ZE 230 FOR SLOW=1 TO DLAY:NEXT SLOW
XZ 240 IF X=14 AND (SPT-40)>1 THEN GOSUB
   300
SQ 250 IF X=13 AND (SPT+40)<200 THEN GOSU
   B 340
HQ 260 IF X=7 THEN GOSUB 430
NY 270 IF X=11 THEN GOSUB 380
ND 280 GOTO 220
LP 290 R=R-3:POSITION 2,7:? CHR$(156);:PO
   SITION 2,R:RETURN
DM 300 L=PEEK(SCREEN+CSPT-40)):POKE SCREE
   N+SPT,F
AH 310 IF L>127 THEN POKE SCREEN+(SPT-40)
   ,L-128
WZ 320 IF L<128 THEN POKE SCREEN+(SPT-40)
   ,L+128
DA 330 SPT=SPT-40:F=L:RETURN
CA 340 L=PEEK(SCREEN+(SPT+40)):POKE SCREE
   N+SPT,F
XX 350 IF L>127 THEN POKE SCREEN+(SPT+40)
   ,L-128
UP 360 IF L<128 THEN POKE SCREEN+(SPT+40)
   ,L+128
CK 370 SPT=SPT+40:F=L:RETURN
QG 380 CNG=1:IF SPT=2 OR SPT=42 OR SPT=82
   OR SPT=122 OR SPT=162 THEN CNG=-37
JK 390 POKE SCREEN+SPT,F:L=PEEK(SCREEN+(S
   PT-CMG))
ZJ 400 IF L>127 THEN POKE SCREEN+(SPT-CNG
   ),L-128
VZ 410 IF L<128 THEN POKE SCREEN+(SPT-CNG
   ),L+128
GQ 420 F=L:SPT=SPT-CNG:RETURN
NW 430 CNG=1:IF SPT=39 OR SPT=79 OR SPT=1
   19 OR SPT=159 OR SPT=199 THEN CNG=-37
FX 440 POKE SCREEN+SPT,F:L=PEEK(SCREEN+(S
   PT+CNG))
XB 450 IF L>127 THEN POKE SCREEN+(SPT+CNG
   ),L-128
TR 460 IF L<128 THEN POKE SCREEN+(SPT+CNG
   ),L+128
FU 470 F=L:SPT=SPT+CNG:RETURN
JX 480 Z=PEEK(85):FOR SPC=Z TO 39:PRINT "
   ";:NEXT SPC:RETURN
QU 490 A=PEEK(SCREEN+SPT):POKE 77,0:IF A=
   164 OR A=172 THEN GOTO 620
CQ 500 C=PEEK(83):R=PEEK(84):IF A=175 OR
   A=176 OR A=180 THEN POP :? CHR$(125):G
   OTO 710
KM 510 IF A=254 THEN A=194
GR 520 IF A<64 THEN A=A+32
ZU 530 IF A=163 OR A=178 THEN A=5
QI 540 IF A=165 THEN A=27
BY 550 SP=SP+1
VF 560 IF PEEK(84)=23 THEN GOSUB 290
OV 570 PRINT CHR$(A):IF SP<1 THEN SP=1
ER 580 IF A=5 THEN GOSUS 480
PS 590 IF A=27 THEN PRINT CHR$(27);
PA 600 LINE$(SP,SP)=CHR$(A):R=PEEK(84):C=
   PEEK(85)
ZE 610 RETURN
IK 620 IF LINE$(SP,SP)=CHR$(5) THEN GOSUB
    660
ZH 630 A=32:LINE$(SP,SP)=CHR$(163):SP=SP-
   1:IF SP<1 THEN SP=1
YH 640 C=C-1:IF C<2 THEN C=39:R=R-1:IF R<
   6 THEN R=6:C=2
HZ 650 POSITION C,R:PRINT " ";CHR$(30);:G
   OTO 610
ZT 660 R=R-1:IF R<6 THEN R=R+1:RETURN
XS 670 POSITION 2,R:FOR I=39 TO 2 STEP -1
YY 680 PRINT CHR$(30);:IF PEEK(93)=69 THE
   N POP :C=I+1:RETURN
GO 690 NEXT I
KC 700 RETURN :REM ERROR TRAP
DZ 710 REM MENU FOR FUNCTIONS
PX 720 POSITION 2,14
FB 730 PRINT ,,"0. NOTHING":? ,,"1. SAVE
   FILE":? ,,"2. PRINT IT":? ,,"3. LOAD F
   ILE":? ,,"4. DIRECTORY":? ,,"5. TYPE"
FD 740 PRINT ,,"6. DELETE FILE":? ,,"7. F
   ORMAT DISK":? ,,"8. ERASE LETTER":POSI
   TION 22,13:PRINT CHR$(29);
YH 750 X=STICK(0):Y=STRIG(0):ROW=PEEK(84)
TY 760 IF Y=0 THEN GOTO 800
HW 770 IF X=13 AND ROW<22 THEN PRINT CHR$
   (29};
JF 780 IF X=14 AND ROW>14 THEN PRINT CHR$
   (28);
HW 790 FOR SLOW=1 TO DLAY:NEXT SLOW:GOTO
   750
IR 800 GET #6,A:POKE 77,0:POKE 85,22:A=A-
   175
SW 810 IF A=8 THEN GOTO 750
IE 820 ON A GOTO 750,1050,1120,1300,1370,
   1450,1550,1590,1810
QE 830 GOTO 750
PR 840 SX=1:DR$="       ":DI$(4,13)=DR$:P
   RINT CHR$(125):PRINT "WHAT IS THE NAME
    OF FILE IN DRIVE ";DI$(2,2)
VE 850 PRINT :PRINT :PRINT :PRINT "M";CHR
   $(160);:FOR I=193 TO 218:PRINT CHR$(I)
   ;:NEXT I
OZ 860 PRINT CHR$(160);CHR$(160);"DL":? "
   E":? "N":? "U"
HZ 870 POSITION 2,10:PRINT DI$
AY 880 COL=3
OT 890 POSITION COL-2,5:PRINT CHR$(31);CH
   R$(31);:FOR SLOW=1 TO DLAY:NEXT SLOW
XO 900 X=STICK(0):Y=STRIG(0):COL=PEEK(85)
ZU 910 IF Y=0 THEN GOTO 960
PD 920 IF X=7 AND COL<32 THEN PRINT CHR$(
   31);
PV 930 IF X=11 AND COL>2 THEN PRINT CHR$(
   30);
ZN 940 FOR SLOW=1 TO DLAY:NEXT SLOW
PA 950 GOTO 900
NZ 960 GET #6,A:IF A=196 THEN GOTO 1020
UT 970 IF A=285 THEN GOTO 710
WM 980 IF A=32 AND SX=1 THEN GOTO 890
FS 990 IF SX>8 THEN GOTO 1840
TO 1000 DR$(SX,SX)=CHR$(A):POSITION 5,10:
   PRINT DR$:? SX:SX=SX+1
TY 1010 GOTO 890
IR 1020 SX=SX-1:IF SX=0 THEN SX=1
GR 1030 DR$(SX,SX)=" ":POSITION 5,10:? DR
   $;" ":? SX:GOTO 890
AY 1040 DI$(4,11)=DR$:RETURN
TB 1050 GOSUB 840:OPEN #2 8,0,DI$:FOR I=1
    TO LEN(LINE$):X$=LINE$(I,I)
EJ 1060 IF X$=CHR$(163) THEN POP :GOTO 10
   80
AS 1070 PRINT #2;X$:NEXT I
NV 1080 PRINT #2;CHR$(163)
UG 1090 CLOSE #2:PRINT CHR$(125):? ,DIS;"
   IS SAVED"
ZZ 1100 GOSUB 1610
PX 1110 GOTO 710
XQ 1120 PRINT CHR$(125):PRINT "SINGLE SPA
   CED OR DOUBLE SPACED?":GOSUB 1870
WG 1130 IF A=49 THEN LS=2
RU 1140 IF A=50 THEN LS=1
ZM 1150 OPEN #2,8,0,"P:":PRINT CHR$(125):
   ? ,,"WAIT": PRINT #2
MW 1160 FOR I=1 TO LEN(LINE$)
FC 1170 IF LINE$(I,I)=CHR$(163) THEN POP
   :GOTO 1320
ER 1180 FIN=I
YL 1190 NEXT I:PRINT ,,"PRINTING"
AI 1200 LL=PLL:SP=1:B=1:Y=0:PRINT #2;MRGS
   ;
YM 1210 Y=Y+1:IF Y>LL OR Y=LL THEN GOSUB
   1640
ZK 1220 IF SP=FIN+1 THEN GOSUB 1770:CLOSE
    #2: GOTO 710
TU 1230 IF P>53 THEN GOSUB 1700
XJ 1240 IF LINE$(SP,SP)=CHR$(32) AND Y=1
   THEN SP=SP+1:GOTO 1210
QA 1250 IF LINE$(SP,SP)=CHR$(5) THEN GOSU
   B 1720:GOTO 1210
SM 1260 IF LINE$(SP,SP)=CHR$(27) THEN PLL
   =LL+2:SP=SP+1:GOTO 1210
MP 1270 IF LINE$(SP,SP)=CHR$(126) THEN LL
   =LL+2:GOTO 1210
CQ 1280 IF LINE$(SP,SP)=CHR$(32) THEN PRI
   NT #2;LINE$(B,SP);:SP=SP+1:B=SP:GOTO 1
   210
GK 1290 SP=SP+1:GOTO 1210
MY 1300 GOSUB 840:LINE$=" ":SP=1:PRINT CH
   R$(125)
JA 1310 OPEN #2,4,0,DI$
MG 1320 INPUT #2,X$:IF X$=CHR$(163) THEN
   SP=SP-1:GOTO 1340
YV 1330 LINE$(SP,SP)=X$:SP=SP+1:GOTO 1320
AW 1340 CLOSE #2:PRINT CHR$(125):PRINT :P
   RINT DI$;" LOADED":CLOSE #2
QN 1350 GOTO 710
TW 1360 CLOSE #2:PRINT "ERROR--NO SUCH FI
    LE":FOR I=1 TO 200:NEXT I
MQ 1370 DB$(2,2)=DI$(2,2):PRINT CHR$(125)
   :OPEN #1,6,0,DB$
AK 1380 INPUT #1;F$:IF ASC(F$(3,3))<65 TH
   EN 1430
PE 1390 PRINT F$(3,13);MRG$;
UW 1400 INPUT #1;F$:IF ASC(F$(3,3))<65 TH
   EN GOTO 1430
WP 1410 PRINT F$(3,13)
SM 1420 GOTO 1380
BT 1430 CLOSE #1:PRINT :GOSUB 1610
QM 1440 GOTO 710
BT 1450 ? CHR$(125):POSITION 2,7:PRINT
MP 1460 GOSUB 60:FIN=LEN(LINE$):IF FIN<1
   THEN GOTO 220
NV 1470 FOR I=1 TO FIN
KR 1480 IF LINE$(I,I)=CHR$(163) THEN R=PE
   EK(84):C=PEEK(85):POP :GOTO 220
QE 1490 IF LINE$(I,I)=CHR$(27) THEN PRINT
    CHR$(197);:GOTO 1530
GR 1500 IF LINE$(I,I)=CHR$(126) THEN PRIN
   T CHR$(194);:GOTO 1530
VN 1510 IF LINE$(I,I)=CHR$(5) THEN PRINT
   CHR$(5);:GOSUB 480:GOTO 1530
MS 1520 PRINT LINE$(I,I);
AN 1530 R=PEEK(84):C=PEEK(85):IF R=23 THE
   N GOSUB 290
LM 1540 NEXT I:SP=I-1:GOTO 220
AW 1550 GOSUB 840
AY 1560 XIO 33 #1,0,0,DI$:PRINT CHR$(125)
   :? ,DI$;" IS GONE"
BC 1570 GOSUB 1610
RA 1580 GOTO 710
BC 1590 PRINT CHR$(125);"NOW FORMATING DR
   IVE ";DI$(2,2):XIO 254,#1,0,0,DI$
GF 1600 PRINT "DISK IS NOW FORMATTED":GOS
   UB 1610:GOTO 710
IA 1610 PRINT "PRESS FOR MENU"
KB 1620 Y=STRIG(0):IF Y<>0 THEN GOTO 1620
AU 1630 RETURN
HP 1640 IF LINES(SP+1,SP+1)=CHR$(32) THEN
    PRINT #2;LINE$(B,SP):SP=SP+2:B=SP:IF
   Y=LL THEN GOTO 1670
UF 1650 IF (SP-B)>40 THEN PRINT #2;LINE$(
   B,SP):IF LS=2 THEN PRINT #2:GOTO 1680
UV 1660 PRINT #2
YZ 1670 IF LS=2 THEN PRINT #2
CF 1680 Y=1:LL=PLL:PRINT #2;MRG$;
BM 1690 RETURN
IF 1700 FOR I=1 TO 12:PRINT #2:NEXT I
MJ 1710 PRINT #2;MRG$;:P=0:RETURN
MA 1720 IF B=SP THEN PRINT #2:P=P+1
GB 1730 IF B<SP THEN PRINT #2;LINE$(B,SP-
   1):P=P+1
BA 1740 IF LS=2 THEN PRINT #2:P=P+1
LE 1750 SP=SP+1:B=SP:Y=0:LL=PLL:PRINT #2;
   MRG$;
BF 1760 RETURN
EX 1770 IF B=SP THEN GOTO 1790
ZN 1780 PRINT #2;LINE$(B,SP-1);CHR$(155)
YT 1790 CLOSE #2:SP=1:RETURN
XW 1800 OPEN #6,4,0,"S:":SETCOLOR 2,0,0
PP 1810 CLR :DIM LINE$(19955),X$(1),F$(15
   },DR$(8),DB$(6),DI$(13):SP=0:R=6:C=2:D
   I$="D :";DB$="D :*.*"
MR 1820 DLAY=10:DIM MRG$(7):MRG$="
   ":PLL=64
XB 1830 ? CHR$(125):PRINT "STORE MESSAGES
    TO DRIVE ONE OR TWO?":GOSUB 1870
LP 1840 IF A=49 THEN DI$(2,2)="2"
GW 1850 IF A=50 THEN DI$(2,2)="1"
UJ 1860 PRINT CHR$(125):POSITION 2,7:PRIN
   T :GOSUB 60:GOTO 220
MH 1870 PRINT ,,"1":PRINT ,,"2":POSITION
   22,2:PRINT CHR$(29);:FOR I=1 TO 100:NE
   XT I
ZG 1880 X=STICK(0):Y=STRIG(0):R=PEEK(84):
   C=PEEK(85)
PL 1890 IF R>2 AND X=13 THEN PRINT CHR$(2
   8);
QK 1900 IF R<3 AND X=14 THEN PRINT CHR$(2
   9);
OG 1910 IF Y<>0 THEN GOTO 1880
VH 1920 GET #6,A:RETURN
QG 1930 POP :OOPS=PEEK(195):IF OOPS=138 T
   HEN PRINT "CHECK PRINTER OR DRIVE":GOT
   O 710
VY 1940 IF OOPS=139 THEN PRINT "FAULTY DR
   IVE?":CLOSE #2:GOTO 710
WL 1950 IF OOPS=5 AND SP<2 THEN PRINT "NO
   THING WRITTEN.":GOTO 710
DO 1960 IF OOPS=5 THEN PRINT "TOO MANY CH
   ARACTERS. SUGGEST SAVE":GOTO 710
DI 1970 IF OOPS=144 THEN PRINT "DISK PROT
   ECTED":CLOSE #2:GOTO 710
MP 1980 IF OOPS=167 THEN PRINT "FILE LOCK
   ED":CLOSE #2:GOTO 710
XY 1990 IF OOPS=169 OR OOPS=162 THEN PRIM
   T "DISK FULL -- TRY AGAIN WITH ANOTHER
    DISK":CLOSE #2:GOTO 710
HB 2000 IF OOPS=170 THEN GOTO 1360
YI 2010 IF OOPS<143 THEN PRINT "WHAT HAVE
    YOU DONE TO THIS PROGRAM?":? "ERROR -
   - ";OOPS:GOTO 710
IL 2020 IF OOPS=160 THEN PRINT "WRONG DRI
   VE?":CLOSE #2:FOR SLOW=1 TO 200:NEXT S
   LOW:GOTO 1830