Namco 163 memory composition

This commit is contained in:
tildearrow 2024-03-14 17:58:55 -05:00
parent d33e645ea8
commit 898155eb6b
12 changed files with 111 additions and 8 deletions

View file

@ -441,6 +441,8 @@ enum DivMemoryEntryType {
DIV_MEMORY_WAVE_RAM,
DIV_MEMORY_WAVE_STATIC,
DIV_MEMORY_ECHO,
DIV_MEMORY_N163_LOAD,
DIV_MEMORY_N163_PLAY,
DIV_MEMORY_BANK0,
DIV_MEMORY_BANK1,
DIV_MEMORY_BANK2,
@ -470,15 +472,25 @@ struct DivMemoryEntry {
end(0) {}
};
enum DivMemoryWaveView: unsigned char {
DIV_MEMORY_WAVE_NONE=0,
DIV_MEMORY_WAVE_4BIT, // Namco 163
DIV_MEMORY_WAVE_6BIT, // Virtual Boy
};
struct DivMemoryComposition {
std::vector<DivMemoryEntry> entries;
String name;
size_t capacity;
size_t used;
const unsigned char* memory;
DivMemoryWaveView waveformView;
DivMemoryComposition():
name(""),
capacity(0),
used(0) {}
used(0),
memory(NULL),
waveformView(DIV_MEMORY_WAVE_NONE) {}
};
class DivEngine;

View file

@ -542,7 +542,7 @@ class DivEngine {
void testFunction();
bool loadDMF(unsigned char* file, size_t len);
bool loadFur(unsigned char* file, size_t len);
bool loadFur(unsigned char* file, size_t len, int variantID=0);
bool loadMod(unsigned char* file, size_t len);
bool loadS3M(unsigned char* file, size_t len);
bool loadFTM(unsigned char* file, size_t len);

View file

@ -131,6 +131,8 @@ bool DivEngine::load(unsigned char* f, size_t slen) {
return loadFTM(file,len);
} else if (memcmp(file,DIV_FUR_MAGIC,16)==0) {
return loadFur(file,len);
} else if (memcmp(file,DIV_FUR_MAGIC_DS0,16)==0) {
return loadFur(file,len,DIV_FUR_VARIANT_B);
} else if (memcmp(file,DIV_FC13_MAGIC,4)==0 || memcmp(file,DIV_FC14_MAGIC,4)==0) {
return loadFC(file,len);
}

View file

@ -52,3 +52,10 @@ struct NotZlibException {
#define DIV_FC13_MAGIC "SMOD"
#define DIV_FC14_MAGIC "FC14"
#define DIV_S3M_MAGIC "SCRM"
#define DIV_FUR_MAGIC_DS0 "Furnace-B module"
enum DivFurVariants: int {
DIV_FUR_VARIANT_VANILLA=0,
DIV_FUR_VARIANT_B=1,
};

View file

@ -691,7 +691,7 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
}
}
bool DivEngine::loadFur(unsigned char* file, size_t len) {
bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
unsigned int insPtr[256];
unsigned int wavePtr[256];
unsigned int samplePtr[256];
@ -720,6 +720,11 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) {
ds.version=reader.readS();
logI("module version %d (0x%.2x)",ds.version,ds.version);
if (variantID!=DIV_FUR_VARIANT_VANILLA) {
logW("Furnace variant detected: %d",variantID);
addWarning("this module was created with a downstream version of Furnace. certain features may not be compatible.");
}
if (ds.version>DIV_ENGINE_VERSION) {
logW("this module was created with a more recent version of Furnace!");
addWarning("this module was created with a more recent version of Furnace!");

View file

@ -2952,6 +2952,8 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version, DivS
type=0;
} else if (memcmp(magic,"INS2",4)==0) {
type=1;
} else if (memcmp(magic,"IN2B",4)==0) { // DIV_FUR_VARIANT_B
type=1;
} else if (memcmp(magic,"FINS",4)==0) {
type=2;
} else {

View file

@ -279,6 +279,19 @@ void DivPlatformN163::tick(bool sysTick) {
chan[i].freqChanged=false;
}
}
// update memory composition positions
for (int i=0; i<=chanMax; i++) {
memCompo.entries[i].begin=chan[i].wavePos>>1;
memCompo.entries[i].end=(chan[i].wavePos+chan[i].waveLen)>>1;
memCompo.entries[i+8].begin=chan[i].curWavePos>>1;
memCompo.entries[i+8].end=(chan[i].curWavePos+chan[i].curWaveLen)>>1;
}
// update register pool
for (int i=0; i<128; i++) {
regPool[i]=n163.reg(i);
}
}
int DivPlatformN163::dispatch(DivCommand c) {
@ -476,6 +489,7 @@ void DivPlatformN163::forceIns() {
chan[i].waveChanged=true;
}
}
memCompo.entries[16].begin=120-chanMax*8;
}
void DivPlatformN163::notifyWaveChange(int wave) {
@ -516,9 +530,6 @@ DivDispatchOscBuffer* DivPlatformN163::getOscBuffer(int ch) {
}
unsigned char* DivPlatformN163::getRegisterPool() {
for (int i=0; i<128; i++) {
regPool[i]=n163.reg(i);
}
return regPool;
}
@ -544,6 +555,8 @@ void DivPlatformN163::reset() {
loadWave=-1;
loadPos=0;
rWrite(0x7f,initChanMax<<4);
memCompo.entries[16].begin=120-chanMax*8;
}
void DivPlatformN163::poke(unsigned int addr, unsigned short val) {
@ -554,6 +567,11 @@ void DivPlatformN163::poke(std::vector<DivRegWrite>& wlist) {
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
}
const DivMemoryComposition* DivPlatformN163::getMemCompo(int index) {
if (index!=0) return NULL;
return &memCompo;
}
void DivPlatformN163::setFlags(const DivConfig& flags) {
switch (flags.getInt("clockSel",0)) {
case 1: // PAL
@ -591,6 +609,20 @@ int DivPlatformN163::init(DivEngine* p, int channels, int sugRate, const DivConf
isMuted[i]=false;
oscBuf[i]=new DivDispatchOscBuffer;
}
memCompo.used=0;
memCompo.capacity=128;
memCompo.memory=regPool;
memCompo.waveformView=DIV_MEMORY_WAVE_4BIT;
for (int i=0; i<8; i++) {
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_N163_LOAD,fmt::sprintf("Channel %d (load)",i),-1,0,0));
}
for (int i=0; i<8; i++) {
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_N163_PLAY,fmt::sprintf("Channel %d (play)",i),-1,0,0));
}
memCompo.entries.push_back(DivMemoryEntry(DIV_MEMORY_RESERVED,"Registers",-1,127,128));
setFlags(flags);
reset();

View file

@ -65,6 +65,7 @@ class DivPlatformN163: public DivDispatch {
n163_core n163;
unsigned char regPool[128];
DivMemoryComposition memCompo;
void updateWave(int ch, int wave, int pos, int len);
void updateWaveCh(int ch);
friend void putDispatchChip(void*,int);
@ -82,6 +83,7 @@ class DivPlatformN163: public DivDispatch {
void forceIns();
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
const DivMemoryComposition* getMemCompo(int index);
void setFlags(const DivConfig& flags);
void notifyWaveChange(int wave);
void notifyInsChange(int ins);