6539b92502
Memory handlers did not have the _memoryType value set, which caused some memory accesses to be much faster than expected
111 lines
No EOL
2.6 KiB
C++
111 lines
No EOL
2.6 KiB
C++
#pragma once
|
|
#include "stdafx.h"
|
|
#include "IMemoryHandler.h"
|
|
#include "Sa1Cpu.h"
|
|
#include "Sa1Types.h"
|
|
#include "Sa1.h"
|
|
|
|
//Manages BWRAM access from the SA-1 CPU, for regions that can enable bitmap mode. e.g:
|
|
//00-3F:6000-7FFF + 80-BF:6000-7FFF (optional bitmap mode + bank select)
|
|
//60-6F:0000-FFFF (always bitmap mode)
|
|
class Sa1BwRamHandler : public IMemoryHandler
|
|
{
|
|
private:
|
|
uint8_t * _ram;
|
|
uint32_t _mask;
|
|
Sa1State* _state;
|
|
|
|
uint32_t GetBwRamAddress(uint32_t addr)
|
|
{
|
|
return ((_state->Sa1BwBank * 0x2000) | (addr & 0x1FFF));
|
|
}
|
|
|
|
__forceinline uint8_t InternalRead(uint32_t addr)
|
|
{
|
|
if((addr & 0x600000) == 0x600000) {
|
|
return ReadBitmapMode(addr - 0x600000);
|
|
} else {
|
|
addr = GetBwRamAddress(addr);
|
|
if(_state->Sa1BwMode) {
|
|
//Bitmap mode is enabled
|
|
return ReadBitmapMode(addr);
|
|
} else {
|
|
//Return regular memory content
|
|
return _ram[addr & _mask];
|
|
}
|
|
}
|
|
}
|
|
|
|
public:
|
|
Sa1BwRamHandler(uint8_t* bwRam, uint32_t bwRamSize, Sa1State* state) : IMemoryHandler(SnesMemoryType::SaveRam)
|
|
{
|
|
_ram = bwRam;
|
|
_mask = bwRamSize - 1;
|
|
_state = state;
|
|
}
|
|
|
|
uint8_t Read(uint32_t addr) override
|
|
{
|
|
return InternalRead(addr);
|
|
}
|
|
|
|
uint8_t Peek(uint32_t addr) override
|
|
{
|
|
return InternalRead(addr);
|
|
}
|
|
|
|
void PeekBlock(uint32_t addr, uint8_t *output) override
|
|
{
|
|
for(int i = 0; i < 0x1000; i++) {
|
|
output[i] = InternalRead(addr + i);
|
|
}
|
|
}
|
|
|
|
void Write(uint32_t addr, uint8_t value) override
|
|
{
|
|
if((addr & 0x600000) == 0x600000) {
|
|
WriteBitmapMode(addr - 0x600000, value);
|
|
} else {
|
|
addr = GetBwRamAddress(addr);
|
|
if(_state->Sa1BwMode) {
|
|
WriteBitmapMode(addr, value);
|
|
} else {
|
|
_ram[addr & _mask] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
uint8_t ReadBitmapMode(uint32_t addr)
|
|
{
|
|
if(_state->BwRam2BppMode) {
|
|
return (_ram[(addr >> 2) & _mask] >> ((addr & 0x03) * 2)) & 0x03;
|
|
} else {
|
|
return (_ram[(addr >> 1) & _mask] >> ((addr & 0x01) * 4)) & 0x0F;
|
|
}
|
|
}
|
|
|
|
void WriteBitmapMode(uint32_t addr, uint8_t value)
|
|
{
|
|
if(_state->BwRam2BppMode) {
|
|
uint8_t shift = (addr & 0x03) * 2;
|
|
addr = (addr >> 2) & _mask;
|
|
_ram[addr] = (_ram[addr] & ~(0x03 << shift)) | ((value & 0x03) << shift);
|
|
} else {
|
|
uint8_t shift = (addr & 0x01) * 4;
|
|
addr = (addr >> 1) & _mask;
|
|
_ram[addr] = (_ram[addr] & ~(0x0F << shift)) | ((value & 0x0F) << shift);
|
|
}
|
|
}
|
|
|
|
AddressInfo GetAbsoluteAddress(uint32_t addr) override
|
|
{
|
|
AddressInfo info;
|
|
if((addr & 0x600000) == 0x600000) {
|
|
info.Address = ((addr - 0x600000) >> (_state->BwRam2BppMode ? 2 : 1)) & _mask;
|
|
} else {
|
|
info.Address = GetBwRamAddress(addr) & _mask;
|
|
}
|
|
info.Type = SnesMemoryType::SaveRam;
|
|
return info;
|
|
}
|
|
}; |