2 FUJITSU FM Towns Emulator 'eFMTowns'
4 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
18 #define EVENT_ADC_CLOCK 1
20 void ADPCM::initialize()
22 adc_fifo = new FIFO(64); // OK?
36 dac_intr_mask = 0x0000; // Disable
37 dac_intr = 0x0000; // OFF
38 latest_dac_intr = false;
44 write_signals(&outputs_intr, 0x00000000);
45 write_signals(&outputs_led_control, 0x00000000);
46 write_signals(&outputs_allmute, 0xffffffff); // OK?
48 initialize_adc_clock(-1);
51 void ADPCM::initialize_adc_clock(int freq)
54 freq = (int)d_adc->read_signal(SIG_AD7820_SAMPLE_RATE);
56 if(event_adc_clock >= 0) {
57 cancel_event(this, event_adc_clock);
59 d_adc->write_signal(SIG_AD7820_DATA_REG, 0x00, 0x00);
60 d_adc->write_signal(SIG_AD7820_CS, 0xffffffff, 0xffffffff);
61 d_adc->write_signal(SIG_AD7820_WR_CONVERSION_MODE, 0, 0xffffffff); // READ MODE..
62 register_event(this, EVENT_ADC_CLOCK, 1.0e6 / (double)freq, true, &event_adc_clock);
65 void ADPCM::event_callback(int id, int err)
69 if(!(adc_fifo->full())) {
70 d_adc->write_signal(SIG_AD7820_WR_CONVERSION_MODE, 0, 0xffffffff); // READ MODE
71 d_adc->write_signal(SIG_AD7820_CS, 0xffffffff, 0xffffffff);
72 d_adc->read_data8(SIG_AD7820_DATA_REG); // Dummy read, start to sample.
78 uint32_t ADPCM::read_io8(uint32_t addr)
81 0x04d5 : OPN2/ADPCM MUTE
83 0x04e9 - 0x04ec : DAC CONTROL
87 case 0x04d5: // Mute reg
88 val |= ((opn2_mute) ? 0 : 0x02);
89 val |= ((adpcm_mute) ? 0 : 0x01);
91 case 0x04e7: // ADC data register
92 if(!(adc_fifo->empty())) {
93 val = (uint8_t)(adc_fifo->read() & 0xff);
98 case 0x04e8: // ADC flags
99 val = (!(adc_fifo->empty())) ? 0x01 : 0x00;
101 case 0x04e9: // Int13 reason
102 val = 0x00 | ((dac_intr != 0) ? 0x08 : 0x00) | ((opx_intr) ? 0x01 : 0x00);
103 // write_signals(&outputs_intr, 0); // Clear Interrupt
107 case 0x04ea: // PCM Interrupt mask
110 case 0x04eb: // PCM Interrupt status
114 if(latest_dac_intr) {
115 latest_dac_intr = false;
117 if(!(opx_intr)) write_signals(&outputs_intr, 0); // Clear Interrupt
126 void ADPCM::write_io8(uint32_t addr, uint32_t data)
129 0x04d5 : OPN2/ADPCM MUTE
130 0x04e7 - 0x04e8 : ADC
131 0x04e9 - 0x04ec : DAC CONTROL
135 opn2_mute = ((data & 0x02) == 0) ? true : false;
136 adpcm_mute = ((data & 0x01) == 0) ? true : false;
137 d_opn2->write_signal(SIG_YM2612_MUTE, (opn2_mute) ? 0xffffffff : 0x00000000, 0xffffffff);
138 d_rf5c68->write_signal(SIG_RF5C68_MUTE, (adpcm_mute) ? 0xffffffff : 0x00000000, 0xffffffff);
144 dac_intr_mask = data;
147 write_signals(&outputs_led_control, ((data & 0x80) == 0) ? 0xffffffff : 0x00000000);
148 write_signals(&outputs_allmute, ((data & 0x40) == 0) ? 0xffffffff : 0x00000000);
155 void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
157 if(ch == SIG_ADPCM_WRITE_INTERRUPT) {
158 // out_debug_log(_T("SIG_ADPCM_WRITE_INTERRUPT val=%08X mask=%08X"), data ,mask);
159 uint32_t n_ch = data & 0x07;
160 bool n_onoff = (((data & mask) & 0x00000008) != 0) ? true : false;
161 bool n_allset =(((data & mask) & 0x80000000) != 0) ? true : false;
164 _d = ((dac_intr_mask & (1 << n_ch)) != 0) ? true : false;
166 dac_intr = dac_intr | (1 << n_ch);
168 dac_intr = dac_intr & ~(1 << n_ch);
172 uint16_t intr_backup = dac_intr;
173 dac_intr = (n_onoff) ? 0xffff : 0x0000;
175 // _d = (dac_intr != intr_backup) ? true : false;
177 if((n_onoff) && (_d)) { // ON
178 write_signals(&outputs_intr, 0xffffffff);
179 latest_dac_intr = true;
180 } else if(!(n_onoff) || !(_d)) {
182 write_signals(&outputs_intr, 0x00000000);
184 latest_dac_intr = false;
186 } else if(ch == SIG_ADPCM_OPX_INTR) { // SET/RESET INT13
187 // out_debug_log(_T("SIG_ADPCM_OPX_INTR val=%08X mask=%08X"), data ,mask);
188 opx_intr = ((data & mask) != 0);
190 write_signals(&outputs_intr, 0xffffffff);
192 if(!(latest_dac_intr)) {
193 write_signals(&outputs_intr, 0x00000000);
196 } else if(ch == SIG_ADPCM_ADC_INTR) { // Push data to FIFO from ADC.
197 if((data & mask) != 0) {
198 uint32_t n_data = d_adc->read_signal(SIG_AD7820_DATA_REG);
199 d_adc->write_signal(SIG_AD7820_CS, 0, 0xffffffff);
200 if(!(adc_fifo->full())) {
201 adc_fifo->write((int)(n_data & 0xff));
207 uint32_t ADPCM::read_signal(int ch)
212 #define STATE_VERSION 2
214 bool ADPCM::process_state(FILEIO* state_fio, bool loading)
216 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
219 if(!state_fio->StateCheckInt32(this_device_id)) {
222 if(!(adc_fifo->process_state((void *)state_fio, loading))) {
225 state_fio->StateValue(opn2_mute);
226 state_fio->StateValue(adpcm_mute);
228 state_fio->StateValue(opx_intr);
229 state_fio->StateValue(dac_intr);
230 state_fio->StateValue(dac_intr_mask);
231 state_fio->StateValue(latest_dac_intr);
233 state_fio->StateValue(event_adc_clock);