Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
interrupts [2016/05/30 12:38] ex_writer [Interrupts] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Interrupts ====== | ||
- | An [[glossary#i|interrupt]] is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code the processor is executing. The processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption is temporary, and, after the interrupt handler finishes, the processor resumes normal activities. ([[wp>Interrupt]]) | ||
- | |||
- | The Bally Arcade provides several interrelated registers that help the user acknowledge and respond to both hardware and software interrupts. | ||
- | |||
- | ===== Vertical Blank ===== | ||
- | |||
- | A [[wp>cathode ray tube|CRT]] television image is drawn by a process known as [[wp>Raster scan|raster scanning]], whereby an electron beam sweeps across the screen horizontally, from left to right and top to bottom, creating stacked rows known as //scanlines//. At the end of each scanline, the beam must temporarily reset to the following scanline during an interval known as //horizontal blank//. When the full field of scanlines is drawn and the beam must travel from the bottom of the screen to the top, it does so during a period known as //vertical blank//. To draw a convincing television image without visible flicker, the electron beam performs its scan incredibly quickly—sixty times per second (NTSC). | ||
- | |||
- | The Bally Arcade provides a Vertical Blank Register (VERBL: [[hardware:i o ports|output port]] $A) that allows the user to set the specific scanline where vertical blanking will begin. The Arcade outputs 102 vertical lines before blanking, so setting a value lower than 101 frees up RAM for scratchpad that would normally be used to display pixel data If the vertical blank register is set to 0, the entirety of RAM can be used for scratchpad. | ||
- | |||
- | The Vertical Blank register is set as follows: | ||
- | |||
- | ^ VERBL Bit ^ Function ^ | ||
- | | 1–7 | Line number where vertical blanking begins | | ||
- | | 0 | None (always 0) | | ||
- | |||
- | Note that VERBL expects the value BLINE*2, where BLINE is the Bottom LINE of the vertical blank. For example, //Astro Battle// sets its vertical blank as follows: | ||
- | |||
- | <code z80> | ||
- | LD A,$B4 ; 180 dec. (90 pixel lines times 2) for | ||
- | OUT (VERBL),A ; Port 10 - Vertical Blank [at scan]line | ||
- | </code> | ||
- | |||
- | The value $B4 (or 180) is two times the desired vertical blanking target of line 90. The remaining 12 lines below vertical blank are reserved for scratchpad use throughout the game. (//Astro Battle// [[http://www.ballyalley.com/ml/ml_source/battle.asm|source code]]) | ||
- | |||
- | [illustration] | ||
- | |||
- | The screen area below the vertical blank line will display the "background" (or frame) color defined in bits 6 and 7 of the Horizontal Color Boundary (HORCB: [[hardware: i o ports|output port]] $9). | ||
- | |||
- | ===== User-Defined Interrupts ===== | ||
- | |||
- | The Bally Arcade also allows the user to enable and respond to two software-controlled interrupts: screen interrupts at designated scanlines and interrupts for tracking [[glossary#l|light pen]] input. | ||
- | |||
- | ==== Screen Interrupts ==== | ||
- | |||
- | The screen interrupt synchronizes the software with the video system. If the screen interrupt enable bit is set, the Z80 will be interrupted when the video system completes scanning the line in the interrupt register. As a result, screen interrupts are especially useful for timing-dependent tasks, such as altering the color registers mid-screen, allowing a program to display more than eight colors onscreen simultaneously. | ||
- | |||
- | To enable screen interrupts, several preliminary steps are necessary: | ||
- | |||
- | * Enable screen interrupts and set its mode in INMOD ($E) | ||
- | * Designate the target interrupt scanline in INLIN ($F) | ||
- | * Set the interrupt handler address... | ||
- | * low byte in INFBK ($D) | ||
- | * high byte in register I | ||
- | * Set the interrupt mode with the IM opcode | ||
- | * Enable interrupts with the EI opcode | ||
- | |||
- | === Interrupt Enable and Mode (INMOD) === | ||
- | |||
- | In order for the Z80 to accept an interrupt, one or two of the external interrupt enable bits must be set ([[output port]] $E). If bit 1 is set, light pen interrupts can occur. If bit 3 is set, screen interrupts can occur. If both bits are set, both interrupts can occur, and the screen interrupt has higher priority. | ||
- | |||
- | The interrupt mode bits determine what happens if an interrupt occurs when the Z80's interrupt enable flip-flop (EI) is not set. Each of the two interrupts may have a different mode. | ||
- | |||
- | * In mode 0, the Z80 will continue to be interrupted until it finally enables interrupts and acknowledges the interrupt. | ||
- | * In mode 1, the interrupt will be discarded if it is not acknowledged by the next instruction after it occurred. In this mode, the software must be designed such that the system will not be executing certain Z80 instructions when the interrupt occurs. The opcodes of these instructions begin with CBH, DDH, EDH, and FDH. | ||
- | |||
- | The INMOD register contains the following interrupt control bits: | ||
- | |||
- | ^ INMOD bit ^ Function ^ | ||
- | | 3 | Screen interrupt enable | | ||
- | | 2 | Interrupt mode for screen interrupts | | ||
- | | 1 | Light pen interrupt enable | | ||
- | | 0 | Interrupt mode for light pen interrupts | | ||
- | |||
- | === Interrupt Line Register (INLIN) === | ||
- | |||
- | If the screen interrupt is enabled in INMOD, the CPU will be interrupted when the display completes scanning the line which is contained in the interrupt line register ([[output port]] $F). To do so, bit 0 is set to 0 and the line number is sent to bits 1–7. | ||
- | |||
- | ^ INLIN bit ^ Function ^ | ||
- | | 1–7 | Line number for screen interrupt | | ||
- | | 0 | None (always 0) | | ||
- | |||
- | === Interrupt Feedback (INFBK) === | ||
- | |||
- | When the CPU acknowledges an interrupt, it reads 8 bits of data from the data bus. It then uses this data as an instruction or an address. In the Bally Arcade, this data is determined by the contents of the interrupt feedback register ([[hardware:i o ports|output port]] $D). In response to a screen interrupt, the contents of the interrupt feedback register are placed directly on the data bus. In response to a light pen interrupt, the lower four bits of the data bus are set to 0 and the upper four bits are the same as the corresponding bits of the feedback register. | ||
- | |||
- | === Interrupt Mode (opcode IM) === | ||
- | |||
- | > "Interrupt processing commences according to the interrupt method stipulated by the IM //i// instruction, where i=0, 1, or 2. If i=1, for direct method, the PC is loaded with 0038H. If i=0, for vectored method, the interrupting device has the opportunity to place the op-code for one byte . If i=2, for indirect vector method, the interrupting device must then place a byte. The Z80 then uses this byte where one of 128 interrupt vectors can be selected by the byte." Wai-Kai Chen (2002). //The circuits and filters handbook//, p. 1943. | ||
- | |||
- | === Enable Interrupts (opcode EI) === | ||
- | |||
- | > "The interrupt vector register, I, is used for the Z80 specific mode 2 interrupts (selected by the IM 2 instruction). It supplies the high byte of the base address for a 128-entry table of service routine addresses which are selected via an index sent to the CPU during an interrupt acknowledge cycle; this index is simply the low byte part of the pointer to the tabulated indirect address pointing to the service routine." (Wikipedia) | ||
- | |||
- | ==== Light Pen Interrupt ==== | ||
- | |||
- | The light pen interrupt occurs when the light pen trigger is pressed and the video scan crosses the point on the screen where the light pen registers. The interrupt routine can read two registers to determine the position of the light pen. The line number is read from the vertical feedback register ([[hardware:i o ports|input port]] $E). Bit 0 is ignored and bits 1–7 indicates the line number. The horizontal position of the light pen can be determined by reading [[hardware:i o ports|input port]] $F and subtracting 8. The resultant value is the pixel number, 0–159. | ||
- | |||
- | ===== Screen Interrupt Examples ===== | ||
- | |||
- | //Football// sets up interrupts as follows: | ||
- | |||
- | <code z80> | ||
- | ; INTERRUPT VECTOR TABLE | ||
- | ; | ||
- | INTTAB: DW L29F0 ; INTERRUPT ROUTINE | ||
- | DW L24D9 ; INTERRUPT ROUTINE | ||
- | |||
- | ;[...] | ||
- | |||
- | L2134: | ||
- | ; | ||
- | ; | ||
- | LD HL,INTTAB ; INTERRUPT TABLE | ||
- | LD A,H | ||
- | LD I,A ; SET INTERRUPT RFG | ||
- | LD A,L | ||
- | OUT (INFBK),A ; AND THE FEEDBACK REGISTER | ||
- | IM 2 | ||
- | EI ; START THE ACTION | ||
- | </code> | ||
- | |||
- | The interrupt table vector (INTTAB) is stored in HL (which can be indexed to access both routines). The high byte from INTTAB is transferred to A, then stored in the interrupt vector register (I). The low byte from INTTAB is then transferred to A, then stored in the Interrupt Feedback register (INFBK). Finally, the program sets interrupt mode to 2 (indirect vector method) and enables interrupts (EI). Consequently, on screen interrupt, the PC will jump to address <I><INFBK>. | ||
- | |||
- | ---- | ||
- | |||
- | //Astro Battle// uses a similar technique to load new color register values at four points down the screen: | ||
- | |||
- | <code z80> | ||
- | ; Setup for Interrupts | ||
- | ; -------------------- | ||
- | ; Initialize first of four screen interrupts to run once EI encountered | ||
- | LD A,IRVEC1 >> 8 ; High Order Byte Address of Interrupt Vector | ||
- | LD I,A ; Load Interrupt Vector Register | ||
- | LD A,IRVEC1 & $FF ; Get Low Order Byte Address | ||
- | OUT (INFBK),A ; Port $0D, INterrupt FeedBacK Register | ||
- | LD A,10*2 ; Screen Line 10 times 2 [below Score] | ||
- | OUT (INLIN),A ; Port $0E, INterrupt LINe Register | ||
- | LD A,$08 | ||
- | OUT (INMOD),A ; Port $0F, INterrupt MODe Register [Screen Ints. only] | ||
- | |||
- | ; Finish Setup for Interrupts | ||
- | ; --------------------------- | ||
- | IM 2 ; Set Interrupt Mode 2 Condition | ||
- | EI ; Enable Interrupts | ||
- | </code> | ||
- | |||
- | ---- | ||
- | |||
- | [NM:92-3] |