Previous 199869 Revisions Next

r33254 Friday 7th November, 2014 at 04:00:57 UTC by Ramiro Polla
upd7810: fix and export timer/event counter output

The timer/event counter outputs (CO0 and CO1) are set differently when
EOM changes and when a timer update occurs. Most EOM values are
cleared on use. The document at [0] is confusing regarding these bits.
An older document [1], easier to understand, was used instead.

[0] NEC Electronics User's Manual, April 1987
[1] NEC uCOM-87AD Family 8-Bit Microcomputers uPD78C1X Users Manual
[src/emu/cpu/upd7810]upd7810.c upd7810.h

trunk/src/emu/cpu/upd7810/upd7810.c
r241765r241766
420420upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
421421   : cpu_device(mconfig, UPD7810, "uPD7810", tag, owner, clock, "upd7810", __FILE__)
422422   , m_to_func(*this)
423   , m_co0_func(*this)
424   , m_co1_func(*this)
423425   , m_txd_func(*this)
424426   , m_rxd_func(*this)
425427   , m_an0_func(*this)
r241765r241766
446448upd7810_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)
447449   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
448450   , m_to_func(*this)
451   , m_co0_func(*this)
452   , m_co1_func(*this)
449453   , m_txd_func(*this)
450454   , m_rxd_func(*this)
451455   , m_an0_func(*this)
r241765r241766
860864
861865void upd7810_device::upd7810_write_EOM()
862866{
863   if (EOM & 0x01) /* output LV0 content ? */
867   if (EOM & 0x01) /* output LV0 content */
864868   {
865869      switch (EOM & 0x0e)
866870      {
867871      case 0x02:  /* toggle CO0 */
868         CO0 = (CO0 >> 1) | ((CO0 ^ 2) & 2);
872         CO0 ^= 1;
869873         break;
870874      case 0x04:  /* reset CO0 */
871875         CO0 = 0;
876         EOM &= 0xfb; /* LRE0 is reset t0 0 */
872877         break;
873878      case 0x08:  /* set CO0 */
874879         CO0 = 1;
880         EOM &= 0xf7; /* LRE1 is reset t0 0 */
875881         break;
876882      }
883      EOM &= 0xfe; /* LO0 is reset t0 0 */
884      m_co0_func(CO0);
877885   }
878   if (EOM & 0x10) /* output LV0 content ? */
886   if (EOM & 0x10) /* output LV1 content */
879887   {
880888      switch (EOM & 0xe0)
881889      {
882890      case 0x20:  /* toggle CO1 */
883         CO1 = (CO1 >> 1) | ((CO1 ^ 2) & 2);
891         CO1 ^= 1;
884892         break;
885893      case 0x40:  /* reset CO1 */
886894         CO1 = 0;
895         EOM &= 0xbf; /* LRE2 is reset t0 0 */
887896         break;
888897      case 0x80:  /* set CO1 */
889898         CO1 = 1;
899         EOM &= 0x7f; /* LRE3 is reset t0 0 */
890900         break;
891901      }
902      EOM &= 0xef; /* LO1 is reset t0 0 */
903      m_co1_func(CO1);
892904   }
893905}
894906
r241765r241766
13191331             ((0x20 == (ETMM & 0x30)) && (ETM0 == ECNT)) || /* set CO0 if ECNT == ETM0 or at falling CI input */
13201332             ((0x30 == (ETMM & 0x30)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */
13211333         {
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);
13331338            }
13341339         }
13351340         /* Conditions When ECNT Causes a CO1 Output Change */
r241765r241766
13381343             ((0x80 == (ETMM & 0xc0)) && (ETM1 == ECNT)) || /* set CO1 if ECNT == ETM1 or at falling CI input */
13391344             ((0xc0 == (ETMM & 0xc0)) && (ETM0 == ECNT || ETM1 == ECNT))) /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */
13401345         {
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);
13521350            }
13531351         }
13541352         /* How and When ECNT is Cleared */
r241765r241766
15431541   m_io = &space(AS_IO);
15441542
15451543   m_to_func.resolve_safe();
1544   m_co0_func.resolve_safe();
1545   m_co1_func.resolve_safe();
15461546   m_txd_func.resolve_safe();
15471547   m_rxd_func.resolve_safe(0);
15481548   m_an0_func.resolve_safe(0);
r241765r241766
16771677   state_add( UPD7810_TI,   "TI",   m_ti).formatstr("%3u");
16781678   state_add( UPD7810_TO,   "TO",   m_to).formatstr("%3u");
16791679   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");
16821682
16831683   state_add( STATE_GENPC, "GENPC", m_pc.w.l ).formatstr("%04X").noshow();
16841684   state_add( STATE_GENPCBASE, "GENPCBASE", m_ppc.w.l ).formatstr("%04X").noshow();
trunk/src/emu/cpu/upd7810/upd7810.h
r241765r241766
5050#define MCFG_UPD7810_TO(_devcb) \
5151   upd7810_device::set_to_func(*device, DEVCB_##_devcb);
5252
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
5359#define MCFG_UPD7810_TXD(_devcb) \
5460   upd7810_device::set_txd_func(*device, DEVCB_##_devcb);
5561
r241765r241766
9096
9197   // static configuration helpers
9298   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); }
93101   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); }
94102   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); }
95103   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); }
r241765r241766
173181   void upd7810_handle_timer1(int cycles, int clkdiv);
174182
175183   devcb_write_line  m_to_func;
184   devcb_write_line  m_co0_func;
185   devcb_write_line  m_co1_func;
176186   devcb_write_line  m_txd_func;
177187   devcb_read_line   m_rxd_func;
178188   devcb_read8       m_an0_func;


Previous 199869 Revisions Next


© 1997-2024 The MAME Team