lc3_zkvm/
utils.rs

1use crate::instruction::execute;
2use crate::memory::Memory;
3use crate::opcode::extract_opcode;
4use crate::register::{Register, RegisterFile};
5use std::fs::File;
6use std::io::{self, Read};
7
8/// Load an LC3 object file into memory
9pub fn load_obj_file(filename: &str, memory: &mut Memory) -> io::Result<u16> {
10    let mut file = File::open(filename)?;
11    let mut buffer = Vec::new();
12    file.read_to_end(&mut buffer)?;
13
14    let mut origin: u16 = 0x3000;
15    let mut i = 0;
16
17    // Read the origin
18    if buffer.len() >= 2 {
19        origin = u16::from_be_bytes([buffer[0], buffer[1]]);
20        // origin = origin.swap_bytes();
21        i = 2;
22    }
23
24    // Load program into memory
25    let mut address = origin;
26    while i < buffer.len() {
27        if i + 1 < buffer.len() {
28            let instruction = u16::from_be_bytes([buffer[i], buffer[i + 1]]);
29
30            memory.write(address, instruction);
31
32            // let opcode = extract_opcode(instruction);
33            // println!("loading image, address: 0x{:04X}, opcode: {:?}, instruction: {:04X}", address, opcode.unwrap(), instruction   );
34
35            address += 1;
36            i += 2;
37        } else {
38            break;
39        }
40    }
41
42    Ok(origin)
43}
44
45/// Execute the loaded program
46pub fn execute_program(
47    memory: &mut Memory,
48    registers: &mut RegisterFile,
49) -> Result<(), &'static str> {
50    // println!("execute_program, PC: 0x{:04X}", registers.read(Register::PC));
51    loop {
52        let pc = registers.read(Register::PC);
53        let raw_instruction = memory.read(pc);
54
55        // Increment PC
56        registers.write(Register::PC, pc.wrapping_add(1));
57
58        if let Some(_opcode) = extract_opcode(raw_instruction) {
59            // println!("execute_program, address: 0x{:04X}, opcode: {:?}", pc, opcode);
60
61            match execute(raw_instruction, registers, memory) {
62                Ok(_) => {}
63                Err("HALT") => return Ok(()),
64                Err(e) => return Err(e),
65            }
66        } else {
67            return Err("Invalid instruction");
68        }
69    }
70}