6 void TOWNS_DMAC::initialize()
8 UPD71071::initialize();
11 void TOWNS_DMAC::reset()
15 // dma_wrap_reg = 0x00;
16 dma_addr_mask = 0xffffffff; // OK?
17 // dma_addr_mask = 0x000fffff; // OK?
18 // b16 = 2; // Fixed 16bit.
21 void TOWNS_DMAC::write_io16(uint32_t addr, uint32_t data)
24 // out_debug_log(_T("OUT16 %04X,%04X"), addr & 0xffff, data & 0xffff);
29 _d.d = dma[selch].areg;
31 dma[selch].areg = _d.d;
33 _d.d = dma[selch].bareg;
35 dma[selch].bareg = _d.d;
40 if((data & 0x04) != (cmd & 0x04)) {
41 if((data & 0x04) == 0) {
42 out_debug_log(_T("START TRANSFER:CH=%d CMD=%04X -> %04X AREG=%08X BAREG=%08X CREG=%04X BCREG=%04X"),
45 dma[selch].areg, dma[selch].bareg,
46 dma[selch].creg, dma[selch].bcreg
49 out_debug_log(_T("CLEAR TRANSFER:CH=%d CMD=%04X -> %04X AREG=%08X BAREG=%08X CREG=%04X BCREG=%04X"),
52 dma[selch].areg, dma[selch].bareg,
53 dma[selch].creg, dma[selch].bcreg
62 UPD71071::write_io16(addr, data);
66 void TOWNS_DMAC::write_io8(uint32_t addr, uint32_t data)
68 // if((addr & 0x0f) == 0x0c) out_debug_log("WRITE REG: %08X %08X", addr, data);
69 // out_debug_log("WRITE REG: %04X %02X", addr, data);
75 // out_debug_log(_T("RESET REG(00h) to %02X"), data);
78 dma[selch].bareg = manipulate_a_byte_from_dword_le(dma[selch].bareg, 3, data);
80 dma[selch].areg = manipulate_a_byte_from_dword_le(dma[selch].areg, 3, data);
84 #if 0 /* For Debugging */
86 if((data & 0x04) != (cmd & 0x04)) {
87 if((data & 0x04) == 0) {
88 out_debug_log(_T("START TRANSFER:CH=%d CMD=%04X -> %04X AREG=%08X BAREG=%08X CREG=%04X BCREG=%04X"),
90 cmd, (cmd & 0xff00) | (data & 0x00ff),
91 dma[selch].areg, dma[selch].bareg,
92 dma[selch].creg, dma[selch].bcreg
95 out_debug_log(_T("CLEAR TRANSFER:CH=%d CMD=%04X -> %04X AREG=%08X BAREG=%08X CREG=%04X BCREG=%04X"),
97 cmd, (cmd & 0xff00) | (data & 0x00ff),
98 dma[selch].areg, dma[selch].bareg,
99 dma[selch].creg, dma[selch].bcreg
105 // if((selch == 3)) {
106 // out_debug_log(_T("SET MODE[%d] to %02X"), selch, data);
110 if(((data | req) & 0x08) != 0) {
111 // out_debug_log(_T("TRANSFER ENABLE@REG0E DATA=%02X"), data);
118 UPD71071::write_io8(addr, data);
121 uint32_t TOWNS_DMAC::read_io16(uint32_t addr)
123 switch(addr & 0x0e) {
126 return ((dma[selch].areg >> 16) & 0xffff);
128 return ((dma[selch].bareg >> 16) & 0xffff);
132 // return read_io8(addr & 0x0e);
135 return UPD71071::read_io16(addr);
139 uint32_t TOWNS_DMAC::read_io8(uint32_t addr)
143 switch(addr & 0x0f) {
146 _d.d = dma[selch].areg;
148 _d.d = dma[selch].bareg;
150 return (uint32_t)(_d.b.h3);
153 return UPD71071::read_io8(addr);
156 void TOWNS_DMAC::do_dma_inc_dec_ptr_8bit(int c)
158 // Note: FM-Towns may extend to 32bit.
159 int32_t incdec = ((dma[c].mode & 0x20) == 0) ? 1 : -1;
160 uint32_t addr = dma[c].areg;
161 uint32_t high_a = addr & 0xff000000;
162 __LIKELY_IF(dma_wrap_reg != 0) {
163 addr = (addr + incdec) & 0x00ffffff;
164 addr = addr | high_a;
166 addr = (addr + incdec) & 0xffffffff;
171 void TOWNS_DMAC::do_dma_inc_dec_ptr_16bit(int c)
173 // Note: FM-Towns may extend to 32bit.
174 int32_t incdec = ((dma[c].mode & 0x20) == 0) ? 2 : -2;
175 uint32_t addr = dma[c].areg;
176 uint32_t high_a = addr & 0xff000000;
177 __LIKELY_IF(dma_wrap_reg != 0) {
178 addr = (addr + incdec) & 0x00ffffff;
179 addr = addr | high_a;
181 addr = (addr + incdec) & 0xffffffff;
186 #if 0 /* For Debug */
187 bool TOWNS_DMAC::do_dma_epilogue(int c)
189 if((dma[c].creg == 0) || ((dma[c].endreq) && !(dma[c].end) && ((dma[c].mode & 0xc0) != 0x40))) { // OK?
192 if((dma[c].end) || (dma[c].endreq)) is_tc = true;
194 if(dma[c].bcreg < (dma[c].creg - 1)) {
199 out_debug_log(_T("TRANSFER COMPLETED:CH=%d AREG=%08X BAREG=%08X CREG=%08X BCREG=%08X"),
201 (dma[c].areg & 0xffffffff) ,
202 (dma[c].bareg & 0xffffffff) ,
203 dma[c].creg & 0x00ffffff,
204 dma[c].bcreg & 0x00ffffff
209 return UPD71071::do_dma_epilogue(c);
213 uint32_t TOWNS_DMAC::read_signal(int id)
215 if(id == SIG_TOWNS_DMAC_WRAP_REG) {
217 } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
218 return dma_addr_mask;
220 return UPD71071::read_signal(id);
223 void TOWNS_DMAC::write_signal(int id, uint32_t data, uint32_t _mask)
225 if(id == SIG_TOWNS_DMAC_WRAP_REG) {
227 // this->write_signal(SIG_TOWNS_DMAC_ADDR_MASK, data, mask);
228 } else if(id == SIG_TOWNS_DMAC_ADDR_MASK) {
229 // From eFMR50 / memory.cpp / update_dma_addr_mask()
230 //dma_addr_mask = data;
233 // if(id == SIG_UPD71071_CH1) {
234 // out_debug_log(_T("DRQ from SCSI %02X %02X"), data, mask);
236 UPD71071::write_signal(id, data, _mask);
241 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
242 bool TOWNS_DMAC::get_debug_regs_info(_TCHAR *buffer, size_t buffer_len)
244 static const _TCHAR *dir[4] = {
245 _T("VERIFY"), _T("I/O->MEM"), _T("MEM->I/O"), _T("INVALID")
247 if(buffer == NULL) return false;
248 _TCHAR sbuf[4][512] = {0};
249 for(int i = 0; i < 4; i++) {
250 my_stprintf_s(sbuf[i], 512,
251 _T("CH%d AREG=%08X CREG=%04X BAREG=%08X BCREG=%04X REQ=%d MASK=%d MODE=%02X %s\n"),
257 ((req | sreq) >> 0) & 1,
260 dir[(dma[i].mode >> 2) & 3]
264 my_stprintf_s(buffer, buffer_len,
265 _T("16Bit=%s ADDR_MASK=%08X ADDR_WRAP=%02X \n")
266 _T("SELECT CH=%d BASE=%02X REQ=%02X SREQ=%02X MASK=%02X TC=%02X ")
267 _T("CMD=%04X TMP=%04X\n")
272 (b16 != 0) ? _T("YES") : _T("NO"), dma_addr_mask, dma_wrap_reg,
273 selch, base, req, sreq, mask, tc,
284 #define STATE_VERSION 3
286 bool TOWNS_DMAC::process_state(FILEIO *state_fio, bool loading)
288 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
291 if(!state_fio->StateCheckInt32(this_device_id)) {
294 if(!(UPD71071::process_state(state_fio, loading))) {
297 state_fio->StateValue(dma_wrap_reg);
298 state_fio->StateValue(dma_addr_mask);