gb-emu/src/processor/mod.rs

1511 lines
70 KiB
Rust
Raw Normal View History

2023-01-17 09:09:53 +11:00
use std::{
mem::transmute,
ops::{BitAnd, BitOr, BitXor},
};
2023-01-16 19:28:03 +11:00
2023-01-16 12:13:53 +11:00
use crate::{Inner, Memory, Register, State};
2023-01-16 14:23:43 +11:00
#[allow(dead_code)]
2023-01-22 09:18:07 +11:00
#[derive(PartialEq)]
2023-01-16 14:23:06 +11:00
enum FLAGS {
Z = 7,
N = 6,
H = 5,
C = 4,
}
2023-01-18 13:14:22 +11:00
enum Direction {
Left,
Right,
}
2023-01-16 12:13:53 +11:00
pub struct CPU {
pub memory: Memory,
pub state: State,
2023-01-18 12:45:56 +11:00
pub last_instruction: u8,
pub last_instruction_addr: u16,
2023-01-16 12:13:53 +11:00
}
impl CPU {
2023-01-17 09:09:53 +11:00
pub fn exec_next(&mut self) {
2023-01-18 12:45:56 +11:00
unsafe { self.last_instruction_addr = self.state.pc.as_u16 };
2023-01-16 12:13:53 +11:00
let opcode = self.next_opcode();
2023-01-18 12:45:56 +11:00
self.last_instruction = opcode;
2023-01-22 09:32:19 +11:00
println!(
"exec {:#4X} from pc: {:#X}",
opcode, self.last_instruction_addr
);
2023-01-18 12:45:56 +11:00
2023-01-16 12:13:53 +11:00
match opcode {
0x0 => {
// noop
}
2023-01-16 14:23:06 +11:00
0x01 => self.state.bc = self.ld_immediate_word(),
0x02 => unsafe {
let address = self.state.bc.as_u16;
self.memory.set(address, self.state.af.as_u8s.left);
},
2023-01-18 12:45:56 +11:00
0x03 => unsafe { self.state.bc.as_u16 = self.add_u16s(self.state.bc.as_u16, 1) },
2023-01-16 19:28:03 +11:00
0x04 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.bc.as_u8s.left = self.add_u8s(self.state.bc.as_u8s.left, 1)
2023-01-16 19:28:03 +11:00
},
0x05 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.bc.as_u8s.left = self.sub_u8s(self.state.bc.as_u8s.left, 1)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:23:06 +11:00
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
2023-01-18 14:43:24 +11:00
0x07 => unsafe { self.state.af.as_u8s.left = self.rlc(self.state.af.as_u8s.left) },
2023-01-16 14:23:06 +11:00
0x08 => unsafe {
let address = self.ld_immediate_word().as_u16;
let word = self.state.sp;
self.store_word(address, word);
},
2023-01-16 19:28:03 +11:00
0x09 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.bc.as_u16)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:23:06 +11:00
0x0A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.bc.as_u16) },
2023-01-18 12:45:56 +11:00
0x0B => unsafe { self.state.bc.as_u16 = self.sub_u16s(self.state.bc.as_u16, 0x1) },
2023-01-16 19:28:03 +11:00
0x0C => unsafe {
2023-01-18 12:45:56 +11:00
self.state.bc.as_u8s.right = self.add_u8s(self.state.bc.as_u8s.right, 0x1)
2023-01-16 19:28:03 +11:00
},
0x0D => unsafe {
2023-01-18 12:45:56 +11:00
self.state.bc.as_u8s.right = self.sub_u8s(self.state.bc.as_u8s.right, 0x1)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:23:06 +11:00
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
2023-01-18 14:43:24 +11:00
0x0F => unsafe { self.state.af.as_u8s.left = self.rrc(self.state.af.as_u8s.left) },
2023-01-16 14:23:06 +11:00
0x10 => panic!("STOP instruction"),
0x11 => self.state.de = self.ld_immediate_word(),
0x12 => unsafe {
let address = self.state.de.as_u16;
let data = self.state.af.as_u8s.left;
self.memory.set(address, data);
},
2023-01-18 12:45:56 +11:00
0x13 => unsafe { self.state.de.as_u16 = self.sub_u16s(self.state.de.as_u16, 0x1) },
2023-01-16 19:28:03 +11:00
0x14 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.de.as_u8s.left = self.add_u8s(self.state.de.as_u8s.left, 0x1)
2023-01-16 19:28:03 +11:00
},
0x15 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.de.as_u8s.left = self.sub_u8s(self.state.de.as_u8s.left, 0x1)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:23:06 +11:00
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
2023-01-18 13:14:22 +11:00
0x17 => unsafe {
2023-01-18 14:43:24 +11:00
self.state.af.as_u8s.left = self.rl(self.state.af.as_u8s.left);
2023-01-18 13:14:22 +11:00
},
2023-01-16 19:28:03 +11:00
0x18 => unsafe {
2023-01-18 12:45:56 +11:00
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
2023-01-22 09:18:07 +11:00
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(t)
2023-01-16 19:28:03 +11:00
},
0x19 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.de.as_u16)
2023-01-16 19:28:03 +11:00
},
2023-01-18 12:45:56 +11:00
0x1A => unsafe {
// println!("loading from {:#X}", self.state.de.as_u16);
self.state.af.as_u8s.left = self.memory.get(self.state.de.as_u16);
},
0x1B => unsafe { self.state.de.as_u16 = self.sub_u16s(self.state.de.as_u16, 1) },
2023-01-16 19:28:03 +11:00
0x1C => unsafe {
2023-01-18 12:45:56 +11:00
self.state.de.as_u8s.right = self.add_u8s(self.state.de.as_u8s.right, 1)
2023-01-16 19:28:03 +11:00
},
0x1D => unsafe {
2023-01-18 12:45:56 +11:00
self.state.de.as_u8s.right = self.sub_u8s(self.state.de.as_u8s.right, 1)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:23:06 +11:00
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
2023-01-18 13:14:22 +11:00
0x1F => unsafe {
2023-01-18 14:43:24 +11:00
self.state.af.as_u8s.left = self.rr(self.state.af.as_u8s.left);
2023-01-18 13:14:22 +11:00
},
2023-01-16 14:23:06 +11:00
0x20 => {
let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::Z) == 0 {
2023-01-22 09:18:07 +11:00
println!("z flag is 0... so doing jump...");
2023-01-16 19:28:03 +11:00
unsafe {
2023-01-17 09:09:53 +11:00
self.state.pc.as_u16 = self
2023-01-22 09:18:07 +11:00
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
}
} else {
unsafe {
println!(
"not jumping! z flag is {0:#b}, flags are {1:#b} / {1:#X}",
self.get_flag(FLAGS::Z),
self.state.af.as_u8s.right
);
2023-01-16 19:28:03 +11:00
}
2023-01-16 14:23:06 +11:00
}
2023-01-16 12:13:53 +11:00
}
2023-01-16 14:23:06 +11:00
0x21 => self.state.hl = self.ld_immediate_word(),
0x22 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1);
2023-01-16 19:28:03 +11:00
},
2023-01-18 12:45:56 +11:00
0x23 => unsafe { self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1) },
2023-01-16 19:28:03 +11:00
0x24 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u8s.left = self.add_u8s(self.state.hl.as_u8s.left, 1)
2023-01-16 19:28:03 +11:00
},
0x25 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u8s.left = self.sub_u8s(self.state.hl.as_u8s.left, 1)
2023-01-16 14:23:06 +11:00
},
2023-01-16 14:43:27 +11:00
0x26 => self.state.hl.as_u8s.left = self.ld_immediate_byte(),
2023-01-17 09:30:42 +11:00
0x27 => unsafe {
println!("Running DAA instruction (0x27) that I'm not too sure about...");
if self.get_flag(FLAGS::N) == 0 {
if self.get_flag(FLAGS::C) == 1 || self.state.af.as_u8s.left > 0x99 {
self.state.af.as_u8s.left += 0x60;
}
if self.get_flag(FLAGS::H) == 1 || (self.state.af.as_u8s.left & 0x0f) > 0x09 {
self.state.af.as_u8s.left += 0x6;
}
} else {
if self.get_flag(FLAGS::C) == 1 {
self.state.af.as_u8s.left -= 0x60;
}
if self.get_flag(FLAGS::H) == 1 {
self.state.af.as_u8s.left -= 0x6;
}
}
2023-01-18 12:45:56 +11:00
println!(
" ...this set register a to {:#X}...",
self.state.af.as_u8s.left
);
2023-01-17 09:30:42 +11:00
},
2023-01-16 14:43:27 +11:00
0x28 => {
let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::Z) == 1 {
2023-01-16 19:28:03 +11:00
unsafe {
2023-01-17 09:09:53 +11:00
self.state.pc.as_u16 = self
2023-01-22 09:18:07 +11:00
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
2023-01-16 19:28:03 +11:00
}
2023-01-16 14:43:27 +11:00
}
2023-01-16 12:13:53 +11:00
}
2023-01-18 14:43:24 +11:00
0x29 => unsafe {
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.hl.as_u16)
},
2023-01-16 14:43:27 +11:00
0x2A => unsafe {
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, 1);
2023-01-16 19:28:03 +11:00
},
2023-01-18 12:45:56 +11:00
0x2B => unsafe { self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1) },
2023-01-16 19:28:03 +11:00
0x2C => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u8s.right = self.add_u8s(self.state.hl.as_u8s.right, 1)
2023-01-16 19:28:03 +11:00
},
0x2D => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u8s.right = self.sub_u8s(self.state.hl.as_u8s.right, 1)
2023-01-16 14:43:27 +11:00
},
0x2E => self.state.hl.as_u8s.right = self.ld_immediate_byte(),
0x2F => unsafe { self.state.af.as_u8s.left = !self.state.af.as_u8s.left },
0x30 => {
let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::C) == 0 {
2023-01-16 19:28:03 +11:00
unsafe {
2023-01-17 09:09:53 +11:00
self.state.pc.as_u16 = self
2023-01-22 09:18:07 +11:00
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
2023-01-16 19:28:03 +11:00
}
2023-01-16 14:43:27 +11:00
}
2023-01-16 12:13:53 +11:00
}
2023-01-16 14:43:27 +11:00
0x31 => self.state.sp = self.ld_immediate_word(),
0x32 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1);
2023-01-16 14:43:27 +11:00
},
2023-01-18 12:45:56 +11:00
0x33 => unsafe { self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 1) },
2023-01-16 14:43:27 +11:00
0x34 => unsafe {
let address = self.state.hl.as_u16;
let data = self.memory.get(address) + 1;
self.memory.set(address, data);
},
0x35 => unsafe {
let address = self.state.hl.as_u16;
let data = self.memory.get(address) - 1;
self.memory.set(address, data);
},
0x36 => unsafe {
let data = self.ld_immediate_byte();
self.memory.set(self.state.hl.as_u16, data);
},
2023-01-16 19:28:03 +11:00
0x37 => self.set_flag(FLAGS::C),
2023-01-16 14:43:27 +11:00
0x38 => {
let jump_size = self.ld_immediate_byte();
if self.get_flag(FLAGS::C) == 1 {
2023-01-16 19:28:03 +11:00
unsafe {
2023-01-17 09:09:53 +11:00
self.state.pc.as_u16 = self
2023-01-22 09:18:07 +11:00
.state
.pc
.as_u16
.wrapping_add((as_signed(jump_size) as i16) as u16)
2023-01-16 19:28:03 +11:00
}
2023-01-16 14:43:27 +11:00
}
}
2023-01-16 19:28:03 +11:00
0x39 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.add_u16s(self.state.hl.as_u16, self.state.sp.as_u16)
2023-01-16 19:28:03 +11:00
},
2023-01-16 14:43:27 +11:00
0x3A => unsafe {
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
2023-01-18 12:45:56 +11:00
self.state.hl.as_u16 = self.sub_u16s(self.state.hl.as_u16, 1);
2023-01-16 19:28:03 +11:00
},
2023-01-18 12:45:56 +11:00
0x3B => unsafe { self.state.sp.as_u16 = self.sub_u16s(self.state.sp.as_u16, 1) },
2023-01-16 19:28:03 +11:00
0x3C => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, 1)
2023-01-16 19:28:03 +11:00
},
0x3D => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, 1)
2023-01-16 14:43:27 +11:00
},
0x3E => self.state.af.as_u8s.left = self.ld_immediate_byte(),
2023-01-16 19:28:03 +11:00
0x3F => self.toggle_flag(FLAGS::C),
0x40 => {}
0x41 => unsafe { self.state.bc.as_u8s.left = self.state.bc.as_u8s.right },
0x42 => unsafe { self.state.bc.as_u8s.left = self.state.de.as_u8s.left },
0x43 => unsafe { self.state.bc.as_u8s.left = self.state.de.as_u8s.right },
0x44 => unsafe { self.state.bc.as_u8s.left = self.state.hl.as_u8s.left },
0x45 => unsafe { self.state.bc.as_u8s.left = self.state.hl.as_u8s.right },
0x46 => unsafe { self.state.bc.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
0x47 => unsafe { self.state.bc.as_u8s.left = self.state.af.as_u8s.left },
0x48 => unsafe { self.state.bc.as_u8s.right = self.state.bc.as_u8s.left },
0x49 => {}
0x4A => unsafe { self.state.bc.as_u8s.right = self.state.de.as_u8s.left },
0x4B => unsafe { self.state.bc.as_u8s.right = self.state.de.as_u8s.right },
0x4C => unsafe { self.state.bc.as_u8s.right = self.state.hl.as_u8s.left },
0x4D => unsafe { self.state.bc.as_u8s.right = self.state.hl.as_u8s.right },
0x4E => unsafe { self.state.bc.as_u8s.right = self.memory.get(self.state.hl.as_u16) },
0x4F => unsafe { self.state.bc.as_u8s.right = self.state.af.as_u8s.left },
0x50 => unsafe { self.state.de.as_u8s.left = self.state.bc.as_u8s.left },
0x51 => unsafe { self.state.de.as_u8s.left = self.state.bc.as_u8s.right },
0x52 => {}
0x53 => unsafe { self.state.de.as_u8s.left = self.state.de.as_u8s.right },
0x54 => unsafe { self.state.de.as_u8s.left = self.state.hl.as_u8s.left },
0x55 => unsafe { self.state.de.as_u8s.left = self.state.hl.as_u8s.right },
0x56 => unsafe { self.state.de.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
0x57 => unsafe { self.state.de.as_u8s.left = self.state.af.as_u8s.left },
0x58 => unsafe { self.state.de.as_u8s.right = self.state.bc.as_u8s.left },
0x59 => unsafe { self.state.de.as_u8s.right = self.state.bc.as_u8s.right },
0x5A => unsafe { self.state.de.as_u8s.right = self.state.de.as_u8s.left },
0x5B => {}
0x5C => unsafe { self.state.de.as_u8s.right = self.state.hl.as_u8s.left },
0x5D => unsafe { self.state.de.as_u8s.right = self.state.hl.as_u8s.right },
0x5E => unsafe { self.state.de.as_u8s.right = self.memory.get(self.state.hl.as_u16) },
0x5F => unsafe { self.state.de.as_u8s.right = self.state.af.as_u8s.left },
0x60 => unsafe { self.state.hl.as_u8s.left = self.state.bc.as_u8s.left },
0x61 => unsafe { self.state.hl.as_u8s.left = self.state.bc.as_u8s.right },
0x62 => unsafe { self.state.hl.as_u8s.left = self.state.de.as_u8s.left },
0x63 => unsafe { self.state.hl.as_u8s.left = self.state.de.as_u8s.right },
0x64 => {}
0x65 => unsafe { self.state.hl.as_u8s.left = self.state.hl.as_u8s.right },
0x66 => unsafe { self.state.hl.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
0x67 => unsafe { self.state.hl.as_u8s.left = self.state.af.as_u8s.left },
0x68 => unsafe { self.state.hl.as_u8s.right = self.state.bc.as_u8s.left },
0x69 => unsafe { self.state.hl.as_u8s.right = self.state.bc.as_u8s.right },
0x6A => unsafe { self.state.hl.as_u8s.right = self.state.de.as_u8s.left },
0x6B => unsafe { self.state.hl.as_u8s.right = self.state.de.as_u8s.right },
0x6C => unsafe { self.state.hl.as_u8s.right = self.state.hl.as_u8s.left },
0x6D => {}
0x6E => unsafe { self.state.hl.as_u8s.right = self.memory.get(self.state.hl.as_u16) },
0x6F => unsafe { self.state.hl.as_u8s.right = self.state.af.as_u8s.left },
0x70 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.bc.as_u8s.left)
},
0x71 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.bc.as_u8s.right)
},
0x72 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.de.as_u8s.left)
},
0x73 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.de.as_u8s.right)
},
0x74 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.hl.as_u8s.left)
},
0x75 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.hl.as_u8s.right)
},
2023-01-17 09:32:49 +11:00
0x76 => panic!("HALT until interrupt... instruction: 0x76"),
2023-01-16 19:28:03 +11:00
0x77 => unsafe {
self.memory
.set(self.state.hl.as_u16, self.state.af.as_u8s.left)
},
0x78 => unsafe { self.state.af.as_u8s.left = self.state.bc.as_u8s.left },
0x79 => unsafe { self.state.af.as_u8s.left = self.state.bc.as_u8s.right },
0x7A => unsafe { self.state.af.as_u8s.left = self.state.de.as_u8s.left },
0x7B => unsafe { self.state.af.as_u8s.left = self.state.de.as_u8s.right },
0x7C => unsafe { self.state.af.as_u8s.left = self.state.hl.as_u8s.left },
0x7D => unsafe { self.state.af.as_u8s.left = self.state.hl.as_u8s.right },
0x7E => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16) },
0x7F => {}
0x80 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x81 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x82 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x83 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x84 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x85 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x86 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left = self.add_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16),
)
2023-01-16 19:28:03 +11:00
},
0x87 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x88 => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x89 => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
2023-01-22 09:18:07 +11:00
self.state.af.as_u8s.left = self.add_u8s(
self.state.af.as_u8s.left,
self.state.bc.as_u8s.right.wrapping_add(f),
)
2023-01-16 19:28:03 +11:00
},
0x8A => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x8B => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
2023-01-16 19:28:03 +11:00
},
0x8C => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x8D => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
2023-01-16 19:28:03 +11:00
},
0x8E => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.add_u8s(
self.state.af.as_u8s.left,
2023-01-22 09:18:07 +11:00
self.memory.get(self.state.hl.as_u16).wrapping_add(f),
2023-01-18 12:45:56 +11:00
)
2023-01-16 19:28:03 +11:00
},
0x8F => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.add_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x90 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x91 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x92 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x93 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x94 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x95 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right)
2023-01-16 19:28:03 +11:00
},
0x96 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left = self.sub_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16),
)
2023-01-16 19:28:03 +11:00
},
0x97 => unsafe {
2023-01-18 12:45:56 +11:00
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left)
2023-01-16 19:28:03 +11:00
},
0x98 => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x99 => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.bc.as_u8s.right + f)
2023-01-16 19:28:03 +11:00
},
0x9A => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x9B => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.de.as_u8s.right + f)
2023-01-16 19:28:03 +11:00
},
0x9C => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0x9D => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.hl.as_u8s.right + f)
2023-01-16 19:28:03 +11:00
},
0x9E => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.sub_u8s(
self.state.af.as_u8s.left,
self.memory.get(self.state.hl.as_u16) + f,
)
2023-01-16 19:28:03 +11:00
},
0x9F => unsafe {
2023-01-18 12:45:56 +11:00
let f = self.get_flag(FLAGS::C);
self.state.af.as_u8s.left =
self.sub_u8s(self.state.af.as_u8s.left, self.state.af.as_u8s.left + f)
2023-01-16 19:28:03 +11:00
},
0xA0 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.bc.as_u8s.left)
},
0xA1 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.bc.as_u8s.right)
},
0xA2 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.de.as_u8s.left)
},
0xA3 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.de.as_u8s.right)
},
0xA4 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.hl.as_u8s.left)
},
0xA5 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.hl.as_u8s.right)
},
0xA6 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.bitand(self.memory.get(self.state.hl.as_u16))
},
0xA7 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.state.af.as_u8s.left)
},
0xA8 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.bc.as_u8s.left)
},
0xA9 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.bc.as_u8s.right)
},
0xAA => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.de.as_u8s.left)
},
0xAB => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.de.as_u8s.right)
},
0xAC => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.hl.as_u8s.left)
},
0xAD => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.hl.as_u8s.right)
},
0xAE => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.bitxor(self.memory.get(self.state.hl.as_u16))
},
0xAF => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.state.af.as_u8s.left)
},
0xB0 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.bc.as_u8s.left)
},
0xB1 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.bc.as_u8s.right)
},
0xB2 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.de.as_u8s.left)
},
0xB3 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.de.as_u8s.right)
},
0xB4 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.hl.as_u8s.left)
},
0xB5 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.hl.as_u8s.right)
},
0xB6 => unsafe {
self.state.af.as_u8s.left = self
.state
.af
.as_u8s
.left
.bitor(self.memory.get(self.state.hl.as_u16))
},
0xB7 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.state.af.as_u8s.left)
},
0xB8 => unsafe {
if self.state.af.as_u8s.left == self.state.bc.as_u8s.left {
self.set_flag(FLAGS::Z);
}
},
0xB9 => unsafe {
if self.state.af.as_u8s.left == self.state.bc.as_u8s.right {
self.set_flag(FLAGS::Z);
}
},
0xBA => unsafe {
if self.state.af.as_u8s.left == self.state.de.as_u8s.left {
self.set_flag(FLAGS::Z);
}
},
0xBB => unsafe {
if self.state.af.as_u8s.left == self.state.de.as_u8s.right {
self.set_flag(FLAGS::Z);
}
},
0xBC => unsafe {
if self.state.af.as_u8s.left == self.state.hl.as_u8s.left {
self.set_flag(FLAGS::Z);
}
},
0xBD => unsafe {
if self.state.af.as_u8s.left == self.state.hl.as_u8s.right {
self.set_flag(FLAGS::Z);
}
},
0xBE => unsafe {
if self.state.af.as_u8s.left == self.memory.get(self.state.hl.as_u16) {
self.set_flag(FLAGS::Z);
}
},
0xBF => self.set_flag(FLAGS::Z),
0xC0 => unsafe {
if self.get_flag(FLAGS::Z) == 0 {
let address = self.state.sp.as_u16;
self.state.pc.as_u8s.left = self.memory.get(address);
self.state.pc.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-16 19:28:03 +11:00
}
},
0xC1 => unsafe {
let address = self.state.sp.as_u16;
self.state.bc.as_u8s.left = self.memory.get(address);
self.state.bc.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-16 19:28:03 +11:00
},
0xC2 => {
let word = self.ld_immediate_word();
if self.get_flag(FLAGS::Z) == 0 {
self.state.pc = word;
}
2023-01-16 12:13:53 +11:00
}
2023-01-16 19:28:03 +11:00
0xC3 => {
self.state.pc = self.ld_immediate_word();
2023-01-16 12:13:53 +11:00
}
2023-01-16 19:28:03 +11:00
0xC4 => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::Z) == 0 {
self.push(self.state.pc);
self.state.pc = maybe_next;
}
2023-01-16 12:13:53 +11:00
}
2023-01-16 19:28:03 +11:00
0xC5 => self.push(self.state.bc),
0xC6 => unsafe {
2023-01-18 12:45:56 +11:00
let t = self.ld_immediate_byte();
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
2023-01-16 19:28:03 +11:00
},
0xC7 => self.rst(0x00),
0xC8 => {
if self.get_flag(FLAGS::Z) == 1 {
self.state.pc = self.pop_word()
}
2023-01-16 12:13:53 +11:00
}
2023-01-16 19:28:03 +11:00
0xC9 => self.state.pc = self.pop_word(),
0xCA => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::Z) == 1 {
self.state.pc = maybe_next;
}
}
2023-01-17 09:09:53 +11:00
0xCB => {
let subop = self.ld_immediate_byte();
self.cb_subop(subop);
}
2023-01-16 19:28:03 +11:00
0xCC => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::Z) == 1 {
self.push(self.state.pc);
self.state.pc = maybe_next;
}
}
0xCD => {
self.push(self.state.pc);
2023-01-16 12:13:53 +11:00
self.state.pc = self.ld_immediate_word();
}
2023-01-16 19:28:03 +11:00
0xCE => unsafe {
2023-01-18 12:45:56 +11:00
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.add_u8s(self.state.af.as_u8s.left, t)
2023-01-16 19:28:03 +11:00
},
0xCF => self.rst(0x08),
2023-01-17 09:09:53 +11:00
0xD0 => unsafe {
if self.get_flag(FLAGS::C) == 0 {
let address = self.state.sp.as_u16;
self.state.pc.as_u8s.left = self.memory.get(address);
self.state.pc.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-17 09:09:53 +11:00
}
},
0xD1 => unsafe {
let address = self.state.sp.as_u16;
self.state.de.as_u8s.left = self.memory.get(address);
self.state.de.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-17 09:09:53 +11:00
},
0xD2 => {
let word = self.ld_immediate_word();
if self.get_flag(FLAGS::C) == 0 {
self.state.pc = word;
}
}
0xD3 => undefined(0xD3),
0xD4 => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::C) == 0 {
self.push(self.state.pc);
self.state.pc = maybe_next;
}
}
0xD5 => self.push(self.state.de),
0xD6 => unsafe {
2023-01-18 12:45:56 +11:00
let t = self.ld_immediate_byte();
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
2023-01-17 09:09:53 +11:00
},
0xD7 => self.rst(0x10),
0xD8 => {
if self.get_flag(FLAGS::C) == 1 {
self.state.pc = self.pop_word()
}
}
2023-01-17 09:30:42 +11:00
0xD9 => {
self.state.pc = self.pop_word();
2023-01-17 09:45:49 +11:00
self.memory.ime = true;
2023-01-17 09:30:42 +11:00
}
2023-01-17 09:09:53 +11:00
0xDA => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::C) == 1 {
self.state.pc = maybe_next;
}
}
0xDB => undefined(0xDB),
0xDC => {
let maybe_next = self.ld_immediate_word();
if self.get_flag(FLAGS::C) == 1 {
self.push(self.state.pc);
self.state.pc = maybe_next;
}
}
0xDD => undefined(0xDE),
0xDE => unsafe {
2023-01-18 12:45:56 +11:00
let t = self.ld_immediate_byte() + self.get_flag(FLAGS::C);
self.state.af.as_u8s.left = self.sub_u8s(self.state.af.as_u8s.left, t)
2023-01-17 09:09:53 +11:00
},
0xDF => self.rst(0x18),
0xE0 => {
unsafe {
let address = Register {
as_u8s: Inner {
left: self.ld_immediate_byte(),
right: 0xFF,
},
};
self.memory.set(address.as_u16, self.state.af.as_u8s.left);
};
}
0xE1 => unsafe {
let address = self.state.sp.as_u16;
self.state.hl.as_u8s.left = self.memory.get(address);
self.state.hl.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-17 09:09:53 +11:00
},
0xE2 => {
unsafe {
let address = Register {
as_u8s: Inner {
left: self.state.bc.as_u8s.right,
right: 0xFF,
},
};
self.memory.set(address.as_u16, self.state.af.as_u8s.left);
};
}
0xE3 => undefined(0xE3),
0xE4 => undefined(0xE4),
0xE5 => self.push(self.state.hl),
0xE6 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitand(self.ld_immediate_byte())
},
0xE7 => self.rst(0x20),
0xE8 => unsafe {
2023-01-18 12:45:56 +11:00
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, t);
2023-01-17 09:09:53 +11:00
},
0xE9 => self.state.pc = self.state.hl,
0xEA => unsafe {
let address = self.ld_immediate_word().as_u16;
self.memory.set(address, self.state.af.as_u8s.left);
},
0xEB => undefined(0xEB),
0xEC => undefined(0xEC),
0xED => undefined(0xED),
0xEE => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitxor(self.ld_immediate_byte())
},
0xEF => self.rst(0x28),
0xF0 => {
2023-01-16 12:13:53 +11:00
unsafe {
2023-01-17 09:09:53 +11:00
let address = Register {
as_u8s: Inner {
left: self.ld_immediate_byte(),
right: 0xFF,
},
};
self.state.af.as_u8s.left = self.memory.get(address.as_u16);
2023-01-16 12:13:53 +11:00
};
}
2023-01-17 09:09:53 +11:00
0xF1 => unsafe {
let address = self.state.sp.as_u16;
self.state.af.as_u8s.left = self.memory.get(address);
self.state.af.as_u8s.right = self.memory.get(address + 1);
2023-01-18 12:45:56 +11:00
self.state.sp.as_u16 = self.add_u16s(self.state.sp.as_u16, 2);
2023-01-17 09:09:53 +11:00
},
0xF2 => {
unsafe {
let address = Register {
as_u8s: Inner {
left: self.state.bc.as_u8s.right,
right: 0xFF,
},
};
self.state.af.as_u8s.left = self.memory.get(address.as_u16);
};
2023-01-16 12:13:53 +11:00
}
2023-01-17 09:45:49 +11:00
0xF3 => self.memory.ime = false,
2023-01-17 09:09:53 +11:00
0xF4 => undefined(0xF4),
0xF5 => self.push(self.state.af),
0xF6 => unsafe {
self.state.af.as_u8s.left =
self.state.af.as_u8s.left.bitor(self.ld_immediate_byte())
},
0xF7 => self.rst(0x30),
0xF8 => unsafe {
2023-01-18 12:45:56 +11:00
let t = (as_signed(self.ld_immediate_byte()) as i16) as u16;
self.state.hl.as_u16 = self.add_u16s(self.state.sp.as_u16, t)
2023-01-17 09:09:53 +11:00
},
0xF9 => self.state.sp = self.state.hl,
0xFA => unsafe {
let address = self.ld_immediate_word().as_u16;
self.state.af.as_u8s.left = self.memory.get(address);
},
2023-01-17 09:45:49 +11:00
0xFB => self.memory.ime = true,
2023-01-17 09:09:53 +11:00
0xFC => undefined(0xFC),
0xFD => undefined(0xFD),
0xFE => unsafe {
if self.ld_immediate_byte() == self.state.af.as_u8s.left {
self.set_flag(FLAGS::Z)
}
},
0xFF => self.rst(0x38),
2023-01-16 12:13:53 +11:00
};
2023-01-17 09:09:53 +11:00
}
fn cb_subop(&mut self, subop: u8) {
2023-01-18 12:45:56 +11:00
match subop {
2023-01-18 14:43:24 +11:00
0x00 => unsafe { self.state.bc.as_u8s.left = self.rlc(self.state.bc.as_u8s.left) },
0x01 => unsafe { self.state.bc.as_u8s.right = self.rlc(self.state.bc.as_u8s.right) },
0x02 => unsafe { self.state.de.as_u8s.left = self.rlc(self.state.de.as_u8s.left) },
0x03 => unsafe { self.state.de.as_u8s.right = self.rlc(self.state.de.as_u8s.right) },
0x04 => unsafe { self.state.hl.as_u8s.left = self.rlc(self.state.hl.as_u8s.left) },
0x05 => unsafe { self.state.hl.as_u8s.right = self.rlc(self.state.hl.as_u8s.right) },
0x06 => unsafe {
let rotated = self.rlc(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x07 => unsafe { self.state.af.as_u8s.left = self.rlc(self.state.af.as_u8s.left) },
0x08 => unsafe { self.state.bc.as_u8s.left = self.rrc(self.state.bc.as_u8s.left) },
0x09 => unsafe { self.state.bc.as_u8s.right = self.rrc(self.state.bc.as_u8s.right) },
0x0A => unsafe { self.state.de.as_u8s.left = self.rrc(self.state.de.as_u8s.left) },
0x0B => unsafe { self.state.de.as_u8s.right = self.rrc(self.state.de.as_u8s.right) },
0x0C => unsafe { self.state.hl.as_u8s.left = self.rrc(self.state.hl.as_u8s.left) },
0x0D => unsafe { self.state.hl.as_u8s.right = self.rrc(self.state.hl.as_u8s.right) },
0x0E => unsafe {
let rotated = self.rrc(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x0F => unsafe { self.state.af.as_u8s.left = self.rrc(self.state.af.as_u8s.left) },
0x10 => unsafe { self.state.bc.as_u8s.left = self.rl(self.state.bc.as_u8s.left) },
0x11 => unsafe { self.state.bc.as_u8s.right = self.rl(self.state.bc.as_u8s.right) },
0x12 => unsafe { self.state.de.as_u8s.left = self.rl(self.state.de.as_u8s.left) },
0x13 => unsafe { self.state.de.as_u8s.right = self.rl(self.state.de.as_u8s.right) },
0x14 => unsafe { self.state.hl.as_u8s.left = self.rl(self.state.hl.as_u8s.left) },
0x15 => unsafe { self.state.hl.as_u8s.right = self.rl(self.state.hl.as_u8s.right) },
0x16 => unsafe {
let rotated = self.rl(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x17 => unsafe { self.state.af.as_u8s.left = self.rl(self.state.af.as_u8s.left) },
0x18 => unsafe { self.state.bc.as_u8s.left = self.rr(self.state.bc.as_u8s.left) },
0x19 => unsafe { self.state.bc.as_u8s.right = self.rr(self.state.bc.as_u8s.right) },
0x1A => unsafe { self.state.de.as_u8s.left = self.rr(self.state.de.as_u8s.left) },
0x1B => unsafe { self.state.de.as_u8s.right = self.rr(self.state.de.as_u8s.right) },
0x1C => unsafe { self.state.hl.as_u8s.left = self.rr(self.state.hl.as_u8s.left) },
0x1D => unsafe { self.state.hl.as_u8s.right = self.rr(self.state.hl.as_u8s.right) },
0x1E => unsafe {
let rotated = self.rr(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x1F => unsafe { self.state.af.as_u8s.left = self.rr(self.state.af.as_u8s.left) },
0x20 => unsafe { self.state.bc.as_u8s.left = self.sla(self.state.bc.as_u8s.left) },
0x21 => unsafe { self.state.bc.as_u8s.right = self.sla(self.state.bc.as_u8s.right) },
0x22 => unsafe { self.state.de.as_u8s.left = self.sla(self.state.de.as_u8s.left) },
0x23 => unsafe { self.state.de.as_u8s.right = self.sla(self.state.de.as_u8s.right) },
0x24 => unsafe { self.state.hl.as_u8s.left = self.sla(self.state.hl.as_u8s.left) },
0x25 => unsafe { self.state.hl.as_u8s.right = self.sla(self.state.hl.as_u8s.right) },
0x26 => unsafe {
let rotated = self.sla(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x27 => unsafe { self.state.af.as_u8s.left = self.sla(self.state.af.as_u8s.left) },
0x28 => unsafe { self.state.bc.as_u8s.left = self.sra(self.state.bc.as_u8s.left) },
0x29 => unsafe { self.state.bc.as_u8s.right = self.sra(self.state.bc.as_u8s.right) },
0x2A => unsafe { self.state.de.as_u8s.left = self.sra(self.state.de.as_u8s.left) },
0x2B => unsafe { self.state.de.as_u8s.right = self.sra(self.state.de.as_u8s.right) },
0x2C => unsafe { self.state.hl.as_u8s.left = self.sra(self.state.hl.as_u8s.left) },
0x2D => unsafe { self.state.hl.as_u8s.right = self.sra(self.state.hl.as_u8s.right) },
0x2E => unsafe {
let rotated = self.sra(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x2F => unsafe { self.state.af.as_u8s.left = self.sra(self.state.af.as_u8s.left) },
0x30 => unsafe { self.state.bc.as_u8s.left = swap_nibbles(self.state.bc.as_u8s.left) },
0x31 => unsafe {
self.state.bc.as_u8s.right = swap_nibbles(self.state.bc.as_u8s.right)
},
0x32 => unsafe { self.state.de.as_u8s.left = swap_nibbles(self.state.de.as_u8s.left) },
0x33 => unsafe {
self.state.de.as_u8s.right = swap_nibbles(self.state.de.as_u8s.right)
},
0x34 => unsafe { self.state.hl.as_u8s.left = swap_nibbles(self.state.hl.as_u8s.left) },
0x35 => unsafe {
self.state.hl.as_u8s.right = swap_nibbles(self.state.hl.as_u8s.right)
2023-01-18 13:14:22 +11:00
},
2023-01-18 14:43:24 +11:00
0x36 => unsafe {
let rotated = swap_nibbles(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x37 => unsafe { self.state.af.as_u8s.left = swap_nibbles(self.state.af.as_u8s.left) },
0x38 => unsafe { self.state.bc.as_u8s.left = self.srl(self.state.bc.as_u8s.left) },
0x39 => unsafe { self.state.bc.as_u8s.right = self.srl(self.state.bc.as_u8s.right) },
0x3A => unsafe { self.state.de.as_u8s.left = self.srl(self.state.de.as_u8s.left) },
0x3B => unsafe { self.state.de.as_u8s.right = self.srl(self.state.de.as_u8s.right) },
0x3C => unsafe { self.state.hl.as_u8s.left = self.srl(self.state.hl.as_u8s.left) },
0x3D => unsafe { self.state.hl.as_u8s.right = self.srl(self.state.hl.as_u8s.right) },
0x3E => unsafe {
let rotated = self.srl(self.memory.get(self.state.hl.as_u16));
self.memory.set(self.state.hl.as_u16, rotated)
},
0x3F => unsafe { self.state.af.as_u8s.left = self.srl(self.state.af.as_u8s.left) },
0x40 => unsafe { self.bit(self.state.bc.as_u8s.left, 0) },
0x41 => unsafe { self.bit(self.state.bc.as_u8s.right, 0) },
0x42 => unsafe { self.bit(self.state.de.as_u8s.left, 0) },
0x43 => unsafe { self.bit(self.state.de.as_u8s.right, 0) },
0x44 => unsafe { self.bit(self.state.hl.as_u8s.left, 0) },
0x45 => unsafe { self.bit(self.state.hl.as_u8s.right, 0) },
0x46 => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 0);
},
0x47 => unsafe { self.bit(self.state.af.as_u8s.left, 1) },
0x48 => unsafe { self.bit(self.state.bc.as_u8s.left, 1) },
0x49 => unsafe { self.bit(self.state.bc.as_u8s.right, 1) },
0x4A => unsafe { self.bit(self.state.de.as_u8s.left, 1) },
0x4B => unsafe { self.bit(self.state.de.as_u8s.right, 1) },
0x4C => unsafe { self.bit(self.state.hl.as_u8s.left, 1) },
0x4D => unsafe { self.bit(self.state.hl.as_u8s.right, 1) },
0x4E => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 1);
},
0x4F => unsafe { self.bit(self.state.af.as_u8s.left, 1) },
0x50 => unsafe { self.bit(self.state.bc.as_u8s.left, 2) },
0x51 => unsafe { self.bit(self.state.bc.as_u8s.right, 2) },
0x52 => unsafe { self.bit(self.state.de.as_u8s.left, 2) },
0x53 => unsafe { self.bit(self.state.de.as_u8s.right, 2) },
0x54 => unsafe { self.bit(self.state.hl.as_u8s.left, 2) },
0x55 => unsafe { self.bit(self.state.hl.as_u8s.right, 2) },
0x56 => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 2);
},
0x57 => unsafe { self.bit(self.state.af.as_u8s.left, 3) },
0x58 => unsafe { self.bit(self.state.bc.as_u8s.left, 3) },
0x59 => unsafe { self.bit(self.state.bc.as_u8s.right, 3) },
0x5A => unsafe { self.bit(self.state.de.as_u8s.left, 3) },
0x5B => unsafe { self.bit(self.state.de.as_u8s.right, 3) },
0x5C => unsafe { self.bit(self.state.hl.as_u8s.left, 3) },
0x5D => unsafe { self.bit(self.state.hl.as_u8s.right, 3) },
0x5E => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 3);
},
0x5F => unsafe { self.bit(self.state.af.as_u8s.left, 3) },
0x60 => unsafe { self.bit(self.state.bc.as_u8s.left, 4) },
0x61 => unsafe { self.bit(self.state.bc.as_u8s.right, 4) },
0x62 => unsafe { self.bit(self.state.de.as_u8s.left, 4) },
0x63 => unsafe { self.bit(self.state.de.as_u8s.right, 4) },
0x64 => unsafe { self.bit(self.state.hl.as_u8s.left, 4) },
0x65 => unsafe { self.bit(self.state.hl.as_u8s.right, 4) },
0x66 => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 4);
},
0x67 => unsafe { self.bit(self.state.af.as_u8s.left, 5) },
0x68 => unsafe { self.bit(self.state.bc.as_u8s.left, 5) },
0x69 => unsafe { self.bit(self.state.bc.as_u8s.right, 5) },
0x6A => unsafe { self.bit(self.state.de.as_u8s.left, 5) },
0x6B => unsafe { self.bit(self.state.de.as_u8s.right, 5) },
0x6C => unsafe { self.bit(self.state.hl.as_u8s.left, 5) },
0x6D => unsafe { self.bit(self.state.hl.as_u8s.right, 5) },
0x6E => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 5);
},
0x6F => unsafe { self.bit(self.state.af.as_u8s.left, 5) },
0x70 => unsafe { self.bit(self.state.bc.as_u8s.left, 6) },
0x71 => unsafe { self.bit(self.state.bc.as_u8s.right, 6) },
0x72 => unsafe { self.bit(self.state.de.as_u8s.left, 6) },
0x73 => unsafe { self.bit(self.state.de.as_u8s.right, 6) },
0x74 => unsafe { self.bit(self.state.hl.as_u8s.left, 6) },
0x75 => unsafe { self.bit(self.state.hl.as_u8s.right, 6) },
0x76 => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 6);
},
0x77 => unsafe { self.bit(self.state.af.as_u8s.left, 7) },
0x78 => unsafe { self.bit(self.state.bc.as_u8s.left, 7) },
0x79 => unsafe { self.bit(self.state.bc.as_u8s.right, 7) },
0x7A => unsafe { self.bit(self.state.de.as_u8s.left, 7) },
0x7B => unsafe { self.bit(self.state.de.as_u8s.right, 7) },
0x7C => unsafe { self.bit(self.state.hl.as_u8s.left, 7) },
0x7D => unsafe { self.bit(self.state.hl.as_u8s.right, 7) },
0x7E => unsafe {
self.bit(self.memory.get(self.state.hl.as_u16), 7);
},
0x7F => unsafe { self.bit(self.state.af.as_u8s.left, 7) },
0x80 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 0) },
0x81 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 0) },
0x82 => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 0) },
0x83 => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 0) },
0x84 => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 0) },
0x85 => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 0) },
0x86 => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 0);
self.memory.set(self.state.hl.as_u16, rotated)
},
0x87 => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 0) },
0x88 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 1) },
0x89 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 1) },
0x8A => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 1) },
0x8B => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 1) },
0x8C => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 1) },
0x8D => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 1) },
0x8E => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 1);
self.memory.set(self.state.hl.as_u16, rotated)
},
0x8F => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 1) },
0x90 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 2) },
0x91 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 2) },
0x92 => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 2) },
0x93 => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 2) },
0x94 => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 2) },
0x95 => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 2) },
0x96 => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 2);
self.memory.set(self.state.hl.as_u16, rotated)
},
0x97 => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 2) },
0x98 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 3) },
0x99 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 3) },
0x9A => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 3) },
0x9B => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 3) },
0x9C => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 3) },
0x9D => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 3) },
0x9E => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 3);
self.memory.set(self.state.hl.as_u16, rotated)
},
0x9F => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 3) },
0xA0 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 4) },
0xA1 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 4) },
0xA2 => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 4) },
0xA3 => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 4) },
0xA4 => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 4) },
0xA5 => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 4) },
0xA6 => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 4);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xA7 => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 4) },
0xA8 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 5) },
0xA9 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 5) },
0xAA => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 5) },
0xAB => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 5) },
0xAC => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 5) },
0xAD => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 5) },
0xAE => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 5);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xAF => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 5) },
0xB0 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 6) },
0xB1 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 6) },
0xB2 => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 6) },
0xB3 => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 6) },
0xB4 => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 6) },
0xB5 => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 6) },
0xB6 => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 6);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xB7 => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 6) },
0xB8 => unsafe { self.state.bc.as_u8s.left = res(self.state.bc.as_u8s.left, 7) },
0xB9 => unsafe { self.state.bc.as_u8s.right = res(self.state.bc.as_u8s.right, 7) },
0xBA => unsafe { self.state.de.as_u8s.left = res(self.state.de.as_u8s.left, 7) },
0xBB => unsafe { self.state.de.as_u8s.right = res(self.state.de.as_u8s.right, 7) },
0xBC => unsafe { self.state.hl.as_u8s.left = res(self.state.hl.as_u8s.left, 7) },
0xBD => unsafe { self.state.hl.as_u8s.right = res(self.state.hl.as_u8s.right, 7) },
0xBE => unsafe {
let rotated = res(self.memory.get(self.state.hl.as_u16), 7);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xBF => unsafe { self.state.af.as_u8s.left = res(self.state.af.as_u8s.left, 7) },
0xC0 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 0) },
0xC1 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 0) },
0xC2 => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 0) },
0xC3 => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 0) },
0xC4 => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 0) },
0xC5 => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 0) },
0xC6 => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 0);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xC7 => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 0) },
0xC8 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 1) },
0xC9 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 1) },
0xCA => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 1) },
0xCB => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 1) },
0xCC => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 1) },
0xCD => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 1) },
0xCE => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 1);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xCF => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 1) },
0xD0 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 2) },
0xD1 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 2) },
0xD2 => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 2) },
0xD3 => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 2) },
0xD4 => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 2) },
0xD5 => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 2) },
0xD6 => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 2);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xD7 => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 2) },
0xD8 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 3) },
0xD9 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 3) },
0xDA => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 3) },
0xDB => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 3) },
0xDC => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 3) },
0xDD => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 3) },
0xDE => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 3);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xDF => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 3) },
0xE0 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 4) },
0xE1 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 4) },
0xE2 => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 4) },
0xE3 => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 4) },
0xE4 => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 4) },
0xE5 => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 4) },
0xE6 => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 4);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xE7 => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 4) },
0xE8 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 5) },
0xE9 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 5) },
0xEA => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 5) },
0xEB => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 5) },
0xEC => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 5) },
0xED => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 5) },
0xEE => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 5);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xEF => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 5) },
0xF0 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 6) },
0xF1 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 6) },
0xF2 => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 6) },
0xF3 => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 6) },
0xF4 => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 6) },
0xF5 => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 6) },
0xF6 => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 6);
self.memory.set(self.state.hl.as_u16, rotated)
},
0xF7 => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 6) },
0xF8 => unsafe { self.state.bc.as_u8s.left = set(self.state.bc.as_u8s.left, 7) },
0xF9 => unsafe { self.state.bc.as_u8s.right = set(self.state.bc.as_u8s.right, 7) },
0xFA => unsafe { self.state.de.as_u8s.left = set(self.state.de.as_u8s.left, 7) },
0xFB => unsafe { self.state.de.as_u8s.right = set(self.state.de.as_u8s.right, 7) },
0xFC => unsafe { self.state.hl.as_u8s.left = set(self.state.hl.as_u8s.left, 7) },
0xFD => unsafe { self.state.hl.as_u8s.right = set(self.state.hl.as_u8s.right, 7) },
0xFE => unsafe {
let rotated = set(self.memory.get(self.state.hl.as_u16), 7);
self.memory.set(self.state.hl.as_u16, rotated)
2023-01-18 12:45:56 +11:00
},
2023-01-18 14:43:24 +11:00
0xFF => unsafe { self.state.af.as_u8s.left = set(self.state.af.as_u8s.left, 7) },
2023-01-18 12:45:56 +11:00
}
2023-01-16 12:13:53 +11:00
}
fn next_opcode(&mut self) -> u8 {
unsafe {
let opcode = self.memory.get(self.state.pc.as_u16);
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(0x1);
2023-01-16 12:13:53 +11:00
return opcode;
};
}
2023-01-18 14:43:24 +11:00
fn rlc(&mut self, byte: u8) -> u8 {
self.rotate_c(byte, Direction::Left)
}
fn rrc(&mut self, byte: u8) -> u8 {
self.rotate_c(byte, Direction::Right)
}
fn rl(&mut self, byte: u8) -> u8 {
self.rotate(byte, Direction::Left)
}
fn rr(&mut self, byte: u8) -> u8 {
self.rotate(byte, Direction::Right)
}
fn rotate_c(&mut self, byte: u8, direction: Direction) -> u8 {
2023-01-18 13:14:22 +11:00
let (mut rotated, carry) = rotate(byte, &direction);
if carry {
rotated += get_rotation_carry(&direction);
self.set_flag(FLAGS::C);
}
return rotated;
}
2023-01-18 14:43:24 +11:00
fn rotate(&mut self, byte: u8, direction: Direction) -> u8 {
2023-01-18 13:14:22 +11:00
let old_carry = self.get_flag(FLAGS::C);
let (mut rotated, carry) = rotate(byte, &direction);
if old_carry > 0 {
rotated += get_rotation_carry(&direction);
}
if carry {
self.set_flag(FLAGS::C);
}
return rotated;
}
2023-01-18 14:43:24 +11:00
fn sla(&mut self, byte: u8) -> u8 {
self.shift(byte, Direction::Left)
}
fn sra(&mut self, byte: u8) -> u8 {
let b = get_bit(byte, 7);
let val = self.shift(byte, Direction::Right);
if b {
val + 0b10000000
} else {
val
}
}
fn srl(&mut self, byte: u8) -> u8 {
self.shift(byte, Direction::Right)
}
fn shift(&mut self, byte: u8, direction: Direction) -> u8 {
let (rotated, carry) = rotate(byte, &direction);
if carry {
self.set_flag(FLAGS::C);
}
return rotated;
}
fn bit(&mut self, byte: u8, bit: u8) {
self.set_or_clear_flag(FLAGS::Z, !get_bit(byte, bit));
}
2023-01-16 19:28:03 +11:00
fn rst(&mut self, address: u16) {
self.push(self.state.pc);
self.state.pc.as_u8s.left = 0x0;
self.state.pc.as_u8s.right = self.memory.get(address);
}
fn push(&mut self, register: Register) {
unsafe {
let address = self.state.sp.as_u16;
2023-01-18 14:43:24 +11:00
self.memory
.set(address.wrapping_sub(1), register.as_u8s.right);
self.memory
.set(address.wrapping_sub(2), register.as_u8s.left);
self.state.sp.as_u16 = address.wrapping_sub(2);
2023-01-16 19:28:03 +11:00
}
}
fn pop_word(&mut self) -> Register {
unsafe {
let address = self.state.sp.as_u16;
2023-01-22 09:18:07 +11:00
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(0x2);
2023-01-16 19:28:03 +11:00
Register {
as_u8s: Inner {
left: self.memory.get(address),
2023-01-22 09:18:07 +11:00
right: self.memory.get(address.wrapping_add(1)),
2023-01-16 19:28:03 +11:00
},
}
}
}
2023-01-16 14:23:06 +11:00
fn store_word(&mut self, address: u16, word: Register) {
unsafe {
self.memory.set(address, word.as_u8s.left);
self.memory.set(address + 1, word.as_u8s.right);
};
}
2023-01-16 12:13:53 +11:00
fn ld_immediate_word(&mut self) -> Register {
Register {
as_u8s: Inner {
left: self.next_opcode(),
right: self.next_opcode(),
},
}
}
fn ld_immediate_byte(&mut self) -> u8 {
self.next_opcode()
}
2023-01-16 14:23:06 +11:00
fn get_flag(&mut self, flag: FLAGS) -> u8 {
unsafe {
2023-01-18 12:45:56 +11:00
if get_bit(self.state.af.as_u8s.right, flag as u8) {
0x1
} else {
0x0
}
2023-01-16 14:23:06 +11:00
}
}
2023-01-16 19:28:03 +11:00
fn set_flag(&mut self, flag: FLAGS) {
2023-01-22 09:18:07 +11:00
if flag == FLAGS::Z {
println!("setting z flag");
}
2023-01-16 19:28:03 +11:00
unsafe {
2023-01-22 09:18:07 +11:00
println!(
"setting flag: currently {0:#b} / {0:#X}",
self.state.af.as_u8s.right
);
2023-01-16 19:28:03 +11:00
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitor(1 << flag as u8);
2023-01-22 09:18:07 +11:00
println!(
" now {0:#b} / {0:#X}",
self.state.af.as_u8s.right
);
2023-01-16 19:28:03 +11:00
};
}
fn clear_flag(&mut self, flag: FLAGS) {
unsafe {
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitand(!(1 << flag as u8));
};
}
fn toggle_flag(&mut self, flag: FLAGS) {
unsafe {
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitxor(1 << flag as u8);
};
}
2023-01-18 12:45:56 +11:00
fn set_or_clear_flag(&mut self, flag: FLAGS, state: bool) {
if state {
self.set_flag(flag)
} else {
self.clear_flag(flag)
}
}
fn add_u8s(&mut self, first: u8, second: u8) -> u8 {
let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
2023-01-22 09:18:07 +11:00
self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag(
FLAGS::H,
(((first & 0xF).wrapping_add(second & 0xF)) & 0x10) == 0x10,
);
2023-01-18 12:45:56 +11:00
return result;
}
fn add_u16s(&mut self, first: u16, second: u16) -> u16 {
let (result, carry) = first.overflowing_add(second);
self.clear_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
2023-01-22 09:18:07 +11:00
self.set_or_clear_flag(FLAGS::Z, result == 0x0);
self.set_or_clear_flag(
FLAGS::H,
(((first & 0xFFF).wrapping_add(second & 0xFFF)) & 0x1000) == 0x1000,
);
2023-01-18 12:45:56 +11:00
return result;
}
fn sub_u8s(&mut self, first: u8, second: u8) -> u8 {
let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
2023-01-22 09:18:07 +11:00
self.set_or_clear_flag(FLAGS::Z, result == 0x0);
2023-01-18 12:45:56 +11:00
self.set_or_clear_flag(
FLAGS::H,
2023-01-22 09:18:07 +11:00
(((first & 0xF).wrapping_sub(second & 0xF)) & 0x10) == 0x10,
2023-01-18 12:45:56 +11:00
);
return result;
}
fn sub_u16s(&mut self, first: u16, second: u16) -> u16 {
let (result, carry) = first.overflowing_sub(second);
self.set_flag(FLAGS::N);
self.set_or_clear_flag(FLAGS::C, carry);
2023-01-22 09:18:07 +11:00
self.set_or_clear_flag(FLAGS::Z, result == 0x0);
2023-01-18 12:45:56 +11:00
self.set_or_clear_flag(
FLAGS::H,
2023-01-22 09:18:07 +11:00
(((first & 0xFFF).wrapping_sub(second & 0xFFF)) & 0x1000) == 0x1000,
2023-01-18 12:45:56 +11:00
);
return result;
}
2023-01-16 12:13:53 +11:00
}
2023-01-17 09:09:53 +11:00
fn undefined(opcode: u8) {
2023-01-22 09:18:07 +11:00
panic!("Undefined behaviour: opcode {:#X}", opcode);
2023-01-17 09:09:53 +11:00
}
fn as_signed(unsigned: u8) -> i8 {
unsafe {
return transmute(unsigned);
}
}
2023-01-18 12:45:56 +11:00
fn get_bit(byte: u8, flag: u8) -> bool {
let mask = 1 << flag;
let got = byte & mask;
return got > 0x0;
}
2023-01-18 13:14:22 +11:00
fn rotate(byte: u8, direction: &Direction) -> (u8, bool) {
match direction {
Direction::Left => {
let carry = get_bit(byte, 7);
let r = byte << 1;
return (r, carry);
}
Direction::Right => {
let carry = get_bit(byte, 0);
let r = byte >> 1;
return (r, carry);
}
}
}
fn get_rotation_carry(direction: &Direction) -> u8 {
match direction {
Direction::Left => 0b1,
Direction::Right => 0b10000000,
}
}
2023-01-18 14:43:24 +11:00
fn swap_nibbles(byte: u8) -> u8 {
(byte & 0x0F) << 4 | (byte & 0xF0) >> 4
}
fn res(byte: u8, bit: u8) -> u8 {
byte & !(1 << bit)
}
fn set(byte: u8, bit: u8) -> u8 {
byte | (1 << bit)
}