Classic Computer Magazine Archive COMPUTE! ISSUE 71 / APRIL 1986 / PAGE 104

COMMODORE 64
Key Phantom

Melvin Baker

By expanding the 64's internal keyboard buffer, you can use. the dynamic keyboard technique for very powerful effects. This machine language utility does all the hard work for you, even if you know nothing about machine language. A disk drive is required.


If you've been following Jim Butterfield's recent series on dynamic keyboard programming (COMPUTE!, October-December 1985), you know that this technique is a powerful programming tool. By making the computer "type on its own keyboard," you can write programs that modify themselves as they run, enter direct mode commands, and do many other things that ordinarily are difficult or impossible from within a program.
    The dynamic keyboard technique works by POKEing the desired character codes into an area of memory called the keyboard buffer, which normally starts at location 631. This is where the computer receives keystrokes, so POKEing character codes into the buffer makes the computer think those keys have been pressed. Next, you POKE the number of characters in the buffer into the keyboard buffer counter at location 198. When the program ends, the computer types the codes in the buffer, just as if you pressed the same keys yourself.
    However, the dynamic keyboard technique suffers from one major limitation. Since the key board buffer can't hold more than ten characters, you're limited to fairly short commands. If your command takes more than ten characters to type (including a carriage return), it simply won't fit into the buffer.
    "Commodore 64 Key Phantom" overcomes this limitation by relocating and expanding the 64's keyboard buffer in a free memory area. When the machine language (ML) portion of Key Phantom is active, the 64 has a keyboard buffer 3,758 characters in length-enough to permit very elaborate command sequences.

A Phantom Typist
Before we get into the details of how Key Phantom works, let's try a short demonstration. Type in and save the program listed below. When you run it, the program automatically POKEs the ML code into memory and then displays a three-option menu on the screen. By pressing a number key from 1-3 you can create a new commands file, execute an existing commands file, or exit the program.
    To get started, press 1 to create a new commands file. This file will be called COMMANDS on the disk, so if your disk already contains a sequential file of that name, you should exit the program and copy the old file to another disk before proceeding.
    Option 1 is a simple text editor which lets you store a series of character codes in the file named COMMANDS. Later on, the Key Phantom can read the character codes from this file and type them with the dynamic keyboard technique. When you choose Option 1, the screen clears and displays a message indicating which line of the commands file is being edited. The line number is solely for your information-it won't become part of the file. Type in the following lines exactly as shown. Where you see the name of a key enclosed in curly braces { } you should press the key indicated inside the braces. For example, press RETURN when you see {RETURN}. Press the cursor-down key when you see {DOWN}.

Key£01 Phantom£02 Demonstration£03
  {DOWN} {RETURN}
Watch me type in a line£01{DOWN}
  {RETURN}
that changes the screen colors ... £02
  {DOWN} {RETURN}
f£01o£01r£01j=1£02to£02200:£02poke
  £0253280,£02j:£02n£01e£01x£01t£03
  {RETURN}

    Use the DEL key to erase any mistakes within a line. When all four lines have been entered, press any key at the prompt to write the commands file to disk. At this point, the program returns you to the main menu. Press the 2 key to execute the commands file. After a brief pause while the ML code is placed in memory, the program loads the commands file.
    Now the Key Phantom begins typing the characters from your commands file directly on the screen. Although the READY prompt and blinking cursor appear on the screen, you are not in BASIC ready mode. The Key Phantom has control of the computer until it reaches the end of the commands file. You should see the following display:

Key Phantom Demonstration
Watch me type in a line
that changes the screen colors...
forj =1to200:poke53280,j:next

    Note the time delays of various durations that are used at different points in the printing sequence. These result from the characters £01, £02, and £03 that you typed when creating the file. The £ character tells the Phantom to pause the printing for the number of seconds specified in the following number. The delay number must be expressed in hexadecimal (base 16). Thus, £01 pauses the printing for one second; £0F pauses for 15 seconds, and so on. By including delays in the character sequence, you can print information at any speed you like.

Pseudo-Keys
The £ character is an example of a Key Phantom pseudo-key. Instead of printing something on the screen, a pseudo-key performs a certain action. A second pseudokey is the back-arrow key, located at the upper-left corner of the keyboard. When you include this character in a command sequence, Key Phantom waits for you to type a line from the keyboard. The input terminates when you press RETURN, just like INPUT in a BASIC program.
    Since Key Phantom essentially types every character from the command file, you must keep in mind what would happen if you were typing those characters yourself. For instance, it's necessary to print a cursor down character before printing RETURN at the ends of the first three example lines. Otherwise you'd get a SYNTAX ERROR, since those lines don't contain BASIC commands. But no cursor down is used at the end of the last line: In this case you want to press RETURN at the end of the line to make the computer perform those actions.
    Cursor control characters can be used for a variety of different effects. Just as in BASIC, you can move left, right, up, or down, go to the home position, clear the screen, and so on. The editor accepts any keys except DEL, CTRL, RUN/ STOP, and RESTORE. Since control characters would garble the editor's screen display, it generally displays a reverse video < or > symbol to show that a control character was typed. If you need to perform an action not available from the keyboard, you can always execute a short PRINT statement. For instance, PRINT CHR$(14)CHR$ (8) locks the keyboard into lowercase/uppercase mode.

