From a604868222b75d04185da684a09e8b317484736b Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 12:01:21 +0100 Subject: upd7810: Fixed ADC output register range. --- src/emu/cpu/upd7810/upd7810.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 1232fd20271..b20f40c4a8a 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1546,7 +1546,7 @@ void upd7810_device::handle_timers(int cycles) case 2: CR2 = cr; break; case 3: CR3 = cr; break; } - m_adout = (m_adout + 1) & 0x07; + m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; } @@ -1577,7 +1577,7 @@ void upd7810_device::handle_timers(int cycles) case 3: CR3 = cr; break; } m_adin = (m_adin + 1) & 0x07; - m_adout = (m_adout + 1) & 0x07; + m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; } -- cgit v1.2.3 From 7f8150e88aa9b439d416c9d3e0cd29c00c5c2089 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 12:05:19 +0100 Subject: upd7810: ADC functions should return bytes. --- src/emu/cpu/upd7810/upd7810.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index 3be3177040c..6aadcfadb95 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -172,14 +172,14 @@ protected: devcb_write_line m_to_func; devcb_write_line m_txd_func; devcb_read_line m_rxd_func; - devcb_read_line m_an0_func; - devcb_read_line m_an1_func; - devcb_read_line m_an2_func; - devcb_read_line m_an3_func; - devcb_read_line m_an4_func; - devcb_read_line m_an5_func; - devcb_read_line m_an6_func; - devcb_read_line m_an7_func; + devcb_read8 m_an0_func; + devcb_read8 m_an1_func; + devcb_read8 m_an2_func; + devcb_read8 m_an3_func; + devcb_read8 m_an4_func; + devcb_read8 m_an5_func; + devcb_read8 m_an6_func; + devcb_read8 m_an7_func; typedef void (upd7810_device::*opcode_func)(); -- cgit v1.2.3 From a7ffdf4650e57d528b732c51b7f7655e223b2b6d Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 12:08:06 +0100 Subject: upd7810: sample and hold ADC value at start of conversion process. --- src/emu/cpu/upd7810/upd7810.c | 70 ++++++++++++++++++++++++------------------- src/emu/cpu/upd7810/upd7810.h | 2 ++ 2 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index b20f40c4a8a..06deb192491 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1524,62 +1524,70 @@ void upd7810_device::handle_timers(int cycles) if (ANM & 0x01) { /* select mode */ - while (m_adcnt > m_adtot) + if (m_shdone == 0) { - UINT8 cr = 0; - m_adcnt -= m_adtot; switch (m_adin) { - case 0: cr = m_an0_func(); break; - case 1: cr = m_an1_func(); break; - case 2: cr = m_an2_func(); break; - case 3: cr = m_an3_func(); break; - case 4: cr = m_an4_func(); break; - case 5: cr = m_an5_func(); break; - case 6: cr = m_an6_func(); break; - case 7: cr = m_an7_func(); break; + case 0: m_tmpcr = m_an0_func(); break; + case 1: m_tmpcr = m_an1_func(); break; + case 2: m_tmpcr = m_an2_func(); break; + case 3: m_tmpcr = m_an3_func(); break; + case 4: m_tmpcr = m_an4_func(); break; + case 5: m_tmpcr = m_an5_func(); break; + case 6: m_tmpcr = m_an6_func(); break; + case 7: m_tmpcr = m_an7_func(); break; } + m_shdone = 1; + } + if (m_adcnt > m_adtot) + { + m_adcnt -= m_adtot; switch (m_adout) { - case 0: CR0 = cr; break; - case 1: CR1 = cr; break; - case 2: CR2 = cr; break; - case 3: CR3 = cr; break; + case 0: CR0 = m_tmpcr; break; + case 1: CR1 = m_tmpcr; break; + case 2: CR2 = m_tmpcr; break; + case 3: CR3 = m_tmpcr; break; } m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; + m_shdone = 0; } } else { /* scan mode */ - while (m_adcnt > m_adtot) + if (m_shdone == 0) { - UINT8 cr = 0; - m_adcnt -= m_adtot; switch (m_adin | m_adrange) { - case 0: cr = m_an0_func(); break; - case 1: cr = m_an1_func(); break; - case 2: cr = m_an2_func(); break; - case 3: cr = m_an3_func(); break; - case 4: cr = m_an4_func(); break; - case 5: cr = m_an5_func(); break; - case 6: cr = m_an6_func(); break; - case 7: cr = m_an7_func(); break; + case 0: m_tmpcr = m_an0_func(); break; + case 1: m_tmpcr = m_an1_func(); break; + case 2: m_tmpcr = m_an2_func(); break; + case 3: m_tmpcr = m_an3_func(); break; + case 4: m_tmpcr = m_an4_func(); break; + case 5: m_tmpcr = m_an5_func(); break; + case 6: m_tmpcr = m_an6_func(); break; + case 7: m_tmpcr = m_an7_func(); break; } + m_shdone = 1; + } + if (m_adcnt > m_adtot) + { + m_adcnt -= m_adtot; switch (m_adout) { - case 0: CR0 = cr; break; - case 1: CR1 = cr; break; - case 2: CR2 = cr; break; - case 3: CR3 = cr; break; + case 0: CR0 = m_tmpcr; break; + case 1: CR1 = m_tmpcr; break; + case 2: CR2 = m_tmpcr; break; + case 3: CR3 = m_tmpcr; break; } m_adin = (m_adin + 1) & 0x07; m_adout = (m_adout + 1) & 0x03; if (m_adout == 0) IRR |= INTFAD; + m_shdone = 0; } } @@ -1902,6 +1910,8 @@ void upd7810_device::device_reset() m_edges = 0; m_adcnt = 0; m_adtot = 0; + m_tmpcr = 0; + m_shdone = 0; m_adout = 0; m_adin = 0; m_adrange = 0; diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index 6aadcfadb95..916ddbd6eb6 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -308,6 +308,8 @@ protected: UINT8 m_edges; /* rising/falling edge flag for serial I/O */ UINT16 m_adcnt; /* A/D converter cycle count */ UINT8 m_adtot; /* A/D converter total cycles per conversion */ + UINT8 m_tmpcr; /* temporary analog digital conversion register */ + int m_shdone; /* A/D converter sample and hold done */ int m_adout; /* currently selected A/D converter output register */ int m_adin; /* currently selected A/D converter input */ int m_adrange;/* in scan mode, A/D converter range (AN0-AN3 or AN4-AN7) */ -- cgit v1.2.3 From 81e9c271629922504c99c2131f0971bcaf5d5966 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 12:09:20 +0100 Subject: upd7810: clear sample and hold on ADC reset --- src/emu/cpu/upd7810/upd7810.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 06deb192491..3aad186e97d 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1508,6 +1508,7 @@ void upd7810_device::handle_timers(int cycles) else m_adtot = 192; m_adout = 0; + m_shdone = 0; if (ANM & 0x01) { /* select mode */ -- cgit v1.2.3 From 2d4007980d126bc47d984d650e3482bd6c66aebb Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 16:00:15 +0100 Subject: upd7810: remove code duplication in timers 0 and 1 --- src/emu/cpu/upd7810/upd7810.c | 160 ++++++++++++++++-------------------------- src/emu/cpu/upd7810/upd7810.h | 3 + 2 files changed, 64 insertions(+), 99 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 3aad186e97d..f3b1f907caa 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1174,84 +1174,78 @@ void upd7810_device::upd7810_sio_input() } } -void upd7810_device::handle_timers(int cycles) +void upd7810_device::upd7810_handle_timer0(int cycles, int clkdiv) { - /**** TIMER 0 ****/ - if (TMM & 0x10) /* timer 0 upcounter reset ? */ - CNT0 = 0; - else + OVC0 += cycles; + while (OVC0 >= clkdiv) { - switch (TMM & 0x0c) /* timer 0 clock source */ + OVC0 -= clkdiv; + CNT0++; + if (CNT0 == TM0) { - case 0x00: /* clock divided by 12 */ - OVC0 += cycles; - while (OVC0 >= 12) + CNT0 = 0; + IRR |= INTFT0; + /* timer F/F source is timer 0 ? */ + if (0x00 == (TMM & 0x03)) { - OVC0 -= 12; - CNT0++; - if (CNT0 == TM0) - { - CNT0 = 0; - IRR |= INTFT0; - /* timer F/F source is timer 0 ? */ - if (0x00 == (TMM & 0x03)) - { - TO ^= 1; - m_to_func(TO); - } - /* timer 1 chained with timer 0 ? */ - if ((TMM & 0xe0) == 0x60) - { - CNT1++; - if (CNT1 == TM1) - { - IRR |= INTFT1; - CNT1 = 0; - /* timer F/F source is timer 1 ? */ - if (0x01 == (TMM & 0x03)) - { - TO ^= 1; - m_to_func(TO); - } - } - } - } + TO ^= 1; + m_to_func(TO); } - break; - case 0x04: /* clock divided by 384 */ - OVC0 += cycles; - while (OVC0 >= 384) + /* timer 1 chained with timer 0 ? */ + if ((TMM & 0xe0) == 0x60) { - OVC0 -= 384; - CNT0++; - if (CNT0 == TM0) + CNT1++; + if (CNT1 == TM1) { - CNT0 = 0; - IRR |= INTFT0; - /* timer F/F source is timer 0 ? */ - if (0x00 == (TMM & 0x03)) + CNT1 = 0; + IRR |= INTFT1; + /* timer F/F source is timer 1 ? */ + if (0x01 == (TMM & 0x03)) { TO ^= 1; m_to_func(TO); } - /* timer 1 chained with timer 0 ? */ - if ((TMM & 0xe0) == 0x60) - { - CNT1++; - if (CNT1 == TM1) - { - CNT1 = 0; - IRR |= INTFT1; - /* timer F/F source is timer 1 ? */ - if (0x01 == (TMM & 0x03)) - { - TO ^= 1; - m_to_func(TO); - } - } - } } } + } + } +} + +void upd7810_device::upd7810_handle_timer1(int cycles, int clkdiv) +{ + OVC1 += cycles; + while (OVC1 >= clkdiv) + { + OVC1 -= clkdiv; + CNT1++; + if (CNT1 == TM1) + { + CNT1 = 0; + IRR |= INTFT1; + /* timer F/F source is timer 1 ? */ + if (0x01 == (TMM & 0x03)) + { + TO ^= 1; + m_to_func(TO); + } + } + } +} + +void upd7810_device::handle_timers(int cycles) +{ + /**** TIMER 0 ****/ + if (TMM & 0x10) /* timer 0 upcounter reset ? */ + CNT0 = 0; + else + { + switch (TMM & 0x0c) /* timer 0 clock source */ + { + case 0x00: /* clock divided by 12 */ + upd7810_handle_timer0(cycles, 12); + break; + case 0x04: /* clock divided by 384 */ + upd7810_handle_timer0(cycles, 384); break; case 0x08: /* external signal at TI */ break; @@ -1268,42 +1262,10 @@ void upd7810_device::handle_timers(int cycles) switch (TMM & 0x60) /* timer 1 clock source */ { case 0x00: /* clock divided by 12 */ - OVC1 += cycles; - while (OVC1 >= 12) - { - OVC1 -= 12; - CNT1++; - if (CNT1 == TM1) - { - CNT1 = 0; - IRR |= INTFT1; - /* timer F/F source is timer 1 ? */ - if (0x01 == (TMM & 0x03)) - { - TO ^= 1; - m_to_func(TO); - } - } - } + upd7810_handle_timer1(cycles, 12); break; case 0x20: /* clock divided by 384 */ - OVC1 += cycles; - while (OVC1 >= 384) - { - OVC1 -= 384; - CNT1++; - if (CNT1 == TM1) - { - CNT1 = 0; - IRR |= INTFT1; - /* timer F/F source is timer 1 ? */ - if (0x01 == (TMM & 0x03)) - { - TO ^= 1; - m_to_func(TO); - } - } - } + upd7810_handle_timer1(cycles, 384); break; case 0x40: /* external signal at TI */ break; diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index 916ddbd6eb6..f975c88c7c7 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -169,6 +169,9 @@ protected: virtual void handle_timers(int cycles); virtual void upd7810_take_irq(); + void upd7810_handle_timer0(int cycles, int clkdiv); + void upd7810_handle_timer1(int cycles, int clkdiv); + devcb_write_line m_to_func; devcb_write_line m_txd_func; devcb_read_line m_rxd_func; -- cgit v1.2.3 From 6f8a6d85be6ae94dead72a5bb5d466344ab9eb31 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 16:13:19 +0100 Subject: upd7810: remove code duplication in ETIMER --- src/emu/cpu/upd7810/upd7810.c | 134 ++++++++++-------------------------------- 1 file changed, 30 insertions(+), 104 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index f3b1f907caa..b188fb6f538 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1315,117 +1315,43 @@ void upd7810_device::handle_timers(int cycles) ECNT = 0; break; } - switch (ETMM & 0x30) + /* 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 */ { - case 0x00: /* set CO0 if ECNT == ETM0 */ - if (ETM0 == ECNT) + switch (EOM & 0x0e) { - 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; - } - } - break; - case 0x10: /* prohibited */ - break; - case 0x20: /* set CO0 if ECNT == ETM0 or at falling CI input */ - if (ETM0 == ECNT) - { - 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; - } - } - break; - case 0x30: /* latch CO0 if ECNT == ETM0 or ECNT == ETM1 */ - if (ETM0 == ECNT || ETM1 == ECNT) - { - 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; - } + 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; } - break; } - switch (ETMM & 0xc0) + /* 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 */ { - case 0x00: /* lacth CO1 if ECNT == ETM1 */ - if (ETM1 == ECNT) + switch (EOM & 0xe0) { - 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; - } - } - break; - case 0x40: /* prohibited */ - break; - case 0x80: /* latch CO1 if ECNT == ETM1 or falling edge of CI input */ - if (ETM1 == ECNT) - { - 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; - } - } - break; - case 0xc0: /* latch CO1 if ECNT == ETM0 or ECNT == ETM1 */ - if (ETM0 == ECNT || ETM1 == ECNT) - { - 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; - } + 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; } - break; } } } -- cgit v1.2.3 From 8d227004875941aae47ce9dff30cb25483b25f7b Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Thu, 30 Oct 2014 16:16:04 +0100 Subject: upd7810: set ETIMER interrupts --- src/emu/cpu/upd7810/upd7810.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index b188fb6f538..bc62fa33ffa 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1300,6 +1300,12 @@ void upd7810_device::handle_timers(int cycles) { OVCE -= 12; ECNT++; + /* Interrupt Control Circuit */ + if (ETM0 == ECNT) + IRR |= INTFE0; + if (ETM1 == ECNT) + IRR |= INTFE1; + /* How and When ECNT is Cleared */ switch (ETMM & 0x0c) { case 0x00: /* clear ECNT */ -- cgit v1.2.3