diff options
author | Miodrag Milanović <mmicko@gmail.com> | 2014-11-07 08:09:40 +0100 |
---|---|---|
committer | Miodrag Milanović <mmicko@gmail.com> | 2014-11-07 08:09:40 +0100 |
commit | 6d011ccbebe12c2e31ef864e913d1623a112765b (patch) | |
tree | 35a38e4fa94d4073f618e0b6c72689cd17de34f8 | |
parent | e28487ff3058764f08bc101dd3d41224f60ba79f (diff) | |
parent | f26bae07da8d680201a7111572eec5b72d3409d2 (diff) |
Merge pull request #37 from ramiropolla/upd7810
upd7810: fix and improve timer/event counter
-rw-r--r-- | src/emu/cpu/upd7810/upd7810.c | 88 | ||||
-rw-r--r-- | src/emu/cpu/upd7810/upd7810.h | 10 |
2 files changed, 54 insertions, 44 deletions
diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 70bdeafe766..cbd70a18cca 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -420,6 +420,8 @@ const device_type UPD78C06 = &device_creator<upd78c06_device>; upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : cpu_device(mconfig, UPD7810, "uPD7810", tag, owner, clock, "upd7810", __FILE__) , m_to_func(*this) + , m_co0_func(*this) + , m_co1_func(*this) , m_txd_func(*this) , m_rxd_func(*this) , m_an0_func(*this) @@ -446,6 +448,8 @@ upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, d 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) : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) , m_to_func(*this) + , m_co0_func(*this) + , m_co1_func(*this) , m_txd_func(*this) , m_rxd_func(*this) , m_an0_func(*this) @@ -860,35 +864,43 @@ void upd7801_device::upd7810_take_irq() void upd7810_device::upd7810_write_EOM() { - if (EOM & 0x01) /* output LV0 content ? */ + if (EOM & 0x01) /* output LV0 content */ { switch (EOM & 0x0e) { case 0x02: /* toggle CO0 */ - CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2); + CO0 ^= 1; break; case 0x04: /* reset CO0 */ CO0 = 0; + EOM &= 0xfb; /* LRE0 is reset t0 0 */ break; case 0x08: /* set CO0 */ CO0 = 1; + EOM &= 0xf7; /* LRE1 is reset t0 0 */ break; } + EOM &= 0xfe; /* LO0 is reset t0 0 */ + m_co0_func(CO0); } - if (EOM & 0x10) /* output LV0 content ? */ + if (EOM & 0x10) /* output LV1 content */ { switch (EOM & 0xe0) { case 0x20: /* toggle CO1 */ - CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2); + CO1 ^= 1; break; case 0x40: /* reset CO1 */ CO1 = 0; + EOM &= 0xbf; /* LRE2 is reset t0 0 */ break; case 0x80: /* set CO1 */ CO1 = 1; + EOM &= 0x7f; /* LRE3 is reset t0 0 */ break; } + EOM &= 0xef; /* LO1 is reset t0 0 */ + m_co1_func(CO1); } } @@ -1313,6 +1325,30 @@ void upd7810_device::handle_timers(int cycles) IRR |= INTFE0; if (ETM1 == ECNT) IRR |= INTFE1; + /* Conditions When ECNT Causes a CO0 Output Change */ + if (((0x00 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 */ + /* ((0x10 == (ETMM & 0x30)) prohibited */ + ((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */ + ((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */ + { + if (EOM & 0x02) { + /* toggle CO0 */ + CO0 ^= 1; + m_co0_func(CO0); + } + } + /* Conditions When ECNT Causes a CO1 Output Change */ + if (((0x00 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 */ + /* ((0x40 == (ETMM & 0xc0)) prohibited */ + ((0x80 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 or at falling CI input */ + ((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */ + { + if (EOM & 0x20) { + /* toggle CO1 */ + CO1 ^= 1; + m_co1_func(CO1); + } + } /* How and When ECNT is Cleared */ switch (ETMM & 0x0c) { @@ -1329,44 +1365,6 @@ void upd7810_device::handle_timers(int cycles) ECNT = 0; break; } - /* Conditions When ECNT Causes a CO0 Output Change */ - if (((0x00 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 */ - /* ((0x10 == (ETMM & 0x30)) prohibited */ - ((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */ - ((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */ - { - switch (EOM & 0x0e) - { - case 0x02: /* toggle CO0 */ - CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2); - break; - case 0x04: /* reset CO0 */ - CO0 = 0; - break; - case 0x08: /* set CO0 */ - CO0 = 1; - break; - } - } - /* Conditions When ECNT Causes a CO1 Output Change */ - if (((0x00 == (ETMM & 0xc0)) && (ETM0 == ECNT)) || /* set CO1 if ECNT == ETM0 */ - /* ((0x40 == (ETMM & 0xc0)) prohibited */ - ((0x80 == (ETMM & 0xc0)) && (ETM0 == ECNT)) || /* set CO1 if ECNT == ETM0 or at falling CI input */ - ((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */ - { - switch (EOM & 0xe0) - { - case 0x20: /* toggle CO1 */ - CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2); - break; - case 0x40: /* reset CO1 */ - CO1 = 0; - break; - case 0x80: /* set CO1 */ - CO1 = 1; - break; - } - } } } @@ -1543,6 +1541,8 @@ void upd7810_device::base_device_start() m_io = &space(AS_IO); m_to_func.resolve_safe(); + m_co0_func.resolve_safe(); + m_co1_func.resolve_safe(); m_txd_func.resolve_safe(); m_rxd_func.resolve_safe(0); m_an0_func.resolve_safe(0); @@ -1677,8 +1677,8 @@ void upd7810_device::device_start() state_add( UPD7810_TI, "TI", m_ti).formatstr("%3u"); state_add( UPD7810_TO, "TO", m_to).formatstr("%3u"); state_add( UPD7810_CI, "CI", m_ci).formatstr("%3u"); - state_add( UPD7810_CO0, "CO0", m_co0).mask(0x01).formatstr("%1X"); - state_add( UPD7810_CO1, "CO1", m_co1).mask(0x01).formatstr("%1X"); + state_add( UPD7810_CO0, "CO0", m_co0).formatstr("%3u"); + state_add( UPD7810_CO1, "CO1", m_co1).formatstr("%3u"); state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow(); state_add( STATE_GENPCBASE, "GENPCBASE", m_ppc.w.l ).formatstr("%04X").noshow(); diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index 45dbbfc8df9..91b1a100e42 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -50,6 +50,12 @@ enum #define MCFG_UPD7810_TO(_devcb) \ upd7810_device::set_to_func(*device, DEVCB_##_devcb); +#define MCFG_UPD7810_CO0(_devcb) \ + upd7810_device::set_co0_func(*device, DEVCB_##_devcb); + +#define MCFG_UPD7810_CO1(_devcb) \ + upd7810_device::set_co1_func(*device, DEVCB_##_devcb); + #define MCFG_UPD7810_TXD(_devcb) \ upd7810_device::set_txd_func(*device, DEVCB_##_devcb); @@ -90,6 +96,8 @@ public: // static configuration helpers 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); } + 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); } + 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); } 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); } 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); } 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); } @@ -173,6 +181,8 @@ protected: void upd7810_handle_timer1(int cycles, int clkdiv); devcb_write_line m_to_func; + devcb_write_line m_co0_func; + devcb_write_line m_co1_func; devcb_write_line m_txd_func; devcb_read_line m_rxd_func; devcb_read8 m_an0_func; |