crustacean_6502_emulator/src/sixty_five/cpu.rs

69 lines
1.7 KiB
Rust

#[repr(u8)]
#[derive(PartialEq, Copy, Clone, Debug)]
pub enum Flags {
Negative = 128,
Overflow = 64,
AlwaysOne = 32,
Break = 16,
Decimal = 8,
Int = 4,
Zero = 2,
Carry = 1,
}
#[allow(non_snake_case)]
pub struct Cpu {
pub A: u8,
pub X: u8,
pub Y: u8,
pub PC: u16,
pub flags: u8,
}
impl Cpu {
pub fn test(&self, flag: Flags) -> bool {
(self.flags & flag as u8) != 0
}
pub fn set_flag(&mut self, flag: Flags, status: bool) {
if status {
self.flags |= flag as u8;
} else {
self.flags &= 0xFF - flag as u8;
}
}
pub fn add_a(&mut self, n: u8) {
let n = n as u16;
let a = self.A as u16;
let res = n + a;
if res > 0xFF {
self.set_flag(Flags::Carry, true);
} else {
self.set_flag(Flags::Carry, false);
}
self.set_a((res & 0xFF) as u8);
}
pub fn set_a(&mut self, value: u8) {
self.set_flag(Flags::Zero, value == 0x00); // Set Zero if A is zero
self.set_flag(Flags::Negative, value & 0x80 != 0); // Test sign bit
self.A = value;
}
}
impl std::default::Default for Cpu {
fn default() -> Self {
Self {
A: 0x00,
X: 0x00,
Y: 0x00,
PC: 0x0000,
flags: 0b_0010_0000,
}
}
}
impl std::fmt::Debug for Cpu {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
write!(
f,
"Registers: \n PC: {:04X}\n A: {:02X} X: {:02X} Y: {:02X}\nNV-BDIZC\n{:08b}",
self.PC, self.A, self.X, self.Y, self.flags
)
}
}