sim86 0.1.0

An 8086/8088 emulator with full support for 16-bit x86.
Documentation
use std::io::{Read, Write};

pub mod execute;
pub mod model;
pub mod parse;

pub fn disassemble<R: Read, W: Write>(input: R, output: &mut W) {
    let mut input = input.bytes();

    loop {
        let b1: u8 = match input.next() {
            Some(Ok(b)) => b,
            Some(Err(e)) => panic!("Failed to get next byte due to IO error - {}", e),
            None => return,
        };
        let instruction =
            parse::parse_complete_instruction(b1, &mut input, parse::parse_instruction);
        writeln!(output, "{}", instruction).unwrap();
    }
}

pub fn disassemble_via_jump_table<R: Read, W: Write>(input: R, output: &mut W) {
    let jump_table: [parse::ParseFunc<R>; 256] = parse::construct_jump_table::<R>();

    let mut input = input.bytes();

    loop {
        let b1: u8 = match input.next() {
            Some(Ok(b)) => b,
            Some(Err(e)) => panic!("Failed to get next byte due to IO error - {}", e),
            None => return,
        };
        let instruction = parse::parse_complete_instruction(b1, &mut input, |b1, input| {
            let parse_function: parse::ParseFunc<R> = jump_table[b1 as usize];
            parse_function(b1, input)
        });
        writeln!(output, "{}", instruction).unwrap();
    }
}

pub fn execute_with_trace<R: Read, W: Write>(input: R, output: &mut W) -> execute::MachineState {
    let mut machine_state = execute::MachineState::default();
    let mut input = input.bytes();
    loop {
        let b1: u8 = match input.next() {
            Some(Ok(b)) => b,
            Some(Err(e)) => panic!("Failed to get next byte due to IO error - {}", e),
            None => break,
        };
        let instruction =
            parse::parse_complete_instruction(b1, &mut input, parse::parse_instruction);

        write!(output, "{}", instruction).unwrap();

        let prev_machine_state = machine_state.clone();
        machine_state.execute_instruction(instruction);

        execute::MachineStateDiff::diff(&prev_machine_state, &machine_state, |diff| {
            write!(output, " ; {}", diff).unwrap();
        });

        writeln!(output).unwrap();
    }

    machine_state
}