remove MemoryReader trait

This commit is contained in:
Daniel Bauer
2020-01-18 21:31:47 +01:00
parent cc43894431
commit c037c349de
4 changed files with 46 additions and 75 deletions

View File

@@ -85,17 +85,3 @@ impl Memory for Bus {
} }
} }
} }
pub trait MemoryReader {
fn readb<T: Memory>(&self, mem: &T, addr: Addr) -> Byte {
mem.readb(addr)
}
fn readw<T: Memory>(&self, mem: &T, addr: Addr) -> Word {
mem.readw(addr)
}
fn writeb<T: Memory>(&mut self, mem: &mut T, addr: Addr, data: Byte) {
mem.writeb(addr, data)
}
}

View File

@@ -1,4 +1,4 @@
use crate::nes::{Memory,MemoryReader}; use crate::nes::Memory;
use crate::nes::types::*; use crate::nes::types::*;
use instructions::{Instruction,Operation,AddrMode}; use instructions::{Instruction,Operation,AddrMode};
use core::fmt::{Debug,Formatter,Result}; use core::fmt::{Debug,Formatter,Result};
@@ -65,9 +65,6 @@ pub struct CPU {
stopped: bool, stopped: bool,
} }
// Default implementation to read/write from mem
impl MemoryReader for CPU { }
impl CPU { impl CPU {
pub fn new() -> Self { pub fn new() -> Self {
CPU { CPU {
@@ -133,14 +130,14 @@ impl CPU {
// read the next opcode and increment pc // read the next opcode and increment pc
fn readb_pc<T: Memory>(&mut self, mem: &T) -> Byte { fn readb_pc<T: Memory>(&mut self, mem: &T) -> Byte {
let val = self.readb(mem, self.regs.pc); let val = mem.readb(self.regs.pc);
self.regs.pc += 1; self.regs.pc += 1;
val val
} }
// read whole Word from pc // read whole Word from pc
fn readw_pc<T: Memory>(&mut self, mem: &T) -> Word { fn readw_pc<T: Memory>(&mut self, mem: &T) -> Word {
let val = self.readw(mem, self.regs.pc); let val = mem.readw(self.regs.pc);
self.regs.pc += 2; self.regs.pc += 2;
val val
} }
@@ -148,13 +145,13 @@ impl CPU {
// Pop a byte from the SP // Pop a byte from the SP
fn popb_sp<T: Memory>(&mut self, mem: &T) -> Byte { fn popb_sp<T: Memory>(&mut self, mem: &T) -> Byte {
self.regs.sp += 1; self.regs.sp += 1;
let val = self.readb(mem, STACK_BASE_ADDR + self.regs.sp as Word); let val = mem.readb(STACK_BASE_ADDR + self.regs.sp as Word);
val val
} }
// Push a byte to the SP. // Push a byte to the SP.
fn pushb_sp<T: Memory>(&mut self, mem: &mut T, val: Byte) { fn pushb_sp<T: Memory>(&mut self, mem: &mut T, val: Byte) {
self.writeb(mem, STACK_BASE_ADDR + self.regs.sp as Word, val); mem.writeb(STACK_BASE_ADDR + self.regs.sp as Word, val);
self.regs.sp -= 1; self.regs.sp -= 1;
} }
@@ -370,12 +367,12 @@ impl CPU {
// and need to wrap around. So hi is fetched from 0x0000 instead of // and need to wrap around. So hi is fetched from 0x0000 instead of
// 0x0100 // 0x0100
let addr = if ind_addr & LO == 0x00FF { let addr = if ind_addr & LO == 0x00FF {
let lo = self.readb(mem, ind_addr); let lo = mem.readb(ind_addr);
let hi_addr = ind_addr - 0x00FF; let hi_addr = ind_addr - 0x00FF;
let hi = self.readb(mem, hi_addr); let hi = mem.readb(hi_addr);
(((hi as Word) << 8) | lo as Word) (((hi as Word) << 8) | lo as Word)
} else { // normal behaviour } else { // normal behaviour
self.readw(mem, ind_addr) mem.readw(ind_addr)
}; };
(addr, false) (addr, false)
@@ -388,16 +385,16 @@ impl CPU {
let lo_addr = ind_addr.wrapping_add(self.regs.x); let lo_addr = ind_addr.wrapping_add(self.regs.x);
let hi_addr = ind_addr.wrapping_add(self.regs.x).wrapping_add(1); let hi_addr = ind_addr.wrapping_add(self.regs.x).wrapping_add(1);
let lo = self.readb(mem, lo_addr as Word); let lo = mem.readb(lo_addr as Word);
let hi = self.readb(mem, hi_addr as Word); let hi = mem.readb(hi_addr as Word);
((hi as Word) << 8 | lo as Word, false) ((hi as Word) << 8 | lo as Word, false)
} }
fn am_IZY<T: Memory>(&mut self, mem: &T) -> (Word, bool) { fn am_IZY<T: Memory>(&mut self, mem: &T) -> (Word, bool) {
let ind_addr = self.readb_pc(mem); let ind_addr = self.readb_pc(mem);
let lo = self.readb(mem, ind_addr as Word); let lo = mem.readb(ind_addr as Word);
let hi = self.readb(mem, ind_addr.wrapping_add(1) as Word); let hi = mem.readb(ind_addr.wrapping_add(1) as Word);
let addr = (hi as Word) << 8 | lo as Word; let addr = (hi as Word) << 8 | lo as Word;
let addr = addr.wrapping_add(self.regs.y as Word); let addr = addr.wrapping_add(self.regs.y as Word);
@@ -419,7 +416,7 @@ impl CPU {
// If the result is 0, Zero bit is set. If the result if negative, // If the result is 0, Zero bit is set. If the result if negative,
// Negative bit is set // Negative bit is set
fn op_ADC<T: Memory>(&mut self, mem: &T, addr: Word) -> bool { fn op_ADC<T: Memory>(&mut self, mem: &T, addr: Word) -> bool {
let val = self.readb(mem, addr) as Word; let val = mem.readb(addr) as Word;
let tmp = self.regs.a as Word + val + self.get_flag(Flags::CARRY) as Word; let tmp = self.regs.a as Word + val + self.get_flag(Flags::CARRY) as Word;
self.set_flag(Flags::CARRY, tmp > 255); self.set_flag(Flags::CARRY, tmp > 255);
@@ -443,7 +440,7 @@ impl CPU {
// If the result is 0, Zero bit is set. If the result if negative, // If the result is 0, Zero bit is set. If the result if negative,
// Negative bit is set // Negative bit is set
fn op_AND<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_AND<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.regs.a &= val; self.regs.a &= val;
self.set_flag_nz(self.regs.a); self.set_flag_nz(self.regs.a);
true true
@@ -464,7 +461,7 @@ impl CPU {
let val = if *addr_mode == AddrMode::IMP { let val = if *addr_mode == AddrMode::IMP {
self.regs.a self.regs.a
} else { } else {
self.readb(mem, addr) mem.readb(addr)
}; };
let shifted = (val << 1) as Byte; let shifted = (val << 1) as Byte;
self.set_flag(Flags::CARRY, (val & 0b10000000) > 0); self.set_flag(Flags::CARRY, (val & 0b10000000) > 0);
@@ -472,7 +469,7 @@ impl CPU {
if *addr_mode == AddrMode::IMP { if *addr_mode == AddrMode::IMP {
self.regs.a = shifted; self.regs.a = shifted;
} else { } else {
self.writeb(mem, addr, shifted); mem.writeb(addr, shifted);
} }
self.set_flag_nz(shifted); self.set_flag_nz(shifted);
@@ -521,7 +518,7 @@ impl CPU {
// bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V); // bits 7 and 6 of operand are transfered to bit 7 and 6 of SR (N,V);
// the zeroflag is set to the result of operand AND accumulator. // the zeroflag is set to the result of operand AND accumulator.
fn op_BIT<T: Memory>(&mut self, mem: &T, addr: Word) -> bool { fn op_BIT<T: Memory>(&mut self, mem: &T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.set_flag(Flags::OVERFLOW, (val & Flags::OVERFLOW.bits()) > 1); self.set_flag(Flags::OVERFLOW, (val & Flags::OVERFLOW.bits()) > 1);
self.set_flag(Flags::NEGATIVE, (val & Flags::NEGATIVE.bits()) > 1); self.set_flag(Flags::NEGATIVE, (val & Flags::NEGATIVE.bits()) > 1);
self.set_flag(Flags::ZERO, (val & self.regs.a) == 0); self.set_flag(Flags::ZERO, (val & self.regs.a) == 0);
@@ -583,7 +580,7 @@ impl CPU {
self.set_flag(Flags::BREAK, false); self.set_flag(Flags::BREAK, false);
// set PC to IRQ vector // set PC to IRQ vector
self.regs.pc = self.readw(mem, 0xFFFE); self.regs.pc = mem.readw(0xFFFE);
false false
} }
@@ -641,7 +638,7 @@ impl CPU {
// This instruction compares the contents of the accumulator with another // This instruction compares the contents of the accumulator with another
// memory held value and sets the zero and carry flags as appropriate. // memory held value and sets the zero and carry flags as appropriate.
fn op_CMP<T: Memory>(&mut self, mem: &mut T, addr: Addr) -> bool { fn op_CMP<T: Memory>(&mut self, mem: &mut T, addr: Addr) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
let tmp = (self.regs.a as Word).wrapping_sub(val as Word); let tmp = (self.regs.a as Word).wrapping_sub(val as Word);
self.set_flag(Flags::CARRY, self.regs.a >= val); self.set_flag(Flags::CARRY, self.regs.a >= val);
@@ -651,7 +648,7 @@ impl CPU {
// Compare X // Compare X
fn op_CPX<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_CPX<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
let tmp = (self.regs.x as Word).wrapping_sub(val as Word); let tmp = (self.regs.x as Word).wrapping_sub(val as Word);
self.set_flag(Flags::CARRY, self.regs.x >= val); self.set_flag(Flags::CARRY, self.regs.x >= val);
@@ -661,7 +658,7 @@ impl CPU {
// Compare Y // Compare Y
fn op_CPY<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_CPY<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
let tmp = (self.regs.y as Word).wrapping_sub(val as Word); let tmp = (self.regs.y as Word).wrapping_sub(val as Word);
self.set_flag(Flags::CARRY, self.regs.y >= val); self.set_flag(Flags::CARRY, self.regs.y >= val);
@@ -681,9 +678,9 @@ impl CPU {
// Subtracts one from the value held at a specified memory location // Subtracts one from the value held at a specified memory location
// setting the zero and negative flags as appropriate. // setting the zero and negative flags as appropriate.
fn op_DEC<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_DEC<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
let val = val.wrapping_sub(1); let val = val.wrapping_sub(1);
self.writeb(mem, addr, val); mem.writeb(addr, val);
self.set_flag_nz(val); self.set_flag_nz(val);
false false
@@ -716,7 +713,7 @@ impl CPU {
// An exclusive OR is performed, bit by bit, on the accumulator contents // An exclusive OR is performed, bit by bit, on the accumulator contents
// using the contents of a byte of memory. // using the contents of a byte of memory.
fn op_EOR<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_EOR<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.regs.a = self.regs.a ^ val; self.regs.a = self.regs.a ^ val;
self.set_flag_nz(self.regs.a); self.set_flag_nz(self.regs.a);
@@ -728,9 +725,9 @@ impl CPU {
// Adds one to the value held at a specified memory location setting the // Adds one to the value held at a specified memory location setting the
// zero and negative flags as appropriate. // zero and negative flags as appropriate.
fn op_INC<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_INC<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
let val = val.wrapping_add(1); let val = val.wrapping_add(1);
self.writeb(mem, addr, val); mem.writeb(addr, val);
self.set_flag_nz(val); self.set_flag_nz(val);
false false
} }
@@ -770,9 +767,9 @@ impl CPU {
// Jump to subroutine (leaves trace on the stack) // Jump to subroutine (leaves trace on the stack)
fn op_JSR<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_JSR<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
self.regs.pc -= 1; self.regs.pc -= 1;
self.writeb(mem, STACK_BASE_ADDR + self.regs.sp as Word, ((self.regs.pc >> 8) & 0x00ff) as Byte); mem.writeb(STACK_BASE_ADDR + self.regs.sp as Word, ((self.regs.pc >> 8) & 0x00ff) as Byte);
self.regs.sp -= 1; self.regs.sp -= 1;
self.writeb(mem, STACK_BASE_ADDR + self.regs.sp as Word, (self.regs.pc & 0x00ff) as Byte); mem.writeb(STACK_BASE_ADDR + self.regs.sp as Word, (self.regs.pc & 0x00ff) as Byte);
self.regs.sp -= 1; self.regs.sp -= 1;
self.jump(addr); self.jump(addr);
false false
@@ -799,7 +796,7 @@ impl CPU {
// Read value from addr into A // Read value from addr into A
fn op_LDA<T: Memory>(&mut self, mem: &T, addr: Word) -> bool { fn op_LDA<T: Memory>(&mut self, mem: &T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.regs.a = val; self.regs.a = val;
self.set_flag_nz(val); self.set_flag_nz(val);
true true
@@ -807,7 +804,7 @@ impl CPU {
// Read value from addr into X // Read value from addr into X
fn op_LDX<T: Memory>(&mut self, mem: &T, addr: Word) -> bool { fn op_LDX<T: Memory>(&mut self, mem: &T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.regs.x = val; self.regs.x = val;
self.set_flag_nz(val); self.set_flag_nz(val);
true true
@@ -815,7 +812,7 @@ impl CPU {
// Read value from addr into Y // Read value from addr into Y
fn op_LDY<T: Memory>(&mut self, mem: &T, addr: Word) -> bool { fn op_LDY<T: Memory>(&mut self, mem: &T, addr: Word) -> bool {
let val = self.readb(mem, addr); let val = mem.readb(addr);
self.regs.y = val; self.regs.y = val;
self.set_flag_nz(val); self.set_flag_nz(val);
true true
@@ -831,7 +828,7 @@ impl CPU {
let val = if *addr_mode == AddrMode::IMP { let val = if *addr_mode == AddrMode::IMP {
self.regs.a as Word self.regs.a as Word
} else { } else {
self.readb(mem, addr) as Word mem.readb(addr) as Word
}; };
self.set_flag(Flags::CARRY, (val & 0b00000001) != 0); self.set_flag(Flags::CARRY, (val & 0b00000001) != 0);
@@ -841,7 +838,7 @@ impl CPU {
if *addr_mode == AddrMode::IMP { if *addr_mode == AddrMode::IMP {
self.regs.a = shifted; self.regs.a = shifted;
} else { } else {
self.writeb(mem, addr, shifted); mem.writeb(addr, shifted);
} }
false false
} }
@@ -859,7 +856,7 @@ impl CPU {
// An inclusive OR is performed, bit by bit, on the accumulator contents // An inclusive OR is performed, bit by bit, on the accumulator contents
// using the contents of a byte of memory. // using the contents of a byte of memory.
fn op_ORA<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_ORA<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
self.regs.a = self.regs.a | self.readb(mem, addr); self.regs.a = self.regs.a | mem.readb(addr);
self.set_flag_nz(self.regs.a); self.set_flag_nz(self.regs.a);
true true
} }
@@ -908,7 +905,7 @@ impl CPU {
let val = if *addr_mode == AddrMode::IMP { let val = if *addr_mode == AddrMode::IMP {
self.regs.a as Word self.regs.a as Word
} else { } else {
self.readb(mem, addr) as Word mem.readb(addr) as Word
}; };
let shifted = (val << 1) as Byte | self.get_flag(Flags::CARRY); let shifted = (val << 1) as Byte | self.get_flag(Flags::CARRY);
@@ -918,7 +915,7 @@ impl CPU {
if *addr_mode == AddrMode::IMP { if *addr_mode == AddrMode::IMP {
self.regs.a = shifted as Byte; self.regs.a = shifted as Byte;
} else { } else {
self.writeb(mem, addr, shifted); mem.writeb(addr, shifted);
} }
false false
} }
@@ -947,7 +944,7 @@ impl CPU {
let val = if *addr_mode == AddrMode::IMP { let val = if *addr_mode == AddrMode::IMP {
self.regs.a as Word self.regs.a as Word
} else { } else {
self.readb(mem, addr) as Word mem.readb(addr) as Word
}; };
let shifted = (val >> 1) as Byte | (self.get_flag(Flags::CARRY) << 7); let shifted = (val >> 1) as Byte | (self.get_flag(Flags::CARRY) << 7);
@@ -958,7 +955,7 @@ impl CPU {
if *addr_mode == AddrMode::IMP { if *addr_mode == AddrMode::IMP {
self.regs.a = shifted; self.regs.a = shifted;
} else { } else {
self.writeb(mem, addr, shifted); mem.writeb(addr, shifted);
} }
false false
} }
@@ -982,9 +979,9 @@ impl CPU {
// calling routine. It pulls the program counter (minus one) from the stack. // calling routine. It pulls the program counter (minus one) from the stack.
fn op_RTS<T: Memory>(&mut self, mem: &T) -> bool { fn op_RTS<T: Memory>(&mut self, mem: &T) -> bool {
self.regs.sp += 1; self.regs.sp += 1;
let lo = self.readb(mem, 0x0100 + self.regs.sp as Addr); let lo = mem.readb(0x0100 + self.regs.sp as Addr);
self.regs.sp += 1; self.regs.sp += 1;
let hi = self.readb(mem, 0x0100 + self.regs.sp as Addr); let hi = mem.readb(0x0100 + self.regs.sp as Addr);
let addr = (hi as Addr) << 8 | lo as Addr; let addr = (hi as Addr) << 8 | lo as Addr;
self.regs.pc = addr + 1; self.regs.pc = addr + 1;
false false
@@ -993,7 +990,7 @@ impl CPU {
// Unofficial: Stores bitwise AND of A and X // Unofficial: Stores bitwise AND of A and X
fn op_SAX<T: Memory>(&mut self, mem: &mut T, addr: Addr) -> bool { fn op_SAX<T: Memory>(&mut self, mem: &mut T, addr: Addr) -> bool {
let val = self.regs.a & self.regs.x; let val = self.regs.a & self.regs.x;
self.writeb(mem, addr, val); mem.writeb(addr, val);
false false
} }
@@ -1005,7 +1002,7 @@ impl CPU {
// the carry bit is clear, this enables multiple byte subtraction to be // the carry bit is clear, this enables multiple byte subtraction to be
// performed. // performed.
fn op_SBC<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool { fn op_SBC<T: Memory>(&mut self, mem: &T, addr: Addr) -> bool {
let val = self.readb(mem, addr) as Word; let val = mem.readb(addr) as Word;
// invert buttom 8 bits // invert buttom 8 bits
let val = val ^ LO; let val = val ^ LO;
@@ -1063,19 +1060,19 @@ impl CPU {
// Push A reg to memory // Push A reg to memory
fn op_STA<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_STA<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
self.writeb(mem, addr, self.regs.a); mem.writeb(addr, self.regs.a);
false false
} }
// Push X reg to memory // Push X reg to memory
fn op_STX<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_STX<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
self.writeb(mem, addr, self.regs.x); mem.writeb(addr, self.regs.x);
false false
} }
// Push Y reg to memory // Push Y reg to memory
fn op_STY<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool { fn op_STY<T: Memory>(&mut self, mem: &mut T, addr: Word) -> bool {
self.writeb(mem, addr, self.regs.y); mem.writeb(addr, self.regs.y);
false false
} }

View File

@@ -13,8 +13,6 @@ pub struct Disasm {
pub addresses: Vec<Addr> pub addresses: Vec<Addr>
} }
impl MemoryReader for Disasm {}
impl Disasm { impl Disasm {
// Disassemble given code region // Disassemble given code region
pub fn disassemble<T: Memory>(mem: &T, start: Addr, stop: Addr) -> Result<Self, Error> { pub fn disassemble<T: Memory>(mem: &T, start: Addr, stop: Addr) -> Result<Self, Error> {

View File

@@ -90,16 +90,6 @@ pub trait PPUMemory {
fn writeb_ppu(&mut self, addr: Addr, data: Byte); fn writeb_ppu(&mut self, addr: Addr, data: Byte);
} }
pub trait PPUMemoryReader {
fn readb_ppu<T: PPUMemory>(&self, mem: &T, addr: Addr) -> Byte {
mem.readb_ppu(addr)
}
fn writeb_ppu<T: PPUMemory>(&mut self, mem: &mut T, addr: Addr, data: Byte) {
mem.writeb_ppu(addr, data)
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;