0x00 - 0x3F opcodes
This commit is contained in:
parent
3da02edc34
commit
e3199f32b6
|
@ -1,15 +1,201 @@
|
|||
use crate::verbose_println;
|
||||
use std::ops::{BitAnd, BitOr, BitXor};
|
||||
|
||||
use super::{as_signed, res, set, swap_nibbles, CPU, FLAGS};
|
||||
use super::{as_signed, res, set, swap_nibbles, Flags, Reg8, SplitRegister, CPU};
|
||||
|
||||
impl CPU {
|
||||
#[allow(dead_code)]
|
||||
pub fn run_opcode(&mut self, opcode: u8) {
|
||||
match opcode {
|
||||
0x0 => {
|
||||
0x00 => {
|
||||
// noop
|
||||
}
|
||||
0x01 => self.reg.bc = self.ld_immediate_word(),
|
||||
0x02 => self.memory.set(self.reg.bc, self.reg.get_8(Reg8::A)),
|
||||
0x03 => self.reg.bc = self.inc_pair(self.reg.bc),
|
||||
0x04 => self.inc(Reg8::B),
|
||||
0x05 => self.dec(Reg8::B),
|
||||
0x06 => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::B, byte);
|
||||
}
|
||||
0x07 => {
|
||||
let val = self.rlc(self.reg.get_8(Reg8::A));
|
||||
self.reg.set_8(Reg8::A, val);
|
||||
}
|
||||
0x08 => {
|
||||
let addr = self.ld_immediate_word();
|
||||
self.memory.set(addr, self.reg.sp.get_low());
|
||||
self.memory
|
||||
.set(addr.wrapping_add(0x1), self.reg.sp.get_high());
|
||||
}
|
||||
0x09 => self.reg.hl = self.add_u16s(self.reg.hl, self.reg.bc),
|
||||
0x0A => self.reg.set_8(Reg8::A, self.memory.get(self.reg.bc)),
|
||||
0x0B => self.reg.bc = self.dec_pair(self.reg.bc),
|
||||
0x0C => self.inc(Reg8::C),
|
||||
0x0D => self.dec(Reg8::C),
|
||||
0x0E => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::C, byte);
|
||||
}
|
||||
0x0F => {
|
||||
let val = self.rrc(self.reg.get_8(Reg8::A));
|
||||
self.reg.set_8(Reg8::A, val);
|
||||
}
|
||||
0x10 => {
|
||||
// stop
|
||||
panic!("stop instruction");
|
||||
}
|
||||
0x11 => self.reg.de = self.ld_immediate_word(),
|
||||
0x12 => self.memory.set(self.reg.de, self.reg.get_8(Reg8::A)),
|
||||
0x13 => self.reg.de = self.inc_pair(self.reg.de),
|
||||
0x14 => self.inc(Reg8::D),
|
||||
0x15 => self.dec(Reg8::D),
|
||||
0x16 => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::D, byte);
|
||||
}
|
||||
0x17 => {
|
||||
let val = self.rl(self.reg.get_8(Reg8::A));
|
||||
self.reg.set_8(Reg8::A, val);
|
||||
}
|
||||
0x18 => {
|
||||
let jump = as_signed(self.ld_immediate_byte());
|
||||
self.jr(jump);
|
||||
}
|
||||
0x19 => self.reg.hl = self.add_u16s(self.reg.hl, self.reg.de),
|
||||
0x1A => self.reg.set_8(Reg8::A, self.memory.get(self.reg.de)),
|
||||
0x1B => self.reg.de = self.dec_pair(self.reg.de),
|
||||
0x1C => self.inc(Reg8::E),
|
||||
0x1D => self.dec(Reg8::E),
|
||||
0x1E => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::E, byte);
|
||||
}
|
||||
0x1F => {
|
||||
let val = self.rr(self.reg.get_8(Reg8::A));
|
||||
self.reg.set_8(Reg8::A, val);
|
||||
}
|
||||
0x20 => {
|
||||
let jump = as_signed(self.ld_immediate_byte());
|
||||
if !self.is_flag(Flags::Zero) {
|
||||
self.jr(jump);
|
||||
}
|
||||
}
|
||||
0x21 => self.reg.hl = self.ld_immediate_word(),
|
||||
0x22 => {
|
||||
self.memory.set(self.reg.hl, self.reg.get_8(Reg8::A));
|
||||
self.reg.hl = self.inc_pair(self.reg.hl);
|
||||
}
|
||||
0x23 => self.reg.hl = self.inc_pair(self.reg.hl),
|
||||
0x24 => self.inc(Reg8::H),
|
||||
0x25 => self.dec(Reg8::H),
|
||||
0x26 => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::H, byte);
|
||||
}
|
||||
0x27 => {
|
||||
let mut a = self.reg.get_8(Reg8::A);
|
||||
if !self.is_flag(Flags::NSubtract) {
|
||||
// after an addition, adjust if (half-)carry occurred or if result is out of bounds
|
||||
if self.is_flag(Flags::Carry) || a > 0x99 {
|
||||
a += 0x60;
|
||||
self.set_flag(Flags::Carry);
|
||||
}
|
||||
if self.is_flag(Flags::HalfCarry) || (a & 0x0f) > 0x09 {
|
||||
a += 0x6;
|
||||
}
|
||||
} else {
|
||||
// after a subtraction, only adjust if (half-)carry occurred
|
||||
if self.is_flag(Flags::Carry) {
|
||||
a -= 0x60;
|
||||
}
|
||||
if self.is_flag(Flags::HalfCarry) {
|
||||
a -= 0x6;
|
||||
}
|
||||
}
|
||||
// these flags are always updated
|
||||
self.set_or_clear_flag(Flags::Zero, a == 0);
|
||||
self.clear_flag(Flags::HalfCarry);
|
||||
self.reg.set_8(Reg8::A, a);
|
||||
}
|
||||
0x28 => {
|
||||
let jump = as_signed(self.ld_immediate_byte());
|
||||
if self.is_flag(Flags::Zero) {
|
||||
self.jr(jump);
|
||||
}
|
||||
}
|
||||
0x29 => self.reg.hl = self.add_u16s(self.reg.hl, self.reg.hl),
|
||||
0x2A => {
|
||||
self.reg.set_8(Reg8::A, self.memory.get(self.reg.hl));
|
||||
self.reg.hl = self.inc_pair(self.reg.hl);
|
||||
}
|
||||
0x2B => self.reg.hl = self.dec_pair(self.reg.hl),
|
||||
0x2C => self.inc(Reg8::L),
|
||||
0x2D => self.dec(Reg8::L),
|
||||
0x2E => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::L, byte);
|
||||
}
|
||||
0x2F => {
|
||||
let val = !self.reg.get_8(Reg8::A);
|
||||
self.reg.set_8(Reg8::A, val);
|
||||
self.set_flag(Flags::NSubtract);
|
||||
self.set_flag(Flags::HalfCarry);
|
||||
}
|
||||
0x30 => {
|
||||
let jump = as_signed(self.ld_immediate_byte());
|
||||
if !self.is_flag(Flags::Carry) {
|
||||
self.jr(jump);
|
||||
}
|
||||
}
|
||||
0x31 => self.reg.sp = self.ld_immediate_word(),
|
||||
0x32 => {
|
||||
self.memory.set(self.reg.hl, self.reg.get_8(Reg8::A));
|
||||
self.reg.hl = self.dec_pair(self.reg.hl);
|
||||
}
|
||||
0x33 => self.reg.sp = self.inc_pair(self.reg.sp),
|
||||
0x34 => {
|
||||
let val = self.inc_raw(self.memory.get(self.reg.hl));
|
||||
self.memory.set(self.reg.hl, val);
|
||||
}
|
||||
0x35 => {
|
||||
let val = self.dec_raw(self.memory.get(self.reg.hl));
|
||||
self.memory.set(self.reg.hl, val);
|
||||
}
|
||||
0x36 => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.memory.set(self.reg.hl, byte);
|
||||
}
|
||||
0x37 => {
|
||||
self.clear_flag(Flags::NSubtract);
|
||||
self.clear_flag(Flags::HalfCarry);
|
||||
self.set_flag(Flags::Carry);
|
||||
}
|
||||
0x38 => {
|
||||
let jump = as_signed(self.ld_immediate_byte());
|
||||
if self.is_flag(Flags::Carry) {
|
||||
self.jr(jump);
|
||||
}
|
||||
}
|
||||
0x39 => self.reg.hl = self.add_u16s(self.reg.hl, self.reg.sp),
|
||||
0x3A => {
|
||||
self.reg.set_8(Reg8::A, self.memory.get(self.reg.hl));
|
||||
self.reg.hl = self.dec_pair(self.reg.hl);
|
||||
}
|
||||
0x3B => self.reg.sp = self.dec_pair(self.reg.sp),
|
||||
0x3C => self.inc(Reg8::A),
|
||||
0x3D => self.dec(Reg8::A),
|
||||
0x3E => {
|
||||
let byte = self.ld_immediate_byte();
|
||||
self.reg.set_8(Reg8::A, byte);
|
||||
}
|
||||
0x3F => {
|
||||
self.clear_flag(Flags::NSubtract);
|
||||
self.clear_flag(Flags::HalfCarry);
|
||||
self.set_or_clear_flag(Flags::Carry, !self.is_flag(Flags::Carry));
|
||||
}
|
||||
|
||||
_ => {
|
||||
undefined(opcode);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue