From f13cea6a8eea786b1b56cff448d8ac9a234b9270 Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 11 Apr 2023 09:19:12 +0900 Subject: [PATCH 1/6] pv1000: Add XORing features --- src/engine/platform/pv1000.cpp | 23 +++++++++++--- src/engine/platform/pv1000.h | 2 +- src/engine/platform/sound/d65modified.c | 41 ++++++++++++++++++++++--- src/engine/platform/sound/d65modified.h | 2 ++ src/engine/sysDef.cpp | 6 +++- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index d5f54e6a6..af4cae0c7 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -29,6 +29,7 @@ const char* regCheatSheetPV1000[]={ "CH1_Pitch", "00", "CH2_Pitch", "01", "CH3_Pitch", "02", + "Control", "03", NULL }; @@ -42,7 +43,7 @@ void DivPlatformPV1000::acquire(short** buf, size_t len) { samp=d65010g031_sound_tick(&d65010g031,1); buf[0][h]=samp; for (int i=0; i<3; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(d65010g031.square[i].out<<12); + oscBuf[i]->data[oscBuf[i]->needle++]=(d65010g031.out[i]); } } } @@ -73,7 +74,7 @@ void DivPlatformPV1000::tick(bool sysTick) { } if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { chan[i].freq=0x3f-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); - if (chan[i].freq<1) chan[i].freq=1; + if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>62) chan[i].freq=62; if (isMuted[i]) chan[i].keyOn=false; if (chan[i].keyOn) { @@ -83,7 +84,7 @@ void DivPlatformPV1000::tick(bool sysTick) { rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0 : chan[i].freq); } if (chan[i].keyOff) { - rWrite(i,0); + rWrite(i,0x3f); chan[i].keyOff=false; } chan[i].freqChanged=false; @@ -137,6 +138,13 @@ int DivPlatformPV1000::dispatch(DivCommand c) { chan[c.chan].pitch=c.value; chan[c.chan].freqChanged=true; break; + case DIV_CMD_WAVE: + if (c.value&1) { + rWrite(3,3); + } else { + rWrite(3,2); + } + break; case DIV_CMD_NOTE_PORTA: { int destFreq=NOTE_PERIODIC(c.value2); bool return2=false; @@ -224,16 +232,21 @@ unsigned char* DivPlatformPV1000::getRegisterPool() { } int DivPlatformPV1000::getRegisterPoolSize() { - return 3; + return 4; } void DivPlatformPV1000::reset() { - memset(regPool,0,3); + memset(regPool,0,4); for (int i=0; i<3; i++) { chan[i]=Channel(); chan[i].std.setEngine(parent); } d65010g031_reset(&d65010g031); + // mute + rWrite(0,0x3f); + rWrite(1,0x3f); + rWrite(2,0x3f); + rWrite(3,2); } int DivPlatformPV1000::getOutputCount() { diff --git a/src/engine/platform/pv1000.h b/src/engine/platform/pv1000.h index c32540763..852bf1204 100644 --- a/src/engine/platform/pv1000.h +++ b/src/engine/platform/pv1000.h @@ -33,7 +33,7 @@ class DivPlatformPV1000: public DivDispatch { DivDispatchOscBuffer* oscBuf[3]; bool isMuted[3]; - unsigned char regPool[3]; + unsigned char regPool[4]; d65010g031_t d65010g031; friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); diff --git a/src/engine/platform/sound/d65modified.c b/src/engine/platform/sound/d65modified.c index 8f53b34c8..5cd49f2fc 100644 --- a/src/engine/platform/sound/d65modified.c +++ b/src/engine/platform/sound/d65modified.c @@ -67,7 +67,7 @@ int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle) { if (square->period > 0) { - int period = d65010g031_max(1, (0x3f - square->period)); + const int period = square->period; square->counter += cycle; while (square->counter >= period) { @@ -92,7 +92,29 @@ 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)?d65Volumes[i]:-d65Volumes[i]; + d65010g031->out[i] = 0; + } + if (d65010g031->ctrl & 2) + { + if (d65010g031->ctrl & 1) + { + int sout[3] = { + d65010g031_square_tick(&d65010g031->square[0], cycle), + d65010g031_square_tick(&d65010g031->square[1], cycle), + d65010g031_square_tick(&d65010g031->square[2], cycle), + }; + d65010g031->out[0] = (sout[0] ^ sout[1]) ? d65Volumes[0] : -d65Volumes[0]; + d65010g031->out[1] = (sout[1] ^ sout[2]) ? d65Volumes[1] : -d65Volumes[1]; + d65010g031->out[2] = (sout[2] ? d65Volumes[2] : -d65Volumes[2]); + } + else + { + for (int i = 0; i < 3; i++) + { + d65010g031->out[i] = d65010g031_square_tick(&d65010g031->square[i], cycle)?d65Volumes[i]:-d65Volumes[i]; + } + } + out = d65010g031->out[0] + d65010g031->out[1] + d65010g031->out[2]; } return out; } @@ -105,12 +127,23 @@ void d65010g031_reset(struct d65010g031_t *d65010g031) d65010g031->square[i].counter = 0; d65010g031->square[i].out = 0; } + d65010g031->ctrl = 0; } void d65010g031_write(struct d65010g031_t *d65010g031, const unsigned char a, const unsigned char d) { - if (a < 3) + switch (a) { - d65010g031->square[a].period = d & 0x3f; + case 3: + d65010g031->ctrl = d; + break; + default: + const unsigned char period = ~d & 0x3f; + if ((period == 0) && (d65010g031->square[a].period != 0)) + { + d65010g031->square[a].out ^= 1; + } + d65010g031->square[a].period = period; + break; } } diff --git a/src/engine/platform/sound/d65modified.h b/src/engine/platform/sound/d65modified.h index 49dc13a15..eae0f8988 100644 --- a/src/engine/platform/sound/d65modified.h +++ b/src/engine/platform/sound/d65modified.h @@ -54,6 +54,8 @@ struct d65010g031_square_t struct d65010g031_t { struct d65010g031_square_t square[3]; + signed short out[3]; + unsigned char ctrl; }; int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle); diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index fbb718cb5..c9aef95ef 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1839,7 +1839,11 @@ void DivEngine::registerSystems() { {"Square 1", "Square 2", "Square 3"}, {"S1", "S2", "S3"}, {DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, - {DIV_INS_PV1000, DIV_INS_PV1000, DIV_INS_PV1000} + {DIV_INS_PV1000, DIV_INS_PV1000, DIV_INS_PV1000}, + {}, + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}} + } ); sysDefs[DIV_SYSTEM_SFX_BEEPER_QUADTONE]=new DivSysDef( From cb340544730eef282091c62740b27fbe8365e022 Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 11 Apr 2023 12:50:24 +0900 Subject: [PATCH 2/6] Fix compile --- src/engine/platform/sound/d65modified.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/platform/sound/d65modified.c b/src/engine/platform/sound/d65modified.c index 5cd49f2fc..1002ede02 100644 --- a/src/engine/platform/sound/d65modified.c +++ b/src/engine/platform/sound/d65modified.c @@ -138,7 +138,7 @@ void d65010g031_write(struct d65010g031_t *d65010g031, const unsigned char a, co d65010g031->ctrl = d; break; default: - const unsigned char period = ~d & 0x3f; + unsigned char period = ~d & 0x3f; if ((period == 0) && (d65010g031->square[a].period != 0)) { d65010g031->square[a].out ^= 1; From f66b703a8139aa1f8d035566762b08833d946fa5 Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 11 Apr 2023 12:55:09 +0900 Subject: [PATCH 3/6] Fix compile again --- src/engine/platform/sound/d65modified.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/sound/d65modified.c b/src/engine/platform/sound/d65modified.c index 1002ede02..edbb21a94 100644 --- a/src/engine/platform/sound/d65modified.c +++ b/src/engine/platform/sound/d65modified.c @@ -138,12 +138,12 @@ void d65010g031_write(struct d65010g031_t *d65010g031, const unsigned char a, co d65010g031->ctrl = d; break; default: - unsigned char period = ~d & 0x3f; - if ((period == 0) && (d65010g031->square[a].period != 0)) + unsigned char per = (unsigned char)(~d) & 0x3f; + if ((per == 0) && (d65010g031->square[a].period != 0)) { d65010g031->square[a].out ^= 1; } - d65010g031->square[a].period = period; + d65010g031->square[a].period = per; break; } } From fe0ba4e530f7e43428316b93106b0e998afa661d Mon Sep 17 00:00:00 2001 From: cam900 Date: Tue, 11 Apr 2023 13:11:54 +0900 Subject: [PATCH 4/6] Fix muting --- src/engine/platform/pv1000.cpp | 4 ++-- src/engine/platform/sound/d65modified.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index af4cae0c7..903748b6d 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -78,10 +78,10 @@ void DivPlatformPV1000::tick(bool sysTick) { if (chan[i].freq>62) chan[i].freq=62; if (isMuted[i]) chan[i].keyOn=false; if (chan[i].keyOn) { - rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0 : chan[i].freq); + rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0x3f : chan[i].freq); chan[i].keyOn=false; } else if (chan[i].freqChanged && chan[i].active && !isMuted[i]) { - rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0 : chan[i].freq); + rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0x3f : chan[i].freq); } if (chan[i].keyOff) { rWrite(i,0x3f); diff --git a/src/engine/platform/sound/d65modified.c b/src/engine/platform/sound/d65modified.c index edbb21a94..ff5a84da3 100644 --- a/src/engine/platform/sound/d65modified.c +++ b/src/engine/platform/sound/d65modified.c @@ -138,12 +138,14 @@ void d65010g031_write(struct d65010g031_t *d65010g031, const unsigned char a, co d65010g031->ctrl = d; break; default: - unsigned char per = (unsigned char)(~d) & 0x3f; + { + const unsigned char per = (unsigned char)(~d) & 0x3f; if ((per == 0) && (d65010g031->square[a].period != 0)) { d65010g031->square[a].out ^= 1; } d65010g031->square[a].period = per; break; + } } } From 52e6246570036a9cb45300e00554ed5f615396af Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 13 Apr 2023 11:56:34 +0900 Subject: [PATCH 5/6] Add notes for ring modulation (XORing) --- src/engine/platform/pv1000.cpp | 2 +- src/engine/platform/sound/d65modified.c | 8 ++++---- src/engine/sysDef.cpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index 903748b6d..4d9597c98 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -138,7 +138,7 @@ int DivPlatformPV1000::dispatch(DivCommand c) { chan[c.chan].pitch=c.value; chan[c.chan].freqChanged=true; break; - case DIV_CMD_WAVE: + case DIV_CMD_STD_NOISE_MODE: // ring modulation if (c.value&1) { rWrite(3,3); } else { diff --git a/src/engine/platform/sound/d65modified.c b/src/engine/platform/sound/d65modified.c index ff5a84da3..4a0ec1ed1 100644 --- a/src/engine/platform/sound/d65modified.c +++ b/src/engine/platform/sound/d65modified.c @@ -82,9 +82,9 @@ int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle) // 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 + 3840, // -6dB + 5120, // -3dB + 8192 // 0dB }; int d65010g031_sound_tick(struct d65010g031_t *d65010g031, const int cycle) @@ -96,7 +96,7 @@ int d65010g031_sound_tick(struct d65010g031_t *d65010g031, const int cycle) } if (d65010g031->ctrl & 2) { - if (d65010g031->ctrl & 1) + if (d65010g031->ctrl & 1) // ring modulation { int sout[3] = { d65010g031_square_tick(&d65010g031->square[0], cycle), diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index c9aef95ef..d92573bb7 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1842,7 +1842,7 @@ void DivEngine::registerSystems() { {DIV_INS_PV1000, DIV_INS_PV1000, DIV_INS_PV1000}, {}, { - {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}} + {0x10, {DIV_CMD_STD_NOISE_MODE, "10xx: Set ring modulation (0: disable, 1: enable)"}} } ); From 1f60d6bdc60be71c28e176fcdd9b7ad37cbbb172 Mon Sep 17 00:00:00 2001 From: cam900 Date: Thu, 13 Apr 2023 12:03:30 +0900 Subject: [PATCH 6/6] Simplify --- src/engine/platform/pv1000.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/engine/platform/pv1000.cpp b/src/engine/platform/pv1000.cpp index 4d9597c98..4d32fc5a0 100644 --- a/src/engine/platform/pv1000.cpp +++ b/src/engine/platform/pv1000.cpp @@ -39,8 +39,7 @@ const char** DivPlatformPV1000::getRegisterSheet() { void DivPlatformPV1000::acquire(short** buf, size_t len) { for (size_t h=0; hdata[oscBuf[i]->needle++]=(d65010g031.out[i]);