2021-11-02 05:06:40 +00:00
|
|
|
|
2023-04-24 01:49:40 +00:00
|
|
|
use moa_core::{ClockTime, Address, BusPort, Signal, Frequency};
|
2021-11-02 05:06:40 +00:00
|
|
|
|
2022-09-25 06:14:03 +00:00
|
|
|
use crate::decode::Z80Decoder;
|
|
|
|
use crate::debugger::Z80Debugger;
|
2021-11-02 05:06:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
|
|
|
pub enum Z80Type {
|
|
|
|
Z80,
|
|
|
|
}
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2021-11-02 05:06:40 +00:00
|
|
|
pub enum Status {
|
|
|
|
Init,
|
|
|
|
Running,
|
|
|
|
Halted,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2021-11-16 04:52:19 +00:00
|
|
|
pub enum InterruptMode {
|
|
|
|
Mode0,
|
|
|
|
Mode01,
|
|
|
|
Mode1,
|
|
|
|
Mode2,
|
|
|
|
}
|
|
|
|
|
2021-11-02 05:06:40 +00:00
|
|
|
#[repr(u8)]
|
|
|
|
#[allow(dead_code)]
|
2023-03-06 04:19:49 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2021-11-02 05:06:40 +00:00
|
|
|
pub enum Flags {
|
2021-11-03 03:58:03 +00:00
|
|
|
Carry = 0x01,
|
|
|
|
AddSubtract = 0x02,
|
|
|
|
Parity = 0x04,
|
2021-11-11 00:05:16 +00:00
|
|
|
F3 = 0x08,
|
2021-11-03 03:58:03 +00:00
|
|
|
HalfCarry = 0x10,
|
2021-11-11 00:05:16 +00:00
|
|
|
F5 = 0x20,
|
2021-11-03 03:58:03 +00:00
|
|
|
Zero = 0x40,
|
|
|
|
Sign = 0x80,
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[repr(u8)]
|
2023-03-06 04:19:49 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
2021-11-03 03:58:03 +00:00
|
|
|
pub enum Register {
|
|
|
|
B = 0,
|
|
|
|
C = 1,
|
|
|
|
D = 2,
|
|
|
|
E = 3,
|
|
|
|
H = 4,
|
|
|
|
L = 5,
|
|
|
|
A = 6,
|
|
|
|
F = 7,
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
2021-11-02 05:06:40 +00:00
|
|
|
pub struct Z80State {
|
|
|
|
pub status: Status,
|
2021-11-05 04:30:33 +00:00
|
|
|
pub interrupts_enabled: bool,
|
2021-11-16 04:52:19 +00:00
|
|
|
pub interrupt_mode: InterruptMode,
|
2021-11-02 05:06:40 +00:00
|
|
|
|
|
|
|
pub pc: u16,
|
|
|
|
pub sp: u16,
|
|
|
|
pub ix: u16,
|
|
|
|
pub iy: u16,
|
|
|
|
|
|
|
|
pub reg: [u8; 8],
|
2021-11-05 04:30:33 +00:00
|
|
|
pub shadow_reg: [u8; 8],
|
2021-11-02 05:06:40 +00:00
|
|
|
|
|
|
|
pub i: u8,
|
|
|
|
pub r: u8,
|
|
|
|
}
|
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
impl Default for Z80State {
|
|
|
|
fn default() -> Self {
|
2021-11-02 05:06:40 +00:00
|
|
|
Self {
|
|
|
|
status: Status::Init,
|
2021-11-05 04:30:33 +00:00
|
|
|
interrupts_enabled: false,
|
2021-11-16 04:52:19 +00:00
|
|
|
interrupt_mode: InterruptMode::Mode0,
|
2021-11-02 05:06:40 +00:00
|
|
|
|
|
|
|
pc: 0,
|
|
|
|
sp: 0,
|
|
|
|
ix: 0,
|
|
|
|
iy: 0,
|
|
|
|
|
|
|
|
reg: [0; 8],
|
2021-11-05 04:30:33 +00:00
|
|
|
shadow_reg: [0; 8],
|
2021-11-02 05:06:40 +00:00
|
|
|
|
|
|
|
i: 0,
|
|
|
|
r: 0,
|
|
|
|
}
|
|
|
|
}
|
2023-03-06 04:19:49 +00:00
|
|
|
}
|
2021-11-09 19:03:57 +00:00
|
|
|
|
2023-03-06 04:19:49 +00:00
|
|
|
impl Z80State {
|
2021-11-09 19:03:57 +00:00
|
|
|
pub fn get_register(&mut self, reg: Register) -> u8 {
|
|
|
|
self.reg[reg as usize]
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_register(&mut self, reg: Register, value: u8) {
|
|
|
|
self.reg[reg as usize] = value;
|
|
|
|
}
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub struct Z80 {
|
|
|
|
pub cputype: Z80Type,
|
2023-04-23 22:46:47 +00:00
|
|
|
pub frequency: Frequency,
|
2021-11-02 05:06:40 +00:00
|
|
|
pub state: Z80State,
|
|
|
|
pub decoder: Z80Decoder,
|
2021-11-07 04:18:45 +00:00
|
|
|
pub debugger: Z80Debugger,
|
2021-11-02 05:06:40 +00:00
|
|
|
pub port: BusPort,
|
2021-11-16 04:52:19 +00:00
|
|
|
pub reset: Signal<bool>,
|
|
|
|
pub bus_request: Signal<bool>,
|
2023-04-24 01:49:40 +00:00
|
|
|
pub current_clock: ClockTime,
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Z80 {
|
2023-04-23 22:46:47 +00:00
|
|
|
pub fn new(cputype: Z80Type, frequency: Frequency, port: BusPort) -> Self {
|
2021-11-02 05:06:40 +00:00
|
|
|
Self {
|
|
|
|
cputype,
|
|
|
|
frequency,
|
2023-03-06 04:19:49 +00:00
|
|
|
state: Z80State::default(),
|
|
|
|
decoder: Z80Decoder::default(),
|
|
|
|
debugger: Z80Debugger::default(),
|
|
|
|
port,
|
2021-11-16 04:52:19 +00:00
|
|
|
reset: Signal::new(false),
|
|
|
|
bus_request: Signal::new(false),
|
2023-04-24 01:49:40 +00:00
|
|
|
current_clock: ClockTime::START,
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
2021-12-13 19:05:22 +00:00
|
|
|
pub fn clear_state(&mut self) {
|
2023-03-06 04:19:49 +00:00
|
|
|
self.state = Z80State::default();
|
|
|
|
self.decoder = Z80Decoder::default();
|
|
|
|
self.debugger = Z80Debugger::default();
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
|
2023-04-24 01:49:40 +00:00
|
|
|
pub fn dump_state(&mut self, clock: ClockTime) {
|
2021-11-02 05:06:40 +00:00
|
|
|
println!("Status: {:?}", self.state.status);
|
2021-11-05 04:30:33 +00:00
|
|
|
println!("PC: {:#06x}", self.state.pc);
|
|
|
|
println!("SP: {:#06x}", self.state.sp);
|
|
|
|
println!("IX: {:#06x}", self.state.ix);
|
|
|
|
println!("IY: {:#06x}", self.state.iy);
|
|
|
|
|
2021-11-10 21:28:31 +00:00
|
|
|
println!("A: {:#04x} F: {:#04x} A': {:#04x} F': {:#04x}", self.state.reg[Register::A as usize], self.state.reg[Register::F as usize], self.state.shadow_reg[Register::A as usize], self.state.shadow_reg[Register::F as usize]);
|
|
|
|
println!("B: {:#04x} C: {:#04x} B': {:#04x} C': {:#04x}", self.state.reg[Register::B as usize], self.state.reg[Register::C as usize], self.state.shadow_reg[Register::B as usize], self.state.shadow_reg[Register::C as usize]);
|
|
|
|
println!("D: {:#04x} E: {:#04x} D': {:#04x} E': {:#04x}", self.state.reg[Register::D as usize], self.state.reg[Register::E as usize], self.state.shadow_reg[Register::D as usize], self.state.shadow_reg[Register::E as usize]);
|
|
|
|
println!("H: {:#04x} L: {:#04x} H': {:#04x} L': {:#04x}", self.state.reg[Register::H as usize], self.state.reg[Register::L as usize], self.state.shadow_reg[Register::H as usize], self.state.shadow_reg[Register::L as usize]);
|
2021-11-02 05:06:40 +00:00
|
|
|
|
2021-11-05 04:30:33 +00:00
|
|
|
println!("Current Instruction: {} {:?}", self.decoder.format_instruction_bytes(&mut self.port), self.decoder.instruction);
|
2023-03-06 04:19:49 +00:00
|
|
|
println!();
|
2023-04-24 01:49:40 +00:00
|
|
|
self.port.dump_memory(clock, self.state.sp as Address, 0x40);
|
2023-03-06 04:19:49 +00:00
|
|
|
println!();
|
2021-11-02 05:06:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|