Commodore's port... (column) Joel Swank.
The Vic SPY routine is a machine language program for the Vic-20 that monitors the contents of any three consecutive memory locations. It is executed every sixtieth of a second as part of the Vic IRQ (Interrupt Request) routine. It allows you to see the value of memory locations change as another program runs. This can be of value for debugging programs or just understanding how the Vic works.
SPY takes advantage of the Vic IRQ feature to display memory on the Vic screen while another program is running. Normally IRQ is used for updating the "jiffy" clock and scanning the keyboard. At power up the vic KERNAL (control program) sets up one of the 6522 VIAs (Versatile Interface Adapters) to interrupt the 6502 microprocessor automatically every sixtieth of a second. When this interrupt occurs, the 6502 suspends execution of the program that is currently running and executes the interrupt handling routine in the KERNAL. The routine saves all of the registers in the 6502 and then executes the routine whose address is stored in the IRQ interrupt vector at memory location 788 ($314).
This vector normally contains the address of the KERNAL routine that updates the jiffy clock and scans the keyboard. But the user can change the contents of the vector to the addresses of another routine and have that routine executed automatically every sixtieth of a second. Only machine language programs, not Basic, can be executed this way. To allow all Vic functions to operate properly, this user IRQ routine should jump to the KERNAL IRQ routine when it has finished executing.
Kisting 1 is a Basic program, called SPY loader, that contains the SPY routine in data statements. It reads the data and pokes it into memory at the proper location. It also adds all data to get a checksum, which it checks against the checksum in the data. If the checksums match, SUCCESS is displayed, otherwise CHECKSUM ERROR is displayed.
This simple checksum does not guarantee that the data are correct, since it is possible to have cancelling errors, but it will catch most typing mistakes. It also changes the top of Basic memory so that Basic will not overwrite SPY with its variables.
After typing in this program, be sure to save a copy on tape before trying to use SPY. An error in a machine language program can cause the 6502 to "hang up". The only way to recover is to turn the Vic off and back on, which erases everything in memory.
Once you have a good copy of SPY Loader, it can be used to load SPY whenever you want to use it. After SPY Loader has been saved on tape, RUN it, and then erase it with a NEW command.
The SPY routine is initialized with a SYS 7168 command. SPY prompts for the address of the first of the three locations to be monitored with ADDRESS. The address must be entered as a one to four-digit hexadecimal number. A full line of digits may be entered, but only the last four are significant. If an invalid digit is entered, a question mark (?) will be displayed immediately following the invalid character, and SPY initialization will be terminated.
So that SPY will not interfere with the information on the screen, the screen is expanded by adding another line at the bottom. The first six bytes of this line are used to display three bytes of memory in hexadecimal. The display is updated every sixtieth of a second until the STOP routine is executed with a SYS 7299 command.
This command turns off SPY and restores the screen to normal. Pressing the STOP/RUN and RESTORE keys will also restore the IRQ vector and the screen to normal. SPY can be re-initialized with the SYS 7168 command. It can also be re-initialized without first executing the STOP routine.
Listing 2 is the assembly listing for SPY. This listing is in standard 6502 assembly language and was generated on an Aim-65 computer. SPY has three entry points.
The first at label SPY is the initialization routine. First it enlarges the screen by altering a register in the Vic 6560 TV controller chip. It then clears the unused portion of the bottom line by storing the current screen color number in the color buffer locations for this line.
Next it prompts for and reads the address of the locations to be monitored. It then disables the IRQ interrupt in case an interrupt should occur during changing of the interrupt vector. It checks the current contents of the interrupt vector to see if the address of the SPY interrupt routine is already there. If it is not, the initialization routine saves the current contents of the vector and inserts that address of the SPY interrupt routine. Finally it enables IRQ interrupts and returns to Basic.
After the initialization routine has been executed, the routing SPYIRQ will be executed at each IRQ interrupt. SPYIRQ reads the contents of memory at the address entered at initialization, and displays three bytes in hexadecimal in the lower left corner of the screen. The three bytes of data are converted into six hexadecimal digits.
Then each digit is converted into its equivalent Vic Screen code and stored in the proper location in the screen buffer. Finally, to allow normal Vic IRQ functions to work properly, SPYIRQ jumps to the routine whose address was originally in the IRQ vector.
The routine at label STOP is the routine that is executed with the SYS 7299 command. It disables interrupts and restores the original contents of the interrupt vector. It then enables interrupts, restores the screen to normal size, and returns to Basic.
The SPY routine is then no longer active.
The Vic tape routines use the IRQ function, and SPY is not active during tape operations. SPY resumes normal operation after the tape operation has finished.
Once SPY is working properly, there are many interesting thins that can be seen. First, use SPY to watch location $AO. This is the Vic jiffy clock. It is a three-byte number that is incremented every sixtieth of a second. You can clear it by typing TI$="000000". You will see that three bytes turn to zero and then start counting rapidly. Set TI$ to the current time (see the user's manual page 114) to see what it looks like in sixtieths of a second since midnight.
Another interesting location is $C5. This is the byte in which the keyboard scan routine stores the keyboard matrix code for any key that is currently pressed. It contains $40 when no key is pressed. SPY location $C5 and watch it change as you press keys. Notice that this is not the ASCII value of the character on the key but an internal code for that key.
Now enter the following statement: FOR I=1 TO 10000:NEXT, and press some keys. You will see the keycode at $C5 change as before, but you will also see the following byte at $C6 increment by one each time you press a key. Location $C6 is the index for the keyboard input buffer in which the Vic saves keystrokes as you enter them. This buffer is located at $277-$280, and can hold up to 10 keystrokes while the Vic is occupied with other tasks. When the above statement ends, you will see that the keys you pressed appear on the screen and that location $C6 returns to zero.
SPY can be used to watch the I/O (Input/Output) ports. If you have a joystick connected, Spy address $9111. This is the port where al joystick functions except RIGHT are read. Move the joystick and press the fire button, and you will see location $9111 change. If you have a set of game paddles, you can spy addresses $9008 and $9009. This is where the 6560 stores the digitized value from the paddles. If you have a light pen, you can spy locations $9006 and $9007 in which the 6560 stores the position of the light pen on the screen.
There are many other interesting things that can be discovered with SPY. It canbe used while testing either machine language or Basic programs. Because SPY uses some of the processing power of the 6502 each sixtieth of a second, programs will run about 4% slower while SPY is operating.