From 843d18290d731824cc6a6fc0eae347b8f8c8854b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 12 Oct 2022 04:05:09 -0500 Subject: [PATCH] T6W28: finish it up (mostly) --- src/engine/platform/t6w28.cpp | 43 +++++++++++++++++++++++++---------- src/engine/platform/t6w28.h | 6 ++--- src/engine/sysDef.cpp | 2 +- src/gui/insEdit.cpp | 5 ++++ src/gui/presets.cpp | 6 +++++ 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 6ff4cc12..5361ce9c 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -25,8 +25,6 @@ //#define rWrite(a,v) pendingWrites[a]=v; #define rWrite(a,v) if (!skipRegisterWrites) {writes.emplace(a,v); if (dumpWrites) {addWrite(a,v);} } -#define CHIP_DIVIDER 16 - const char* regCheatSheetT6W28[]={ "Data0", "0", "Data1", "1", @@ -72,14 +70,21 @@ void DivPlatformT6W28::acquire(short* bufL, short* bufR, size_t start, size_t le } void DivPlatformT6W28::writeOutVol(int ch) { - int left=15-CLAMP(chan[ch].outVol+chan[ch].panL-15,0,15); - int right=15-CLAMP(chan[ch].outVol+chan[ch].panR-15,0,15); - rWrite(0,0x90|(ch<<5)|(isMuted[ch]?15:left)); - rWrite(1,0x90|(ch<<5)|(isMuted[ch]?15:right)); + if (chan[ch].active) { + int left=15-CLAMP(chan[ch].outVol+chan[ch].panL-15,0,15); + int right=15-CLAMP(chan[ch].outVol+chan[ch].panR-15,0,15); + rWrite(0,0x90|(ch<<5)|(isMuted[ch]?15:left)); + rWrite(1,0x90|(ch<<5)|(isMuted[ch]?15:right)); + } else { + rWrite(0,0x9f|(ch<<5)); + rWrite(1,0x9f|(ch<<5)); + } } void DivPlatformT6W28::tick(bool sysTick) { for (int i=0; i<4; i++) { + double CHIP_DIVIDER=16; + if (i==3) CHIP_DIVIDER=15; chan[i].std.next(); if (chan[i].std.vol.had) { chan[i].outVol=VOL_SCALE_LOG(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15); @@ -91,6 +96,12 @@ void DivPlatformT6W28::tick(bool sysTick) { } chan[i].freqChanged=true; } + if (i==3 && chan[i].std.duty.had) { + if (chan[i].duty!=chan[i].std.duty.val) { + chan[i].duty=chan[i].std.duty.val&7; + rWrite(1,0xe0+chan[i].duty); + } + } if (chan[i].std.panL.had) { chan[i].panL=chan[i].std.panL.val&15; } @@ -109,12 +120,13 @@ void DivPlatformT6W28::tick(bool sysTick) { } chan[i].freqChanged=true; } + if (chan[i].std.phaseReset.had) { + rWrite(1,0xe0+chan[i].duty); + } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { - //DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE); chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER); if (chan[i].freq>1023) chan[i].freq=1023; if (i==3) { - rWrite(1,0xe7); rWrite(1,0x80|(2<<5)|(chan[3].freq&15)); rWrite(1,chan[3].freq>>4); } else { @@ -129,6 +141,8 @@ void DivPlatformT6W28::tick(bool sysTick) { } int DivPlatformT6W28::dispatch(DivCommand c) { + double CHIP_DIVIDER=16; + if (c.chan==3) CHIP_DIVIDER=15; switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_PCE); @@ -142,6 +156,7 @@ int DivPlatformT6W28::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; + writeOutVol(c.chan); } chan[c.chan].insChanged=false; break; @@ -150,6 +165,7 @@ int DivPlatformT6W28::dispatch(DivCommand c) { chan[c.chan].active=false; chan[c.chan].keyOff=true; chan[c.chan].macroInit(NULL); + writeOutVol(c.chan); break; case DIV_CMD_NOTE_OFF_ENV: case DIV_CMD_ENV_RELEASE: @@ -166,8 +182,7 @@ int DivPlatformT6W28::dispatch(DivCommand c) { chan[c.chan].vol=c.value; if (!chan[c.chan].std.vol.has) { chan[c.chan].outVol=c.value; - if (chan[c.chan].active) { - } + writeOutVol(c.chan); } } break; @@ -205,7 +220,9 @@ int DivPlatformT6W28::dispatch(DivCommand c) { break; } case DIV_CMD_STD_NOISE_MODE: - chan[c.chan].noise=c.value; + if (c.chan!=3) break; + chan[c.chan].duty=(((c.value&15)==1)?4:0)|((c.value>>4)&3); + rWrite(1,0xe0+chan[c.chan].duty); break; case DIV_CMD_PANNING: { chan[c.chan].panL=c.value>>4; @@ -226,7 +243,7 @@ int DivPlatformT6W28::dispatch(DivCommand c) { chan[c.chan].inPorta=c.value; break; case DIV_CMD_GET_VOLMAX: - return 31; + return 15; break; case DIV_ALWAYS_SET_VOLUME: return 1; @@ -289,6 +306,8 @@ void DivPlatformT6W28::reset() { cycles=0; curChan=-1; delay=0; + // default noise mode + rWrite(1,0xe7); } bool DivPlatformT6W28::isStereo() { diff --git a/src/engine/platform/t6w28.h b/src/engine/platform/t6w28.h index bc445991..5b5f1fc8 100644 --- a/src/engine/platform/t6w28.h +++ b/src/engine/platform/t6w28.h @@ -29,8 +29,8 @@ class DivPlatformT6W28: public DivDispatch { struct Channel { int freq, baseFreq, pitch, pitch2, note; int ins; - unsigned char panL, panR; - bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise; + unsigned char panL, panR, duty; + bool active, insChanged, freqChanged, keyOn, keyOff, inPorta; signed char vol, outVol; DivMacroInt std; void macroInit(DivInstrument* which) { @@ -46,13 +46,13 @@ class DivPlatformT6W28: public DivDispatch { ins(-1), panL(15), panR(15), + duty(7), active(false), insChanged(true), freqChanged(false), keyOn(false), keyOff(false), inPorta(false), - noise(false), vol(15), outVol(15) {} }; diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index b4b1bfcc..025b64d6 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1664,7 +1664,7 @@ void DivEngine::registerSystems() { {DIV_INS_T6W28, DIV_INS_T6W28, DIV_INS_T6W28, DIV_INS_T6W28}, {}, { - {0x20, {DIV_CMD_STD_NOISE_MODE, "20xy: Set noise mode (x: preset/variable; y: thin pulse/noise)"}} + {0x20, {DIV_CMD_STD_NOISE_MODE, "20xy: Set noise mode (x: 0-2 for preset, 3 for tonal; y: thin pulse/noise)"}} } ); diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index a22e9dbe..0f0d0d7f 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -4693,6 +4693,10 @@ void FurnaceGUI::drawInsEdit() { dutyLabel="Pulse Width"; dutyMax=255; } + if (ins->type==DIV_INS_T6W28) { + dutyLabel="Noise Type/Freq"; + dutyMax=7; + } if (ins->type==DIV_INS_AY8930) { dutyMax=ins->amiga.useSample?0:255; } @@ -4973,6 +4977,7 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_SU || ins->type==DIV_INS_MIKEY || ins->type==DIV_INS_ES5506 || + ins->type==DIV_INS_T6W28 || (ins->type==DIV_INS_X1_010 && ins->amiga.useSample)) { macroList.push_back(FurnaceGUIMacroDesc("Phase Reset",&ins->std.phaseResetMacro,0,1,32,uiColors[GUI_COLOR_MACRO_OTHER],false,NULL,NULL,true)); } diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index a8c49703..e95b800d 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -270,6 +270,12 @@ void FurnaceGUI::initSystemPresets() { 0 } )); + cat.systems.push_back(FurnaceGUISysDef( + "Toshiba T6W28", { + DIV_SYSTEM_T6W28, 64, 0, 0, + 0 + } + )); cat.systems.push_back(FurnaceGUISysDef( "AY-3-8910", { DIV_SYSTEM_AY8910, 64, 0, 0,