use bitflags::bitflags;
#[derive(Copy, Clone, Debug)]
#[allow(clippy::struct_excessive_bools)]
pub struct StatusArgs {
pub negative: bool,
pub overflow: bool,
pub unused: bool,
pub brk: bool,
pub decimal_mode: bool,
pub disable_interrupts: bool,
pub zero: bool,
pub carry: bool,
}
impl StatusArgs {
#[must_use]
pub const fn none() -> StatusArgs {
StatusArgs {
negative: false,
overflow: false,
unused: false,
brk: false,
decimal_mode: false,
disable_interrupts: false,
zero: false,
carry: false,
}
}
}
bitflags! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Status: u8 {
const PS_NEGATIVE = 0b1000_0000;
const PS_OVERFLOW = 0b0100_0000;
const PS_UNUSED = 0b0010_0000; const PS_BRK = 0b0001_0000;
const PS_DECIMAL_MODE = 0b0000_1000;
const PS_DISABLE_INTERRUPTS = 0b0000_0100;
const PS_ZERO = 0b0000_0010;
const PS_CARRY = 0b0000_0001;
}
}
impl Status {
#[must_use]
pub fn new(
StatusArgs {
negative,
overflow,
unused,
brk,
decimal_mode,
disable_interrupts,
zero,
carry,
}: StatusArgs,
) -> Status {
let mut out = Status::empty();
if negative {
out |= Status::PS_NEGATIVE;
}
if overflow {
out |= Status::PS_OVERFLOW;
}
if unused {
out |= Status::PS_UNUSED;
}
if brk {
out |= Status::PS_BRK;
}
if decimal_mode {
out |= Status::PS_DECIMAL_MODE;
}
if disable_interrupts {
out |= Status::PS_DISABLE_INTERRUPTS;
}
if zero {
out |= Status::PS_ZERO;
}
if carry {
out |= Status::PS_CARRY;
}
out
}
pub fn and(&mut self, rhs: Status) {
*self &= rhs;
}
pub fn or(&mut self, rhs: Status) {
*self |= rhs;
}
pub fn set_with_mask(&mut self, mask: Status, rhs: Status) {
*self = (*self & !mask) | rhs;
}
}
impl Default for Status {
fn default() -> Self {
Status::new(StatusArgs {
negative: false, overflow: false, unused: true, brk: false, decimal_mode: false, disable_interrupts: true, zero: false, carry: false, })
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct StackPointer(pub u8);
impl StackPointer {
#[must_use]
pub const fn to_u16(self) -> u16 {
let StackPointer(val) = self;
u16::from_le_bytes([val, 0x01])
}
pub const fn decrement(&mut self) {
self.0 = self.0.wrapping_sub(1);
}
pub const fn increment(&mut self) {
self.0 = self.0.wrapping_add(1);
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Registers {
pub accumulator: u8,
pub index_x: u8,
pub index_y: u8,
pub stack_pointer: StackPointer,
pub program_counter: u16,
pub status: Status,
}
impl Default for Registers {
fn default() -> Self {
Self::new()
}
}
impl Registers {
#[must_use]
pub fn new() -> Registers {
Registers {
accumulator: 0,
index_x: 0,
index_y: 0,
stack_pointer: StackPointer(0), program_counter: 0, status: Status::default(),
}
}
}