mirror of
https://github.com/wavemotion-dave/NINTV-DS.git
synced 2025-06-18 13:55:33 -04:00
181 lines
5.4 KiB
C++
181 lines
5.4 KiB
C++
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "AY38914.h"
|
|
#include "AY38914_Registers.h"
|
|
|
|
AY38914_Registers::AY38914_Registers(UINT16 address)
|
|
: RAM(0x10, address, 0xFFFF, 0xFFFF)
|
|
{}
|
|
|
|
void AY38914_Registers::init(AY38914* ay38914)
|
|
{
|
|
this->ay38914 = ay38914;
|
|
}
|
|
|
|
void AY38914_Registers::reset()
|
|
{
|
|
memset(memory, 0, sizeof(memory));
|
|
}
|
|
|
|
void AY38914_Registers::poke(UINT16 location, UINT16 value)
|
|
{
|
|
location &= 0x0F;
|
|
switch(location) {
|
|
case 0x00:
|
|
value = value & 0x00FF;
|
|
channel0.period = (channel0.period & 0x0F00) |
|
|
value;
|
|
channel0.periodValue = (channel0.period
|
|
? channel0.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x01:
|
|
value = value & 0x00FF;
|
|
channel1.period = (channel1.period & 0x0F00) |
|
|
value;
|
|
channel1.periodValue = (channel1.period
|
|
? channel1.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x02:
|
|
value = value & 0x00FF;
|
|
channel2.period = (channel2.period & 0x0F00) |
|
|
value;
|
|
channel2.periodValue = (channel2.period
|
|
? channel2.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x03:
|
|
value = value & 0x00FF;
|
|
envelopePeriod = (envelopePeriod & 0xFF00) |
|
|
value;
|
|
envelopePeriodValue = (envelopePeriod
|
|
? (envelopePeriod << 1) : 0x20000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x04:
|
|
value = value & 0x000F;
|
|
channel0.period = (channel0.period & 0x00FF) |
|
|
(value<<8);
|
|
channel0.periodValue = (channel0.period
|
|
? channel0.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x05:
|
|
value = value & 0x000F;
|
|
channel1.period = (channel1.period & 0x00FF) |
|
|
(value<<8);
|
|
channel1.periodValue = (channel1.period
|
|
? channel1.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x06:
|
|
value = value & 0x000F;
|
|
channel2.period = (channel2.period & 0x00FF) |
|
|
(value<<8);
|
|
channel2.periodValue = (channel2.period
|
|
? channel2.period : 0x1000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x07:
|
|
value = value & 0x00FF;
|
|
envelopePeriod = (envelopePeriod & 0x00FF) |
|
|
(value<<8);
|
|
envelopePeriodValue = (envelopePeriod
|
|
? (envelopePeriod << 1) : 0x20000);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x08:
|
|
value = value & 0x00FF;
|
|
channel0.toneDisabled = !!(value & 0x0001);
|
|
channel1.toneDisabled = !!(value & 0x0002);
|
|
channel2.toneDisabled = !!(value & 0x0004);
|
|
channel0.noiseDisabled = !!(value & 0x0008);
|
|
channel1.noiseDisabled = !!(value & 0x0010);
|
|
channel2.noiseDisabled = !!(value & 0x0020);
|
|
channel0.isDirty = TRUE;
|
|
channel1.isDirty = TRUE;
|
|
channel2.isDirty = TRUE;
|
|
noiseIdle = channel0.noiseDisabled &
|
|
channel1.noiseDisabled &
|
|
channel2.noiseDisabled;
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x09:
|
|
value = value & 0x001F;
|
|
noisePeriod = value;
|
|
noisePeriodValue = (noisePeriod
|
|
? (noisePeriod << 1) : 0x0040);
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x0A:
|
|
value = value & 0x000F;
|
|
envelopeHold = !!(value & 0x0001);
|
|
envelopeAltr = !!(value & 0x0002);
|
|
envelopeAtak = !!(value & 0x0004);
|
|
envelopeCont = !!(value & 0x0008);
|
|
envelopeVolume = (envelopeAtak ? 0 : 15);
|
|
envelopeCounter = envelopePeriodValue;
|
|
envelopeIdle = FALSE;
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x0B:
|
|
value = value & 0x003F;
|
|
channel0.envelope = !!(value & 0x0010);
|
|
channel0.volume = (value & 0x000F);
|
|
channel0.isDirty = TRUE;
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x0C:
|
|
value = value & 0x003F;
|
|
channel1.envelope = !!(value & 0x0010);
|
|
channel1.volume = (value & 0x000F);
|
|
channel1.isDirty = TRUE;
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x0D:
|
|
value = value & 0x003F;
|
|
channel2.envelope = !!(value & 0x0010);
|
|
channel2.volume = (value & 0x000F);
|
|
channel2.isDirty = TRUE;
|
|
memory[location] = value;
|
|
break;
|
|
|
|
case 0x0E:
|
|
ay38914->psgIO1->setOutputValue(value);
|
|
break;
|
|
|
|
case 0x0F:
|
|
ay38914->psgIO0->setOutputValue(value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
UINT16 AY38914_Registers::peek(UINT16 location)
|
|
{
|
|
location &= 0x0F;
|
|
switch(location) {
|
|
case 0x0E:
|
|
return ay38914->psgIO1->getInputValue();
|
|
case 0x0F:
|
|
return ay38914->psgIO0->getInputValue();
|
|
default:
|
|
return memory[location];
|
|
}
|
|
}
|
|
|