Advanced Applications
Because the ML portion of Key Phantom is driven by the computer's hardware interrupt routine, it can operate while a BASIC program is running. This means you can use it to feed input directly to a running BASIC program.
    When would this be useful? To take a simple example, let's say you use a certain BASIC program frequently: It could be a checkbook program, an events calendar, or whatever. The program may begin by asking you to choose from several different options, input various items of information, and so on. By writing an appropriate command file for Key Phantom, you could make the computer load and run the BASIC program, select the option or options you want, and input as many items of information as needed. If you need to input new information at any point, the back arrow pseudo-key lets you do so. And when automatic control is no longer needed, the command file can terminate, leaving you in the BASIC program as usual.
    If you're the type who likes to have several programming aids active at once, why not write a Key Phantom command file that automatically loads and activates all your favorite utilities at once? When you begin using Key Phantom, you'll probably think of many more uses as well.
    Of course, since it uses memory from locations 49152-53247, this program is not compatible with utilities that use the same memory area. And you must be careful not to activate any other ML routines that disturb the 64's hardware interrupt vector at locations 788-789 ($0314-$0315). You should also look out for BASIC programs that begin by clearing the computer's keyboard buffer-to avoid losing information from the command file, you should pause Key Phantom for a few seconds (with the £ pseudo-key) when the program begins.
    When feeding input to a program, you must keep in mind what sort of input the program expects. If the program accepts data with INPUT, you should terminate the corresponding data item with a carriage return. On the other hand, if the program accepts data with GET, you should not end the data with a carriage return. GET usually takes a single keypress, not a keypress plus a carriage return.
    Occasionally you may find a program that needs to use Key Phantom pseudo-keys for its own purposes. Then you'll have to change the pseudo-keys to some other character. This can be done by substituting different character codes in lines 570 and 590. The REMs in the program indicate which value belongs to which pseudo-key.

Commodore 64 Key Phantom

For instructions on entering this listing, please refer to "COMPUTE!'s Guide to Typing In Programs" published in this issue of COMPUTE!.

JH 100 ZZ=53368
HJ 110 CLOSE15:PRINT"{CLR}
       {2 DOWN}KEY PHANTOM
       {2 DOWN}"
GQ 120 PRINT"1] EDITOR{DOWN}":
       PRINT"2] EXECUTE{DOWN}"
       :PRINT"3] EXIT{DOWN}"
CH 130 GOSUB820:K=VAL(Q$):IFK<
       1ORK>3THEN130
AP 140 ON K GOTO150,460,510
FB 150 OPEN15,8,15,"I"
XG 160 GOSUB520:PRINT: PRINTD$
FK 170 OPEN5,8,5,"0:COMMANDS,S
       ,W":GOSUB520
HR 180 PRINT:PRINTD$:IF A1<20T
       HEN260
BK 190 CLOSE5
QG 200 IF A1<>63THEN110
JQ 210 PRINT"{DOWN}1] SCRATCH
       {DOWN}":PRINT"2] APPEND
       {DOWN}":PRINT"3] MENU
       {DOWN}"
RQ 220 GOSUB820:K=VAL(Q$):IFK<
       1ORK>3THEN220
CF 230 ON K GOTO240,250,110
XD 240 PRINT#15,"S:COMMANDS":G
       OTO160
MK 250 OPEN5,8,5,"0:COMMANDS,S
       ,A":GOSUB520:GOTO180
QF 260 FOR LN=1TO4000:NEXT:LN=
       1
PG 270 PRINT"{CLR}{RIGHT}KEY P
       HANTOM "D$"{DOWN}":PRIN
       T"LINE - "LN"{DOWN}":L$
       =""
HC 280 PRINT"{RVS} {OFF}{LEFT}
       ";
MP 290 GOSUB820:K=ASC(Q$):IF K
       <32THENQ$="{RVS}<{OFF}"
XQ 300 IF K>127AND K<160THENQ$
       ="{RVS}>{OFF}"
HA 310 IF K=34THENQ$-"{RVS}'
       {OFF}"
CA 320 IF K=20THENPRINT"
       {2 LEFT}";:K=LEN(L$)-1:
       L$=LEFT$(L$,K-(K<0/-2))
       :GOTO280
RK 330 PRINTQ$;
AQ 340 IF K<>13THENL$=L$+CHR$(
       K):GOTO280
