2 Skelton for retropc emulator
5 Author : Takeda.Toshiya
20 void I8237::write_io8(uint32_t addr, uint32_t data)
22 int ch = (addr >> 1) & 3;
23 uint8_t bit = 1 << (data & 3);
26 case 0x00: case 0x02: case 0x04: case 0x06:
28 dma[ch].bareg = (dma[ch].bareg & 0xff) | (data << 8);
30 dma[ch].bareg = (dma[ch].bareg & 0xff00) | data;
32 dma[ch].areg = dma[ch].bareg;
35 case 0x01: case 0x03: case 0x05: case 0x07:
37 dma[ch].bcreg = (dma[ch].bcreg & 0xff) | (data << 8);
39 dma[ch].bcreg = (dma[ch].bcreg & 0xff00) | data;
41 dma[ch].creg = dma[ch].bcreg;
53 #ifndef SINGLE_MODE_DMA
62 // single mask register
71 dma[data & 3].mode = data;
81 // clear mask register
91 uint32_t I8237::read_io8(uint32_t addr)
93 int ch = (addr >> 1) & 3;
97 case 0x00: case 0x02: case 0x04: case 0x06:
99 val = dma[ch].areg >> 8;
101 val = dma[ch].areg & 0xff;
103 low_high = !low_high;
105 case 0x01: case 0x03: case 0x05: case 0x07:
107 val = dma[ch].creg >> 8;
109 val = dma[ch].creg & 0xff;
111 low_high = !low_high;
115 val = (req << 4) | tc;
119 // temporary register
125 void I8237::write_signal(int id, uint32_t data, uint32_t mask)
127 if(SIG_I8237_CH0 <= id && id <= SIG_I8237_CH3) {
128 uint8_t bit = 1 << (id & 3);
131 write_signals(&dma[id & 3].outputs_tc, 0);
133 #ifndef SINGLE_MODE_DMA
140 } else if(SIG_I8237_BANK0 <= id && id <= SIG_I8237_BANK3) {
141 // external bank registers
142 dma[id & 3].bankreg = data & mask;
143 } else if(SIG_I8237_MASK0 <= id && id <= SIG_I8237_MASK3) {
144 // external bank registers
145 dma[id & 3].incmask = data & mask;
149 // note: if SINGLE_MODE_DMA is defined, do_dma() is called in every machine cycle
153 for(int ch = 0; ch < 4; ch++) {
154 uint8_t bit = 1 << ch;
155 if((req & bit) && !(mask & bit)) {
158 if((dma[ch].mode & 0x0c) == 0) {
160 } else if((dma[ch].mode & 0x0c) == 4) {
163 write_mem(dma[ch].areg | (dma[ch].bankreg << 16), tmp);
164 } else if((dma[ch].mode & 0x0c) == 8) {
166 tmp = read_mem(dma[ch].areg | (dma[ch].bankreg << 16));
169 if(dma[ch].mode & 0x20) {
171 if(dma[ch].areg == 0xffff) {
172 dma[ch].bankreg = (dma[ch].bankreg & ~dma[ch].incmask) | ((dma[ch].bankreg - 1) & dma[ch].incmask);
176 if(dma[ch].areg == 0) {
177 dma[ch].bankreg = (dma[ch].bankreg & ~dma[ch].incmask) | ((dma[ch].bankreg + 1) & dma[ch].incmask);
181 // check dma condition
182 if(dma[ch].creg-- == 0) {
184 if(dma[ch].mode & 0x10) {
186 dma[ch].areg = dma[ch].bareg;
187 dma[ch].creg = dma[ch].bcreg;
193 write_signals(&dma[ch].outputs_tc, 0xffffffff);
194 #ifdef SINGLE_MODE_DMA
195 } else if((dma[ch].mode & 0xc0) == 0x40) {
203 #ifdef SINGLE_MODE_DMA
210 void I8237::write_mem(uint32_t addr, uint32_t data)
213 d_mem->write_dma_data16(addr << 1, data);
215 d_mem->write_dma_data8(addr, data);
219 uint32_t I8237::read_mem(uint32_t addr)
222 return d_mem->read_dma_data16(addr << 1);
224 return d_mem->read_dma_data8(addr);
228 void I8237::write_io(int ch, uint32_t data)
231 dma[ch].dev->write_dma_io16(0, data);
233 dma[ch].dev->write_dma_io8(0, data);
237 uint32_t I8237::read_io(int ch)
240 return dma[ch].dev->read_dma_io16(0);
242 return dma[ch].dev->read_dma_io8(0);
246 #define STATE_VERSION 1
248 void I8237::save_state(FILEIO* state_fio)
250 state_fio->FputUint32(STATE_VERSION);
251 state_fio->FputInt32(this_device_id);
253 for(int i = 0; i < 4; i++) {
254 state_fio->FputUint16(dma[i].areg);
255 state_fio->FputUint16(dma[i].creg);
256 state_fio->FputUint16(dma[i].bareg);
257 state_fio->FputUint16(dma[i].bcreg);
258 state_fio->FputUint8(dma[i].mode);
259 state_fio->FputUint16(dma[i].bankreg);
260 state_fio->FputUint16(dma[i].incmask);
262 state_fio->FputBool(low_high);
263 state_fio->FputUint8(cmd);
264 state_fio->FputUint8(req);
265 state_fio->FputUint8(mask);
266 state_fio->FputUint8(tc);
267 state_fio->FputUint32(tmp);
268 state_fio->FputBool(mode_word);
271 bool I8237::load_state(FILEIO* state_fio)
273 if(state_fio->FgetUint32() != STATE_VERSION) {
276 if(state_fio->FgetInt32() != this_device_id) {
279 for(int i = 0; i < 4; i++) {
280 dma[i].areg = state_fio->FgetUint16();
281 dma[i].creg = state_fio->FgetUint16();
282 dma[i].bareg = state_fio->FgetUint16();
283 dma[i].bcreg = state_fio->FgetUint16();
284 dma[i].mode = state_fio->FgetUint8();
285 dma[i].bankreg = state_fio->FgetUint16();
286 dma[i].incmask = state_fio->FgetUint16();
288 low_high = state_fio->FgetBool();
289 cmd = state_fio->FgetUint8();
290 req = state_fio->FgetUint8();
291 mask = state_fio->FgetUint8();
292 tc = state_fio->FgetUint8();
293 tmp = state_fio->FgetUint32();
294 mode_word = state_fio->FgetBool();