Interrupts
An important feature to understand is the vertical blank (Vblank) interrupt. I will give you a working definition of what an interrupt is, then discuss how Vblank fits into the overall interrupt structure, what is accomplished in this time period, and how programmers may access this interrupt for their own use. I will also provide a simple program to illustrate the use of Vblank vectors and how to insert code at VVBLKD.
Recall from my discussion of raster scan graphics, that the term vertical blank is given to that time period when the electron beam is turned off and returned to the upper-left corner of the video screen, ready to start tracing a new frame. The number of machine cycles available at Vblank is some fraction of 29868 machine cycles that are needed to trace one entire television frame. In the normal Graphics Mode 0 (text screen), approximately 7980 machine cycles are left over at Vblank to be shared by the Operating System Vblank interrupt service routine (ISR) and any programmer supplied code. The term interrupt applies to any signal, originating from hardware or software, which serves to suspend normal mainline program flow.
When an interrupting event occurs, the program counter (PC) and processor status registers are automatically saved on the system stack. The processor then executes special code referred to as an interrupt service routine (ISR). The address of the ISR is found in a memory location reserved for this purpose, called an interrupt vector. When the ISR is finished, the values of the PC and status registers are retrieved from the stack and processing of the suspended program is resumed as if nothing had intervened. This all happens at machine speed--in hundreds of microseconds.
The vertical blank interrupt is an essential part of the ATARI Operating System and appears as a non-maskable interrupt (NMI) to the system. The NMI is one one of three possible interrupts that the ATARI can process. These three-chip reset, NMI, and IRQ-are analyzed further by interrupt service software. Whenever an NMI or an IRQ signal occurs, the appropriate service routine is executed. These service routines interrogate a status register to isolate the interrupting source. See Table 1 for a breakdown of vectors and contents for each type of interrupt.
It's apparent from Table 1 that all NMI interrupts are vectored through location $FFFA to the NMI interrupt service routine starting at address $E7B4. Since there are three possible causes of an NMI, the ISR must determine the source of the interrupt by interrogating an NMI status register at address $D40F. This location, called NMIST in the documentation, has bit 7 set when a DLI occurs, bit 6 set when [SYSTEM RESET] has been pressed. If neither a DLI nor a [SYSTEM RESET] caused the NMI, then a Vblank interrupt is assumed by the ISR and the processor jumps to the address contained in the vector at $0222. There are actually two vectors used by Vblank through which a programmer may introduce additional or replacement code. One vector, referred to as vertical blank immediate vector VVBLKI, is at address $0222. This vector normally contains the address $E7D1, the start of the system Stage 1 Vblank ISR. Should it be necessary to either replace system functions or simply perform operations prior to the system code, then you would use this vector. The other vector location, called vertical blank deferred VVBLKD, is at address $0224. This vector normally contains the address $E93E, which is the start of code for the system return from interrupt. The contents of $0224 would be changed to point to new code when your operation was needed after system housekeeeping was accomplished.
Table 1. | ||||
INTERRUPT | VECTOR | ISR LOCATION | ||
---|---|---|---|---|
CHIP RESET | FFFC | E477 | ||
NMI | FFFA | E784 | ||
Display list Jump through | 0200 | |||
Vertical Blank | 0222 and 0224 | |||
S/Reset key | E474 | |||
IRQ | FFFE | E6F3 | ||
Serial bus output ready jump through | 020C | |||
Serial bus output complete | 020A | |||
Serial bus input ready | 020E | |||
*Serial bus proceed line | 0202 | |||
*Serial bus interrupt line | 0204 | |||
*Pokey timer 1 | 0210 | |||
*Pokey timer 2 | 0212 | |||
*Pokey timer 4(Bug in O.S. timer 4) | 0214 | |||
Keyboard key scan | 0208 | |||
Break key | ???? | |||
*6502 break instruction | 0206 |
* These vectors are unused by the O.S. and are initialized to point to an RTI instruction.
The Vblank process is actually divided into two stages. Whenever a Vblank NMI occurs, the following events always happen:
1. Processor registers A, X, and Y are pushed on stack.
2. Interrupt request is cleared by writing zero to $D40F.
3. Jump through VVBLKI normally pointing to Stage 1 Vblank.
When Stage 1 processing is executed, it increments the three-byte counter called RTCLOK at addresses $12, $13, and $14. Location at $12 is the most significant byte. This counter wraps to zero after approximately 77 hours and then continues counting. The attract mode is also processed at Stage 1; that is the process which causes the colors on your screen to start shifting if no key has been pressed on the keyboard in the previous nine minutes.
Additionally, system timer one at locations $218 and $219 is decremented if it is non-zero. When the counter goes to zero, an indirect JSR is performed via a vector at addresses $226 and $227. Note that an indirect JSR is performed by copying the address from the vector to the stack and executing an RTS instruction.
At this point a test is made to determine if a time-critical section of code was interrupted. If either the I bit in the processor status register or the critical flag at address $42 are set, then the interrupted code is assumed to be time-critical. When this occurs, the registers are restored and an RTI instruction is executed.
The critical flag can be set by a Serial I/O in progress. If no time constraints are present, then Stage 2 processing is begun. It is in this section of code that IRQ interrupts are enabled, keyboard auto-repeat logic is processed, keyboard debounce is performed, and system timers, 2, 3, 4, and 5 are processed. In addition, the color data for playfield and Player/Missiles are updated. This color data and other RAM locations, called shadow registers, are copied into their associated hardware locations. Stage 2 also reads the game controller data from jacks 1, 2, 3, and 4 into RAM memory.
To insert code either at VVBLKI or VVBLKD, the address where the new code resides must be placed into the appropriate vector. A system routine insures that both bytes of the vector will be updated while Vblank is enabled. A vertical blank can be processed during a call to this routine. The routine is called SETVBV in the documentation and the calling sequence is:
Register A | (update indicator) |
= 1-5 then update timers 1-5 | |
= 6 for immediate Vblank vector VVBLKI | |
= 7 for deferred Vblank vector VVBLKD | |
Register X | = most significant byte of vector address (hi-byte) |
Register Y | = least-significant byte of vector address (lo-byte) |
JSR SETVBV | Jump to subroutine |
The A, X, and Y registers may be altered.
The display list interrupt will always be enabled on return.
A knowledge of processing interrupts and inserting code at interrupt vectors is essential to get the most from the ATARI. With this example you should have enough information to experiment with the Vblank vectors. Interrupt-driven sound control, page flipping, animation techniques, greater color control, and many other procedures are possible.
James Capparell
"Interrupts," by James Caparell, is reprinted with permission from MICRO Magazine, Issue No. 43, P.O. Box 6502, Amherst, NH 03031.
Listing: INTRUPT.SRC Download / View