From 6de0a7b7e0b2176bad151e8db4dacea9b5cbae43 Mon Sep 17 00:00:00 2001 From: Sour Date: Wed, 1 Jan 2020 22:21:15 -0500 Subject: [PATCH] Study Box: Improved some timings, reimplemented command $86 in a way that makes more sense --- Core/StudyBox.h | 37 +++++++++++++++++++++++++------------ Utilities/WavReader.cpp | 5 +++++ Utilities/WavReader.h | 1 + 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Core/StudyBox.h b/Core/StudyBox.h index 83f4b4b9..eef4e032 100644 --- a/Core/StudyBox.h +++ b/Core/StudyBox.h @@ -3,6 +3,7 @@ #include "BaseMapper.h" #include "MemoryManager.h" #include "Console.h" +#include "Cpu.h" #include "../Utilities/WavReader.h" #include "../Utilities/FolderUtilities.h" #include "../Utilities/StringUtilities.h" @@ -12,6 +13,7 @@ class StudyBox : public BaseMapper { private: shared_ptr _wavReader; + uint32_t _audioSampleRate; bool _readyForBit = false; uint16_t _processBitDelay = 0; @@ -55,7 +57,7 @@ protected: SelectPRGPage(1, 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); RemoveCpuMemoryMapping(0x4000, 0x43FF); @@ -67,7 +69,10 @@ protected: _tapeData = romData.StudyBox; _wavReader = WavReader::Create(_tapeData.AudioFile.data(), (uint32_t)_tapeData.AudioFile.size()); if(!_wavReader) { + _audioSampleRate = 44100; 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 { if(_processBitDelay > 0) { @@ -103,7 +118,6 @@ protected: _seekPageDelay--; if(_seekPageDelay == 0) { _seekPageDelay = 3000000; - _pageFound = true; if(_seekPage > _currentPage) { _currentPage++; } else { @@ -119,9 +133,7 @@ protected: } } - _inDataDelay = 300000; - _pagePosition = -1; - _byteReadDelay = 0; + ReadLeadInTrack(); } } else if(_inDataDelay > 0) { _inDataRegion = true; @@ -245,29 +257,30 @@ protected: //MessageManager::Log("Command sent: " + std::to_string(_command)); if(_command >= 1 && _command < 0x40) { + //Move forward X pages _seekPage = _command + _currentPage; _seekPageDelay = 3000000; _motorDisabled = false; } else if(_command > 0x40 && _command < 0x80) { + //Move back X pages _seekPage = -(_command - 0x40) + _currentPage; _seekPageDelay = 3000000; _motorDisabled = false; } 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; _currentPage = _currentPage - 1; _seekPageDelay = 3000000; _motorDisabled = false; } 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++; - _pagePosition = -1; } 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; - _motorDisabled = false; - _byteReadDelay = 0; - _pageFound = true; + ReadLeadInTrack(); } else { MessageManager::Log("Unknown command sent: " + std::to_string(_command)); } diff --git a/Utilities/WavReader.cpp b/Utilities/WavReader.cpp index ad93b4c2..6861e57a 100644 --- a/Utilities/WavReader.cpp +++ b/Utilities/WavReader.cpp @@ -141,4 +141,9 @@ void WavReader::ApplySamples(int16_t *buffer, size_t sampleCount, double volume) int32_t WavReader::GetPosition() { return _done ? -1 : (_fileOffset - _dataStartOffset) / 2; +} + +uint32_t WavReader::GetSampleRate() +{ + return _fileSampleRate; } \ No newline at end of file diff --git a/Utilities/WavReader.h b/Utilities/WavReader.h index ee52750e..a59706f1 100644 --- a/Utilities/WavReader.h +++ b/Utilities/WavReader.h @@ -35,4 +35,5 @@ public: void SetSampleRate(uint32_t sampleRate); void ApplySamples(int16_t* buffer, size_t sampleCount, double volume); int32_t GetPosition(); + uint32_t GetSampleRate(); };