mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-11 17:29:57 +00:00
First stab at implementing GB timer control.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
0457dffba4
commit
86a4e22ae1
@ -103,6 +103,53 @@ namespace EightBit {
|
||||
return Memory::read(BASE + offset);
|
||||
}
|
||||
|
||||
void checkTimer(int cycles) {
|
||||
if (timerEnabled()) {
|
||||
m_timerCounter -= cycles;
|
||||
if (m_timerCounter <= 0) {
|
||||
m_timerCounter = m_timerRate;
|
||||
incrementTIMA();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int timerClockTicks() {
|
||||
switch (timerClock()) {
|
||||
case 0b00:
|
||||
return 1024; // 4.096 Khz
|
||||
case 0b01:
|
||||
return 16; // 262.144 Khz
|
||||
case 0b10:
|
||||
return 64; // 65.536 Khz
|
||||
case 0b11:
|
||||
return 256; // 16.384 Khz
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
throw std::domain_error("Invalid timer clock specification");
|
||||
}
|
||||
|
||||
int timerClock() {
|
||||
return readRegister(TAC) & Processor::Mask2;
|
||||
}
|
||||
|
||||
bool timerEnabled() {
|
||||
return !timerDisabled();
|
||||
}
|
||||
|
||||
bool timerDisabled() {
|
||||
return (readRegister(TAC) & Processor::Bit2) == 0;
|
||||
}
|
||||
|
||||
void incrementTIMA() {
|
||||
uint16_t updated = readRegister(TIMA) + 1;
|
||||
if (updated & Processor::Bit8) {
|
||||
triggerInterrupt(TimerOverflow);
|
||||
updated = readRegister(TMA);
|
||||
}
|
||||
writeRegister(TIMA, updated & Processor::Mask8);
|
||||
}
|
||||
|
||||
void incrementLY() {
|
||||
writeRegister(LY, (readRegister(LY) + 1) % TotalLineCount);
|
||||
}
|
||||
@ -127,5 +174,10 @@ namespace EightBit {
|
||||
private:
|
||||
std::array<uint8_t, 0x100> m_boot;
|
||||
bool m_disableBootRom;
|
||||
|
||||
int m_timerCounter;
|
||||
int m_timerRate;
|
||||
|
||||
void Bus_WrittenByte(const AddressEventArgs& e);
|
||||
};
|
||||
}
|
@ -35,4 +35,12 @@ uint8_t EightBit::Bus::peek(uint16_t address) const {
|
||||
if (isBootRom(effective))
|
||||
return m_boot[effective];
|
||||
return m_bus[effective];
|
||||
}
|
||||
|
||||
void EightBit::Bus::Bus_WrittenByte(const AddressEventArgs& e) {
|
||||
switch (e.getAddress()) {
|
||||
case EightBit::Bus::BASE + TAC:
|
||||
m_timerRate = timerClockTicks();
|
||||
break;
|
||||
}
|
||||
}
|
@ -354,6 +354,8 @@ int EightBit::LR35902::run(int limit) {
|
||||
current += step();
|
||||
}
|
||||
|
||||
m_bus.checkTimer(current);
|
||||
|
||||
} while (current < limit);
|
||||
return current;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user