6 void TOWNS_DMAC::initialize()
8 UPD71071::initialize();
11 void TOWNS_DMAC::reset()
15 dma_addr_mask = 0xffffffff; // OK?
16 // dma_addr_mask = 0x000fffff; // OK?
17 for(int i = 0; i < 4; i++) {
21 // b16 = 2; // Fixed 16bit.
24 void TOWNS_DMAC::write_io16(uint32_t addr, uint32_t data)
32 creg_set[selch] = true;
33 dma[selch].creg = data & 0xffff;
35 dma[selch].bcreg = data & 0xffff;
36 bcreg_set[selch] = true;
43 _d.d = dma[selch].areg;
44 _bd.d = dma[selch].bareg;
45 if((addr & 0x0f) < 6) {
47 _d.w.l = (data & 0xffff);
48 dma[selch].areg = _d.d;
50 _bd.w.l = (data & 0xffff);
51 dma[selch].bareg = _bd.d;
54 _d.w.h = (data & 0xffff);
55 dma[selch].areg = _d.d;
57 _bd.w.h = (data & 0xffff);
58 dma[selch].bareg = _bd.d;
64 if(((data & 0x04) != (cmd & 0x04)) && (selch == 3)) {
65 if((data & 0x04) == 0) {
66 out_debug_log(_T("TRANSFER: CMD=%04X -> %04X CH=%d\nADDR=%08X"), cmd, (cmd & 0xff00) | (data & 0xff), selch, dma[selch].areg);
71 // write_io8(addr & 0x0e, data);
72 write_io8(addr, data);
76 write_io8(addr, data);
77 // write_io8((addr & 0x0e) + 0, data);
78 // write_io8((addr & 0x0e) + 1, data);
82 void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data)
84 // if((addr & 0x0f) == 0x0c) out_debug_log("WRITE REG: %08X %08X", addr, data);
85 // out_debug_log("WRITE REG: %04X %02X", addr, data);
91 // out_debug_log(_T("RESET REG(00h) to %02X"), data);
95 // Note: This is *temporaly* workaround for 16bit transfer mode with 8bit bus.
98 creg_set[selch] = true;
100 bcreg_set[selch] = true;
103 _d.d = dma[selch].areg;
104 _bd.d = dma[selch].bareg;
108 dma[selch].areg = _d.d;
110 dma[selch].bareg = _bd.d;
114 if(((data & 0x04) != (cmd & 0x04)) && (selch == 3)) {
115 if((data & 0x04) != 0) break;
116 out_debug_log(_T("TRANSFER: CMD=%04X -> %04X CH=%d\nADDR=%08X"), cmd, (cmd & 0xff00) | (data & 0xff), selch, dma[selch].areg);
121 out_debug_log(_T("SET MODE[%d] to %02X"), selch, data);
125 if(((data | req) & 0x08) != 0) {
126 // out_debug_log(_T("TRANSFER ENABLE@REG0E DATA=%02X"), data);
130 // Note: This is *temporaly* workaround for 16bit transfer mode with 8bit bus.
132 #if !defined(USE_QUEUED_SCSI_TRANSFER)
133 if((dma[selch].is_16bit) && !(inputs_ube[selch])) {
134 if(creg_set[selch]) {
135 dma[selch].creg <<= 1;
137 creg_set[selch] = false;
139 if(bcreg_set[selch]) {
140 dma[selch].bcreg <<= 1;
142 bcreg_set[selch] = false;
145 bcreg_set[selch] = false;
146 creg_set[selch] = false;
152 UPD71071::write_io8(addr, data);
155 uint32_t TOWNS_DMAC::read_io16(uint32_t addr)
158 switch(addr & 0x0f) {
162 return (dma[selch].creg & 0xffff);
164 return (dma[selch].bcreg & 0xffff);
170 return (dma[selch].areg & 0xffff);
172 return (dma[selch].bareg & 0xffff);
178 return ((dma[selch].areg >> 16) & 0xffff);
180 return ((dma[selch].bareg >> 16) & 0xffff);
185 return (uint32_t)(cmd & 0xffff);
188 return read_io8(addr);
189 // return read_io8(addr & 0x0e);
195 _d.b.l = read_io8(addr);
196 // _d.b.l = read_io8((addr & 0x0e) + 0);
197 // _d.b.h = read_io8((addr & 0x0e) + 1);
198 return (uint32_t)(_d.w);
202 uint32_t TOWNS_DMAC::read_io8(uint32_t addr)
206 switch(addr & 0x0f) {
208 return (base << 3) | (1 << (selch & 3));
213 _d.d = dma[selch].creg;
214 #if !defined(USE_QUEUED_SCSI_TRANSFER)
215 if((dma[selch].is_16bit) && !(inputs_ube[selch])) {
216 if(!(creg_set[selch])) {
222 _d.d = dma[selch].bcreg;
223 #if !defined(USE_QUEUED_SCSI_TRANSFER)
224 if((dma[selch].is_16bit) && !(inputs_ube[selch])) {
225 if(!(bcreg_set[selch])) {
231 switch(addr & 0x0f) {
242 _d.d = dma[selch].areg;
244 _d.d = dma[selch].bareg;
246 return (uint32_t)(_d.b.h3);
249 return UPD71071::read_io8(addr);
252 void TOWNS_DMAC::do_dma_inc_dec_ptr_8bit(int c)
254 // Note: FM-Towns may extend to 32bit.
255 if(dma_wrap_reg != 0) {
256 uint32_t high_a = dma[c].areg & 0xff000000;
257 if(dma[c].mode & 0x20) {
258 dma[c].areg = dma[c].areg - 1;
260 dma[c].areg = dma[c].areg + 1;
262 dma[c].areg = ((dma[c].areg & 0x00ffffff) | high_a) & dma_addr_mask;
264 if(dma[c].mode & 0x20) {
265 dma[c].areg = (dma[c].areg - 1) & dma_addr_mask;
267 dma[c].areg = (dma[c].areg + 1) & dma_addr_mask;
272 void TOWNS_DMAC::do_dma_inc_dec_ptr_16bit(int c)
274 // Note: FM-Towns may extend to 32bit.
275 if(dma_wrap_reg != 0) {
276 uint32_t high_a = dma[c].areg & 0xff000000;
277 if(dma[c].mode & 0x20) {
278 dma[c].areg = dma[c].areg - 2;
280 dma[c].areg = dma[c].areg + 2;
282 dma[c].areg = ((dma[c].areg & 0x00ffffff) | high_a) & dma_addr_mask;
284 if(dma[c].mode & 0x20) {
285 dma[c].areg = (dma[c].areg - 2) & dma_addr_mask;
287 dma[c].areg = (dma[c].areg + 2) & dma_addr_mask;
292 bool TOWNS_DMAC::do_dma_epilogue(int c)
294 if(dma[c].creg == 0) { // OK?
297 out_debug_log(_T("TRANSFER COMPLETED CH.3: AREG=%08X BAREG=%08X CREG=%08X BCREG=%08X"),
298 (dma[c].areg & 0xffffffff) ,
299 (dma[c].bareg & 0xffffffff) ,
300 dma[c].creg & 0x00ffffff,
301 dma[c].bcreg & 0x00ffffff
306 return UPD71071::do_dma_epilogue(c);
309 uint32_t TOWNS_DMAC::read_signal(int id)
311 if(SIG_TOWNS_DMAC_WRAP_REG) {
313 } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
314 return dma_addr_mask;
316 return UPD71071::read_signal(id);
319 void TOWNS_DMAC::write_signal(int id, uint32_t data, uint32_t _mask)
321 if(id == SIG_TOWNS_DMAC_WRAP_REG) {
323 // this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask);
324 } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
325 // From eFMR50 / memory.cpp / update_dma_addr_mask()
326 dma_addr_mask = data;
329 // if(id == SIG_UPD71071_CH1) {
330 // out_debug_log(_T("DRQ from SCSI %02X %02X"), data, mask);
332 UPD71071::write_signal(id, data, _mask);
336 void TOWNS_DMAC::do_dma_dev_to_mem_8bit(int c)
340 uint32_t addr = dma[c].areg;
342 val = dma[c].dev->read_dma_io8(0);
344 // update temporary register
345 tmp = (tmp >> 8) | (val << 8);
348 if(d_debugger != NULL && d_debugger->now_device_debugging) {
349 d_debugger->write_via_debugger_data8(addr, val);
351 write_via_debugger_data8(addr, val);
354 write_via_debugger_data8(addr, val);
358 void TOWNS_DMAC::do_dma_mem_to_dev_8bit(int c)
362 uint32_t addr = dma[c].areg;
365 if(d_debugger != NULL && d_debugger->now_device_debugging) {
366 val = d_debugger->read_via_debugger_data8(addr);
368 val = read_via_debugger_data8(addr);
371 val = read_via_debugger_data8(addr);
373 // update temporary register
374 tmp = (tmp >> 8) | (val << 8);
376 dma[c].dev->write_dma_io8(0, val);
379 void TOWNS_DMAC::do_dma_dev_to_mem_16bit(int c)
383 uint32_t addr = dma[c].areg;
385 val = dma[c].dev->read_dma_io16(0);
386 // update temporary register
389 if((addr & 1) != 0) {
390 // If odd address, write a byte.
391 uint32_t tval = (val >> 8) & 0xff;
393 if(d_debugger != NULL && d_debugger->now_device_debugging) {
394 d_debugger->write_via_debugger_data8(addr, tval);
396 write_via_debugger_data8(addr, tval);
399 write_via_debugger_data8(addr, tval);
405 if(d_debugger != NULL && d_debugger->now_device_debugging) {
406 d_debugger->write_via_debugger_data16(addr, val);
408 write_via_debugger_data16(addr, val);
411 write_via_debugger_data16(addr, val);
416 void TOWNS_DMAC::do_dma_mem_to_dev_16bit(int c)
420 uint32_t addr = dma[c].areg;
423 if(d_debugger != NULL && d_debugger->now_device_debugging) {
424 val = d_debugger->read_via_debugger_data16(addr);
426 val = this->read_via_debugger_data16(addr);
429 val = this->read_via_debugger_data16(addr);
431 // if((addr & 1) != 0) {
432 // // If odd address, read a high byte.
433 // val = (val >> 8) & 0xff;
435 // update temporary register
438 dma[c].dev->write_dma_io16(0, val);
442 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
443 bool TOWNS_DMAC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
445 static const _TCHAR *dir[4] = {
446 _T("VERIFY"), _T("I/O->MEM"), _T("MEM->I/O"), _T("INVALID")
448 if(buffer == NULL) return false;
449 _TCHAR sbuf[4][512] = {0};
450 for(int i = 0; i < 4; i++) {
451 my_stprintf_s(sbuf[i], 512,
452 _T("CH%d AREG=%08X CREG=%04X BAREG=%08X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n"),
458 ((req | sreq) >> 0) & 1,
461 dir[(dma[i].mode >> 2) & 3]
465 my_stprintf_s(buffer, buffer_len,
466 _T("16Bit=%s ADDR_MASK=%08X ADDR_WRAP=%02X \n")
467 _T("SELECT CH=%d BASE=%02X REQ=%02X SREQ=%02X MASK=%02X TC=%02X ")
468 _T("CMD=%04X TMP=%04X\n")
473 (b16 != 0) ? _T("YES") : _T("NO"), dma_addr_mask, dma_wrap_reg,
474 selch, base, req, sreq, mask, tc,
485 #define STATE_VERSION 3
487 bool TOWNS_DMAC::process_state(FILEIO *state_fio, bool loading)
489 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
492 if(!state_fio->StateCheckInt32(this_device_id)) {
495 if(!(UPD71071::process_state(state_fio, loading))) {
498 state_fio->StateValue(dma_wrap_reg);
499 state_fio->StateValue(dma_addr_mask);
500 state_fio->StateArray(creg_set, sizeof(creg_set), 1);
501 state_fio->StateArray(bcreg_set, sizeof(bcreg_set), 1);