Skip to content

Commit

Permalink
Implement reading IE
Browse files Browse the repository at this point in the history
  • Loading branch information
ytausky committed Feb 14, 2020
1 parent 708a2a2 commit c7f40fb
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 15 deletions.
40 changes: 26 additions & 14 deletions src/cpu/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ impl<'a> RunView<'a, InstructionExecutionState> {
(None, output)
}
Tock => {
self.state.bus_data = input.data;
self.state.bus_data = if self.state.read_ie {
self.state.read_ie = false;
Some(self.basic.ie)
} else {
input.data
};
let transition = if self.state.m1 {
Some(if self.basic.ime && input.r#if & self.basic.ie != 0x00 {
ModeTransition::Interrupt
Expand Down Expand Up @@ -105,7 +110,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn ld_r_deref_hl(&mut self, dest: R) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(self.basic.hl()),
M2 => self.bus_read(self.basic.hl()),
M3 => {
self.basic.write(dest, self.state.bus_data.unwrap());
self.execute_m1()
Expand Down Expand Up @@ -133,7 +138,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn ld_a_deref_bc(&mut self) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(self.basic.bc()),
M2 => self.bus_read(self.basic.bc()),
M3 => {
self.basic.a = self.state.bus_data.unwrap();
self.execute_m1()
Expand All @@ -144,7 +149,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn ld_a_deref_de(&mut self) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(self.basic.de()),
M2 => self.bus_read(self.basic.de()),
M3 => {
self.basic.a = self.state.bus_data.unwrap();
self.execute_m1()
Expand All @@ -155,7 +160,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn ld_a_deref_c(&mut self) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(u16::from_be_bytes([0xff, self.basic.c])),
M2 => self.bus_read(u16::from_be_bytes([0xff, self.basic.c])),
M3 => {
self.basic.a = self.state.bus_data.unwrap();
self.execute_m1()
Expand All @@ -175,7 +180,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {
fn ld_a_deref_n(&mut self) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => self.read_immediate(),
M3 => bus_read(u16::from_be_bytes([0xff, self.state.bus_data.unwrap()])),
M3 => self.bus_read(u16::from_be_bytes([0xff, self.state.bus_data.unwrap()])),
M4 => {
self.basic.a = self.state.bus_data.unwrap();
self.execute_m1()
Expand Down Expand Up @@ -203,7 +208,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {
self.state.data = self.state.bus_data.unwrap();
self.read_immediate()
}
M4 => bus_read(u16::from_be_bytes([
M4 => self.bus_read(u16::from_be_bytes([
self.state.bus_data.unwrap(),
self.state.data,
])),
Expand Down Expand Up @@ -238,7 +243,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {
let incremented_hl = hl + 1;
self.basic.h = high_byte(incremented_hl);
self.basic.l = low_byte(incremented_hl);
bus_read(hl)
self.bus_read(hl)
}
M3 => {
self.basic.a = self.state.bus_data.unwrap();
Expand All @@ -255,7 +260,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {
let decremented_hl = hl - 1;
self.basic.h = high_byte(decremented_hl);
self.basic.l = low_byte(decremented_hl);
bus_read(hl)
self.bus_read(hl)
}
M3 => {
self.basic.a = self.state.bus_data.unwrap();
Expand Down Expand Up @@ -422,7 +427,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn alu_op_deref_hl(&mut self, op: AluOp) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(self.basic.hl()),
M2 => self.bus_read(self.basic.hl()),
M3 => {
let (result, flags) = self.alu_op(op, self.basic.a, self.state.bus_data.unwrap());
self.basic.a = result;
Expand All @@ -449,7 +454,7 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn inc_deref_hl(&mut self) -> Option<BusActivity> {
match self.run.m_cycle {
M2 => bus_read(self.basic.hl()),
M2 => self.bus_read(self.basic.hl()),
M3 => {
let (result, flags) = add(self.state.bus_data.unwrap(), 1, false);
self.basic.f.z = flags.z;
Expand Down Expand Up @@ -540,13 +545,13 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn execute_m1(&mut self) -> Option<BusActivity> {
self.state.m1 = true;
bus_read(self.basic.pc)
self.bus_read(self.basic.pc)
}

fn read_immediate(&mut self) -> Option<BusActivity> {
let addr = self.basic.pc;
self.basic.pc += 1;
bus_read(addr)
self.bus_read(addr)
}

fn push_byte(&mut self, data: u8) -> Option<BusActivity> {
Expand All @@ -559,7 +564,14 @@ impl<'a> RunView<'a, InstructionExecutionState> {

fn pop_byte(&mut self) -> Option<BusActivity> {
let addr = self.basic.sp;
self.basic.sp += 1;
self.basic.sp = self.basic.sp.wrapping_add(1);
self.bus_read(addr)
}

fn bus_read(&mut self, addr: u16) -> Option<BusActivity> {
if addr == 0xffff {
self.state.read_ie = true;
}
bus_read(addr)
}

Expand Down
2 changes: 2 additions & 0 deletions src/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ enum Task {
struct InstructionExecutionState {
opcode: u8,
bus_data: Option<u8>,
read_ie: bool,
m1: bool,
data: u8,
addr: u16,
Expand Down Expand Up @@ -322,6 +323,7 @@ impl InstructionExecutionState {
opcode,
m1: false,
bus_data: None,
read_ie: false,
addr: 0xffff,
data: 0xff,
}
Expand Down
34 changes: 33 additions & 1 deletion src/cpu/tests/interrupt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,39 @@ fn enabled_interrupt_not_dispatched_with_reset_ime() {
}

#[test]
fn ld_deref_0xffff_sets_5_lower_bits_of_ie() {
fn reading_0xffff_returns_ie() {
let mut cpu = Cpu::default();
cpu.data.ie = 0x15;
cpu.test_simple_instr(
&[0xf0, 0xff],
&[
(Input::with_data(None), bus_read(0xffff)),
(Input::with_data(None), None),
],
);
assert_eq!(cpu.data.a, 0x15)
}

#[test]
fn read_memory_in_same_instruction_after_reading_0xffff() {
let mut cpu = Cpu::default();
cpu.data.sp = 0xffff;
cpu.data.ie = 0x15;
const POP_BC: u8 = 0xc1;
cpu.test_simple_instr(
&[POP_BC],
&[
(Input::with_data(None), bus_read(0xffff)),
(Input::with_data(None), None),
(Input::with_data(None), bus_read(0x0000)),
(Input::with_data(Some(0x42)), None),
],
);
assert_eq!(cpu.data.bc(), 0x4215)
}

#[test]
fn writing_0xffff_sets_5_lower_bits_of_ie() {
let mut cpu = Cpu::default();
cpu.data.ie = 0x00;
cpu.data.a = 0xff;
Expand Down

0 comments on commit c7f40fb

Please sign in to comment.