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) == 4) {
205 if(dma[c].dev != NULL) {
206 val = dma[c].dev->read_dma_io16(0);
210 d_mem->write_dma_data16(dma[c].areg, val);
211 // update temporary register
213 } else if((dma[c].mode & 0x0c) == 8) {
215 uint32_t val = d_mem->read_dma_data16(dma[c].areg);
216 if(dma[c].dev != NULL) dma[c].dev->write_dma_io16(0, val);
217 // update temporary register
220 if(dma[c].mode & 0x20) {
221 dma[c].areg = (dma[c].areg - 2) & 0xffffff;
223 dma[c].areg = (dma[c].areg + 2) & 0xffffff;
228 // 8bit transfer mode
229 if((dma[c].mode & 0x0c) == 4) {
232 val = dma[c].dev->read_dma_io8(0);
233 d_mem->write_dma_data8(dma[c].areg, val);
234 // update temporary register
235 tmp = (tmp >> 8) | (val << 8);
236 } else if((dma[c].mode & 0x0c) == 8) {
238 uint32_t val = d_mem->read_dma_data8(dma[c].areg);
239 dma[c].dev->write_dma_io8(0, val);
240 // update temporary register
241 tmp = (tmp >> 8) | (val << 8);
243 if(dma[c].mode & 0x20) {
244 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
246 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
249 if(dma[c].creg-- == 0) {
251 if(dma[c].mode & 0x10) {
253 dma[c].areg = dma[c].bareg;
254 dma[c].creg = dma[c].bcreg;
262 write_signals(&outputs_tc, 0xffffffff);
263 //#ifdef SINGLE_MODE_DMA
264 } else if(_SINGLE_MODE_DMA) {
265 if((dma[c].mode & 0xc0) == 0x40) {
274 //#ifdef SINGLE_MODE_DMA
275 if(_SINGLE_MODE_DMA) {
283 #define STATE_VERSION 1
285 void UPD71071::save_state(FILEIO* state_fio)
287 state_fio->FputUint32(STATE_VERSION);
288 state_fio->FputInt32(this_device_id);
290 for(int i = 0; i < 4; i++) {
291 state_fio->FputUint32(dma[i].areg);
292 state_fio->FputUint32(dma[i].bareg);
293 state_fio->FputUint16(dma[i].creg);
294 state_fio->FputUint16(dma[i].bcreg);
295 state_fio->FputUint8(dma[i].mode);
297 state_fio->FputUint8(b16);
298 state_fio->FputUint8(selch);
299 state_fio->FputUint8(base);
300 state_fio->FputUint16(cmd);
301 state_fio->FputUint16(tmp);
302 state_fio->FputUint8(req);
303 state_fio->FputUint8(sreq);
304 state_fio->FputUint8(mask);
305 state_fio->FputUint8(tc);
308 bool UPD71071::load_state(FILEIO* state_fio)
310 if(state_fio->FgetUint32() != STATE_VERSION) {
313 if(state_fio->FgetInt32() != this_device_id) {
316 for(int i = 0; i < 4; i++) {
317 dma[i].areg = state_fio->FgetUint32();
318 dma[i].bareg = state_fio->FgetUint32();
319 dma[i].creg = state_fio->FgetUint16();
320 dma[i].bcreg = state_fio->FgetUint16();
321 dma[i].mode = state_fio->FgetUint8();
323 b16 = state_fio->FgetUint8();
324 selch = state_fio->FgetUint8();
325 base = state_fio->FgetUint8();
326 cmd = state_fio->FgetUint16();
327 tmp = state_fio->FgetUint16();
328 req = state_fio->FgetUint8();
329 sreq = state_fio->FgetUint8();
330 mask = state_fio->FgetUint8();
331 tc = state_fio->FgetUint8();