timing: added support for PAL timing

This commit is contained in:
Jakub Czekański 2021-10-19 01:16:36 +02:00
parent f8609f2eae
commit 4ef44fb086
5 changed files with 37 additions and 10 deletions

View file

@ -786,6 +786,20 @@ void GPU::writeGP1(uint32_t data) {
}
}
float GPU::cyclesPerLine() const {
if (isNtsc())
return timing::CYCLES_PER_LINE_NTSC;
else
return timing::CYCLES_PER_LINE_PAL;
}
int GPU::linesPerFrame() const {
if (isNtsc())
return timing::LINES_TOTAL_NTSC;
else
return timing::LINES_TOTAL_PAL;
}
bool GPU::emulateGpuCycles(int cycles) {
gpuDot += cycles;
@ -794,7 +808,7 @@ bool GPU::emulateGpuCycles(int cycles) {
gpuDot %= 3413;
gpuLine += newLines;
if (gpuLine < timing::LINE_VBLANK_START_NTSC - 1) {
if (gpuLine < linesPerFrame() - 20 - 1) {
if (gp1_08.verticalResolution == GP1_08::VerticalResolution::r480 && gp1_08.interlace) {
odd = (frames % 2) != 0;
} else {
@ -804,7 +818,7 @@ bool GPU::emulateGpuCycles(int cycles) {
odd = false;
}
if (gpuLine == timing::LINES_TOTAL_NTSC - 1) {
if (gpuLine == linesPerFrame() - 1) {
gpuLine = 0;
frames++;
return true;
@ -825,7 +839,7 @@ bool GPU::insideDrawingArea(int x, int y) const {
&& (y < VRAM_HEIGHT);
}
bool GPU::isNtsc() { return forceNtsc || gp1_08.videoMode == GP1_08::VideoMode::ntsc; }
bool GPU::isNtsc() const { return forceNtsc || gp1_08.videoMode == GP1_08::VideoMode::ntsc; }
void GPU::dumpVram() {
const char* dumpName = "vram.png";

View file

@ -132,6 +132,9 @@ class GPU {
uint32_t readVramData();
uint32_t getStat();
float cyclesPerLine() const;
int linesPerFrame() const;
public:
GPU(System* sys);
~GPU();
@ -139,7 +142,7 @@ class GPU {
bool emulateGpuCycles(int cycles);
uint32_t read(uint32_t address);
void write(uint32_t address, uint32_t data);
bool isNtsc();
bool isNtsc() const;
int minDrawingX(int x) const;
int minDrawingY(int y) const;

View file

@ -41,7 +41,7 @@ double limitFramerate(bool framelimiter, bool ntsc) {
double currentTime = SDL_GetPerformanceCounter() / counterFrequency;
double deltaTime = currentTime - startTime;
double frameTime = ntsc ? (1.0 / timing::NTSC_FRAMERATE) : (1.0 / 50.0);
double frameTime = ntsc ? (1.0 / timing::NTSC_FRAMERATE) : (1.0 / timing::PAL_FRAMERATE);
if (framelimiter && deltaTime < frameTime) {
// If deltaTime was shorter than frameTime - spin

View file

@ -409,7 +409,7 @@ void System::emulateFrame() {
}
// TODO: Move this code to Timer class
if (gpu->gpuLine > timing::LINE_VBLANK_START_NTSC) {
if (gpu->gpuLine > gpu->linesPerFrame() - 20) {
auto& t = *timer[1];
if (t.mode.syncEnabled) {
using modes = device::timer::CounterMode::SyncMode1;

View file

@ -6,11 +6,21 @@ constexpr uint64_t US_IN_SECOND = 1'000'000;
constexpr uint64_t CPU_CLOCK = 33'868'800; // 44100 * 768
constexpr uint64_t GPU_CLOCK = 53'222'400;
// NTSC
const float DOTS_TOTAL = 3413.6f;
const int LINE_VBLANK_START_NTSC = 243;
//#define USE_EXACT_FPS
#ifdef USE_EXACT_FPS
const float CYCLES_PER_LINE_NTSC = 3413.6f;
const float CYCLES_PER_LINE_PAL = 3406.1f;
const int LINES_TOTAL_NTSC = 263;
const float NTSC_FRAMERATE = (float)GPU_CLOCK / (DOTS_TOTAL * LINES_TOTAL_NTSC);
const int LINES_TOTAL_PAL = 314;
#else
const float CYCLES_PER_LINE_NTSC = 3372;
const float CYCLES_PER_LINE_PAL = 3389;
const int LINES_TOTAL_NTSC = 263;
const int LINES_TOTAL_PAL = 314;
#endif
const float NTSC_FRAMERATE = (float)GPU_CLOCK / (CYCLES_PER_LINE_NTSC * LINES_TOTAL_NTSC);
const float PAL_FRAMERATE = (float)GPU_CLOCK / (CYCLES_PER_LINE_PAL * LINES_TOTAL_PAL);
constexpr uint64_t usToCpuCycles(uint64_t us) { return us * CPU_CLOCK / US_IN_SECOND; }
} // namespace timing