Start a more careful documentation of the I/O registers.

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-08-26 09:46:53 +01:00
parent 4cbab14750
commit 73a34f4fae
3 changed files with 95 additions and 22 deletions

View File

@ -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; }

View File

@ -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);
} }
} }
} }

View File

@ -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();