Classic Computer Magazine Archive COMPUTE! ISSUE 80 / JANUARY 1987 / PAGE 79

FastKey

Ronald Carnell


Efficiency experts have long believed that as you reduce the number of keystrokes needed to perform a given operation, productivity goes up and the risk of errors goes down. "FastKey" for the Commodore 64 allows you to create abbreviated commands that perform an entire line of BASIC commands with just a few keystrokes. FastKey abbreviations can be used in either direct mode or in a BASIC program. A disk drive is required.


I hate to type. That's why, for over a year, each time I sat down to my 64, the first program I loaded into my 64 was a utility that allowed me to program the computer's function keys. The program has changed from time to time, but the concept has remained constant: commands that can be activated by a single key. The problem, of course, is that the 64 has only eight function keys, but I have a multitude of commands I'd like to automate. That's why I wrote "FastKey."
    FastKey allows you to abbreviate virtually any command that will fit into a normal (80-character) BASIC line. You select your own abbreviations, so they're easy to remember. The commands can be executed either in direct mode or in a BASIC program. Best of all, you can have over 8000 bytes of abbreviations in memory at once, while stealing only 437 bytes from BASIC program space.

Entering FastKey Generator
Program 1, "FastKey Generator," creates FastKey programs and definition files for later use. Since this is a machine language program, type it in using the "MLX" machine language entry program found elsewhere in this issue. Read the MLX instructions carefully before you type and save this program. When you run MLX, you'll be asked for the starting and ending addresses of the data you'll be entering. Here are the addresses you need for FastKey:

Starting address:  0801
Ending address:    0BA8

    After you type and save all the data from Program 1, load it into your computer and list it. Although it's written in machine language, you can load, save, and run FastKey Generator just like any BASIC program. When you run FastKey Generator, it moves itself to the top of memory and prints a reminder of its SYS address.

FastKey Definition Program
The next step is to write a short pseudo-BASIC program to define your key abbreviations and definitions. The first line of the definition program will always consist of a SYS command which activates FastKey Generator. It's also the only line of the program that actually runs in the normal sense. The remainder of the definition program is simply information which FastKey Generator processes to create a FastKey program or definition file. Here's what the first line should look like:

100 SYS 40110

    The second line of the definition program tells FastKey Generator what to name the resulting FastKey file. This line should begin with a REM followed by a special character and the filename you wish to use. The special character will be either an at sign (@) or an English pound character (£).
    The @ sign tells FastKey Generator to create a FastKey program complete with key definitions. This is what you'll want most of the time, and certainly what you'll need the first time you run FastKey Generator. The £ sign, on the other hand, tells FastKey Generator to create only a FastKey definition file. This isn't a program, but a file containing definitions that a FastKey program can load directly into memory (more on this later).
    So far, your definition program should look like this:

100 SYS 40110
110 REM @filename

    The remainder of the program contains nothing but key definitions. As an example, let's set up a definition to change all the screen colors. The first thing to do is to select an abbreviation. It can be as short as one character or as long as 80 (which, of course, wouldn't be very abbreviated). Let's choose the abbreviation c to represent color.

120 *C

    The asterisk (*) at the beginning of this line tells the program that everything else on the line is a key abbreviation. It also indicates that the next line in the file contains the key definition for the abbreviation:

130 POKE 53280,6:POKE 53281,6:POKE
    646,1

    That's all there is to it. Of course, you'll want to define a few more abbreviations. Program 2 is a complete example of a FastKey definition program. You may want to use the same definitions it contains, or you can simply use it as a model in creating your own definitions. When you're finished typing the definition program, save a copy to disk.
    At this point, you should have FastKey Generator installed in memory and a definition program residing in BASIC memory. When you run the definition program, the SYS in the first line transfers control to FastKey Generator. As it reads and defines each abbreviation, FastKey Generator prints the current line number on the screen. When the conversion is complete, FastKey Generator writes a FastKey program to disk.
    If you load the resulting FastKey program and list it, you'll see that it loads like a normal BASIC program. To install the new abbreviations, run the program as you would any BASIC program.

