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
- MSM6258 pitch and clock select
- rewrite the system name detection function anyway
- add another FM editor layout
- if macros have release, note off should release them

View File

@ -31,51 +31,68 @@ const char** DivPlatformMSM6258::getRegisterSheet() {
}
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;
}
void DivPlatformMSM6258::acquire(short* bufL, short* bufR, size_t start, size_t len) {
short* outs[2]={
&msmOut,
NULL
};
for (size_t h=start; h<start+len; h++) {
short* outs[2]={
&bufL[h],
NULL
};
if (!writes.empty()) {
QueuedWrite& w=writes.front();
switch (w.addr) {
case 0:
msm->ctrl_w(w.val);
break;
case 2:
msmPan=w.val;
break;
case 8:
msmClock=w.val;
break;
case 12:
msmDivider=4-(w.val&3);
if (msmDivider<2) msmDivider=2;
break;
}
writes.pop();
}
if (sample>=0 && sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(sample);
unsigned char nextData=(s->dataVOX[samplePos]>>4)|(s->dataVOX[samplePos]<<4);
if (msm->data_w(nextData)) {
samplePos++;
if (samplePos>=(int)s->lengthVOX) {
sample=-1;
samplePos=0;
msm->ctrl_w(1);
if (--msmClockCount<0) {
if (--msmDividerCount<=0) {
if (!writes.empty()) {
QueuedWrite& w=writes.front();
switch (w.addr) {
case 0:
msm->ctrl_w(w.val);
break;
case 2:
msmPan=w.val;
break;
case 8:
msmClock=w.val;
break;
case 12:
msmDivider=4-(w.val&3);
if (msmDivider<2) msmDivider=2;
break;
}
writes.pop();
}
if (sample>=0 && sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(sample);
unsigned char nextData=(s->dataVOX[samplePos]>>4)|(s->dataVOX[samplePos]<<4);
if (msm->data_w(nextData)) {
samplePos++;
if (samplePos>=(int)s->lengthVOX) {
sample=-1;
samplePos=0;
msm->ctrl_w(1);
}
}
}
msm->sound_stream_update(outs,1);
msmDividerCount=msmDivider;
}
msmClockCount=msmClock;
}
msm->sound_stream_update(outs,1);
if (isMuted[0]) {
bufL[h]=0;
} else {
bufL[h]=msmOut;
}
/*if (++updateOsc>=22) {
@ -186,6 +203,14 @@ int DivPlatformMSM6258::dispatch(DivCommand c) {
sampleBank=parent->song.sample.size()/12;
}
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: {
break;
}
@ -215,6 +240,8 @@ void DivPlatformMSM6258::forceIns() {
for (int i=0; i<1; i++) {
chan[i].insChanged=true;
}
rWrite(12,rateSel);
rWrite(8,clockSel);
}
void* DivPlatformMSM6258::getChanState(int ch) {
@ -244,6 +271,14 @@ void DivPlatformMSM6258::poke(std::vector<DivRegWrite>& wlist) {
void DivPlatformMSM6258::reset() {
while (!writes.empty()) writes.pop();
msm->device_reset();
msmClock=chipClock;
msmDivider=2;
msmDividerCount=0;
msmClock=0;
msmClockCount=0;
msmPan=3;
rateSel=0;
clockSel=0;
if (dumpWrites) {
addWrite(0xffffffff,0);
}
@ -317,15 +352,24 @@ void DivPlatformMSM6258::renderSamples() {
}
void DivPlatformMSM6258::setFlags(unsigned int flags) {
if (flags&1) {
chipClock=4096000;
} else {
chipClock=4000000;
switch (flags) {
case 3:
chipClock=8192000;
break;
case 2:
chipClock=8000000;
break;
case 1:
chipClock=4096000;
break;
default:
chipClock=4000000;
break;
}
rate=chipClock/256;
rate=chipClock/128;
for (int i=0; i<1; i++) {
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;
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;

View File

@ -1975,7 +1975,21 @@ void DivEngine::registerSystems() {
{"Sample"},
{"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(

View File

@ -415,6 +415,22 @@ void FurnaceGUI::drawSysConf(int chan, DivSystem type, unsigned int& flags, bool
}
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: {
ImGui::Text("Clock rate:");
if (ImGui::RadioButton("1MHz",flags==0)) {