trunk/src/mess/drivers/x68k.c
| r26768 | r26769 | |
| 140 | 140 | |
| 141 | 141 | |
| 142 | 142 | |
| 143 | | //emu_timer* mfp_timer[4]; |
| 144 | | //emu_timer* mfp_irq; |
| 145 | | |
| 146 | | // MFP is clocked at 4MHz, so at /4 prescaler the timer is triggered after 1us (4 cycles) |
| 147 | | // No longer necessary with the new MFP core |
| 148 | | #ifdef UNUSED_FUNCTION |
| 149 | | attotime x68k_state::prescale(int val) |
| 150 | | { |
| 151 | | switch(val) |
| 152 | | { |
| 153 | | case 0: return attotime::from_nsec(0); |
| 154 | | case 1: return attotime::from_nsec(1000); |
| 155 | | case 2: return attotime::from_nsec(2500); |
| 156 | | case 3: return attotime::from_nsec(4000); |
| 157 | | case 4: return attotime::from_nsec(12500); |
| 158 | | case 5: return attotime::from_nsec(16000); |
| 159 | | case 6: return attotime::from_nsec(25000); |
| 160 | | case 7: return attotime::from_nsec(50000); |
| 161 | | default: |
| 162 | | fatalerror("out of range\n"); |
| 163 | | } |
| 164 | | } |
| 165 | | #endif |
| 166 | | |
| 167 | 143 | void x68k_state::mfp_init() |
| 168 | 144 | { |
| 169 | 145 | m_mfp.tadr = m_mfp.tbdr = m_mfp.tcdr = m_mfp.tddr = 0xff; |
| 170 | 146 | |
| 171 | 147 | m_mfp.irqline = 6; // MFP is connected to 68000 IRQ line 6 |
| 172 | 148 | m_mfp.current_irq = -1; // No current interrupt |
| 173 | | |
| 174 | | #if 0 |
| 175 | | mfp_timer[0] = timer_alloc(TIMER_MFP_TIMER_A); |
| 176 | | mfp_timer[1] = timer_alloc(TIMER_MFP_TIMER_B); |
| 177 | | mfp_timer[2] = timer_alloc(TIMER_MFP_TIMER_C); |
| 178 | | mfp_timer[3] = timer_alloc(TIMER_MFP_TIMER_D); |
| 179 | | mfp_irq = timer_alloc(TIMER_MFP_UPDATE_IRQ); |
| 180 | | mfp_irq->adjust(attotime::zero, 0, attotime::from_usec(32)); |
| 181 | | #endif |
| 182 | 149 | } |
| 183 | 150 | |
| 184 | 151 | void x68k_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 185 | 152 | { |
| 186 | 153 | switch (id) |
| 187 | 154 | { |
| 188 | | case TIMER_MFP_UPDATE_IRQ: |
| 189 | | //mfp_update_irq(ptr, param); |
| 190 | | break; |
| 191 | | case TIMER_MFP_TIMER_A: |
| 192 | | //mfp_timer_a_callback(ptr, param); |
| 193 | | break; |
| 194 | | case TIMER_MFP_TIMER_B: |
| 195 | | //mfp_timer_b_callback(ptr, param); |
| 196 | | break; |
| 197 | | case TIMER_MFP_TIMER_C: |
| 198 | | //mfp_timer_c_callback(ptr, param); |
| 199 | | break; |
| 200 | | case TIMER_MFP_TIMER_D: |
| 201 | | //mfp_timer_d_callback(ptr, param); |
| 202 | | break; |
| 203 | 155 | case TIMER_X68K_LED: |
| 204 | 156 | x68k_led_callback(ptr, param); |
| 205 | 157 | break; |
| r26768 | r26769 | |
| 245 | 197 | } |
| 246 | 198 | } |
| 247 | 199 | |
| 248 | | |
| 249 | | #ifdef UNUSED_FUNCTION |
| 250 | | TIMER_CALLBACK_MEMBER(x68k_state::mfp_update_irq) |
| 251 | | { |
| 252 | | int x; |
| 253 | | |
| 254 | | if((m_ioc.irqstatus & 0xc0) != 0) |
| 255 | | return; |
| 256 | | |
| 257 | | // check for pending IRQs, in priority order |
| 258 | | if(m_mfp.ipra != 0) |
| 259 | | { |
| 260 | | for(x=7;x>=0;x--) |
| 261 | | { |
| 262 | | if((m_mfp.ipra & (1 << x)) && (m_mfp.imra & (1 << x))) |
| 263 | | { |
| 264 | | m_current_irq_line = m_mfp.irqline; |
| 265 | | m_mfp.current_irq = x + 8; |
| 266 | | // assert IRQ line |
| 267 | | // if(m_mfp.iera & (1 << x)) |
| 268 | | { |
| 269 | | m_current_vector[6] = (m_mfp.vr & 0xf0) | (x+8); |
| 270 | | m_maincpu->set_input_line_and_vector(m_mfp.irqline,ASSERT_LINE,(m_mfp.vr & 0xf0) | (x + 8)); |
| 271 | | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(m_mfp.vr & 0xf0) | (x+8),m_mfp.irqline); |
| 272 | | return; // one at a time only |
| 273 | | } |
| 274 | | } |
| 275 | | } |
| 276 | | } |
| 277 | | if(m_mfp.iprb != 0) |
| 278 | | { |
| 279 | | for(x=7;x>=0;x--) |
| 280 | | { |
| 281 | | if((m_mfp.iprb & (1 << x)) && (m_mfp.imrb & (1 << x))) |
| 282 | | { |
| 283 | | m_current_irq_line = m_mfp.irqline; |
| 284 | | m_mfp.current_irq = x; |
| 285 | | // assert IRQ line |
| 286 | | // if(m_mfp.ierb & (1 << x)) |
| 287 | | { |
| 288 | | m_current_vector[6] = (m_mfp.vr & 0xf0) | x; |
| 289 | | m_maincpu->set_input_line_and_vector(m_mfp.irqline,ASSERT_LINE,(m_mfp.vr & 0xf0) | x); |
| 290 | | // logerror("MFP: Sent IRQ vector 0x%02x (IRQ line %i)\n",(m_mfp.vr & 0xf0) | x,m_mfp.irqline); |
| 291 | | return; // one at a time only |
| 292 | | } |
| 293 | | } |
| 294 | | } |
| 295 | | } |
| 296 | | } |
| 297 | | |
| 298 | | void x68k_state::mfp_trigger_irq(int irq) |
| 299 | | { |
| 300 | | // check if interrupt is enabled |
| 301 | | if(irq > 7) |
| 302 | | { |
| 303 | | if(!(m_mfp.iera & (1 << (irq-8)))) |
| 304 | | return; // not enabled, no action taken |
| 305 | | } |
| 306 | | else |
| 307 | | { |
| 308 | | if(!(m_mfp.ierb & (1 << irq))) |
| 309 | | return; // not enabled, no action taken |
| 310 | | } |
| 311 | | |
| 312 | | // set requested IRQ as pending |
| 313 | | if(irq > 7) |
| 314 | | m_mfp.ipra |= (1 << (irq-8)); |
| 315 | | else |
| 316 | | m_mfp.iprb |= (1 << irq); |
| 317 | | |
| 318 | | // check for IRQs to be called |
| 319 | | // mfp_update_irq(0); |
| 320 | | |
| 321 | | } |
| 322 | | |
| 323 | | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_a_callback) |
| 324 | | { |
| 325 | | m_mfp.timer[0].counter--; |
| 326 | | if(m_mfp.timer[0].counter == 0) |
| 327 | | { |
| 328 | | m_mfp.timer[0].counter = m_mfp.tadr; |
| 329 | | mfp_trigger_irq(MFP_IRQ_TIMERA); |
| 330 | | } |
| 331 | | } |
| 332 | | |
| 333 | | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_b_callback) |
| 334 | | { |
| 335 | | m_mfp.timer[1].counter--; |
| 336 | | if(m_mfp.timer[1].counter == 0) |
| 337 | | { |
| 338 | | m_mfp.timer[1].counter = m_mfp.tbdr; |
| 339 | | mfp_trigger_irq(MFP_IRQ_TIMERB); |
| 340 | | } |
| 341 | | } |
| 342 | | |
| 343 | | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_c_callback) |
| 344 | | { |
| 345 | | m_mfp.timer[2].counter--; |
| 346 | | if(m_mfp.timer[2].counter == 0) |
| 347 | | { |
| 348 | | m_mfp.timer[2].counter = m_mfp.tcdr; |
| 349 | | mfp_trigger_irq(MFP_IRQ_TIMERC); |
| 350 | | } |
| 351 | | } |
| 352 | | |
| 353 | | TIMER_CALLBACK_MEMBER(x68k_state::mfp_timer_d_callback) |
| 354 | | { |
| 355 | | m_mfp.timer[3].counter--; |
| 356 | | if(m_mfp.timer[3].counter == 0) |
| 357 | | { |
| 358 | | m_mfp.timer[3].counter = m_mfp.tddr; |
| 359 | | mfp_trigger_irq(MFP_IRQ_TIMERD); |
| 360 | | } |
| 361 | | } |
| 362 | | |
| 363 | | void x68k_state::mfp_set_timer(int timer, unsigned char data) |
| 364 | | { |
| 365 | | if((data & 0x07) == 0x0000) |
| 366 | | { // Timer stop |
| 367 | | mfp_timer[timer]->adjust(attotime::zero); |
| 368 | | logerror("MFP: Timer #%i stopped. \n",timer); |
| 369 | | return; |
| 370 | | } |
| 371 | | |
| 372 | | mfp_timer[timer]->adjust(attotime::zero, 0, prescale(data & 0x07)); |
| 373 | | logerror("MFP: Timer #%i set to %2.1fus\n",timer, prescale(data & 0x07).as_double() * 1000000); |
| 374 | | |
| 375 | | } |
| 376 | | #endif |
| 377 | | |
| 378 | 200 | // LED timer callback |
| 379 | 201 | TIMER_CALLBACK_MEMBER(x68k_state::x68k_led_callback) |
| 380 | 202 | { |
| r26768 | r26769 | |
| 570 | 392 | } |
| 571 | 393 | |
| 572 | 394 | |
| 573 | | #ifdef UNUSED_FUNCTION |
| 574 | | void x68k_state::mfp_recv_data(int data) |
| 575 | | { |
| 576 | | m_mfp.rsr |= 0x80; // Buffer full |
| 577 | | m_mfp.tsr |= 0x80; |
| 578 | | m_mfp.usart.recv_buffer = 0x00; // TODO: set up keyboard data |
| 579 | | m_mfp.vector = m_current_vector[6] = (m_mfp.vr & 0xf0) | 0x0c; |
| 580 | | // mfp_trigger_irq(MFP_IRQ_RX_FULL); |
| 581 | | // logerror("MFP: Receive buffer full IRQ sent\n"); |
| 582 | | } |
| 583 | | #endif |
| 584 | | |
| 585 | 395 | // mouse input |
| 586 | 396 | // port B of the Z8530 SCC |
| 587 | 397 | // typically read from the SCC data port on receive buffer full interrupt per byte |
| r26768 | r26769 | |
| 1277 | 1087 | } |
| 1278 | 1088 | } |
| 1279 | 1089 | |
| 1280 | | #ifdef UNUSED_FUNCTION |
| 1281 | 1090 | READ16_MEMBER(x68k_state::x68k_mfp_r) |
| 1282 | 1091 | { |
| 1283 | | device_t *x68k_mfp = machine().device(MC68901_TAG); |
| 1284 | | |
| 1285 | | return mc68901_register_r(x68k_mfp, offset); |
| 1286 | | } |
| 1287 | | #endif |
| 1288 | | |
| 1289 | | READ16_MEMBER(x68k_state::x68k_mfp_r) |
| 1290 | | { |
| 1291 | 1092 | // Initial settings indicate that IRQs are generated for FM (YM2151), Receive buffer error or full, |
| 1292 | 1093 | // MFP Timer C, and the power switch |
| 1293 | 1094 | // logerror("MFP: [%08x] Reading offset %i\n",space.device().safe_pc(),offset); |
| 1294 | 1095 | switch(offset) |
| 1295 | 1096 | { |
| 1296 | | #if 0 |
| 1297 | | case 0x00: // GPIP - General purpose I/O register (read-only) |
| 1298 | | ret = 0x23; |
| 1299 | | if(machine.primary_screen->vpos() == m_crtc.reg[9]) |
| 1300 | | ret |= 0x40; |
| 1301 | | if(m_crtc.vblank == 0) |
| 1302 | | ret |= 0x10; // Vsync signal (low if in vertical retrace) |
| 1303 | | // if(m_mfp.isrb & 0x08) |
| 1304 | | // ret |= 0x08; // FM IRQ signal |
| 1305 | | if(machine.primary_screen->hpos() > m_crtc.width - 32) |
| 1306 | | ret |= 0x80; // Hsync signal |
| 1307 | | // logerror("MFP: [%08x] Reading offset %i (ret=%02x)\n",space.device().safe_pc(),offset,ret); |
| 1308 | | return ret; // bit 5 is always 1 |
| 1309 | | case 3: |
| 1310 | | return m_mfp.iera; |
| 1311 | | case 4: |
| 1312 | | return m_mfp.ierb; |
| 1313 | | case 5: |
| 1314 | | return m_mfp.ipra; |
| 1315 | | case 6: |
| 1316 | | return m_mfp.iprb; |
| 1317 | | case 7: |
| 1318 | | if(m_mfp.eoi_mode == 0) // forced low in auto EOI mode |
| 1319 | | return 0; |
| 1320 | | else |
| 1321 | | return m_mfp.isra; |
| 1322 | | case 8: |
| 1323 | | if(m_mfp.eoi_mode == 0) // forced low in auto EOI mode |
| 1324 | | return 0; |
| 1325 | | else |
| 1326 | | return m_mfp.isrb; |
| 1327 | | case 9: |
| 1328 | | return m_mfp.imra; |
| 1329 | | case 10: |
| 1330 | | return m_mfp.imrb; |
| 1331 | | case 15: // TADR |
| 1332 | | return m_mfp.timer[0].counter; // Timer data registers return their main counter values |
| 1333 | | case 16: // TBDR |
| 1334 | | return m_mfp.timer[1].counter; |
| 1335 | | case 17: // TCDR |
| 1336 | | return m_mfp.timer[2].counter; |
| 1337 | | case 18: // TDDR |
| 1338 | | return m_mfp.timer[3].counter; |
| 1339 | | #endif |
| 1340 | 1097 | case 21: // RSR |
| 1341 | 1098 | return m_mfp.rsr; |
| 1342 | 1099 | case 22: // TSR |
| r26768 | r26769 | |
| 1371 | 1128 | */ |
| 1372 | 1129 | switch(offset) |
| 1373 | 1130 | { |
| 1374 | | #if 0 |
| 1375 | | case 0: // GPDR |
| 1376 | | // All bits are inputs generally, so no action taken. |
| 1377 | | break; |
| 1378 | | case 1: // AER |
| 1379 | | m_mfp.aer = data; |
| 1380 | | break; |
| 1381 | | case 2: // DDR |
| 1382 | | m_mfp.ddr = data; // usually all bits are 0 (input) |
| 1383 | | break; |
| 1384 | | case 3: // IERA |
| 1385 | | m_mfp.iera = data; |
| 1386 | | break; |
| 1387 | | case 4: // IERB |
| 1388 | | m_mfp.ierb = data; |
| 1389 | | break; |
| 1390 | | case 5: // IPRA |
| 1391 | | m_mfp.ipra = data; |
| 1392 | | break; |
| 1393 | | case 6: // IPRB |
| 1394 | | m_mfp.iprb = data; |
| 1395 | | break; |
| 1396 | | case 7: |
| 1397 | | m_mfp.isra = data; |
| 1398 | | break; |
| 1399 | | case 8: |
| 1400 | | m_mfp.isrb = data; |
| 1401 | | break; |
| 1402 | | case 9: |
| 1403 | | m_mfp.imra = data; |
| 1404 | | // mfp_update_irq(0); |
| 1405 | | // logerror("MFP: IRQ Mask A write: %02x\n",data); |
| 1406 | | break; |
| 1407 | | case 10: |
| 1408 | | m_mfp.imrb = data; |
| 1409 | | // mfp_update_irq(0); |
| 1410 | | // logerror("MFP: IRQ Mask B write: %02x\n",data); |
| 1411 | | break; |
| 1412 | | case 11: // VR |
| 1413 | | m_mfp.vr = 0x40;//data; // High 4 bits = high 4 bits of IRQ vector |
| 1414 | | m_mfp.eoi_mode = data & 0x08; // 0 = Auto, 1 = Software End-of-interrupt |
| 1415 | | if(m_mfp.eoi_mode == 0) // In-service registers are cleared if this bit is cleared. |
| 1416 | | { |
| 1417 | | m_mfp.isra = 0; |
| 1418 | | m_mfp.isrb = 0; |
| 1419 | | } |
| 1420 | | break; |
| 1421 | | case 12: // TACR |
| 1422 | | m_mfp.tacr = data; |
| 1423 | | mfp_set_timer(0,data & 0x0f); |
| 1424 | | break; |
| 1425 | | case 13: // TBCR |
| 1426 | | m_mfp.tbcr = data; |
| 1427 | | mfp_set_timer(1,data & 0x0f); |
| 1428 | | break; |
| 1429 | | case 14: // TCDCR |
| 1430 | | m_mfp.tcdcr = data; |
| 1431 | | mfp_set_timer(2,(data & 0x70)>>4); |
| 1432 | | mfp_set_timer(3,data & 0x07); |
| 1433 | | break; |
| 1434 | | case 15: // TADR |
| 1435 | | m_mfp.tadr = data; |
| 1436 | | m_mfp.timer[0].counter = data; |
| 1437 | | break; |
| 1438 | | case 16: // TBDR |
| 1439 | | m_mfp.tbdr = data; |
| 1440 | | m_mfp.timer[1].counter = data; |
| 1441 | | break; |
| 1442 | | case 17: // TCDR |
| 1443 | | m_mfp.tcdr = data; |
| 1444 | | m_mfp.timer[2].counter = data; |
| 1445 | | break; |
| 1446 | | case 18: // TDDR |
| 1447 | | m_mfp.tddr = data; |
| 1448 | | m_mfp.timer[3].counter = data; |
| 1449 | | break; |
| 1450 | | case 20: |
| 1451 | | m_mfp.ucr = data; |
| 1452 | | break; |
| 1453 | | #endif |
| 1454 | 1131 | case 21: |
| 1455 | 1132 | if(data & 0x01) |
| 1456 | 1133 | m_mfp.usart.recv_enable = 1; |
| r26768 | r26769 | |
| 1509 | 1186 | { |
| 1510 | 1187 | m_mfp.gpio |= 0x01; |
| 1511 | 1188 | m_mfpdev->i0_w(1); |
| 1512 | | //mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1513 | 1189 | } |
| 1514 | 1190 | } |
| 1515 | 1191 | else |
| r26768 | r26769 | |
| 1518 | 1194 | { |
| 1519 | 1195 | m_mfp.gpio &= ~0x01; |
| 1520 | 1196 | m_mfpdev->i0_w(0); |
| 1521 | | //mfp_trigger_irq(MFP_IRQ_GPIP0); // RTC ALARM |
| 1522 | 1197 | } |
| 1523 | 1198 | } |
| 1524 | 1199 | } |
| r26768 | r26769 | |
| 1539 | 1214 | // return 0x0000; |
| 1540 | 1215 | if(offset == 0x08/2) |
| 1541 | 1216 | return m_ram->size() >> 16; // RAM size |
| 1542 | | #if 0 |
| 1543 | | if(offset == 0x46/2) |
| 1544 | | return 0x0024; |
| 1545 | | if(offset == 0x6e/2) |
| 1546 | | return 0xff00; |
| 1547 | | if(offset == 0x70/2) |
| 1548 | | return 0x0700; |
| 1549 | | #endif |
| 1550 | 1217 | return m_nvram16[offset]; |
| 1551 | 1218 | } |
| 1552 | 1219 | |
| r26768 | r26769 | |
| 1554 | 1221 | { |
| 1555 | 1222 | if(offset == 0x08/4) |
| 1556 | 1223 | return (m_ram->size() & 0xffff0000); // RAM size |
| 1557 | | #if 0 |
| 1558 | | if(offset == 0x46/2) |
| 1559 | | return 0x0024; |
| 1560 | | if(offset == 0x6e/2) |
| 1561 | | return 0xff00; |
| 1562 | | if(offset == 0x70/2) |
| 1563 | | return 0x0700; |
| 1564 | | #endif |
| 1565 | 1224 | return m_nvram32[offset]; |
| 1566 | 1225 | } |
| 1567 | 1226 | |
| r26768 | r26769 | |
| 1840 | 1499 | data &= ~(m_crtc.vblank << 4); |
| 1841 | 1500 | data |= 0x23; // GPIP5 is unused, always 1 |
| 1842 | 1501 | |
| 1843 | | // m_mfpdev->tai_w(state->m_crtc.vblank); |
| 1844 | | |
| 1845 | 1502 | return data; |
| 1846 | 1503 | } |
| 1847 | 1504 | |
| r26768 | r26769 | |
| 1871 | 1528 | m_mfp_prev = state; |
| 1872 | 1529 | } |
| 1873 | 1530 | |
| 1874 | | INTERRUPT_GEN_MEMBER(x68k_state::x68k_vsync_irq) |
| 1875 | | { |
| 1876 | | #if 0 |
| 1877 | | x68k_state *state = machine.driver_data<x68k_state>(); |
| 1878 | | if(m_mfp.ierb & 0x40) |
| 1879 | | { |
| 1880 | | m_mfp.isrb |= 0x40; |
| 1881 | | m_current_vector[6] = (m_mfp.vr & 0xf0) | 0x06; // GPIP4 (V-DISP) |
| 1882 | | m_current_irq_line = 6; |
| 1883 | | mfp_timer_a_callback(0); // Timer A is usually always in event count mode, and is tied to V-DISP |
| 1884 | | mfp_trigger_irq(MFP_IRQ_GPIP4); |
| 1885 | | } |
| 1886 | | if(m_crtc.height == 256) |
| 1887 | | machine.primary_screen->update_partial(256);//m_crtc.reg[4]/2); |
| 1888 | | else |
| 1889 | | machine.primary_screen->update_partial(512);//m_crtc.reg[4]); |
| 1890 | | #endif |
| 1891 | | } |
| 1892 | | |
| 1893 | 1531 | IRQ_CALLBACK_MEMBER(x68k_state::x68k_int_ack) |
| 1894 | 1532 | { |
| 1895 | 1533 | if(irqline == 6) // MFP |
| r26768 | r26769 | |
| 2701 | 2339 | /* basic machine hardware */ |
| 2702 | 2340 | MCFG_CPU_ADD("maincpu", M68000, 10000000) /* 10 MHz */ |
| 2703 | 2341 | MCFG_CPU_PROGRAM_MAP(x68k_map) |
| 2704 | | MCFG_CPU_VBLANK_INT_DRIVER("screen", x68k_state, x68k_vsync_irq) |
| 2705 | 2342 | MCFG_QUANTUM_TIME(attotime::from_hz(60)) |
| 2706 | 2343 | |
| 2707 | 2344 | MCFG_MACHINE_START_OVERRIDE(x68k_state, x68000 ) |
trunk/src/mess/includes/x68k.h
| r26768 | r26769 | |
| 46 | 46 | public: |
| 47 | 47 | enum |
| 48 | 48 | { |
| 49 | | TIMER_MFP_UPDATE_IRQ, |
| 50 | | TIMER_MFP_TIMER_A, |
| 51 | | TIMER_MFP_TIMER_B, |
| 52 | | TIMER_MFP_TIMER_C, |
| 53 | | TIMER_MFP_TIMER_D, |
| 54 | 49 | TIMER_X68K_LED, |
| 55 | 50 | TIMER_X68K_KEYBOARD_POLL, |
| 56 | 51 | TIMER_X68K_SCC_ACK, |
| r26768 | r26769 | |
| 136 | 131 | } m_adpcm; |
| 137 | 132 | struct |
| 138 | 133 | { |
| 139 | | int gpdr; // [0] GPIP data register. Typically all inputs. |
| 140 | 134 | int aer; // [1] GPIP active edge register. Determines on which transition an IRQ is triggered. 0 = 1->0 |
| 141 | | int ddr; // [2] GPIP data direction register. Determines which GPIP bits are inputs (0) or outputs (1) |
| 142 | | int iera; // [3] Interrupt enable register A. |
| 143 | | int ierb; // [4] Interrupt enable register B. |
| 144 | | int ipra; // [5] Interrupt pending register A. |
| 145 | | int iprb; // [6] Interrupt pending register B. |
| 146 | | int isra; // [7] Interrupt in-service register A. |
| 147 | | int isrb; // [8] Interrupt in-service register B. |
| 148 | | int imra; // [9] Interrupt mask register A. |
| 149 | | int imrb; // [10] Interrupt mask register B. |
| 150 | | int vr; // [11] Vector register |
| 151 | | int tacr; // [12] Timer A control register |
| 152 | | int tbcr; // [13] Timer B control register |
| 153 | | int tcdcr; // [14] Timer C & D control register |
| 154 | 135 | int tadr; // [15] Timer A data register |
| 155 | 136 | int tbdr; // [16] Timer B data register |
| 156 | 137 | int tcdr; // [17] Timer C data register |
| 157 | 138 | int tddr; // [18] Timer D data register |
| 158 | | int scr; // [19] Synchronous character register |
| 159 | | int ucr; // [20] USART control register |
| 160 | 139 | int rsr; // [21] Receiver status register |
| 161 | 140 | int tsr; // [22] Transmitter status register |
| 162 | | int udr; // [23] USART data register |
| 163 | 141 | struct |
| 164 | 142 | { |
| 165 | | int counter; |
| 166 | | int prescaler; |
| 167 | | } timer[4]; |
| 168 | | struct |
| 169 | | { |
| 170 | 143 | unsigned char recv_buffer; |
| 171 | 144 | unsigned char send_buffer; |
| 172 | 145 | int recv_enable; |
| 173 | 146 | int send_enable; |
| 174 | 147 | } usart; |
| 175 | | int vector; |
| 176 | 148 | int irqline; |
| 177 | | int eoi_mode; |
| 178 | 149 | int current_irq; |
| 179 | 150 | unsigned char gpio; |
| 180 | 151 | } m_mfp; // MC68901 Multifunction Peripheral (4MHz) |
| r26768 | r26769 | |
| 303 | 274 | DECLARE_VIDEO_START(x68000); |
| 304 | 275 | DECLARE_PALETTE_INIT(x68000); |
| 305 | 276 | UINT32 screen_update_x68000(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 306 | | INTERRUPT_GEN_MEMBER(x68k_vsync_irq); |
| 307 | 277 | TIMER_CALLBACK_MEMBER(mfp_update_irq); |
| 308 | 278 | TIMER_CALLBACK_MEMBER(mfp_timer_a_callback); |
| 309 | 279 | TIMER_CALLBACK_MEMBER(mfp_timer_b_callback); |