2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void UPD71071::initialize()
15 _SINGLE_MODE_DMA = osd->check_feature(_T("SINGLE_MODE_DMA"));
17 for(int i = 0; i < 4; i++) {
18 dma[i].areg = dma[i].bareg = 0;
19 dma[i].creg = dma[i].bcreg = 0;
23 void UPD71071::reset()
25 for(int i = 0; i < 4; i++) {
28 b16 = selch = base = 0;
34 void UPD71071::write_io8(uint32_t addr, uint32_t data)
40 for(int i = 0; i < 4; i++) {
55 dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data;
57 dma[selch].creg = (dma[selch].creg & 0xff00) | data;
61 dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8);
63 dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8);
67 dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data;
69 dma[selch].areg = (dma[selch].areg & 0xffff00) | data;
73 dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8);
75 dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8);
79 dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16);
81 dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16);
85 cmd = (cmd & 0xff00) | data;
88 cmd = (cmd & 0xff) | (data << 8);
91 dma[selch].mode = data;
94 if(((sreq = data) != 0) && !(_SINGLE_MODE_DMA)) {
95 //#ifndef SINGLE_MODE_DMA
106 uint32_t UPD71071::read_io8(uint32_t addr)
110 switch(addr & 0x0f) {
114 return (base << 2) | (1 << selch);
117 return dma[selch].bcreg & 0xff;
119 return dma[selch].creg & 0xff;
123 return (dma[selch].bcreg >> 8) & 0xff;
125 return (dma[selch].creg >> 8) & 0xff;
129 return dma[selch].bareg & 0xff;
131 return dma[selch].areg & 0xff;
135 return (dma[selch].bareg >> 8) & 0xff;
137 return (dma[selch].areg >> 8) & 0xff;
141 return (dma[selch].bareg >> 16) & 0xff;
143 return (dma[selch].areg >> 16) & 0xff;
148 return (cmd >> 8) & 0xff;
150 return dma[selch].mode;
152 val = (req << 4) | tc;
158 return (tmp >> 8) & 0xff;
167 void UPD71071::write_signal(int id, uint32_t data, uint32_t mask)
169 uint8_t bit = 1 << (id & 3);
174 //#ifndef SINGLE_MODE_DMA
175 if(!_SINGLE_MODE_DMA) do_dma();
183 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
185 void UPD71071::do_dma()
193 for(int c = 0; c < 4; c++) {
194 uint8_t bit = 1 << c;
195 if(((req | sreq) & bit) && !(mask & bit)) {
197 while((req | sreq) & bit) {
198 // ToDo: Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1).
200 if((dma[c].mode & 0x01) == 1) {
201 // 16bit transfer mode
202 if((dma[c].mode & 0x0c) == 0x00) {
204 uint32_t val = dma[c].dev->read_dma_io16(0);
205 // update temporary register
207 } else if((dma[c].mode & 0x0c) == 0x04) {
210 if(dma[c].dev != NULL) {
211 val = dma[c].dev->read_dma_io16(0);
215 d_mem->write_dma_data16(dma[c].areg, val);
216 // update temporary register
218 } else if((dma[c].mode & 0x0c) == 0x08) {
220 uint32_t val = d_mem->read_dma_data16(dma[c].areg);
221 if(dma[c].dev != NULL) dma[c].dev->write_dma_io16(0, val);
222 // update temporary register
225 if(dma[c].mode & 0x20) {
226 dma[c].areg = (dma[c].areg - 2) & 0xffffff;
228 dma[c].areg = (dma[c].areg + 2) & 0xffffff;
233 // 8bit transfer mode
234 if((dma[c].mode & 0x0c) == 0x00) {
236 uint32_t val = dma[c].dev->read_dma_io8(0);
237 // update temporary register
238 tmp = (tmp >> 8) | (val << 8);
239 } else if((dma[c].mode & 0x0c) == 0x04) {
242 val = dma[c].dev->read_dma_io8(0);
243 d_mem->write_dma_data8(dma[c].areg, val);
244 // update temporary register
245 tmp = (tmp >> 8) | (val << 8);
246 } else if((dma[c].mode & 0x0c) == 0x08) {
248 uint32_t val = d_mem->read_dma_data8(dma[c].areg);
249 dma[c].dev->write_dma_io8(0, val);
250 // update temporary register
251 tmp = (tmp >> 8) | (val << 8);
253 if(dma[c].mode & 0x20) {
254 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
256 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
259 if(dma[c].creg-- == 0) {
261 if(dma[c].mode & 0x10) {
263 dma[c].areg = dma[c].bareg;
264 dma[c].creg = dma[c].bcreg;
272 write_signals(&outputs_tc, 0xffffffff);
273 //#ifdef SINGLE_MODE_DMA
274 } else if(_SINGLE_MODE_DMA) {
275 if((dma[c].mode & 0xc0) == 0x40) {
284 //#ifdef SINGLE_MODE_DMA
285 if(_SINGLE_MODE_DMA) {
293 #define STATE_VERSION 1
295 #include "../statesub.h"
297 void UPD71071::decl_state()
299 enter_decl_state(STATE_VERSION);
301 for(int i = 0; i < 4; i++) {
302 DECL_STATE_ENTRY_UINT32_MEMBER((dma[i].areg), i);
303 DECL_STATE_ENTRY_UINT32_MEMBER((dma[i].bareg), i);
304 DECL_STATE_ENTRY_UINT16_MEMBER((dma[i].creg), i);
305 DECL_STATE_ENTRY_UINT16_MEMBER((dma[i].bcreg), i);
306 DECL_STATE_ENTRY_UINT8_MEMBER((dma[i].mode), i);
308 DECL_STATE_ENTRY_UINT8(b16);
309 DECL_STATE_ENTRY_UINT8(selch);
310 DECL_STATE_ENTRY_UINT8(base);
311 DECL_STATE_ENTRY_UINT16(cmd);
312 DECL_STATE_ENTRY_UINT16(tmp);
313 DECL_STATE_ENTRY_UINT8(req);
314 DECL_STATE_ENTRY_UINT8(sreq);
315 DECL_STATE_ENTRY_UINT8(mask);
316 DECL_STATE_ENTRY_UINT8(tc);
321 void UPD71071::save_state(FILEIO* state_fio)
323 if(state_entry != NULL) {
324 state_entry->save_state(state_fio);
327 // state_fio->FputUint32(STATE_VERSION);
328 // state_fio->FputInt32(this_device_id);
330 // for(int i = 0; i < 4; i++) {
331 // state_fio->FputUint32(dma[i].areg);
332 // state_fio->FputUint32(dma[i].bareg);
333 // state_fio->FputUint16(dma[i].creg);
334 // state_fio->FputUint16(dma[i].bcreg);
335 // state_fio->FputUint8(dma[i].mode);
337 // state_fio->FputUint8(b16);
338 // state_fio->FputUint8(selch);
339 // state_fio->FputUint8(base);
340 // state_fio->FputUint16(cmd);
341 // state_fio->FputUint16(tmp);
342 // state_fio->FputUint8(req);
343 // state_fio->FputUint8(sreq);
344 // state_fio->FputUint8(mask);
345 // state_fio->FputUint8(tc);
348 bool UPD71071::load_state(FILEIO* state_fio)
351 if(state_entry != NULL) {
352 mb = state_entry->load_state(state_fio);
354 if(!mb) return false;
356 // if(state_fio->FgetUint32() != STATE_VERSION) {
359 // if(state_fio->FgetInt32() != this_device_id) {
362 // for(int i = 0; i < 4; i++) {
363 // dma[i].areg = state_fio->FgetUint32();
364 // dma[i].bareg = state_fio->FgetUint32();
365 // dma[i].creg = state_fio->FgetUint16();
366 // dma[i].bcreg = state_fio->FgetUint16();
367 // dma[i].mode = state_fio->FgetUint8();
369 // b16 = state_fio->FgetUint8();
370 // selch = state_fio->FgetUint8();
371 // base = state_fio->FgetUint8();
372 // cmd = state_fio->FgetUint16();
373 // tmp = state_fio->FgetUint16();
374 // req = state_fio->FgetUint8();
375 // sreq = state_fio->FgetUint8();
376 // mask = state_fio->FgetUint8();
377 // tc = state_fio->FgetUint8();