hg80 1.0.0

Z80 and Z80N CPU core, stepped one clock edge at a time
Documentation
//! A long, mixed workload for a sampling profiler or a counter run to chew on.

use hg80::{Cpu, Host};

struct Flat {
    bytes: Box<[u8; 0x10000]>,
}

impl Host for Flat {
    fn read(&mut self, a: u16, _at: u32) -> u8 {
        self.bytes[a as usize]
    }
    fn write(&mut self, a: u16, v: u8, _at: u32) {
        self.bytes[a as usize] = v;
    }
    fn input(&mut self, _p: u16, _at: u32) -> u8 {
        0xFF
    }
    fn output(&mut self, _p: u16, _v: u8, _at: u32) {}
}

fn main() {
    let program: &[u8] = &[
        0xDD, 0x21, 0x00, 0x80, 0xFD, 0x21, 0x00, 0x90, 0x06, 0x20, 0xDD, 0x7E, 0x05, 0xDD, 0x77,
        0x06, 0xFD, 0x35, 0x02, 0xDD, 0xCB, 0x05, 0x46, 0xCB, 0x27, 0x10, 0xEF, 0x3E, 0x01, 0xC6,
        0x11, 0xD6, 0x07, 0x27, 0x21, 0x00, 0x80, 0x11, 0x00, 0x90, 0x01, 0x00, 0x08, 0xED, 0xB0,
        0xC3, 0x00, 0x00,
    ];
    let mut bytes = vec![0u8; 0x10000].into_boxed_slice();
    bytes[..program.len()].copy_from_slice(program);
    let mut host = Flat {
        bytes: bytes.try_into().unwrap(),
    };
    let mut cpu = Cpu::new();
    cpu.reset();
    cpu.set_z80n_enabled(true);
    cpu.registers_mut().sp = 0xFF00;
    let mut total: u64 = 0;
    for _ in 0..300_000_000u64 {
        cpu.tick(&mut host);
        total += 1;
    }
    println!("{total}");
}