Virtual Boy: make it work on hardware

issue #2373
This commit is contained in:
tildearrow 2025-02-18 02:30:14 -05:00
parent 63ee7cf5d8
commit e1b7618348
3 changed files with 70 additions and 3 deletions

View file

@ -127,8 +127,9 @@ void DivPlatformVB::updateWave(int ch) {
if (ch>=5) return;
for (int i=0; i<32; i++) {
rWrite((ch<<7)+(i<<2),chan[ch].ws.output[i]);
rWrite((ch<<7)+(i<<2),chan[ch].ws.output[(i+chan[ch].antiClickWavePos)&31]);
}
chan[ch].antiClickWavePos&=31;
}
void DivPlatformVB::writeEnv(int ch, bool upperByteToo) {
@ -139,7 +140,17 @@ void DivPlatformVB::writeEnv(int ch, bool upperByteToo) {
}
void DivPlatformVB::tick(bool sysTick) {
bool mustUpdateWaves=false;
for (int i=0; i<6; i++) {
// anti-click
int actualFreq=2047-chan[i].freq;
if (antiClickEnabled && !screwThis && sysTick && actualFreq>0) {
chan[i].antiClickPeriodCount+=(chipClock/MAX(parent->getCurHz(),1.0f));
chan[i].antiClickWavePos+=chan[i].antiClickPeriodCount/actualFreq;
chan[i].antiClickPeriodCount%=actualFreq;
}
chan[i].std.next();
if (chan[i].std.vol.had) {
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
@ -192,10 +203,16 @@ void DivPlatformVB::tick(bool sysTick) {
}
if (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1) {
chWrite(i,0x00,0x80);
chan[i].intWritten=true;
chan[i].antiClickWavePos=0;
chan[i].antiClickPeriodCount=0;
}
if (chan[i].active) {
if (chan[i].ws.tick() || (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1)) {
updateWave(i);
if (!romMode) {
chan[i].deferredWaveUpdate=true;
}
mustUpdateWaves=true;
}
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
@ -215,6 +232,32 @@ void DivPlatformVB::tick(bool sysTick) {
chan[i].freqChanged=false;
}
}
// trigger wave changes
if (mustUpdateWaves && !romMode) {
//rWrite(0x580,1);
if (!screwThis) {
chWrite(0,0x00,0x00);
chWrite(1,0x00,0x00);
chWrite(2,0x00,0x00);
chWrite(3,0x00,0x00);
chWrite(4,0x00,0x00);
}
for (int i=0; i<5; i++) {
//if (chan[i].deferredWaveUpdate) {
//chan[i].deferredWaveUpdate=false;
updateWave(i);
//}
}
if (!screwThis) {
// restore channel state...
for (int i=0; i<5; i++) {
if (chan[i].intWritten) {
chWrite(i,0x00,0x80);
}
}
}
}
}
int DivPlatformVB::dispatch(DivCommand c) {
@ -477,6 +520,7 @@ void DivPlatformVB::reset() {
for (int i=0; i<6; i++) {
chWrite(i,0x01,isMuted[i]?0:chan[i].pan);
chWrite(i,0x05,0x00);
chan[i].intWritten=true;
chWrite(i,0x00,0x80);
if (romMode) {
chWrite(i,0x06,0);
@ -545,6 +589,8 @@ void DivPlatformVB::setFlags(const DivConfig& flags) {
}
romMode=flags.getBool("romMode",false);
antiClickEnabled=!flags.getBool("noAntiClick",false);
screwThis=flags.getBool("screwThis",false);
if (vb!=NULL) {
delete vb;

View file

@ -27,22 +27,27 @@
class DivPlatformVB: public DivDispatch {
struct Channel: public SharedChannel<signed char> {
int antiClickPeriodCount, antiClickWavePos;
unsigned char pan, envLow, envHigh;
bool noise, deferredWaveUpdate;
bool noise, deferredWaveUpdate, intWritten;
signed short wave;
DivWaveSynth ws;
Channel():
SharedChannel<signed char>(15),
antiClickPeriodCount(0),
antiClickWavePos(0),
pan(255),
envLow(0),
envHigh(0),
noise(false),
deferredWaveUpdate(false),
intWritten(false),
wave(-1) {}
};
Channel chan[6];
DivDispatchOscBuffer* oscBuf[6];
bool isMuted[6];
bool antiClickEnabled, screwThis;
struct QueuedWrite {
unsigned short addr;
unsigned char val;