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 if(dma[c].dev != NULL) {
233 val = dma[c].dev->read_dma_io8(0);
237 d_mem->write_dma_data8(dma[c].areg, val);
238 // update temporary register
239 tmp = (tmp >> 8) | (val << 8);
240 } else if((dma[c].mode & 0x0c) == 8) {
242 uint32_t val = d_mem->read_dma_data8(dma[c].areg);
243 if(dma[c].dev != NULL) {
244 dma[c].dev->write_dma_io8(0, val);
246 // update temporary register
247 tmp = (tmp >> 8) | (val << 8);
249 if(dma[c].mode & 0x20) {
250 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
252 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
255 if(dma[c].creg-- == 0) {
257 if(dma[c].mode & 0x10) {
259 dma[c].areg = dma[c].bareg;
260 dma[c].creg = dma[c].bcreg;
268 write_signals(&outputs_tc, 0xffffffff);
269 //#ifdef SINGLE_MODE_DMA
270 } else if(_SINGLE_MODE_DMA) {
271 if((dma[c].mode & 0xc0) == 0x40) {
280 //#ifdef SINGLE_MODE_DMA
281 if(_SINGLE_MODE_DMA) {
289 #define STATE_VERSION 1
291 void UPD71071::save_state(FILEIO* state_fio)
293 state_fio->FputUint32(STATE_VERSION);
294 state_fio->FputInt32(this_device_id);
296 for(int i = 0; i < 4; i++) {
297 state_fio->FputUint32(dma[i].areg);
298 state_fio->FputUint32(dma[i].bareg);
299 state_fio->FputUint16(dma[i].creg);
300 state_fio->FputUint16(dma[i].bcreg);
301 state_fio->FputUint8(dma[i].mode);
303 state_fio->FputUint8(b16);
304 state_fio->FputUint8(selch);
305 state_fio->FputUint8(base);
306 state_fio->FputUint16(cmd);
307 state_fio->FputUint16(tmp);
308 state_fio->FputUint8(req);
309 state_fio->FputUint8(sreq);
310 state_fio->FputUint8(mask);
311 state_fio->FputUint8(tc);
314 bool UPD71071::load_state(FILEIO* state_fio)
316 if(state_fio->FgetUint32() != STATE_VERSION) {
319 if(state_fio->FgetInt32() != this_device_id) {
322 for(int i = 0; i < 4; i++) {
323 dma[i].areg = state_fio->FgetUint32();
324 dma[i].bareg = state_fio->FgetUint32();
325 dma[i].creg = state_fio->FgetUint16();
326 dma[i].bcreg = state_fio->FgetUint16();
327 dma[i].mode = state_fio->FgetUint8();
329 b16 = state_fio->FgetUint8();
330 selch = state_fio->FgetUint8();
331 base = state_fio->FgetUint8();
332 cmd = state_fio->FgetUint16();
333 tmp = state_fio->FgetUint16();
334 req = state_fio->FgetUint8();
335 sreq = state_fio->FgetUint8();
336 mask = state_fio->FgetUint8();
337 tc = state_fio->FgetUint8();