mirror of
https://github.com/libretro/Mesen.git
synced 2025-01-21 00:04:24 +00:00
-Fixed timing issues (with sprite DMA) + a bit of refactoring
-PPU is now run AFTER a read/write, instead of before. (And the CPU class is in charge of running it, instead of the MemoryManager class)
This commit is contained in:
parent
f3df2ecf17
commit
7cf5dafc40
16
Core/CPU.cpp
16
Core/CPU.cpp
@ -118,24 +118,28 @@ void CPU::EndFrame()
|
||||
_cycleCount = 0;
|
||||
}
|
||||
|
||||
void CPU::IncCycleCount()
|
||||
{
|
||||
PPU::ExecStatic();
|
||||
_cycleCount++;
|
||||
}
|
||||
|
||||
void CPU::RunDMATransfer(uint8_t* spriteRAM, uint32_t &spriteRamAddr, uint8_t offsetValue)
|
||||
{
|
||||
//"the DMA procedure takes 513 CPU cycles (+1 on odd CPU cycles)"
|
||||
if((CPU::GetRelativeCycleCount() + Instance->_cycleCount) % 2 != 0) {
|
||||
Instance->_cycleCount++;
|
||||
Instance->IncCycleCount();
|
||||
}
|
||||
Instance->_cycleCount++;
|
||||
Instance->IncCycleCount();
|
||||
|
||||
//DMA transfer starts at SpriteRamAddr and wraps around
|
||||
for(int i = 0; i < 0x100; i++) {
|
||||
//Read value
|
||||
uint8_t readValue = Instance->_memoryManager->Read(offsetValue*0x100 + i);
|
||||
Instance->_cycleCount++;
|
||||
uint8_t readValue = Instance->MemoryRead(offsetValue * 0x100 + i);
|
||||
|
||||
//Write to ram
|
||||
spriteRAM[(spriteRamAddr+i) & 0xFF] = readValue;
|
||||
PPU::ExecStatic();
|
||||
Instance->_cycleCount++;
|
||||
Instance->IncCycleCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
23
Core/CPU.h
23
Core/CPU.h
@ -2,6 +2,7 @@
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "PPU.h"
|
||||
#include "Snapshotable.h"
|
||||
|
||||
namespace PSFlags
|
||||
@ -74,18 +75,16 @@ private:
|
||||
bool _runNMI = false;
|
||||
bool _runIRQ = false;
|
||||
|
||||
void IncCycleCount();
|
||||
|
||||
uint8_t GetOPCode()
|
||||
{
|
||||
uint8_t value = _memoryManager->Read(_state.PC, true);
|
||||
_cycleCount++;
|
||||
_state.PC++;
|
||||
return value;
|
||||
return MemoryRead(_state.PC++, true);
|
||||
}
|
||||
|
||||
void DummyRead()
|
||||
{
|
||||
_memoryManager->Read(_state.PC, false);
|
||||
_cycleCount++;
|
||||
MemoryRead(_state.PC);
|
||||
}
|
||||
|
||||
uint8_t ReadByte()
|
||||
@ -139,19 +138,19 @@ private:
|
||||
void MemoryWrite(uint16_t addr, uint8_t value)
|
||||
{
|
||||
_memoryManager->Write(addr, value);
|
||||
_cycleCount++;
|
||||
IncCycleCount();
|
||||
}
|
||||
|
||||
uint8_t MemoryRead(uint16_t addr) {
|
||||
uint8_t MemoryRead(uint16_t addr, bool forExecute = false) {
|
||||
uint8_t value = _memoryManager->Read(addr);
|
||||
_cycleCount++;
|
||||
IncCycleCount();
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t MemoryReadWord(uint16_t addr) {
|
||||
uint16_t value = _memoryManager->ReadWord(addr);
|
||||
_cycleCount+=2;
|
||||
return value;
|
||||
uint8_t lo = MemoryRead(addr);
|
||||
uint8_t hi = MemoryRead(addr + 1);
|
||||
return lo | hi << 8;
|
||||
}
|
||||
|
||||
void SetRegister(uint8_t ®, uint8_t value) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "BaseMapper.h"
|
||||
#include "PPU.h"
|
||||
#include "Debugger.h"
|
||||
|
||||
MemoryManager::MemoryManager(shared_ptr<BaseMapper> mapper)
|
||||
@ -109,12 +108,12 @@ uint8_t MemoryManager::Read(uint16_t addr, bool forExecution)
|
||||
Debugger::CheckBreakpoint(forExecution ? BreakpointType::Execute : BreakpointType::Read, addr);
|
||||
|
||||
uint8_t value;
|
||||
PPU::ExecStatic();
|
||||
if(addr <= 0x1FFF) {
|
||||
value = _internalRAM[addr & 0x07FF];
|
||||
} else {
|
||||
value = ReadRegister(addr);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -122,7 +121,6 @@ void MemoryManager::Write(uint16_t addr, uint8_t value)
|
||||
{
|
||||
Debugger::CheckBreakpoint(BreakpointType::Write, addr);
|
||||
|
||||
PPU::ExecStatic();
|
||||
if(addr <= 0x1FFF) {
|
||||
_internalRAM[addr & 0x07FF] = value;
|
||||
} else {
|
||||
@ -130,13 +128,6 @@ void MemoryManager::Write(uint16_t addr, uint8_t value)
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t MemoryManager::ReadWord(uint16_t addr)
|
||||
{
|
||||
uint8_t lo = Read(addr);
|
||||
uint8_t hi = Read(addr+1);
|
||||
return lo | hi << 8;
|
||||
}
|
||||
|
||||
uint8_t MemoryManager::ReadVRAM(uint16_t addr)
|
||||
{
|
||||
addr &= 0x3FFF;
|
||||
|
@ -48,7 +48,6 @@ class MemoryManager: public Snapshotable
|
||||
uint8_t* GetInternalRAM();
|
||||
|
||||
uint8_t Read(uint16_t addr, bool forExecution = false);
|
||||
uint16_t ReadWord(uint16_t addr);
|
||||
void Write(uint16_t addr, uint8_t value);
|
||||
|
||||
uint8_t ReadVRAM(uint16_t addr);
|
||||
|
@ -459,7 +459,7 @@ void PPU::ProcessPrerenderScanline()
|
||||
{
|
||||
ProcessPreVBlankScanline();
|
||||
|
||||
if(_cycle == 1) {
|
||||
if(_cycle == 0) {
|
||||
_statusFlags.SpriteOverflow = false;
|
||||
_statusFlags.Sprite0Hit = false;
|
||||
_statusFlags.VerticalBlank = false;
|
||||
@ -601,7 +601,7 @@ void PPU::CopyOAMData()
|
||||
|
||||
void PPU::BeginVBlank()
|
||||
{
|
||||
if(_cycle == 1) {
|
||||
if(_cycle == 0) {
|
||||
if(!_doNotSetVBFlag) {
|
||||
_statusFlags.VerticalBlank = true;
|
||||
if(_flags.VBlank) {
|
||||
|
@ -95,7 +95,6 @@ class PPU : public IMemoryHandler, public Snapshotable
|
||||
int32_t _scanline = 0;
|
||||
uint32_t _cycle = 0;
|
||||
uint32_t _frameCount = 0;
|
||||
int32_t _cycleCount = 0;
|
||||
uint8_t _memoryReadBuffer = 0;
|
||||
|
||||
uint8_t _paletteRAM[0x100];
|
||||
|
Loading…
x
Reference in New Issue
Block a user