emu_run_cycles
Run the emulator for a specified number of CPU cycles.Parameters
- emu: Pointer to emulator instance
- cycles: Number of CPU cycles to execute (must be > 0)
Returns
- >= 0: Number of cycles actually executed
- 0: No execution (null pointer or cycles <= 0)
Description
Executes the eZ80 CPU for the specified number of cycles. This is the main emulation loop driver. The function also updates the framebuffer with current VRAM contents after execution completes. The TI-84 Plus CE runs at 15 MHz (15,000,000 cycles per second). For real-time emulation at 60 FPS, call this function with250,000 cycles per frame.
The returned value may differ from the requested cycles if:
- The CPU is halted or stopped
- An internal error occurs
- The emulator needs to synchronize internal state
Example: Real-Time Emulation Loop
Example: Fast-Forward (Maximum Speed)
Example: Step-by-Step Debugging
Example: Variable Speed Emulation
Timing Details
Clock Speed
The TI-84 Plus CE eZ80 CPU can run at multiple clock speeds:- 6 MHz: Low power mode
- 12 MHz: Medium speed
- 15 MHz: Default speed (most common)
- 24 MHz: High speed
- 48 MHz: Maximum speed
Frame Rate
The LCD has no fixed refresh rate, but 60 FPS is standard for emulators:- 60 FPS → 15,000,000 / 60 = 250,000 cycles/frame
- 30 FPS → 15,000,000 / 30 = 500,000 cycles/frame
- 120 FPS → 15,000,000 / 120 = 125,000 cycles/frame
Instruction Timing
eZ80 instructions take 1-20+ cycles depending on:- Instruction type (register ops are fast, memory ops are slow)
- Memory region (flash has wait states, RAM is faster)
- ADL mode vs Z80 mode (ADL uses 24-bit addresses)
- NOP: 1 cycle
- LD r,r: 1 cycle
- LD r,(HL): 6 cycles
- CALL: 17 cycles
- Flash read: +2 wait state cycles
Thread Safety
Theemu_run_cycles() function is thread-safe and can be called concurrently with other API functions like emu_set_key() or emu_framebuffer(). The internal mutex ensures atomicity.
Typical multi-threaded usage:
Performance Considerations
Chunk Size
Running larger chunks per call reduces overhead:- Small chunks (1,000 cycles): High overhead, good for fine-grained control
- Medium chunks (100,000 cycles): Balanced for responsive UI
- Large chunks (1,000,000 cycles): Low overhead, best for maximum speed
Framebuffer Updates
The function automatically callsemu.render_frame() after execution, which updates the framebuffer from VRAM. This adds minimal overhead (~0.1ms) but ensures the display is always current.
Error Handling
The function returns 0 in these cases:- Null emulator pointer
- cycles parameter <= 0
- Internal CPU halt state
See Also
- Display - Read framebuffer after execution
- Input - Send key events during execution
- Lifecycle - Power on before execution
- ROM Management - Load ROM before execution