NES: fix Furnace-style DPCM
This commit is contained in:
		
							parent
							
								
									ce40085d3b
								
							
						
					
					
						commit
						960048cf4b
					
				|  | @ -313,8 +313,6 @@ void DivPlatformNES::tick(bool sysTick) { | ||||||
|         if (chan[i].freq<0) chan[i].freq=0; |         if (chan[i].freq<0) chan[i].freq=0; | ||||||
|       } |       } | ||||||
|       if (chan[i].keyOn) { |       if (chan[i].keyOn) { | ||||||
|         //rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(ins->gb.soundLen&63)));
 |  | ||||||
|         //rWrite(16+i*5+2,((chan[i].vol<<4))|(ins->gb.envLen&7)|((ins->gb.envDir&1)<<3));
 |  | ||||||
|       } |       } | ||||||
|       if (chan[i].keyOff) { |       if (chan[i].keyOff) { | ||||||
|         //rWrite(16+i*5+2,8);
 |         //rWrite(16+i*5+2,8);
 | ||||||
|  | @ -343,7 +341,7 @@ void DivPlatformNES::tick(bool sysTick) { | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // PCM
 |   // PCM
 | ||||||
|   if (chan[4].freqChanged) { |   if (chan[4].freqChanged || chan[4].keyOn) { | ||||||
|     chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,false); |     chan[4].freq=parent->calcFreq(chan[4].baseFreq,chan[4].pitch,false); | ||||||
|     if (chan[4].furnaceDac) { |     if (chan[4].furnaceDac) { | ||||||
|       double off=1.0; |       double off=1.0; | ||||||
|  | @ -352,11 +350,27 @@ void DivPlatformNES::tick(bool sysTick) { | ||||||
|         off=(double)s->centerRate/8363.0; |         off=(double)s->centerRate/8363.0; | ||||||
|       } |       } | ||||||
|       dacRate=MIN(chan[4].freq*off,32000); |       dacRate=MIN(chan[4].freq*off,32000); | ||||||
|       if (dpcmMode && !skipRegisterWrites) { |       if (chan[4].keyOn) { | ||||||
|         rWrite(0x4010,calcDPCMRate(dacRate)); |         if (dpcmMode && !skipRegisterWrites && dacSample>=0 && dacSample<parent->song.sampleLen) { | ||||||
|  |           unsigned int dpcmAddr=parent->getSample(dacSample)->offDPCM; | ||||||
|  |           unsigned int dpcmLen=(parent->getSample(dacSample)->lengthDPCM+15)>>4; | ||||||
|  |           if (dpcmLen>255) dpcmLen=255; | ||||||
|  |           // write DPCM
 | ||||||
|  |           rWrite(0x4015,15); | ||||||
|  |           rWrite(0x4010,calcDPCMRate(dacRate)); | ||||||
|  |           rWrite(0x4012,(dpcmAddr>>6)&0xff); | ||||||
|  |           rWrite(0x4013,dpcmLen&0xff); | ||||||
|  |           rWrite(0x4015,31); | ||||||
|  |           dpcmBank=dpcmAddr>>14; | ||||||
|  |         } | ||||||
|  |       } else { | ||||||
|  |         if (dpcmMode) { | ||||||
|  |           rWrite(0x4010,calcDPCMRate(dacRate)); | ||||||
|  |         } | ||||||
|       } |       } | ||||||
|       if (dumpWrites) addWrite(0xffff0001,dacRate); |       if (dumpWrites && !dpcmMode) addWrite(0xffff0001,dacRate); | ||||||
|     } |     } | ||||||
|  |     if (chan[4].keyOn) chan[4].keyOn=false; | ||||||
|     chan[4].freqChanged=false; |     chan[4].freqChanged=false; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | @ -378,25 +392,13 @@ int DivPlatformNES::dispatch(DivCommand c) { | ||||||
|           dacPos=0; |           dacPos=0; | ||||||
|           dacPeriod=0; |           dacPeriod=0; | ||||||
|           if (c.value!=DIV_NOTE_NULL) { |           if (c.value!=DIV_NOTE_NULL) { | ||||||
|             chan[c.chan].baseFreq=parent->song.tuning*pow(2.0f,((float)(c.value+3)/12.0f)); |             chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value,false); | ||||||
|             chan[c.chan].freqChanged=true; |             chan[c.chan].freqChanged=true; | ||||||
|             chan[c.chan].note=c.value; |             chan[c.chan].note=c.value; | ||||||
|           } |           } | ||||||
|           chan[c.chan].active=true; |           chan[c.chan].active=true; | ||||||
|           chan[c.chan].keyOn=true; |           chan[c.chan].keyOn=true; | ||||||
|           chan[c.chan].furnaceDac=true; |           chan[c.chan].furnaceDac=true; | ||||||
|           if (dpcmMode && !skipRegisterWrites) { |  | ||||||
|             unsigned int dpcmAddr=parent->getSample(dacSample)->offDPCM; |  | ||||||
|             unsigned int dpcmLen=(parent->getSample(dacSample)->lengthDPCM+15)>>4; |  | ||||||
|             if (dpcmLen>255) dpcmLen=255; |  | ||||||
|             // write DPCM
 |  | ||||||
|             rWrite(0x4015,15); |  | ||||||
|             rWrite(0x4010,calcDPCMRate(chan[c.chan].baseFreq)); |  | ||||||
|             rWrite(0x4012,(dpcmAddr>>6)&0xff); |  | ||||||
|             rWrite(0x4013,dpcmLen&0xff); |  | ||||||
|             rWrite(0x4015,31); |  | ||||||
|             dpcmBank=dpcmAddr>>14; |  | ||||||
|           } |  | ||||||
|         } else { |         } else { | ||||||
|           if (c.value!=DIV_NOTE_NULL) { |           if (c.value!=DIV_NOTE_NULL) { | ||||||
|             chan[c.chan].note=c.value; |             chan[c.chan].note=c.value; | ||||||
|  | @ -492,7 +494,7 @@ int DivPlatformNES::dispatch(DivCommand c) { | ||||||
|       chan[c.chan].freqChanged=true; |       chan[c.chan].freqChanged=true; | ||||||
|       break; |       break; | ||||||
|     case DIV_CMD_NOTE_PORTA: { |     case DIV_CMD_NOTE_PORTA: { | ||||||
|       int destFreq=NOTE_PERIODIC(c.value2); |       int destFreq=(c.chan==4)?(parent->calcBaseFreq(1,1,c.value2,false)):(NOTE_PERIODIC(c.value2)); | ||||||
|       bool return2=false; |       bool return2=false; | ||||||
|       if (destFreq>chan[c.chan].baseFreq) { |       if (destFreq>chan[c.chan].baseFreq) { | ||||||
|         chan[c.chan].baseFreq+=c.value; |         chan[c.chan].baseFreq+=c.value; | ||||||
|  | @ -554,7 +556,11 @@ int DivPlatformNES::dispatch(DivCommand c) { | ||||||
|       break; |       break; | ||||||
|     case DIV_CMD_LEGATO: |     case DIV_CMD_LEGATO: | ||||||
|       if (c.chan==3) break; |       if (c.chan==3) break; | ||||||
|       chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0))); |       if (c.chan==4) { | ||||||
|  |         chan[c.chan].baseFreq=parent->calcBaseFreq(1,1,c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0)),false); | ||||||
|  |       } else { | ||||||
|  |         chan[c.chan].baseFreq=NOTE_PERIODIC(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0))); | ||||||
|  |       } | ||||||
|       chan[c.chan].freqChanged=true; |       chan[c.chan].freqChanged=true; | ||||||
|       chan[c.chan].note=c.value; |       chan[c.chan].note=c.value; | ||||||
|       break; |       break; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 tildearrow
						tildearrow