mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-04 20:05:05 +00:00
parent
28e7b86728
commit
467036df2a
12 changed files with 1171 additions and 17 deletions
|
@ -52,6 +52,9 @@ no plans have been made for TX81Z MIDI passthrough, because:
|
||||||
- `2Bxy`: set EG shift of operator.
|
- `2Bxy`: set EG shift of operator.
|
||||||
- `x` is the operator (1-4). a value of 0 means "all operators".
|
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||||
- `y` is the value.
|
- `y` is the value.
|
||||||
|
- `2Cxy` set fine multiplier of operator.
|
||||||
|
- `x` is the operator (1-4). a value of 0 means "all operators".
|
||||||
|
- `y` is the value.
|
||||||
- `2Fxx`: enable envelope hard reset.
|
- `2Fxx`: enable envelope hard reset.
|
||||||
- this works by inserting a quick release and tiny delay before a new note.
|
- this works by inserting a quick release and tiny delay before a new note.
|
||||||
- `3xyy`: set fixed frequency of operator 1/2.
|
- `3xyy`: set fixed frequency of operator 1/2.
|
||||||
|
|
|
@ -383,6 +383,7 @@ class DivEngine {
|
||||||
bool loadDMF(unsigned char* file, size_t len);
|
bool loadDMF(unsigned char* file, size_t len);
|
||||||
bool loadFur(unsigned char* file, size_t len);
|
bool loadFur(unsigned char* file, size_t len);
|
||||||
bool loadMod(unsigned char* file, size_t len);
|
bool loadMod(unsigned char* file, size_t len);
|
||||||
|
bool loadFTM(unsigned char* file, size_t len);
|
||||||
|
|
||||||
void loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadDMP(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
void loadTFI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
void loadTFI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#define DIV_READ_SIZE 131072
|
#define DIV_READ_SIZE 131072
|
||||||
#define DIV_DMF_MAGIC ".DelekDefleMask."
|
#define DIV_DMF_MAGIC ".DelekDefleMask."
|
||||||
#define DIV_FUR_MAGIC "-Furnace module-"
|
#define DIV_FUR_MAGIC "-Furnace module-"
|
||||||
|
#define DIV_FTM_MAGIC "FamiTracker Module"
|
||||||
|
|
||||||
struct InflateBlock {
|
struct InflateBlock {
|
||||||
unsigned char* buf;
|
unsigned char* buf;
|
||||||
|
@ -1617,8 +1618,6 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
struct InvalidHeaderException {};
|
struct InvalidHeaderException {};
|
||||||
bool success=false;
|
bool success=false;
|
||||||
|
@ -2029,10 +2028,43 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivEngine::loadFTM(unsigned char* file, size_t len) {
|
||||||
|
SafeReader reader=SafeReader(file,len);
|
||||||
|
warnings="";
|
||||||
|
try {
|
||||||
|
DivSong ds;
|
||||||
|
|
||||||
|
if (!reader.seek(18,SEEK_SET)) {
|
||||||
|
logE("premature end of file!");
|
||||||
|
lastError="incomplete file";
|
||||||
|
delete[] file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ds.version=(unsigned short)reader.readS();
|
||||||
|
logI("module version %d (0x%.4x)",ds.version,ds.version);
|
||||||
|
|
||||||
|
if (ds.version>0x0440) {
|
||||||
|
logE("incompatible version %x!",ds.version);
|
||||||
|
lastError="incompatible version";
|
||||||
|
delete[] file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} catch (EndOfFileException& e) {
|
||||||
|
logE("premature end of file!");
|
||||||
|
lastError="incomplete file";
|
||||||
|
delete[] file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delete[] file;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool DivEngine::load(unsigned char* f, size_t slen) {
|
bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
unsigned char* file;
|
unsigned char* file;
|
||||||
size_t len;
|
size_t len;
|
||||||
if (slen<16) {
|
if (slen<18) {
|
||||||
logE("too small!");
|
logE("too small!");
|
||||||
lastError="file is too small";
|
lastError="file is too small";
|
||||||
delete[] f;
|
delete[] f;
|
||||||
|
@ -2137,6 +2169,8 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
|
||||||
// step 2: try loading as .fur or .dmf
|
// step 2: try loading as .fur or .dmf
|
||||||
if (memcmp(file,DIV_DMF_MAGIC,16)==0) {
|
if (memcmp(file,DIV_DMF_MAGIC,16)==0) {
|
||||||
return loadDMF(file,len);
|
return loadDMF(file,len);
|
||||||
|
} else if (memcmp(file,DIV_FTM_MAGIC,18)==0) {
|
||||||
|
return loadFTM(file,len);
|
||||||
} else if (memcmp(file,DIV_FUR_MAGIC,16)==0) {
|
} else if (memcmp(file,DIV_FUR_MAGIC,16)==0) {
|
||||||
return loadFur(file,len);
|
return loadFur(file,len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -650,6 +650,134 @@ int DivPlatformArcade::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT2: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt2=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt2=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_AM_DEPTH: {
|
case DIV_CMD_FM_AM_DEPTH: {
|
||||||
amDepth=c.value;
|
amDepth=c.value;
|
||||||
immWrite(0x19,amDepth);
|
immWrite(0x19,amDepth);
|
||||||
|
|
|
@ -780,7 +780,7 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
}
|
}
|
||||||
} else {
|
} else if (c.value<4) {
|
||||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
op.ar=c.value2&31;
|
op.ar=c.value2&31;
|
||||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
@ -788,6 +788,134 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
chan[c.chan].hardReset=c.value;
|
chan[c.chan].hardReset=c.value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -235,6 +235,134 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_GET_VOLMAX:
|
case DIV_CMD_GET_VOLMAX:
|
||||||
return 127;
|
return 127;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -604,8 +604,10 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_FM_MULT: {
|
case DIV_CMD_FM_MULT: {
|
||||||
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
if (!op.egt) {
|
||||||
op.mult=c.value2&15;
|
op.mult=c.value2&15;
|
||||||
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_TL: {
|
case DIV_CMD_FM_TL: {
|
||||||
|
@ -639,6 +641,221 @@ int DivPlatformTX81Z::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.egt<<5)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.egt<<5)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT2: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt2=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt2=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,(op.d2r&31)|(op.dt2<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
if (!op.egt) {
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
if (!op.egt) {
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_EG_SHIFT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.ksl=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_EGS_REV,(op.dam&7)|(op.ksl<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.ksl=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_EGS_REV,(op.dam&7)|(op.ksl<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_REV: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dam=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_EGS_REV,(op.dam&7)|(op.ksl<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dam=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_EGS_REV,(op.dam&7)|(op.ksl<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_WS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.ws=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.ws=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_FINE: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
if (!op.egt) {
|
||||||
|
op.dvb=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
if (!op.egt) {
|
||||||
|
op.dvb=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_FIXFREQ: {
|
||||||
|
if (c.value<0 || c.value>3) break;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.egt=(c.value2>0);
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.egt<<5)|(op.rs<<6));
|
||||||
|
if (op.egt) {
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,((c.value2>>4)&15)|((c.value2>>8)&7));
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(c.value2&15)|(op.ws<<4));
|
||||||
|
} else {
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|((op.egt?(op.dt&7):dtTable[op.dt&7])<<4));
|
||||||
|
rWrite(baseAddr+ADDR_WS_FINE,(op.dvb&15)|(op.ws<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_AM_DEPTH: {
|
case DIV_CMD_FM_AM_DEPTH: {
|
||||||
amDepth=c.value;
|
amDepth=c.value;
|
||||||
immWrite(0x19,amDepth);
|
immWrite(0x19,amDepth);
|
||||||
|
|
|
@ -1088,6 +1088,134 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
chan[c.chan].hardReset=c.value;
|
chan[c.chan].hardReset=c.value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1066,6 +1066,134 @@ int DivPlatformYM2610B::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[c.chan].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[c.chan]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case DIV_CMD_FM_HARD_RESET:
|
case DIV_CMD_FM_HARD_RESET:
|
||||||
chan[c.chan].hardReset=c.value;
|
chan[c.chan].hardReset=c.value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -175,17 +175,146 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_AR: {
|
case DIV_CMD_FM_AR: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
|
||||||
if (c.value<0) {
|
if (c.value<0) {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[i];
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.ar=c.value2&31;
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
rWrite(baseAddr+0x50,(c.value2&31)|(op.rs<<6));
|
rWrite(baseAddr+0x50,(op.ar&31)|(op.rs<<6));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.ar=c.value2&31;
|
||||||
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
rWrite(baseAddr+0x50,(c.value2&31)|(op.rs<<6));
|
rWrite(baseAddr+0x50,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[2].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[2]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,17 +175,146 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_FM_AR: {
|
case DIV_CMD_FM_AR: {
|
||||||
DivInstrument* ins=parent->getIns(opChan[ch].ins,DIV_INS_FM);
|
|
||||||
if (c.value<0) {
|
if (c.value<0) {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[i];
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.ar=c.value2&31;
|
||||||
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
rWrite(baseAddr+0x50,(c.value2&31)|(op.rs<<6));
|
rWrite(baseAddr+0x50,(op.ar&31)|(op.rs<<6));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DivInstrumentFM::Operator op=ins->fm.op[orderedOps[c.value]];
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.ar=c.value2&31;
|
||||||
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
rWrite(baseAddr+0x50,(c.value2&31)|(op.rs<<6));
|
rWrite(baseAddr+0x50,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RS: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.rs=c.value2&3;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_RS_AR,(op.ar&31)|(op.rs<<6));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_AM: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.am=c.value2&1;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.dr=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_AM_DR,(op.dr&31)|(op.am<<7));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SL: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.sl=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_RR: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.rr=c.value2&15;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SL_RR,(op.rr&15)|(op.sl<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_D2R: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.d2r=c.value2&31;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_DT2_D2R,op.d2r&31);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_DT: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.dt=c.value&7;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.dt=c.value2&7;
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_MULT_DT,(op.mult&15)|(dtTable[op.dt&7]<<4));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DIV_CMD_FM_SSG: {
|
||||||
|
if (c.value<0) {
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[i];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[i];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
|
}
|
||||||
|
} else if (c.value<4) {
|
||||||
|
DivInstrumentFM::Operator& op=chan[1].state.op[orderedOps[c.value]];
|
||||||
|
op.ssgEnv=8^(c.value2&15);
|
||||||
|
unsigned short baseAddr=chanOffs[1]|opOffs[orderedOps[c.value]];
|
||||||
|
rWrite(baseAddr+ADDR_SSG,op.ssgEnv&15);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,6 +496,7 @@ void DivEngine::registerSystems() {
|
||||||
OP_EFFECT_SINGLE(0x28,DIV_CMD_FM_REV,4,7);
|
OP_EFFECT_SINGLE(0x28,DIV_CMD_FM_REV,4,7);
|
||||||
OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
|
OP_EFFECT_SINGLE(0x2a,DIV_CMD_FM_WS,4,7);
|
||||||
OP_EFFECT_SINGLE(0x2b,DIV_CMD_FM_EG_SHIFT,4,3);
|
OP_EFFECT_SINGLE(0x2b,DIV_CMD_FM_EG_SHIFT,4,3);
|
||||||
|
OP_EFFECT_SINGLE(0x2c,DIV_CMD_FM_FINE,4,15);
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue