Study Box: Improved some timings, reimplemented command $86 in a way that makes more sense
This commit is contained in:
parent
a8d41596c0
commit
6de0a7b7e0
3 changed files with 31 additions and 12 deletions
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue