mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-09-07 23:54:50 +00:00
Extensive change warning: lots of "noexcept" and "constexpr" changes. Not sure if I'll keep all of them, but interesting...
Signed-off-by: Adrian Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
2f76e901f9
commit
22506ea56c
@ -26,8 +26,8 @@ namespace Gaming {
|
||||
virtual void raisePOWER() override;
|
||||
|
||||
protected:
|
||||
virtual float fps() const = 0;
|
||||
virtual bool useVsync() const = 0;
|
||||
virtual float fps() const noexcept = 0;
|
||||
virtual bool useVsync() const noexcept = 0;
|
||||
|
||||
virtual int windowWidth() const noexcept;
|
||||
virtual int windowHeight() const noexcept;
|
||||
@ -37,7 +37,7 @@ namespace Gaming {
|
||||
virtual int rasterWidth() const noexcept = 0;
|
||||
virtual int rasterHeight() const noexcept = 0;
|
||||
|
||||
virtual std::string title() const = 0;
|
||||
virtual std::string title() const noexcept = 0;
|
||||
|
||||
virtual void handleEvents();
|
||||
virtual void update();
|
||||
|
@ -14,6 +14,10 @@
|
||||
|
||||
namespace EightBit {
|
||||
class Intel8080 final : public IntelProcessor {
|
||||
public:
|
||||
DECLARE_PIN_OUTPUT(DBIN) // Active high
|
||||
DECLARE_PIN_OUTPUT(WR) // Active low
|
||||
|
||||
public:
|
||||
enum StatusBits {
|
||||
SF = Bit7,
|
||||
@ -31,19 +35,16 @@ namespace EightBit {
|
||||
virtual int execute() final;
|
||||
virtual int step() final;
|
||||
|
||||
virtual register16_t& AF() final;
|
||||
virtual register16_t& BC() final;
|
||||
virtual register16_t& DE() final;
|
||||
virtual register16_t& HL() final;
|
||||
[[nodiscard]] virtual register16_t& AF() noexcept final;
|
||||
[[nodiscard]] virtual register16_t& BC() noexcept final;
|
||||
[[nodiscard]] virtual register16_t& DE() noexcept final;
|
||||
[[nodiscard]] virtual register16_t& HL() noexcept final;
|
||||
|
||||
bool requestingIO() noexcept { return m_requestIO; }
|
||||
bool requestingMemory() noexcept { return m_requestMemory; }
|
||||
[[nodiscard]] bool requestingIO() noexcept { return m_requestIO; }
|
||||
[[nodiscard]] bool requestingMemory() noexcept { return m_requestMemory; }
|
||||
|
||||
bool requestingRead() { return raised(DBIN()); }
|
||||
bool requestingWrite() { return lowered(WR()); }
|
||||
|
||||
DECLARE_PIN_OUTPUT(DBIN) // Active high
|
||||
DECLARE_PIN_OUTPUT(WR) // Active low
|
||||
[[nodiscard]] bool requestingRead() noexcept { return raised(DBIN()); }
|
||||
[[nodiscard]] bool requestingWrite() noexcept { return lowered(WR()); }
|
||||
|
||||
protected:
|
||||
void handleRESET() final;
|
||||
|
@ -19,20 +19,20 @@ EightBit::Intel8080::Intel8080(Bus& bus)
|
||||
DEFINE_PIN_LEVEL_CHANGERS(DBIN, Intel8080);
|
||||
DEFINE_PIN_LEVEL_CHANGERS(WR, Intel8080);
|
||||
|
||||
EightBit::register16_t& EightBit::Intel8080::AF() {
|
||||
EightBit::register16_t& EightBit::Intel8080::AF() noexcept {
|
||||
af.low = (af.low | Bit1) & ~(Bit5 | Bit3);
|
||||
return af;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::Intel8080::BC() {
|
||||
EightBit::register16_t& EightBit::Intel8080::BC() noexcept {
|
||||
return bc;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::Intel8080::DE() {
|
||||
EightBit::register16_t& EightBit::Intel8080::DE() noexcept {
|
||||
return de;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::Intel8080::HL() {
|
||||
EightBit::register16_t& EightBit::Intel8080::HL() noexcept {
|
||||
return hl;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
virtual void initialise() final;
|
||||
|
||||
protected:
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
||||
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@ namespace Fuse {
|
||||
EightBit::register16_t actual, EightBit::register16_t expected) const;
|
||||
|
||||
protected:
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
||||
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||
}
|
||||
|
||||
|
@ -10,9 +10,9 @@ namespace EightBit {
|
||||
namespace GameBoy {
|
||||
class CharacterDefinition final {
|
||||
public:
|
||||
CharacterDefinition(Ram& vram, uint16_t address);
|
||||
CharacterDefinition(Ram& vram, uint16_t address) noexcept;
|
||||
|
||||
[[nodiscard]] std::array<int, 8> get(int row) const;
|
||||
[[nodiscard]] std::array<int, 8> get(int row) const noexcept;
|
||||
|
||||
private:
|
||||
Ram& m_vram;
|
||||
|
@ -27,12 +27,12 @@ namespace EightBit {
|
||||
PixelCount = RasterWidth * RasterHeight,
|
||||
};
|
||||
|
||||
Display(const AbstractColourPalette* colours, Bus& bus, Ram& oam, Ram& vram);
|
||||
Display(const AbstractColourPalette* colours, Bus& bus, Ram& oam, Ram& vram) noexcept;
|
||||
|
||||
[[nodiscard]] const auto& pixels() const noexcept { return m_pixels; }
|
||||
|
||||
void renderCurrentScanline();
|
||||
void loadObjectAttributes();
|
||||
void renderCurrentScanline() noexcept;
|
||||
void loadObjectAttributes() noexcept;
|
||||
|
||||
private:
|
||||
enum class tile_offset_t {
|
||||
@ -48,35 +48,35 @@ namespace EightBit {
|
||||
uint8_t m_control = 0;
|
||||
uint8_t m_scanLine = 0;
|
||||
|
||||
[[nodiscard]] std::array<int, 4> createPalette(int address);
|
||||
[[nodiscard]] std::array<int, 4> createPalette(int address) noexcept;
|
||||
|
||||
void renderBackground();
|
||||
void renderBackground() noexcept;
|
||||
void renderBackground(
|
||||
int bgArea, int bgCharacters,
|
||||
tile_offset_t offsetType,
|
||||
int offsetX, int offsetY,
|
||||
const std::array<int, 4>& palette);
|
||||
const std::array<int, 4>& palette) noexcept;
|
||||
|
||||
void renderObjects();
|
||||
void renderObjects() noexcept;
|
||||
|
||||
void renderSpriteTile(
|
||||
int height,
|
||||
int drawX, int drawY,
|
||||
bool flipX, bool flipY,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition);
|
||||
const CharacterDefinition& definition) noexcept;
|
||||
|
||||
void renderBackgroundTile(
|
||||
int drawX, int drawY,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition);
|
||||
const CharacterDefinition& definition) noexcept;
|
||||
|
||||
void renderTile(
|
||||
int height,
|
||||
int drawX, int drawY,
|
||||
bool flipX, bool flipY, bool allowTransparencies,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition);
|
||||
const CharacterDefinition& definition) noexcept;
|
||||
};
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ namespace EightBit {
|
||||
void runVerticalBlankLines();
|
||||
|
||||
protected:
|
||||
virtual MemoryMapping mapping(uint16_t address) override;
|
||||
virtual MemoryMapping mapping(uint16_t address) noexcept override;
|
||||
|
||||
private:
|
||||
LR35902 m_cpu;
|
||||
@ -94,7 +94,7 @@ namespace EightBit {
|
||||
|
||||
void validateCartridgeType();
|
||||
|
||||
void Bus_WrittenByte(EightBit::EventArgs);
|
||||
void Bus_WrittenByte(EightBit::EventArgs) noexcept;
|
||||
|
||||
void runRasterLines(int lines);
|
||||
void runVerticalBlankLines(int lines);
|
||||
|
@ -26,16 +26,16 @@ namespace EightBit {
|
||||
Signal<LR35902> ExecutingInstruction;
|
||||
Signal<LR35902> ExecutedInstruction;
|
||||
|
||||
[[nodiscard]] register16_t& AF() final;
|
||||
[[nodiscard]] register16_t& BC() final;
|
||||
[[nodiscard]] register16_t& DE() final;
|
||||
[[nodiscard]] register16_t& HL() final;
|
||||
[[nodiscard]] register16_t& AF() noexcept final;
|
||||
[[nodiscard]] register16_t& BC() noexcept final;
|
||||
[[nodiscard]] register16_t& DE() noexcept final;
|
||||
[[nodiscard]] register16_t& HL() noexcept final;
|
||||
|
||||
bool& IME() noexcept { return m_ime; }
|
||||
|
||||
[[nodiscard]] uint8_t enabledInterrupts();
|
||||
[[nodiscard]] uint8_t flaggedInterrupts();
|
||||
[[nodiscard]] uint8_t maskedInterrupts();
|
||||
[[nodiscard]] uint8_t enabledInterrupts() noexcept;
|
||||
[[nodiscard]] uint8_t flaggedInterrupts() noexcept;
|
||||
[[nodiscard]] uint8_t maskedInterrupts() noexcept;
|
||||
|
||||
Signal<EventArgs> MachineTicked;
|
||||
|
||||
@ -76,33 +76,33 @@ namespace EightBit {
|
||||
[[nodiscard]] uint8_t R(int r);
|
||||
void R(int r, uint8_t value);
|
||||
|
||||
[[nodiscard]] register16_t& RP(int rp);
|
||||
[[nodiscard]] register16_t& RP2(int rp);
|
||||
[[nodiscard]] register16_t& RP(int rp) noexcept;
|
||||
[[nodiscard]] register16_t& RP2(int rp) noexcept;
|
||||
|
||||
[[nodiscard]] static auto adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||
[[nodiscard]] static constexpr auto adjustHalfCarryAdd(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
return setBit(f, HC, calculateHalfCarryAdd(before, value, calculation));
|
||||
}
|
||||
|
||||
[[nodiscard]] static auto adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) {
|
||||
[[nodiscard]] static constexpr auto adjustHalfCarrySub(uint8_t f, const uint8_t before, const uint8_t value, const int calculation) noexcept {
|
||||
return setBit(f, HC, calculateHalfCarrySub(before, value, calculation));
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool convertCondition(uint8_t f, int flag);
|
||||
[[nodiscard]] static bool convertCondition(uint8_t f, int flag) noexcept;
|
||||
|
||||
static uint8_t subtract(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
|
||||
static uint8_t subtract(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0) noexcept;
|
||||
|
||||
void executeCB(int x, int y, int z, int p, int q);
|
||||
void executeOther(int x, int y, int z, int p, int q);
|
||||
|
||||
[[nodiscard]] static uint8_t increment(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t decrement(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t increment(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t decrement(uint8_t& f, uint8_t operand) noexcept;
|
||||
|
||||
void stop(bool value = true) noexcept { m_stopped = value; }
|
||||
void start() noexcept { stop(false); }
|
||||
[[nodiscard]] bool stopped() const noexcept { return m_stopped; }
|
||||
|
||||
void di();
|
||||
void ei();
|
||||
void di() noexcept;
|
||||
void ei() noexcept;
|
||||
|
||||
void reti();
|
||||
|
||||
@ -113,33 +113,33 @@ namespace EightBit {
|
||||
|
||||
[[nodiscard]] register16_t add(uint8_t& f, register16_t operand, register16_t value);
|
||||
|
||||
[[nodiscard]] static uint8_t add(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0);
|
||||
[[nodiscard]] static uint8_t adc(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
[[nodiscard]] static uint8_t sbc(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
static uint8_t andr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
[[nodiscard]] static uint8_t xorr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
[[nodiscard]] static uint8_t orr(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
[[nodiscard]] static void compare(uint8_t& f, uint8_t operand, uint8_t value);
|
||||
[[nodiscard]] static uint8_t add(uint8_t& f, uint8_t operand, uint8_t value, int carry = 0) noexcept;
|
||||
[[nodiscard]] static uint8_t adc(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
[[nodiscard]] static uint8_t sbc(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
static uint8_t andr(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
[[nodiscard]] static uint8_t xorr(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
[[nodiscard]] static uint8_t orr(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
[[nodiscard]] static void compare(uint8_t& f, uint8_t operand, uint8_t value) noexcept;
|
||||
|
||||
[[nodiscard]] static uint8_t rlc(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t rrc(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t rl(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t rr(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t sla(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t sra(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t srl(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t rlc(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t rrc(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t rl(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t rr(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t sla(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t sra(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t srl(uint8_t& f, uint8_t operand) noexcept;
|
||||
|
||||
static void bit(uint8_t& f, int n, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t res(int n, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t set(int n, uint8_t operand);
|
||||
static void bit(uint8_t& f, int n, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t res(int n, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t set(int n, uint8_t operand) noexcept;
|
||||
|
||||
[[nodiscard]] static uint8_t daa(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t daa(uint8_t& f, uint8_t operand) noexcept;
|
||||
|
||||
static void scf(uint8_t& f, uint8_t operand);
|
||||
static void ccf(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t cpl(uint8_t& f, uint8_t operand);
|
||||
static void scf(uint8_t& f, uint8_t operand) noexcept;
|
||||
static void ccf(uint8_t& f, uint8_t operand) noexcept;
|
||||
[[nodiscard]] static uint8_t cpl(uint8_t& f, uint8_t operand) noexcept;
|
||||
|
||||
[[nodiscard]] static uint8_t swap(uint8_t& f, uint8_t operand);
|
||||
[[nodiscard]] static uint8_t swap(uint8_t& f, uint8_t operand) noexcept;
|
||||
};
|
||||
}
|
||||
}
|
@ -3,12 +3,12 @@
|
||||
|
||||
#include <Ram.h>
|
||||
|
||||
EightBit::GameBoy::CharacterDefinition::CharacterDefinition(Ram& vram, const uint16_t address)
|
||||
EightBit::GameBoy::CharacterDefinition::CharacterDefinition(Ram& vram, const uint16_t address) noexcept
|
||||
: m_vram(vram),
|
||||
m_address(address) {
|
||||
}
|
||||
|
||||
std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) const {
|
||||
std::array<int, 8> EightBit::GameBoy::CharacterDefinition::get(int row) const noexcept {
|
||||
|
||||
std::array<int, 8> returned;
|
||||
|
||||
|
@ -7,14 +7,14 @@
|
||||
|
||||
#include <Processor.h>
|
||||
|
||||
EightBit::GameBoy::Display::Display(const AbstractColourPalette* colours, Bus& bus, Ram& oam, Ram& vram)
|
||||
EightBit::GameBoy::Display::Display(const AbstractColourPalette* colours, Bus& bus, Ram& oam, Ram& vram) noexcept
|
||||
: m_bus(bus),
|
||||
m_oam(oam),
|
||||
m_vram(vram),
|
||||
m_colours(colours) {
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Display::renderCurrentScanline() {
|
||||
void EightBit::GameBoy::Display::renderCurrentScanline() noexcept {
|
||||
m_scanLine = m_bus.IO().peek(IoRegisters::LY);
|
||||
if (m_scanLine < RasterHeight) {
|
||||
m_control = m_bus.IO().peek(IoRegisters::LCDC);
|
||||
@ -26,7 +26,7 @@ void EightBit::GameBoy::Display::renderCurrentScanline() {
|
||||
}
|
||||
}
|
||||
|
||||
std::array<int, 4> EightBit::GameBoy::Display::createPalette(const int address) {
|
||||
std::array<int, 4> EightBit::GameBoy::Display::createPalette(const int address) noexcept {
|
||||
const auto raw = m_bus.IO().peek(address);
|
||||
const std::array<int, 4> palette = {
|
||||
raw & 0b11,
|
||||
@ -37,12 +37,12 @@ std::array<int, 4> EightBit::GameBoy::Display::createPalette(const int address)
|
||||
return palette;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Display::loadObjectAttributes() {
|
||||
void EightBit::GameBoy::Display::loadObjectAttributes() noexcept {
|
||||
for (int i = 0; i < 40; ++i)
|
||||
m_objectAttributes[i] = ObjectAttribute(m_oam, 4 * i);
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Display::renderObjects() {
|
||||
void EightBit::GameBoy::Display::renderObjects() noexcept {
|
||||
|
||||
const auto objBlockHeight = (m_control & IoRegisters::OBJ_SIZE) ? 16 : 8;
|
||||
|
||||
@ -81,7 +81,7 @@ void EightBit::GameBoy::Display::renderObjects() {
|
||||
}
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Display::renderBackground() {
|
||||
void EightBit::GameBoy::Display::renderBackground() noexcept {
|
||||
|
||||
const auto palette = createPalette(IoRegisters::BGP);
|
||||
|
||||
@ -105,7 +105,7 @@ void EightBit::GameBoy::Display::renderBackground() {
|
||||
void EightBit::GameBoy::Display::renderBackground(
|
||||
int bgArea, int bgCharacters, tile_offset_t offsetType,
|
||||
int offsetX, int offsetY,
|
||||
const std::array<int, 4>& palette) {
|
||||
const std::array<int, 4>& palette) noexcept {
|
||||
|
||||
const int row = (m_scanLine - offsetY) / 8;
|
||||
auto address = bgArea + row * BufferCharacterWidth;
|
||||
@ -128,7 +128,7 @@ void EightBit::GameBoy::Display::renderSpriteTile(
|
||||
const int drawX, const int drawY,
|
||||
const bool flipX, const bool flipY,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition) {
|
||||
const CharacterDefinition& definition) noexcept {
|
||||
renderTile(
|
||||
height,
|
||||
drawX, drawY,
|
||||
@ -140,7 +140,7 @@ void EightBit::GameBoy::Display::renderSpriteTile(
|
||||
void EightBit::GameBoy::Display::renderBackgroundTile(
|
||||
const int drawX, const int drawY,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition) {
|
||||
const CharacterDefinition& definition) noexcept {
|
||||
renderTile(
|
||||
8,
|
||||
drawX, drawY,
|
||||
@ -154,7 +154,7 @@ void EightBit::GameBoy::Display::renderTile(
|
||||
const int drawX, const int drawY,
|
||||
const bool flipX, const bool flipY, const bool allowTransparencies,
|
||||
const std::array<int, 4>& palette,
|
||||
const CharacterDefinition& definition) {
|
||||
const CharacterDefinition& definition) noexcept {
|
||||
|
||||
const auto width = 8;
|
||||
|
||||
|
@ -40,7 +40,7 @@ void EightBit::GameBoy::Bus::loadGameRom(const std::string path) {
|
||||
validateCartridgeType();
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::Bus::Bus_WrittenByte(EightBit::EventArgs) {
|
||||
void EightBit::GameBoy::Bus::Bus_WrittenByte(EightBit::EventArgs) noexcept {
|
||||
|
||||
const auto address = ADDRESS().word;
|
||||
const auto value = DATA();
|
||||
@ -161,7 +161,7 @@ void EightBit::GameBoy::Bus::validateCartridgeType() {
|
||||
}
|
||||
}
|
||||
|
||||
EightBit::MemoryMapping EightBit::GameBoy::Bus::mapping(uint16_t address) {
|
||||
EightBit::MemoryMapping EightBit::GameBoy::Bus::mapping(uint16_t address) noexcept {
|
||||
|
||||
if ((address < 0x100) && IO().bootRomEnabled())
|
||||
return { m_bootRom, 0x0000, 0xffff, MemoryMapping::AccessLevel::ReadOnly };
|
||||
|
@ -13,20 +13,20 @@ EightBit::GameBoy::LR35902::LR35902(Bus& memory)
|
||||
});
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::AF() {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::AF() noexcept {
|
||||
af.low = higherNibble(af.low);
|
||||
return af;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::BC() {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::BC() noexcept {
|
||||
return bc;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::DE() {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::DE() noexcept {
|
||||
return de;
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::HL() {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::HL() noexcept {
|
||||
return hl;
|
||||
}
|
||||
|
||||
@ -87,15 +87,15 @@ void EightBit::GameBoy::LR35902::ret() {
|
||||
tickMachine();
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::di() {
|
||||
void EightBit::GameBoy::LR35902::di() noexcept {
|
||||
IME() = false;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::ei() {
|
||||
void EightBit::GameBoy::LR35902::ei() noexcept {
|
||||
IME() = true;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::increment(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::increment(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF);
|
||||
const uint8_t result = operand + 1;
|
||||
f = adjustZero<LR35902>(f, result);
|
||||
@ -103,7 +103,7 @@ uint8_t EightBit::GameBoy::LR35902::increment(uint8_t& f, const uint8_t operand)
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::decrement(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::decrement(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = setBit(f, NF);
|
||||
f = clearBit(f, HC, lowNibble(operand));
|
||||
const uint8_t result = operand - 1;
|
||||
@ -165,7 +165,7 @@ void EightBit::GameBoy::LR35902::R(const int r, const uint8_t value) {
|
||||
}
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::RP(const int rp) {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::RP(const int rp) noexcept {
|
||||
switch (rp) {
|
||||
case 0b00:
|
||||
return BC();
|
||||
@ -180,7 +180,7 @@ EightBit::register16_t& EightBit::GameBoy::LR35902::RP(const int rp) {
|
||||
}
|
||||
}
|
||||
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::RP2(const int rp) {
|
||||
EightBit::register16_t& EightBit::GameBoy::LR35902::RP2(const int rp) noexcept {
|
||||
switch (rp) {
|
||||
case 0b00:
|
||||
return BC();
|
||||
@ -195,7 +195,7 @@ EightBit::register16_t& EightBit::GameBoy::LR35902::RP2(const int rp) {
|
||||
}
|
||||
}
|
||||
|
||||
bool EightBit::GameBoy::LR35902::convertCondition(const uint8_t f, int flag) {
|
||||
bool EightBit::GameBoy::LR35902::convertCondition(const uint8_t f, int flag) noexcept {
|
||||
ASSUME(flag >= 0);
|
||||
ASSUME(flag <= 7);
|
||||
switch (flag) {
|
||||
@ -249,7 +249,7 @@ EightBit::register16_t EightBit::GameBoy::LR35902::add(uint8_t& f, const registe
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::add(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) {
|
||||
uint8_t EightBit::GameBoy::LR35902::add(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) noexcept {
|
||||
|
||||
const register16_t addition = operand + value + carry;
|
||||
const auto result = addition.low;
|
||||
@ -263,11 +263,11 @@ uint8_t EightBit::GameBoy::LR35902::add(uint8_t& f, const uint8_t operand, const
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::adc(uint8_t& f, const uint8_t operand, const uint8_t value) {
|
||||
uint8_t EightBit::GameBoy::LR35902::adc(uint8_t& f, const uint8_t operand, const uint8_t value) noexcept {
|
||||
return add(f, operand, value, (f & CF) >> 4);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::subtract(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) {
|
||||
uint8_t EightBit::GameBoy::LR35902::subtract(uint8_t& f, const uint8_t operand, const uint8_t value, const int carry) noexcept {
|
||||
|
||||
const register16_t subtraction = operand - value - carry;
|
||||
const auto result = subtraction.low;
|
||||
@ -281,11 +281,11 @@ uint8_t EightBit::GameBoy::LR35902::subtract(uint8_t& f, const uint8_t operand,
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::sbc(uint8_t& f, const uint8_t operand, const uint8_t value) {
|
||||
uint8_t EightBit::GameBoy::LR35902::sbc(uint8_t& f, const uint8_t operand, const uint8_t value) noexcept {
|
||||
return subtract(f, operand, value, (f & CF) >> 4);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::andr(uint8_t& f, const uint8_t operand, const uint8_t value) {
|
||||
uint8_t EightBit::GameBoy::LR35902::andr(uint8_t& f, const uint8_t operand, const uint8_t value) noexcept {
|
||||
f = setBit(f, HC);
|
||||
f = clearBit(f, CF | NF);
|
||||
const uint8_t result = operand & value;
|
||||
@ -293,76 +293,76 @@ uint8_t EightBit::GameBoy::LR35902::andr(uint8_t& f, const uint8_t operand, cons
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::xorr(uint8_t& f, const uint8_t operand, const uint8_t value) {
|
||||
uint8_t EightBit::GameBoy::LR35902::xorr(uint8_t& f, const uint8_t operand, const uint8_t value) noexcept {
|
||||
f = clearBit(f, HC | CF | NF);
|
||||
const uint8_t result = operand ^ value;
|
||||
f = adjustZero<LR35902>(f, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::orr(uint8_t& f, const uint8_t operand, const uint8_t value) {
|
||||
uint8_t EightBit::GameBoy::LR35902::orr(uint8_t& f, const uint8_t operand, const uint8_t value) noexcept {
|
||||
f = clearBit(f, HC | CF | NF);
|
||||
const uint8_t result = operand | value;
|
||||
f = adjustZero<LR35902>(f, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::compare(uint8_t& f, uint8_t operand, const uint8_t value) {
|
||||
void EightBit::GameBoy::LR35902::compare(uint8_t& f, uint8_t operand, const uint8_t value) noexcept {
|
||||
subtract(f, operand, value);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::rlc(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::rlc(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
const auto carry = operand & Bit7;
|
||||
f = setBit(f, CF, carry);
|
||||
return (operand << 1) | (carry >> 7);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::rrc(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::rrc(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
const auto carry = operand & Bit0;
|
||||
f = setBit(f, CF, carry);
|
||||
return (operand >> 1) | (carry << 7);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::rl(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::rl(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
const auto carry = f & CF;
|
||||
f = setBit(f, CF, operand & Bit7);
|
||||
return (operand << 1) | (carry >> 4); // CF at Bit4
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::rr(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::rr(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
const auto carry = f & CF;
|
||||
f = setBit(f, CF, operand & Bit0);
|
||||
return (operand >> 1) | (carry << 3); // CF at Bit4
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::sla(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::sla(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
f = setBit(f, CF, operand & Bit7);
|
||||
return operand << 1;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::sra(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::sra(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
f = setBit(f, CF, operand & Bit0);
|
||||
return (operand >> 1) | (operand & Bit7);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::swap(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::swap(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | CF);
|
||||
return promoteNibble(operand) | demoteNibble(operand);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::srl(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::srl(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC | ZF);
|
||||
f = setBit(f, CF, operand & Bit0);
|
||||
return (operand >> 1) & ~Bit7;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::bit(uint8_t& f, const int n, const uint8_t operand) {
|
||||
void EightBit::GameBoy::LR35902::bit(uint8_t& f, const int n, const uint8_t operand) noexcept {
|
||||
ASSUME(n >= 0);
|
||||
ASSUME(n <= 7);
|
||||
const auto carry = f & CF;
|
||||
@ -370,19 +370,19 @@ void EightBit::GameBoy::LR35902::bit(uint8_t& f, const int n, const uint8_t oper
|
||||
f = setBit(f, CF, carry);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::res(const int n, const uint8_t operand) noexcept {
|
||||
ASSUME(n >= 0);
|
||||
ASSUME(n <= 7);
|
||||
return clearBit(operand, Chip::bit(n));
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::set(const int n, const uint8_t operand) noexcept {
|
||||
ASSUME(n >= 0);
|
||||
ASSUME(n <= 7);
|
||||
return setBit(operand, Chip::bit(n));
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::daa(uint8_t& f, uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::daa(uint8_t& f, uint8_t operand) noexcept {
|
||||
|
||||
int updated = operand;
|
||||
|
||||
@ -407,30 +407,30 @@ uint8_t EightBit::GameBoy::LR35902::daa(uint8_t& f, uint8_t operand) {
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::cpl(uint8_t& f, const uint8_t operand) {
|
||||
uint8_t EightBit::GameBoy::LR35902::cpl(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = setBit(f, HC | NF);
|
||||
return ~operand;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::scf(uint8_t& f, const uint8_t operand) {
|
||||
void EightBit::GameBoy::LR35902::scf(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = setBit(f, CF);
|
||||
f = clearBit(f, HC | NF);
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::LR35902::ccf(uint8_t& f, const uint8_t operand) {
|
||||
void EightBit::GameBoy::LR35902::ccf(uint8_t& f, const uint8_t operand) noexcept {
|
||||
f = clearBit(f, NF | HC);
|
||||
f = clearBit(f, CF, f & CF);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::enabledInterrupts() {
|
||||
uint8_t EightBit::GameBoy::LR35902::enabledInterrupts() noexcept {
|
||||
return BUS().peek(IoRegisters::BASE + IoRegisters::IE);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::flaggedInterrupts() {
|
||||
uint8_t EightBit::GameBoy::LR35902::flaggedInterrupts() noexcept {
|
||||
return m_bus.IO().peek(IoRegisters::IF);
|
||||
}
|
||||
|
||||
uint8_t EightBit::GameBoy::LR35902::maskedInterrupts() {
|
||||
uint8_t EightBit::GameBoy::LR35902::maskedInterrupts() noexcept {
|
||||
return enabledInterrupts() & flaggedInterrupts();
|
||||
}
|
||||
|
||||
|
@ -34,13 +34,13 @@ namespace EightBit {
|
||||
int execute() final;
|
||||
[[nodiscard]] int step() final;
|
||||
|
||||
[[nodiscard]] auto& X() { return x; }
|
||||
[[nodiscard]] auto& Y() { return y; }
|
||||
[[nodiscard]] auto& A() { return a; }
|
||||
[[nodiscard]] auto& S() { return s; }
|
||||
[[nodiscard]] constexpr auto& X() noexcept { return x; }
|
||||
[[nodiscard]] constexpr auto& Y() noexcept { return y; }
|
||||
[[nodiscard]] constexpr auto& A() noexcept { return a; }
|
||||
[[nodiscard]] constexpr auto& S() noexcept { return s; }
|
||||
|
||||
[[nodiscard]] auto& P() { return p; }
|
||||
[[nodiscard]] const auto& P() const { return p; }
|
||||
[[nodiscard]] constexpr auto& P() noexcept { return p; }
|
||||
[[nodiscard]] constexpr const auto& P() const noexcept { return p; }
|
||||
|
||||
DECLARE_PIN_INPUT(NMI)
|
||||
DECLARE_PIN_INPUT(SO)
|
||||
@ -55,15 +55,15 @@ namespace EightBit {
|
||||
void busWrite() final;
|
||||
[[nodiscard]] uint8_t busRead() final;
|
||||
|
||||
[[nodiscard]] virtual uint8_t sub(uint8_t operand, uint8_t data, int borrow = 0);
|
||||
[[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t data);
|
||||
[[nodiscard]] uint8_t sub_b(uint8_t operand, uint8_t data, int borrow);
|
||||
[[nodiscard]] uint8_t sub_d(uint8_t operand, uint8_t data, int borrow);
|
||||
[[nodiscard]] virtual uint8_t sub(uint8_t operand, uint8_t data, int borrow = 0) noexcept;
|
||||
[[nodiscard]] uint8_t sbc(uint8_t operand, uint8_t data) noexcept;
|
||||
[[nodiscard]] uint8_t sub_b(uint8_t operand, uint8_t data, int borrow) noexcept;
|
||||
[[nodiscard]] uint8_t sub_d(uint8_t operand, uint8_t data, int borrow) noexcept;
|
||||
|
||||
[[nodiscard]] virtual uint8_t add(uint8_t operand, uint8_t data, int carry = 0);
|
||||
[[nodiscard]] uint8_t adc(uint8_t operand, uint8_t data);
|
||||
[[nodiscard]] uint8_t add_b(uint8_t operand, uint8_t data, int carry);
|
||||
[[nodiscard]] uint8_t add_d(uint8_t operand, uint8_t data, int carry);
|
||||
[[nodiscard]] virtual uint8_t add(uint8_t operand, uint8_t data, int carry = 0) noexcept;
|
||||
[[nodiscard]] uint8_t adc(uint8_t operand, uint8_t data) noexcept;
|
||||
[[nodiscard]] uint8_t add_b(uint8_t operand, uint8_t data, int carry) noexcept;
|
||||
[[nodiscard]] uint8_t add_d(uint8_t operand, uint8_t data, int carry) noexcept;
|
||||
|
||||
private:
|
||||
const uint8_t IRQvector = 0xfe; // IRQ vector
|
||||
@ -111,29 +111,29 @@ namespace EightBit {
|
||||
|
||||
// Flag adjustment
|
||||
|
||||
void adjustZero(const uint8_t datum) { P() = clearBit(P(), ZF, datum); }
|
||||
void adjustNegative(const uint8_t datum) { P() = setBit(P(), NF, datum & NF); }
|
||||
void adjustZero(const uint8_t datum) noexcept { P() = clearBit(P(), ZF, datum); }
|
||||
void adjustNegative(const uint8_t datum) noexcept { P() = setBit(P(), NF, datum & NF); }
|
||||
|
||||
void adjustNZ(const uint8_t datum) {
|
||||
void adjustNZ(const uint8_t datum) noexcept {
|
||||
adjustZero(datum);
|
||||
adjustNegative(datum);
|
||||
}
|
||||
|
||||
// Flag checking
|
||||
|
||||
[[nodiscard]] auto interruptMasked() const { return P() & IF; }
|
||||
[[nodiscard]] auto decimal() const { return P() & DF; }
|
||||
[[nodiscard]] auto interruptMasked() const noexcept { return P() & IF; }
|
||||
[[nodiscard]] auto decimal() const noexcept { return P() & DF; }
|
||||
|
||||
[[nodiscard]] auto negative() const { return P() & NF; }
|
||||
[[nodiscard]] auto zero() const { return P() & ZF; }
|
||||
[[nodiscard]] auto overflow() const { return P() & VF; }
|
||||
[[nodiscard]] auto carry() const { return P() & CF; }
|
||||
[[nodiscard]] auto negative() const noexcept { return P() & NF; }
|
||||
[[nodiscard]] auto zero() const noexcept { return P() & ZF; }
|
||||
[[nodiscard]] auto overflow() const noexcept { return P() & VF; }
|
||||
[[nodiscard]] auto carry() const noexcept { return P() & CF; }
|
||||
|
||||
// Miscellaneous
|
||||
|
||||
void branch(int condition);
|
||||
|
||||
[[nodiscard]] auto through(const uint8_t data) {
|
||||
[[nodiscard]] auto through(const uint8_t data) noexcept {
|
||||
adjustNZ(data);
|
||||
return data;
|
||||
}
|
||||
@ -146,29 +146,29 @@ namespace EightBit {
|
||||
|
||||
// Instruction implementations
|
||||
|
||||
[[nodiscard]] uint8_t andr(uint8_t operand, uint8_t data);
|
||||
[[nodiscard]] uint8_t asl(uint8_t value);
|
||||
void bit(uint8_t operand, uint8_t data);
|
||||
void cmp(uint8_t first, uint8_t second);
|
||||
[[nodiscard]] uint8_t dec(uint8_t value);
|
||||
[[nodiscard]] uint8_t eorr(uint8_t operand, uint8_t data);
|
||||
[[nodiscard]] uint8_t inc(uint8_t value);
|
||||
[[nodiscard]] uint8_t andr(uint8_t operand, uint8_t data) noexcept;
|
||||
[[nodiscard]] uint8_t asl(uint8_t value) noexcept;
|
||||
void bit(uint8_t operand, uint8_t data) noexcept;
|
||||
void cmp(uint8_t first, uint8_t second) noexcept;
|
||||
[[nodiscard]] uint8_t dec(uint8_t value) noexcept;
|
||||
[[nodiscard]] uint8_t eorr(uint8_t operand, uint8_t data) noexcept;
|
||||
[[nodiscard]] uint8_t inc(uint8_t value) noexcept;
|
||||
void jsr();
|
||||
[[nodiscard]] uint8_t lsr(uint8_t value);
|
||||
[[nodiscard]] uint8_t orr(uint8_t operand, uint8_t data);
|
||||
[[nodiscard]] uint8_t lsr(uint8_t value) noexcept;
|
||||
[[nodiscard]] uint8_t orr(uint8_t operand, uint8_t data) noexcept;
|
||||
void php();
|
||||
void plp();
|
||||
[[nodiscard]] uint8_t rol(uint8_t operand);
|
||||
[[nodiscard]] uint8_t ror(uint8_t operand);
|
||||
[[nodiscard]] uint8_t rol(uint8_t operand) noexcept;
|
||||
[[nodiscard]] uint8_t ror(uint8_t operand) noexcept;
|
||||
void rti();
|
||||
void rts();
|
||||
|
||||
// Undocumented compound instructions
|
||||
|
||||
void anc(uint8_t value);
|
||||
void arr(uint8_t value);
|
||||
void asr(uint8_t value);
|
||||
void axs(uint8_t value);
|
||||
void anc(uint8_t value) noexcept;
|
||||
void arr(uint8_t value) noexcept;
|
||||
void asr(uint8_t value) noexcept;
|
||||
void axs(uint8_t value) noexcept;
|
||||
void dcp(uint8_t value);
|
||||
void isb(uint8_t value);
|
||||
void rla(uint8_t value);
|
||||
|
@ -437,17 +437,15 @@ uint8_t EightBit::MOS6502::Address_ZeroPageY() {
|
||||
}
|
||||
|
||||
std::pair<EightBit::register16_t, uint8_t> EightBit::MOS6502::Address_AbsoluteX() {
|
||||
auto address = Address_Absolute();
|
||||
const auto address = Address_Absolute();
|
||||
const auto page = address.high;
|
||||
address += X();
|
||||
return { address, page };
|
||||
return { address + X(), page };
|
||||
}
|
||||
|
||||
std::pair<EightBit::register16_t, uint8_t> EightBit::MOS6502::Address_AbsoluteY() {
|
||||
auto address = Address_Absolute();
|
||||
const auto address = Address_Absolute();
|
||||
const auto page = address.high;
|
||||
address += Y();
|
||||
return { address, page };
|
||||
return { address + Y(), page };
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::MOS6502::Address_IndexedIndirectX() {
|
||||
@ -455,10 +453,9 @@ EightBit::register16_t EightBit::MOS6502::Address_IndexedIndirectX() {
|
||||
}
|
||||
|
||||
std::pair<EightBit::register16_t, uint8_t> EightBit::MOS6502::Address_IndirectIndexedY() {
|
||||
auto address = Address_ZeroPageIndirect();
|
||||
const auto address = Address_ZeroPageIndirect();
|
||||
const auto page = address.high;
|
||||
address += Y();
|
||||
return { address, page };
|
||||
return { address + Y(), page };
|
||||
}
|
||||
|
||||
EightBit::register16_t EightBit::MOS6502::Address_relative_byte() {
|
||||
@ -488,7 +485,7 @@ uint8_t EightBit::MOS6502::AM_AbsoluteX(const PageCrossingBehavior behaviour) {
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::AM_AbsoluteY() {
|
||||
const auto[address, page] = Address_AbsoluteY();
|
||||
const auto [address, page] = Address_AbsoluteY();
|
||||
auto possible = getBytePaged(page, address.low);
|
||||
if (UNLIKELY(page != address.high))
|
||||
possible = memoryRead(address);
|
||||
@ -524,13 +521,13 @@ void EightBit::MOS6502::branch(const int condition) {
|
||||
const auto page = PC().high;
|
||||
jump(destination);
|
||||
if (UNLIKELY(PC().high != page))
|
||||
memoryRead(register16_t(PC().low, page));
|
||||
getBytePaged(page, PC().low);
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) {
|
||||
uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) noexcept {
|
||||
|
||||
const auto returned = sub(operand, data, ~P() & CF);
|
||||
|
||||
@ -542,16 +539,16 @@ uint8_t EightBit::MOS6502::sbc(const uint8_t operand, const uint8_t data) {
|
||||
return returned;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::sub(const uint8_t operand, const uint8_t data, const int borrow) {
|
||||
uint8_t EightBit::MOS6502::sub(const uint8_t operand, const uint8_t data, const int borrow) noexcept {
|
||||
return decimal() ? sub_d(operand, data, borrow) : sub_b(operand, data, borrow);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::sub_b(const uint8_t operand, const uint8_t data, const int borrow) {
|
||||
uint8_t EightBit::MOS6502::sub_b(const uint8_t operand, const uint8_t data, const int borrow) noexcept {
|
||||
m_intermediate.word = operand - data - borrow;
|
||||
return m_intermediate.low;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::sub_d(const uint8_t operand, const uint8_t data, const int borrow) {
|
||||
uint8_t EightBit::MOS6502::sub_d(const uint8_t operand, const uint8_t data, const int borrow) noexcept {
|
||||
m_intermediate.word = operand - data - borrow;
|
||||
|
||||
uint8_t low = lowNibble(operand) - lowNibble(data) - borrow;
|
||||
@ -567,17 +564,17 @@ uint8_t EightBit::MOS6502::sub_d(const uint8_t operand, const uint8_t data, cons
|
||||
return promoteNibble(high) | lowNibble(low);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::adc(const uint8_t operand, const uint8_t data) {
|
||||
uint8_t EightBit::MOS6502::adc(const uint8_t operand, const uint8_t data) noexcept {
|
||||
const auto returned = add(operand, data, carry());
|
||||
adjustNZ(m_intermediate.low);
|
||||
return returned;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carry) {
|
||||
uint8_t EightBit::MOS6502::add(uint8_t operand, uint8_t data, int carry) noexcept {
|
||||
return decimal() ? add_d(operand, data, carry) : add_b(operand, data, carry);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) {
|
||||
uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) noexcept {
|
||||
m_intermediate.word = operand + data + carry;
|
||||
|
||||
P() = setBit(P(), VF, ~(operand ^ data) & (operand ^ m_intermediate.low) & NF);
|
||||
@ -586,7 +583,7 @@ uint8_t EightBit::MOS6502::add_b(uint8_t operand, uint8_t data, int carry) {
|
||||
return m_intermediate.low;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) {
|
||||
uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) noexcept {
|
||||
|
||||
m_intermediate.word = operand + data + carry;
|
||||
|
||||
@ -605,36 +602,36 @@ uint8_t EightBit::MOS6502::add_d(uint8_t operand, uint8_t data, int carry) {
|
||||
return promoteNibble(high) | lowNibble(low);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::andr(const uint8_t operand, const uint8_t data) {
|
||||
uint8_t EightBit::MOS6502::andr(const uint8_t operand, const uint8_t data) noexcept {
|
||||
return through(operand & data);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::asl(const uint8_t value) {
|
||||
uint8_t EightBit::MOS6502::asl(const uint8_t value) noexcept {
|
||||
P() = setBit(P(), CF, value & Bit7);
|
||||
return through(value << 1);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) {
|
||||
void EightBit::MOS6502::bit(const uint8_t operand, const uint8_t data) noexcept {
|
||||
P() = setBit(P(), VF, data & VF);
|
||||
adjustZero(operand & data);
|
||||
adjustNegative(data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::cmp(const uint8_t first, const uint8_t second) {
|
||||
void EightBit::MOS6502::cmp(const uint8_t first, const uint8_t second) noexcept {
|
||||
const register16_t result = first - second;
|
||||
adjustNZ(result.low);
|
||||
P() = clearBit(P(), CF, result.high);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::dec(const uint8_t value) {
|
||||
uint8_t EightBit::MOS6502::dec(const uint8_t value) noexcept {
|
||||
return through(value - 1);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::eorr(const uint8_t operand, const uint8_t data) {
|
||||
uint8_t EightBit::MOS6502::eorr(const uint8_t operand, const uint8_t data) noexcept {
|
||||
return through(operand ^ data);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::inc(const uint8_t value) {
|
||||
uint8_t EightBit::MOS6502::inc(const uint8_t value) noexcept {
|
||||
return through(value + 1);
|
||||
}
|
||||
|
||||
@ -646,12 +643,12 @@ void EightBit::MOS6502::jsr() {
|
||||
PC().low = low;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::lsr(const uint8_t value) {
|
||||
uint8_t EightBit::MOS6502::lsr(const uint8_t value) noexcept {
|
||||
P() = setBit(P(), CF, value & Bit0);
|
||||
return through(value >> 1);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::orr(const uint8_t operand, const uint8_t data) {
|
||||
uint8_t EightBit::MOS6502::orr(const uint8_t operand, const uint8_t data) noexcept {
|
||||
return through(operand | data);
|
||||
}
|
||||
|
||||
@ -663,14 +660,14 @@ void EightBit::MOS6502::plp() {
|
||||
P() = (pop() | RF) & ~BF;
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::rol(const uint8_t operand) {
|
||||
uint8_t EightBit::MOS6502::rol(const uint8_t operand) noexcept {
|
||||
const auto carryIn = carry();
|
||||
P() = setBit(P(), CF, operand & Bit7);
|
||||
const uint8_t result = (operand << 1) | carryIn;
|
||||
return through(result);
|
||||
}
|
||||
|
||||
uint8_t EightBit::MOS6502::ror(const uint8_t operand) {
|
||||
uint8_t EightBit::MOS6502::ror(const uint8_t operand) noexcept {
|
||||
const auto carryIn = carry();
|
||||
P() = setBit(P(), CF, operand & Bit0);
|
||||
const uint8_t result = (operand >> 1) | (carryIn << 7);
|
||||
@ -691,24 +688,24 @@ void EightBit::MOS6502::rts() {
|
||||
|
||||
// Undocumented compound instructions
|
||||
|
||||
void EightBit::MOS6502::anc(const uint8_t value) {
|
||||
void EightBit::MOS6502::anc(const uint8_t value) noexcept {
|
||||
A() = andr(A(), value);
|
||||
P() = setBit(P(), CF, A() & Bit7);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::arr(const uint8_t value) {
|
||||
void EightBit::MOS6502::arr(const uint8_t value) noexcept {
|
||||
A() = andr(A(), value);
|
||||
A() = ror(A());
|
||||
P() = setBit(P(), CF, A() & Bit6);
|
||||
P() = setBit(P(), VF, ((A() & Bit6) >> 6) ^((A() & Bit5) >> 5));
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::asr(const uint8_t value) {
|
||||
void EightBit::MOS6502::asr(const uint8_t value) noexcept {
|
||||
A() = andr(A(), value);
|
||||
A() = lsr(A());
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::axs(const uint8_t value) {
|
||||
void EightBit::MOS6502::axs(const uint8_t value) noexcept {
|
||||
X() = through(sub(A() & X(), value));
|
||||
P() = clearBit(P(), CF, m_intermediate.high);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ public:
|
||||
virtual void initialise() final;
|
||||
|
||||
protected:
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) final {
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final {
|
||||
return { m_ram, 0x0000, 0xffff, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,14 @@
|
||||
|
||||
namespace EightBit {
|
||||
class mc6809 : public BigEndianProcessor {
|
||||
public:
|
||||
DECLARE_PIN_INPUT(NMI)
|
||||
DECLARE_PIN_INPUT(FIRQ)
|
||||
DECLARE_PIN_INPUT(HALT)
|
||||
DECLARE_PIN_OUTPUT(BA)
|
||||
DECLARE_PIN_OUTPUT(BS)
|
||||
DECLARE_PIN_OUTPUT(RW)
|
||||
|
||||
public:
|
||||
enum StatusBits {
|
||||
|
||||
@ -89,13 +97,6 @@ namespace EightBit {
|
||||
void halt() noexcept { --PC(); lowerHALT(); }
|
||||
void proceed() noexcept { ++PC(); raiseHALT(); }
|
||||
|
||||
DECLARE_PIN_INPUT(NMI)
|
||||
DECLARE_PIN_INPUT(FIRQ)
|
||||
DECLARE_PIN_INPUT(HALT)
|
||||
DECLARE_PIN_OUTPUT(BA)
|
||||
DECLARE_PIN_OUTPUT(BS)
|
||||
DECLARE_PIN_OUTPUT(RW)
|
||||
|
||||
protected:
|
||||
// Default push/pop handlers
|
||||
|
||||
|
@ -111,7 +111,7 @@ void Board::initialise() {
|
||||
}
|
||||
}
|
||||
|
||||
EightBit::MemoryMapping Board::mapping(uint16_t address) {
|
||||
EightBit::MemoryMapping Board::mapping(uint16_t address) noexcept {
|
||||
|
||||
if (address < 0x8000)
|
||||
return { m_ram, 0x0000, EightBit::Chip::Mask16, EightBit::MemoryMapping::AccessLevel::ReadWrite };
|
||||
|
@ -26,7 +26,7 @@ public:
|
||||
virtual void initialise() final;
|
||||
|
||||
protected:
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) final;
|
||||
virtual EightBit::MemoryMapping mapping(uint16_t address) noexcept final;
|
||||
|
||||
private:
|
||||
const Configuration& m_configuration;
|
||||
|
@ -36,6 +36,6 @@ void Board::initialise() {
|
||||