hg80 1.0.0

Z80 and Z80N CPU core, stepped one clock edge at a time
Documentation
//! A Z80 and Z80N CPU core, stepped one clock edge at a time.
//!
//! The core is a hardware model, not an interpreter. A combinational microcode decode and ALU feed
//! a machine-cycle and T-state sequencer, and register writes commit on the clock edge.
//!
//! [`Cpu::tick`] advances one edge — half a T-state. That makes each bus transition a real Z80
//! presents visible on its own tick: the address becoming valid, the control lines asserting, the
//! data bus being latched.
//!
//! [`Cpu::step`] runs to the next instruction boundary and returns the T-states taken, for callers
//! that don't need that detail.
//!
//! # Driving the core
//!
//! Everything outside the CPU — memory, ports, wait states, the interrupt vector — comes through
//! the [`Host`] trait, which the caller implements:
//!
//! ```
//! use hg80::{Cpu, Host};
//!
//! struct FlatMemory {
//!     bytes: [u8; 0x10000],
//! }
//!
//! impl Host for FlatMemory {
//!     fn read(&mut self, address: u16, _at: u32) -> u8 {
//!         self.bytes[address as usize]
//!     }
//!
//!     fn write(&mut self, address: u16, value: u8, _at: u32) {
//!         self.bytes[address as usize] = value;
//!     }
//!
//!     fn input(&mut self, _port: u16, _at: u32) -> u8 {
//!         0xFF
//!     }
//!
//!     fn output(&mut self, _port: u16, _value: u8, _at: u32) {}
//! }
//!
//! let mut cpu = Cpu::new();
//! let mut host = FlatMemory { bytes: [0; 0x10000] };
//! cpu.reset();
//! assert_eq!(cpu.registers().pc, 0);
//! ```
//!
//! # Z80 and Z80N
//!
//! [`Cpu::set_z80n_enabled`] switches between a plain Z80 and the Z80N superset at run time. With
//! Z80N off, the extended `ED`-prefixed opcodes decode as the no-operation forms a real Z80 gives
//! them, so one instance can model either part.
//!
//! Z80N instructions with effects outside the CPU don't reach outside the core themselves. They're
//! reported to the host as a [`Z80nCommand`] carrying its operand, and the host does the work. That
//! keeps the core free of any particular machine's memory-management or register-file details.

#![no_std]
#![forbid(unsafe_code)]

#[cfg(test)]
extern crate std;

mod alu;
mod consts;
mod control;
mod core;
mod extended;
mod flags;
mod host;
mod mcode;
mod plan;
mod stepped;
mod types;

pub use consts::flag;
pub use core::Cpu;
pub use host::{BusCycle, BusRequest, Host};
pub use types::{
    ClockEdge, InterruptMode, MachineCycle, Registers, UndocumentedFlags, Z80nCommand,
};