Update Apu class

This commit is contained in:
scawful
2024-04-24 10:04:24 -04:00
parent 5741596a89
commit 6842c08b3a
2 changed files with 55 additions and 56 deletions

View File

@@ -31,10 +31,21 @@ void Apu::Init() {
} }
void Apu::Reset() { void Apu::Reset() {
clock_.ResetAccumulatedTime();
spc700_.Reset(true); spc700_.Reset(true);
dsp_.Reset(); dsp_.Reset();
romReadable = true; ram.clear();
rom_readable_ = true;
dsp_adr_ = 0;
cycles_ = 0;
memset(in_ports_, 0, sizeof(in_ports_));
memset(out_ports_, 0, sizeof(out_ports_));
for (int i = 0; i < 3; i++) {
timer_[i].cycles = 0;
timer_[i].divider = 0;
timer_[i].target = 0;
timer_[i].counter = 0;
timer_[i].enabled = false;
}
} }
void Apu::Update() { void Apu::Update() {
@@ -69,18 +80,18 @@ void Apu::Cycle() {
// handle timers // handle timers
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (timer[i].cycles == 0) { if (timer_[i].cycles == 0) {
timer[i].cycles = i == 2 ? 16 : 128; timer_[i].cycles = i == 2 ? 16 : 128;
if (timer[i].enabled) { if (timer_[i].enabled) {
timer[i].divider++; timer_[i].divider++;
if (timer[i].divider == timer[i].target) { if (timer_[i].divider == timer_[i].target) {
timer[i].divider = 0; timer_[i].divider = 0;
timer[i].counter++; timer_[i].counter++;
timer[i].counter &= 0xf; timer_[i].counter &= 0xf;
} }
} }
} }
timer[i].cycles--; timer_[i].cycles--;
} }
cycles_++; cycles_++;
@@ -96,10 +107,10 @@ uint8_t Apu::Read(uint16_t adr) {
return 0; return 0;
} }
case 0xf2: { case 0xf2: {
return dspAdr; return dsp_adr_;
} }
case 0xf3: { case 0xf3: {
return dsp_.Read(dspAdr & 0x7f); return dsp_.Read(dsp_adr_ & 0x7f);
} }
case 0xf4: case 0xf4:
case 0xf5: case 0xf5:
@@ -107,20 +118,20 @@ uint8_t Apu::Read(uint16_t adr) {
case 0xf7: case 0xf7:
case 0xf8: case 0xf8:
case 0xf9: { case 0xf9: {
return inPorts[adr - 0xf4]; return in_ports_[adr - 0xf4];
} }
case 0xfd: case 0xfd:
case 0xfe: case 0xfe:
case 0xff: { case 0xff: {
uint8_t ret = timer[adr - 0xfd].counter; uint8_t ret = timer_[adr - 0xfd].counter;
timer[adr - 0xfd].counter = 0; timer_[adr - 0xfd].counter = 0;
return ret; return ret;
} }
} }
if (romReadable && adr >= 0xffc0) { if (rom_readable_ && adr >= 0xffc0) {
return bootRom[adr - 0xffc0]; return bootRom[adr - 0xffc0];
} }
return aram_.read(adr); return ram[adr];
} }
void Apu::Write(uint16_t adr, uint8_t val) { void Apu::Write(uint16_t adr, uint8_t val) {
@@ -130,51 +141,51 @@ void Apu::Write(uint16_t adr, uint8_t val) {
} }
case 0xf1: { case 0xf1: {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (!timer[i].enabled && (val & (1 << i))) { if (!timer_[i].enabled && (val & (1 << i))) {
timer[i].divider = 0; timer_[i].divider = 0;
timer[i].counter = 0; timer_[i].counter = 0;
} }
timer[i].enabled = val & (1 << i); timer_[i].enabled = val & (1 << i);
} }
if (val & 0x10) { if (val & 0x10) {
inPorts[0] = 0; in_ports_[0] = 0;
inPorts[1] = 0; in_ports_[1] = 0;
} }
if (val & 0x20) { if (val & 0x20) {
inPorts[2] = 0; in_ports_[2] = 0;
inPorts[3] = 0; in_ports_[3] = 0;
} }
romReadable = val & 0x80; rom_readable_ = val & 0x80;
break; break;
} }
case 0xf2: { case 0xf2: {
dspAdr = val; dsp_adr_ = val;
break; break;
} }
case 0xf3: { case 0xf3: {
if (dspAdr < 0x80) dsp_.Write(dspAdr, val); if (dsp_adr_ < 0x80) dsp_.Write(dsp_adr_, val);
break; break;
} }
case 0xf4: case 0xf4:
case 0xf5: case 0xf5:
case 0xf6: case 0xf6:
case 0xf7: { case 0xf7: {
outPorts[adr - 0xf4] = val; out_ports_[adr - 0xf4] = val;
break; break;
} }
case 0xf8: case 0xf8:
case 0xf9: { case 0xf9: {
inPorts[adr - 0xf4] = val; in_ports_[adr - 0xf4] = val;
break; break;
} }
case 0xfa: case 0xfa:
case 0xfb: case 0xfb:
case 0xfc: { case 0xfc: {
timer[adr - 0xfa].target = val; timer_[adr - 0xfa].target = val;
break; break;
} }
} }
aram_.write(adr, val); ram[adr] = val;
} }
uint8_t Apu::SpcRead(uint16_t adr) { uint8_t Apu::SpcRead(uint16_t adr) {

View File

@@ -56,8 +56,8 @@ typedef struct Timer {
*/ */
class Apu { class Apu {
public: public:
Apu(MemoryImpl &memory, AudioRam &aram, Clock &clock) Apu(MemoryImpl &memory, Clock &clock)
: aram_(aram), clock_(clock), memory_(memory) {} : clock_(clock), memory_(memory) {}
void Init(); void Init();
void Reset(); void Reset();
@@ -73,34 +73,22 @@ class Apu {
uint8_t Read(uint16_t address); uint8_t Read(uint16_t address);
void Write(uint16_t address, uint8_t data); void Write(uint16_t address, uint8_t data);
// Called upon a reset
void Initialize() {
spc700_.Reset();
dsp_.Reset();
}
void UpdateClock(int delta_time) { clock_.UpdateClock(delta_time); } void UpdateClock(int delta_time) { clock_.UpdateClock(delta_time); }
auto dsp() -> Dsp & { return dsp_; } auto dsp() -> Dsp & { return dsp_; }
uint8_t inPorts[6]; // includes 2 bytes of ram // Port buffers (equivalent to $2140 to $2143 for the main CPU)
uint8_t outPorts[4]; uint8_t in_ports_[6]; // includes 2 bytes of ram
uint8_t out_ports_[4];
private: private:
// Constants for communication Timer timer_[3];
static const uint8_t READY_SIGNAL_0 = 0xAA;
static const uint8_t READY_SIGNAL_1 = 0xBB;
static const uint8_t BEGIN_SIGNAL = 0xCC;
// Port buffers (equivalent to $2140 to $2143 for the main CPU)
uint8_t ports_[4] = {0};
Timer timer[3];
uint32_t cycles_; uint32_t cycles_;
uint8_t dspAdr; uint8_t dsp_adr_;
bool romReadable = false; bool rom_readable_ = false;
std::vector<uint8_t> ram = std::vector<uint8_t>(0x10000, 0);
// Member variables to store internal APU state and resources // Member variables to store internal APU state and resources
AudioRam &aram_;
Clock &clock_; Clock &clock_;
MemoryImpl &memory_; MemoryImpl &memory_;
@@ -109,8 +97,8 @@ class Apu {
[&](uint16_t adr) { return SpcRead(adr); }, [&](uint16_t adr) { return SpcRead(adr); },
[&](bool waiting) { SpcIdle(waiting); }, [&](bool waiting) { SpcIdle(waiting); },
}; };
Dsp dsp_{aram_}; Dsp dsp_{ram};
Spc700 spc700_{aram_, callbacks_}; Spc700 spc700_{callbacks_};
}; };
} // namespace audio } // namespace audio