cleanup spc700 and add todos

This commit is contained in:
scawful
2023-12-06 01:32:59 -05:00
parent d0c9229093
commit 87db938963
17 changed files with 559 additions and 633 deletions

View File

@@ -39,134 +39,32 @@ const int apuClocksPerSample = 64; // 64 clocks per sample
class APU : public Observer {
public:
// Initializes the APU with the necessary resources and dependencies
APU(MemoryImpl &memory, AudioRam &aram, Clock &clock)
: aram_(aram), clock_(clock), memory_(memory) {}
void Init();
// Resets the APU to its initial state
void Reset();
// Runs the APU for one frame
void Update();
void Notify(uint32_t address, uint8_t data) override;
void ProcessSamples();
uint8_t FetchSampleForVoice(uint8_t voice_num);
uint16_t CalculateAddressForVoice(uint8_t voice_num);
int16_t GetNextSample();
void Notify(uint32_t address, uint8_t data) override {
ports_[address - 0x2140] = data;
switch (address) {
case 0x2140:
if (data == BEGIN_SIGNAL) {
BeginTransfer();
} else {
AcknowledgeSignal();
}
break;
case 0x2141:
// Handle data byte transfer here, if needed
break;
case 0x2142:
// Handle the setup of destination address, if needed
break;
case 0x2143:
// Handle additional communication or commands
break;
}
}
// Called upon a reset
void Initialize() {
spc700_.Reset();
dsp_.Reset();
// Set stack pointer, zero-page values, etc. for the SPC700
SignalReady();
}
// Set Port 0 = $AA and Port 1 = $BB
void SignalReady() {
// Set Port 0 = $AA and Port 1 = $BB
ports_[0] = READY_SIGNAL_0;
ports_[1] = READY_SIGNAL_1;
memory_.WriteByte(0x2140, READY_SIGNAL_0);
memory_.WriteByte(0x2141, READY_SIGNAL_1);
}
bool IsReadySignalReceived() const {
return ports_[0] == READY_SIGNAL_0 && ports_[1] == READY_SIGNAL_1;
}
void WaitForSignal() const {
// This might be an active wait or a passive state where APU does nothing
// until it's externally triggered by the main CPU writing to its ports.
while (ports_[0] != BEGIN_SIGNAL)
;
}
uint16_t ReadAddressFromPorts() const {
// Read 2 byte address from port 2 (low) and 3 (high)
return static_cast<uint16_t>(ports_[2]) |
(static_cast<uint16_t>(ports_[3]) << 8);
}
void AcknowledgeSignal() {
// Read value from Port 0 and write it back to Port 0
ports_[0] = ports_[0];
}
void BeginTransfer() {
const uint16_t startAddress = 0x0200;
// Write the starting address to ports 0x2142 and 0x2143
WriteToPort(2, static_cast<uint8_t>(startAddress & 0xFF)); // Lower byte
WriteToPort(3, static_cast<uint8_t>(startAddress >> 8)); // Upper byte
// Trigger the actual data transfer process
TriggerDataTransfer(startAddress);
}
void TriggerDataTransfer(uint16_t startAddress) {
const int DATA_SIZE = 0x1000; // Size of the data to be transferred
uint8_t audioData[DATA_SIZE]; // Buffer containing the audio data
// Load audioData as needed...
for (int i = 0; i < DATA_SIZE; ++i) {
WriteToPort(1, audioData[i]); // Write data byte
WriteToPort(0, i & 0xFF); // Write index and wait for acknowledgment
WaitForAcknowledgment(i & 0xFF);
}
// After transferring all data, trigger the execution of the program
StartSpcProgram(startAddress);
}
void WaitForAcknowledgment(uint8_t expectedIndex) {
while (ports_[0] != expectedIndex) {
// Active wait - consider implementing a more efficient mechanism
}
}
void StartSpcProgram(uint16_t startAddress) {
// Send the start address for execution
WriteToPort(2, static_cast<uint8_t>(startAddress & 0xFF)); // Lower byte
WriteToPort(3, static_cast<uint8_t>(startAddress >> 8)); // Upper byte
WriteToPort(1, 0x00); // Zero value indicates execution command
WriteToPort(0, 0xCE); // Send a unique signal to start execution
// Wait for acknowledgment
WaitForAcknowledgment(0xCE);
}
void ExecuteProgram() { spc700_.ExecuteInstructions(ReadAddressFromPorts()); }
void WriteToPort(uint8_t portNum, uint8_t value) {
ports_[portNum] = value;
switch (portNum) {
@@ -185,10 +83,6 @@ class APU : public Observer {
}
}
void SetReadyCallback(std::function<void()> callback) {
ready_callback_ = callback;
}
void UpdateClock(int delta_time) { clock_.UpdateClock(delta_time); }
// Method to fetch a sample from AudioRam
@@ -197,13 +91,7 @@ class APU : public Observer {
}
// Method to push a processed sample to the audio buffer
void PushToAudioBuffer(int16_t sample) { audioSamples_.push_back(sample); }
// Reads a byte from the specified APU register
uint8_t ReadRegister(uint16_t address);
// Writes a byte to the specified APU register
void WriteRegister(uint16_t address, uint8_t value);
void PushToAudioBuffer(int16_t sample) { audio_samples_.push_back(sample); }
// Returns the audio samples for the current frame
const std::vector<int16_t> &GetAudioSamples() const;
@@ -227,8 +115,8 @@ class APU : public Observer {
void ApplyEnvelope(int channel);
// Handles DSP (Digital Signal Processor) memory reads and writes
uint8_t ReadDSPMemory(uint16_t address);
void WriteDSPMemory(uint16_t address, uint8_t value);
uint8_t ReadDspMemory(uint16_t address);
void WriteDspMemory(uint16_t address, uint8_t value);
// Member variables to store internal APU state and resources
AudioRam &aram_;
@@ -237,7 +125,7 @@ class APU : public Observer {
DigitalSignalProcessor dsp_;
Spc700 spc700_{aram_};
std::vector<int16_t> audioSamples_;
std::vector<int16_t> audio_samples_;
std::function<void()> ready_callback_;
};