Use simpler LR35902 CPU/render sequence.

Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
Adrian Conlon 2019-11-18 00:54:52 +00:00
parent 43cf7e523b
commit 3a49a9cc59
2 changed files with 22 additions and 28 deletions

View File

@ -55,8 +55,8 @@ namespace EightBit {
void loadBootRom(const std::string& path); void loadBootRom(const std::string& path);
void loadGameRom(const std::string& path); void loadGameRom(const std::string& path);
int runRasterLines(); void runRasterLines();
int runVerticalBlankLines(); void runVerticalBlankLines();
protected: protected:
virtual MemoryMapping mapping(uint16_t address) override; virtual MemoryMapping mapping(uint16_t address) override;
@ -90,13 +90,15 @@ namespace EightBit {
int m_romBank = 1; int m_romBank = 1;
int m_ramBank = 0; int m_ramBank = 0;
int m_allowed = 0;
void validateCartridgeType(); void validateCartridgeType();
void Bus_WrittenByte(EightBit::EventArgs); void Bus_WrittenByte(EightBit::EventArgs);
int runRasterLines(int lines); void runRasterLines(int lines);
int runVerticalBlankLines(int lines); void runVerticalBlankLines(int lines);
int runRasterLine(int limit); void runRasterLine(int suggested);
}; };
} }
} }

View File

@ -191,24 +191,18 @@ EightBit::MemoryMapping EightBit::GameBoy::Bus::mapping(uint16_t address) {
return { m_highInternalRam, 0xff80, 0xffff, MemoryMapping::AccessLevel::ReadWrite }; return { m_highInternalRam, 0xff80, 0xffff, MemoryMapping::AccessLevel::ReadWrite };
} }
int EightBit::GameBoy::Bus::runRasterLines() { void EightBit::GameBoy::Bus::runRasterLines() {
m_enabledLCD = !!(IO().peek(IoRegisters::LCDC) & IoRegisters::LcdEnable); m_enabledLCD = !!(IO().peek(IoRegisters::LCDC) & IoRegisters::LcdEnable);
IO().resetLY(); IO().resetLY();
return runRasterLines(Display::RasterHeight); runRasterLines(Display::RasterHeight);
} }
int EightBit::GameBoy::Bus::runRasterLines(int lines) { void EightBit::GameBoy::Bus::runRasterLines(int lines) {
int count = 0; for (int line = 0; line < lines; ++line)
int allowed = CyclesPerLine; runRasterLine(CyclesPerLine);
for (int line = 0; line < lines; ++line) {
auto executed = runRasterLine(allowed);
count += executed;
allowed = CyclesPerLine - (executed - CyclesPerLine);
}
return count;
} }
int EightBit::GameBoy::Bus::runRasterLine(int limit) { void EightBit::GameBoy::Bus::runRasterLine(int suggested) {
/* /*
A scanline normally takes 456 clocks (912 clocks in double speed A scanline normally takes 456 clocks (912 clocks in double speed
@ -233,7 +227,7 @@ int EightBit::GameBoy::Bus::runRasterLine(int limit) {
The rest of the clocks of line 153 are spent in line 0 in mode 1! The rest of the clocks of line 153 are spent in line 0 in mode 1!
*/ */
int count = 0; m_allowed += suggested;
if (m_enabledLCD) { if (m_enabledLCD) {
if ((IO().peek(IoRegisters::STAT) & Chip::Bit6) && (IO().peek(IoRegisters::LYC) == IO().peek(IoRegisters::LY))) if ((IO().peek(IoRegisters::STAT) & Chip::Bit6) && (IO().peek(IoRegisters::LYC) == IO().peek(IoRegisters::LY)))
@ -243,32 +237,30 @@ int EightBit::GameBoy::Bus::runRasterLine(int limit) {
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::SearchingOamRam); IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::SearchingOamRam);
if (IO().peek(IoRegisters::STAT) & Chip::Bit5) if (IO().peek(IoRegisters::STAT) & Chip::Bit5)
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus); IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
count += CPU().run(80); // ~19us m_allowed -= CPU().run(80); // ~19us
// Mode 3, OAM/VRAM unavailable // Mode 3, OAM/VRAM unavailable
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::TransferringDataToLcd); IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::TransferringDataToLcd);
count += CPU().run(170); // ~41us m_allowed -= CPU().run(170); // ~41us
// Mode 0 // Mode 0
IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::HBlank); IO().updateLcdStatusMode(IoRegisters::LcdStatusMode::HBlank);
if (IO().peek(IoRegisters::STAT) & Chip::Bit3) if (IO().peek(IoRegisters::STAT) & Chip::Bit3)
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus); IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
count += CPU().run(limit - count); // ~48.6us m_allowed -= CPU().run(m_allowed); // ~48.6us
IO().incrementLY(); IO().incrementLY();
} else { } else {
count += CPU().run(CyclesPerLine); m_allowed -= CPU().run(CyclesPerLine);
} }
return count;
} }
int EightBit::GameBoy::Bus::runVerticalBlankLines() { void EightBit::GameBoy::Bus::runVerticalBlankLines() {
const auto lines = TotalLineCount - Display::RasterHeight; const auto lines = TotalLineCount - Display::RasterHeight;
return runVerticalBlankLines(lines); runVerticalBlankLines(lines);
} }
int EightBit::GameBoy::Bus::runVerticalBlankLines(int lines) { void EightBit::GameBoy::Bus::runVerticalBlankLines(int lines) {
/* /*
Vertical Blank interrupt is triggered when the LCD Vertical Blank interrupt is triggered when the LCD
@ -293,5 +285,5 @@ int EightBit::GameBoy::Bus::runVerticalBlankLines(int lines) {
IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus); IO().triggerInterrupt(IoRegisters::Interrupts::DisplayControlStatus);
IO().triggerInterrupt(IoRegisters::Interrupts::VerticalBlank); IO().triggerInterrupt(IoRegisters::Interrupts::VerticalBlank);
} }
return runRasterLines(lines); runRasterLines(lines);
} }