K007232: acquireDirect()

This commit is contained in:
tildearrow 2025-03-09 18:20:44 -05:00
parent 804e8b7fb8
commit 85981822fa
4 changed files with 66 additions and 44 deletions

View file

@ -8,15 +8,15 @@
#include "k007232.hpp" #include "k007232.hpp"
void k007232_core::tick() void k007232_core::tick(int cycles)
{ {
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
m_voice[i].tick(i); m_voice[i].tick(i,cycles);
} }
} }
void k007232_core::voice_t::tick(u8 ne) void k007232_core::voice_t::tick(u8 ne, int cycles)
{ {
if (m_busy) if (m_busy)
{ {
@ -26,12 +26,12 @@ void k007232_core::voice_t::tick(u8 ne)
// update counter // update counter
if (is4bit) if (is4bit)
{ {
m_counter = (m_counter & ~0x0ff) | (bitfield(bitfield(m_counter, 0, 8) + 1, 0, 8) << 0); m_counter = (m_counter & ~0x0ff) | (bitfield(bitfield(m_counter, 0, 8) + cycles, 0, 8) << 0);
m_counter = (m_counter & ~0xf00) | (bitfield(bitfield(m_counter, 8, 4) + 1, 0, 4) << 8); m_counter = (m_counter & ~0xf00) | (bitfield(bitfield(m_counter, 8, 4) + cycles, 0, 4) << 8);
} }
else else
{ {
m_counter++; m_counter+=cycles;
} }
// handle counter carry // handle counter carry

View file

@ -55,7 +55,7 @@ class k007232_core : public vgsound_emu_core
// internal state // internal state
void reset(); void reset();
void tick(u8 ne); void tick(u8 ne, int cycles);
// accessors // accessors
void write(u8 address, u8 data); void write(u8 address, u8 data);
@ -67,7 +67,7 @@ class k007232_core : public vgsound_emu_core
// getters // getters
inline s8 out() { return m_out; } inline s8 out() { return m_out; }
private: public:
// registers // registers
k007232_core &m_host; k007232_core &m_host;
bool m_busy = false; // busy status bool m_busy = false; // busy status
@ -98,7 +98,7 @@ class k007232_core : public vgsound_emu_core
// internal state // internal state
void reset(); void reset();
void tick(); void tick(int cycles);
// output for each voices, ASD/BSD pin // output for each voices, ASD/BSD pin
inline s32 output(u8 voice) { return m_voice[voice & 1].out(); } inline s32 output(u8 voice) { return m_voice[voice & 1].out(); }
@ -106,7 +106,7 @@ class k007232_core : public vgsound_emu_core
// getters for debug, trackers, etc // getters for debug, trackers, etc
inline u8 reg_r(u8 address) { return m_reg[address & 0xf]; } inline u8 reg_r(u8 address) { return m_reg[address & 0xf]; }
private: public:
std::array<voice_t, 2> m_voice; std::array<voice_t, 2> m_voice;
k007232_intf &m_intf; // common memory interface k007232_intf &m_intf; // common memory interface

View file

@ -54,49 +54,67 @@ inline void DivPlatformK007232::chWrite(unsigned char ch, unsigned int addr, uns
} }
} }
void DivPlatformK007232::acquire(short** buf, size_t len) { void DivPlatformK007232::acquireDirect(blip_buffer_t** bb, size_t len) {
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
oscBuf[i]->begin(len); oscBuf[i]->begin(len);
} }
for (size_t h=0; h<len; h++) { for (size_t h=0; h<len; h++) {
if ((--delay)<=0) { int advance=len-h;
delay=MAX(0,delay); if (!writes.empty()) {
if (!writes.empty()) { advance=1;
QueuedWrite& w=writes.front(); QueuedWrite& w=writes.front();
// write on-chip register // write on-chip register
if (w.addr<=0xd) { if (w.addr<=0xd) {
k007232.write(w.addr,w.val); k007232.write(w.addr,w.val);
}
regPool[w.addr]=w.val;
writes.pop();
delay=w.delay;
} }
regPool[w.addr]=w.val;
writes.pop();
} else {
for (int i=0; i<2; i++) {
if (k007232.m_voice[i].m_busy) {
const int remain=4096-k007232.m_voice[i].m_counter;
if (remain<advance) advance=remain;
}
}
if (advance<1) advance=1;
} }
k007232.tick(); k007232.tick(advance);
h+=advance-1;
if (stereo) { if (stereo) {
const unsigned char vol1=regPool[0x10],vol2=regPool[0x11]; const unsigned char vol1=regPool[0x10],vol2=regPool[0x11];
const signed int lout[2]={(k007232.output(0)*(vol1&0xf)),(k007232.output(1)*(vol2&0xf))}; const signed int lout[2]={(k007232.output(0)*(vol1&0xf)),(k007232.output(1)*(vol2&0xf))};
const signed int rout[2]={(k007232.output(0)*((vol1>>4)&0xf)),(k007232.output(1)*((vol2>>4)&0xf))}; const signed int rout[2]={(k007232.output(0)*((vol1>>4)&0xf)),(k007232.output(1)*((vol2>>4)&0xf))};
buf[0][h]=(lout[0]+lout[1])<<4; const int outL=(lout[0]+lout[1])<<4;
buf[1][h]=(rout[0]+rout[1])<<4; const int outR=(rout[0]+rout[1])<<4;
if (++oscDivider>=8) {
oscDivider=0; if (outL!=lastOut[0]) {
for (int i=0; i<2; i++) { blip_add_delta(bb[0],h,outL-lastOut[0]);
oscBuf[i]->putSample(h,(lout[i]+rout[i])<<3); lastOut[0]=outL;
} }
if (outR!=lastOut[1]) {
blip_add_delta(bb[1],h,outR-lastOut[1]);
lastOut[1]=outR;
}
for (int i=0; i<2; i++) {
oscBuf[i]->putSample(h,(lout[i]+rout[i])<<3);
} }
} else { } else {
const unsigned char vol=regPool[0xc]; const unsigned char vol=regPool[0xc];
const signed int out[2]={(k007232.output(0)*(vol&0xf)),(k007232.output(1)*((vol>>4)&0xf))}; const signed int out[2]={(k007232.output(0)*(vol&0xf)),(k007232.output(1)*((vol>>4)&0xf))};
buf[0][h]=(out[0]+out[1])<<4; const int outFinal=(out[0]+out[1])<<4;
if (++oscDivider>=8) {
oscDivider=0; if (outFinal!=lastOut[0]) {
for (int i=0; i<2; i++) { blip_add_delta(bb[0],h,outFinal-lastOut[0]);
oscBuf[i]->putSample(h,out[i]<<4); lastOut[0]=outFinal;
} }
for (int i=0; i<2; i++) {
oscBuf[i]->putSample(h,out[i]<<4);
} }
} }
} }
@ -456,7 +474,8 @@ void DivPlatformK007232::reset() {
k007232.reset(); k007232.reset();
lastLoop=0; lastLoop=0;
lastVolume=0; lastVolume=0;
delay=0; lastOut[0]=0;
lastOut[1]=0;
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
chan[i]=DivPlatformK007232::Channel(); chan[i]=DivPlatformK007232::Channel();
chan[i].std.setEngine(parent); chan[i].std.setEngine(parent);
@ -474,6 +493,10 @@ int DivPlatformK007232::getOutputCount() {
return stereo?2:1; return stereo?2:1;
} }
bool DivPlatformK007232::hasAcquireDirect() {
return true;
}
void DivPlatformK007232::notifyInsChange(int ins) { void DivPlatformK007232::notifyInsChange(int ins) {
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
if (chan[i].ins==ins) { if (chan[i].ins==ins) {
@ -601,7 +624,6 @@ int DivPlatformK007232::init(DivEngine* p, int channels, int sugRate, const DivC
} }
sampleMem=new unsigned char[getSampleMemCapacity()]; sampleMem=new unsigned char[getSampleMemCapacity()];
sampleMemLen=0; sampleMemLen=0;
oscDivider=0;
setFlags(flags); setFlags(flags);
reset(); reset();

View file

@ -52,16 +52,15 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
}; };
Channel chan[2]; Channel chan[2];
DivDispatchOscBuffer* oscBuf[2]; DivDispatchOscBuffer* oscBuf[2];
int lastOut[2];
bool isMuted[2]; bool isMuted[2];
struct QueuedWrite { struct QueuedWrite {
unsigned short addr; unsigned short addr;
unsigned char val; unsigned char val;
unsigned short delay; QueuedWrite(): addr(0), val(0) {}
QueuedWrite(): addr(0), val(0), delay(1) {} QueuedWrite(unsigned short a, unsigned char v):
QueuedWrite(unsigned short a, unsigned char v, unsigned short d=1):
addr(a), addr(a),
val(v), val(v) {}
delay(d) {}
}; };
FixedQueue<QueuedWrite,256> writes; FixedQueue<QueuedWrite,256> writes;
unsigned int sampleOffK007232[256]; unsigned int sampleOffK007232[256];
@ -82,7 +81,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
void chWrite(unsigned char ch, unsigned int addr, unsigned char val); void chWrite(unsigned char ch, unsigned int addr, unsigned char val);
public: public:
u8 read_sample(u8 ne, u32 address); u8 read_sample(u8 ne, u32 address);
void acquire(short** buf, size_t len); void acquireDirect(blip_buffer_t** bb, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void* getChanState(int chan); void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch); DivMacroInt* getChanMacroInt(int ch);
@ -95,6 +94,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
void tick(bool sysTick=true); void tick(bool sysTick=true);
void muteChannel(int ch, bool mute); void muteChannel(int ch, bool mute);
int getOutputCount(); int getOutputCount();
bool hasAcquireDirect();
void notifyInsChange(int ins); void notifyInsChange(int ins);
void notifyWaveChange(int wave); void notifyWaveChange(int wave);
void notifyInsDeletion(void* ins); void notifyInsDeletion(void* ins);