107 lines
1.6 KiB
Dart
107 lines
1.6 KiB
Dart
import 'package:dartboy/emulator/utils.dart';
|
|
|
|
enum _Clock {
|
|
clock4096,
|
|
clock262144,
|
|
clock65536,
|
|
clock16384,
|
|
}
|
|
|
|
class Timer {
|
|
int _counter = 0;
|
|
int _tima = 0;
|
|
int _tma = 0;
|
|
bool _enable = false;
|
|
_Clock _clock = _Clock.clock4096;
|
|
bool _prev = false;
|
|
|
|
bool interrupt = false;
|
|
|
|
void _sync() {
|
|
var cur = false;
|
|
|
|
if (_enable) {
|
|
int mask;
|
|
switch (_clock) {
|
|
case _Clock.clock4096:
|
|
mask = 1 << 9;
|
|
break;
|
|
|
|
case _Clock.clock262144:
|
|
mask = 1 << 3;
|
|
break;
|
|
|
|
case _Clock.clock65536:
|
|
mask = 1 << 5;
|
|
break;
|
|
|
|
case _Clock.clock16384:
|
|
mask = 1 << 7;
|
|
break;
|
|
}
|
|
|
|
cur = _counter & mask > 0;
|
|
}
|
|
|
|
if (_prev && !cur) {
|
|
_tima = _tima.wrappingAddU8(1);
|
|
|
|
if (_counter % 4 == 0 && _tima == 0) {
|
|
_tima = _tma;
|
|
interrupt = true;
|
|
}
|
|
}
|
|
|
|
_prev = cur;
|
|
}
|
|
|
|
void tick() {
|
|
_counter = _counter.wrappingAddU16(1);
|
|
|
|
_sync();
|
|
}
|
|
|
|
int readDiv() => (_counter >> 8).toU8();
|
|
|
|
void writeDiv(int _) {
|
|
_counter = 0;
|
|
}
|
|
|
|
int readTima() => _tima;
|
|
|
|
void writeTima(int val) {
|
|
_sync();
|
|
|
|
_tima = val;
|
|
}
|
|
|
|
int readTma() => _tma;
|
|
|
|
void writeTma(int val) {
|
|
_tma = val;
|
|
|
|
_sync();
|
|
}
|
|
|
|
int readTac() {
|
|
return bitpack([
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
_enable,
|
|
isSet(_clock.index, 1),
|
|
isSet(_clock.index, 0)
|
|
]);
|
|
}
|
|
|
|
void writeTac(int val) {
|
|
_enable = isSet(val, 2);
|
|
|
|
final index = val & 3;
|
|
|
|
_clock = _Clock.values[index];
|
|
}
|
|
}
|