all opcodes to 0xCF
This commit is contained in:
parent
c131791608
commit
866d4ded80
1 changed files with 686 additions and 56 deletions
742
src/processor.rs
742
src/processor.rs
|
@ -1,3 +1,5 @@
|
|||
use std::ops::{BitAnd, BitOr, BitXor};
|
||||
|
||||
use crate::{Inner, Memory, Register, State};
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
@ -16,6 +18,7 @@ pub struct CPU {
|
|||
impl CPU {
|
||||
pub fn exec_next(&mut self) -> u8 {
|
||||
let opcode = self.next_opcode();
|
||||
unsafe { println!("exec {:#4X} from {:#4X}", opcode, self.state.pc.as_u16 - 1) };
|
||||
match opcode {
|
||||
0x0 => {
|
||||
// noop
|
||||
|
@ -25,9 +28,13 @@ impl CPU {
|
|||
let address = self.state.bc.as_u16;
|
||||
self.memory.set(address, self.state.af.as_u8s.left);
|
||||
},
|
||||
0x03 => unsafe { self.state.bc.as_u16 += 1 },
|
||||
0x04 => unsafe { self.state.bc.as_u8s.left += 1 },
|
||||
0x05 => unsafe { self.state.bc.as_u8s.left -= 1 },
|
||||
0x03 => unsafe { self.state.bc.as_u16 = self.state.bc.as_u16.wrapping_add(1) },
|
||||
0x04 => unsafe {
|
||||
self.state.bc.as_u8s.left = self.state.bc.as_u8s.left.wrapping_add(1)
|
||||
},
|
||||
0x05 => unsafe {
|
||||
self.state.bc.as_u8s.left = self.state.bc.as_u8s.left.wrapping_sub(1)
|
||||
},
|
||||
0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(),
|
||||
0x07 => panic!("RCLA instruction: 0x07"),
|
||||
0x08 => unsafe {
|
||||
|
@ -35,11 +42,17 @@ impl CPU {
|
|||
let word = self.state.sp;
|
||||
self.store_word(address, word);
|
||||
},
|
||||
0x09 => unsafe { self.state.hl.as_u16 += self.state.bc.as_u16 },
|
||||
0x09 => unsafe {
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.bc.as_u16)
|
||||
},
|
||||
0x0A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.bc.as_u16) },
|
||||
0x0B => unsafe { self.state.bc.as_u16 -= 0x1 },
|
||||
0x0C => unsafe { self.state.bc.as_u8s.right += 0x1 },
|
||||
0x0D => unsafe { self.state.bc.as_u8s.right -= 0x1 },
|
||||
0x0B => unsafe { self.state.bc.as_u16 = self.state.bc.as_u16.wrapping_sub(0x1) },
|
||||
0x0C => unsafe {
|
||||
self.state.bc.as_u8s.right = self.state.bc.as_u8s.right.wrapping_add(0x1)
|
||||
},
|
||||
0x0D => unsafe {
|
||||
self.state.bc.as_u8s.right = self.state.bc.as_u8s.right.wrapping_sub(0x1)
|
||||
},
|
||||
0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(),
|
||||
0x0F => panic!("RRCA instruction: 0x0F"),
|
||||
0x10 => panic!("STOP instruction"),
|
||||
|
@ -49,65 +62,95 @@ impl CPU {
|
|||
let data = self.state.af.as_u8s.left;
|
||||
self.memory.set(address, data);
|
||||
},
|
||||
0x13 => unsafe { self.state.de.as_u16 -= 0x1 },
|
||||
0x14 => unsafe { self.state.de.as_u8s.left += 0x1 },
|
||||
0x15 => unsafe { self.state.de.as_u8s.left -= 0x1 },
|
||||
0x13 => unsafe { self.state.de.as_u16 = self.state.de.as_u16.wrapping_sub(0x1) },
|
||||
0x14 => unsafe {
|
||||
self.state.de.as_u8s.left = self.state.de.as_u8s.left.wrapping_add(0x1)
|
||||
},
|
||||
0x15 => unsafe {
|
||||
self.state.de.as_u8s.left = self.state.de.as_u8s.left.wrapping_sub(0x1)
|
||||
},
|
||||
0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(),
|
||||
0x17 => panic!("RLA instruction: 0x17"),
|
||||
0x18 => unsafe { self.state.pc.as_u16 += self.ld_immediate_byte() as u16 },
|
||||
0x19 => unsafe { self.state.hl.as_u16 += self.state.de.as_u16 },
|
||||
0x18 => unsafe {
|
||||
self.state.pc.as_u16 = self
|
||||
.state
|
||||
.pc
|
||||
.as_u16
|
||||
.wrapping_add(self.ld_immediate_byte() as u16)
|
||||
},
|
||||
0x19 => unsafe {
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.de.as_u16)
|
||||
},
|
||||
0x1A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.de.as_u16) },
|
||||
0x1B => unsafe { self.state.de.as_u16 -= 1 },
|
||||
0x1C => unsafe { self.state.de.as_u8s.right += 1 },
|
||||
0x1D => unsafe { self.state.de.as_u8s.right -= 1 },
|
||||
0x1B => unsafe { self.state.de.as_u16 = self.state.de.as_u16.wrapping_sub(1) },
|
||||
0x1C => unsafe {
|
||||
self.state.de.as_u8s.right = self.state.de.as_u8s.right.wrapping_add(1)
|
||||
},
|
||||
0x1D => unsafe {
|
||||
self.state.de.as_u8s.right = self.state.de.as_u8s.right.wrapping_sub(1)
|
||||
},
|
||||
0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(),
|
||||
0x1F => panic!("RRA instruction: 0x1F"),
|
||||
0x20 => {
|
||||
let jump_size = self.ld_immediate_byte();
|
||||
if self.get_flag(FLAGS::Z) == 0 {
|
||||
unsafe { self.state.pc.as_u16 += jump_size as u16 }
|
||||
unsafe {
|
||||
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(jump_size as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
0x21 => self.state.hl = self.ld_immediate_word(),
|
||||
0x22 => unsafe {
|
||||
self.memory
|
||||
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
|
||||
self.state.hl.as_u16 += 1;
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1);
|
||||
},
|
||||
0x23 => unsafe { self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1) },
|
||||
0x24 => unsafe {
|
||||
self.state.hl.as_u8s.left = self.state.hl.as_u8s.left.wrapping_add(1)
|
||||
},
|
||||
0x25 => unsafe {
|
||||
self.state.hl.as_u8s.left = self.state.hl.as_u8s.left.wrapping_sub(1)
|
||||
},
|
||||
0x23 => unsafe { self.state.hl.as_u16 += 1 },
|
||||
0x24 => unsafe { self.state.hl.as_u8s.left += 1 },
|
||||
0x25 => unsafe { self.state.hl.as_u8s.left -= 1 },
|
||||
0x26 => self.state.hl.as_u8s.left = self.ld_immediate_byte(),
|
||||
0x27 => panic!("DAA instruction: 0x27"),
|
||||
0x28 => {
|
||||
let jump_size = self.ld_immediate_byte();
|
||||
if self.get_flag(FLAGS::Z) == 1 {
|
||||
unsafe { self.state.pc.as_u16 += jump_size as u16 }
|
||||
unsafe {
|
||||
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(jump_size as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
0x29 => unsafe { self.state.hl.as_u16 *= 2 },
|
||||
0x2A => unsafe {
|
||||
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
|
||||
self.state.hl.as_u16 += 1;
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(1);
|
||||
},
|
||||
0x2B => unsafe { self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1) },
|
||||
0x2C => unsafe {
|
||||
self.state.hl.as_u8s.right = self.state.hl.as_u8s.right.wrapping_add(1)
|
||||
},
|
||||
0x2D => unsafe {
|
||||
self.state.hl.as_u8s.right = self.state.hl.as_u8s.right.wrapping_sub(1)
|
||||
},
|
||||
0x2B => unsafe { self.state.hl.as_u16 -= 1 },
|
||||
0x2C => unsafe { self.state.hl.as_u8s.right += 1 },
|
||||
0x2D => unsafe { self.state.hl.as_u8s.right -= 1 },
|
||||
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 {
|
||||
unsafe { self.state.pc.as_u16 += jump_size as u16 }
|
||||
unsafe {
|
||||
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(jump_size as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
0x31 => self.state.sp = self.ld_immediate_word(),
|
||||
0x32 => unsafe {
|
||||
self.memory
|
||||
.set(self.state.hl.as_u16, self.state.af.as_u8s.left);
|
||||
self.state.hl.as_u16 -= 1;
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1);
|
||||
},
|
||||
0x33 => unsafe { self.state.sp.as_u16 += 1 },
|
||||
0x33 => unsafe { self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(1) },
|
||||
0x34 => unsafe {
|
||||
let address = self.state.hl.as_u16;
|
||||
let data = self.memory.get(address) + 1;
|
||||
|
@ -122,46 +165,586 @@ impl CPU {
|
|||
let data = self.ld_immediate_byte();
|
||||
self.memory.set(self.state.hl.as_u16, data);
|
||||
},
|
||||
0x37 => panic!("SCF instruction: 0x37 - set carry flag"),
|
||||
0x37 => self.set_flag(FLAGS::C),
|
||||
0x38 => {
|
||||
let jump_size = self.ld_immediate_byte();
|
||||
if self.get_flag(FLAGS::C) == 1 {
|
||||
unsafe { self.state.pc.as_u16 += jump_size as u16 }
|
||||
unsafe {
|
||||
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(jump_size as u16)
|
||||
}
|
||||
}
|
||||
}
|
||||
0x39 => unsafe { self.state.hl.as_u16 += self.state.sp.as_u16 },
|
||||
0x39 => unsafe {
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_add(self.state.sp.as_u16)
|
||||
},
|
||||
0x3A => unsafe {
|
||||
self.state.af.as_u8s.left = self.memory.get(self.state.hl.as_u16);
|
||||
self.state.hl.as_u16 -= 1;
|
||||
self.state.hl.as_u16 = self.state.hl.as_u16.wrapping_sub(1);
|
||||
},
|
||||
0x3B => unsafe { self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_sub(1) },
|
||||
0x3C => unsafe {
|
||||
self.state.af.as_u8s.left = self.state.af.as_u8s.left.wrapping_add(1)
|
||||
},
|
||||
0x3D => unsafe {
|
||||
self.state.af.as_u8s.left = self.state.af.as_u8s.left.wrapping_sub(1)
|
||||
},
|
||||
0x3B => unsafe { self.state.sp.as_u16 -= 1 },
|
||||
0x3C => unsafe { self.state.af.as_u8s.left += 1 },
|
||||
0x3D => unsafe { self.state.af.as_u8s.left -= 1 },
|
||||
0x3E => self.state.af.as_u8s.left = self.ld_immediate_byte(),
|
||||
0x3F => panic!("CCF instruction: 0x3F - flip carry flag"),
|
||||
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;
|
||||
};
|
||||
}
|
||||
0x53 => {
|
||||
unsafe {
|
||||
self.state.de.as_u8s.left = self.state.de.as_u8s.right;
|
||||
};
|
||||
}
|
||||
0x66 => {
|
||||
unsafe {
|
||||
self.state.hl.as_u8s.left = self.memory.get(self.state.hl.as_u16);
|
||||
};
|
||||
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)
|
||||
},
|
||||
0x76 => panic!("HALT instruction: 0x76"),
|
||||
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 {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.bc.as_u8s.left)
|
||||
},
|
||||
0x81 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.bc.as_u8s.right)
|
||||
},
|
||||
0x82 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.de.as_u8s.left)
|
||||
},
|
||||
0x83 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.de.as_u8s.right)
|
||||
},
|
||||
0x84 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.hl.as_u8s.left)
|
||||
},
|
||||
0x85 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.hl.as_u8s.right)
|
||||
},
|
||||
0x86 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.memory.get(self.state.hl.as_u16))
|
||||
},
|
||||
0x87 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.af.as_u8s.left)
|
||||
},
|
||||
0x88 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x89 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x8A => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x8B => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x8C => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x8D => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x8E => unsafe {
|
||||
self.state.af.as_u8s.left =
|
||||
self.state.af.as_u8s.left.wrapping_add(
|
||||
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
|
||||
)
|
||||
},
|
||||
0x8F => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x90 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.bc.as_u8s.left)
|
||||
},
|
||||
0x91 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.bc.as_u8s.right)
|
||||
},
|
||||
0x92 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.de.as_u8s.left)
|
||||
},
|
||||
0x93 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.de.as_u8s.right)
|
||||
},
|
||||
0x94 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.hl.as_u8s.left)
|
||||
},
|
||||
0x95 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.hl.as_u8s.right)
|
||||
},
|
||||
0x96 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.memory.get(self.state.hl.as_u16))
|
||||
},
|
||||
0x97 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.af.as_u8s.left)
|
||||
},
|
||||
0x98 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.bc.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x99 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.bc.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x9A => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.de.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x9B => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.de.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x9C => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.hl.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x9D => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.hl.as_u8s.right + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0x9E => unsafe {
|
||||
self.state.af.as_u8s.left =
|
||||
self.state.af.as_u8s.left.wrapping_sub(
|
||||
self.memory.get(self.state.hl.as_u16) + self.get_flag(FLAGS::C),
|
||||
)
|
||||
},
|
||||
0x9F => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_sub(self.state.af.as_u8s.left + self.get_flag(FLAGS::C))
|
||||
},
|
||||
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);
|
||||
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
|
||||
}
|
||||
},
|
||||
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);
|
||||
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
|
||||
},
|
||||
0xC2 => {
|
||||
let word = self.ld_immediate_word();
|
||||
if self.get_flag(FLAGS::Z) == 0 {
|
||||
self.state.pc = word;
|
||||
}
|
||||
}
|
||||
0xC3 => {
|
||||
self.state.pc = self.ld_immediate_word();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
0xC5 => self.push(self.state.bc),
|
||||
0xC6 => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.ld_immediate_byte())
|
||||
},
|
||||
0xC7 => self.rst(0x00),
|
||||
0xC8 => {
|
||||
if self.get_flag(FLAGS::Z) == 1 {
|
||||
self.state.pc = self.pop_word()
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
0xCB => println!("Undefined behaviour: opcode CB"),
|
||||
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);
|
||||
self.state.pc = self.ld_immediate_word();
|
||||
}
|
||||
0xCE => unsafe {
|
||||
self.state.af.as_u8s.left = self
|
||||
.state
|
||||
.af
|
||||
.as_u8s
|
||||
.left
|
||||
.wrapping_add(self.ld_immediate_byte() + self.get_flag(FLAGS::C))
|
||||
},
|
||||
0xCF => self.rst(0x08),
|
||||
|
||||
0xEA => {
|
||||
unsafe {
|
||||
let address = self.ld_immediate_word().as_u16;
|
||||
|
@ -178,11 +761,39 @@ impl CPU {
|
|||
fn next_opcode(&mut self) -> u8 {
|
||||
unsafe {
|
||||
let opcode = self.memory.get(self.state.pc.as_u16);
|
||||
self.state.pc.as_u16 += 0x1;
|
||||
self.state.pc.as_u16 = self.state.pc.as_u16.wrapping_add(0x1);
|
||||
return opcode;
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
self.memory.set(address - 1, register.as_u8s.right);
|
||||
self.memory.set(address - 2, register.as_u8s.left);
|
||||
self.state.sp.as_u16 = address - 2;
|
||||
}
|
||||
}
|
||||
|
||||
fn pop_word(&mut self) -> Register {
|
||||
unsafe {
|
||||
let address = self.state.sp.as_u16;
|
||||
self.state.sp.as_u16 = self.state.sp.as_u16.wrapping_add(2);
|
||||
Register {
|
||||
as_u8s: Inner {
|
||||
left: self.memory.get(address),
|
||||
right: self.memory.get(address + 1),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn store_word(&mut self, address: u16, word: Register) {
|
||||
unsafe {
|
||||
self.memory.set(address, word.as_u8s.left);
|
||||
|
@ -208,4 +819,23 @@ impl CPU {
|
|||
return self.state.af.as_u8s.right & (1 << flag as u8);
|
||||
}
|
||||
}
|
||||
|
||||
fn set_flag(&mut self, flag: FLAGS) {
|
||||
unsafe {
|
||||
self.state.af.as_u8s.right = self.state.af.as_u8s.right.bitor(1 << flag as u8);
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue