2 Skelton for retropc emulator
4 Origin : Neko Project 2
5 Author : Takeda.Toshiya
14 static const uint16_t np2_freq_table[] = {
15 0, 0x051B, 0x0569, 0x05BB, 0x0613, 0x066F, 0x06D1,
16 0x0739, 0x07A7, 0x081B, 0x0897, 0x091A, 0x09A4, 0,0,0,
17 0, 0x0A37, 0x0AD3, 0x0B77, 0x0C26, 0x0CDF, 0x0DA3,
18 0x0E72, 0x0F4E, 0x1037, 0x112E, 0x1234, 0x1349, 0,0,0,
19 0, 0x146E, 0x15A6, 0x16EF, 0x184C, 0x19BE, 0x1B46,
20 0x1CE5, 0x1E9D, 0x206F, 0x225D, 0x2468, 0x2692, 0,0,0,
21 0, 0x28DD, 0x2B4C, 0x2DDF, 0x3099, 0x337D, 0x368D,
22 0x39CB, 0x3D3B, 0x40DF, 0x44BA, 0x48D1, 0x4D25, 0x51BB, 0,0
27 datareg = maskreg = 0;
28 memset(ch, 0, sizeof(ch));
33 void TMS3631::write_signal(int id, uint32_t data, uint32_t mask)
35 if(id == SIG_TMS3631_ENVELOP1) {
37 envelop1 = (envelop1 & ~mask) | (data & mask);
38 } else if(id == SIG_TMS3631_ENVELOP2) {
40 envelop2 = (envelop2 & ~mask) | (data & mask);
41 } else if(id == SIG_TMS3631_DATAREG) {
44 data = (datareg & ~mask) | (data & mask);
46 if(!(datareg & 0x80)) {
50 ch[channel].freq = freq_table[data & 0x3f];
52 } else if(!(data & 0x40) && (datareg & 0x40)) {
54 channel = (channel + 1) & 7;
58 } else if(id == SIG_TMS3631_MASKREG) {
60 maskreg = (maskreg & ~mask) | (data & mask);
64 void TMS3631::mix(int32_t* buffer, int cnt)
67 for(int i = 0; i < cnt; i++) {
69 for(int j = 0; j < 2; j++) {
70 if((maskreg & (1 << j)) && ch[j].freq != 0) {
71 for(int k = 0; k < 4; k++) {
72 ch[j].count += ch[j].freq;
73 data += (ch[j].count & 0x10000) ? 1 : -1;
77 int vol_l = data * vol;
78 int vol_r = data * vol;
79 for(int j = 2; j < 5; j++) {
80 if((maskreg & (1 << j)) && ch[j].freq != 0) {
81 for(int k = 0; k < 4; k++) {
82 ch[j].count += ch[j].freq;
83 vol_l += feet[(ch[j].count >> 16) & 15];
87 for(int j = 5; j < 8; j++) {
88 if((maskreg & (1 << j)) && ch[j].freq != 0) {
89 for(int k = 0; k < 4; k++) {
90 ch[j].count += ch[j].freq;
91 vol_r += feet[(ch[j].count >> 16) & 15];
95 *buffer++ += apply_volume(vol_l, volume_l); // L
96 *buffer++ += apply_volume(vol_r, volume_r); // R
100 void TMS3631::set_volume(int ch, int decibel_l, int decibel_r)
102 volume_l = decibel_to_volume(decibel_l);
103 volume_r = decibel_to_volume(decibel_r);
106 void TMS3631::initialize_sound(int rate, int volume)
109 for(int i = 0; i < 64; i++) {
110 freq_table[i] = (uint32_t)((double)np2_freq_table[i] * 11025.0 / (double)rate / 2.0 + 0.5);
112 for(int i = 0; i < 16; i++) {
114 for(int j = 0; j < 4; j++) {
115 data += (volume / 8) * ((i & (1 << j)) ? 1 : -1);
122 #define STATE_VERSION 2
124 bool TMS3631::process_state(FILEIO* state_fio, bool loading)
126 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
129 if(!state_fio->StateCheckInt32(this_device_id)) {
132 state_fio->StateUint8(envelop1);
133 state_fio->StateUint8(envelop2);
134 state_fio->StateUint8(datareg);
135 state_fio->StateUint8(maskreg);
136 // state_fio->StateBuffer(ch, sizeof(ch), 1);
137 for(int i = 0; i < 8; i++) {
138 state_fio->StateUint32(ch[i].freq);
139 state_fio->StateUint32(ch[i].count);
142 state_fio->StateUint8(channel);
143 state_fio->StateBool(set_key);