Study Box: Improved some timings, reimplemented command $86 in a way that makes more sense

This commit is contained in:
Sour 2020-01-01 22:21:15 -05:00
parent a8d41596c0
commit 6de0a7b7e0
3 changed files with 31 additions and 12 deletions

View file

@ -3,6 +3,7 @@
#include "BaseMapper.h" #include "BaseMapper.h"
#include "MemoryManager.h" #include "MemoryManager.h"
#include "Console.h" #include "Console.h"
#include "Cpu.h"
#include "../Utilities/WavReader.h" #include "../Utilities/WavReader.h"
#include "../Utilities/FolderUtilities.h" #include "../Utilities/FolderUtilities.h"
#include "../Utilities/StringUtilities.h" #include "../Utilities/StringUtilities.h"
@ -12,6 +13,7 @@ class StudyBox : public BaseMapper
{ {
private: private:
shared_ptr<WavReader> _wavReader; shared_ptr<WavReader> _wavReader;
uint32_t _audioSampleRate;
bool _readyForBit = false; bool _readyForBit = false;
uint16_t _processBitDelay = 0; uint16_t _processBitDelay = 0;
@ -55,7 +57,7 @@ protected:
SelectPRGPage(1, 0); SelectPRGPage(1, 0);
SelectCHRPage(0, 0); SelectCHRPage(0, 0);
//First bank is mapped to 4000-4FFF, but the first 1kb is not accessible //First bank (on the 2nd RAM chip, so bank #8 in the code) is mapped to 4000-4FFF, but the first 1kb is not accessible
SetCpuMemoryMapping(0x4000, 0x4FFF, 8, PrgMemoryType::WorkRam); SetCpuMemoryMapping(0x4000, 0x4FFF, 8, PrgMemoryType::WorkRam);
RemoveCpuMemoryMapping(0x4000, 0x43FF); RemoveCpuMemoryMapping(0x4000, 0x43FF);
@ -67,7 +69,10 @@ protected:
_tapeData = romData.StudyBox; _tapeData = romData.StudyBox;
_wavReader = WavReader::Create(_tapeData.AudioFile.data(), (uint32_t)_tapeData.AudioFile.size()); _wavReader = WavReader::Create(_tapeData.AudioFile.data(), (uint32_t)_tapeData.AudioFile.size());
if(!_wavReader) { if(!_wavReader) {
_audioSampleRate = 44100;
MessageManager::Log("[Study Box] Unsupported audio file format."); MessageManager::Log("[Study Box] Unsupported audio file format.");
} else {
_audioSampleRate = _wavReader->GetSampleRate();
} }
} }
@ -86,6 +91,16 @@ protected:
} }
} }
void ReadLeadInTrack()
{
//Wait for the tape to read through the lead-in before the actual data
_inDataDelay = (uint64_t)(_tapeData.Pages[_pageIndex].AudioOffset - _tapeData.Pages[_pageIndex].LeadInOffset) * _console->GetCpu()->GetClockRate(_console->GetModel()) / _audioSampleRate;
_pagePosition = -1;
_byteReadDelay = 0;
_motorDisabled = false;
_pageFound = true;
}
void ProcessCpuClock() override void ProcessCpuClock() override
{ {
if(_processBitDelay > 0) { if(_processBitDelay > 0) {
@ -103,7 +118,6 @@ protected:
_seekPageDelay--; _seekPageDelay--;
if(_seekPageDelay == 0) { if(_seekPageDelay == 0) {
_seekPageDelay = 3000000; _seekPageDelay = 3000000;
_pageFound = true;
if(_seekPage > _currentPage) { if(_seekPage > _currentPage) {
_currentPage++; _currentPage++;
} else { } else {
@ -119,9 +133,7 @@ protected:
} }
} }
_inDataDelay = 300000; ReadLeadInTrack();
_pagePosition = -1;
_byteReadDelay = 0;
} }
} else if(_inDataDelay > 0) { } else if(_inDataDelay > 0) {
_inDataRegion = true; _inDataRegion = true;
@ -245,29 +257,30 @@ protected:
//MessageManager::Log("Command sent: " + std::to_string(_command)); //MessageManager::Log("Command sent: " + std::to_string(_command));
if(_command >= 1 && _command < 0x40) { if(_command >= 1 && _command < 0x40) {
//Move forward X pages
_seekPage = _command + _currentPage; _seekPage = _command + _currentPage;
_seekPageDelay = 3000000; _seekPageDelay = 3000000;
_motorDisabled = false; _motorDisabled = false;
} else if(_command > 0x40 && _command < 0x80) { } else if(_command > 0x40 && _command < 0x80) {
//Move back X pages
_seekPage = -(_command - 0x40) + _currentPage; _seekPage = -(_command - 0x40) + _currentPage;
_seekPageDelay = 3000000; _seekPageDelay = 3000000;
_motorDisabled = false; _motorDisabled = false;
} else if(_command == 0) { } else if(_command == 0) {
//Move back to the start of this page (based on the internal page ID, not the page "index" in the array? - to validate)
_seekPage = _currentPage; _seekPage = _currentPage;
_currentPage = _currentPage - 1; _currentPage = _currentPage - 1;
_seekPageDelay = 3000000; _seekPageDelay = 3000000;
_motorDisabled = false; _motorDisabled = false;
} else if(_command == 0x86) { } else if(_command == 0x86) {
if(_pageIndex < (int32_t)_tapeData.Pages.size() - 1 && _tapeData.Pages[_pageIndex + 1].Data[5] == _currentPage - 1) { //Reenable motor (and continue to the next page)
if(_pageIndex < (int32_t)_tapeData.Pages.size() - 1) {
_pageIndex++; _pageIndex++;
_pagePosition = -1;
} else { } else {
_pagePosition = (int32_t)_tapeData.Pages[_pageIndex + 1].Data.size(); //Pretend we go back to the start of the tape (inaccurate)
_pageIndex = 0;
} }
_inDataDelay = 300000; ReadLeadInTrack();
_motorDisabled = false;
_byteReadDelay = 0;
_pageFound = true;
} else { } else {
MessageManager::Log("Unknown command sent: " + std::to_string(_command)); MessageManager::Log("Unknown command sent: " + std::to_string(_command));
} }

View file

@ -141,4 +141,9 @@ void WavReader::ApplySamples(int16_t *buffer, size_t sampleCount, double volume)
int32_t WavReader::GetPosition() int32_t WavReader::GetPosition()
{ {
return _done ? -1 : (_fileOffset - _dataStartOffset) / 2; return _done ? -1 : (_fileOffset - _dataStartOffset) / 2;
}
uint32_t WavReader::GetSampleRate()
{
return _fileSampleRate;
} }

View file

@ -35,4 +35,5 @@ public:
void SetSampleRate(uint32_t sampleRate); void SetSampleRate(uint32_t sampleRate);
void ApplySamples(int16_t* buffer, size_t sampleCount, double volume); void ApplySamples(int16_t* buffer, size_t sampleCount, double volume);
int32_t GetPosition(); int32_t GetPosition();
uint32_t GetSampleRate();
}; };