2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
13 void UPD71071::initialize()
16 _SINGLE_MODE_DMA = osd->check_feature(_T("SINGLE_MODE_DMA"));
17 _USE_DEBUGGER = osd->check_feature(_T("USE_DEBUGGER"));
18 for(int i = 0; i < 4; i++) {
19 dma[i].areg = dma[i].bareg = 0;
20 dma[i].creg = dma[i].bcreg = 0;
23 if(d_debugger != NULL) {
24 d_debugger->set_device_name(_T("Debugger (uPD71071 DMAC)"));
25 d_debugger->set_context_mem(this);
26 d_debugger->set_context_io(vm->dummy);
31 void UPD71071::reset()
33 for(int i = 0; i < 4; i++) {
36 b16 = selch = base = 0;
42 void UPD71071::write_io8(uint32_t addr, uint32_t data)
48 for(int i = 0; i < 4; i++) {
63 dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data;
65 dma[selch].creg = (dma[selch].creg & 0xff00) | data;
69 dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8);
71 dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8);
75 dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data;
77 dma[selch].areg = (dma[selch].areg & 0xffff00) | data;
81 dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8);
83 dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8);
87 dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16);
89 dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16);
93 cmd = (cmd & 0xff00) | data;
96 cmd = (cmd & 0xff) | (data << 8);
99 dma[selch].mode = data;
102 if(((sreq = data) != 0) && !(_SINGLE_MODE_DMA)) {
103 //#ifndef SINGLE_MODE_DMA
114 uint32_t UPD71071::read_io8(uint32_t addr)
118 switch(addr & 0x0f) {
122 return (base << 2) | (1 << selch);
125 return dma[selch].bcreg & 0xff;
127 return dma[selch].creg & 0xff;
131 return (dma[selch].bcreg >> 8) & 0xff;
133 return (dma[selch].creg >> 8) & 0xff;
137 return dma[selch].bareg & 0xff;
139 return dma[selch].areg & 0xff;
143 return (dma[selch].bareg >> 8) & 0xff;
145 return (dma[selch].areg >> 8) & 0xff;
149 return (dma[selch].bareg >> 16) & 0xff;
151 return (dma[selch].areg >> 16) & 0xff;
156 return (cmd >> 8) & 0xff;
158 return dma[selch].mode;
160 val = (req << 4) | tc;
166 return (tmp >> 8) & 0xff;
175 void UPD71071::write_signal(int id, uint32_t data, uint32_t mask)
177 uint8_t bit = 1 << (id & 3);
182 //#ifndef SINGLE_MODE_DMA
183 if(!_SINGLE_MODE_DMA) do_dma();
191 void UPD71071::write_via_debugger_data8(uint32_t addr, uint32_t data)
193 d_mem->write_dma_data8(addr, data);
196 uint32_t UPD71071::read_via_debugger_data8(uint32_t addr)
198 return d_mem->read_dma_data8(addr);
201 void UPD71071::write_via_debugger_data16(uint32_t addr, uint32_t data)
203 d_mem->write_dma_data16(addr, data);
206 uint32_t UPD71071::read_via_debugger_data16(uint32_t addr)
208 return d_mem->read_dma_data16(addr);
211 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
213 uint32_t UPD71071::read_signal(int ch)
215 if((ch >= (SIG_UPD71071_IS_TRANSFERING + 0)) && (ch < (SIG_UPD71071_IS_TRANSFERING + 4))) {
216 bool _nch = ch - SIG_UPD71071_IS_TRANSFERING;
217 if((cmd & 0x04) != 0) return 0x00; // Not transfering
218 if((dma[_nch].creg == 0)) return 0x00; //
220 } else if((ch >= (SIG_UPD71071_IS_16BITS_TRANSFER + 0)) && (ch < (SIG_UPD71071_IS_16BITS_TRANSFER + 4))) {
221 bool _nch = ch - SIG_UPD71071_IS_16BITS_TRANSFER;
222 return ((dma[_nch].mode & 1) != 0) ? 0xffffffff : 0;
227 void UPD71071::do_dma()
235 for(int c = 0; c < 4; c++) {
236 uint8_t bit = 1 << c;
237 if(((req | sreq) & bit) && !(mask & bit)) {
239 while((req | sreq) & bit) {
240 // Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1).
241 if((dma[c].mode & 0x01) == 1) {
242 // 8bit transfer mode
243 if((dma[c].mode & 0x0c) == 0x00) {
245 uint32_t val = dma[c].dev->read_dma_io16(0);
246 // update temporary register
248 } else if((dma[c].mode & 0x0c) == 0x04) {
251 val = dma[c].dev->read_dma_io16(0);
252 write_signals(&outputs_wrote_mem_word, dma[c].areg);
254 if(d_debugger != NULL && d_debugger->now_device_debugging) {
255 d_debugger->write_via_debugger_data16(dma[c].areg, val);
257 this->write_via_debugger_data16(dma[c].areg, val);
260 this->write_via_debugger_data16(dma[c].areg, val);
263 // update temporary register
265 } else if((dma[c].mode & 0x0c) == 0x08) {
269 if(d_debugger != NULL && d_debugger->now_device_debugging) {
270 val = d_debugger->read_via_debugger_data16(dma[c].areg);
272 val = this->read_via_debugger_data16(dma[c].areg);
275 val = this->read_via_debugger_data16(dma[c].areg);
277 dma[c].dev->write_dma_io16(0, val);
278 // update temporary register
281 if(dma[c].mode & 0x20) {
282 dma[c].areg = (dma[c].areg - 2) & 0xffffff;
284 dma[c].areg = (dma[c].areg + 2) & 0xffffff;
286 if(dma[c].creg-- == 0) { // OK?
288 if(dma[c].mode & 0x10) {
290 dma[c].areg = dma[c].bareg;
291 dma[c].creg = dma[c].bcreg;
299 write_signals(&outputs_tc, 0xffffffff);
300 } else if(_SINGLE_MODE_DMA) {
301 if((dma[c].mode & 0xc0) == 0x40) {
307 // 8bit transfer mode
308 if((dma[c].mode & 0x0c) == 0x00) {
310 uint32_t val = dma[c].dev->read_dma_io8(0);
311 // update temporary register
312 tmp = (tmp >> 8) | (val << 8);
313 } else if((dma[c].mode & 0x0c) == 0x04) {
316 val = dma[c].dev->read_dma_io8(0);
317 write_signals(&outputs_wrote_mem_byte, dma[c].areg);
319 if(d_debugger != NULL && d_debugger->now_device_debugging) {
320 d_debugger->write_via_debugger_data8(dma[c].areg, val);
322 this->write_via_debugger_data8(dma[c].areg, val);
325 this->write_via_debugger_data8(dma[c].areg, val);
327 // update temporary register
328 tmp = (tmp >> 8) | (val << 8);
329 } else if((dma[c].mode & 0x0c) == 0x08) {
333 if(d_debugger != NULL && d_debugger->now_device_debugging) {
334 val = d_debugger->read_via_debugger_data8(dma[c].areg);
336 val = this->read_via_debugger_data8(dma[c].areg);
339 val = this->read_via_debugger_data8(dma[c].areg);
341 dma[c].dev->write_dma_io8(0, val);
342 // update temporary register
343 tmp = (tmp >> 8) | (val << 8);
345 if(dma[c].mode & 0x20) {
346 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
348 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
351 if(dma[c].creg-- == 0) {
353 if(dma[c].mode & 0x10) {
355 dma[c].areg = dma[c].bareg;
356 dma[c].creg = dma[c].bcreg;
364 write_signals(&outputs_tc, 0xffffffff);
365 //#ifdef SINGLE_MODE_DMA
366 } else if(_SINGLE_MODE_DMA) {
367 if((dma[c].mode & 0xc0) == 0x40) {
376 //#ifdef SINGLE_MODE_DMA
377 if(_SINGLE_MODE_DMA) {
385 bool UPD71071::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
388 CH0 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF MEM->I/O
389 CH1 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF I/O->MEM
390 CH2 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF VERIFY
391 CH3 AREG=FFFF CREG=FFFF BAREG=FFFF BCREG=FFFF REQ=1 MASK=1 MODE=FF INVALID
393 static const _TCHAR *dir[4] = {
394 _T("VERIFY"), _T("I/O->MEM"), _T("MEM->I/O"), _T("INVALID")
396 my_stprintf_s(buffer, buffer_len,
397 _T("CH0 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n")
398 _T("CH1 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n")
399 _T("CH2 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n")
400 _T("CH3 AREG=%04X CREG=%04X BAREG=%04X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s"),
401 dma[0].areg, dma[0].creg, dma[0].bareg, dma[0].bcreg, ((req | sreq) >> 0) & 1, (mask >> 0) & 1, dma[0].mode, dir[(dma[0].mode >> 2) & 3],
402 dma[1].areg, dma[1].creg, dma[1].bareg, dma[1].bcreg, ((req | sreq) >> 1) & 1, (mask >> 1) & 1, dma[1].mode, dir[(dma[1].mode >> 2) & 3],
403 dma[2].areg, dma[2].creg, dma[2].bareg, dma[2].bcreg, ((req | sreq) >> 2) & 1, (mask >> 2) & 1, dma[2].mode, dir[(dma[2].mode >> 2) & 3],
404 dma[3].areg, dma[3].creg, dma[3].bareg, dma[3].bcreg, ((req | sreq) >> 3) & 1, (mask >> 3) & 1, dma[3].mode, dir[(dma[3].mode >> 2) & 3]);
408 #define STATE_VERSION 1
410 bool UPD71071::process_state(FILEIO* state_fio, bool loading)
412 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
415 if(!state_fio->StateCheckInt32(this_device_id)) {
418 for(int i = 0; i < 4; i++) {
419 state_fio->StateValue(dma[i].areg);
420 state_fio->StateValue(dma[i].bareg);
421 state_fio->StateValue(dma[i].creg);
422 state_fio->StateValue(dma[i].bcreg);
423 state_fio->StateValue(dma[i].mode);
425 state_fio->StateValue(b16);
426 state_fio->StateValue(selch);
427 state_fio->StateValue(base);
428 state_fio->StateValue(cmd);
429 state_fio->StateValue(tmp);
430 state_fio->StateValue(req);
431 state_fio->StateValue(sreq);
432 state_fio->StateValue(mask);
433 state_fio->StateValue(tc);