Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
I wrote a game boy emulator in C99 that works and a lot of games can play just fine, including sound.
But there are a few issues and one issue that particular bugs me is that i want to show the background-map in my editor, while running the game - seeing the actual viewport.
I already implemented this and it works great for a lot of games (Super Mario Land 2, R-Type, Mega-Man to name a few).
But not for "Super Mario Land 1"! The Game somehow resets the SCX and SCY register to zero after the frame is rendered - so when i use SCX and SCY to compute the viewport rectangles, it will always be zero or has the correct value, but then gets reset on the next frame - so it flickers around.
Other emulators such as BGB works just fine and displays the background-map with the viewport properly.
My implementation of this stores the current SCX/SCY values into separate fields that are updated, after the frame is rendered.
A frame is rendered when the PPU is in mode VBlank and LY is >= 154:
static void fgb__PPUModeVerticalBlank(fgbGameboy *gameboy) {
fgbPPU *ppu = &gameboy->ppu;
fgbLCDRegister *lcd = &ppu->lcd;
if (ppu->lineTicks >= FGB__PPU_HORIZONTAL_BLANK_DOTS) {
fgb__PPUIncrementLine(gameboy);
if (lcd->ly >= FGB__PPU_VERTICAL_BLANK_LINE_COUNT) {
fgb__PPUSetMode(gameboy, lcd, fgbPPUMode_OAMSearch);
fgb__PPUResetLine(gameboy);
fgb__PPUStatusInterruptTest(gameboy, false);
ppu->frameCount++;
ppu->isFrameFinished = true;
// Store scroll register for rendering the background-map viewport
ppu->backgroundMap.scrollX = ppu->lcd.scx;
ppu->backgroundMap.scrollY = ppu->lcd.scy;
fgb__Breakpoint(gameboy, fgbBreakpointType_PPUFrameEnd);
}
ppu->lineTicks = 0;
}
}I assume that the problem is, that the registers are set by the game - but it should not should not.
So my question is, when are the game allowed to update the SCX/SCY register and when is it not allowed?
Or do i have to save the SCX/SCY registers much earlier?
My implementation for the SCX/SCY bus read/write is really simple:
static uint8_t fgb__PPULCDRegisterRead(uint16_t address) {
switch (address) {
...
case 0xFF42:
return lcd->scy;
case 0xFF43:
return lcd->scx;
...
}
}
static void fgb__PPULCDRegisterWrite(const uint16_t address, uint8_t value) {
switch (address) {
...
case 0xFF42:
lcd->scy = value;
break;
case 0xFF43:
lcd->scx = value;
break;
...
}
}Offline
Ignore it... writing this post actually fixed it for me, because i simply moved the "frame finished" to the mode HBlank when LY >= 144.
This works correctly ![]()
Offline