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 bool UPD71071::process_state(FILEIO* state_fio, bool loading)
297 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
300 if(!state_fio->StateCheckInt32(this_device_id)) {
303 for(int i = 0; i < 4; i++) {
304 state_fio->StateValue(dma[i].areg);
305 state_fio->StateValue(dma[i].bareg);
306 state_fio->StateValue(dma[i].creg);
307 state_fio->StateValue(dma[i].bcreg);
308 state_fio->StateValue(dma[i].mode);
310 state_fio->StateValue(b16);
311 state_fio->StateValue(selch);
312 state_fio->StateValue(base);
313 state_fio->StateValue(cmd);
314 state_fio->StateValue(tmp);
315 state_fio->StateValue(req);
316 state_fio->StateValue(sreq);
317 state_fio->StateValue(mask);
318 state_fio->StateValue(tc);