Classic Computer Magazine Archive COMPUTE! ISSUE 39 / AUGUST 1983 / PAGE 198

VIC And 64 Escape Key

Thomas Henry

While programming, there are lots of ways to get trapped inside quotes and be unable to use the cursor controls. Until now, your only recourse was to hit RETURN and try the line again. With this handy utility, you can escape from "quote mode" traps by just hitting the pound sign key. The routine also serves as an example of machine language programming for those who are interested in trying their hand at it.

How many times has this happened to you? You're sitting at your VIC-20 or Commodore 64, entering or editing a program, and through a series of keystrokes that you probably don't even remember, get into the following trap. When you push a cursor movement key, instead of the cursor actually moving, you get a reverse field symbol on the screen. Frustrating, isn't it? As you have probably learned, about the only way to get free of the trap is to hit RETURN to get out of the line, and then start over.

Here's an easier way: a program that adds a valuable "escape" option to your computer. With this feature, the seldom used British pound symbol (£) becomes an escape key. When you are stuck in the "cursor trap" mentioned above, simply push the key; you will be released from what's called the quote mode and will be free to move the cursor as desired. Before looking at the program, let's examine the problem in greater detail.

Store Or Perform The Action

Some of the computer's keys are able to perform two distinct jobs, depending on whether the computer is in the immediate mode or program mode. These keys include LEFT, RIGHT, UP, DOWN, REV, OFF, CLEAR, HOME, INSERT, DELETE, and all of the color selection keys. In the immediate mode, you push one of these keys and the action is performed immediately. For example, depress the RIGHT key and the cursor moves one space to the right.

But one of the truly impressive features of all Commodore computers is their ability to store or save the action implied by the key. For example, here is a one-line program:

10 PRINT "{RIGHT} HELLO"

The string contains the word "HELLO" preceded by a cursor-right. When you type this line into the computer, the cursor-right movement is not performed; instead it is stored in the string. The cursor-right will be performed only when the program is run. We are storing a cursor movement to be executed later in the program mode. To indicate that a cursor-right movement is stored in the string, the computer will leave a reverse field brace symbol inside the quotes. In fact, every one of the keys mentioned above has a reverse field character which stands for it when it's inside quotes.

The trouble comes in when the computer thinks you're trying to store an action, but you want to perform it. There are a number of ways this can happen. One way is if you've typed in an odd number of quote marks while entering a line. Another way is pushing the insert key more times than you expected.

Escape By Machine Language

Having defined the problem, let's look at a program that will take care of it. Examine Program 1. This is the assembler listing of the VIC-20 "escape key" program. Since assemblers are now becoming quite common for the VIC and 64, enterprising users might wish to enter the source code in directly and assemble their own version. If you're an experimenter, you'll find that this is a great program to begin with. It's not too long, and yet not so short as to be a trivial exercise. And it has a practical use too.

Examine Program 1 now. The first part shows the "equates" for the program. These equates give names or labels to the various internal addresses that are used by the program. For example, NOKEYS stands for location $C6, and this location always contains the number of keystrokes stored in the keyboard buffer. IRQVEC stands for the IRQ vector stored in RAM (Random Access Memory). And so it goes for all of the labels. Each stands for a location, and usually the label suggests the meaning of the location in question.

The IRQ Routine

The escape key initialization occurs next. A new vector is stuffed into RAM, and this vector directs the computer to always jump to the start of the new IRQ routine. This routine occurs next in the listing. As this is the heart of the whole program, let's examine it in greater detail.

The first thing that happens here is that all of the registers are saved temporarily. Next, the last key depressed is examined. If it wasn't the British pound symbol (which is used for the escape key), then the registers are restored and the normal IRQ is finished. But if it is the desired key, then a zero is stored in three important locations. These are CMODE, REVERS, and NOINST. Stuffing a zero in CMODE turns off the quote mode, a zero in REVERS turns off the reverse screen mode, and a zero in NOINST nulls out the number of inserts pending. Turning off these three locations allows you to escape from all of the "offending" modes.

Blanking The Pound

Recall that a British pound symbol has been printed to the screen. A true escape key shouldn't print anything; it should simply "escape." So the next block of code deposits a blank on top of the British pound character and backs the cursor up one space. The net effect is that no residua] character is printed. So a true escape key has been implemented.

Before going on to the rest of the normal IRQ routine (called IRQRTN in Program 1), the registers are restored. We have kept the new routine transparent to the normal VIC-20 operating system. For the Commodore 64, IRQRTN is $EA31 instead of $EABF.

Since there are now countless memory packages available for the VIC-20, some consideration must be given to finding a convenient location for the program. As mentioned, you might wish to assemble your own version. Most users, however, will want to use the BASIC loader in Program 2. This loader will put the program into the top of memory, wherever that might be. Thus, it works for all VIC-20's with any amount of extra memory (if any). For the Commodore 64, a minor change must be made to reflect the different value for IRQRTN, Line 230 should read:

230 DATA168, 104, 170, 104, 76, 49, 234

Make An Escape

Program 1: Disassembly Of VIC Version

