forked from Lea/invadeez
fix memory related bugs
god fucking damnit that's not how the program counter works lea
This commit is contained in:
parent
8a1c99ee39
commit
6d26e7de54
|
@ -9,25 +9,7 @@ mod structs;
|
||||||
pub const MEMORY_SIZE: usize = 8192;
|
pub const MEMORY_SIZE: usize = 8192;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut state = EmulatorState {
|
let mut state = EmulatorState::default();
|
||||||
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();
|
||||||
|
@ -48,7 +30,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(state: &mut EmulatorState) {
|
fn tick(state: &mut EmulatorState) {
|
||||||
let instruction = state.memory[state.pc as usize];
|
let instruction = state.next_byte();
|
||||||
|
|
||||||
match instruction {
|
match instruction {
|
||||||
0x00 => {} // NOP
|
0x00 => {} // NOP
|
||||||
|
|
|
@ -25,21 +25,23 @@ pub struct EmulatorState {
|
||||||
impl EmulatorState {
|
impl EmulatorState {
|
||||||
// Read the next byte from memory pointed at by PC
|
// Read the next byte from memory pointed at by PC
|
||||||
pub fn next_byte(&mut self) -> u8 {
|
pub fn next_byte(&mut self) -> u8 {
|
||||||
self.pc += 1;
|
let value = self.memory[self.pc as usize];
|
||||||
self.memory[self.pc as usize]
|
(self.pc, ..) = self.pc.overflowing_add(1);
|
||||||
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the next 16-bit word from memory pointed at by PC, in little endian order
|
// Read the next 16-bit word from memory pointed at by PC, in little endian order
|
||||||
pub fn next_word(&mut self) -> u16 {
|
pub fn next_word(&mut self) -> u16 {
|
||||||
self.pc += 2;
|
let value = self.read_word(self.pc);
|
||||||
self.read_word(self.pc - 1)
|
(self.pc, ..) = self.pc.overflowing_add(2);
|
||||||
|
value
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read a 16-bit word at a specific address
|
// Read a 16-bit word at a specific address
|
||||||
pub fn read_word(&mut self, address: u16) -> u16 {
|
pub fn read_word(&mut self, address: u16) -> u16 {
|
||||||
u16::from_le_bytes([
|
u16::from_le_bytes([
|
||||||
self.memory[address as usize],
|
self.memory[address as usize],
|
||||||
self.memory[address as usize + 1],
|
self.memory[address.overflowing_add(1).0 as usize],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +49,31 @@ impl EmulatorState {
|
||||||
pub fn write_word(&mut self, address: u16, value: u16) {
|
pub fn write_word(&mut self, address: u16, value: u16) {
|
||||||
let [low, high] = u16::to_le_bytes(value);
|
let [low, high] = u16::to_le_bytes(value);
|
||||||
self.memory[address as usize] = low;
|
self.memory[address as usize] = low;
|
||||||
self.memory[address as usize + 1] = high;
|
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],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,3 +224,32 @@ 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue