BS-X: General fixes/improvements
This commit is contained in:
parent
b29fabbb57
commit
393a8f3b38
8 changed files with 88 additions and 42 deletions
|
@ -439,7 +439,7 @@ void BaseCartridge::InitCoprocessor()
|
||||||
_coprocessor.reset(new Spc7110(_console, _hasRtc));
|
_coprocessor.reset(new Spc7110(_console, _hasRtc));
|
||||||
} else if(_coprocessorType == CoprocessorType::Satellaview) {
|
} else if(_coprocessorType == CoprocessorType::Satellaview) {
|
||||||
//Share save file across all .bs files that use the BS-X bios
|
//Share save file across all .bs files that use the BS-X bios
|
||||||
_console->GetBatteryManager()->Initialize("bsxbios");
|
_console->GetBatteryManager()->Initialize("BsxBios");
|
||||||
|
|
||||||
if(!_bsxMemPack) {
|
if(!_bsxMemPack) {
|
||||||
//Create an empty memory pack if the BIOS was loaded directly (instead of a .bs file)
|
//Create an empty memory pack if the BIOS was loaded directly (instead of a .bs file)
|
||||||
|
|
|
@ -140,11 +140,13 @@ uint8_t BsxMemoryPack::BsxMemoryPackHandler::Read(uint32_t addr)
|
||||||
|
|
||||||
void BsxMemoryPack::BsxMemoryPackHandler::Write(uint32_t addr, uint8_t value)
|
void BsxMemoryPack::BsxMemoryPackHandler::Write(uint32_t addr, uint8_t value)
|
||||||
{
|
{
|
||||||
if(addr == 0xC00000) {
|
if(_memPack->_writeByte) {
|
||||||
|
if(!_memPack->_writeProtect) {
|
||||||
|
uint8_t currentByte = RamHandler::Read(addr);
|
||||||
|
RamHandler::Write(addr, value & currentByte);
|
||||||
|
}
|
||||||
|
_memPack->_writeByte = false;
|
||||||
|
} else if(addr == 0xC00000) {
|
||||||
_memPack->ProcessCommand(value, _page);
|
_memPack->ProcessCommand(value, _page);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!_memPack->_writeProtect) {
|
|
||||||
RamHandler::Write(addr, value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "BsxSatellaview.h"
|
#include "BsxSatellaview.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
|
#include "MemoryManager.h"
|
||||||
#include "EmuSettings.h"
|
#include "EmuSettings.h"
|
||||||
#include "../Utilities/Serializer.h"
|
#include "../Utilities/Serializer.h"
|
||||||
|
|
||||||
BsxSatellaview::BsxSatellaview(Console* console, IMemoryHandler* bBusHandler)
|
BsxSatellaview::BsxSatellaview(Console* console, IMemoryHandler* bBusHandler)
|
||||||
{
|
{
|
||||||
|
_console = console;
|
||||||
|
_memoryManager = console->GetMemoryManager().get();
|
||||||
_customDate = console->GetSettings()->GetEmulationConfig().BsxCustomDate;
|
_customDate = console->GetSettings()->GetEmulationConfig().BsxCustomDate;
|
||||||
_bBusHandler = bBusHandler;
|
_bBusHandler = bBusHandler;
|
||||||
Reset();
|
Reset();
|
||||||
|
@ -13,10 +16,20 @@ BsxSatellaview::BsxSatellaview(Console* console, IMemoryHandler* bBusHandler)
|
||||||
|
|
||||||
void BsxSatellaview::Reset()
|
void BsxSatellaview::Reset()
|
||||||
{
|
{
|
||||||
|
_prevMasterClock = 0;
|
||||||
_streamReg = 0;
|
_streamReg = 0;
|
||||||
_extOutput = 0xFF;
|
_extOutput = 0xFF;
|
||||||
_stream[0].Reset(_customDate);
|
|
||||||
_stream[1].Reset(_customDate);
|
time_t resetDate;
|
||||||
|
if(_customDate >= 0) {
|
||||||
|
resetDate = (time_t)_customDate;
|
||||||
|
} else {
|
||||||
|
//Use the current date/time as the BS-X date/time
|
||||||
|
time(&resetDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream[0].Reset(_console, resetDate);
|
||||||
|
_stream[1].Reset(_console, resetDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t BsxSatellaview::Read(uint32_t addr)
|
uint8_t BsxSatellaview::Read(uint32_t addr)
|
||||||
|
@ -24,6 +37,8 @@ uint8_t BsxSatellaview::Read(uint32_t addr)
|
||||||
addr &= 0xFFFF;
|
addr &= 0xFFFF;
|
||||||
if(addr >= 0x2188 && addr <= 0x219F) {
|
if(addr >= 0x2188 && addr <= 0x219F) {
|
||||||
//Handle BS-X $2188-219F registers
|
//Handle BS-X $2188-219F registers
|
||||||
|
ProcessClocks();
|
||||||
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x2188: return _stream[0].GetChannel() & 0xFF;
|
case 0x2188: return _stream[0].GetChannel() & 0xFF;
|
||||||
case 0x2189: return (_stream[0].GetChannel()) >> 8;
|
case 0x2189: return (_stream[0].GetChannel()) >> 8;
|
||||||
|
@ -58,6 +73,8 @@ void BsxSatellaview::Write(uint32_t addr, uint8_t value)
|
||||||
addr &= 0xFFFF;
|
addr &= 0xFFFF;
|
||||||
if(addr >= 0x2188 && addr <= 0x219F) {
|
if(addr >= 0x2188 && addr <= 0x219F) {
|
||||||
//Handle BS-X register writes
|
//Handle BS-X register writes
|
||||||
|
ProcessClocks();
|
||||||
|
|
||||||
switch(addr) {
|
switch(addr) {
|
||||||
case 0x2188: _stream[0].SetChannelLow(value); break;
|
case 0x2188: _stream[0].SetChannelLow(value); break;
|
||||||
case 0x2189: _stream[0].SetChannelHigh(value); break;
|
case 0x2189: _stream[0].SetChannelHigh(value); break;
|
||||||
|
@ -78,6 +95,25 @@ void BsxSatellaview::Write(uint32_t addr, uint8_t value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BsxSatellaview::ProcessClocks()
|
||||||
|
{
|
||||||
|
if(_stream[0].NeedUpdate() || _stream[1].NeedUpdate()) {
|
||||||
|
uint64_t gap = _memoryManager->GetMasterClock() - _prevMasterClock;
|
||||||
|
|
||||||
|
while(gap >= 288 * 2) {
|
||||||
|
bool needUpdate = _stream[0].FillQueues() || _stream[1].FillQueues();
|
||||||
|
if(!needUpdate) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gap -= 288 * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
_prevMasterClock = _memoryManager->GetMasterClock() - gap;
|
||||||
|
} else {
|
||||||
|
_prevMasterClock = _memoryManager->GetMasterClock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t BsxSatellaview::Peek(uint32_t addr)
|
uint8_t BsxSatellaview::Peek(uint32_t addr)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -95,7 +131,7 @@ AddressInfo BsxSatellaview::GetAbsoluteAddress(uint32_t address)
|
||||||
|
|
||||||
void BsxSatellaview::Serialize(Serializer& s)
|
void BsxSatellaview::Serialize(Serializer& s)
|
||||||
{
|
{
|
||||||
s.Stream(_extOutput, _streamReg);
|
s.Stream(_extOutput, _streamReg, _customDate, _prevMasterClock);
|
||||||
s.Stream(&_stream[0]);
|
s.Stream(&_stream[0]);
|
||||||
s.Stream(&_stream[1]);
|
s.Stream(&_stream[1]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,17 +5,24 @@
|
||||||
#include "../Utilities/ISerializable.h"
|
#include "../Utilities/ISerializable.h"
|
||||||
|
|
||||||
class Console;
|
class Console;
|
||||||
|
class MemoryManager;
|
||||||
|
|
||||||
class BsxSatellaview : public IMemoryHandler, public ISerializable
|
class BsxSatellaview : public IMemoryHandler, public ISerializable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
IMemoryHandler* _bBusHandler;
|
IMemoryHandler* _bBusHandler;
|
||||||
|
Console* _console;
|
||||||
|
MemoryManager* _memoryManager;
|
||||||
|
|
||||||
BsxStream _stream[2];
|
BsxStream _stream[2];
|
||||||
uint8_t _streamReg;
|
uint8_t _streamReg;
|
||||||
uint8_t _extOutput;
|
uint8_t _extOutput;
|
||||||
int64_t _customDate;
|
int64_t _customDate;
|
||||||
|
|
||||||
|
uint64_t _prevMasterClock;
|
||||||
|
|
||||||
|
void ProcessClocks();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BsxSatellaview(Console* console, IMemoryHandler *bBusHandler);
|
BsxSatellaview(Console* console, IMemoryHandler *bBusHandler);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "BsxStream.h"
|
#include "BsxStream.h"
|
||||||
|
#include "Console.h"
|
||||||
|
#include "MemoryManager.h"
|
||||||
#include "../Utilities/FolderUtilities.h"
|
#include "../Utilities/FolderUtilities.h"
|
||||||
#include "../Utilities/HexUtilities.h"
|
#include "../Utilities/HexUtilities.h"
|
||||||
#include "../Utilities/Serializer.h"
|
#include "../Utilities/Serializer.h"
|
||||||
|
@ -8,8 +10,11 @@ BsxStream::BsxStream()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void BsxStream::Reset(int64_t customDate)
|
void BsxStream::Reset(Console* console, int64_t resetDate)
|
||||||
{
|
{
|
||||||
|
_console = console;
|
||||||
|
_memoryManager = console->GetMemoryManager().get();
|
||||||
|
|
||||||
_file.close();
|
_file.close();
|
||||||
|
|
||||||
_channel = 0;
|
_channel = 0;
|
||||||
|
@ -30,9 +35,9 @@ void BsxStream::Reset(int64_t customDate)
|
||||||
_activeChannel = 0;
|
_activeChannel = 0;
|
||||||
_activeFileIndex = 0;
|
_activeFileIndex = 0;
|
||||||
|
|
||||||
_customDate = customDate;
|
_resetDate = resetDate;
|
||||||
time(&_resetTime);
|
_resetMasterClock = 0;
|
||||||
_latchedTime = 0;
|
|
||||||
_tm = {};
|
_tm = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,10 +46,14 @@ uint16_t BsxStream::GetChannel()
|
||||||
return _channel;
|
return _channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BsxStream::FillQueues()
|
bool BsxStream::NeedUpdate()
|
||||||
{
|
{
|
||||||
//TODO: Make this run based on master clock
|
return _queueLength > 0;
|
||||||
while(_queueLength > 0) {
|
}
|
||||||
|
|
||||||
|
bool BsxStream::FillQueues()
|
||||||
|
{
|
||||||
|
if(_queueLength > 0) {
|
||||||
_queueLength--;
|
_queueLength--;
|
||||||
if(_prefixLatch && _prefixQueueLength < 0x80) {
|
if(_prefixLatch && _prefixQueueLength < 0x80) {
|
||||||
_prefixQueueLength++;
|
_prefixQueueLength++;
|
||||||
|
@ -53,6 +62,7 @@ void BsxStream::FillQueues()
|
||||||
_dataQueueLength++;
|
_dataQueueLength++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return NeedUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BsxStream::OpenStreamFile()
|
void BsxStream::OpenStreamFile()
|
||||||
|
@ -76,7 +86,6 @@ bool BsxStream::LoadStreamFile()
|
||||||
_queueLength = (uint16_t)std::ceil(_file.tellg() / 22.0);
|
_queueLength = (uint16_t)std::ceil(_file.tellg() / 22.0);
|
||||||
_file.seekg(0, ios::beg);
|
_file.seekg(0, ios::beg);
|
||||||
_fileIndex++;
|
_fileIndex++;
|
||||||
FillQueues();
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if(_fileIndex > 0) {
|
if(_fileIndex > 0) {
|
||||||
|
@ -106,7 +115,6 @@ uint8_t BsxStream::GetPrefixCount()
|
||||||
if(_channel == 0) {
|
if(_channel == 0) {
|
||||||
//Time channel
|
//Time channel
|
||||||
_queueLength = 1;
|
_queueLength = 1;
|
||||||
FillQueues();
|
|
||||||
_firstPacket = true;
|
_firstPacket = true;
|
||||||
} else {
|
} else {
|
||||||
LoadStreamFile();
|
LoadStreamFile();
|
||||||
|
@ -213,16 +221,12 @@ void BsxStream::SetDataLatch(uint8_t value)
|
||||||
|
|
||||||
void BsxStream::InitTimeStruct()
|
void BsxStream::InitTimeStruct()
|
||||||
{
|
{
|
||||||
if(_customDate >= 0) {
|
time_t dateTime = _resetDate + ((_memoryManager->GetMasterClock() - _resetMasterClock) / _console->GetMasterClockRate());
|
||||||
//Use custom date
|
|
||||||
time_t elapsed = _latchedTime - _resetTime;
|
|
||||||
_latchedTime = _customDate + elapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
localtime_s(&_tm, &_latchedTime);
|
localtime_s(&_tm, &dateTime);
|
||||||
#else
|
#else
|
||||||
localtime_r(&_latchedTime, &_tm);
|
localtime_r(&dateTime, &_tm);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_tm.tm_wday++;
|
_tm.tm_wday++;
|
||||||
|
@ -233,7 +237,6 @@ void BsxStream::InitTimeStruct()
|
||||||
uint8_t BsxStream::GetTime()
|
uint8_t BsxStream::GetTime()
|
||||||
{
|
{
|
||||||
if(_fileOffset == 0) {
|
if(_fileOffset == 0) {
|
||||||
time(&_latchedTime);
|
|
||||||
InitTimeStruct();
|
InitTimeStruct();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,8 +267,7 @@ void BsxStream::Serialize(Serializer& s)
|
||||||
{
|
{
|
||||||
s.Stream(
|
s.Stream(
|
||||||
_channel, _prefix, _data, _status, _prefixLatch, _dataLatch, _firstPacket, _fileOffset, _fileIndex,
|
_channel, _prefix, _data, _status, _prefixLatch, _dataLatch, _firstPacket, _fileOffset, _fileIndex,
|
||||||
_queueLength, _prefixQueueLength, _dataQueueLength, _latchedTime, _resetTime, _customDate,
|
_queueLength, _prefixQueueLength, _dataQueueLength, _resetDate, _resetMasterClock, _activeChannel, _activeFileIndex
|
||||||
_activeChannel, _activeFileIndex
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!s.IsSaving()) {
|
if(!s.IsSaving()) {
|
||||||
|
|
|
@ -2,9 +2,15 @@
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "../Utilities/ISerializable.h"
|
#include "../Utilities/ISerializable.h"
|
||||||
|
|
||||||
|
class Console;
|
||||||
|
class MemoryManager;
|
||||||
|
|
||||||
class BsxStream : public ISerializable
|
class BsxStream : public ISerializable
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
Console* _console;
|
||||||
|
MemoryManager* _memoryManager;
|
||||||
|
|
||||||
ifstream _file;
|
ifstream _file;
|
||||||
tm _tm = {};
|
tm _tm = {};
|
||||||
|
|
||||||
|
@ -26,11 +32,9 @@ private:
|
||||||
uint16_t _activeChannel = 0;
|
uint16_t _activeChannel = 0;
|
||||||
uint8_t _activeFileIndex = 0;
|
uint8_t _activeFileIndex = 0;
|
||||||
|
|
||||||
int64_t _customDate = -1;
|
int64_t _resetDate = -1;
|
||||||
time_t _resetTime = 0;
|
uint64_t _resetMasterClock = 0;
|
||||||
time_t _latchedTime = 0;
|
|
||||||
|
|
||||||
void FillQueues();
|
|
||||||
void OpenStreamFile();
|
void OpenStreamFile();
|
||||||
bool LoadStreamFile();
|
bool LoadStreamFile();
|
||||||
|
|
||||||
|
@ -39,9 +43,11 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BsxStream();
|
BsxStream();
|
||||||
void Reset(int64_t customDate);
|
void Reset(Console* console, int64_t customDate);
|
||||||
|
|
||||||
uint16_t GetChannel();
|
uint16_t GetChannel();
|
||||||
|
bool NeedUpdate();
|
||||||
|
bool FillQueues();
|
||||||
|
|
||||||
uint8_t GetPrefixCount();
|
uint8_t GetPrefixCount();
|
||||||
uint8_t GetPrefix();
|
uint8_t GetPrefix();
|
||||||
|
|
|
@ -38,7 +38,7 @@ private:
|
||||||
|
|
||||||
static bool AttemptLoadBsxFirmware(uint8_t** prgRom, uint32_t& prgSize)
|
static bool AttemptLoadBsxFirmware(uint8_t** prgRom, uint32_t& prgSize)
|
||||||
{
|
{
|
||||||
VirtualFile firmware(FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), "BS-X BIOS.sfc"));
|
VirtualFile firmware(FolderUtilities::CombinePath(FolderUtilities::GetFirmwareFolder(), "BsxBios.sfc"));
|
||||||
if(firmware.IsValid() && firmware.GetSize() >= 0x8000) {
|
if(firmware.IsValid() && firmware.GetSize() >= 0x8000) {
|
||||||
*prgRom = new uint8_t[firmware.GetSize()];
|
*prgRom = new uint8_t[firmware.GetSize()];
|
||||||
prgSize = (uint32_t)firmware.GetSize();
|
prgSize = (uint32_t)firmware.GetSize();
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
MissingFirmwareMessage msg;
|
MissingFirmwareMessage msg;
|
||||||
msg.Filename = "BS-X BIOS.sfc";
|
msg.Filename = "BsxBios.sfc";
|
||||||
msg.FirmwareType = CoprocessorType::Satellaview;
|
msg.FirmwareType = CoprocessorType::Satellaview;
|
||||||
msg.Size = 1024*1024;
|
msg.Size = 1024*1024;
|
||||||
console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg);
|
console->GetNotificationManager()->SendNotification(ConsoleNotificationType::MissingFirmware, &msg);
|
||||||
|
|
|
@ -15,13 +15,6 @@ Windows: [![Build status](https://ci.appveyor.com/api/projects/status/cjk97u1yvw
|
||||||
|
|
||||||
Linux: [![Build status](https://ci.appveyor.com/api/projects/status/arkaatgy94f23ll3/branch/master?svg=true)](https://ci.appveyor.com/project/Sour/mesen-s-hayo4/build/artifacts)
|
Linux: [![Build status](https://ci.appveyor.com/api/projects/status/arkaatgy94f23ll3/branch/master?svg=true)](https://ci.appveyor.com/project/Sour/mesen-s-hayo4/build/artifacts)
|
||||||
|
|
||||||
## Roadmap
|
|
||||||
|
|
||||||
The following should be added over time (in no particular order):
|
|
||||||
|
|
||||||
* Additions/improvements in the debugging tools
|
|
||||||
* Satellaview/BS-X support
|
|
||||||
|
|
||||||
## Compiling
|
## Compiling
|
||||||
|
|
||||||
See [COMPILING.md](COMPILING.md)
|
See [COMPILING.md](COMPILING.md)
|
||||||
|
|
Loading…
Add table
Reference in a new issue