per-channel oscilloscope, part 7
YM2610 and YM2610B only TIA is left
This commit is contained in:
parent
415e490025
commit
47f83c0472
|
@ -203,11 +203,15 @@ public:
|
||||||
// return a reference to our registers
|
// return a reference to our registers
|
||||||
adpcm_a_registers ®s() { return m_regs; }
|
adpcm_a_registers ®s() { return m_regs; }
|
||||||
|
|
||||||
|
// debug functions
|
||||||
|
adpcm_a_channel* debug_channel(uint32_t index) const { return m_channel[index].get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
ymfm_interface &m_intf; // reference to the interface
|
ymfm_interface &m_intf; // reference to the interface
|
||||||
std::unique_ptr<adpcm_a_channel> m_channel[CHANNELS]; // array of channels
|
std::unique_ptr<adpcm_a_channel> m_channel[CHANNELS]; // array of channels
|
||||||
adpcm_a_registers m_regs; // registers
|
adpcm_a_registers m_regs; // registers
|
||||||
|
int32_t m_last_out[CHANNELS]; // last output of channels
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -697,6 +697,12 @@ public:
|
||||||
// generate one sample of sound
|
// generate one sample of sound
|
||||||
void generate(output_data *output, uint32_t numsamples = 1);
|
void generate(output_data *output, uint32_t numsamples = 1);
|
||||||
|
|
||||||
|
// get the engine
|
||||||
|
fm_engine* debug_fm_engine() { return &m_fm; }
|
||||||
|
ssg_engine* debug_ssg_engine() { return &m_ssg; }
|
||||||
|
adpcm_a_engine* debug_adpcm_a_engine() { return &m_adpcm_a; }
|
||||||
|
adpcm_b_engine* debug_adpcm_b_engine() { return &m_adpcm_b; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// internal helpers
|
// internal helpers
|
||||||
void update_prescale();
|
void update_prescale();
|
||||||
|
|
|
@ -232,6 +232,8 @@ void ssg_engine::output(output_data &output)
|
||||||
// convert to amplitude
|
// convert to amplitude
|
||||||
output.data[chan] = s_amplitudes[volume];
|
output.data[chan] = s_amplitudes[volume];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_last_out=output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,9 @@ public:
|
||||||
// indicate the prescale has changed
|
// indicate the prescale has changed
|
||||||
void prescale_changed() { if (m_override != nullptr) m_override->ssg_prescale_changed(); }
|
void prescale_changed() { if (m_override != nullptr) m_override->ssg_prescale_changed(); }
|
||||||
|
|
||||||
|
// get the last output
|
||||||
|
void get_last_out(output_data& out) { out=m_last_out; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
ymfm_interface &m_intf; // reference to the interface
|
ymfm_interface &m_intf; // reference to the interface
|
||||||
|
@ -198,6 +201,7 @@ private:
|
||||||
uint32_t m_noise_state; // current noise state
|
uint32_t m_noise_state; // current noise state
|
||||||
ssg_registers m_regs; // registers
|
ssg_registers m_regs; // registers
|
||||||
ssg_override *m_override; // override interface
|
ssg_override *m_override; // override interface
|
||||||
|
output_data m_last_out;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@ static unsigned char konOffs[4]={
|
||||||
1, 2, 5, 6
|
1, 2, 5, 6
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned char bchOffs[4]={
|
||||||
|
1, 2, 4, 5
|
||||||
|
};
|
||||||
|
|
||||||
#define CHIP_DIVIDER 32
|
#define CHIP_DIVIDER 32
|
||||||
|
|
||||||
const char* regCheatSheetYM2610[]={
|
const char* regCheatSheetYM2610[]={
|
||||||
|
@ -337,6 +341,14 @@ double DivPlatformYM2610::NOTE_ADPCMB(int note) {
|
||||||
void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
static int os[2];
|
static int os[2];
|
||||||
|
|
||||||
|
ymfm::ym2612::fm_engine* fme=fm->debug_fm_engine();
|
||||||
|
ymfm::ssg_engine* ssge=fm->debug_ssg_engine();
|
||||||
|
ymfm::adpcm_a_engine* aae=fm->debug_adpcm_a_engine();
|
||||||
|
ymfm::adpcm_b_engine* abe=fm->debug_adpcm_b_engine();
|
||||||
|
|
||||||
|
ymfm::ssg_engine::output_data ssgOut;
|
||||||
|
ymfm::ymfm_output<2> adpcmOut;
|
||||||
|
|
||||||
for (size_t h=start; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
os[0]=0; os[1]=0;
|
os[0]=0; os[1]=0;
|
||||||
if (!writes.empty()) {
|
if (!writes.empty()) {
|
||||||
|
@ -362,6 +374,26 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l
|
||||||
|
|
||||||
bufL[h]=os[0];
|
bufL[h]=os[0];
|
||||||
bufR[h]=os[1];
|
bufR[h]=os[1];
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
int ch=bchOffs[i];
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(ch)->debug_output(0)+fme->debug_channel(ch)->debug_output(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
ssge->get_last_out(ssgOut);
|
||||||
|
for (int i=4; i<7; i++) {
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-4];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=7; i<13; i++) {
|
||||||
|
adpcmOut.clear();
|
||||||
|
aae->debug_channel(i-7)->output(adpcmOut);
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
adpcmOut.clear();
|
||||||
|
abe->output(adpcmOut,1);
|
||||||
|
oscBuf[13]->data[oscBuf[13]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1058,6 +1090,10 @@ void* DivPlatformYM2610::getChanState(int ch) {
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivDispatchOscBuffer* DivPlatformYM2610::getOscBuffer(int ch) {
|
||||||
|
return oscBuf[ch];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformYM2610::getRegisterPool() {
|
unsigned char* DivPlatformYM2610::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
@ -1153,9 +1189,13 @@ int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
skipRegisterWrites=false;
|
skipRegisterWrites=false;
|
||||||
for (int i=0; i<14; i++) {
|
for (int i=0; i<14; i++) {
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
chipClock=8000000;
|
chipClock=8000000;
|
||||||
rate=chipClock/16;
|
rate=chipClock/16;
|
||||||
|
for (int i=0; i<14; i++) {
|
||||||
|
oscBuf[i]->rate=rate;
|
||||||
|
}
|
||||||
iface.parent=parent;
|
iface.parent=parent;
|
||||||
iface.sampleBank=0;
|
iface.sampleBank=0;
|
||||||
fm=new ymfm::ym2610(iface);
|
fm=new ymfm::ym2610(iface);
|
||||||
|
@ -1168,6 +1208,9 @@ int DivPlatformYM2610::init(DivEngine* p, int channels, int sugRate, unsigned in
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformYM2610::quit() {
|
void DivPlatformYM2610::quit() {
|
||||||
|
for (int i=0; i<14; i++) {
|
||||||
|
delete oscBuf[i];
|
||||||
|
}
|
||||||
ay->quit();
|
ay->quit();
|
||||||
delete ay;
|
delete ay;
|
||||||
delete fm;
|
delete fm;
|
||||||
|
|
|
@ -82,6 +82,7 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
pan(3) {}
|
pan(3) {}
|
||||||
};
|
};
|
||||||
Channel chan[14];
|
Channel chan[14];
|
||||||
|
DivDispatchOscBuffer* oscBuf[14];
|
||||||
bool isMuted[14];
|
bool isMuted[14];
|
||||||
struct QueuedWrite {
|
struct QueuedWrite {
|
||||||
unsigned short addr;
|
unsigned short addr;
|
||||||
|
@ -117,6 +118,7 @@ class DivPlatformYM2610: public DivDispatch {
|
||||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -401,6 +401,14 @@ double DivPlatformYM2610B::NOTE_ADPCMB(int note) {
|
||||||
void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
static int os[2];
|
static int os[2];
|
||||||
|
|
||||||
|
ymfm::ym2612::fm_engine* fme=fm->debug_fm_engine();
|
||||||
|
ymfm::ssg_engine* ssge=fm->debug_ssg_engine();
|
||||||
|
ymfm::adpcm_a_engine* aae=fm->debug_adpcm_a_engine();
|
||||||
|
ymfm::adpcm_b_engine* abe=fm->debug_adpcm_b_engine();
|
||||||
|
|
||||||
|
ymfm::ssg_engine::output_data ssgOut;
|
||||||
|
ymfm::ymfm_output<2> adpcmOut;
|
||||||
|
|
||||||
for (size_t h=start; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
os[0]=0; os[1]=0;
|
os[0]=0; os[1]=0;
|
||||||
if (!writes.empty()) {
|
if (!writes.empty()) {
|
||||||
|
@ -426,6 +434,25 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t
|
||||||
|
|
||||||
bufL[h]=os[0];
|
bufL[h]=os[0];
|
||||||
bufR[h]=os[1];
|
bufR[h]=os[1];
|
||||||
|
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
ssge->get_last_out(ssgOut);
|
||||||
|
for (int i=6; i<9; i++) {
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=ssgOut.data[i-6];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=9; i<15; i++) {
|
||||||
|
adpcmOut.clear();
|
||||||
|
aae->debug_channel(i-9)->output(adpcmOut);
|
||||||
|
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
adpcmOut.clear();
|
||||||
|
abe->output(adpcmOut,1);
|
||||||
|
oscBuf[15]->data[oscBuf[15]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1121,6 +1148,10 @@ void* DivPlatformYM2610B::getChanState(int ch) {
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivDispatchOscBuffer* DivPlatformYM2610B::getOscBuffer(int ch) {
|
||||||
|
return oscBuf[ch];
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char* DivPlatformYM2610B::getRegisterPool() {
|
unsigned char* DivPlatformYM2610B::getRegisterPool() {
|
||||||
return regPool;
|
return regPool;
|
||||||
}
|
}
|
||||||
|
@ -1216,9 +1247,13 @@ int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned i
|
||||||
skipRegisterWrites=false;
|
skipRegisterWrites=false;
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
isMuted[i]=false;
|
isMuted[i]=false;
|
||||||
|
oscBuf[i]=new DivDispatchOscBuffer;
|
||||||
}
|
}
|
||||||
chipClock=8000000;
|
chipClock=8000000;
|
||||||
rate=chipClock/16;
|
rate=chipClock/16;
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
oscBuf[i]->rate=rate;
|
||||||
|
}
|
||||||
iface.parent=parent;
|
iface.parent=parent;
|
||||||
iface.sampleBank=0;
|
iface.sampleBank=0;
|
||||||
fm=new ymfm::ym2610b(iface);
|
fm=new ymfm::ym2610b(iface);
|
||||||
|
@ -1231,6 +1266,9 @@ int DivPlatformYM2610B::init(DivEngine* p, int channels, int sugRate, unsigned i
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformYM2610B::quit() {
|
void DivPlatformYM2610B::quit() {
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
delete oscBuf[i];
|
||||||
|
}
|
||||||
ay->quit();
|
ay->quit();
|
||||||
delete ay;
|
delete ay;
|
||||||
delete fm;
|
delete fm;
|
||||||
|
|
|
@ -74,6 +74,7 @@ class DivPlatformYM2610B: public DivDispatch {
|
||||||
pan(3) {}
|
pan(3) {}
|
||||||
};
|
};
|
||||||
Channel chan[16];
|
Channel chan[16];
|
||||||
|
DivDispatchOscBuffer* oscBuf[16];
|
||||||
bool isMuted[16];
|
bool isMuted[16];
|
||||||
struct QueuedWrite {
|
struct QueuedWrite {
|
||||||
unsigned short addr;
|
unsigned short addr;
|
||||||
|
@ -108,6 +109,7 @@ class DivPlatformYM2610B: public DivDispatch {
|
||||||
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
unsigned char* getRegisterPool();
|
unsigned char* getRegisterPool();
|
||||||
int getRegisterPoolSize();
|
int getRegisterPoolSize();
|
||||||
void reset();
|
void reset();
|
||||||
|
|
|
@ -336,13 +336,18 @@ void DivPlatformYM2610BExt::forceIns() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void* DivPlatformYM2610BExt::getChanState(int ch) {
|
void* DivPlatformYM2610BExt::getChanState(int ch) {
|
||||||
if (ch>=6) return &chan[ch-3];
|
if (ch>=6) return &chan[ch-3];
|
||||||
if (ch>=2) return &opChan[ch-2];
|
if (ch>=2) return &opChan[ch-2];
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivDispatchOscBuffer* DivPlatformYM2610BExt::getOscBuffer(int ch) {
|
||||||
|
if (ch>=6) return oscBuf[ch-3];
|
||||||
|
if (ch<3) return oscBuf[ch];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformYM2610BExt::reset() {
|
void DivPlatformYM2610BExt::reset() {
|
||||||
DivPlatformYM2610B::reset();
|
DivPlatformYM2610B::reset();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class DivPlatformYM2610BExt: public DivPlatformYM2610B {
|
||||||
public:
|
public:
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
void reset();
|
void reset();
|
||||||
void forceIns();
|
void forceIns();
|
||||||
void tick(bool sysTick=true);
|
void tick(bool sysTick=true);
|
||||||
|
|
|
@ -343,6 +343,12 @@ void* DivPlatformYM2610Ext::getChanState(int ch) {
|
||||||
return &chan[ch];
|
return &chan[ch];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivDispatchOscBuffer* DivPlatformYM2610Ext::getOscBuffer(int ch) {
|
||||||
|
if (ch>=5) return oscBuf[ch-3];
|
||||||
|
if (ch<2) return oscBuf[ch];
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformYM2610Ext::reset() {
|
void DivPlatformYM2610Ext::reset() {
|
||||||
DivPlatformYM2610::reset();
|
DivPlatformYM2610::reset();
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ class DivPlatformYM2610Ext: public DivPlatformYM2610 {
|
||||||
public:
|
public:
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
|
DivDispatchOscBuffer* getOscBuffer(int chan);
|
||||||
void reset();
|
void reset();
|
||||||
void forceIns();
|
void forceIns();
|
||||||
void tick(bool sysTick=true);
|
void tick(bool sysTick=true);
|
||||||
|
|
Loading…
Reference in a new issue