mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-23 15:29:24 +00:00
Start a more careful documentation of the I/O registers.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
4cbab14750
commit
73a34f4fae
@ -89,6 +89,24 @@ namespace EightBit {
|
|||||||
Keypad = Processor::Bit3 // Hi-Lo of P10-P13
|
Keypad = Processor::Bit3 // Hi-Lo 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
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LcdStatusMode {
|
||||||
|
CpuAccessAllowed = 0b00,
|
||||||
|
VerticalBlankingPeriod = 0b01,
|
||||||
|
SearchingOamRam = 0b10,
|
||||||
|
TransferringDataToLcd = 0b11
|
||||||
|
};
|
||||||
|
|
||||||
Bus();
|
Bus();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
@ -96,17 +114,25 @@ namespace EightBit {
|
|||||||
virtual void clear() override;
|
virtual void clear() override;
|
||||||
|
|
||||||
void triggerInterrupt(int cause) {
|
void triggerInterrupt(int cause) {
|
||||||
writeRegister(IF, readRegister(IF) | cause);
|
pokeRegister(IF, peekRegister(IF) | cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRegister(int offset, uint8_t content) {
|
void writeRegister(int offset, uint8_t content) {
|
||||||
return Memory::write(BASE + offset, content);
|
Memory::write(BASE + offset, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pokeRegister(int offset, uint8_t content) {
|
||||||
|
poke(BASE + offset, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t readRegister(int offset) {
|
uint8_t readRegister(int offset) {
|
||||||
return Memory::read(BASE + offset);
|
return Memory::read(BASE + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t peekRegister(int offset) {
|
||||||
|
return peek(BASE + offset);
|
||||||
|
}
|
||||||
|
|
||||||
void checkTimers(int cycles);
|
void checkTimers(int cycles);
|
||||||
|
|
||||||
int timerClockTicks() {
|
int timerClockTicks() {
|
||||||
@ -126,7 +152,7 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int timerClock() {
|
int timerClock() {
|
||||||
return readRegister(TAC) & Processor::Mask2;
|
return peekRegister(TAC) & Processor::Mask2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool timerEnabled() {
|
bool timerEnabled() {
|
||||||
@ -134,29 +160,29 @@ namespace EightBit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool timerDisabled() {
|
bool timerDisabled() {
|
||||||
return (readRegister(TAC) & Processor::Bit2) == 0;
|
return (peekRegister(TAC) & Processor::Bit2) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void incrementDIV() {
|
void incrementDIV() {
|
||||||
auto current = readRegister(DIV);
|
auto current = peekRegister(DIV);
|
||||||
writeRegister(DIV, ++current);
|
pokeRegister(DIV, ++current);
|
||||||
}
|
}
|
||||||
|
|
||||||
void incrementTIMA() {
|
void incrementTIMA() {
|
||||||
uint16_t updated = readRegister(TIMA) + 1;
|
uint16_t updated = peekRegister(TIMA) + 1;
|
||||||
if (updated & Processor::Bit8) {
|
if (updated & Processor::Bit8) {
|
||||||
triggerInterrupt(TimerOverflow);
|
triggerInterrupt(TimerOverflow);
|
||||||
updated = readRegister(TMA);
|
updated = peekRegister(TMA);
|
||||||
}
|
}
|
||||||
writeRegister(TIMA, updated & Processor::Mask8);
|
pokeRegister(TIMA, updated & Processor::Mask8);
|
||||||
}
|
}
|
||||||
|
|
||||||
void incrementLY() {
|
void incrementLY() {
|
||||||
writeRegister(LY, (readRegister(LY) + 1) % TotalLineCount);
|
pokeRegister(LY, (peekRegister(LY) + 1) % TotalLineCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetLY() {
|
void resetLY() {
|
||||||
writeRegister(LY, 0);
|
pokeRegister(LY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void disableBootRom() { m_disableBootRom = true; }
|
void disableBootRom() { m_disableBootRom = true; }
|
||||||
|
@ -21,8 +21,8 @@ EightBit::Bus::Bus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::reset() {
|
void EightBit::Bus::reset() {
|
||||||
writeRegister(NR52, 0xf1);
|
pokeRegister(NR52, 0xf1);
|
||||||
writeRegister(LCDC, 0x91);
|
pokeRegister(LCDC, DisplayBackground | BackgroundCharacterDataSelection | LcdEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EightBit::Bus::clear() {
|
void EightBit::Bus::clear() {
|
||||||
@ -102,16 +102,63 @@ void EightBit::Bus::Bus_WrittenByte(const AddressEventArgs& e) {
|
|||||||
|
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
switch (address) {
|
switch (address) {
|
||||||
case BASE + TAC:
|
|
||||||
m_timerRate = timerClockTicks();
|
case BASE + SB: // R/W
|
||||||
|
case BASE + SC: // R/W
|
||||||
break;
|
break;
|
||||||
case BASE + BOOT_DISABLE:
|
|
||||||
m_disableBootRom = value != 0;
|
case BASE + DIV: // R/W
|
||||||
break;
|
|
||||||
case BASE + DIV:
|
|
||||||
Memory::reference() = 0;
|
Memory::reference() = 0;
|
||||||
m_timerCounter = 0;
|
m_timerCounter = 0;
|
||||||
break;
|
break;
|
||||||
|
case BASE + TIMA: // R/W
|
||||||
|
case BASE + TMA: // R/W
|
||||||
|
break;
|
||||||
|
case BASE + TAC: // R/W
|
||||||
|
m_timerRate = timerClockTicks();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BASE + IF: // R/W
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BASE + NR10:
|
||||||
|
case BASE + NR11:
|
||||||
|
case BASE + NR12:
|
||||||
|
case BASE + NR13:
|
||||||
|
case BASE + NR14:
|
||||||
|
case BASE + NR22:
|
||||||
|
case BASE + NR24:
|
||||||
|
case BASE + NR30:
|
||||||
|
case BASE + NR42:
|
||||||
|
case BASE + NR44:
|
||||||
|
case BASE + NR50:
|
||||||
|
case BASE + NR51:
|
||||||
|
case BASE + NR52:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BASE + LCDC:
|
||||||
|
case BASE + STAT:
|
||||||
|
case BASE + SCY:
|
||||||
|
case BASE + SCX:
|
||||||
|
case BASE + DMA:
|
||||||
|
break;
|
||||||
|
case BASE + LY: // R/O
|
||||||
|
Memory::reference() = 0;
|
||||||
|
break;
|
||||||
|
case BASE + BGP:
|
||||||
|
case BASE + OBP0:
|
||||||
|
case BASE + OBP1:
|
||||||
|
case BASE + WY:
|
||||||
|
case BASE + WX:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BASE + BOOT_DISABLE:
|
||||||
|
m_disableBootRom = value != 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if ((address > BASE) && (address < (BASE + 0x4c)))
|
||||||
|
assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,14 +332,14 @@ void EightBit::LR35902::ccf(uint8_t& a, uint8_t& f) {
|
|||||||
int EightBit::LR35902::run(int limit) {
|
int EightBit::LR35902::run(int limit) {
|
||||||
int current = 0;
|
int current = 0;
|
||||||
do {
|
do {
|
||||||
auto interruptEnable = m_bus.readRegister(Bus::IE);
|
auto interruptEnable = m_bus.peekRegister(Bus::IE);
|
||||||
auto interruptFlags = m_bus.readRegister(Bus::IF);
|
auto interruptFlags = m_bus.peekRegister(Bus::IF);
|
||||||
auto ime = IME();
|
auto ime = IME();
|
||||||
|
|
||||||
auto masked = interruptEnable & interruptFlags;
|
auto masked = interruptEnable & interruptFlags;
|
||||||
if (masked) {
|
if (masked) {
|
||||||
if (ime) {
|
if (ime) {
|
||||||
m_bus.writeRegister(Bus::IF, 0);
|
m_bus.pokeRegister(Bus::IF, 0);
|
||||||
} else {
|
} else {
|
||||||
if (isHalted())
|
if (isHalted())
|
||||||
proceed();
|
proceed();
|
||||||
|
Loading…
Reference in New Issue
Block a user