2020-10-06 02:23:33 +00:00
|
|
|
//
|
|
|
|
// LazyFlags.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 05/10/2020.
|
|
|
|
// Copyright © 2020 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef LazyFlags_h
|
|
|
|
#define LazyFlags_h
|
|
|
|
|
|
|
|
#include "../6502Esque.hpp"
|
|
|
|
|
2023-05-10 21:02:18 +00:00
|
|
|
namespace CPU::MOS6502Esque {
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
struct LazyFlags {
|
|
|
|
/// Bit 7 is set if the negative flag is set; otherwise it is clear.
|
2020-10-09 02:02:14 +00:00
|
|
|
uint8_t negative_result = 0;
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
/// Non-zero if the zero flag is clear, zero if it is set.
|
2020-10-09 02:02:14 +00:00
|
|
|
uint8_t zero_result = 0;
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
/// Contains Flag::Carry.
|
2020-10-09 02:02:14 +00:00
|
|
|
uint8_t carry = 0;
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
/// Contains Flag::Decimal.
|
2020-10-09 02:02:14 +00:00
|
|
|
uint8_t decimal = 0;
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
/// Contains Flag::Overflow.
|
2020-10-09 02:02:14 +00:00
|
|
|
uint8_t overflow = 0;
|
2020-10-06 02:23:33 +00:00
|
|
|
|
|
|
|
/// Contains Flag::Interrupt, complemented.
|
|
|
|
uint8_t inverse_interrupt = 0;
|
|
|
|
|
2020-10-07 22:15:18 +00:00
|
|
|
/// Sets N and Z flags per the 8-bit value @c value.
|
2020-10-06 02:23:33 +00:00
|
|
|
void set_nz(uint8_t value) {
|
|
|
|
zero_result = negative_result = value;
|
|
|
|
}
|
|
|
|
|
2020-10-07 22:15:18 +00:00
|
|
|
/// Sets N and Z flags per the 8- or 16-bit value @c value; @c shift should be 0 to indicate an 8-bit value or 8 to indicate a 16-bit value.
|
2020-10-07 01:47:26 +00:00
|
|
|
void set_nz(uint16_t value, int shift) {
|
|
|
|
negative_result = uint8_t(value >> shift);
|
|
|
|
zero_result = uint8_t(value | (value >> shift));
|
|
|
|
}
|
|
|
|
|
2020-10-07 22:15:18 +00:00
|
|
|
/// Sets the Z flag per the 8- or 16-bit value @c value; @c shift should be 0 to indicate an 8-bit value or 8 to indicate a 16-bit value.
|
|
|
|
void set_z(uint16_t value, int shift) {
|
|
|
|
zero_result = uint8_t(value | (value >> shift));
|
|
|
|
}
|
|
|
|
|
2020-10-10 21:47:33 +00:00
|
|
|
/// Sets the N flag per the 8- or 16-bit value @c value; @c shift should be 0 to indicate an 8-bit value or 8 to indicate a 16-bit value.
|
|
|
|
void set_n(uint16_t value, int shift) {
|
|
|
|
negative_result = uint8_t(value >> shift);
|
|
|
|
}
|
|
|
|
|
2020-10-06 02:23:33 +00:00
|
|
|
void set(uint8_t flags) {
|
|
|
|
carry = flags & Flag::Carry;
|
|
|
|
negative_result = flags & Flag::Sign;
|
|
|
|
zero_result = (~flags) & Flag::Zero;
|
|
|
|
overflow = flags & Flag::Overflow;
|
|
|
|
inverse_interrupt = (~flags) & Flag::Interrupt;
|
|
|
|
decimal = flags & Flag::Decimal;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t get() const {
|
2022-06-23 15:23:00 +00:00
|
|
|
return carry | overflow | (inverse_interrupt ^ Flag::Interrupt) | (negative_result & 0x80) | (zero_result ? 0 : Flag::Zero) | Flag::Always | Flag::Break | decimal;
|
2020-10-06 02:23:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
LazyFlags() {
|
|
|
|
// Only the interrupt flag is defined upon reset but get_flags isn't going to
|
|
|
|
// mask the other flags so we need to do that, at least.
|
|
|
|
carry &= Flag::Carry;
|
|
|
|
decimal &= Flag::Decimal;
|
|
|
|
overflow &= Flag::Overflow;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* LazyFlags_h */
|