86:Interrupts

From WikiTI
Revision as of 23:01, 20 September 2021 by Zeroko (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search


Individual interrupt sources can be enabled, disabled, or acknowledged using Port 3. When an interrupt occurs, the CPU automatically masks interrupts, so there is no need to start with DI. Interrupts must be acknowledged before executing EI, or the interrupt will retrigger immediately after the instruction following the EI is executed. RET & RETI have the same effects on the TI-86, so RET can be used to save one byte.

There is no way to cause a non-maskable interrupt, so the OS does not have an NMI handler.

Interrupt Mode 0

When an interrupt occurs, the CPU treats the current bus content as an opcode & executes it. If the interrupt source was the LCD Controller, this will be the last byte transferred by DMA. For any other interrupt source, it will be the last byte accessed by the instruction that was executing when the interrupt condition arose, either as part of the instruction itself or as a memory operand. If the resulting opcode requires additional opcode or operand bytes, they will all have the same value fetched from the address in PC without changing the value of PC. Under normal circumstances, IM 0 is likely to result in a crash.

Interrupt Mode 1

When an interrupt occurs, the CPU pushes the return address & then jumps to address 0038h. Note that ROM access should not be disabled (see bit 6 of Port 4) while IM 1 is set & interrupts are enabled, or the calculator will likely crash.

The first thing the OS interrupt service routine does (after doing EX AF,AF' & EXX to preserve the registers of the code that was interrupted) is to check whether bit 2 of (IY+23h) is set. If so, it will call the user interrupt handler, provided its checksum is correct. The user interrupt handler starts execution at address D2FEh, & the last usable byte is at D2C5h. The checksum, which is stored at D2FDh, must contain the sum of the bytes stored at D2FEh, D325h, D34Dh, D375h, D39Dh, & D3C5h, or else the aforementioned IY flag will be cleared instead of executing the handler.

If the user handler is not set (or after it returns), the OS checks if ON triggered the interrupt. If so, it either turns the calculator on (if it was off), turns the calculator off (if 2nd was pressed), or makes note of ON having been pressed. Regardless of the interrupt type, it then checks the keypad state, updates the cursor & run indicator if they are enabled, & updates the APD timer. If the APD timer expires, it turns the calculator off after setting a flag (bit 4 of (IY+08)) to indicate that it should resume where it left off instead of returning to the home screen. (Note that certain special cases have been ignored in this description.)

Interrupt Mode 2

When an interrupt occurs, the CPU treats the current bus content as the lower 8 bits of an address, with the upper 8 bits being the value of the I register. Regardless of interrupt source, the bus content will be the last byte accessed (either as part of the opcode or as a memory operand) by the instruction that was executing when the interrupt condition arose, because if LCD DMA occurs, it takes place after the CPU reads the previous bus content. The CPU then pushes the return address & jumps to the address stored at the address saved earlier. If the first or both of the bytes of this new address are read from an unused bank, their value will be the lower 8 bits of the return address. If just the second byte is read from an unused bank, its value will be the same as the first.