eZ80 CPU Architecture
The TI-84 Plus CE uses the Zilog eZ80 CPU, a Z80-compatible processor with extended 24-bit addressing capabilities. The emulator implements the complete eZ80 instruction set with cycle-accurate timing.Overview
The eZ80 is a hybrid CPU that supports:- Z80 mode: 16-bit addressing with MBASE register (backward compatibility)
- ADL mode: 24-bit addressing (Address Data Long)
- Mixed mode: Dynamic switching between Z80 and ADL modes per instruction
Register Set
Main Registers (ADL Mode)
Special Registers
- I (16-bit): Interrupt vector base for mode 2 interrupts
- R (8-bit): Memory refresh register (increments per instruction)
- MBASE (8-bit): Memory base register for Z80 mode addressing
Shadow Registers
For fast context switching:- AF’: Shadow accumulator/flags
- BC’: Shadow BC
- DE’: Shadow DE
- HL’: Shadow HL
EX AF, AF' and EXX instructions.
Flags Register (F)
ADL Mode
Address Data Long (ADL)
When ADL = 1:- All register pairs (BC, DE, HL, IX, IY, SP) are 24-bit
- Memory addresses are 24-bit
- Stack operations push/pop 3 bytes
CALL/RETuse 24-bit return addresses
Z80 Mode
When ADL = 0:- Register pairs are 16-bit (upper byte preserved but ignored)
- Memory addresses are 16-bit + MBASE (8-bit page register)
- Effective address =
(MBASE << 16) | 16-bit_address
- Effective address =
- Stack operations push/pop 2 bytes
CALL/RETuse 16-bit return addresses
Per-Instruction Mode Flags
eZ80 supports mixed-mode execution with per-instruction overrides:- L: Data addressing mode for current instruction
L=1: Use 24-bit addresses for memory operandsL=0: Use 16-bit addresses (MBASE applied)
- IL: Instruction/index addressing mode
IL=1: Use 24-bit addresses for instruction fetchesIL=0: Use 16-bit addresses (MBASE applied)
Instruction Execution
Fetch-Decode-Execute Cycle
Prefix Bytes
eZ80 uses prefix bytes to extend the instruction set:| Prefix | Category | Example Instructions |
|---|---|---|
DD | IX-indexed | LD A, (IX+d) |
FD | IY-indexed | LD A, (IY+d) |
ED | Extended | ADC HL, BC, LDI, MLT |
CB | Bit operations | BIT n, r, SET n, r |
DD CB | IX bit ops | BIT n, (IX+d) |
FD CB | IY bit ops | BIT n, (IY+d) |
eZ80-Specific Instructions
The eZ80 adds several instructions beyond the standard Z80:MLT - Multiply
ED 4C/5C/6C/7CCycles: 8
LEA - Load Effective Address
ED 22/23 + register encodingCycles: 3
PEA - Push Effective Address
ED 65/66Cycles: 7 (ADL) or 5 (Z80)
LD A, MB - Load MBASE
ED 6ECycles: 2
Used by ROM: For RAM address validation during boot
STMIX / RSMIX - Mixed Mode Control
ED 7D / ED 7ECycles: 1
Interrupt Handling
Interrupt Enable Flip-Flops
- IFF1: Master interrupt enable (checked before servicing IRQ)
- IFF2: Shadow of IFF1 (preserved during NMI)
EI, allowing:
Interrupt Modes
Mode 0 (IM 0)
Mode 1 (IM 1)
RST 0x38
Mode 2 (IM 2)
- Read interrupt vector byte from device (typically 0x00)
- Form 16-bit address:
(I << 8) | vector - Read 24-bit handler address from that location
- Jump to handler
NMI (Non-Maskable Interrupt)
Triggered by:- Memory protection violations (stack limit, protected RAM writes)
- External NMI signal (not used on CE)
- Save IFF1 to IFF2
- Clear IFF1 (disable interrupts)
- Call 0x0066
Cycle Timing
Instruction Timing
Instructions charge cycles based on:- Opcode complexity: Simple ops (1-2 cycles), complex ops (4-8 cycles)
- Memory accesses: Flash reads (10 cycles), RAM reads (4 cycles)
- Prefixes: DD/FD add 1 cycle, CB adds 2 cycles
- Operand size: ADL mode adds cycles for 24-bit operations
| Instruction | Opcode | Internal | Memory | Total |
|---|---|---|---|---|
NOP | F3 | 1 | 0 | 1 |
LD A, B | 78 | 1 | 0 | 1 |
LD A, (HL) | 7E | 1 | 4 (RAM read) | 5 |
LD HL, nnnn | 21 nn nn nn | 3 | 0 | 3 |
CALL nn (ADL) | CD nn nn nn | 5 | 10 (stack write) | 15 |
MLT BC | ED 4C | 8 | 0 | 8 |
Prefetch Buffer
The emulator maintains a prefetch buffer to match CEmu’s cycle accounting:- During each fetch, the next byte is prefetched
- The prefetch cost is charged to the current instruction
- This matches real hardware behavior where the bus is kept busy
CPU State
HALT State
- Maskable interrupt (IRQ) if IFF1=1
- Non-maskable interrupt (NMI)
- ON key press (TI-specific, wakes even if IFF1=0)
- Any key press (when keypad in any-key mode)
Execution History
For debugging, the emulator maintains a 64-entry ring buffer:Critical eZ80 Behaviors
Flash Unlock Sequence
Flash writes require detecting a specific instruction sequence fetched from privileged code (PC ≤ privileged boundary):ADL Mode Persistence
Key rule:CALL, RET, and RST with IL=1 set ADL=IL permanently for the called function.
Stack Pointer Selection
Instruction Set Reference
Opcode Table (Base Instructions)
The eZ80 instruction set is organized by opcode byte patterns:Testing and Verification
Trace Format
For parity testing with CEmu:Common Test Points
- Boot sequence: First 1M cycles should match CEmu exactly
- Flag behavior: Verify S/Z/H/P/N/C flags for all ALU operations
- ADL mode: Test 24-bit addressing with mixed-mode calls
- Interrupts: Verify IM 1/2 handler dispatch and RETI
- eZ80 extensions: MLT, LEA, PEA, LD A,MB timing
Performance Optimizations
Cycle Batching
During HALT, the emulator batches peripheral ticks:Inline Hot Paths
Critical functions are marked#[inline(always)]:
Next Steps
- Emulator Core - Core architecture overview
- Memory Map - Address space and peripherals
- Dual Backend - Cycle timing modes