PPU: Fixed mirroring behavior when vram address is over $7FFF

Prevents graphical glitches in Lemmings 2 (which appeared because the game uses addresses over $7FFF, which loaded random data outside the vram buffer)
This commit is contained in:
Sour 2020-05-26 18:10:19 -04:00
parent eceb8d790b
commit 2a6504c2d4
2 changed files with 7 additions and 7 deletions

View file

@ -189,7 +189,7 @@ void Ppu::GetTilemapData(uint8_t layerIndex, uint8_t columnIndex)
/* The tilemap address to read the tile data from */
uint16_t addr = baseOffset + (column & 0x1F) + (config.DoubleWidth ? (column & 0x20) << 5 : 0);
_layerData[layerIndex].Tiles[columnIndex].TilemapData = _vram[addr];
_layerData[layerIndex].Tiles[columnIndex].TilemapData = _vram[addr & 0x7FFF];
_layerData[layerIndex].Tiles[columnIndex].VScroll = vScroll;
}
@ -244,7 +244,7 @@ void Ppu::GetHorizontalOffsetByte(uint8_t columnIndex)
uint16_t columnOffset = (((columnIndex << 3) + (_state.Layers[2].HScroll & ~0x07)) >> 3) & (_state.Layers[2].DoubleWidth ? 0x3F : 0x1F);
uint16_t rowOffset = (_state.Layers[2].VScroll >> 3) & (_state.Layers[2].DoubleHeight ? 0x3F : 0x1F);
_hOffset = _vram[_state.Layers[2].TilemapAddress + columnOffset + (rowOffset << 5)];
_hOffset = _vram[(_state.Layers[2].TilemapAddress + columnOffset + (rowOffset << 5)) & 0x7FFF];
}
void Ppu::GetVerticalOffsetByte(uint8_t columnIndex)
@ -257,7 +257,7 @@ void Ppu::GetVerticalOffsetByte(uint8_t columnIndex)
//The vertical offset is 0x40 bytes later - but wraps around within the tilemap based on the tilemap size (0x800 or 0x1000 bytes)
uint16_t vOffsetAddr = _state.Layers[2].TilemapAddress + ((tileOffset + 0x20) & (_state.Layers[2].DoubleHeight ? 0x7FF : 0x3FF));
_vOffset = _vram[vOffsetAddr];
_vOffset = _vram[vOffsetAddr & 0x7FFF];
}
void Ppu::FetchTileData()
@ -706,8 +706,8 @@ void Ppu::FetchSpriteAttributes(uint16_t oamAddress)
uint8_t row = (tileRow + rowOffset) & 0x0F;
uint8_t columnOffset = _currentSprite.HorizontalMirror ? _currentSprite.ColumnOffset : (columnCount - _currentSprite.ColumnOffset - 1);
uint8_t tileIndex = (row << 4) | ((tileColumn + columnOffset) & 0x0F);
uint16_t tileStart = (_state.OamBaseAddress + (tileIndex << 4) + (useSecondTable ? _state.OamAddressOffset : 0)) & 0x7FFF;
_currentSprite.FetchAddress = tileStart + yOffset;
uint16_t tileStart = (_state.OamBaseAddress + (tileIndex << 4) + (useSecondTable ? _state.OamAddressOffset : 0));
_currentSprite.FetchAddress = (tileStart + yOffset) & 0x7FFF;
int16_t x = _currentSprite.X == -256 ? 0 : _currentSprite.X;
int16_t endTileX = x + ((columnCount - _currentSprite.ColumnOffset - 1) << 3) + 8;
@ -727,7 +727,7 @@ void Ppu::FetchSpriteTile(bool secondCycle)
_currentSprite.ChrData[secondCycle] = chrData;
if(!secondCycle) {
_currentSprite.FetchAddress += 8;
_currentSprite.FetchAddress = (_currentSprite.FetchAddress + 8) & 0x7FFF;
} else {
int16_t xPos = _currentSprite.DrawX;
for(int x = 0; x < 8; x++) {

View file

@ -271,7 +271,7 @@ namespace Mesen.GUI.Debugger
LayerConfig layer = _state.Layers[_options.Layer];
int addrVerticalScrollingOffset = layer.DoubleHeight ? ((row & 0x20) << (layer.DoubleWidth ? 6 : 5)) : 0;
int baseOffset = layer.TilemapAddress + addrVerticalScrollingOffset + ((row & 0x1F) << 5);
int address = (baseOffset + (column & 0x1F) + (layer.DoubleWidth ? ((column & 0x20) << 5) : 0)) << 1;
int address = ((baseOffset + (column & 0x1F) + (layer.DoubleWidth ? ((column & 0x20) << 5) : 0)) << 1) & 0xFFFF;
int value = _vram[address] | (_vram[address + 1] << 8);
//Selected tile