Trevor Merritt b4383436aa emmagui isnt rendering correctly.
backend isnt writing a sprite correctly and attempting to poke outside memory
2024-10-07 13:33:35 -04:00

109 lines
3.3 KiB
Rust

use log::{debug, error};
use crate::chip8::delay_timer::DelayTimer;
use crate::chip8::instructions::Chip8CpuInstructions::XXXXERRORINSTRUCTION;
use crate::chip8::keypad::Keypad;
use crate::chip8::registers::Chip8Registers;
use crate::chip8::sound_timer::SoundTimer;
use crate::chip8::stack::Chip8Stack;
use crate::chip8::util::InstructionUtil;
use crate::constants::{CHIP8_MEMORY_SIZE, CHIP8_REGISTER_COUNT};
use super::{
cpu_states::Chip8CpuStates, instructions::Chip8CpuInstructions, system_memory::Chip8SystemMemory, video::Chip8Video,
};
const STACK_POINTER_DEFAULT: i16 = 0x100;
#[derive(Clone)]
pub struct Chip8Computer {
pub memory: Chip8SystemMemory,
pub registers: Chip8Registers,
pub sound_timer: SoundTimer,
pub delay_timer: DelayTimer,
pub video_memory: Chip8Video,
pub state: Chip8CpuStates,
pub keypad: Keypad,
pub stack: Chip8Stack
}
impl Default for Chip8Computer {
fn default() -> Self {
Self {
memory: Chip8SystemMemory::default(),
video_memory: Chip8Video::default(),
registers: Chip8Registers::default(),
sound_timer: SoundTimer::new(),
delay_timer: DelayTimer::new(),
state: Chip8CpuStates::default(),
keypad: Keypad::default(),
stack: Chip8Stack::default()
}
}
}
impl Chip8Computer {
pub fn new_with_program(new_program: Box<Vec<u16>>) -> Self {
let mut working = Chip8Computer::new();
for i in 0..new_program.len() {
let high_byte = (new_program[i as usize] >> 8) as u8;
let low_byte = (new_program[i] & 0xff) as u8;
let base_offset = i * 2;
working.memory.poke(base_offset as u16, high_byte);
working.memory.poke((base_offset + 1) as u16, low_byte);
}
working
}
pub fn new() -> Self {
Chip8Computer::default()
}
pub fn load_bytes_to_memory(&mut self, offset: u16, to_load: Box<Vec<u8>>) {
let total_len = to_load.len() as u16;
for current_index in 0..total_len {
let new_value = to_load[current_index as usize];
let new_location = current_index + offset;
self.memory.poke(new_location, new_value);
}
}
pub fn step_system(&mut self) -> &mut Chip8Computer {
debug!("Stepping System 1 Step");
// read the next instruction
let mut working_instruction: u16 = 0b0000000000000000;
let start_pc = self.registers.peek_pc();
let high_byte = (self.memory.clone().peek(start_pc) as u16).rotate_left(8);
let low_byte = self.memory.clone().peek(start_pc + 1) as u16;
let result = high_byte | low_byte;
let decoded_instruction =
Chip8CpuInstructions::decode(result);
// todo: THIS IS BAD AND IS A SIDE EFFECT
decoded_instruction.execute(self);
match self.state {
Chip8CpuStates::WaitingForInstruction => {
self.sound_timer.tick();
self.delay_timer.tick();
}
Chip8CpuStates::WaitingForKey => {
println!("waiting for a key press...");
}
_ => {}
}
self
}
}
#[cfg(test)]
mod test {
use rand::random;
use crate::constants::CHIP8_VIDEO_MEMORY;
use super::*;
#[test]
fn smoke() {
assert!(true)
}
}