fn fetch_and_decode(&mut self) -> Result<usize, io::Error> {
        let inst = self.memory.get_word(self.program_counter);

        // first byte, second nybble
        self.vx = (inst & 0x0f00) >> 8;
        // second byte, first nybble
        self.vy = (inst & 0x00f0) >> 4;

        self.instruction = Some(match inst {
            0x00e0 => Chip8Interpreter::inst_clear_screen,
            0x00ee => Chip8Interpreter::inst_ret,
            0x1000..=0x1fff => Chip8Interpreter::inst_branch,
            0x2000..=0x2fff => Chip8Interpreter::inst_subroutine,
            0x3000..=0x3fff => Chip8Interpreter::inst_skip_vx_eq,
            0x4000..=0x4fff => Chip8Interpreter::inst_skip_vx_ne,
            0x5000..=0x5fff => Chip8Interpreter::inst_x_eq_y,
            0x6000..=0x6fff => Chip8Interpreter::inst_load_vx,
            0x7000..=0x7fff => Chip8Interpreter::inst_add_to_vx,
            0x8000..=0x8fff => match inst & 0xf {
                0x0 => Chip8Interpreter::inst_load_x_with_y,
                0x1 => Chip8Interpreter::inst_x_or_with_y,
                0x2 => Chip8Interpreter::inst_x_and_with_y,
                0x3 => Chip8Interpreter::inst_x_xor_with_y,
                0x4 => Chip8Interpreter::inst_x_add_y,
                0x5 => Chip8Interpreter::inst_x_minus_y,
                0x6 => Chip8Interpreter::inst_rshift_y_load_x,
                0x7 => Chip8Interpreter::inst_y_minus_x,
                0xe => Chip8Interpreter::inst_lshift_y_load_x,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            0x9000..=0x9fff => Chip8Interpreter::inst_x_ne_y,
            0xa000..=0xafff => Chip8Interpreter::inst_set_i,
            0xb000..=0xbfff => Chip8Interpreter::inst_jump_with_offset,
            0xc000..=0xcfff => Chip8Interpreter::inst_random,
            0xd000..=0xdfff => Chip8Interpreter::inst_draw_sprite,
            0xe000..=0xefff => match inst & 0xff {
                0x9e => Chip8Interpreter::inst_skip_key_eq,
                0xa1 => Chip8Interpreter::inst_skip_key_ne,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            0xf000..=0xffff => match inst & 0xff {
                0x07 => Chip8Interpreter::inst_get_timer,
                0x0a => Chip8Interpreter::inst_wait_key,
                0x15 => Chip8Interpreter::inst_set_timer,
                0x18 => Chip8Interpreter::inst_set_sound,
                0x1e => Chip8Interpreter::inst_add_x_to_i,
                0x29 => Chip8Interpreter::inst_load_char,
                0x33 => Chip8Interpreter::inst_x_to_bcd,
                0x55 => Chip8Interpreter::inst_save_v_at_i,
                0x65 => Chip8Interpreter::inst_load_v_at_i,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            _ => panic!("Failed to decode instruction {:04x?}", inst),
        });

        self.instruction_data = inst;

        self.program_counter += 2;
        self.state = InterpreterState::Execute;

        // execution time is 40 cycles for 0xxx and 68 cycles otherwise
        if inst > 0x0fff {
            Ok(68)
        } else {
            Ok(40)
        }
    }
/// fetch the instruction at the program counter, figure out what it is,
/// set vx/vy, update the program counter, update the interpreter state
fetch the instruction at the program counter, figure out what it is,
set vx/vy, update the program counter, update the interpreter state
fetch the instruction at the program counter figure out what it is set vx / vy update the program counter update the interpreter state
fn fetch_and_decode(&mut self) -> Result<usize, io::Error> {
        let inst = self.memory.get_word(self.program_counter);
        // first byte, second nybble
        self.vx = (inst & 0x0f00) >> 8;
        // second byte, first nybble
        self.vy = (inst & 0x00f0) >> 4;
        self.instruction = Some(match inst {
            0x00e0 => Chip8Interpreter::inst_clear_screen,
            0x00ee => Chip8Interpreter::inst_ret,
            0x1000..=0x1fff => Chip8Interpreter::inst_branch,
            0x2000..=0x2fff => Chip8Interpreter::inst_subroutine,
            0x3000..=0x3fff => Chip8Interpreter::inst_skip_vx_eq,
            0x4000..=0x4fff => Chip8Interpreter::inst_skip_vx_ne,
            0x5000..=0x5fff => Chip8Interpreter::inst_x_eq_y,
            0x6000..=0x6fff => Chip8Interpreter::inst_load_vx,
            0x7000..=0x7fff => Chip8Interpreter::inst_add_to_vx,
            0x8000..=0x8fff => match inst & 0xf {
                0x0 => Chip8Interpreter::inst_load_x_with_y,
                0x1 => Chip8Interpreter::inst_x_or_with_y,
                0x2 => Chip8Interpreter::inst_x_and_with_y,
                0x3 => Chip8Interpreter::inst_x_xor_with_y,
                0x4 => Chip8Interpreter::inst_x_add_y,
                0x5 => Chip8Interpreter::inst_x_minus_y,
                0x6 => Chip8Interpreter::inst_rshift_y_load_x,
                0x7 => Chip8Interpreter::inst_y_minus_x,
                0xe => Chip8Interpreter::inst_lshift_y_load_x,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            0x9000..=0x9fff => Chip8Interpreter::inst_x_ne_y,
            0xa000..=0xafff => Chip8Interpreter::inst_set_i,
            0xb000..=0xbfff => Chip8Interpreter::inst_jump_with_offset,
            0xc000..=0xcfff => Chip8Interpreter::inst_random,
            0xd000..=0xdfff => Chip8Interpreter::inst_draw_sprite,
            0xe000..=0xefff => match inst & 0xff {
                0x9e => Chip8Interpreter::inst_skip_key_eq,
                0xa1 => Chip8Interpreter::inst_skip_key_ne,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            0xf000..=0xffff => match inst & 0xff {
                0x07 => Chip8Interpreter::inst_get_timer,
                0x0a => Chip8Interpreter::inst_wait_key,
                0x15 => Chip8Interpreter::inst_set_timer,
                0x18 => Chip8Interpreter::inst_set_sound,
                0x1e => Chip8Interpreter::inst_add_x_to_i,
                0x29 => Chip8Interpreter::inst_load_char,
                0x33 => Chip8Interpreter::inst_x_to_bcd,
                0x55 => Chip8Interpreter::inst_save_v_at_i,
                0x65 => Chip8Interpreter::inst_load_v_at_i,
                _ => panic!("Failed to decode instruction {:04x?}", inst),
            },
            _ => panic!("Failed to decode instruction {:04x?}", inst),
        });
        self.instruction_data = inst;
        self.program_counter += 2;
        self.state = InterpreterState::Execute;
        // execution time is 40 cycles for 0xxx and 68 cycles otherwise
        if inst > 0x0fff {
            Ok(68)
        } else {
            Ok(40)
        }
    }
fn fetch_and_decode ( & mut self ) -> Result < usize , io :: Error > { let inst = self . memory . get_word ( self . program_counter ) ; // first byte, second nybble self . vx = ( inst & 0x0f00 ) >> 8 ; // second byte, first nybble self . vy = ( inst & 0x00f0 ) >> 4 ; self . instruction = Some ( match inst { 0x00e0 => Chip8Interpreter :: inst_clear_screen , 0x00ee => Chip8Interpreter :: inst_ret , 0x1000 ..= 0x1fff => Chip8Interpreter :: inst_branch , 0x2000 ..= 0x2fff => Chip8Interpreter :: inst_subroutine , 0x3000 ..= 0x3fff => Chip8Interpreter :: inst_skip_vx_eq , 0x4000 ..= 0x4fff => Chip8Interpreter :: inst_skip_vx_ne , 0x5000 ..= 0x5fff => Chip8Interpreter :: inst_x_eq_y , 0x6000 ..= 0x6fff => Chip8Interpreter :: inst_load_vx , 0x7000 ..= 0x7fff => Chip8Interpreter :: inst_add_to_vx , 0x8000 ..= 0x8fff => match inst & 0xf { 0x0 => Chip8Interpreter :: inst_load_x_with_y , 0x1 => Chip8Interpreter :: inst_x_or_with_y , 0x2 => Chip8Interpreter :: inst_x_and_with_y , 0x3 => Chip8Interpreter :: inst_x_xor_with_y , 0x4 => Chip8Interpreter :: inst_x_add_y , 0x5 => Chip8Interpreter :: inst_x_minus_y , 0x6 => Chip8Interpreter :: inst_rshift_y_load_x , 0x7 => Chip8Interpreter :: inst_y_minus_x , 0xe => Chip8Interpreter :: inst_lshift_y_load_x , _ => panic ! ( " " inst ) , } , 0x9000 ..= 0x9fff => Chip8Interpreter :: inst_x_ne_y , 0xa000 ..= 0xafff => Chip8Interpreter :: inst_set_i , 0xb000 ..= 0xbfff => Chip8Interpreter :: inst_jump_with_offset , 0xc000 ..= 0xcfff => Chip8Interpreter :: inst_random , 0xd000 ..= 0xdfff => Chip8Interpreter :: inst_draw_sprite , 0xe000 ..= 0xefff => match inst & 0xff { 0x9e => Chip8Interpreter :: inst_skip_key_eq , 0xa1 => Chip8Interpreter :: inst_skip_key_ne , _ => panic ! ( " " inst ) , } , 0xf000 ..= 0xffff => match inst & 0xff { 0x07 => Chip8Interpreter :: inst_get_timer , 0x0a => Chip8Interpreter :: inst_wait_key , 0x15 => Chip8Interpreter :: inst_set_timer , 0x18 => Chip8Interpreter :: inst_set_sound , 0x1e => Chip8Interpreter :: inst_add_x_to_i , 0x29 => Chip8Interpreter :: inst_load_char , 0x33 => Chip8Interpreter :: inst_x_to_bcd , 0x55 => Chip8Interpreter :: inst_save_v_at_i , 0x65 => Chip8Interpreter :: inst_load_v_at_i , _ => panic ! ( " " inst ) , } , _ => panic ! ( " " inst ) , } ) ; self . instruction_data = inst ; self . program_counter += 2 ; self . state = InterpreterState :: Execute ; // execution time is 40 cycles for 0xxx and 68 cycles otherwise if inst > 0x0fff { Ok ( 68 ) } else { Ok ( 40 ) } }
fetch the instruction at the program counter, figure out what it is,
set vx/vy, update the program counter, update the interpreter state
fetch the instruction at the program counter figure out what it is set vx / vy update the program counter update the interpreter state
&mut self