mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-03-13 07:33:34 +00:00
Use simpler LR35902 CPU/render sequence.
Signed-off-by: Adrian Conlon <Adrian.conlon@gmail.com>
This commit is contained in:
parent
43cf7e523b
commit
3a49a9cc59
@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user