summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2018-11-03 19:22:12 +0100
committer hap <happppp@users.noreply.github.com>2018-11-03 19:22:28 +0100
commitbccaa9fa81f3e18c41684e07e1c5517b9ba9460a (patch)
treed2197fbebda56b17a3e7c3bc2b308eb23b842a36
parent5f2e1268dcf07a6039d0be0ce76e101171c7fc40 (diff)
m37710: added basic support for up-down count on timers in event counter mode (nw)
NOTE1: namcos22 propcycl always pedals backwards now, will resolve in next commit. NOTE2: diexec.h MAX_INPUT_LINES had to be increased, even without this commit m37710 was already more than 32 input lines.
-rw-r--r--src/devices/cpu/m37710/m37710.cpp64
-rw-r--r--src/devices/cpu/m37710/m37710.h33
-rw-r--r--src/emu/diexec.h2
-rw-r--r--src/mame/drivers/namcos22.cpp4
4 files changed, 70 insertions, 33 deletions
diff --git a/src/devices/cpu/m37710/m37710.cpp b/src/devices/cpu/m37710/m37710.cpp
index 86470acd453..3db1605c5c0 100644
--- a/src/devices/cpu/m37710/m37710.cpp
+++ b/src/devices/cpu/m37710/m37710.cpp
@@ -151,7 +151,7 @@ std::vector<std::pair<int, const address_space_config *>> m37710_cpu_device::mem
/* interrupt control mapping */
-const int m37710_cpu_device::m37710_irq_levels[M37710_LINE_MAX] =
+const int m37710_cpu_device::m37710_irq_levels[M37710_INTERRUPT_MAX] =
{
// maskable
0x6f, // DMA3 0
@@ -183,7 +183,7 @@ const int m37710_cpu_device::m37710_irq_levels[M37710_LINE_MAX] =
0, // reset
};
-const int m37710_cpu_device::m37710_irq_vectors[M37710_LINE_MAX] =
+const int m37710_cpu_device::m37710_irq_vectors[M37710_INTERRUPT_MAX] =
{
// maskable
0xffce, // DMA3
@@ -375,20 +375,31 @@ void m37710_cpu_device::m37710_external_tick(int timer, int state)
return;
}
- // check if enabled
+ // check if enabled and in event counter mode
if (m_m37710_regs[0x40] & (1<<timer))
{
if ((m_m37710_regs[0x56+timer] & 0x3) == 1)
{
- if (m_m37710_regs[0x46+(timer*2)] == 0xff)
- {
- m_m37710_regs[0x46+(timer*2)] = 0;
- m_m37710_regs[0x46+(timer*2)+1]++;
- }
- else
+ int upcount = 0;
+
+ // timer b always counts down
+ if (timer <= 4)
{
- m_m37710_regs[0x46+(timer*2)]++;
+ if (m_m37710_regs[0x56+timer] & 0x10)
+ {
+ // up/down determined by timer out pin
+ upcount = m_timer_out[timer];
+ }
+ else
+ upcount = m_m37710_regs[0x44] >> timer & 1;
}
+
+ int incval = (upcount) ? 1 : -1;
+ int edgeval = (upcount) ? 0xff : 0x00;
+
+ if (m_m37710_regs[0x46+(timer*2)] == edgeval)
+ m_m37710_regs[0x46+(timer*2)+1] += incval;
+ m_m37710_regs[0x46+(timer*2)] += incval;
}
else
{
@@ -756,7 +767,7 @@ void m37710_cpu_device::m37710i_update_irqs()
int wantedIRQ = -1;
int curpri = 0;
- for (curirq = M37710_LINE_MAX - 1; curirq >= 0; curirq--)
+ for (curirq = M37710_INTERRUPT_MAX - 1; curirq >= 0; curirq--)
{
if ((pending & (1 << curirq)))
{
@@ -1014,6 +1025,7 @@ void m37710_cpu_device::device_start()
{
m_timers[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m37710_cpu_device::m37710_timer_cb), this));
m_reload[i] = attotime::never;
+ m_timer_out[i] = 0;
}
save_item(NAME(m_a));
@@ -1058,6 +1070,7 @@ void m37710_cpu_device::device_start()
save_item(NAME(m_reload[5]));
save_item(NAME(m_reload[6]));
save_item(NAME(m_reload[7]));
+ save_item(NAME(m_timer_out));
machine().save().register_postload(save_prepost_delegate(save_prepost_delegate(FUNC(m37710_cpu_device::m37710_restore_state), this)));
@@ -1178,15 +1191,26 @@ void m37710_cpu_device::execute_set_input(int inputnum, int state)
m37710_set_irq_line(inputnum, state);
break;
- case M37710_LINE_TIMERA0TICK:
- case M37710_LINE_TIMERA1TICK:
- case M37710_LINE_TIMERA2TICK:
- case M37710_LINE_TIMERA3TICK:
- case M37710_LINE_TIMERA4TICK:
- case M37710_LINE_TIMERB0TICK:
- case M37710_LINE_TIMERB1TICK:
- case M37710_LINE_TIMERB2TICK:
- m37710_external_tick(inputnum - M37710_LINE_TIMERA0TICK, state);
+ case M37710_LINE_TIMERA0IN:
+ case M37710_LINE_TIMERA1IN:
+ case M37710_LINE_TIMERA2IN:
+ case M37710_LINE_TIMERA3IN:
+ case M37710_LINE_TIMERA4IN:
+ case M37710_LINE_TIMERB0IN:
+ case M37710_LINE_TIMERB1IN:
+ case M37710_LINE_TIMERB2IN:
+ m37710_external_tick(inputnum - M37710_LINE_TIMERA0IN, state);
+ break;
+
+ case M37710_LINE_TIMERA0OUT:
+ case M37710_LINE_TIMERA1OUT:
+ case M37710_LINE_TIMERA2OUT:
+ case M37710_LINE_TIMERA3OUT:
+ case M37710_LINE_TIMERA4OUT:
+ case M37710_LINE_TIMERB0OUT:
+ case M37710_LINE_TIMERB1OUT:
+ case M37710_LINE_TIMERB2OUT:
+ m_timer_out[inputnum - M37710_LINE_TIMERA0OUT] = state ? 1 : 0;
break;
}
}
diff --git a/src/devices/cpu/m37710/m37710.h b/src/devices/cpu/m37710/m37710.h
index c96301013b6..7592b5edabe 100644
--- a/src/devices/cpu/m37710/m37710.h
+++ b/src/devices/cpu/m37710/m37710.h
@@ -55,18 +55,30 @@ enum
M37710_LINE_RESET,
// these are not interrupts, they're signals external hardware can send
- M37710_LINE_TIMERA0TICK,
- M37710_LINE_TIMERA1TICK,
- M37710_LINE_TIMERA2TICK,
- M37710_LINE_TIMERA3TICK,
- M37710_LINE_TIMERA4TICK,
- M37710_LINE_TIMERB0TICK,
- M37710_LINE_TIMERB1TICK,
- M37710_LINE_TIMERB2TICK,
+ M37710_LINE_TIMERA0IN,
+ M37710_LINE_TIMERA1IN,
+ M37710_LINE_TIMERA2IN,
+ M37710_LINE_TIMERA3IN,
+ M37710_LINE_TIMERA4IN,
+ M37710_LINE_TIMERB0IN,
+ M37710_LINE_TIMERB1IN,
+ M37710_LINE_TIMERB2IN,
+
+ M37710_LINE_TIMERA0OUT,
+ M37710_LINE_TIMERA1OUT,
+ M37710_LINE_TIMERA2OUT,
+ M37710_LINE_TIMERA3OUT,
+ M37710_LINE_TIMERA4OUT,
+ M37710_LINE_TIMERB0OUT,
+ M37710_LINE_TIMERB1OUT,
+ M37710_LINE_TIMERB2OUT,
M37710_LINE_MAX
};
+#define M37710_INTERRUPT_MAX (M37710_LINE_RESET + 1)
+
+
/* Registers - used by m37710_set_reg() and m37710_get_reg() */
enum
{
@@ -178,6 +190,7 @@ private:
uint8_t m_m37710_regs[128];
attotime m_reload[8];
emu_timer *m_timers[8];
+ int m_timer_out[8];
uint32_t m_dma0_src, m_dma0_dst, m_dma0_cnt, m_dma0_mode;
uint32_t m_dma1_src, m_dma1_dst, m_dma1_cnt, m_dma1_mode;
uint32_t m_dma2_src, m_dma2_dst, m_dma2_cnt, m_dma2_mode;
@@ -198,8 +211,8 @@ private:
typedef void (m37710_cpu_device::*set_line_func)(int line, int state);
typedef int (m37710_cpu_device::*execute_func)(int cycles);
- static const int m37710_irq_levels[M37710_LINE_MAX];
- static const int m37710_irq_vectors[M37710_LINE_MAX];
+ static const int m37710_irq_levels[M37710_INTERRUPT_MAX];
+ static const int m37710_irq_vectors[M37710_INTERRUPT_MAX];
static const char *const m37710_rnames[128];
static const char *const m37710_tnames[8];
static const opcode_func *const m37710i_opcodes[4];
diff --git a/src/emu/diexec.h b/src/emu/diexec.h
index 6192264f62e..e44c75778d4 100644
--- a/src/emu/diexec.h
+++ b/src/emu/diexec.h
@@ -43,7 +43,7 @@ enum line_state
enum
{
// input lines
- MAX_INPUT_LINES = 32+3,
+ MAX_INPUT_LINES = 64+3,
INPUT_LINE_IRQ0 = 0,
INPUT_LINE_IRQ1 = 1,
INPUT_LINE_IRQ2 = 2,
diff --git a/src/mame/drivers/namcos22.cpp b/src/mame/drivers/namcos22.cpp
index a625242023b..ea4e4905c85 100644
--- a/src/mame/drivers/namcos22.cpp
+++ b/src/mame/drivers/namcos22.cpp
@@ -3025,7 +3025,7 @@ void namcos22_state::alpine_io_map(address_map &map)
TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_interrupt)
{
- m_mcu->pulse_input_line(M37710_LINE_TIMERA3TICK, m_mcu->minimum_quantum_time());
+ m_mcu->pulse_input_line(M37710_LINE_TIMERA3IN, m_mcu->minimum_quantum_time());
}
TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_update)
@@ -3060,7 +3060,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::propcycl_pedal_update)
TIMER_CALLBACK_MEMBER(namcos22_state::adillor_trackball_interrupt)
{
- m_mcu->pulse_input_line(param ? M37710_LINE_TIMERA2TICK : M37710_LINE_TIMERA3TICK, m_mcu->minimum_quantum_time());
+ m_mcu->pulse_input_line(param ? M37710_LINE_TIMERA2IN : M37710_LINE_TIMERA3IN, m_mcu->minimum_quantum_time());
}
TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::adillor_trackball_update)