trunk/src/emu/cpu/tms7000/tms7000.c
| r29472 | r29473 | |
| 57 | 57 | |
| 58 | 58 | |
| 59 | 59 | static ADDRESS_MAP_START(tms7000_mem, AS_PROGRAM, 8, tms7000_device ) |
| 60 | | AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */ |
| 61 | | AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */ |
| 62 | | AM_RANGE(0x0100, 0x01ff) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */ |
| 60 | AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w) /* tms7000 internal RAM */ |
| 61 | AM_RANGE(0x0080, 0x00ff) AM_NOP /* reserved */ |
| 62 | AM_RANGE(0x0100, 0x01ff) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w) /* tms7000 internal I/O ports */ |
| 63 | 63 | ADDRESS_MAP_END |
| 64 | 64 | |
| 65 | 65 | |
| r29472 | r29473 | |
| 133 | 133 | return result | RM((mAddr+1)&0xffff); |
| 134 | 134 | } |
| 135 | 135 | |
| 136 | | UINT16 tms7000_device::RRF16( UINT32 mAddr ) /*Read register file (16 bit) */ |
| 136 | UINT16 tms7000_device::RRF16( UINT32 mAddr ) /* Read register file (16 bit) */ |
| 137 | 137 | { |
| 138 | 138 | PAIR result; |
| 139 | 139 | result.b.h = RM((mAddr-1)&0xffff); |
| r29472 | r29473 | |
| 141 | 141 | return result.w.l; |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | | void tms7000_device::WRF16( UINT32 mAddr, PAIR p ) /*Write register file (16 bit) */ |
| 144 | void tms7000_device::WRF16( UINT32 mAddr, PAIR p ) /* Write register file (16 bit) */ |
| 145 | 145 | { |
| 146 | 146 | WM( (mAddr-1)&0xffff, p.b.h ); |
| 147 | 147 | WM( mAddr, p.b.l ); |
| r29472 | r29473 | |
| 527 | 527 | } |
| 528 | 528 | |
| 529 | 529 | // BCD arthrimetic handling |
| 530 | | UINT16 tms7000_device::bcd_add( UINT16 a, UINT16 b ) |
| 530 | static const UINT8 lut_bcd_out[6] = { 0x00, 0x06, 0x00, 0x66, 0x60, 0x66 }; |
| 531 | |
| 532 | inline UINT8 tms7000_device::bcd_add( UINT8 a, UINT8 b, UINT8 c ) |
| 531 | 533 | { |
| 532 | | UINT16 t1,t2,t3,t4,t5,t6; |
| 534 | c = (c != 0) ? 1 : 0; |
| 533 | 535 | |
| 534 | | /* Sure it is a lot of code, but it works! */ |
| 535 | | t1 = a + 0x0666; |
| 536 | | t2 = t1 + b; |
| 537 | | t3 = t1 ^ b; |
| 538 | | t4 = t2 ^ t3; |
| 539 | | t5 = ~t4 & 0x1110; |
| 540 | | t6 = (t5 >> 2) | (t5 >> 3); |
| 541 | | return t2-t6; |
| 536 | UINT8 h1 = a >> 4 & 0xf; |
| 537 | UINT8 l1 = a >> 0 & 0xf; |
| 538 | UINT8 h2 = b >> 4 & 0xf; |
| 539 | UINT8 l2 = b >> 0 & 0xf; |
| 540 | |
| 541 | // compute bcd constant |
| 542 | UINT8 d = ((l1 + l2 + c) < 10) ? 0 : 1; |
| 543 | if ((h1 + h2) == 9) |
| 544 | d |= 2; |
| 545 | else if ((h1 + h2) > 9) |
| 546 | d |= 4; |
| 547 | |
| 548 | UINT8 ret = a + b + c + lut_bcd_out[d]; |
| 549 | |
| 550 | CLR_NZC; |
| 551 | SET_N8(ret); |
| 552 | SET_Z8(ret); |
| 553 | |
| 554 | if (d > 2) |
| 555 | pSR |= SR_C; |
| 556 | |
| 557 | return ret; |
| 542 | 558 | } |
| 543 | 559 | |
| 544 | | UINT16 tms7000_device::bcd_tencomp( UINT16 a ) |
| 560 | inline UINT8 tms7000_device::bcd_sub( UINT8 a, UINT8 b, UINT8 c ) |
| 545 | 561 | { |
| 546 | | UINT16 t1,t2,t3,t4,t5,t6; |
| 562 | c = (c != 0) ? 0 : 1; |
| 547 | 563 | |
| 548 | | t1 = 0xffff - a; |
| 549 | | t2 = -a; |
| 550 | | t3 = t1 ^ 0x0001; |
| 551 | | t4 = t2 ^ t3; |
| 552 | | t5 = ~t4 & 0x1110; |
| 553 | | t6 = (t5 >> 2)|(t5>>3); |
| 554 | | return t2-t6; |
| 555 | | } |
| 564 | UINT8 h1 = a >> 4 & 0xf; |
| 565 | UINT8 l1 = a >> 0 & 0xf; |
| 566 | UINT8 h2 = b >> 4 & 0xf; |
| 567 | UINT8 l2 = b >> 0 & 0xf; |
| 556 | 568 | |
| 557 | | /* |
| 558 | | Compute difference a-b??? |
| 559 | | */ |
| 560 | | UINT16 tms7000_device::bcd_sub( UINT16 a, UINT16 b) |
| 561 | | { |
| 562 | | //return bcd_tencomp(b) - bcd_tencomp(a); |
| 563 | | return bcd_add(a, bcd_tencomp(b) & 0xff); |
| 569 | // compute bcd constant |
| 570 | UINT8 d = ((l1 - c) >= l2) ? 0 : 1; |
| 571 | if (h1 == h2) |
| 572 | d |= 2; |
| 573 | else if (h1 < h2) |
| 574 | d |= 4; |
| 575 | |
| 576 | UINT8 ret = a - b - c - lut_bcd_out[d]; |
| 577 | |
| 578 | CLR_NZC; |
| 579 | SET_N8(ret); |
| 580 | SET_Z8(ret); |
| 581 | |
| 582 | if (d > 2) |
| 583 | pSR |= SR_C; |
| 584 | |
| 585 | return ret; |
| 564 | 586 | } |
| 565 | 587 | |
| 566 | 588 | WRITE8_MEMBER( tms7000_device::tms7000_internal_w ) |
trunk/src/emu/cpu/tms7000/tms7000.h
| r29472 | r29473 | |
| 92 | 92 | static const opcode_func s_opfn_exl[0x100]; |
| 93 | 93 | const opcode_func *m_opcode; |
| 94 | 94 | |
| 95 | | static UINT16 bcd_add( UINT16 a, UINT16 b ); |
| 96 | | static UINT16 bcd_tencomp( UINT16 a ); |
| 97 | | static UINT16 bcd_sub( UINT16 a, UINT16 b); |
| 95 | inline UINT8 bcd_add( UINT8 a, UINT8 b, UINT8 c ); |
| 96 | inline UINT8 bcd_sub( UINT8 a, UINT8 b, UINT8 c ); |
| 98 | 97 | |
| 99 | | PAIR m_pc; /* Program counter */ |
| 100 | | UINT8 m_sp; /* Stack Pointer */ |
| 101 | | UINT8 m_sr; /* Status Register */ |
| 102 | | UINT8 m_irq_state[3]; /* State of the three IRQs */ |
| 103 | | UINT8 m_rf[0x80]; /* Register file (SJE) */ |
| 104 | | UINT8 m_pf[0x100]; /* Perpherial file */ |
| 105 | | address_space *m_program; |
| 106 | | direct_read_data *m_direct; |
| 107 | | address_space *m_io; |
| 98 | PAIR m_pc; /* Program counter */ |
| 99 | UINT8 m_sp; /* Stack Pointer */ |
| 100 | UINT8 m_sr; /* Status Register */ |
| 101 | UINT8 m_irq_state[3]; /* State of the three IRQs */ |
| 102 | UINT8 m_rf[0x80]; /* Register file (SJE) */ |
| 103 | UINT8 m_pf[0x100]; /* Perpherial file */ |
| 104 | |
| 108 | 105 | int m_icount; |
| 109 | 106 | int m_div_by_16_trigger; |
| 110 | 107 | int m_cycles_per_INT2; |
| 111 | 108 | UINT8 m_t1_capture_latch; /* Timer 1 capture latch */ |
| 112 | | INT8 m_t1_prescaler; /* Timer 1 prescaler (5 bits) */ |
| 113 | | INT16 m_t1_decrementer; /* Timer 1 decrementer (8 bits) */ |
| 114 | | UINT8 m_idle_state; /* Set after the execution of an idle instruction */ |
| 109 | INT8 m_t1_prescaler; /* Timer 1 prescaler (5 bits) */ |
| 110 | INT16 m_t1_decrementer; /* Timer 1 decrementer (8 bits) */ |
| 111 | UINT8 m_idle_state; /* Set after the execution of an idle instruction */ |
| 115 | 112 | |
| 113 | address_space *m_program; |
| 114 | direct_read_data *m_direct; |
| 115 | address_space *m_io; |
| 116 | |
| 116 | 117 | inline UINT16 RM16( UINT32 mAddr ); |
| 117 | 118 | inline UINT16 RRF16( UINT32 mAddr ); |
| 118 | 119 | inline void WRF16( UINT32 mAddr, PAIR p ); |
| 120 | |
| 119 | 121 | void tms7000_check_IRQ_lines(); |
| 120 | 122 | void tms7000_do_interrupt( UINT16 address, UINT8 line ); |
| 121 | 123 | void illegal(); |
| r29472 | r29473 | |
| 348 | 350 | void xorp_b2p(); |
| 349 | 351 | void xorp_i2p(); |
| 350 | 352 | void tms7000_service_timer1(); |
| 351 | | |
| 352 | 353 | }; |
| 353 | 354 | |
| 354 | 355 | |
trunk/src/emu/cpu/tms7000/tms70op.inc
| r29472 | r29473 | |
| 1292 | 1292 | |
| 1293 | 1293 | void tms7000_device::dac_b2a() |
| 1294 | 1294 | { |
| 1295 | | UINT16 t; |
| 1295 | WRA(bcd_add(RDA, RDB, pSR & SR_C)); |
| 1296 | 1296 | |
| 1297 | | t = bcd_add( RDA, RDB ); |
| 1298 | | |
| 1299 | | if (pSR & SR_C) |
| 1300 | | t = bcd_add( t, 1 ); |
| 1301 | | |
| 1302 | | WRA(t); |
| 1303 | | |
| 1304 | | CLR_NZC; |
| 1305 | | SET_C8(t); |
| 1306 | | SET_N8(t); |
| 1307 | | SET_Z8(t); |
| 1308 | | |
| 1309 | 1297 | m_icount -= 7; |
| 1310 | 1298 | } |
| 1311 | 1299 | |
| 1312 | 1300 | void tms7000_device::dac_r2a() |
| 1313 | 1301 | { |
| 1314 | | UINT8 r; |
| 1315 | | UINT16 t; |
| 1316 | | |
| 1302 | UINT8 r; |
| 1317 | 1303 | IMMBYTE(r); |
| 1318 | 1304 | |
| 1319 | | t = bcd_add( RDA, RM(r) ); |
| 1305 | WRA(bcd_add(RDA, RM(r), pSR & SR_C)); |
| 1320 | 1306 | |
| 1321 | | if (pSR & SR_C) |
| 1322 | | t = bcd_add( t, 1 ); |
| 1323 | | |
| 1324 | | WRA(t); |
| 1325 | | |
| 1326 | | CLR_NZC; |
| 1327 | | SET_C8(t); |
| 1328 | | SET_N8(t); |
| 1329 | | SET_Z8(t); |
| 1330 | | |
| 1331 | 1307 | m_icount -= 10; |
| 1332 | 1308 | } |
| 1333 | 1309 | |
| 1334 | 1310 | void tms7000_device::dac_r2b() |
| 1335 | 1311 | { |
| 1336 | | UINT8 r; |
| 1337 | | UINT16 t; |
| 1338 | | |
| 1312 | UINT8 r; |
| 1339 | 1313 | IMMBYTE(r); |
| 1340 | 1314 | |
| 1341 | | t = bcd_add( RDB, RM(r) ); |
| 1315 | WRB(bcd_add(RDB, RM(r), pSR & SR_C)); |
| 1342 | 1316 | |
| 1343 | | if (pSR & SR_C) |
| 1344 | | t = bcd_add( t, 1 ); |
| 1345 | | |
| 1346 | | WRB(t); |
| 1347 | | |
| 1348 | | CLR_NZC; |
| 1349 | | SET_C8(t); |
| 1350 | | SET_N8(t); |
| 1351 | | SET_Z8(t); |
| 1352 | | |
| 1353 | 1317 | m_icount -= 10; |
| 1354 | 1318 | } |
| 1355 | 1319 | |
| 1356 | 1320 | void tms7000_device::dac_r2r() |
| 1357 | 1321 | { |
| 1358 | | UINT8 r,s; |
| 1359 | | UINT16 t; |
| 1360 | | |
| 1322 | UINT8 s, r; |
| 1361 | 1323 | IMMBYTE(s); |
| 1362 | 1324 | IMMBYTE(r); |
| 1363 | 1325 | |
| 1364 | | t = bcd_add( RM(s), RM(r) ); |
| 1326 | WM(r, bcd_add(RM(s), RM(r), pSR & SR_C)); |
| 1365 | 1327 | |
| 1366 | | if (pSR & SR_C) |
| 1367 | | t = bcd_add( t, 1 ); |
| 1368 | | |
| 1369 | | WM(r,t); |
| 1370 | | |
| 1371 | | CLR_NZC; |
| 1372 | | SET_C8(t); |
| 1373 | | SET_N8(t); |
| 1374 | | SET_Z8(t); |
| 1375 | | |
| 1376 | 1328 | m_icount -= 12; |
| 1377 | 1329 | } |
| 1378 | 1330 | |
| 1379 | 1331 | void tms7000_device::dac_i2a() |
| 1380 | 1332 | { |
| 1381 | | UINT8 i; |
| 1382 | | UINT16 t; |
| 1383 | | |
| 1333 | UINT8 i; |
| 1384 | 1334 | IMMBYTE(i); |
| 1385 | 1335 | |
| 1386 | | t = bcd_add( i, RDA ); |
| 1336 | WRA(bcd_add(i, RDA, pSR & SR_C)); |
| 1387 | 1337 | |
| 1388 | | if (pSR & SR_C) |
| 1389 | | t = bcd_add( t, 1 ); |
| 1390 | | |
| 1391 | | WRA(t); |
| 1392 | | |
| 1393 | | CLR_NZC; |
| 1394 | | SET_C8(t); |
| 1395 | | SET_N8(t); |
| 1396 | | SET_Z8(t); |
| 1397 | | |
| 1398 | 1338 | m_icount -= 9; |
| 1399 | 1339 | } |
| 1400 | 1340 | |
| 1401 | 1341 | void tms7000_device::dac_i2b() |
| 1402 | 1342 | { |
| 1403 | | UINT8 i; |
| 1404 | | UINT16 t; |
| 1405 | | |
| 1343 | UINT8 i; |
| 1406 | 1344 | IMMBYTE(i); |
| 1407 | 1345 | |
| 1408 | | t = bcd_add( i, RDB ); |
| 1346 | WRB(bcd_add(i, RDB, pSR & SR_C)); |
| 1409 | 1347 | |
| 1410 | | if (pSR & SR_C) |
| 1411 | | t = bcd_add( t, 1 ); |
| 1412 | | |
| 1413 | | WRB(t); |
| 1414 | | |
| 1415 | | CLR_NZC; |
| 1416 | | SET_C8(t); |
| 1417 | | SET_N8(t); |
| 1418 | | SET_Z8(t); |
| 1419 | | |
| 1420 | 1348 | m_icount -= 9; |
| 1421 | 1349 | } |
| 1422 | 1350 | |
| 1423 | 1351 | void tms7000_device::dac_i2r() |
| 1424 | 1352 | { |
| 1425 | | UINT8 i,r; |
| 1426 | | UINT16 t; |
| 1427 | | |
| 1353 | UINT8 i, r; |
| 1428 | 1354 | IMMBYTE(i); |
| 1429 | 1355 | IMMBYTE(r); |
| 1430 | 1356 | |
| 1431 | | t = bcd_add( i, RM(r) ); |
| 1357 | WM(r, bcd_add(i, RM(r), pSR & SR_C)); |
| 1432 | 1358 | |
| 1433 | | if (pSR & SR_C) |
| 1434 | | t = bcd_add( t, 1 ); |
| 1435 | | |
| 1436 | | WM(r,t); |
| 1437 | | |
| 1438 | | CLR_NZC; |
| 1439 | | SET_C8(t); |
| 1440 | | SET_N8(t); |
| 1441 | | SET_Z8(t); |
| 1442 | | |
| 1443 | 1359 | m_icount -= 11; |
| 1444 | 1360 | } |
| 1445 | 1361 | |
| r29472 | r29473 | |
| 1642 | 1558 | |
| 1643 | 1559 | void tms7000_device::dsb_b2a() |
| 1644 | 1560 | { |
| 1645 | | UINT16 t; |
| 1561 | WRA(bcd_sub(RDA, RDB, pSR & SR_C)); |
| 1646 | 1562 | |
| 1647 | | t = bcd_sub( RDA, RDB ); |
| 1648 | | |
| 1649 | | if( !(pSR & SR_C) ) |
| 1650 | | t = bcd_sub( t, 1 ); |
| 1651 | | |
| 1652 | | WRA(t); |
| 1653 | | |
| 1654 | | CLR_NZC; |
| 1655 | | SET_C8(~t); |
| 1656 | | SET_N8(t); |
| 1657 | | SET_Z8(t); |
| 1658 | | |
| 1659 | 1563 | m_icount -= 7; |
| 1660 | 1564 | } |
| 1661 | 1565 | |
| 1662 | 1566 | void tms7000_device::dsb_r2a() |
| 1663 | 1567 | { |
| 1664 | | UINT8 r; |
| 1665 | | UINT16 t; |
| 1666 | | |
| 1568 | UINT8 r; |
| 1667 | 1569 | IMMBYTE(r); |
| 1668 | 1570 | |
| 1669 | | t = bcd_sub( RDA, RM(r) ); |
| 1571 | WRA(bcd_sub(RDA, RM(r), pSR & SR_C)); |
| 1670 | 1572 | |
| 1671 | | if( !(pSR & SR_C) ) |
| 1672 | | t = bcd_sub( t, 1 ); |
| 1673 | | |
| 1674 | | WRA(t); |
| 1675 | | |
| 1676 | | CLR_NZC; |
| 1677 | | SET_C8(~t); |
| 1678 | | SET_N8(t); |
| 1679 | | SET_Z8(t); |
| 1680 | | |
| 1681 | 1573 | m_icount -= 10; |
| 1682 | 1574 | } |
| 1683 | 1575 | |
| 1684 | 1576 | void tms7000_device::dsb_r2b() |
| 1685 | 1577 | { |
| 1686 | | UINT8 r; |
| 1687 | | UINT16 t; |
| 1688 | | |
| 1578 | UINT8 r; |
| 1689 | 1579 | IMMBYTE(r); |
| 1690 | 1580 | |
| 1691 | | t = bcd_sub( RDB, RM(r) ); |
| 1581 | WRB(bcd_sub(RDB, RM(r), pSR & SR_C)); |
| 1692 | 1582 | |
| 1693 | | if( !(pSR & SR_C) ) |
| 1694 | | t = bcd_sub( t, 1 ); |
| 1695 | | |
| 1696 | | WRB(t); |
| 1697 | | |
| 1698 | | CLR_NZC; |
| 1699 | | SET_C8(~t); |
| 1700 | | SET_N8(t); |
| 1701 | | SET_Z8(t); |
| 1702 | | |
| 1703 | 1583 | m_icount -= 10; |
| 1704 | 1584 | } |
| 1705 | 1585 | |
| 1706 | 1586 | void tms7000_device::dsb_r2r() |
| 1707 | 1587 | { |
| 1708 | | UINT8 r,s; |
| 1709 | | UINT16 t; |
| 1710 | | |
| 1588 | UINT8 s, r; |
| 1711 | 1589 | IMMBYTE(s); |
| 1712 | 1590 | IMMBYTE(r); |
| 1713 | 1591 | |
| 1714 | | t = bcd_sub( RM(s), RM(r) ); |
| 1592 | WM(r, bcd_sub(RM(s), RM(r), pSR & SR_C)); |
| 1715 | 1593 | |
| 1716 | | if( !(pSR & SR_C) ) |
| 1717 | | t = bcd_sub( t, 1 ); |
| 1718 | | |
| 1719 | | WM(r,t); |
| 1720 | | |
| 1721 | | CLR_NZC; |
| 1722 | | SET_C8(~t); |
| 1723 | | SET_N8(t); |
| 1724 | | SET_Z8(t); |
| 1725 | | |
| 1726 | 1594 | m_icount -= 12; |
| 1727 | 1595 | } |
| 1728 | 1596 | |
| 1729 | 1597 | void tms7000_device::dsb_i2a() |
| 1730 | 1598 | { |
| 1731 | | UINT8 i; |
| 1732 | | UINT16 t; |
| 1733 | | |
| 1599 | UINT8 i; |
| 1734 | 1600 | IMMBYTE(i); |
| 1735 | 1601 | |
| 1736 | | t = bcd_sub( RDA, i ); |
| 1602 | WRA(bcd_sub(RDA, i, pSR & SR_C)); |
| 1737 | 1603 | |
| 1738 | | if( !(pSR & SR_C) ) |
| 1739 | | t = bcd_sub( t, 1 ); |
| 1740 | | |
| 1741 | | WRA(t); |
| 1742 | | |
| 1743 | | CLR_NZC; |
| 1744 | | SET_C8(~t); |
| 1745 | | SET_N8(t); |
| 1746 | | SET_Z8(t); |
| 1747 | | |
| 1748 | 1604 | m_icount -= 9; |
| 1749 | 1605 | } |
| 1750 | 1606 | |
| 1751 | 1607 | void tms7000_device::dsb_i2b() |
| 1752 | 1608 | { |
| 1753 | | UINT8 i; |
| 1754 | | UINT16 t; |
| 1755 | | |
| 1609 | UINT8 i; |
| 1756 | 1610 | IMMBYTE(i); |
| 1757 | 1611 | |
| 1758 | | t = bcd_sub( RDB, i ); |
| 1612 | WRB(bcd_sub(RDB, i, pSR & SR_C)); |
| 1759 | 1613 | |
| 1760 | | if( !(pSR & SR_C) ) |
| 1761 | | t = bcd_sub( t, 1 ); |
| 1762 | | |
| 1763 | | WRB(t); |
| 1764 | | |
| 1765 | | CLR_NZC; |
| 1766 | | SET_C8(~t); |
| 1767 | | SET_N8(t); |
| 1768 | | SET_Z8(t); |
| 1769 | | |
| 1770 | 1614 | m_icount -= 9; |
| 1771 | 1615 | } |
| 1772 | 1616 | |
| 1773 | 1617 | void tms7000_device::dsb_i2r() |
| 1774 | 1618 | { |
| 1775 | | UINT8 r,i; |
| 1776 | | UINT16 t; |
| 1777 | | |
| 1619 | UINT8 i, r; |
| 1778 | 1620 | IMMBYTE(i); |
| 1779 | 1621 | IMMBYTE(r); |
| 1780 | 1622 | |
| 1781 | | t = bcd_sub( RM(r), i ); |
| 1623 | WM(r, bcd_sub(RM(r), i, pSR & SR_C)); |
| 1782 | 1624 | |
| 1783 | | if( !(pSR & SR_C) ) |
| 1784 | | t = bcd_sub( t, 1 ); |
| 1785 | | |
| 1786 | | WM(r,t); |
| 1787 | | |
| 1788 | | CLR_NZC; |
| 1789 | | SET_C8(~t); |
| 1790 | | SET_N8(t); |
| 1791 | | SET_Z8(t); |
| 1792 | | |
| 1793 | 1625 | m_icount -= 11; |
| 1794 | 1626 | } |
| 1795 | 1627 | |