C140 Part 2

This commit is contained in:
cam900 2023-08-09 20:30:00 +09:00
parent 54cd69aabf
commit 14c5d94499
21 changed files with 210 additions and 56 deletions

View File

@ -80,6 +80,7 @@
#include "platform/pv1000.h"
#include "platform/k053260.h"
#include "platform/ted.h"
#include "platform/c140.h"
#include "platform/pcmdac.h"
#include "platform/dummy.h"
#include "../ta-log.h"
@ -504,6 +505,9 @@ void DivDispatchContainer::init(DivSystem sys, DivEngine* eng, int chanCount, do
case DIV_SYSTEM_TED:
dispatch=new DivPlatformTED;
break;
case DIV_SYSTEM_C140:
dispatch=new DivPlatformC140;
break;
case DIV_SYSTEM_PCM_DAC:
dispatch=new DivPlatformPCMDAC;
break;

View File

@ -963,6 +963,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song) {
break;
case DIV_INS_TED:
break;
case DIV_INS_C140:
featureSM=true;
featureSL=true;
break;
case DIV_INS_MAX:
break;

View File

@ -83,6 +83,7 @@ enum DivInstrumentType: unsigned short {
DIV_INS_K053260=50,
// DIV_INS_YMF292=51,
DIV_INS_TED=52,
DIV_INS_C140=53,
DIV_INS_MAX,
DIV_INS_NULL
};

View File

@ -80,10 +80,9 @@ void DivPlatformC140::tick(bool sysTick) {
chan[i].std.next();
if (chan[i].std.vol.had) {
chan[i].outVol=(chan[i].vol*MIN(chan[i].macroVolMul,chan[i].std.vol.val))/chan[i].macroVolMul;
chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/255;
chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/255;
rWrite(1+(i<<4),chan[i].chVolL);
rWrite(0+(i<<4),chan[i].chVolR);
if (!isMuted[i]) {
chan[i].volumeChanged.changed=0xff;
}
}
if (NEW_ARP_STRAT) {
chan[i].handleArp();
@ -104,14 +103,16 @@ void DivPlatformC140::tick(bool sysTick) {
}
if (chan[i].std.panL.had) {
chan[i].chPanL=chan[i].std.panL.val&255;
chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/255;
rWrite(1+(i<<4),chan[i].chVolL);
if (!isMuted[i]) {
chan[i].volumeChanged.left=1;
}
}
if (chan[i].std.panR.had) {
chan[i].chPanR=chan[i].std.panR.val&255;
chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/255;
rWrite(0+(i<<4),chan[i].chVolR);
if (!isMuted[i]) {
chan[i].volumeChanged.right=1;
}
}
if (chan[i].std.phaseReset.had) {
@ -120,6 +121,25 @@ void DivPlatformC140::tick(bool sysTick) {
chan[i].setPos=true;
}
}
if (chan[i].volumeChanged.changed) {
if (chan[i].volumeChanged.left) {
if (isMuted[i]) {
chan[i].chVolL=0;
} else {
chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/255;
}
rWrite(1+(i<<4),chan[i].chVolL);
}
if (chan[i].volumeChanged.right) {
if (isMuted[i]) {
chan[i].chVolR=0;
} else {
chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/255;
}
rWrite(0+(i<<4),chan[i].chVolR);
}
chan[i].volumeChanged.changed=0;
}
if (chan[i].setPos) {
// force keyon
chan[i].keyOn=true;
@ -141,7 +161,7 @@ void DivPlatformC140::tick(bool sysTick) {
unsigned int end=0;
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
start=sampleOff[chan[i].sample];
end=MIN(start+s->getCurBufLen(),getSampleMemCapacity()-1);
end=MIN(start+s->length8,getSampleMemCapacity()-1);
}
if (chan[i].audPos>0) {
start=start+MIN(chan[i].audPos,s->length8);
@ -149,19 +169,18 @@ void DivPlatformC140::tick(bool sysTick) {
if (s->isLoopable()) {
loop=start+s->loopStart;
}
rWrite(0x05+i*16,ctrl&~0x80); // force keyoff first
rWrite(0x06+i*16,(start>>8)&0xff);
rWrite(0x07+i*16,start&0xff);
rWrite(0x08+i*16,(end>>8)&0xff);
rWrite(0x09+i*16,end&0xff);
rWrite(0x0a+i*16,(loop>>8)&0xff);
rWrite(0x0b+i*16,loop&0xff);
rWrite(0x05+(i<<4),0); // force keyoff first
rWrite(0x06+(i<<4),(start>>8)&0xff);
rWrite(0x07+(i<<4),start&0xff);
rWrite(0x08+(i<<4),(end>>8)&0xff);
rWrite(0x09+(i<<4),end&0xff);
rWrite(0x0a+(i<<4),(loop>>8)&0xff);
rWrite(0x0b+(i<<4),loop&0xff);
if (!chan[i].std.vol.had) {
chan[i].outVol=chan[i].vol;
chan[i].chVolL=(chan[i].outVol*chan[i].chPanL)/255;
chan[i].chVolR=(chan[i].outVol*chan[i].chPanR)/255;
rWrite(1+(i<<4),chan[i].chVolL);
rWrite(0+(i<<4),chan[i].chVolR);
if (!isMuted[i]) {
chan[i].volumeChanged.changed=0xff;
}
}
chan[i].keyOn=false;
}
@ -169,11 +188,11 @@ void DivPlatformC140::tick(bool sysTick) {
chan[i].keyOff=false;
}
if (chan[i].freqChanged) {
rWrite(0x02+i*16,chan[i].freq&0xff);
rWrite(0x03+i*16,chan[i].freq>>8);
rWrite(0x02+(i<<4),chan[i].freq>>8);
rWrite(0x03+(i<<4),chan[i].freq&0xff);
chan[i].freqChanged=false;
}
rWrite(0x05+i*16,ctrl);
rWrite(0x05+(i<<4),ctrl);
}
}
}
@ -182,7 +201,6 @@ int DivPlatformC140::dispatch(DivCommand c) {
switch (c.cmd) {
case DIV_CMD_NOTE_ON: {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_AMIGA);
chan[c.chan].isNewYMZ=ins->type==DIV_INS_YMZ280B;
chan[c.chan].macroVolMul=ins->type==DIV_INS_AMIGA?64:255;
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].sample=ins->amiga.getSample(c.value);
@ -203,11 +221,9 @@ int DivPlatformC140::dispatch(DivCommand c) {
chan[c.chan].macroInit(ins);
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
chan[c.chan].outVol=chan[c.chan].vol;
chan[c.chan].chVolL=(chan[c.chan].outVol*chan[c.chan].chPanL)/255;
chan[c.chan].chVolR=(chan[c.chan].outVol*chan[c.chan].chPanR)/255;
rWrite(1+(c.chan<<4),chan[c.chan].chVolL);
rWrite(0+(c.chan<<4),chan[c.chan].chVolR);
if (!isMuted[c.chan]) {
chan[c.chan].volumeChanged.changed=0xff;
}
}
break;
}
@ -231,10 +247,9 @@ int DivPlatformC140::dispatch(DivCommand c) {
if (!chan[c.chan].std.vol.has) {
chan[c.chan].outVol=c.value;
}
chan[c.chan].chVolL=(c.value*chan[c.chan].chPanL)/255;
chan[c.chan].chVolR=(c.value*chan[c.chan].chPanR)/255;
rWrite(1+(c.chan<<4),chan[c.chan].chVolL);
rWrite(0+(c.chan<<4),chan[c.chan].chVolR);
if (!isMuted[c.chan]) {
chan[c.chan].volumeChanged.changed=0xff;
}
break;
case DIV_CMD_GET_VOLUME:
if (chan[c.chan].std.vol.has) {
@ -245,10 +260,9 @@ int DivPlatformC140::dispatch(DivCommand c) {
case DIV_CMD_PANNING:
chan[c.chan].chPanL=c.value;
chan[c.chan].chPanR=c.value2;
chan[c.chan].chVolL=(chan[c.chan].outVol*chan[c.chan].chPanL)/255;
chan[c.chan].chVolR=(chan[c.chan].outVol*chan[c.chan].chPanR)/255;
rWrite(1+(c.chan<<4),chan[c.chan].chVolL);
rWrite(0+(c.chan<<4),chan[c.chan].chVolR);
if (!isMuted[c.chan]) {
chan[c.chan].volumeChanged.changed=0xff;
}
break;
case DIV_CMD_PITCH:
chan[c.chan].pitch=c.value;
@ -314,12 +328,14 @@ int DivPlatformC140::dispatch(DivCommand c) {
void DivPlatformC140::muteChannel(int ch, bool mute) {
isMuted[ch]=mute;
chan[ch].volumeChanged.changed=0xff;
}
void DivPlatformC140::forceIns() {
for (int i=0; i<24; i++) {
chan[i].insChanged=true;
chan[i].freqChanged=true;
chan[i].volumeChanged.changed=0xff;
chan[i].sample=-1;
}
}
@ -343,7 +359,7 @@ void DivPlatformC140::reset() {
for (int i=0; i<24; i++) {
chan[i]=DivPlatformC140::Channel();
chan[i].std.setEngine(parent);
rWrite(0x05+i*16,0);
rWrite(0x05+(i<<4),0);
}
}
@ -435,7 +451,7 @@ void DivPlatformC140::renderSamples(int sysID) {
} else {
memcpy(sampleMem+(memPos/sizeof(short)),s->data16,length);
}
sampleOff[i]=memPos;
sampleOff[i]=memPos>>1;
sampleLoaded[i]=true;
memPos+=length;
}
@ -447,7 +463,7 @@ void DivPlatformC140::setChipModel(int type) {
}
void DivPlatformC140::setFlags(const DivConfig& flags) {
chipClock = 8192000;
chipClock=32000*256; // 8.192MHz and 12.288MHz input, verified from Assault Schematics
CHECK_CUSTOM_CLOCK;
rate=chipClock/192;
for (int i=0; i<24; i++) {
@ -464,9 +480,10 @@ int DivPlatformC140::init(DivEngine* p, int channels, int sugRate, const DivConf
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
sampleMem=new unsigned char[getSampleMemCapacity()];
sampleMem=new signed short[getSampleMemCapacity()/sizeof(short)];
sampleMemLen=0;
c140_init(&c140);
c140.sample_mem=sampleMem;
setFlags(flags);
reset();

View File

@ -26,21 +26,33 @@
class DivPlatformC140: public DivDispatch {
struct Channel: public SharedChannel<int> {
struct VolumeUpdate {
union { // pack flag bits in single byte
struct { // flag bits
unsigned char left : 1; // left volume
unsigned char right : 1; // right volume
unsigned char reserved : 6;
};
unsigned char changed = 0; // Packed flags are stored here
};
VolumeUpdate():
changed(0) {}
} volumeChanged;
unsigned int audPos;
int sample, wave;
int panning;
bool setPos, isNewYMZ;
bool setPos;
int chPanL, chPanR;
int chVolL, chVolR;
int macroVolMul;
Channel():
SharedChannel<int>(255),
volumeChanged(VolumeUpdate()),
audPos(0),
sample(-1),
wave(-1),
panning(8),
setPos(false),
isNewYMZ(false),
chPanL(255),
chPanR(255),
chVolL(255),
@ -54,7 +66,7 @@ class DivPlatformC140: public DivDispatch {
unsigned int sampleOff[256];
bool sampleLoaded[256];
unsigned char* sampleMem;
signed short* sampleMem;
size_t sampleMemLen;
struct QueuedWrite {
unsigned short addr;
@ -97,6 +109,7 @@ class DivPlatformC140: public DivDispatch {
void setFlags(const DivConfig& flags);
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
private:
};
#endif

View File

@ -46,6 +46,8 @@ static int c140_bit(int val, int bit) { return (val >> bit) & 1; }
void c140_tick(struct c140_t *c140, const int cycle)
{
c140->lout = 0;
c140->rout = 0;
for (int i = 0; i < 24; i++)
{
c140_voice_tick(c140, i, cycle);
@ -53,8 +55,8 @@ void c140_tick(struct c140_t *c140, const int cycle)
c140->rout += c140->voice[i].rout;
}
// scale as 16bit
c140->lout >>= 5;
c140->rout >>= 5;
c140->lout >>= 8;
c140->rout >>= 8;
}
void c140_voice_tick(struct c140_t *c140, const unsigned char voice, const int cycle)
@ -82,8 +84,8 @@ void c140_voice_tick(struct c140_t *c140, const unsigned char voice, const int c
c140_voice->frac &= 0xffff;
}
// fetch 12 bit sample
signed short s1 = c140->read_sample(c140_voice->bank, c140_voice->addr) & ~0xf;
signed short s2 = c140->read_sample(c140_voice->bank, c140_voice->addr + 1) & ~0xf;
signed short s1 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | c140_voice->addr] & ~0xf;
signed short s2 = c140->sample_mem[((unsigned int)(c140_voice->bank) << 16) | ((c140_voice->addr + 1) & 0xffff)] & ~0xf;
if (c140_voice->compressed)
{
s1 = c140->mulaw[(s1 >> 8) & 0xff];

View File

@ -69,7 +69,7 @@ struct c140_t
struct c140_voice_t voice[24];
signed int lout, rout;
signed short mulaw[256];
unsigned short (*read_sample)(unsigned char bank, unsigned short addr);
signed short *sample_mem;
};
void c140_tick(struct c140_t *c140, const int cycle);

View File

@ -129,7 +129,8 @@ enum DivSystem {
DIV_SYSTEM_SM8521,
DIV_SYSTEM_PV1000,
DIV_SYSTEM_K053260,
DIV_SYSTEM_TED
DIV_SYSTEM_TED,
DIV_SYSTEM_C140
};
enum DivEffectType: unsigned short {

View File

@ -1872,6 +1872,18 @@ void DivEngine::registerSystems() {
{}
);
// TODO: Custom sample format
sysDefs[DIV_SYSTEM_C140]=new DivSysDef(
"Namco C140", NULL, 0xfe/*Placeholder*/, 0, 24, false, true, 0x161, false, 1U<<DIV_SAMPLE_DEPTH_8BIT,
"Namco's first PCM chip arrived from 1987.",
{"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6", "Channel 7", "Channel 8", "Channel 9", "Channel 10", "Channel 11", "Channel 12", "Channel 13", "Channel 14", "Channel 15", "Channel 16", "Channel 17", "Channel 18", "Channel 19", "Channel 20", "Channel 21", "Channel 22", "Channel 23", "Channel 24"},
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"},
{DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM, DIV_CH_PCM},
{DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140, DIV_INS_C140},
{DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA, DIV_INS_AMIGA},
{}
);
sysDefs[DIV_SYSTEM_DUMMY]=new DivSysDef(
"Dummy System", NULL, 0xfd, 0, 8, false, true, 0, false, 0,
"this is a system designed for testing purposes.",

View File

@ -583,6 +583,19 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(0);
}
break;
case DIV_SYSTEM_C140:
for (int i=0; i<24; i++) {
w->writeC(0xd4); // mute
w->writeS(baseAddr2S|(i<<4)|0);
w->writeC(0);
w->writeC(0xd4);
w->writeS(baseAddr2S|(i<<4)|1);
w->writeC(0);
w->writeC(0xd4); // keyoff
w->writeS(baseAddr2S|(i<<4)|5);
w->writeC(0);
}
break;
default:
break;
}
@ -1044,6 +1057,11 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
w->writeC(baseAddr2|(write.addr&0x3f));
w->writeC(write.val&0xff);
break;
case DIV_SYSTEM_C140:
w->writeC(0xd4);
w->writeC(baseAddr2S|(write.addr&0x1ff));
w->writeC(write.val&0xff);
break;
default:
logW("write not handled!");
break;
@ -1217,6 +1235,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
DivDispatch* writeMSM6295[2]={NULL,NULL};
DivDispatch* writeGA20[2]={NULL,NULL};
DivDispatch* writeK053260[2]={NULL,NULL};
DivDispatch* writeC140[2]={NULL,NULL};
DivDispatch* writeNES[2]={NULL,NULL};
int writeNESIndex[2]={0,0};
@ -1765,6 +1784,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
willExport[i]=true;
}
break;
case DIV_SYSTEM_C140:
if (!hasNamco) {
hasNamco=disCont[i].dispatch->chipClock;
CHIP_VOL(40,0.4);
willExport[i]=true;
writeC140[0]=disCont[i].dispatch;
} else if (!(hasNamco&0x40000000)) {
isSecond[i]=true;
CHIP_VOL_SECOND(40,0.4);
willExport[i]=true;
writeC140[1]=disCont[i].dispatch;
hasNamco|=0x40000000;
howManyChips++;
}
break;
default:
break;
}
@ -2163,6 +2197,15 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
w->writeI(0);
w->write(writeES5506[i]->getSampleMem(),writeES5506[i]->getSampleMemUsage());
}
if (writeC140[i]!=NULL && writeC140[i]->getSampleMemUsage()>0) {
w->writeC(0x67);
w->writeC(0x66);
w->writeC(0x8d);
w->writeI((writeC140[i]->getSampleMemUsage()+8)|(i*0x80000000));
w->writeI(writeC140[i]->getSampleMemCapacity());
w->writeI(0);
w->write(writeC140[i]->getSampleMem(),writeC140[i]->getSampleMemUsage());
}
}
// initialize streams

View File

@ -286,6 +286,10 @@ void FurnaceGUI::insListItem(int i, int dir, int asset) {
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_TED]);
name=fmt::sprintf(ICON_FA_BAR_CHART "##_INS%d",i);
break;
case DIV_INS_C140:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_C140]);
name=fmt::sprintf(ICON_FA_BAR_CHART "##_INS%d",i);
break;
default:
ImGui::PushStyleColor(ImGuiCol_Text,uiColors[GUI_COLOR_INSTR_UNKNOWN]);
name=fmt::sprintf(ICON_FA_QUESTION "##_INS%d",i);

View File

@ -54,6 +54,7 @@
#include "../engine/platform/sm8521.h"
#include "../engine/platform/pv1000.h"
#include "../engine/platform/k053260.h"
#include "../engine/platform/c140.h"
#include "../engine/platform/dummy.h"
#define COMMON_CHIP_DEBUG \
@ -1093,6 +1094,23 @@ void putDispatchChan(void* data, int chanNum, int type) {
ImGui::TextColored(ch->reverse?colorOn:colorOff,">> Reverse");
break;
}
case DIV_SYSTEM_C140: {
DivPlatformC140::Channel* ch=(DivPlatformC140::Channel*)data;
ImGui::Text("> C140");
COMMON_CHAN_DEBUG;
ImGui::Text("* Sample: %d",ch->sample);
ImGui::Text(" - pos: %d",ch->audPos);
ImGui::Text("- chPanL: %.2x",ch->chPanL);
ImGui::Text("- chPanR: %.2x",ch->chPanR);
ImGui::Text("- chVolL: %.2x",ch->chVolL);
ImGui::Text("- chVolR: %.2x",ch->chVolR);
ImGui::Text("- macroVolMul: %.2x",ch->macroVolMul);
COMMON_CHAN_DEBUG_BOOL;
ImGui::TextColored(ch->volumeChanged.left?colorOn:colorOff,">> VolumeChangedLeft");
ImGui::TextColored(ch->volumeChanged.right?colorOn:colorOff,">> VolumeChangedRight");
ImGui::TextColored(ch->setPos?colorOn:colorOff,">> SetPos");
break;
}
default:
ImGui::Text("Unimplemented chip! Help!");
break;

View File

@ -1396,7 +1396,8 @@ void FurnaceGUI::doAction(int what) {
i==DIV_INS_ES5506 ||
i==DIV_INS_K007232 ||
i==DIV_INS_GA20 ||
i==DIV_INS_K053260) {
i==DIV_INS_K053260 ||
i==DIV_INS_C140) {
makeInsTypeList.push_back(i);
}
}

View File

@ -258,6 +258,7 @@ enum FurnaceGUIColors {
GUI_COLOR_INSTR_K053260,
GUI_COLOR_INSTR_SCSP,
GUI_COLOR_INSTR_TED,
GUI_COLOR_INSTR_C140,
GUI_COLOR_INSTR_UNKNOWN,
GUI_COLOR_CHANNEL_BG,

View File

@ -170,6 +170,7 @@ const char* insTypes[DIV_INS_MAX+1]={
"K053260",
"SCSP",
"TED",
"C140",
NULL
};
@ -934,6 +935,7 @@ const FurnaceGUIColorDef guiColors[GUI_COLOR_MAX]={
D(GUI_COLOR_INSTR_K053260,"",ImVec4(1.0f,0.8f,0.1f,1.0f)),
D(GUI_COLOR_INSTR_SCSP,"",ImVec4(0.5f,0.5f,0.5f,1.0f)),
D(GUI_COLOR_INSTR_TED,"",ImVec4(0.7f,0.6f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_C140,"",ImVec4(0.7f,0.6f,1.0f,1.0f)),
D(GUI_COLOR_INSTR_UNKNOWN,"",ImVec4(0.3f,0.3f,0.3f,1.0f)),
D(GUI_COLOR_CHANNEL_BG,"",ImVec4(0.4f,0.6f,0.8f,1.0f)),
@ -1119,6 +1121,7 @@ const int availableSystems[]={
DIV_SYSTEM_PV1000,
DIV_SYSTEM_K053260,
DIV_SYSTEM_TED,
DIV_SYSTEM_C140,
DIV_SYSTEM_PCM_DAC,
DIV_SYSTEM_PONG,
0 // don't remove this last one!
@ -1229,6 +1232,7 @@ const int chipsSample[]={
DIV_SYSTEM_PCM_DAC,
DIV_SYSTEM_ES5506,
DIV_SYSTEM_K053260,
DIV_SYSTEM_C140,
0 // don't remove this last one!
};

View File

@ -4411,7 +4411,8 @@ void FurnaceGUI::drawInsEdit() {
ins->type==DIV_INS_ES5506 ||
ins->type==DIV_INS_K007232 ||
ins->type==DIV_INS_GA20 ||
ins->type==DIV_INS_K053260) {
ins->type==DIV_INS_K053260 ||
ins->type==DIV_INS_C140) {
if (ImGui::BeginTabItem((ins->type==DIV_INS_SU)?"Sound Unit":"Sample")) {
String sName;
bool wannaOpenSMPopup=false;
@ -5397,7 +5398,7 @@ void FurnaceGUI::drawInsEdit() {
volMax=31;
}
if (ins->type==DIV_INS_ADPCMB || ins->type==DIV_INS_YMZ280B || ins->type==DIV_INS_RF5C68 ||
ins->type==DIV_INS_GA20) {
ins->type==DIV_INS_GA20 || ins->type==DIV_INS_C140) {
volMax=255;
}
if (ins->type==DIV_INS_QSOUND) {
@ -5457,7 +5458,8 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_TIA || ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SCC ||
ins->type==DIV_INS_PET || ins->type==DIV_INS_SEGAPCM ||
ins->type==DIV_INS_FM || ins->type==DIV_INS_K007232 || ins->type==DIV_INS_GA20 ||
ins->type==DIV_INS_SM8521 || ins->type==DIV_INS_PV1000 || ins->type==DIV_INS_K053260) {
ins->type==DIV_INS_SM8521 || ins->type==DIV_INS_PV1000 || ins->type==DIV_INS_K053260 ||
ins->type==DIV_INS_C140) {
dutyMax=0;
}
if (ins->type==DIV_INS_VBOY) {
@ -5565,6 +5567,7 @@ void FurnaceGUI::drawInsEdit() {
if (ins->type==DIV_INS_K053260) waveMax=0;
if (ins->type==DIV_INS_POKEMINI) waveMax=0;
if (ins->type==DIV_INS_TED) waveMax=0;
if (ins->type==DIV_INS_C140) waveMax=0;
if (ins->type==DIV_INS_SU || ins->type==DIV_INS_POKEY) waveMax=7;
if (ins->type==DIV_INS_PET) {
waveMax=8;
@ -5695,6 +5698,10 @@ void FurnaceGUI::drawInsEdit() {
panMin=0;
panMax=127;
}
if (ins->type==DIV_INS_C140) {
panMin=0;
panMax=255;
}
if (ins->type==DIV_INS_ES5506) {
panMax=4095;
}
@ -5780,6 +5787,7 @@ void FurnaceGUI::drawInsEdit() {
ins->type==DIV_INS_K007232 ||
ins->type==DIV_INS_GA20 ||
ins->type==DIV_INS_K053260 ||
ins->type==DIV_INS_C140 ||
ins->type==DIV_INS_TED) {
macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true));
}

View File

@ -2024,6 +2024,12 @@ void FurnaceGUI::initSystemPresets() {
) // ""
}
);
ENTRY(
"Namco System 2", {
CH(DIV_SYSTEM_YM2151, 1.0f, 0, ""),
CH(DIV_SYSTEM_C140, 1.0f, 0, "")
}
);
ENTRY(
"Taito Arcade", {
CH(DIV_SYSTEM_YM2610B, 1.0f, 0, "")
@ -2530,6 +2536,11 @@ void FurnaceGUI::initSystemPresets() {
CH(DIV_SYSTEM_K053260, 1.0f, 0, "")
}
);
ENTRY(
"Namco C140", {
CH(DIV_SYSTEM_C140, 1.0f, 0, "")
}
);
CATEGORY_END;
CATEGORY_BEGIN("Wavetable","chips which use user-specified waveforms to generate sound.");

View File

@ -277,6 +277,11 @@ void FurnaceGUI::drawSampleEdit() {
SAMPLE_WARN(warnLength,"K053260: maximum sample length is 65535");
}
break;
case DIV_SYSTEM_C140:
if (sample->samples>65535) {
SAMPLE_WARN(warnLength,"C140: maximum sample length is 65535");
}
break;
default:
break;
}

View File

@ -2671,6 +2671,7 @@ void FurnaceGUI::drawSettings() {
UI_COLOR_CONFIG(GUI_COLOR_INSTR_SM8521,"SM8521");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_PV1000,"PV-1000");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_K053260,"K053260");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_C140,"C140");
UI_COLOR_CONFIG(GUI_COLOR_INSTR_UNKNOWN,"Other/Unknown");
ImGui::TreePop();
}

View File

@ -2052,6 +2052,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo
case DIV_SYSTEM_GA20:
case DIV_SYSTEM_PV1000:
case DIV_SYSTEM_VERA:
case DIV_SYSTEM_C140:
break;
case DIV_SYSTEM_YMU759:
supportsCustomRate=false;

View File

@ -265,6 +265,9 @@ const char* FurnaceGUI::getSystemPartNumber(DivSystem sys, DivConfig& flags) {
case DIV_SYSTEM_TED:
return "TED";
break;
case DIV_SYSTEM_C140:
return "C140";
break;
default:
return FurnaceGUI::getSystemName(sys);
break;