mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-23 00:29:47 +00:00
Refactor bit set/get routines from processor class to lower level chip class.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
de5a9963e0
commit
8d3551e681
@ -448,11 +448,11 @@ std::string EightBit::Disassembler::flags(uint8_t value) {
|
||||
output
|
||||
<< flag(value, Intel8080::SF, "S")
|
||||
<< flag(value, Intel8080::ZF, "Z")
|
||||
<< flag(value, Processor::Bit5, "1", "0")
|
||||
<< flag(value, Chip::Bit5, "1", "0")
|
||||
<< flag(value, Intel8080::AC, "A")
|
||||
<< flag(value, Processor::Bit3, "1", "0")
|
||||
<< flag(value, Chip::Bit3, "1", "0")
|
||||
<< flag(value, Intel8080::PF, "P")
|
||||
<< flag(value, Processor::Bit1, "1", "0")
|
||||
<< flag(value, Chip::Bit1, "1", "0")
|
||||
<< flag(value, Intel8080::CF, "C");
|
||||
return output.str();
|
||||
}
|
||||
|
@ -80,22 +80,22 @@ namespace EightBit {
|
||||
|
||||
// IF and IE flags
|
||||
enum Interrupts {
|
||||
VerticalBlank = Processor::Bit0, // VBLANK
|
||||
DisplayControlStatus = Processor::Bit1, // LCDC Status
|
||||
TimerOverflow = Processor::Bit2, // Timer Overflow
|
||||
SerialTransfer = Processor::Bit3, // Serial Transfer
|
||||
KeypadPressed = Processor::Bit4 // Hi-Lo transition of P10-P13
|
||||
VerticalBlank = Chip::Bit0, // VBLANK
|
||||
DisplayControlStatus = Chip::Bit1, // LCDC Status
|
||||
TimerOverflow = Chip::Bit2, // Timer Overflow
|
||||
SerialTransfer = Chip::Bit3, // Serial Transfer
|
||||
KeypadPressed = Chip::Bit4 // Hi-Lo transition of P10-P13
|
||||
};
|
||||
|
||||
enum LcdcControl {
|
||||
DisplayBackground = Processor::Bit0,
|
||||
ObjectEnable = Processor::Bit1,
|
||||
ObjectBlockCompositionSelection = Processor::Bit2,
|
||||
BackgroundCodeAreaSelection = Processor::Bit3,
|
||||
BackgroundCharacterDataSelection = Processor::Bit4,
|
||||
WindowEnable = Processor::Bit5,
|
||||
WindowCodeAreaSelection = Processor::Bit6,
|
||||
LcdEnable = Processor::Bit7
|
||||
DisplayBackground = Chip::Bit0,
|
||||
ObjectEnable = Chip::Bit1,
|
||||
ObjectBlockCompositionSelection = Chip::Bit2,
|
||||
BackgroundCodeAreaSelection = Chip::Bit3,
|
||||
BackgroundCharacterDataSelection = Chip::Bit4,
|
||||
WindowEnable = Chip::Bit5,
|
||||
WindowCodeAreaSelection = Chip::Bit6,
|
||||
LcdEnable = Chip::Bit7
|
||||
};
|
||||
|
||||
enum LcdStatusMode {
|
||||
|
@ -19,13 +19,13 @@ namespace EightBit {
|
||||
uint8_t pattern() const { return m_pattern; }
|
||||
uint8_t flags() const { return m_flags; }
|
||||
|
||||
uint8_t priority() const { return flags() & Processor::Bit7; }
|
||||
uint8_t priority() const { return flags() & Chip::Bit7; }
|
||||
|
||||
bool highPriority() const { return !!priority(); }
|
||||
bool lowPriority() const { return !priority(); }
|
||||
bool flipY() const { return !!(flags() & Processor::Bit6); }
|
||||
bool flipX() const { return !!(flags() & Processor::Bit5); }
|
||||
int palette() const { return (flags() & Processor::Bit4) >> 3; }
|
||||
bool flipY() const { return !!(flags() & Chip::Bit6); }
|
||||
bool flipX() const { return !!(flags() & Chip::Bit5); }
|
||||
int palette() const { return (flags() & Chip::Bit4) >> 3; }
|
||||
|
||||
private:
|
||||
uint8_t m_positionY;
|
||||
|
@ -539,10 +539,10 @@ std::string EightBit::GameBoy::Disassembler::flags(uint8_t value) {
|
||||
<< flag(value, LR35902::NF, "N")
|
||||
<< flag(value, LR35902::HC, "H")
|
||||
<< flag(value, LR35902::CF, "C")
|
||||
<< flag(value, EightBit::Processor::Bit3, "+")
|
||||
<< flag(value, EightBit::Processor::Bit2, "+")
|
||||
<< flag(value, EightBit::Processor::Bit1, "+")
|
||||
<< flag(value, EightBit::Processor::Bit0, "+");
|
||||
<< flag(value, EightBit::Chip::Bit3, "+")
|
||||
<< flag(value, EightBit::Chip::Bit2, "+")
|
||||
<< flag(value, EightBit::Chip::Bit1, "+")
|
||||
<< flag(value, EightBit::Chip::Bit0, "+");
|
||||
return output.str();
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ void EightBit::GameBoy::Bus::Bus_WrittenByte(EightBit::EventArgs) {
|
||||
if (m_banked && m_higherRomBank) {
|
||||
assert((address >= 0x2000) && (address < 0x4000));
|
||||
assert((value > 0) && (value < 0x20));
|
||||
m_romBank = value & Processor::Mask5;
|
||||
m_romBank = value & Chip::Mask5;
|
||||
}
|
||||
break;
|
||||
case 0x4000:
|
||||
@ -69,7 +69,7 @@ void EightBit::GameBoy::Bus::Bus_WrittenByte(EightBit::EventArgs) {
|
||||
case 0x6000:
|
||||
// Register 3: ROM/RAM change
|
||||
if (m_banked) {
|
||||
switch (value & Processor::Mask1) {
|
||||
switch (value & Chip::Mask1) {
|
||||
case 0:
|
||||
m_higherRomBank = true;
|
||||
m_ramBankSwitching = false;
|
||||
@ -236,12 +236,12 @@ int EightBit::GameBoy::Bus::runRasterLine(int limit) {
|
||||
int count = 0;
|
||||
if (m_enabledLCD) {
|
||||
|
||||
if ((IO().peek(IoRegisters::STAT) & Processor::Bit6) && (IO().peek(IoRegisters::LYC) == IO().peek(IoRegisters::LY)))
|
||||
if ((IO().peek(IoRegisters::STAT) & Chip::Bit6) && (IO().peek(IoRegisters::LYC) == IO().peek(IoRegisters::LY)))
|
||||
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
|
||||
|
||||
// Mode 2, OAM unavailable
|
||||
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::SearchingOamRam);
|
||||
if (IO().peek(IoRegisters::STAT) & Processor::Bit5)
|
||||
if (IO().peek(IoRegisters::STAT) & Chip::Bit5)
|
||||
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
|
||||
count += CPU().run(80); // ~19us
|
||||
|
||||
@ -251,7 +251,7 @@ int EightBit::GameBoy::Bus::runRasterLine(int limit) {
|
||||
|
||||
// Mode 0
|
||||
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::HBlank);
|
||||
if (IO().peek(IoRegisters::STAT) & Processor::Bit3)
|
||||
if (IO().peek(IoRegisters::STAT) & Chip::Bit3)
|
||||
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
|
||||
count += CPU().run(limit - count); // ~48.6us
|
||||
|
||||
@ -289,7 +289,7 @@ int EightBit::GameBoy::Bus::runVerticalBlankLines(int lines) {
|
||||
|
||||
if (m_enabledLCD) {
|
||||
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::VBlank);
|
||||
if (IO().peek(IoRegisters::STAT) & Processor::Bit4)
|
||||
if (IO().peek(IoRegisters::STAT) & Chip::Bit4)
|
||||
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
|
||||
IO().triggerInterrupt(IoRegisters::Interrupts::VerticalBlank);
|
||||
}
|
||||
|
@ -44,14 +44,14 @@ void EightBit::GameBoy::IoRegisters::Bus_ReadingByte(EightBit::EventArgs) {
|
||||
| ((int)!p11 << 1)
|
||||
| ((int)!p12 << 2)
|
||||
| ((int)!p13 << 3)
|
||||
| Processor::Bit4 | Processor::Bit5
|
||||
| Processor::Bit6 | Processor::Bit7);
|
||||
| Chip::Bit4 | Chip::Bit5
|
||||
| Chip::Bit6 | Chip::Bit7);
|
||||
}
|
||||
break;
|
||||
case SB:
|
||||
break;
|
||||
case SC:
|
||||
mask(port, Processor::Bit7 | Processor::Bit0);
|
||||
mask(port, Chip::Bit7 | Chip::Bit0);
|
||||
break;
|
||||
|
||||
// Timer control
|
||||
@ -60,19 +60,19 @@ void EightBit::GameBoy::IoRegisters::Bus_ReadingByte(EightBit::EventArgs) {
|
||||
case TMA:
|
||||
break;
|
||||
case TAC:
|
||||
mask(port, Processor::Mask3);
|
||||
mask(port, Chip::Mask3);
|
||||
break;
|
||||
|
||||
// Interrupt Flags
|
||||
case IF:
|
||||
mask(port, Processor::Mask5);
|
||||
mask(port, Chip::Mask5);
|
||||
break;
|
||||
|
||||
// LCD Display Registers
|
||||
case LCDC:
|
||||
break;
|
||||
case STAT:
|
||||
mask(port, Processor::Mask7);
|
||||
mask(port, Chip::Mask7);
|
||||
break;
|
||||
case SCY:
|
||||
case SCX:
|
||||
@ -102,8 +102,8 @@ void EightBit::GameBoy::IoRegisters::Bus_WrittenByte(EightBit::EventArgs) {
|
||||
switch (port) {
|
||||
|
||||
case P1:
|
||||
m_scanP14 = (value & Processor::Bit4) == 0;
|
||||
m_scanP15 = (value & Processor::Bit5) == 0;
|
||||
m_scanP14 = (value & Chip::Bit4) == 0;
|
||||
m_scanP15 = (value & Chip::Bit5) == 0;
|
||||
break;
|
||||
|
||||
case SB: // R/W
|
||||
@ -181,7 +181,7 @@ int EightBit::GameBoy::IoRegisters::timerClockTicks() {
|
||||
}
|
||||
|
||||
int EightBit::GameBoy::IoRegisters::timerClock() {
|
||||
return peek(TAC) & Processor::Mask2;
|
||||
return peek(TAC) & Chip::Mask2;
|
||||
}
|
||||
|
||||
bool EightBit::GameBoy::IoRegisters::timerEnabled() {
|
||||
@ -189,7 +189,7 @@ bool EightBit::GameBoy::IoRegisters::timerEnabled() {
|
||||
}
|
||||
|
||||
bool EightBit::GameBoy::IoRegisters::timerDisabled() {
|
||||
return (peek(TAC) & Processor::Bit2) == 0;
|
||||
return (peek(TAC) & Chip::Bit2) == 0;
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::IoRegisters::incrementDIV(int cycles) {
|
||||
@ -199,11 +199,11 @@ void EightBit::GameBoy::IoRegisters::incrementDIV(int cycles) {
|
||||
|
||||
void EightBit::GameBoy::IoRegisters::incrementTIMA() {
|
||||
uint16_t updated = peek(TIMA) + 1;
|
||||
if (updated & Processor::Bit8) {
|
||||
if (updated & Chip::Bit8) {
|
||||
triggerInterrupt(TimerOverflow);
|
||||
updated = peek(TMA);
|
||||
}
|
||||
poke(TIMA, updated & Processor::Mask8);
|
||||
poke(TIMA, updated & Chip::Mask8);
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::IoRegisters::incrementLY() {
|
||||
@ -215,7 +215,7 @@ void EightBit::GameBoy::IoRegisters::resetLY() {
|
||||
}
|
||||
|
||||
void EightBit::GameBoy::IoRegisters::updateLcdStatusMode(int mode) {
|
||||
const auto current = peek(STAT) & ~Processor::Mask2;
|
||||
const auto current = peek(STAT) & ~Chip::Mask2;
|
||||
poke(STAT, current | mode);
|
||||
DisplayStatusModeUpdated.fire(mode);
|
||||
}
|
||||
|
@ -655,16 +655,16 @@ std::string EightBit::Disassembly::Address_indexed(std::string mnemomic) {
|
||||
std::ostringstream output;
|
||||
|
||||
const auto type = getByte(++m_address);
|
||||
const auto r = RR((type & (Processor::Bit6 | Processor::Bit5)) >> 5);
|
||||
const auto r = RR((type & (Chip::Bit6 | Chip::Bit5)) >> 5);
|
||||
|
||||
uint8_t byte = 0xff;
|
||||
uint16_t word = 0xffff;
|
||||
|
||||
output << dump_ByteValue(type);
|
||||
|
||||
if (type & Processor::Bit7) {
|
||||
const auto indirect = type & Processor::Bit4;
|
||||
switch (type & Processor::Mask4) {
|
||||
if (type & Chip::Bit7) {
|
||||
const auto indirect = type & Chip::Bit4;
|
||||
switch (type & Chip::Mask4) {
|
||||
case 0b0000: // ,R+
|
||||
output
|
||||
<< "\t" << mnemomic << "\t"
|
||||
@ -749,7 +749,7 @@ std::string EightBit::Disassembly::Address_indexed(std::string mnemomic) {
|
||||
// EA = ,R + 5-bit offset
|
||||
output
|
||||
<< "\t" << mnemomic << "\t"
|
||||
<< (int)Processor::signExtend(5, type & Processor::Mask5) << "," << r;
|
||||
<< (int)Processor::signExtend(5, type & Chip::Mask5) << "," << r;
|
||||
}
|
||||
|
||||
return output.str();
|
||||
@ -858,14 +858,14 @@ std::string EightBit::Disassembly::tfr(std::string mnemomic) {
|
||||
std::ostringstream output;
|
||||
|
||||
const auto data = getByte(++m_address);
|
||||
const auto reg1 = Processor::highNibble(data);
|
||||
const auto reg2 = Processor::lowNibble(data);
|
||||
const auto reg1 = Chip::highNibble(data);
|
||||
const auto reg2 = Chip::lowNibble(data);
|
||||
|
||||
output
|
||||
<< dump_ByteValue(data)
|
||||
<< "\t" << mnemomic << "\t";
|
||||
|
||||
const bool type8 = !!(reg1 & Processor::Bit3); // 8 bit?
|
||||
const bool type8 = !!(reg1 & Chip::Bit3); // 8 bit?
|
||||
if (type8)
|
||||
output << referenceTransfer8(reg1) << "," << referenceTransfer8(reg2);
|
||||
else
|
||||
|
@ -39,7 +39,7 @@ void Board::initialise() {
|
||||
}
|
||||
|
||||
void Board::Cpu_ExecutingInstruction_Cpm(EightBit::Z80& cpu) {
|
||||
if (UNLIKELY(EightBit::Processor::lowered(cpu.HALT())))
|
||||
if (UNLIKELY(EightBit::Chip::lowered(cpu.HALT())))
|
||||
CPU().powerOff();
|
||||
switch (cpu.PC().word) {
|
||||
case 0x0: // CP/M warm start
|
||||
|
11
inc/Chip.h
11
inc/Chip.h
@ -48,6 +48,17 @@ namespace EightBit {
|
||||
Low, High
|
||||
};
|
||||
|
||||
static void clearFlag(uint8_t& f, const int flag) { f &= ~flag; }
|
||||
static void setFlag(uint8_t& f, const int flag) { f |= flag; }
|
||||
|
||||
static void setFlag(uint8_t& f, const int flag, const int condition) { setFlag(f, flag, !!condition); }
|
||||
static void setFlag(uint8_t& f, const int flag, const uint32_t condition) { setFlag(f, flag, !!condition); }
|
||||
static void setFlag(uint8_t& f, const int flag, const bool condition) { condition ? setFlag(f, flag) : clearFlag(f, flag); }
|
||||
|
||||
static void clearFlag(uint8_t& f, const int flag, const int condition) { clearFlag(f, flag, !!condition); }
|
||||
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) { clearFlag(f, flag, !!condition); }
|
||||
static void clearFlag(uint8_t& f, const int flag, const bool condition) { setFlag(f, flag, !condition); }
|
||||
|
||||
static bool raised(const PinLevel line) { return line == High; }
|
||||
static void raise(PinLevel& line) { line = High; }
|
||||
static bool lowered(const PinLevel line) { return line == Low; }
|
||||
|
@ -11,17 +11,6 @@
|
||||
namespace EightBit {
|
||||
class Processor : public Chip {
|
||||
public:
|
||||
static void clearFlag(uint8_t& f, const int flag) { f &= ~flag; }
|
||||
static void setFlag(uint8_t& f, const int flag) { f |= flag; }
|
||||
|
||||
static void setFlag(uint8_t& f, const int flag, const int condition) { setFlag(f, flag, !!condition); }
|
||||
static void setFlag(uint8_t& f, const int flag, const uint32_t condition) { setFlag(f, flag, !!condition); }
|
||||
static void setFlag(uint8_t& f, const int flag, const bool condition) { condition ? setFlag(f, flag) : clearFlag(f, flag); }
|
||||
|
||||
static void clearFlag(uint8_t& f, const int flag, const int condition) { clearFlag(f, flag, !!condition); }
|
||||
static void clearFlag(uint8_t& f, const int flag, const uint32_t condition) { clearFlag(f, flag, !!condition); }
|
||||
static void clearFlag(uint8_t& f, const int flag, const bool condition) { setFlag(f, flag, !condition); }
|
||||
|
||||
// b: number of bits representing the number in x
|
||||
// x: sign extend this b-bit number to r
|
||||
static int8_t signExtend(int b, uint8_t x);
|
||||
|
Loading…
Reference in New Issue
Block a user