Add cowgod docs, small changes to main, add experimental opcode parsing

This commit is contained in:
Garrett Dickinson 2024-08-05 15:55:23 -05:00
parent 0b0353c923
commit e12bbe91a0
4 changed files with 1249 additions and 13 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -9,8 +9,18 @@ pub const MAX_MEM_SIZE: usize = 4096;
pub const MAX_PRG_SIZE: usize = 3584;
// Instruction constants
const INSTR_NOOP: u16 = 0x0000;
const INSTR_EXIT: u16 = 0x00FD;
const INSTR_NOOP: u16 = 0x0000;
const INSTR_EXIT: u16 = 0x00FD;
const INSTR_CLS: u16 = 0x00E0;
const INSTR_RET: u16 = 0x00EE;
// Commonn Instruction Masks
const INSTR_MASK_SYS: u16 = 0x0000;
const INSTR_MASK_JP: u16 = 0x1000;
const INSTR_MASK_CALL: u16 = 0x2000;
const ADDR_MASK: u16 = 0x0FFF;
#[derive(Debug)]
struct EmulationState {
@ -73,7 +83,7 @@ fn exec_program(state: &mut EmulationState) {
let mut head_byte: u8;
let mut tail_byte: u8;
let mut instruction_tuple: (u8, u8);
let mut instruction: u16;
for _i in PRGRM_START+usize::from(state.program_counter)..MAX_MEM_SIZE {
// Grab the first byte of instruction
@ -84,20 +94,47 @@ fn exec_program(state: &mut EmulationState) {
tail_byte = state.memory[PRGRM_START + usize::from(state.program_counter)];
state.program_counter += 1;
instruction_tuple = (head_byte, tail_byte);
instruction = util::u8_tuple_to_u16((head_byte, tail_byte));
println!("0x{:02X?}{:02X?}", head_byte, tail_byte);
if util::u8_tuple_to_u16(instruction_tuple) == INSTR_EXIT {
if instruction == INSTR_EXIT {
println!("Read exit instruction, stopping emulation");
return;
}
if util::u8_tuple_to_u16(instruction_tuple) == INSTR_NOOP {
if instruction == INSTR_NOOP {
println!("Read no-op instruction, stopping emulation");
return;
}
parse_instruction(state, instruction);
}
}
fn parse_instruction(state: &mut EmulationState, instr: u16) {
if (instr == INSTR_CLS) {
println!("Clear screen");
}
if (instr == INSTR_RET) {
println!("Return");
}
if ((instr & INSTR_MASK_SYS) > 0) {
let addr: u16 = (instr & ADDR_MASK);
println!("Got SYS instruction {:04X?} with address {:04X?}", instr, addr);
}
if ((instr & INSTR_MASK_JP) > 0) {
let addr: u16 = (instr & ADDR_MASK);
println!("Got JP instruction {:04X?} with address {:04X?}", instr, addr);
}
if ((instr & INSTR_MASK_CALL) > 0) {
let addr: u16 = (instr & ADDR_MASK);
println!("Got CALL instruction {:04X?} with address {:04X?}", instr, addr);
}
}

View File

@ -11,8 +11,6 @@ fn main()
{
// Collect our execution args
let args: Vec<String> = env::args().collect();
// let mut inject_mode: bool = false;
// let mut patch_file_path: &String = &"".to_string();
// Grab our filepath from our options
if &args.len() < &2
@ -22,11 +20,12 @@ fn main()
exit(0);
}
let file_path: &String = &args[1];
// Read last argument as path of chip8 executable
let file_path: &String = &args[args.len()-1];
if path::Path::new(file_path).exists()
{
println!("File exists, reading '{}'...", file_path);
println!("'{}' exists, reading...", file_path);
let contents: Result<Vec<u8>, std::io::Error> = fs::read(file_path);
@ -49,9 +48,9 @@ fn main()
println!("Read {} bytes of program data", file_data.len());
chip8::start_emulation(program);
}
} else
}
else
{
println!("[Error] File '{}' does not exist", file_path);
exit(-1);