0x00 - 0x3F opcodes

This commit is contained in:
Alex Janka 2023-02-01 22:46:58 +11:00
parent 3da02edc34
commit e3199f32b6

View file

@ -1,15 +1,201 @@
use crate::verbose_println; use crate::verbose_println;
use std::ops::{BitAnd, BitOr, BitXor}; 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 { impl CPU {
#[allow(dead_code)] #[allow(dead_code)]
pub fn run_opcode(&mut self, opcode: u8) { pub fn run_opcode(&mut self, opcode: u8) {
match opcode { match opcode {
0x0 => { 0x00 => {
// noop // 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); undefined(opcode);
} }