pv1000: Add XORing features

This commit is contained in:
cam900 2023-04-11 09:19:12 +09:00
parent ad2af793ba
commit f13cea6a8e
5 changed files with 63 additions and 11 deletions

View file

@ -29,6 +29,7 @@ const char* regCheatSheetPV1000[]={
"CH1_Pitch", "00", "CH1_Pitch", "00",
"CH2_Pitch", "01", "CH2_Pitch", "01",
"CH3_Pitch", "02", "CH3_Pitch", "02",
"Control", "03",
NULL NULL
}; };
@ -42,7 +43,7 @@ void DivPlatformPV1000::acquire(short** buf, size_t len) {
samp=d65010g031_sound_tick(&d65010g031,1); samp=d65010g031_sound_tick(&d65010g031,1);
buf[0][h]=samp; buf[0][h]=samp;
for (int i=0; i<3; i++) { 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) { 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); 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 (chan[i].freq>62) chan[i].freq=62;
if (isMuted[i]) chan[i].keyOn=false; if (isMuted[i]) chan[i].keyOn=false;
if (chan[i].keyOn) { 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); rWrite(i,(isMuted[i] || (chan[i].outVol<=0)) ? 0 : chan[i].freq);
} }
if (chan[i].keyOff) { if (chan[i].keyOff) {
rWrite(i,0); rWrite(i,0x3f);
chan[i].keyOff=false; chan[i].keyOff=false;
} }
chan[i].freqChanged=false; chan[i].freqChanged=false;
@ -137,6 +138,13 @@ int DivPlatformPV1000::dispatch(DivCommand c) {
chan[c.chan].pitch=c.value; chan[c.chan].pitch=c.value;
chan[c.chan].freqChanged=true; chan[c.chan].freqChanged=true;
break; break;
case DIV_CMD_WAVE:
if (c.value&1) {
rWrite(3,3);
} else {
rWrite(3,2);
}
break;
case DIV_CMD_NOTE_PORTA: { case DIV_CMD_NOTE_PORTA: {
int destFreq=NOTE_PERIODIC(c.value2); int destFreq=NOTE_PERIODIC(c.value2);
bool return2=false; bool return2=false;
@ -224,16 +232,21 @@ unsigned char* DivPlatformPV1000::getRegisterPool() {
} }
int DivPlatformPV1000::getRegisterPoolSize() { int DivPlatformPV1000::getRegisterPoolSize() {
return 3; return 4;
} }
void DivPlatformPV1000::reset() { void DivPlatformPV1000::reset() {
memset(regPool,0,3); memset(regPool,0,4);
for (int i=0; i<3; i++) { for (int i=0; i<3; i++) {
chan[i]=Channel(); chan[i]=Channel();
chan[i].std.setEngine(parent); chan[i].std.setEngine(parent);
} }
d65010g031_reset(&d65010g031); d65010g031_reset(&d65010g031);
// mute
rWrite(0,0x3f);
rWrite(1,0x3f);
rWrite(2,0x3f);
rWrite(3,2);
} }
int DivPlatformPV1000::getOutputCount() { int DivPlatformPV1000::getOutputCount() {

View file

@ -33,7 +33,7 @@ class DivPlatformPV1000: public DivDispatch {
DivDispatchOscBuffer* oscBuf[3]; DivDispatchOscBuffer* oscBuf[3];
bool isMuted[3]; bool isMuted[3];
unsigned char regPool[3]; unsigned char regPool[4];
d65010g031_t d65010g031; d65010g031_t d65010g031;
friend void putDispatchChip(void*,int); friend void putDispatchChip(void*,int);
friend void putDispatchChan(void*,int,int); friend void putDispatchChan(void*,int,int);

View file

@ -67,7 +67,7 @@ int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle)
{ {
if (square->period > 0) if (square->period > 0)
{ {
int period = d65010g031_max(1, (0x3f - square->period)); const int period = square->period;
square->counter += cycle; square->counter += cycle;
while (square->counter >= period) while (square->counter >= period)
{ {
@ -92,7 +92,29 @@ int d65010g031_sound_tick(struct d65010g031_t *d65010g031, const int cycle)
int out = 0; int out = 0;
for (int i = 0; i < 3; i++) 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; return out;
} }
@ -105,12 +127,23 @@ void d65010g031_reset(struct d65010g031_t *d65010g031)
d65010g031->square[i].counter = 0; d65010g031->square[i].counter = 0;
d65010g031->square[i].out = 0; d65010g031->square[i].out = 0;
} }
d65010g031->ctrl = 0;
} }
void d65010g031_write(struct d65010g031_t *d65010g031, const unsigned char a, const unsigned char d) 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;
} }
} }

View file

@ -54,6 +54,8 @@ struct d65010g031_square_t
struct d65010g031_t struct d65010g031_t
{ {
struct d65010g031_square_t square[3]; 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); int d65010g031_square_tick(struct d65010g031_square_t *square, const int cycle);

View file

@ -1839,7 +1839,11 @@ void DivEngine::registerSystems() {
{"Square 1", "Square 2", "Square 3"}, {"Square 1", "Square 2", "Square 3"},
{"S1", "S2", "S3"}, {"S1", "S2", "S3"},
{DIV_CH_PULSE, DIV_CH_PULSE, DIV_CH_PULSE}, {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( sysDefs[DIV_SYSTEM_SFX_BEEPER_QUADTONE]=new DivSysDef(