Allow 8 bit filter write, Linear pitch support

This commit is contained in:
cam900 2022-05-11 15:10:21 +09:00
parent 54e78699a7
commit 23f086fda6
3 changed files with 64 additions and 39 deletions

View file

@ -170,8 +170,8 @@ enum DivDispatchCmds {
DIV_CMD_N163_GLOBAL_WAVE_LOADMODE, DIV_CMD_N163_GLOBAL_WAVE_LOADMODE,
DIV_CMD_ES5506_FILTER_MODE, // (value) DIV_CMD_ES5506_FILTER_MODE, // (value)
DIV_CMD_ES5506_FILTER_K1, // (value) DIV_CMD_ES5506_FILTER_K1, // (value, mask)
DIV_CMD_ES5506_FILTER_K2, // (value) DIV_CMD_ES5506_FILTER_K2, // (value, mask)
DIV_CMD_ES5506_FILTER_K1_SLIDE, // (value, negative) DIV_CMD_ES5506_FILTER_K1_SLIDE, // (value, negative)
DIV_CMD_ES5506_FILTER_K2_SLIDE, // (value, negative) DIV_CMD_ES5506_FILTER_K2_SLIDE, // (value, negative)
DIV_CMD_ES5506_ENVELOPE_COUNT, // (count) DIV_CMD_ES5506_ENVELOPE_COUNT, // (count)

View file

@ -23,8 +23,8 @@
#include <math.h> #include <math.h>
#include <map> #include <map>
#define CHIP_FREQBASE (16*2048*(chanMax+1)) #define PITCH_OFFSET ((double)(16*2048*(chanMax+1)))
#define NOTE_ES5506(c,note) (chan[c].pcm.freqOffs*NOTE_FREQUENCY(note)) #define NOTE_ES5506(c,note) (parent->calcBaseFreq(chipClock,chan[c].pcm.freqOffs,note,false))
#define rWrite(a,...) {if(!skipRegisterWrites) {hostIntf32.emplace(4,(a),__VA_ARGS__); }} #define rWrite(a,...) {if(!skipRegisterWrites) {hostIntf32.emplace(4,(a),__VA_ARGS__); }}
#define rRead(a,...) {hostIntf32.emplace(4,(a),__VA_ARGS__);} #define rRead(a,...) {hostIntf32.emplace(4,(a),__VA_ARGS__);}
@ -111,6 +111,30 @@ const char* DivPlatformES5506::getEffectName(unsigned char effect) {
case 0x11: case 0x11:
return "11xx: Set filter mode (00 to 03)"; return "11xx: Set filter mode (00 to 03)";
break; break;
case 0x14:
return "14xx: Set filter coefficient K1 low byte";
break;
case 0x15:
return "15xx: Set filter coefficient K1 high byte";
break;
case 0x16:
return "16xx: Set filter coefficient K2 low byte";
break;
case 0x17:
return "17xx: Set filter coefficient K2 high byte";
break;
case 0x18:
return "18xx: Set filter coefficient K1 slide up";
break;
case 0x19:
return "19xx: Set filter coefficient K1 slide down";
break;
case 0x1a:
return "1axx: Set filter coefficient K2 slide up";
break;
case 0x1b:
return "1bxx: Set filter coefficient K2 slide down";
break;
case 0x20: case 0x20:
return "20xx: Set envelope count (000 to 0FF)"; return "20xx: Set envelope count (000 to 0FF)";
break; break;
@ -124,35 +148,24 @@ const char* DivPlatformES5506::getEffectName(unsigned char effect) {
return "23xx: Set envelope right volume ramp (signed)"; return "23xx: Set envelope right volume ramp (signed)";
break; break;
case 0x24: case 0x24:
return "24xx: Set envelope k1 ramp (signed)"; return "24xx: Set envelope filter coefficient k1 ramp (signed)";
break; break;
case 0x25: case 0x25:
return "25xx: Set envelope k1 ramp (signed, slower)"; return "25xx: Set envelope filter coefficient k1 ramp (signed, slower)";
break; break;
case 0x26: case 0x26:
return "26xx: Set envelope k2 ramp (signed)"; return "26xx: Set envelope filter coefficient k2 ramp (signed)";
break; break;
case 0x27: case 0x27:
return "27xx: Set envelope k2 ramp (signed, slower)"; return "27xx: Set envelope filter coefficient k2 ramp (signed, slower)";
break;
case 0x28:
return "28xx: Set filter K1 slide up";
break;
case 0x29:
return "29xx: Set filter K1 slide down";
break;
case 0x2a:
return "28xx: Set filter K2 slide up";
break;
case 0x2b:
return "29xx: Set filter K2 slide down";
break; break;
default: default:
if ((effect&0xf0)==0x30) { if ((effect&0xf0)==0x30) {
return "3xxx: Set filter K1"; return "3xxx: Set filter coefficient K1";
} else if ((effect&0xf0)==0x40) { } else if ((effect&0xf0)==0x40) {
return "4xxx: Set filter K2"; return "4xxx: Set filter coefficient K2";
} }
break;
} }
return NULL; return NULL;
} }
@ -480,7 +493,7 @@ void DivPlatformES5506::tick(bool sysTick) {
const unsigned int length=s->samples-1; const unsigned int length=s->samples-1;
const unsigned int end=start+(length<<11); const unsigned int end=start+(length<<11);
chan[i].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT; chan[i].pcm.loopMode=s->isLoopable()?s->loopMode:DIV_SAMPLE_LOOPMODE_ONESHOT;
chan[i].pcm.freqOffs=off; chan[i].pcm.freqOffs=PITCH_OFFSET*off;
chan[i].pcm.reversed=ins->amiga.reversed; chan[i].pcm.reversed=ins->amiga.reversed;
chan[i].pcm.bank=(s->offES5506>>22)&3; chan[i].pcm.bank=(s->offES5506>>22)&3;
chan[i].pcm.start=start; chan[i].pcm.start=start;
@ -565,7 +578,7 @@ void DivPlatformES5506::tick(bool sysTick) {
chan[i].noteChanged.changed=0; chan[i].noteChanged.changed=0;
} }
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=CLAMP_VAL(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2),0,0x1ffff); chan[i].freq=CLAMP_VAL(parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,2,chan[i].pitch2,chipClock,chan[c].pcm.freqOffs),0,0x1ffff);
if (chan[i].keyOn) { if (chan[i].keyOn) {
if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) { if (chan[i].pcm.index>=0 && chan[i].pcm.index<parent->song.sampleLen) {
chan[i].k1Prev=0xffff; chan[i].k1Prev=0xffff;
@ -707,7 +720,7 @@ int DivPlatformES5506::dispatch(DivCommand c) {
const unsigned int length=s->samples-1; const unsigned int length=s->samples-1;
const unsigned int end=start+(length<<11); const unsigned int end=start+(length<<11);
chan[c.chan].pcm.loopMode=loopMode; chan[c.chan].pcm.loopMode=loopMode;
chan[c.chan].pcm.freqOffs=off; chan[c.chan].pcm.freqOffs=PITCH_OFFSET*off;
chan[c.chan].pcm.reversed=reversed; chan[c.chan].pcm.reversed=reversed;
chan[c.chan].pcm.bank=(s->offES5506>>22)&3; chan[c.chan].pcm.bank=(s->offES5506>>22)&3;
chan[c.chan].pcm.start=start; chan[c.chan].pcm.start=start;
@ -815,11 +828,11 @@ int DivPlatformES5506::dispatch(DivCommand c) {
chan[c.chan].filterChanged.mode=1; chan[c.chan].filterChanged.mode=1;
break; break;
case DIV_CMD_ES5506_FILTER_K1: case DIV_CMD_ES5506_FILTER_K1:
chan[c.chan].filter.k1=(chan[c.chan].filter.k1&0xf)|((c.value&0xfff)<<4); chan[c.chan].filter.k1=(chan[c.chan].filter.k1&~c.value2)|(c.value&c.value2);
chan[c.chan].filterChanged.k1=1; chan[c.chan].filterChanged.k1=1;
break; break;
case DIV_CMD_ES5506_FILTER_K2: case DIV_CMD_ES5506_FILTER_K2:
chan[c.chan].filter.k2=(chan[c.chan].filter.k2&0xf)|((c.value&0xfff)<<4); chan[c.chan].filter.k2=(chan[c.chan].filter.k2&~c.value2)|(c.value&c.value2);
chan[c.chan].filterChanged.k2=1; chan[c.chan].filterChanged.k2=1;
break; break;
case DIV_CMD_ES5506_FILTER_K1_SLIDE: case DIV_CMD_ES5506_FILTER_K1_SLIDE:

View file

@ -1730,6 +1730,26 @@ void DivEngine::registerSystems() {
case 0x11: // filter mode case 0x11: // filter mode
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_MODE,ch,effectVal&3)); dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_MODE,ch,effectVal&3));
break; break;
case 0x14: // filter coefficient K1, 8 bit LSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1,ch,effectVal&0xff,0x00ff));
break;
case 0x15: // filter coefficient K1, 8 bit MSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1,ch,(effectVal&0xff)<<8,0xff00));
break;
case 0x16: // filter coefficient K2, 8 bit LSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2,ch,effectVal&0xff,0x00ff));
break;
case 0x17: // filter coefficient K2, 8 bit MSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2,ch,(effectVal&0xff)<<8,0xff00));
break;
case 0x18: // filter coefficient K1 slide up
case 0x19: // filter coefficient K1 slide down
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1_SLIDE,ch,effectVal,effect&0x01));
break;
case 0x1a: // filter coefficient K2 slide up
case 0x1b: // filter coefficient K2 slide down
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2_SLIDE,ch,effectVal,effect&0x01));
break;
case 0x20: case 0x20:
case 0x21: // envelope ECOUNT case 0x21: // envelope ECOUNT
dispatchCmd(DivCommand(DIV_CMD_ES5506_ENVELOPE_COUNT,ch,((effect&0x01)<<8)|effectVal)); dispatchCmd(DivCommand(DIV_CMD_ES5506_ENVELOPE_COUNT,ch,((effect&0x01)<<8)|effectVal));
@ -1748,19 +1768,11 @@ void DivEngine::registerSystems() {
case 0x27: // envelope K2RAMP case 0x27: // envelope K2RAMP
dispatchCmd(DivCommand(DIV_CMD_ES5506_ENVELOPE_K2RAMP,ch,effectVal,effect&0x01)); dispatchCmd(DivCommand(DIV_CMD_ES5506_ENVELOPE_K2RAMP,ch,effectVal,effect&0x01));
break; break;
case 0x28: // filter K1 slide up
case 0x29: // filter K1 slide down
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1_SLIDE,ch,effectVal,effect&0x01));
break;
case 0x2a: // filter K2 slide up
case 0x2b: // filter K2 slide down
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2_SLIDE,ch,effectVal,effect&0x01));
break;
default: default:
if ((effect&0xf0)==0x30) { if ((effect&0xf0)==0x30) { // filter coefficient K1, 12 bit MSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1,ch,((effect&0x0f)<<8)|effectVal)); dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K1,ch,((effect&0x0f)<<12)|((effectVal&0xff)<<4),0xfff0));
} else if ((effect&0xf0)==0x40) { } else if ((effect&0xf0)==0x40) { // filter coefficient K2, 12 bit MSB
dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2,ch,((effect&0x0f)<<8)|effectVal)); dispatchCmd(DivCommand(DIV_CMD_ES5506_FILTER_K2,ch,((effect&0x0f)<<12)|((effectVal&0xff)<<4),0xfff0));
} else { } else {
return false; return false;
} }