Merge branch 'master' of https://github.com/tildearrow/furnace into x1_010_bank

This commit is contained in:
cam900 2023-03-27 15:07:45 +09:00
commit 2a881c9f66
84 changed files with 3061 additions and 381 deletions

View file

@ -37,6 +37,10 @@ DivMacroInt* DivDispatch::getChanMacroInt(int chan) {
return NULL;
}
DivSamplePos DivDispatch::getSamplePos(int chan) {
return DivSamplePos();
}
DivDispatchOscBuffer* DivDispatch::getOscBuffer(int chan) {
return NULL;
}

View file

@ -213,6 +213,10 @@ void DivPlatformAmiga::rWrite(unsigned short addr, unsigned short val) {
//logV("%.3x = %.4x",addr,val);
regPool[addr>>1]=val;
if (!skipRegisterWrites && dumpWrites) {
addWrite(addr,val);
}
switch (addr&0x1fe) {
case 0x96: { // DMACON
if (val&32768) {
@ -400,6 +404,29 @@ void DivPlatformAmiga::tick(bool sysTick) {
chan[i].keyOn=true;
}
}
}
unsigned short dmaOff=0;
unsigned short dmaOn=0;
for (int i=0; i<4; i++) {
if (chan[i].keyOn || chan[i].keyOff) {
chWrite(i,6,1);
dmaOff|=1<<i;
}
}
if (dmaOff) rWrite(0x96,dmaOff);
for (int i=0; i<4; i++) {
double off=1.0;
if (!chan[i].useWave && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[i].sample);
if (s->centerRate<1) {
off=1.0;
} else {
off=8363.0/(double)s->centerRate;
}
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_AMIGA);
chan[i].freq=off*parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER);
@ -409,13 +436,16 @@ void DivPlatformAmiga::tick(bool sysTick) {
chWrite(i,6,chan[i].freq);
if (chan[i].keyOn) {
rWrite(0x96,1<<i);
if (chan[i].useWave) {
rWrite(0x9a,(128<<i));
chWrite(i,0,0);
chWrite(i,2,i<<8);
chWrite(i,4,chan[i].audLen);
rWrite(0x96,0x8000|(1<<i));
if (dumpWrites) {
addWrite(0x200+i,i<<8);
addWrite(0x204+i,chan[i].audLen);
}
dmaOn|=1<<i;
} else {
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
DivSample* s=parent->getSample(chan[i].sample);
@ -432,13 +462,21 @@ void DivPlatformAmiga::tick(bool sysTick) {
chWrite(i,0,0);
chWrite(i,2,0x400);
chWrite(i,4,1);
if (dumpWrites) {
addWrite(0x200+i,0x400);
addWrite(0x204+i,1);
}
} else {
chWrite(i,0,start>>16);
chWrite(i,2,start);
chWrite(i,4,len);
if (dumpWrites) {
addWrite(0x200+i,start);
addWrite(0x204+i,len);
}
}
rWrite(0x96,0x8000|(1<<i));
dmaOn|=1<<i;
if (s->isLoopable()) {
int loopPos=(sampleOff[chan[i].sample]+s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT))&(~1);
int loopEnd=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT)-s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT))>>1;
@ -455,19 +493,28 @@ void DivPlatformAmiga::tick(bool sysTick) {
chWrite(i,0,0);
chWrite(i,2,0x400);
chWrite(i,4,1);
if (dumpWrites) {
addWrite(0x200+i,0x400);
addWrite(0x204+i,1);
}
}
}
}
if (chan[i].keyOff) {
rWrite(0x96,1<<i);
}
if (chan[i].keyOn) chan[i].keyOn=false;
if (chan[i].keyOff) chan[i].keyOff=false;
chan[i].freqChanged=false;
}
}
if (dmaOn) rWrite(0x96,0x8000|dmaOn);
for (int i=0; i<4; i++) {
if ((dmaOn&(1<<i)) && !chan[i].useWave && dumpWrites) {
addWrite(0x200+i,(chan[i].irLocH<<16)|chan[i].irLocL);
addWrite(0x204+i,chan[i].irLen);
}
}
for (int i=0; i<4; i++) {
if (chan[i].writeVol) {
chan[i].writeVol=false;
@ -718,6 +765,18 @@ DivMacroInt* DivPlatformAmiga::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformAmiga::getSamplePos(int ch) {
if (ch>=4) return DivSamplePos();
if (chan[ch].sample<0 || chan[ch].sample>=parent->song.sampleLen) return DivSamplePos();
int audPer=amiga.audPer[ch];
if (audPer<1) audPer=1;
return DivSamplePos(
chan[ch].sample,
amiga.dmaLoc[ch]-sampleOff[chan[ch].sample],
chipClock/audPer
);
}
void DivPlatformAmiga::notifyInsChange(int ins) {
for (int i=0; i<4; i++) {
if (chan[i].ins==ins) {

View file

@ -116,6 +116,7 @@ class DivPlatformAmiga: public DivDispatch {
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);
friend class DivExportAmigaValidation;
void irq(int ch);
void rWrite(unsigned short addr, unsigned short val);
@ -136,6 +137,7 @@ class DivPlatformAmiga: public DivDispatch {
int getOutputCount();
bool keyOffAffectsArp(int ch);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
void setFlags(const DivConfig& flags);
void notifyInsChange(int ins);
void notifyWaveChange(int wave);

View file

@ -700,6 +700,15 @@ DivMacroInt* DivPlatformAY8910::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformAY8910::getSamplePos(int ch) {
if (ch>=3) return DivSamplePos();
return DivSamplePos(
chan[ch].dac.sample,
chan[ch].dac.pos,
chan[ch].dac.rate
);
}
DivDispatchOscBuffer* DivPlatformAY8910::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -143,6 +143,7 @@ class DivPlatformAY8910: public DivDispatch {
int getOutputCount();
bool keyOffAffectsArp(int ch);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
bool getDCOffRequired();
void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val);

View file

@ -696,6 +696,15 @@ DivMacroInt* DivPlatformAY8930::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformAY8930::getSamplePos(int ch) {
if (ch>=3) return DivSamplePos();
return DivSamplePos(
chan[ch].dac.sample,
chan[ch].dac.pos,
chan[ch].dac.rate
);
}
DivDispatchOscBuffer* DivPlatformAY8930::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -145,6 +145,7 @@ class DivPlatformAY8930: public DivDispatch {
int getOutputCount();
bool keyOffAffectsArp(int ch);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
void notifyInsDeletion(void* ins);
void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist);

View file

@ -336,6 +336,18 @@ DivMacroInt* DivPlatformGA20::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformGA20::getSamplePos(int ch) {
if (ch>=4) return DivSamplePos();
if (chan[ch].sample<0 || chan[ch].sample>=parent->song.sampleLen) return DivSamplePos();
if (!ga20.is_playing(ch)) return DivSamplePos();
unsigned char f=chan[ch].freq;
return DivSamplePos(
chan[ch].sample,
ga20.get_position(ch)-sampleOffGA20[chan[ch].sample],
chipClock/(4*(0x100-(int)f))
);
}
DivDispatchOscBuffer* DivPlatformGA20::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -78,6 +78,7 @@ class DivPlatformGA20: public DivDispatch, public iremga20_intf {
virtual int dispatch(DivCommand c) override;
virtual void* getChanState(int chan) override;
virtual DivMacroInt* getChanMacroInt(int ch) override;
virtual DivSamplePos getSamplePos(int ch) override;
virtual DivDispatchOscBuffer* getOscBuffer(int chan) override;
virtual unsigned char* getRegisterPool() override;
virtual int getRegisterPoolSize() override;

View file

@ -172,7 +172,14 @@ void DivPlatformGenesis::acquire_nuked(short** buf, size_t len) {
flushFirst=false;
}
OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1];
OPN2_Clock(&fm,o);
if (chipType==2) {
os[0]+=CLAMP(o[0],-8192,8191);
os[1]+=CLAMP(o[1],-8192,8191);
} else {
os[0]+=o[0];
os[1]+=o[1];
}
//OPN2_Write(&fm,0,0);
if (i==5) {
if (fm.dacen) {
@ -1202,6 +1209,17 @@ DivMacroInt* DivPlatformGenesis::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformGenesis::getSamplePos(int ch) {
if (!chan[5].dacMode) return DivSamplePos();
if (ch<5) return DivSamplePos();
if (ch>5 && !softPCM) return DivSamplePos();
return DivSamplePos(
chan[ch].dacSample,
chan[ch].dacPos,
chan[ch].dacRate
);
}
DivDispatchOscBuffer* DivPlatformGenesis::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -105,6 +105,7 @@ class DivPlatformGenesis: public DivPlatformOPN {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -415,6 +415,16 @@ DivMacroInt* DivPlatformLynx::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformLynx::getSamplePos(int ch) {
if (ch>=4) return DivSamplePos();
if (!chan[ch].pcm) return DivSamplePos();
return DivSamplePos(
chan[ch].sample,
chan[ch].samplePos,
chan[ch].sampleFreq
);
}
DivDispatchOscBuffer* DivPlatformLynx::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -72,6 +72,7 @@ class DivPlatformLynx: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -19,6 +19,7 @@
#include "n163.h"
#include "../engine.h"
#include "../../ta-log.h"
#include <math.h>
#define rRead(a,v) n163.addr_w(a); n163.data_r(v);
@ -166,6 +167,7 @@ void DivPlatformN163::updateWave(int ch, int wave, int pos, int len) {
void DivPlatformN163::updateWaveCh(int ch) {
if (ch<=chanMax) {
logV("updateWave with pos %d and len %d",chan[ch].wavePos,chan[ch].waveLen);
updateWave(ch,-1,chan[ch].wavePos,chan[ch].waveLen);
if (chan[ch].active && !isMuted[ch]) {
chan[ch].volumeChanged=true;
@ -337,15 +339,15 @@ int DivPlatformN163::dispatch(DivCommand c) {
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_N163);
if (chan[c.chan].insChanged) {
chan[c.chan].wave=ins->n163.wave;
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
chan[c.chan].wavePos=ins->n163.wavePos;
chan[c.chan].waveLen=ins->n163.waveLen;
chan[c.chan].waveMode=ins->n163.waveMode;
chan[c.chan].ws.init(NULL,chan[c.chan].waveLen,15,false);
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
chan[c.chan].waveChanged=true;
if (chan[c.chan].waveMode&0x3 || ins->ws.enabled) {
chan[c.chan].waveUpdated=true;
}
chan[c.chan].insChanged=false;
}
if (c.value!=DIV_NOTE_NULL) {
chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value);
@ -360,6 +362,7 @@ int DivPlatformN163::dispatch(DivCommand c) {
}
chan[c.chan].macroInit(ins);
chan[c.chan].ws.init(ins,chan[c.chan].waveLen,15,chan[c.chan].insChanged);
chan[c.chan].insChanged=false;
break;
}
case DIV_CMD_NOTE_OFF:

View file

@ -183,6 +183,7 @@ void DivPlatformNamcoWSG::acquire(short** buf, size_t len) {
}
void DivPlatformNamcoWSG::updateWave(int ch) {
if (romMode) return;
if (devType==30) {
for (int i=0; i<32; i++) {
((namco_cus30_device*)namco)->namcos1_cus30_w(i+ch*32,chan[ch].ws.output[i]);
@ -291,9 +292,9 @@ void DivPlatformNamcoWSG::tick(bool sysTick) {
rWrite(0x1d,(chan[2].freq>>12)&15);
rWrite(0x1e,(chan[2].freq>>16)&15);
rWrite(0x05,0);
rWrite(0x0a,1);
rWrite(0x0f,2);
rWrite(0x05,romMode?(chan[0].wave&7):0);
rWrite(0x0a,romMode?(chan[1].wave&7):1);
rWrite(0x0f,romMode?(chan[2].wave&7):2);
break;
case 15:
for (int i=0; i<8; i++) {
@ -304,7 +305,7 @@ void DivPlatformNamcoWSG::tick(bool sysTick) {
}
rWrite((i<<3)+0x04,chan[i].freq&0xff);
rWrite((i<<3)+0x05,(chan[i].freq>>8)&0xff);
rWrite((i<<3)+0x06,((chan[i].freq>>16)&15)|(i<<4));
rWrite((i<<3)+0x06,((chan[i].freq>>16)&15)|((romMode?(chan[i].wave&7):i)<<4));
}
break;
case 30:
@ -496,10 +497,11 @@ void DivPlatformNamcoWSG::reset() {
if (dumpWrites) {
addWrite(0xffffffff,0);
}
// TODO: wave memory
namco->set_voices(chans);
namco->set_stereo((devType==2 || devType==30));
namco->device_start(NULL);
updateROMWaves();
}
int DivPlatformNamcoWSG::getOutputCount() {
@ -510,6 +512,27 @@ bool DivPlatformNamcoWSG::keyOffAffectsArp(int ch) {
return true;
}
void DivPlatformNamcoWSG::updateROMWaves() {
if (romMode) {
// copy wavetables
for (int i=0; i<8; i++) {
int data=0;
DivWavetable* w=parent->getWave(i);
for (int j=0; j<32; j++) {
if (w->max<1 || w->len<1) {
data=0;
} else {
data=w->data[j*w->len/32]*15/w->max;
if (data<0) data=0;
if (data>15) data=15;
}
namco->update_namco_waveform(i*32+j,data);
}
}
}
}
void DivPlatformNamcoWSG::notifyWaveChange(int wave) {
for (int i=0; i<chans; i++) {
if (chan[i].wave==wave) {
@ -517,6 +540,7 @@ void DivPlatformNamcoWSG::notifyWaveChange(int wave) {
updateWave(i);
}
}
updateROMWaves();
}
void DivPlatformNamcoWSG::notifyInsDeletion(void* ins) {
@ -552,6 +576,8 @@ void DivPlatformNamcoWSG::setFlags(const DivConfig& flags) {
oscBuf[i]->rate=rate;
}
newNoise=flags.getBool("newNoise",true);
romMode=flags.getBool("romMode",true);
if (devType==30) romMode=false;
}
void DivPlatformNamcoWSG::poke(unsigned int addr, unsigned short val) {

View file

@ -50,8 +50,10 @@ class DivPlatformNamcoWSG: public DivDispatch {
namco_audio_device* namco;
int devType, chans;
bool newNoise;
bool romMode;
unsigned char regPool[512];
void updateWave(int ch);
void updateROMWaves();
friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int);
public:

View file

@ -505,6 +505,16 @@ DivMacroInt* DivPlatformPCE::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformPCE::getSamplePos(int ch) {
if (ch>=6) return DivSamplePos();
if (!chan[ch].pcm) return DivSamplePos();
return DivSamplePos(
chan[ch].dacSample,
chan[ch].dacPos,
chan[ch].dacRate
);
}
DivDispatchOscBuffer* DivPlatformPCE::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -81,6 +81,7 @@ class DivPlatformPCE: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -30,7 +30,7 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
const int depthScale=(15-outDepth);
int output=0;
for (size_t h=0; h<len; h++) {
if (!chan[0].active || isMuted) {
if (!chan[0].active) {
buf[0][h]=0;
buf[1][h]=0;
oscBuf->data[oscBuf->needle++]=0;
@ -171,7 +171,11 @@ void DivPlatformPCMDAC::acquire(short** buf, size_t len) {
}
}
}
output=output*chan[0].vol*chan[0].envVol/16384;
if (isMuted) {
output=0;
} else {
output=output*chan[0].vol*chan[0].envVol/16384;
}
oscBuf->data[oscBuf->needle++]=output;
if (outStereo) {
buf[0][h]=((output*chan[0].panL)>>(depthScale+8))<<depthScale;
@ -437,6 +441,15 @@ DivMacroInt* DivPlatformPCMDAC::getChanMacroInt(int ch) {
return &chan[0].std;
}
DivSamplePos DivPlatformPCMDAC::getSamplePos(int ch) {
if (ch>=1) return DivSamplePos();
return DivSamplePos(
chan[ch].sample,
chan[ch].audPos,
chan[ch].freq
);
}
void DivPlatformPCMDAC::notifyInsChange(int ins) {
if (chan[0].ins==ins) {
chan[0].insChanged=true;

View file

@ -79,6 +79,7 @@ class DivPlatformPCMDAC: public DivDispatch {
void muteChannel(int ch, bool mute);
int getOutputCount();
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
void setFlags(const DivConfig& flags);
void notifyInsChange(int ins);
void notifyWaveChange(int wave);

View file

@ -40,7 +40,7 @@ void DivPlatformPV1000::acquire(short** buf, size_t len) {
for (size_t h=0; h<len; h++) {
short samp;
samp=d65010g031_sound_tick(&d65010g031,1);
buf[0][h]=samp<<12;
buf[0][h]=samp;
for (int i=0; i<3; i++) {
oscBuf[i]->data[oscBuf[i]->needle++]=(d65010g031.square[i].out<<12);
}
@ -263,6 +263,10 @@ void DivPlatformPV1000::poke(std::vector<DivRegWrite>& wlist) {
for (DivRegWrite& i: wlist) rWrite(i.addr,i.val);
}
bool DivPlatformPV1000::getDCOffRequired() {
return true;
}
int DivPlatformPV1000::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) {
parent=p;
dumpWrites=false;

View file

@ -21,7 +21,7 @@
#define _PV1000_H
#include "../dispatch.h"
#include "sound/d65010g031.h"
#include "sound/d65modified.h"
#include <queue>
class DivPlatformPV1000: public DivDispatch {
@ -55,6 +55,7 @@ class DivPlatformPV1000: public DivDispatch {
void poke(unsigned int addr, unsigned short val);
void poke(std::vector<DivRegWrite>& wlist);
const char** getRegisterSheet();
bool getDCOffRequired();
int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags);
void quit();
~DivPlatformPV1000();

View file

@ -307,6 +307,7 @@ void DivPlatformRF5C68::forceIns() {
chan[i].insChanged=true;
chan[i].freqChanged=true;
chan[i].sample=-1;
chWrite(i,1,isMuted[i]?0:chan[i].panning);
}
}

View file

@ -382,6 +382,17 @@ DivMacroInt* DivPlatformSegaPCM::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformSegaPCM::getSamplePos(int ch) {
if (ch>=16) return DivSamplePos();
if (chan[ch].pcm.sample<0 || chan[ch].pcm.sample>=parent->song.sampleLen) return DivSamplePos();
if (!pcm.is_playing(ch)) return DivSamplePos();
return DivSamplePos(
chan[ch].pcm.sample,
pcm.get_addr(ch)-sampleOffSegaPCM[chan[ch].pcm.sample],
122*(chan[ch].pcm.freq+1)
);
}
DivDispatchOscBuffer* DivPlatformSegaPCM::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -87,6 +87,7 @@ class DivPlatformSegaPCM: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -681,6 +681,20 @@ DivMacroInt* DivPlatformSNES::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformSNES::getSamplePos(int ch) {
if (ch>=8) return DivSamplePos();
if (!chan[ch].active) return DivSamplePos();
if (chan[ch].sample<0 || chan[ch].sample>=parent->song.sampleLen) return DivSamplePos();
const SPC_DSP::voice_t* v=dsp.get_voice(ch);
// TODO: fix?
if (sampleMem[v->brr_addr&0xffff]==0) return DivSamplePos();
return DivSamplePos(
chan[ch].sample,
((v->brr_addr-sampleOff[chan[ch].sample])*16/9)+v->brr_offset,
(chan[ch].freq*125)/16
);
}
DivDispatchOscBuffer* DivPlatformSNES::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -97,6 +97,7 @@ class DivPlatformSNES: public DivDispatch {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();

View file

@ -34,9 +34,31 @@ freely, subject to the following restrictions:
TODO:
- needs hardware test
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
ALTERED VERSION!!!
THIS IS **NOT** NOT NOT NOT!!!! THE ORIGINAL SOFTWARE
IT ISN'T
THE MODIFICATIONS THAT WERE MADE ARE:
1. FIX VOLUMES - APPARENTLY THE SQUARES HAVE DIFFERENT VOLUMES (thanks forple)
*/
#include "d65010g031.h"
#include "d65modified.h"
#include <stdlib.h>
static int d65010g031_max(int a, int b) { return (a > b) ? a : b; }
@ -57,12 +79,20 @@ int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle)
return 0;
}
// this is the bit I altered
// THIS IS **NOT** THE ORIGINAL SOFTWARE! I am plainly marking it as such!
const int d65Volumes[3]={
3840,
5120,
8192
};
int d65010g031_sound_tick(struct d65010g031_t *d65010g031, const int cycle)
{
int out = 0;
for (int i = 0; i < 3; i++)
{
out += d65010g031_square_tick(&d65010g031->square[i], cycle);
out += d65010g031_square_tick(&d65010g031->square[i], cycle)?d65Volumes[i]:-d65Volumes[i];
}
return out;
}

View file

@ -39,12 +39,19 @@ public:
u8 read(u32 offset);
inline void set_mute(const int ch, const bool mute) { m_channel[ch & 3].mute = mute; }
inline unsigned int get_position(const int ch) {
return m_channel[ch&3].pos;
}
inline bool is_playing(const int ch) {
return m_channel[ch&3].play;
}
// device-level overrides
void device_reset();
// sound stream update overrides
void sound_stream_update(short** outputs, int len);
private:
struct channel_def

View file

@ -134,6 +134,18 @@ uint8_t* segapcm_device::get_ram() {
return m_ram;
}
unsigned int segapcm_device::get_addr(int ch) {
uint8_t *regs = &m_ram[8*ch];
int offset = (regs[0x86] & m_bankmask) << m_bankshift;
uint32_t addr = (regs[0x85] << 8) | (regs[0x84]) | offset;
return addr;
}
bool segapcm_device::is_playing(int ch) {
uint8_t *regs = &m_ram[8*ch];
return !(regs[0x86]&1);
}
void segapcm_device::mute(int ch, bool doMute) {
m_muted[ch&15]=doMute;
}
}

View file

@ -34,6 +34,8 @@ public:
void write(unsigned int offset, uint8_t data);
uint8_t read(unsigned int offset);
uint8_t* get_ram();
unsigned int get_addr(int ch);
bool is_playing(int ch);
void mute(int ch, bool doMute);
// device-level overrides

View file

@ -123,6 +123,9 @@ public:
uint8_t t_envx_out;
sample_t out[2]; // Furnace addition, for per-channel oscilloscope
};
// Furnace addition, gets a voice
const voice_t* get_voice(int n);
private:
enum { brr_block_size = 9 };
@ -298,6 +301,10 @@ inline void SPC_DSP::get_voice_outputs( sample_t* outs )
}
}
inline const SPC_DSP::voice_t* SPC_DSP::get_voice(int n) {
return &m.voices[n];
}
#if !SPC_NO_COPY_STATE_FUNCS
class SPC_State_Copier {

View file

@ -19,6 +19,7 @@
#include "vic20.h"
#include "../engine.h"
#include "../../ta-log.h"
#include <math.h>
#define rWrite(a,v) {regPool[(a)]=(v)&0xff; vic_sound_machine_store(vic,a,(v)&0xff);}
@ -79,9 +80,7 @@ void DivPlatformVIC20::calcAndWriteOutVol(int ch, int env) {
}
void DivPlatformVIC20::writeOutVol(int ch) {
if (!isMuted[ch] && chan[ch].active) {
rWrite(14,chan[ch].outVol);
}
rWrite(14,chan[ch].outVol);
}
void DivPlatformVIC20::tick(bool sysTick) {
@ -99,6 +98,20 @@ void DivPlatformVIC20::tick(bool sysTick) {
}
chan[i].freqChanged=true;
}
if (chan[i].std.duty.had) {
if (chan[i].onOff!=(bool)chan[i].std.duty.val) {
chan[i].onOff=(bool)chan[i].std.duty.val;
if (chan[i].active) {
if (chan[i].onOff) {
chan[i].keyOn=true;
chan[i].keyOff=false;
} else {
chan[i].keyOn=false;
chan[i].keyOff=true;
}
}
}
}
if (chan[i].std.wave.had) {
if (chan[i].wave!=chan[i].std.wave.val) {
chan[i].wave=chan[i].std.wave.val&0x0f;
@ -156,6 +169,7 @@ int DivPlatformVIC20::dispatch(DivCommand c) {
chan[c.chan].freqChanged=true;
chan[c.chan].note=c.value;
}
chan[c.chan].onOff=true;
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].macroInit(ins);

View file

@ -27,10 +27,12 @@
class DivPlatformVIC20: public DivDispatch {
struct Channel: public SharedChannel<int> {
int wave, waveWriteCycle;
bool onOff;
Channel():
SharedChannel<int>(15),
wave(0),
waveWriteCycle(-1) {}
waveWriteCycle(-1),
onOff(true) {}
};
Channel chan[4];
DivDispatchOscBuffer* oscBuf[4];

View file

@ -448,6 +448,16 @@ DivMacroInt* DivPlatformVRC6::getChanMacroInt(int ch) {
return &chan[ch].std;
}
DivSamplePos DivPlatformVRC6::getSamplePos(int ch) {
if (ch>=2) return DivSamplePos();
if (!chan[ch].pcm) return DivSamplePos();
return DivSamplePos(
chan[ch].dacSample,
chan[ch].dacPos,
chan[ch].dacRate
);
}
DivDispatchOscBuffer* DivPlatformVRC6::getOscBuffer(int ch) {
return oscBuf[ch];
}

View file

@ -65,6 +65,7 @@ class DivPlatformVRC6: public DivDispatch, public vrcvi_intf {
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
DivSamplePos getSamplePos(int ch);
DivDispatchOscBuffer* getOscBuffer(int chan);
unsigned char* getRegisterPool();
int getRegisterPoolSize();