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
};
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();
void reset();
@ -96,17 +114,25 @@ namespace EightBit {
virtual void clear() override;
void triggerInterrupt(int cause) {
writeRegister(IF, readRegister(IF) | cause);
pokeRegister(IF, peekRegister(IF) | cause);
}
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) {
return Memory::read(BASE + offset);
}
uint8_t peekRegister(int offset) {
return peek(BASE + offset);
}
void checkTimers(int cycles);
int timerClockTicks() {
@ -126,7 +152,7 @@ namespace EightBit {
}
int timerClock() {
return readRegister(TAC) & Processor::Mask2;
return peekRegister(TAC) & Processor::Mask2;
}
bool timerEnabled() {
@ -134,29 +160,29 @@ namespace EightBit {
}
bool timerDisabled() {
return (readRegister(TAC) & Processor::Bit2) == 0;
return (peekRegister(TAC) & Processor::Bit2) == 0;
}
void incrementDIV() {
auto current = readRegister(DIV);
writeRegister(DIV, ++current);
auto current = peekRegister(DIV);
pokeRegister(DIV, ++current);
}
void incrementTIMA() {
uint16_t updated = readRegister(TIMA) + 1;
uint16_t updated = peekRegister(TIMA) + 1;
if (updated & Processor::Bit8) {
triggerInterrupt(TimerOverflow);
updated = readRegister(TMA);
updated = peekRegister(TMA);
}
writeRegister(TIMA, updated & Processor::Mask8);
pokeRegister(TIMA, updated & Processor::Mask8);
}
void incrementLY() {
writeRegister(LY, (readRegister(LY) + 1) % TotalLineCount);
pokeRegister(LY, (peekRegister(LY) + 1) % TotalLineCount);
}
void resetLY() {
writeRegister(LY, 0);
pokeRegister(LY, 0);
}
void disableBootRom() { m_disableBootRom = true; }

View File

@ -21,8 +21,8 @@ EightBit::Bus::Bus()
}
void EightBit::Bus::reset() {
writeRegister(NR52, 0xf1);
writeRegister(LCDC, 0x91);
pokeRegister(NR52, 0xf1);
pokeRegister(LCDC, DisplayBackground | BackgroundCharacterDataSelection | LcdEnable);
}
void EightBit::Bus::clear() {
@ -102,16 +102,63 @@ void EightBit::Bus::Bus_WrittenByte(const AddressEventArgs& e) {
if (!handled) {
switch (address) {
case BASE + TAC:
m_timerRate = timerClockTicks();
case BASE + SB: // R/W
case BASE + SC: // R/W
break;
case BASE + BOOT_DISABLE:
m_disableBootRom = value != 0;
break;
case BASE + DIV:
case BASE + DIV: // R/W
Memory::reference() = 0;
m_timerCounter = 0;
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 current = 0;
do {
auto interruptEnable = m_bus.readRegister(Bus::IE);
auto interruptFlags = m_bus.readRegister(Bus::IF);
auto interruptEnable = m_bus.peekRegister(Bus::IE);
auto interruptFlags = m_bus.peekRegister(Bus::IF);
auto ime = IME();
auto masked = interruptEnable & interruptFlags;
if (masked) {
if (ime) {
m_bus.writeRegister(Bus::IF, 0);
m_bus.pokeRegister(Bus::IF, 0);
} else {
if (isHalted())
proceed();