!pr2
Interrupt Trace..............................Charles H. Putney
                                               Dublin, Ireland

Have you ever wondered what's happening when the Apple goes off into nothingness?  If your answer is yes, then this short utility will help you find out.

I was recently debugging an assembly language program and ran into this problem.  The program seemed to work for almost all the input data, but occasionally would hang.  After several frustrating hours trying to simulate the event, I decided that an interrupt trace utility would solve my problems.  Later when I had this utility working, it was easy to see why the program was hanging.

This utility consists of a pushbutton addition to the Apple which connects to the interrupt request line (IRQ) of the 6502 and an interrupt service routine which is in page three.  When the interrupt pushbutton is depressed, the interrupt service routine displays the program counter and all the registers on the bottom line of the screen.  It also displays a flashing cursor and waits for an "S" or "G" from the keyboard to stop or resume execution.

I have mounted a pushbutton switch at the upper right hand side of the keyboard in the center of the styling surface.  For a temporary installation I suggest leaving the pushbutton on a flexible lead.  The wiring is easily done with 30 gage wire wrap wire.  One side of the pushbutton is connected to ground.  You may solder a wire to any convenient ground point on the top of the circuit board.  Or, for a temporary installation, you could stick a wire into pin 8 of the game I/O connector.

The other side of the pushbutton is connected to the IRQ signal.  I found that signal at pin 4 of the 6502.  Remove the 6502 from the socket and strip the insulation from the end of the 30 gage wire.  Insert it in the socket for the 6502 in pin 4 and replace the 6502 to retain the wire.  Route the wire along the chips for a neat installation.

For a temporary hookup, Bob S-C suggests folding a 3-by-5 card in half, and triming it so that the folded edge just fits into an empty slot.  Then, while power to the Apple is off, slip one wire into the space between the card and pin 26 (ground) and the other wire between the card and pin 30 (IRQ).  Both of these wires will be on the power-supply side of the card:  pin 26 is at the back edge, and pin 30 is the fifth from the back.  Once the wires are inserted, you may wish to tape them down.

Enter the routine at address $300 and BSAVE it.  When you want to debug a hanging program, first BRUN the INTERRUPT TRACE utility.  This installs the utility at address $300 to $3CA.  Pressing the pushbutton will cause an immediate display of the current program counter and registers.  The utility will wait with a blinking cursor for a "G" or "S" from the keyboard to continue or enter monitor.

Sometimes the program you're investigating may not respond to the pushbutton.  This is because somewhere in the program interrupts have been disabled with the SEI command ($78).  You must search through the entire program and replace these with a CLI instruction ($58).  Make sure that each $78 found is not data in the program and is a valid instruction before you replace it.

The next time that you have a problem with your Apple "hanging" for no apparent reason, use this  utility to see where the 6502 "is".  It may help solve those "hard to debug programs".

When you run the program, the SETUP routine (from $300 to $30B) sets the interrupt vector location and then enables interrupts.  When the pushbutton is depressed, the IRQ line (pin 4 on the 6502) is pulled low.  At the completion of the current instruction, the program counter high, program counter low, and processor status are pushed on the stack.  Interrupt disable is automatically set and the program counter is loaded with the contents of $FFFE and $FFFF.  In the Autostart monitor ROM the program counter is set to $FA40 where the monitor interrupt service routine is located. (In the old monitor the identical routine is at $FA86)  This routine saves the accumulator in $45 and examines the processor status register to see if the inter- rupt was caused by a BRK command.  Remember, the BRK command shares the same vector location with the interrupt for software simulation of interrupts.  If the interrupt was not caused by BREAK then a JMP indirect to location ($3FE) is performed.

Lines 1280-1290 save the X- and Y-registers.  The accumulator has already been saved by the monitor interrupt routine.

Lines 1300-1350 copy the register display titles to the bottom of the screen.  Of course, if your program happened to be in one of the full-screen graphics modes, this line will not be visible.  If you have a //e, you can add code to sense the graphics mode, save it, switch to text mode; then you will have to restore it all when you type "G" to continue after the interrupt.  The new enhanced //e ROMs automatically handle saving and restoring all the bank switched memory, but they still leave the graphics modes up to the programmer.

Lines 1360-1510 convert the values of the five registers and store them into the bottom line.  I add 3 to the S-register value before displaying it, so you see the value before the IRQ code pushed PC and S onto the stack.  I start with the Y-register pointing at the point on the bottom line where the A-register should be displayed.  The DISPLAY.HEX subroutine advances the Y-register by 5, so it is always ready for displaying the next register.

Lines 1520-1590 display the PC-register.  This value is taken from the stack, where the IRQ automatically saved it.

Lines 1600-1750 wait for you to type "G" or "S".  While waiting, the last character on the bottom line is flashed to remind you to type.  If you type "G", lines 1760-1800 restore the registers and return to the interrupted program.  If you type "S", line 1820 takes you to the monitor.