Wedging Into BASIC
FastKey wedges the new commands into BASIC via the error vector. Whenever it encounters a BASIC statement that would otherwise cause an error, the computer checks to see whether the first character in the command is a period (.), the marker that precedes every FastKey command. If the period is present, FastKey reads further and performs the abbreviated command. If not, it passes control to BASIC's normal error-processing routine. For instance, after you activate the example FastKey program, enter the following command:

.C

    This command performs the color changes you defined in line 130 of the definition program. After it performs the command, FastKey prints the command definition on the next screen line as a reminder of what's happening.
    It's also possible to perform FastKey commands within a BASIC program. Enter NEW; then type this line and press RETURN:

.100,C

Again, the leading period signals that this line is intended for FastKey- it's not an error. But this time the period is followed immediately by a line number. When it detects a line number, FastKey knows that you want to add the command as a program line rather than execute it immediately. FastKey prints the line to indicate that it has been added to memory. If you perform a LIST, you'll see that line 100 has been added to the current BASIC program.

Definition Files
The quotation mark (") is the only character that can't come at the beginning of a key definition. The reason for this limitation concerns FastKey definition files. If you write a definition program that generates more than 8K (8192 bytes) of abbreviations, FastKey Generator will abort the generating process, tell you that it ran out of memory, and write as much of the FastKey program as it can. You'll know where it stopped because the current definition line number is printed on the screen.
    At this point, you would have to write a second FastKey program to handle the remaining definitions. Or, even if size isn't a factor, you may decide that you'd rather have different versions of FastKey for different purposes. In either case, it would be inconvenient to stop what you're doing, save whatever is in BASIC, and load a new version of FastKey.
    FastKey definition files eliminate this inconvenience. Whenever FastKey evaluates an abbreviated command, it checks the first character following the period. If this character is a quotation mark, FastKey expects the remainder of the command to be the filename of a FastKey definition file. This file is loaded directly into memory, and the new abbreviations instantly replace the old ones. For instance, this command loads the file MYDEFS from disk and installs its definitions in memory:

."MYDEFS"

    I still hate to type, but FastKey has turned torment into a minor irritation. I hope it can perform the same service for you.


Program 1: FastKey Generator
Please refer to the "MLX" article in this issue before entering the following listing.

0801:63 9C 00 00 9E 32 30 36 3E
0809:33 3A A2 00 00 00 A9 57 40
0811:85 FB A9 0B 85 FC A9 AE BA
0819:85 FD 85 37 A9 9C 85 FE 59
0821:85 38 A2 04 A0 00 B1 FB FA
0829:91 FD C8 D0 F9 E6 FC E6 F3
0831:FE CA D0 F2 A9 3D A0 08 48
0839:20 1E AB 60 93 11 27 53 DE
0841:59 53 20 34 30 31 31 30 F2
0849:27 20 54 4F 20 41 43 54 55
0851:49 56 41 54 45 00 20 73 E6
0859:00 C9 40 F0 04 C9 5C D0 C3
0861:F5 E6 7A D0 02 E6 7B A2 C7
0869:00 8E 87 9D C9 40 F0 03 1C
0871:EE 87 9D A0 00 B1 7A F0 45
0879:03 C8 D0 F9 8C 86 9D A5 56
0881:7A 8D 84 9D A5 7B 8D 85 58
0889:9D A9 00 85 F9 A9 A8 85 78
0891:FA A9 00 85 F7 A9 A0 85 0F
0899:FB A0 FF D0 0B A0 00 B1 E7
08A1:7A 91 F9 F0 03 CS D0 F7 76
08A9:C8 98 18 65 F9 85 F9 90 08
08B1:02 E6 FA A5 FA C9 BF 90 45
08B9:09 A5 F9 C9 A5 90 03 4C 55
08C1:D7 9D 20 73 00 AA D0 FA A7
08C9:20 73 00 8D 3A 03 20 73 31
08D1:00 18 6D 3A 03 D0 03 4C E6
08D9:88 9D 20 73 00 20 73 00 38
08E1:20 73 00 C9 AC D0 F9 20 38
08E9:73 00 A0 00 B1 7A 91 F7 5A
08F1:AA F0 03 C8 D0 F6 A5 F9 28
08F9:C8 91 F7 A5 FA C8 91 F7 42
0901:C8 98 18 65 F7 85 F7 90 4D
0909:02 E6 F8 20 73 00 AA D0 B8
0911:FA 20 73 00 20 73 00 20 06
0919:73 00 AA 20 73 00 20 CD E5
0921:BD A9 0D 20 D2 FF 20 73 6A
0929:00 4C F5 9C 00 00 00 00 D6
0931:A0 00 98 91 F7 38 A5 7A 26
0939:E9 02 85 7A B0 02 C6 7B AF
0941:78 A9 36 85 01 58 A9 02 D7
0949:A8 A2 08 20 BA FF AE 84 13
0951:9D AC 85 9D AD 86 9D 20 CA
0959:BD FF A9 EE 85 FB A9 9D 7B
0961:85 FC AD 87 9D F0 08 A9 0E
0969:00 85 FB A9 A0 85 FC A6 B2
0971:F9 A4 FA A9 FB 20 D8 FF B5
0979:78 A9 37 85 01 58 60 A9 45
0981:E1 A0 9D 20 lE AB 4C 88 23
0989:9D 4D 45 4D 4F 52 59 20 D1
0991:46 55 4C 4C 0D 00 F9 9D 64
0999:00 00 9E 32 30 36 33 3A 9D
09A1:A2 00 00 00 AD 00 03 48 C0
09A9:AD 01 03 48 A9 5D 85 FB 81
09B1:A9 08 85 FC A9 4A 85 FD 9A
09B9:85 37 8D 00 03 A9 9E 85 8F
09C1:FE 85 38 8D 01 03 A2 22 10
09C9:A0 00 B1 FB 91 FD C8 D0 09
09D1:F9 E6 FC E6 FE CA D0 F2 60
09D9:68 8D 5E 9E 68 8D 5D 9E 0C
09E1:A9 53 A0 08 20 1E AB 60 63
09E9:93 11 46 41 53 54 4B 45 AE
09F1:59 00 8E 34 03 AD 00 02 96
09F9:C9 2E F0 0B D0 06 20 C9 F3
0A01:9F AE 34 03 4C 8B E3 AD 4D
0A09:01 02 C9 22 D0 03 4C D0 75
0A11:9F A0 50 A9 00 99 3E 03 A7
0A19:88 10 FA 8D 35 03 AA AD 66
0A21:01 02 C9 30 90 2E C9 3A 7D
0A29:B0 2A 20 73 00 20 9E AD C6
0A31:20 F7 B7 A6 14 BE 36 03 FE
0A39:A5 15 8D 37 03 20 CD BD 7C
0A41:A9 0D 20 D2 FF EE 35 03 C7
0A49:A2 FF E8 BD 00 02 F0 AE 40
0A51:C9 2C D0 F6 A0 00 E8 BD 73
0A59:00 02 F0 06 99 3E 03 CB 01
0A61:D0 F4 8C 38 03 A9 00 85 74
0A69:F7 A9 A0 85 F8 20 C2 9F BD
0A71:A0 00 8C 39 03 B1 F7 F0 BA
0A79:0B D9 3E 03 D0 03 EE 39 2B
0A81:03 C8 D0 F1 AD 38 03 CD A4
0A89:39 03 D0 05 CC 38 03 F0 A3
0A91:17 C8 C8 C8 B1 F7 D0 03 1B
0A99:4C 56 9E 98 18 65 F7 85 92
0AA1:F7 90 02 E6 F8 4C C8 9E AD
0AA9:C8 B1 F7 85 F9 C8 B1 F7 34
0AB1:85 FA A9 80 8D 34 03 AD 75
0AB9:35 03 F0 22 AD 36 03 85 3B
0AC1:14 AD 37 03 85 15 A0 00 24
0AC9:B1 F9 99 00 02 AA F0 03 08
0AD1:C8 D0 F5 20 C9 9F 98 18 55
0AD9:69 05 A8 4C A2 A4 A0 00 A6
0AE1:A2 00 B1 F9 30 0E 9D 00 12
0AE9:02 C9 00 F0 62 20 D2 FF B9
0AF1:C8 E8 D0 EE 8C 3A 03 BE 8F
0AF9:3B 03 8D 3D 03 A9 80 8D 3F
0B01:3C 03 A9 9E 85 F7 A9 A0 15
0B09:85 F8 20 C9 9F A0 00 AD ED
0B11:3D 03 CD 3C 03 F0 17 B1 BF
0B19:F7 30 03 C8 D0 F1 C8 98 9C
0B21:18 65 F7 85 F7 90 02 E6 E0
0B29:F8 EE 3C 03 D0 DF AE 3B CD
0B31:03 B1 F7 30 0A 9D 00 02 FF
0B39:20 D2 FF E8 CS D0 F2 49 5B
0B41:80 9D 00 02 48 20 C2 9F 07
0B49:68 AC 3A 03 4C 45 9F 20 0D
0B51:C9 9F A9 0D 20 D2 FF A9 30
0B59:00 85 7A A9 02 85 7B 98 70
0B61:A2 FF 86 3A 20 79 A5 4C BB
0B69:E1 A7 78 A9 36 85 01 58 26
0B71:60 78 A9 37 85 01 58 60 BF
0B79:A0 00 B9 02 02 F0 07 C9 E2
0B81:22 F0 03 C8 D0 F4 98 A2 FF
0B89:02 A0 02 20 BD FF A9 02 4E
0B91:A0 01 A2 08 20 BA FF A9 A2
0B99:00 A2 FF A0 FF 20 D5 FF 8E
0BA1:A2 80 4C 5C 9E 00 00 00 6D


Program 2: Sample Definitions

Please refer to the typing instructions in the article before entering this listing.

RE 1000 SYS 40110
DR 1010 REM @FASTKEY PRG
CA 1020
MP 1030 REM[2 SPACES}CHANGE CO
        LOR DEFAULTS
KG 1040 *C
KM 1050 POKE 53280,6:POKE 5328
        1,6:POKE 646,1
QP 1060 REM[2 SPACES}PEEK ZERO
         PAGE
XQ 1070 *ZEEK
GX 1080 FOR I=251 TO 254:PRINT
         PEEK(I);:NEXT:PRINT
EJ 1090 REM LIST VECTORS
RA 1100 *VEC
KC 1110 FORI=768TO779STEP2:PRI
        NTPEEK(I)PEEK(I+1):NEX
        T:FORI=788TO819STEP2
QH 1115 PRINTPEEK(I)PEEK(I+1):
        NEXT
KF 1120 END
QB 1130 REM[2 SPACES}COLD STAR
        T
PP 1140 *COLD
DX 1150 SYS 64738
FD 1160 REM(2 SPACES)WARM STAR
        T
CG 1170 *WARM
GD 1180 SYS 64767
CB 1190 REM{2 SPACES}FIND TOP
        {SPACE}OF BASIC
XX 1200 *HIMEM
KP 1210 PRINT PEEK(55)+256*PEE
        K(56)
KF 1220 REM FIND SIZE OF BASIC
         PROGRAM
QM 1230 *SIZE
GS 1240 PRINT "PRG SIZE IS";(P
        EEK(45)+256*PEEK(46))-
        (PEEK(43)+256*PEEK(44)
XC 1250 REM PRINT LAST FILE NA
        ME CALLED
FD 1260 *NAME
CA 1270 SYS 62913
RC 1280 REM LIST TO PRINTER
FP 1290 *P
RE 1300 OPEN4,4:CMD4:LIST
DF 1310 REM END LIST TO PRINTE
        R
BM 1320 *PE
BQ 1330 PRINT#4:CLOSE4
CD 1340 REM LOAD THE DIRECTORY
PD 1350 *DIR
GD 1360 L0AD"$",8:LIST
GE 1370 REM INITIALIZE THE DRI
        VE
CS 1380 *I
QF 1390 OPEN15,8,15:PRINT#15,"
        I0:":CLOSE15
XS 1400 REM FOR/NEXT FOR PROGR
        AMS
MA 1410 *FN
JH 1420 FOR I=1 TO 100:NEXT
SM 1430 REM GET FOR PROGRAMS
PB 1440 *G
HD 1450 GET K$:IF K$="" GOTO14
        50
PK 1460 REM DISK GET FOR PROGR
        AMS
PB 1470 *DG
PG 1480 GET#2,A$:S=ST:A$=A$+CH
        R$(0)
MM 1490 REM DATA STATEMENT
PD 1500 *D
RA 1510 DATA
SD 1520 REM ERROR STATUS FOR P
        ROGRAMS
DC 1530 *ERR
GC 1540 OPEN15,8,15:INPUT#15,E
        ,E$,T,S:PRINT E;E$:CLO
        SE15
AG 1550 REM CHANGE TEXT COLOR
        {SPACE}ON SCREEN
RB 1560 *HUE
GS 1570 FORI=55296TO56295:POKE
        I,0:NEXT
GR 1580 REM ML LOAD FOR PROGRA
        MS
MH 1590 *LOAD
XD 1600 IFA=0THENA=1:PRINT"
        {CLR}{DOWN}LOADING..."
        :LOAD"FILE NAME",B,1
JE 1610 REM RANDOM FUNCTION
JE 1620 *RND
PP 1630 R=INT(RND(0)*1000)+1
KE 1640 REM MEM FREE FUNCTION
GM 1650 *FREE
GM 1660 PRINT FRE(0)-(FRE(0)<0
        )*65536
JE 1670 REM STRIP NUMBER OF LE
        ADING SPACE
DX 1680 *STRIP
GB 1690 N$=MID$(STR$(N),2):PRI
        NT N$
JM 1700 REM LIST
BD 1710 *L
ER 1720 LIST
CC 1730 REM FORMATTED TIME FUN
        CTION
HH 1740 *TIME
AA 1750 A$=TI$:T$=LEFT$(A$,2)+
        " "+MID$(A$,2,2)+" "+R
        IGHT$(A$,2):PRINT"TIME
        ="T$
QE 1760 REM GO TO ML WORK SPAC
        E
SK 1770 *GO
GA 1780 SYS 49152
XM 1790 REM CLEAR ML HARK SPAC
        E
PP 1800 *CLRML
JA 1810 FORI=49152TO53247:POKE
        I,0:NEXT
QH 1820 REM CLEAR TOP OF SCREE
        N
DJ 1830 *TOP
JS 1840 FORI=1024TO1504:POKEI,
        32:NEXT
BS 1850 REM CLEAR BOTTOM OF SC
        REEN
SH 1860 *BOT
PA 1870 FORI=1505TO2023:POKEI,
        32:NEXT
PB 1880 REM PRINT ASCII CODE O
        F STRING
PS 1890 REM DEFINE A$ BEFORE C
        ALL
PG 1900 *CODE
HH 1910 L=LEN(A$):FORI=1TOL:PR
        INT ASC(MID$(A$,I,1));
        :NEXT