2 FUJITSU FM Towns Emulator 'eFMTowns'
4 Author : Kyuma.Ohta <whatisthis.sowhat _at_ gmail.com>
15 void ADPCM::initialize()
17 for(int i = 0; i < 8; i++) {
18 dac_int_mask[i] = true; // true = enable intrrupt.
28 uint32_t ADPCM::read_io8(uint32_t addr)
36 case 0x07: // ADC data register
37 if(!(adc_fifo->empty())) {
38 val = (uint8_t)(adc_fifo->read() & 0xff);
43 case 0x08: // ADC flags
44 val = (!(adc_fifo->empty())) ? 0x01 : 0x00;
46 case 0x09: // Int13 reason
48 bool intr_pcm = false;
49 for(int i = 0; i < 8; i++) {
55 val = 0xf6 | ((intr_pcm) ? 0x08 : 0x00) | ((intr_opx) ? 0x01 : 0x00);
58 case 0x0a: // PCM Interrupt mask
60 for(int i = 0; i < 8; i++) {
61 val = val | ((dac_int_mask[i]) ? (0x01 << i) : 0);
64 case 0x0b: // PCM Interrupt status
68 for(int i = 0; i < 8; i++) {
69 val = val | ((dac_intr[i]) ? (0x01 << i) : 0);
71 for(int i = 0; i < 8; i++) {
78 d_pic->write_signal(SIG_I8259_IR5 | SIG_I8259_CHIP1, 0x00000000, 0xffffffff);
83 if((addr & 0x1f) >= 0x10) val = d_rf5c68->read_io8(addr & 0x0f); // AROUND DAC
89 void ADPCM::write_io8(uint32_t addr, uint32_t data)
91 uint32_t naddr = addr & 0x1f;
94 } else if(naddr == 0x0a) {
96 for(int i = 0; i < 8; i++) {
97 if((data & mask) != 0) {
98 dac_int_mask[i] = true;
100 dac_int_mask[i] = false;
104 } else if(naddr >= 0x10) {
105 d_rf5c68->write_io8(naddr & 0x0f, data);
109 uint32_t ADPCM::read_data8(uint32_t addr)
111 if((addr >= 0xc2200000) && (addr < 0xc2201000)) {
112 return d_rf5c68->read_data8(addr & 0x0fff);
117 void ADPCM::write_data8(uint32_t addr, uint32_t data)
119 if((addr >= 0xc2200000) && (addr < 0xc2201000)) {
120 d_rf5c68->write_data8(addr & 0x0fff, data);
124 void ADPCM::write_signal(int ch, uint32_t data, uint32_t mask)
126 if(ch == SIG_ADPCM_WRITE_INTERRUPT) {
127 uint32_t n_ch = data & 0x07;
128 bool n_onoff = (((data & mask) & 0x00000008) != 0) ? true : false;
129 bool n_allset =(((data & mask) & 0x80000000) != 0) ? true : false;
131 n_onoff = n_onoff & dac_int_mask[n_ch];
132 if(n_onoff != dac_intr[n_ch]) { // SET/RESET INT13
133 write_signals(&output_intr, (n_onoff) ? 0xffffffff : 0x00000000);
135 dac_intr[n_ch] = n_onoff;
140 for(int i = 0; i < 8; i++) { // SET/RESET INT13
141 n_backup = dac_intr[i];
142 dac_intr[i] = n_onoff & dac_int_mask[i];
143 if(n_backup != dac_intr[i]) _s = true;
146 write_signals(&output_intr, (n_onoff) ? 0xffffffff : 0x00000000);
149 } else if(ch == SIG_ADPCM_OPX_INTR) { // SET/RESET INT13
150 intr_opx = ((data & mask) != 0);
151 write_signals(&output_intr, (intr_opx) ? 0xffffffff : 0x00000000);
152 } else if(ch == SIG_ADPCM_PUSH_FIFO) { // Push data to FIFO from ADC.
153 if(adc_fifo->full()) {
154 adc_fifo->read(); // Dummy read
156 adc_fifo->write((int)(data & 0xff));
160 #define STATE_VERSION 1
162 bool ADPCM::process_state(FILEIO* state_fio, bool loading)
164 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
167 if(!state_fio->StateCheckInt32(this_device_id)) {
170 if(!(adc_fifo->process_state((void *)state_fio, loading))) {
173 state_fio->StateValue(intr_opx);
174 state_fio->StateArray(dac_intr, sizeof(dac_intr), 1);
175 state_fio->StateArray(dac_int_mask, sizeof(dac_int_mask), 1);