trunk/src/emu/cpu/upd7810/upd7810.c
r241765 | r241766 | |
420 | 420 | upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
421 | 421 | : cpu_device(mconfig, UPD7810, "uPD7810", tag, owner, clock, "upd7810", __FILE__) |
422 | 422 | , m_to_func(*this) |
| 423 | , m_co0_func(*this) |
| 424 | , m_co1_func(*this) |
423 | 425 | , m_txd_func(*this) |
424 | 426 | , m_rxd_func(*this) |
425 | 427 | , m_an0_func(*this) |
r241765 | r241766 | |
446 | 448 | upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) |
447 | 449 | : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) |
448 | 450 | , m_to_func(*this) |
| 451 | , m_co0_func(*this) |
| 452 | , m_co1_func(*this) |
449 | 453 | , m_txd_func(*this) |
450 | 454 | , m_rxd_func(*this) |
451 | 455 | , m_an0_func(*this) |
r241765 | r241766 | |
860 | 864 | |
861 | 865 | void upd7810_device::upd7810_write_EOM() |
862 | 866 | { |
863 | | if (EOM & 0x01) /* output LV0 content ? */ |
| 867 | if (EOM & 0x01) /* output LV0 content */ |
864 | 868 | { |
865 | 869 | switch (EOM & 0x0e) |
866 | 870 | { |
867 | 871 | case 0x02: /* toggle CO0 */ |
868 | | CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2); |
| 872 | CO0 ^= 1; |
869 | 873 | break; |
870 | 874 | case 0x04: /* reset CO0 */ |
871 | 875 | CO0 = 0; |
| 876 | EOM &= 0xfb; /* LRE0 is reset t0 0 */ |
872 | 877 | break; |
873 | 878 | case 0x08: /* set CO0 */ |
874 | 879 | CO0 = 1; |
| 880 | EOM &= 0xf7; /* LRE1 is reset t0 0 */ |
875 | 881 | break; |
876 | 882 | } |
| 883 | EOM &= 0xfe; /* LO0 is reset t0 0 */ |
| 884 | m_co0_func(CO0); |
877 | 885 | } |
878 | | if (EOM & 0x10) /* output LV0 content ? */ |
| 886 | if (EOM & 0x10) /* output LV1 content */ |
879 | 887 | { |
880 | 888 | switch (EOM & 0xe0) |
881 | 889 | { |
882 | 890 | case 0x20: /* toggle CO1 */ |
883 | | CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2); |
| 891 | CO1 ^= 1; |
884 | 892 | break; |
885 | 893 | case 0x40: /* reset CO1 */ |
886 | 894 | CO1 = 0; |
| 895 | EOM &= 0xbf; /* LRE2 is reset t0 0 */ |
887 | 896 | break; |
888 | 897 | case 0x80: /* set CO1 */ |
889 | 898 | CO1 = 1; |
| 899 | EOM &= 0x7f; /* LRE3 is reset t0 0 */ |
890 | 900 | break; |
891 | 901 | } |
| 902 | EOM &= 0xef; /* LO1 is reset t0 0 */ |
| 903 | m_co1_func(CO1); |
892 | 904 | } |
893 | 905 | } |
894 | 906 | |
r241765 | r241766 | |
1319 | 1331 | ((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */ |
1320 | 1332 | ((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */ |
1321 | 1333 | { |
1322 | | switch (EOM & 0x0e) |
1323 | | { |
1324 | | case 0x02: /* toggle CO0 */ |
1325 | | CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2); |
1326 | | break; |
1327 | | case 0x04: /* reset CO0 */ |
1328 | | CO0 = 0; |
1329 | | break; |
1330 | | case 0x08: /* set CO0 */ |
1331 | | CO0 = 1; |
1332 | | break; |
| 1334 | if (EOM & 0x02) { |
| 1335 | /* toggle CO0 */ |
| 1336 | CO0 ^= 1; |
| 1337 | m_co0_func(CO0); |
1333 | 1338 | } |
1334 | 1339 | } |
1335 | 1340 | /* Conditions When ECNT Causes a CO1 Output Change */ |
r241765 | r241766 | |
1338 | 1343 | ((0x80 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 or at falling CI input */ |
1339 | 1344 | ((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */ |
1340 | 1345 | { |
1341 | | switch (EOM & 0xe0) |
1342 | | { |
1343 | | case 0x20: /* toggle CO1 */ |
1344 | | CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2); |
1345 | | break; |
1346 | | case 0x40: /* reset CO1 */ |
1347 | | CO1 = 0; |
1348 | | break; |
1349 | | case 0x80: /* set CO1 */ |
1350 | | CO1 = 1; |
1351 | | break; |
| 1346 | if (EOM & 0x20) { |
| 1347 | /* toggle CO1 */ |
| 1348 | CO1 ^= 1; |
| 1349 | m_co1_func(CO1); |
1352 | 1350 | } |
1353 | 1351 | } |
1354 | 1352 | /* How and When ECNT is Cleared */ |
r241765 | r241766 | |
1543 | 1541 | m_io = &space(AS_IO); |
1544 | 1542 | |
1545 | 1543 | m_to_func.resolve_safe(); |
| 1544 | m_co0_func.resolve_safe(); |
| 1545 | m_co1_func.resolve_safe(); |
1546 | 1546 | m_txd_func.resolve_safe(); |
1547 | 1547 | m_rxd_func.resolve_safe(0); |
1548 | 1548 | m_an0_func.resolve_safe(0); |
r241765 | r241766 | |
1677 | 1677 | state_add( UPD7810_TI, "TI", m_ti).formatstr("%3u"); |
1678 | 1678 | state_add( UPD7810_TO, "TO", m_to).formatstr("%3u"); |
1679 | 1679 | state_add( UPD7810_CI, "CI", m_ci).formatstr("%3u"); |
1680 | | state_add( UPD7810_CO0, "CO0", m_co0).mask(0x01).formatstr("%1X"); |
1681 | | state_add( UPD7810_CO1, "CO1", m_co1).mask(0x01).formatstr("%1X"); |
| 1680 | state_add( UPD7810_CO0, "CO0", m_co0).formatstr("%3u"); |
| 1681 | state_add( UPD7810_CO1, "CO1", m_co1).formatstr("%3u"); |
1682 | 1682 | |
1683 | 1683 | state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow(); |
1684 | 1684 | state_add( STATE_GENPCBASE, "GENPCBASE", m_ppc.w.l ).formatstr("%04X").noshow(); |
trunk/src/emu/cpu/upd7810/upd7810.h
r241765 | r241766 | |
50 | 50 | #define MCFG_UPD7810_TO(_devcb) \ |
51 | 51 | upd7810_device::set_to_func(*device, DEVCB_##_devcb); |
52 | 52 | |
| 53 | #define MCFG_UPD7810_CO0(_devcb) \ |
| 54 | upd7810_device::set_co0_func(*device, DEVCB_##_devcb); |
| 55 | |
| 56 | #define MCFG_UPD7810_CO1(_devcb) \ |
| 57 | upd7810_device::set_co1_func(*device, DEVCB_##_devcb); |
| 58 | |
53 | 59 | #define MCFG_UPD7810_TXD(_devcb) \ |
54 | 60 | upd7810_device::set_txd_func(*device, DEVCB_##_devcb); |
55 | 61 | |
r241765 | r241766 | |
90 | 96 | |
91 | 97 | // static configuration helpers |
92 | 98 | template<class _Object> static devcb_base &set_to_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_to_func.set_callback(object); } |
| 99 | template<class _Object> static devcb_base &set_co0_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_co0_func.set_callback(object); } |
| 100 | template<class _Object> static devcb_base &set_co1_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_co1_func.set_callback(object); } |
93 | 101 | template<class _Object> static devcb_base &set_txd_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_txd_func.set_callback(object); } |
94 | 102 | template<class _Object> static devcb_base &set_rxd_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_rxd_func.set_callback(object); } |
95 | 103 | template<class _Object> static devcb_base &set_an0_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an0_func.set_callback(object); } |
r241765 | r241766 | |
173 | 181 | void upd7810_handle_timer1(int cycles, int clkdiv); |
174 | 182 | |
175 | 183 | devcb_write_line m_to_func; |
| 184 | devcb_write_line m_co0_func; |
| 185 | devcb_write_line m_co1_func; |
176 | 186 | devcb_write_line m_txd_func; |
177 | 187 | devcb_read_line m_rxd_func; |
178 | 188 | devcb_read8 m_an0_func; |