Skip to content

Commit

Permalink
Simplify the crate interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanizag committed Apr 20, 2020
1 parent 937f2c1 commit 996d16f
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 262 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "iz80"
version = "0.1.0"
version = "0.2.0"
authors = ["Ivan Izaguirre <[email protected]>"]
edition = "2018"
license = "MIT"
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ use iz80::*;
fn main() {
// Prepare the device
let mut machine = PlainMachine::new();
let mut state = State::new();
let mut cpu = Cpu::new();
cpu.set_trace(true);

Expand All @@ -41,12 +40,12 @@ fn main() {
}

// Run emulation
state.reg.set_pc(0x0000);
cpu.registers().set_pc(0x0000);
loop {
cpu.execute_instruction(&mut state, &mut machine);
cpu.execute_instruction(&mut machine);

// Examine Machine state to update the hosting device as needed.
if state.reg.a() == 0x10 {
if cpu.registers().a() == 0x10 {
// Let's stop
break;
}
Expand Down
8 changes: 3 additions & 5 deletions src/bin/cpuville.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,12 @@ use std::time::Duration;

use iz80::Cpu;
use iz80::Machine;
use iz80::State;

static TINY_BASIC: &'static [u8] = include_bytes!("rom/tinybasic2dms.bin");

fn main() {
let mut machine = VilleMachine::new();
let mut state = State::new();
let cpu = Cpu::new();
let mut cpu = Cpu::new();

// Init console
let mut stdout = stdout();
Expand All @@ -34,11 +32,11 @@ fn main() {
}

// Init
state.reg.set_pc(0x0000);
cpu.registers().set_pc(0x0000);
machine.in_values[3] = 1; // TX Ready

loop {
cpu.execute_instruction(&mut state, &mut machine);
cpu.execute_instruction(&mut machine);

if machine.out_called {
match machine.out_port {
Expand Down
7 changes: 3 additions & 4 deletions src/bin/simplest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use iz80::*;
fn main() {
// Prepare the device
let mut machine = PlainMachine::new();
let mut state = State::new();
let mut cpu = Cpu::new();
cpu.set_trace(true);

Expand All @@ -16,12 +15,12 @@ fn main() {
}

// Run emulation
state.reg.set_pc(0x0000);
cpu.registers().set_pc(0x0000);
loop {
cpu.execute_instruction(&mut state, &mut machine);
cpu.execute_instruction(&mut machine);

// Examine Machine state to update the hosting device as needed.
if state.reg.a() == 0x10 {
if cpu.registers().a() == 0x10 {
// Let's stop
break;
}
Expand Down
32 changes: 19 additions & 13 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use super::state::*;
/// Executes Z80 instructions changing the cpu State and Machine
pub struct Cpu {
decoder: Decoder,
state: State,
trace: bool,
}

Expand All @@ -17,6 +18,7 @@ impl Cpu {
pub fn new() -> Cpu {
Cpu {
decoder: Decoder::new(),
state: State::new(),
trace: false
}
}
Expand All @@ -25,19 +27,18 @@ impl Cpu {
///
/// # Arguments
///
/// * `state` - The internal state of the Z80
/// * `sys` - A representation of the emulated machine that has the Machine trait
///
pub fn execute_instruction(&self, state: &mut State, sys: &mut dyn Machine) {
pub fn execute_instruction(&mut self, sys: &mut dyn Machine) {
if self.trace {
let pc = state.reg.pc();
let pc = self.state.reg.pc();
let opcode_index = sys.peek(pc);
//print!("==== {:04x}: {:02x} ", pc, opcode_index);
print!("==== {:04x}: {:02x} {:02x} {:02x} ", pc, opcode_index,
sys.peek(pc+1), sys.peek(pc+2));
}

let mut env = Environment::new(state, sys);
let mut env = Environment::new(&mut self.state, sys);
let opcode = self.decoder.decode(&mut env);
if self.trace {
println!("{}", opcode.disasm(&mut env));
Expand All @@ -48,15 +49,15 @@ impl Cpu {
if self.trace {
// CPU registers
println!("PC({:04x}) AF({:04x}) BC({:04x}) DE({:04x}) HL({:04x}) SP({:04x}) IX({:04x}) IY({:04x}) Flags({:08b})",
state.reg.pc(),
state.reg.get16(Reg16::AF),
state.reg.get16(Reg16::BC),
state.reg.get16(Reg16::DE),
state.reg.get16(Reg16::HL),
state.reg.get16(Reg16::SP),
state.reg.get16(Reg16::IX),
state.reg.get16(Reg16::IY),
state.reg.get8(Reg8::F)
self.state.reg.pc(),
self.state.reg.get16(Reg16::AF),
self.state.reg.get16(Reg16::BC),
self.state.reg.get16(Reg16::DE),
self.state.reg.get16(Reg16::HL),
self.state.reg.get16(Reg16::SP),
self.state.reg.get16(Reg16::IX),
self.state.reg.get16(Reg16::IY),
self.state.reg.get8(Reg8::F)
);
}
}
Expand All @@ -70,6 +71,11 @@ impl Cpu {
pub fn set_trace(&mut self, trace: bool) {
self.trace = trace;
}

/// Returns a Registers struct to read and write on the Z80 registers
pub fn registers(&mut self) -> &mut Registers {
&mut self.state.reg
}
}


10 changes: 4 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
//!fn main() {
//! // Prepare the device
//! let mut machine = PlainMachine::new();
//! let mut state = State::new();
//! let mut cpu = Cpu::new();
//! cpu.set_trace(true);
//!
Expand All @@ -26,12 +25,12 @@
//! }
//!
//! // Run emulation
//! state.reg.set_pc(0x0000);
//! cpu.registers().set_pc(0x0000);
//! loop {
//! cpu.execute_instruction(&mut state, &mut machine);
//! cpu.execute_instruction(&mut machine);
//!
//! // Examine Machine state to update the hosting device as needed.
//! if state.reg.a() == 0x10 {
//! if cpu.registers().a() == 0x10 {
//! // Let's stop
//! break;
//! }
Expand Down Expand Up @@ -60,5 +59,4 @@ mod operators;
pub use cpu::Cpu;
pub use machine::Machine;
pub use machine::PlainMachine;
pub use registers::*;
pub use state::State;
pub use registers::*;
8 changes: 4 additions & 4 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ pub struct State {
/// Halt state of the CPU
pub halted: bool,
// Alternate index management
pub(crate) index: Reg16, // Using HL, IX or IY
pub(crate) displacement: i8, // Used for (IX+d) and (iY+d)
pub(crate) displacement_loaded: bool, // TODO: remove
pub(crate) index_changed: bool, // Use the index change for the next opcode, reset afterwards
pub index: Reg16, // Using HL, IX or IY
pub displacement: i8, // Used for (IX+d) and (iY+d)
pub displacement_loaded: bool, // TODO: remove
pub index_changed: bool, // Use the index change for the next opcode, reset afterwards
}

impl State {
Expand Down
26 changes: 11 additions & 15 deletions tests/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,33 @@ use iz80::*;
#[test]
fn test_two_opcodes() {
let mut sys = PlainMachine::new();
let mut state = State::new();
let mut cpu = Cpu::new();

sys.poke(0x0000, 0x06); // LD B, $34
sys.poke(0x0001, 0x34);
sys.poke(0x0002, 0x78); // LD A, B

cpu.execute_instruction(&mut state, &mut sys);
cpu.execute_instruction(&mut state, &mut sys);
cpu.execute_instruction(&mut sys);
cpu.execute_instruction(&mut sys);

println!("Registers: {:?}", state.reg);

assert_eq!(0x34, state.reg.a());
assert_eq!(0x34, cpu.registers().a());
}

#[test]
fn test_push_pop_rr() {
let mut sys = PlainMachine::new();
let mut state = State::new();
let mut cpu = Cpu::new();

sys.poke(0x0000, 0xc5); // PUSH BC
sys.poke(0x0001, 0xf1); // POP AF
state.reg.set16(Reg16::AF, 0x5678);
state.reg.set16(Reg16::BC, 0x1234);
cpu.registers().set16(Reg16::AF, 0x5678);
cpu.registers().set16(Reg16::BC, 0x1234);

cpu.execute_instruction(&mut state, &mut sys);
assert_eq!(0x1234, state.reg.get16(Reg16::BC));
assert_eq!(0x5678, state.reg.get16(Reg16::AF));
cpu.execute_instruction(&mut sys);
assert_eq!(0x1234, cpu.registers().get16(Reg16::BC));
assert_eq!(0x5678, cpu.registers().get16(Reg16::AF));

cpu.execute_instruction(&mut state, &mut sys);
assert_eq!(0x1234, state.reg.get16(Reg16::BC));
assert_eq!(0x1234, state.reg.get16(Reg16::AF));
cpu.execute_instruction(&mut sys);
assert_eq!(0x1234, cpu.registers().get16(Reg16::BC));
assert_eq!(0x1234, cpu.registers().get16(Reg16::AF));
}
Loading

0 comments on commit 996d16f

Please sign in to comment.