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.
This commit is contained in:
hap 2018-11-03 19:22:12 +01:00
parent 5f2e1268dc
commit bccaa9fa81
4 changed files with 70 additions and 33 deletions

View File

@ -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)
int upcount = 0;
// timer b always counts down
if (timer <= 4)
{
m_m37710_regs[0x46+(timer*2)] = 0;
m_m37710_regs[0x46+(timer*2)+1]++;
}
else
{
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;
}
}

View File

@ -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];

View File

@ -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,

View File

@ -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)