void Tima::setTac(unsigned const data, unsigned long const cc, TimaInterruptRequester timaIrq) { if (tac_ ^ data) { unsigned long nextIrqEventTime = timaIrq.nextIrqEventTime(); if (tac_ & 0x04) { updateIrq(cc, timaIrq); updateTima(cc); // FIXME: this looks naive. // TODO: more TIMA tests. lastUpdate_ -= (1u << (timaClock[tac_ & 3] - 1)) + 3; tmatime_ -= (1u << (timaClock[tac_ & 3] - 1)) + 3; nextIrqEventTime -= (1u << (timaClock[tac_ & 3] - 1)) + 3; if (cc >= nextIrqEventTime) timaIrq.flagIrq(); updateTima(cc); tmatime_ = disabled_time; nextIrqEventTime = disabled_time; } if (data & 4) { lastUpdate_ = (cc >> timaClock[data & 3]) << timaClock[data & 3]; nextIrqEventTime = lastUpdate_ + ((256u - tima_) << timaClock[data & 3]) + 3; }
void Tima::setTac(const unsigned data, const unsigned long cycleCounter, const TimaInterruptRequester timaIrq) { if (tac_ ^ data) { unsigned long nextIrqEventTime = timaIrq.nextIrqEventTime(); if (tac_ & 0x04) { updateIrq(cycleCounter, timaIrq); updateTima(cycleCounter); lastUpdate_ -= (1u << (timaClock[tac_ & 3] - 1)) + 3; tmatime_ -= (1u << (timaClock[tac_ & 3] - 1)) + 3; nextIrqEventTime -= (1u << (timaClock[tac_ & 3] - 1)) + 3; if (cycleCounter >= nextIrqEventTime) timaIrq.flagIrq(); updateTima(cycleCounter); tmatime_ = DISABLED_TIME; nextIrqEventTime = DISABLED_TIME; } if (data & 4) { lastUpdate_ = (cycleCounter >> timaClock[data & 3]) << timaClock[data & 3]; nextIrqEventTime = lastUpdate_ + ((256u - tima_) << timaClock[data & 3]) + 3; }
void Tima::resetCc(unsigned long const oldCc, unsigned long const newCc, TimaInterruptRequester timaIrq) { if (tac_ & 0x04) { updateIrq(oldCc, timaIrq); updateTima(oldCc); unsigned long const dec = oldCc - newCc; lastUpdate_ -= dec; timaIrq.setNextIrqEventTime(timaIrq.nextIrqEventTime() - dec); if (tmatime_ != disabled_time) tmatime_ -= dec; } }
void Tima::resetCc(const unsigned long oldCc, const unsigned long newCc, const TimaInterruptRequester timaIrq) { const unsigned long dec = oldCc - newCc; if (tac_ & 0x04) { updateIrq(oldCc, timaIrq); updateTima(oldCc); lastUpdate_ -= dec; timaIrq.setNextIrqEventTime(timaIrq.nextIrqEventTime() - dec); if (tmatime_ != DISABLED_TIME) tmatime_ -= dec; } }
void Tima::setTima(unsigned const data, unsigned long const cc, TimaInterruptRequester timaIrq) { if (tac_ & 0x04) { updateIrq(cc, timaIrq); updateTima(cc); if (tmatime_ - cc < 4) tmatime_ = disabled_time; timaIrq.setNextIrqEventTime(lastUpdate_ + ((256u - data) << timaClock[tac_ & 3]) + 3); } tima_ = data; }
void Tima::setTima(const unsigned data, const unsigned long cycleCounter, const TimaInterruptRequester timaIrq) { if (tac_ & 0x04) { updateIrq(cycleCounter, timaIrq); updateTima(cycleCounter); if (tmatime_ - cycleCounter < 4) tmatime_ = DISABLED_TIME; timaIrq.setNextIrqEventTime(lastUpdate_ + ((256u - data) << timaClock[tac_ & 3]) + 3); } tima_ = data; }
void Tima::loadState(SaveState const &state, TimaInterruptRequester timaIrq) { lastUpdate_ = state.mem.timaLastUpdate; tmatime_ = state.mem.tmatime; tima_ = state.mem.ioamhram.get()[0x105]; tma_ = state.mem.ioamhram.get()[0x106]; tac_ = state.mem.ioamhram.get()[0x107]; unsigned long nextIrqEventTime = disabled_time; if (tac_ & 4) { nextIrqEventTime = tmatime_ != disabled_time && tmatime_ > state.cpu.cycleCounter ? tmatime_ : lastUpdate_ + ((256u - tima_) << timaClock[tac_ & 3]) + 3; } timaIrq.setNextIrqEventTime(nextIrqEventTime); }
void Tima::loadState(const SaveState &state, const TimaInterruptRequester timaIrq) { lastUpdate_ = state.mem.timaLastUpdate; tmatime_ = state.mem.tmatime; tima_ = state.mem.ioamhram.get()[0x105]; tma_ = state.mem.ioamhram.get()[0x106]; tac_ = state.mem.ioamhram.get()[0x107]; timaIrq.setNextIrqEventTime((tac_ & 4) ? (tmatime_ != DISABLED_TIME && tmatime_ > state.cpu.cycleCounter ? tmatime_ : lastUpdate_ + ((256u - tima_) << timaClock[tac_ & 3]) + 3) : static_cast<unsigned long>(DISABLED_TIME) ); }