DF 350 PRINT: PRINT"{DOWN}[RET]
        FOR NEXT LINE{DOWN}"
JC 360 PRINT-[DEL] TO REDO LIN
       E{DOWN}"
SR 370 PRINT"ANY OTHER TO EXIT
       {DOWN}"
GP 380 GOSUB820
DH 390 IFQ$=CHR$(13)THENLN-LN+
       1:PRINT#5,L$:GOSUB520:G
       OTO270
FQ 400 IFOS-CHR$(20)THEN270
DO 410 PRINT:PRINT"ARE YOU SUR
       E [Y/N]? ";
GB 420 GOSUB820:IFQ$<>"Y"ANDQ$
       <>"N"THEN420
JS 430 PRINTQ$:IFQ$="N"THEN350
OF 440 PRINT#5,L$:GOSUB520:PRI
       NT:PRINTD$
HE 450 CLOSE5:GOSUB520:PRINT:P
       RINTD$:PRINT:CLOSE15:GO
       TO110
XR 460 RESTORE:CS=0:READ LB,HB
       :Al=HB*256+LB:A2=Al:PRI
       NT "LOADING AT "Al;
MC 470 READK:PRINT" >{LEFT}";:
       IFK<0THEN490
QH 480 CS=CS+K:POKEA2,K:A2=A2+
       1:GOTO470
KC 490 IF CS<>ZZ THENPRINT"
       {RVS} CHECKSUM ERROR
       {OFF}";CS:GOTO110
JG 500 SYS Al
FH 510 PRINT"{CLR}":END
PQ 520 INPUT#15,Al,D$,A2,A3
EJ 530 IF A1<20THENRETURN
CB 540 D$="{RVS} "+D$+" {OFF}"
       :RETURN
RH 550 DATA 0,192,76,81,193,17
       3,183,192,201,0,208,79,
       173,185,192,201,0
OF 560 DATA 208,34,173,198,0,2
       01,0,208,24,32,154,192,
       201,0,240,41,201
GE 570 DATA 92:REM COMMAND ONE
        (£)
AP 580 DATA 240,75,201
PR 590 DATA 95:REM COMMAND TWO
       (<)
GA 600 DATA 240,27,141,119,2,2
       38,198,0,32,158,192,76
DM 610 DATA 226,252,173,197,0,
       201,1,208,246,169,0,141
       ,185,192,76,48,192
RP 620 DATA 238,185,192,76,45,
       192,120,173,49,192,141,
       20,3,173,50,192,141
FC 630 DATA 21,3,88,76,48,192,
       238,184,192,173,184,192
       ,201,60,208,8,169
EA 640 DATA 0,141,184,192,206,
       183,192,76,48,192,32,13
       2,192,10,10,10,10
PB 650 DATA 141,183,192,32,132
       ,192,13,183,192,141,183
       ,192,76,45,192,32,158
BB 660 DATA 192,32,154,192,162
       ,0,221,186,192,240,7,23
       2,224,16,208,246,162
CR 670 DATA 0,138,96,173,81,19
       3,96,238,155,192,208,5,
       238,156,192,240,160
BC 680 DATA 173,156,192,201,20
       7,208,7,173,155,192,201
       ,255,240,146,96,0,0
MF 690 DATA 0,48,49,50,51,52,5
       3,54,55,56,57,65,66,67,
       68,69,70
FK 700 DATA 48,58,67,79,77,77,
       65,78,68,83,32,207,255,
       176,74,145,253
CM 710 DATA 230,253,208,2,230,
       254,165,254,201,207,208
       ,6,165,253,201,255,240
FM 720 DATA 54,32,183,255,41,6
       4,240,224,169,0,145,253
       ,169,5,32,195,255
BM 730 DATA 32,51,193,169,15,3
       2,195,255,176,28,32,204
       ,255,120,173,20,3
CF 740 DATA 141,49,192,173,21,
       3,141,50,192,169,3,141,
       20,3,169,192,141
BK 750 DATA 21,3,88,96,169,5,3
       2,195,255,169,15,32,195
       ,255,32,138,255
SS 760 DATA 76,131,164,176,238
       ,162,15,32,198,255,176,
       231,32,207,255,176,226
SB 770 DATA 72,32,207,255,176,
       220,201,13,208,247,104,
       201,48,208,211,96,169
GR 780 DATA 15,162,8,160,15,32
       ,186,255,169,0,32,189,2
       55,32,192,255,32
HH 790 DATA 51,193,169,5,162,8
       ,160,5,32,186,255,169,1
       0,162,202,160,192
JR 800 DATA 32,189,255,32,192,
       255,32,51,193,162,5,32,
       198,255,176,159,169
ES 810 DATA 81,133,253,169,193
       ,133,254,160,0,76,212,1
       92,255,-l
KG 820 GETQ$:IFQ$=""THEN820
GP 830 RETURN