Compare commits

..

No commits in common. "6d26e7de54aac46e9f173d01efd0c0439aa906b2" and "eb993eb1b4c2b04cc81a211770d5971c50d074fd" have entirely different histories.

2 changed files with 27 additions and 76 deletions

View file

@ -9,7 +9,25 @@ mod structs;
pub const MEMORY_SIZE: usize = 8192; pub const MEMORY_SIZE: usize = 8192;
fn main() { fn main() {
let mut state = EmulatorState::default(); let mut state = EmulatorState {
a: 0,
b: 0,
c: 0,
d: 0,
e: 0,
h: 0,
l: 0,
sp: 0,
cc: ConditionCodes {
z: true,
s: true,
p: true,
c: true,
},
pc: 0,
ei: true,
memory: [0; MEMORY_SIZE],
};
// Load the ROM into memory // Load the ROM into memory
let mut args = env::args(); let mut args = env::args();
@ -30,7 +48,7 @@ fn main() {
} }
fn tick(state: &mut EmulatorState) { fn tick(state: &mut EmulatorState) {
let instruction = state.next_byte(); let instruction = state.memory[state.pc as usize];
match instruction { match instruction {
0x00 => {} // NOP 0x00 => {} // NOP

View file

@ -23,58 +23,20 @@ pub struct EmulatorState {
} }
impl EmulatorState { impl EmulatorState {
// Read the next byte from memory pointed at by PC // Get the next byte from memory
pub fn next_byte(&mut self) -> u8 { pub fn next_byte(&mut self) -> u8 {
let value = self.memory[self.pc as usize]; self.pc += 1;
(self.pc, ..) = self.pc.overflowing_add(1); self.memory[self.pc as usize]
value
} }
// Read the next 16-bit word from memory pointed at by PC, in little endian order // Get the next 16-bit word from memory, in little endian order
pub fn next_word(&mut self) -> u16 { pub fn next_word(&mut self) -> u16 {
let value = self.read_word(self.pc); self.pc += 2;
(self.pc, ..) = self.pc.overflowing_add(2);
value
}
// Read a 16-bit word at a specific address
pub fn read_word(&mut self, address: u16) -> u16 {
u16::from_le_bytes([ u16::from_le_bytes([
self.memory[address as usize], self.memory[self.pc as usize - 1],
self.memory[address.overflowing_add(1).0 as usize], self.memory[self.pc as usize],
]) ])
} }
// Write a 16-bit word at a specific address
pub fn write_word(&mut self, address: u16, value: u16) {
let [low, high] = u16::to_le_bytes(value);
self.memory[address as usize] = low;
self.memory[address.overflowing_add(1).0 as usize] = high;
}
}
impl Default for EmulatorState {
fn default() -> Self {
Self {
a: 0,
b: 0,
c: 0,
d: 0,
e: 0,
h: 0,
l: 0,
sp: 0,
cc: ConditionCodes {
z: true,
s: true,
p: true,
c: true,
},
pc: 0,
ei: false,
memory: [0; MEMORY_SIZE],
}
}
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug)]
@ -224,32 +186,3 @@ pub fn print_state(state: &EmulatorState) {
state.cc.z, state.cc.s, state.cc.p, state.cc.c state.cc.z, state.cc.s, state.cc.p, state.cc.c
); );
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_word() {
let mut state = EmulatorState::default();
state.memory[0x10] = 0x34;
state.memory[0x11] = 0x12;
assert_eq!(state.read_word(0x10), 0x1234);
}
#[test]
fn write_word() {
let mut state = EmulatorState::default();
state.write_word(0x10, 0x1234);
assert_eq!([0x34, 0x12], state.memory[0x10..0x12]);
}
#[test]
fn next_word_at_pc() {
let mut state = EmulatorState::default();
state.memory[0x10] = 0x34;
state.memory[0x11] = 0x12;
state.pc = 0x10;
assert_eq!(state.next_word(), 0x1234);
}
}