Implement DIV timer (TBC)

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-08-20 09:52:26 +01:00
parent 75b17e47a8
commit 42b0fdc23d
3 changed files with 44 additions and 12 deletions

View File

@ -103,15 +103,7 @@ 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();
}
}
}
void checkTimers(int cycles);
int timerClockTicks() {
switch (timerClock()) {
@ -141,6 +133,11 @@ namespace EightBit {
return (readRegister(TAC) & Processor::Bit2) == 0;
}
void incrementDIV() {
auto current = readRegister(DIV);
writeRegister(DIV, ++current);
}
void incrementTIMA() {
uint16_t updated = readRegister(TIMA) + 1;
if (updated & Processor::Bit8) {
@ -175,9 +172,13 @@ namespace EightBit {
std::array<uint8_t, 0x100> m_boot;
bool m_disableBootRom;
int m_divCounter;
int m_timerCounter;
int m_timerRate;
void Bus_WrittenByte(const AddressEventArgs& e);
void checkDiv(int cycles);
void checkTimer(int cycles);
};
}

View File

@ -2,7 +2,11 @@
#include "Bus.h"
EightBit::Bus::Bus()
: Memory(0xffff) {
: Memory(0xffff),
m_disableBootRom(false),
m_divCounter(256),
m_timerCounter(0),
m_timerRate(0) {
WrittenByte.connect(std::bind(&Bus::Bus_WrittenByte, this, std::placeholders::_1));
}
@ -45,5 +49,32 @@ void EightBit::Bus::Bus_WrittenByte(const AddressEventArgs& e) {
case BASE + BOOT_DISABLE:
m_disableBootRom = e.getCell() != 0;
break;
case BASE + DIV:
reference() = 0;
m_timerCounter = 0;
break;
}
}
}
void EightBit::Bus::checkTimers(int cycles) {
checkDiv(cycles);
checkTimer(cycles);
}
void EightBit::Bus::checkDiv(int cycles) {
m_divCounter -= cycles;
if (m_divCounter <= 0) {
m_divCounter = 256;
incrementDIV();
}
}
void EightBit::Bus::checkTimer(int cycles) {
if (timerEnabled()) {
m_timerCounter -= cycles;
if (m_timerCounter <= 0) {
m_timerCounter = m_timerRate;
incrementTIMA();
}
}
}

View File

@ -354,7 +354,7 @@ int EightBit::LR35902::run(int limit) {
current += step();
}
m_bus.checkTimer(current);
m_bus.checkTimers(current);
} while (current < limit);
return current;