0000         NOKEYS = $C6           ;NUMBER OF KEYS IN BUFFER.
0000         REVERS = $C7           ;SCREEN REVERSE FLAG.
0000         ROW    = $D1           ;CURRENT CURSOR ROW.
0000         COLUMN = $D3           ;CURRENT CURSOR COLUMN.
0000         CMODE  = $D4           ;CURSOR MODE : 0 = DIRECT.
0000         INKEY  = $D7           ;LAST KEYSTROKE IN.
0000         NOINST = $D8           ;NUMBER OF INSERTS PENDING.
0000         KEYBRD = $0277         ;KEYBOARD BUFFER.
0000         IRQVEC = $0314         ;IRQ VECTOR.
0000         IRQRTN = $EABF         ;NORMAL IRQ ROUTINE.
0000         ;
1000 78             SEI
1001 A2 0D          LDX #<NEWIRQ ;SET UP NEW IRQ VECTOR.
1003 A0 10          LDY #>NEWIRQ
1005 8E 14 03       STX IRQVEC
1008 8C 15 03       STY IRQVEC + 1
100B 58             CLI
100C 60             RTS             ;RETURN TO BASIC.
100D         ;
100D 48      NEWIRQ PHA             ;SAVE ALL REGISTERS.
100E 8A             TXA
100F 48             PHA
1010 98             TYA
1011 48             PHA
1012 A5 D7          LDA INKEY       ;GET LAST KEY PUSHED.
1014 C9 5C          CMP #$5C        ;IS IT BRITISH POUND SIGN?
1016 D0 17          BNE MOVEON      ;BRANCH IF NOT.
1018 A2 00          LDX #$00        ;YES.
101A 86 D4          STX CMODE       ;TURN QUOTE MODE OFF.
101C 86 C7          STX REVERS      ;TURN REVERSE MODE OFF.
101E 86 D8          STX NOINST      ;TURN INSERT MODE OFF.
1020 E8             INX             ;TELL THE KBD BUFFER THAT
1021 86 C6          STX NOKEYS      ;IT CONTAINS ONE KEYSTROKE.
1023 A4 D3          LDY COLUMN
1025 88             DEY             ;MOVE CURSOR BACK ONE SPACE.
1026 A9 20          LDA #$20        ;THEN DEPOSIT A BLANK.
1028 91 D1          STA (ROW), Y
102A A9 9D          LDA #$9D        ;FINALLY, PUT A CURSOR LEFT
102C 8D 77 02       STA KEYBRD      ;IN THE KEYBOARD BUFFER.
102F 68      MOVEON PLA             ;RESTORE ALL REGISTERS.
1030 A8             TAY
1031 68             PLA
1032 AA             TAX
1033 68             PLA
1034 4C BF EA       JMP IRQRTN      ;FINISH NORMAL INTERRUPT.

To prepare a copy of this program for use, follow these steps:

  1. Type in Program 2. If you have a Commodore 64, be sure to make the change to line 230 mentioned above.
  2. Check for errors.
  3. Save the program first.
  4. Now try it out. Type RUN and hit RETURN.
  5. Almost instantly, the program will relocate to the top of memory and perform a self-initialization. You may leave the program in place for the duration of a programming session; it will not interfere with normal BASIC operation.

Typing NEW will not affect the escape key program, but if you hit the RUN-STOP/RESTORE key combination, the program will be disabled. You can re-enable it quite easily by typing:

SYS 256*PEEK(56) + PEEK(55)

Since cassette operations affect the IRQ loop, you may wish to disable the escape option with a RUN-STOP/RESTORE before doing any loading or saving and re-enable it afterwards with the SYS 256*PEEK(56) + PEEK(55).

If you have the program in place, try it out. For example, type a quote mark. Now hit the RIGHT key a number of times. Do you see the reverse field brace? Now hit the British pound key. Then hit the RIGHT key once more. Notice that this time you actually move to the right. Think of the most outlandish combination of keystrokes that you can, then try the escape.

Program 2: Basic Loader

100 T = 256 * PEEK (56) + PEEK (55) - 55 : GOSUB160
110 POKE56, HI% : POKE55, LO
120 FORA = TTOT + 54 : READD : POKEA, D : NEXT
130 X = T : T = T + 13 : GOSUB160 : POKEX + 2, LO : POKEX +4, HI%
140 SYS (X)
150 NEW
160 HI% = T / 256 : LO = T - HI% * 256 : RETURN
170 DATA120, 162, 13, 160, 16, 142, 20, 3
180 DATA140, 21, 3, 88, 96, 72, 138, 72
190 DATA152, 72, 165, 215, 201, 92, 208, 23
200 DATA162, 0, 134, 212, 134, 199, 134, 216
210 DATA232, 134, 198, 164, 211, 136, 169, 32
220 DATA145, 209, 169, 157, 141, 119, 2, 104
230 DATA168, 104, 170, 104, 76, 191, 234

program sees a number it has to change it over. Variables are stored in floating point form, however, and simply have to be looked up in memory. This is much faster.

The delay loop in line 160 can be left out without hurting the program. Some people who have played with the program have been startled by the sudden switch from text to graphic screen and have managed to hit interesting things on the keyboard. The delay gives fingers a fraction of a second to move to a less dangerous position.

Lines 170 to 220 are just setting up parameters. The program will calculate a point and draw a line to it and then repeat the process. Lines 210 and 220 calculate an arbitrary line length. The idea is to achieve a compromise between a slowly drawn, beautiful pattern and a quickly drawn, jagged pattern.

Lines 230 and 240 produce the sine calculations. The multiplier expands the pattern to fill the screen. The number added to the end shifts the pattern so that the center of the pattern is also the center of the screen.

Lines 250 and 260 help to make things look a little better. Leave them out of the program to see why. Line 280 checks to see if you've pressed the space bar and want a new pattern.