2 Skelton for retropc emulator
4 Author : Takeda.Toshiya
12 void UPD71071::initialize()
14 for(int i = 0; i < 4; i++) {
15 dma[i].areg = dma[i].bareg = 0;
16 dma[i].creg = dma[i].bcreg = 0;
20 void UPD71071::reset()
22 for(int i = 0; i < 4; i++) {
25 b16 = selch = base = 0;
31 void UPD71071::write_io8(uint32_t addr, uint32_t data)
37 for(int i = 0; i < 4; i++) {
52 dma[selch].bcreg = (dma[selch].bcreg & 0xff00) | data;
54 dma[selch].creg = (dma[selch].creg & 0xff00) | data;
58 dma[selch].bcreg = (dma[selch].bcreg & 0x00ff) | (data << 8);
60 dma[selch].creg = (dma[selch].creg & 0x00ff) | (data << 8);
64 dma[selch].bareg = (dma[selch].bareg & 0xffff00) | data;
66 dma[selch].areg = (dma[selch].areg & 0xffff00) | data;
70 dma[selch].bareg = (dma[selch].bareg & 0xff00ff) | (data << 8);
72 dma[selch].areg = (dma[selch].areg & 0xff00ff) | (data << 8);
76 dma[selch].bareg = (dma[selch].bareg & 0x00ffff) | (data << 16);
78 dma[selch].areg = (dma[selch].areg & 0x00ffff) | (data << 16);
82 cmd = (cmd & 0xff00) | data;
85 cmd = (cmd & 0xff) | (data << 8);
88 dma[selch].mode = data;
91 if((sreq = data) != 0) {
92 #ifndef SINGLE_MODE_DMA
103 uint32_t UPD71071::read_io8(uint32_t addr)
107 switch(addr & 0x0f) {
111 return (base << 2) | (1 << selch);
114 return dma[selch].bcreg & 0xff;
116 return dma[selch].creg & 0xff;
120 return (dma[selch].bcreg >> 8) & 0xff;
122 return (dma[selch].creg >> 8) & 0xff;
126 return dma[selch].bareg & 0xff;
128 return dma[selch].areg & 0xff;
132 return (dma[selch].bareg >> 8) & 0xff;
134 return (dma[selch].areg >> 8) & 0xff;
138 return (dma[selch].bareg >> 16) & 0xff;
140 return (dma[selch].areg >> 16) & 0xff;
145 return (cmd >> 8) & 0xff;
147 return dma[selch].mode;
149 val = (req << 4) | tc;
155 return (tmp >> 8) & 0xff;
164 void UPD71071::write_signal(int id, uint32_t data, uint32_t mask)
166 uint8_t bit = 1 << (id & 3);
171 #ifndef SINGLE_MODE_DMA
180 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
182 void UPD71071::do_dma()
188 // ToDo: Will check WORD transfer mode for FM-Towns.(mode.bit0 = '1).
190 for(int c = 0; c < 4; c++) {
191 uint8_t bit = 1 << c;
192 if(((req | sreq) & bit) && !(mask & bit)) {
194 while((req | sreq) & bit) {
196 if((dma[c].mode & 0x01) == 1) { // 16bit transfer mode.
197 if((dma[c].mode & 0x0c) == 4) {
199 uint32_t val = dma[c].dev->read_dma_io16(0);
200 d_mem->write_dma_data16(dma[c].areg, val);
201 // update temporary register
203 } else if((dma[c].mode & 0x0c) == 8) {
205 uint32_t val = d_mem->read_dma_data16(dma[c].areg);
206 dma[c].dev->write_dma_io16(0, val);
207 // update temporary register
210 if(dma[c].mode & 0x20) {
211 dma[c].areg = (dma[c].areg - 2) & 0xffffff;
213 dma[c].areg = (dma[c].areg + 2) & 0xffffff;
215 } else { // 8bit mode
217 if((dma[c].mode & 0x0c) == 4) {
219 uint32_t val = dma[c].dev->read_dma_io8(0);
220 d_mem->write_dma_data8(dma[c].areg, val);
221 // update temporary register
222 tmp = (tmp >> 8) | (val << 8);
223 } else if((dma[c].mode & 0x0c) == 8) {
225 uint32_t val = d_mem->read_dma_data8(dma[c].areg);
226 dma[c].dev->write_dma_io8(0, val);
227 // update temporary register
228 tmp = (tmp >> 8) | (val << 8);
230 if(dma[c].mode & 0x20) {
231 dma[c].areg = (dma[c].areg - 1) & 0xffffff;
233 dma[c].areg = (dma[c].areg + 1) & 0xffffff;
238 if(dma[c].creg-- == 0) {
240 if(dma[c].mode & 0x10) {
242 dma[c].areg = dma[c].bareg;
243 dma[c].creg = dma[c].bcreg;
251 write_signals(&outputs_tc, 0xffffffff);
252 #ifdef SINGLE_MODE_DMA
253 } else if((dma[c].mode & 0xc0) == 0x40) {
261 #ifdef SINGLE_MODE_DMA
268 #define STATE_VERSION 1
270 void UPD71071::save_state(FILEIO* state_fio)
272 state_fio->FputUint32(STATE_VERSION);
273 state_fio->FputInt32(this_device_id);
275 for(int i = 0; i < 4; i++) {
276 state_fio->FputUint32(dma[i].areg);
277 state_fio->FputUint32(dma[i].bareg);
278 state_fio->FputUint16(dma[i].creg);
279 state_fio->FputUint16(dma[i].bcreg);
280 state_fio->FputUint8(dma[i].mode);
282 state_fio->FputUint8(b16);
283 state_fio->FputUint8(selch);
284 state_fio->FputUint8(base);
285 state_fio->FputUint16(cmd);
286 state_fio->FputUint16(tmp);
287 state_fio->FputUint8(req);
288 state_fio->FputUint8(sreq);
289 state_fio->FputUint8(mask);
290 state_fio->FputUint8(tc);
293 bool UPD71071::load_state(FILEIO* state_fio)
295 if(state_fio->FgetUint32() != STATE_VERSION) {
298 if(state_fio->FgetInt32() != this_device_id) {
301 for(int i = 0; i < 4; i++) {
302 dma[i].areg = state_fio->FgetUint32();
303 dma[i].bareg = state_fio->FgetUint32();
304 dma[i].creg = state_fio->FgetUint16();
305 dma[i].bcreg = state_fio->FgetUint16();
306 dma[i].mode = state_fio->FgetUint8();
308 b16 = state_fio->FgetUint8();
309 selch = state_fio->FgetUint8();
310 base = state_fio->FgetUint8();
311 cmd = state_fio->FgetUint16();
312 tmp = state_fio->FgetUint16();
313 req = state_fio->FgetUint8();
314 sreq = state_fio->FgetUint8();
315 mask = state_fio->FgetUint8();
316 tc = state_fio->FgetUint8();