MSM6258: clock/rate selection

This commit is contained in:
tildearrow 2022-06-04 17:51:59 -05:00
parent 036bf12b89
commit 05c2fb357f
5 changed files with 119 additions and 44 deletions

View file

@ -1,6 +1,5 @@
# to-do for 0.6pre1 # to-do for 0.6pre1
- MSM6258 pitch and clock select
- rewrite the system name detection function anyway - rewrite the system name detection function anyway
- add another FM editor layout - add another FM editor layout
- if macros have release, note off should release them - if macros have release, note off should release them

View file

@ -31,15 +31,25 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
} }
const char* DivPlatformMSM6258::getEffectName(unsigned char effect) { const char* DivPlatformMSM6258::getEffectName(unsigned char effect) {
switch (effect) {
case 0x20:
return "20xx: Set frequency divider (0-2)";
break;
case 0x21:
return "21xx: Select clock rate (0: full; 1: half)";
break;
}
return NULL; return NULL;
} }
void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t len) { void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t len) {
for (size_t h=start; h<start+len; h++) {
short* outs[2]={ short* outs[2]={
&bufL[h], &msmOut,
NULL NULL
}; };
for (size_t h=start; h<start+len; h++) {
if (--msmClockCount<0) {
if (--msmDividerCount<=0) {
if (!writes.empty()) { if (!writes.empty()) {
QueuedWrite& w=writes.front(); QueuedWrite& w=writes.front();
switch (w.addr) { switch (w.addr) {
@ -74,8 +84,15 @@ void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t
} }
msm->sound_stream_update(outs,1); msm->sound_stream_update(outs,1);
msmDividerCount=msmDivider;
}
msmClockCount=msmClock;
}
if (isMuted[0]) { if (isMuted[0]) {
bufL[h]=0; bufL[h]=0;
} else {
bufL[h]=msmOut;
} }
/*if (++updateOsc>=22) { /*if (++updateOsc>=22) {
@ -186,6 +203,14 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
sampleBank=parent->song.sample.size()/12; sampleBank=parent->song.sample.size()/12;
} }
break; break;
case DIV_CMD_SAMPLE_FREQ:
rateSel=c.value&3;
rWrite(12,rateSel);
break;
case DIV_CMD_SAMPLE_MODE:
clockSel=c.value&1;
rWrite(8,clockSel);
break;
case DIV_CMD_LEGATO: { case DIV_CMD_LEGATO: {
break; break;
} }
@ -215,6 +240,8 @@ void DivPlatformMSM6258::forceIns() {
for (int i=0; i<1; i++) { for (int i=0; i<1; i++) {
chan[i].insChanged=true; chan[i].insChanged=true;
} }
rWrite(12,rateSel);
rWrite(8,clockSel);
} }
void* DivPlatformMSM6258::getChanState(int ch) { void* DivPlatformMSM6258::getChanState(int ch) {
@ -244,6 +271,14 @@ void DivPlatformMSM6258::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformMSM6258::reset() { void DivPlatformMSM6258::reset() {
while (!writes.empty()) writes.pop(); while (!writes.empty()) writes.pop();
msm->device_reset(); msm->device_reset();
msmClock=chipClock;
msmDivider=2;
msmDividerCount=0;
msmClock=0;
msmClockCount=0;
msmPan=3;
rateSel=0;
clockSel=0;
if (dumpWrites) { if (dumpWrites) {
addWrite(0xffffffff,0); addWrite(0xffffffff,0);
} }
@ -317,15 +352,24 @@ void DivPlatformMSM6258::renderSamples() {
} }
void DivPlatformMSM6258::setFlags(unsigned int flags) { void DivPlatformMSM6258::setFlags(unsigned int flags) {
if (flags&1) { switch (flags) {
case 3:
chipClock=8192000;
break;
case 2:
chipClock=8000000;
break;
case 1:
chipClock=4096000; chipClock=4096000;
} else { break;
default:
chipClock=4000000; chipClock=4000000;
break;
} }
rate=chipClock/256; rate=chipClock/128;
for (int i=0; i<1; i++) { for (int i=0; i<1; i++) {
isMuted[i]=false; isMuted[i]=false;
oscBuf[i]->rate=rate/256; oscBuf[i]->rate=rate;
} }
} }

View file

@ -87,9 +87,11 @@ class DivPlatformMSM6258: public DivDispatch {
unsigned char* adpcmMem; unsigned char* adpcmMem;
size_t adpcmMemLen; size_t adpcmMemLen;
unsigned char sampleBank, msmPan, msmDivider; unsigned char sampleBank, msmPan, msmDivider, rateSel, msmClock, clockSel;
signed char msmDividerCount, msmClockCount;
short msmOut;
int delay, updateOsc, sample, samplePos, msmClock; int delay, updateOsc, sample, samplePos;
bool extMode; bool extMode;

View file

@ -1975,7 +1975,21 @@ void DivEngine::registerSystems() {
{"Sample"}, {"Sample"},
{"PCM"}, {"PCM"},
{DIV_CH_PCM}, {DIV_CH_PCM},
{DIV_INS_AMIGA} {DIV_INS_AMIGA},
{},
[this](int ch, unsigned char effect, unsigned char effectVal) -> bool {
switch (effect) {
case 0x20: // select rate
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_FREQ,ch,effectVal));
break;
case 0x21: // select clock
dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal));
break;
default:
return false;
}
return true;
}
); );
sysDefs[DIV_SYSTEM_YMZ280B]=new DivSysDef( sysDefs[DIV_SYSTEM_YMZ280B]=new DivSysDef(

View file

@ -415,6 +415,22 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
} }
break; break;
} }
case DIV_SYSTEM_MSM6258: {
ImGui::Text("Clock rate:");
if (ImGui::RadioButton("4MHz",flags==0)) {
copyOfFlags=0;
}
if (ImGui::RadioButton("4.096MHz",flags==1)) {
copyOfFlags=1;
}
if (ImGui::RadioButton("8MHz (X68000)",flags==2)) {
copyOfFlags=2;
}
if (ImGui::RadioButton("8.192MHz",flags==3)) {
copyOfFlags=3;
}
break;
}
case DIV_SYSTEM_MSM6295: { case DIV_SYSTEM_MSM6295: {
ImGui::Text("Clock rate:"); ImGui::Text("Clock rate:");
if (ImGui::RadioButton("1MHz",flags==0)) { if (ImGui::RadioButton("1MHz",flags==0)) {