2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void UPD71071::initialize()
15 for(int i = 0; i < 4; i++) {
16 dma[i].areg = dma[i].bareg = 0;
17 dma[i].creg = dma[i].bcreg = 0;
21 void UPD71071::reset()
23 for(int i = 0; i < 4; i++) {
26 b16 = selch = base = 0;
32 void UPD71071::write_io8(uint32_t addr, uint32_t data)
38 for(int i = 0; i < 4; i++) {
53 dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data;
55 dma[selch].creg = (dma[selch].creg & 0xff00) | data;
59 dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8);
61 dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8);
65 dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data;
67 dma[selch].areg = (dma[selch].areg & 0xffff00) | data;
71 dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8);
73 dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8);
77 dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16);
79 dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16);
83 cmd = (cmd & 0xff00) | data;
86 cmd = (cmd & 0xff) | (data << 8);
89 dma[selch].mode = data;
92 if((sreq = data) != 0) {
93 #ifndef SINGLE_MODE_DMA
104 uint32_t UPD71071::read_io8(uint32_t addr)
108 switch(addr & 0x0f) {
112 return (base << 2) | (1 << selch);
115 return dma[selch].bcreg & 0xff;
117 return dma[selch].creg & 0xff;
121 return (dma[selch].bcreg >> 8) & 0xff;
123 return (dma[selch].creg >> 8) & 0xff;
127 return dma[selch].bareg & 0xff;
129 return dma[selch].areg & 0xff;
133 return (dma[selch].bareg >> 8) & 0xff;
135 return (dma[selch].areg >> 8) & 0xff;
139 return (dma[selch].bareg >> 16) & 0xff;
141 return (dma[selch].areg >> 16) & 0xff;
146 return (cmd >> 8) & 0xff;
148 return dma[selch].mode;
150 val = (req << 4) | tc;
156 return (tmp >> 8) & 0xff;
165 void UPD71071::write_signal(int id, uint32_t data, uint32_t mask)
167 uint8_t bit = 1 << (id & 3);
172 #ifndef SINGLE_MODE_DMA
181 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
183 void UPD71071::do_dma()
191 for(int c = 0; c < 4; c++) {
192 uint8_t bit = 1 << c;
193 if(((req | sreq) & bit) && !(mask & bit)) {
195 while((req | sreq) & bit) {
196 // ToDo: Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1).
198 if((dma[c].mode & 0x01) == 1) {
199 // 16bit transfer mode
200 if((dma[c].mode & 0x0c) == 4) {
202 uint32_t val = dma[c].dev->read_dma_io16(0);
203 d_mem->write_dma_data16(dma[c].areg, val);
204 // update temporary register
206 } else if((dma[c].mode & 0x0c) == 8) {
208 uint32_t val = d_mem->read_dma_data16(dma[c].areg);
209 dma[c].dev->write_dma_io16(0, val);
210 // update temporary register
213 if(dma[c].mode & 0x20) {
214 dma[c].areg = (dma[c].areg - 2) & 0xffffff;
216 dma[c].areg = (dma[c].areg + 2) & 0xffffff;
221 // 8bit transfer mode
222 if((dma[c].mode & 0x0c) == 4) {
224 uint32_t val = dma[c].dev->read_dma_io8(0);
225 d_mem->write_dma_data8(dma[c].areg, val);
226 // update temporary register
227 tmp = (tmp >> 8) | (val << 8);
228 } else if((dma[c].mode & 0x0c) == 8) {
230 uint32_t val = d_mem->read_dma_data8(dma[c].areg);
231 dma[c].dev->write_dma_io8(0, val);
232 // update temporary register
233 tmp = (tmp >> 8) | (val << 8);
235 if(dma[c].mode & 0x20) {
236 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
238 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
241 if(dma[c].creg-- == 0) {
243 if(dma[c].mode & 0x10) {
245 dma[c].areg = dma[c].bareg;
246 dma[c].creg = dma[c].bcreg;
254 write_signals(&outputs_tc, 0xffffffff);
255 #ifdef SINGLE_MODE_DMA
256 } else if((dma[c].mode & 0xc0) == 0x40) {
264 #ifdef SINGLE_MODE_DMA
271 #define STATE_VERSION 1
273 void UPD71071::save_state(FILEIO* state_fio)
275 state_fio->FputUint32(STATE_VERSION);
276 state_fio->FputInt32(this_device_id);
278 for(int i = 0; i < 4; i++) {
279 state_fio->FputUint32(dma[i].areg);
280 state_fio->FputUint32(dma[i].bareg);
281 state_fio->FputUint16(dma[i].creg);
282 state_fio->FputUint16(dma[i].bcreg);
283 state_fio->FputUint8(dma[i].mode);
285 state_fio->FputUint8(b16);
286 state_fio->FputUint8(selch);
287 state_fio->FputUint8(base);
288 state_fio->FputUint16(cmd);
289 state_fio->FputUint16(tmp);
290 state_fio->FputUint8(req);
291 state_fio->FputUint8(sreq);
292 state_fio->FputUint8(mask);
293 state_fio->FputUint8(tc);
296 bool UPD71071::load_state(FILEIO* state_fio)
298 if(state_fio->FgetUint32() != STATE_VERSION) {
301 if(state_fio->FgetInt32() != this_device_id) {
304 for(int i = 0; i < 4; i++) {
305 dma[i].areg = state_fio->FgetUint32();
306 dma[i].bareg = state_fio->FgetUint32();
307 dma[i].creg = state_fio->FgetUint16();
308 dma[i].bcreg = state_fio->FgetUint16();
309 dma[i].mode = state_fio->FgetUint8();
311 b16 = state_fio->FgetUint8();
312 selch = state_fio->FgetUint8();
313 base = state_fio->FgetUint8();
314 cmd = state_fio->FgetUint16();
315 tmp = state_fio->FgetUint16();
316 req = state_fio->FgetUint8();
317 sreq = state_fio->FgetUint8();
318 mask = state_fio->FgetUint8();
319 tc = state_fio->FgetUint8();