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 */ /* 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 // maskable
0x6f, // DMA3 0 0x6f, // DMA3 0
@ -183,7 +183,7 @@ const int m37710_cpu_device::m37710_irq_levels[M37710_LINE_MAX] =
0, // reset 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 // maskable
0xffce, // DMA3 0xffce, // DMA3
@ -375,20 +375,31 @@ void m37710_cpu_device::m37710_external_tick(int timer, int state)
return; return;
} }
// check if enabled // check if enabled and in event counter mode
if (m_m37710_regs[0x40] & (1<<timer)) if (m_m37710_regs[0x40] & (1<<timer))
{ {
if ((m_m37710_regs[0x56+timer] & 0x3) == 1) 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; if (m_m37710_regs[0x56+timer] & 0x10)
m_m37710_regs[0x46+(timer*2)+1]++; {
} // up/down determined by timer out pin
else upcount = m_timer_out[timer];
{ }
m_m37710_regs[0x46+(timer*2)]++; 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 else
{ {
@ -756,7 +767,7 @@ void m37710_cpu_device::m37710i_update_irqs()
int wantedIRQ = -1; int wantedIRQ = -1;
int curpri = 0; 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))) 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_timers[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(m37710_cpu_device::m37710_timer_cb), this));
m_reload[i] = attotime::never; m_reload[i] = attotime::never;
m_timer_out[i] = 0;
} }
save_item(NAME(m_a)); 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[5]));
save_item(NAME(m_reload[6])); save_item(NAME(m_reload[6]));
save_item(NAME(m_reload[7])); 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))); 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); m37710_set_irq_line(inputnum, state);
break; break;
case M37710_LINE_TIMERA0TICK: case M37710_LINE_TIMERA0IN:
case M37710_LINE_TIMERA1TICK: case M37710_LINE_TIMERA1IN:
case M37710_LINE_TIMERA2TICK: case M37710_LINE_TIMERA2IN:
case M37710_LINE_TIMERA3TICK: case M37710_LINE_TIMERA3IN:
case M37710_LINE_TIMERA4TICK: case M37710_LINE_TIMERA4IN:
case M37710_LINE_TIMERB0TICK: case M37710_LINE_TIMERB0IN:
case M37710_LINE_TIMERB1TICK: case M37710_LINE_TIMERB1IN:
case M37710_LINE_TIMERB2TICK: case M37710_LINE_TIMERB2IN:
m37710_external_tick(inputnum - M37710_LINE_TIMERA0TICK, state); 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; break;
} }
} }

View File

@ -55,18 +55,30 @@ enum
M37710_LINE_RESET, M37710_LINE_RESET,
// these are not interrupts, they're signals external hardware can send // these are not interrupts, they're signals external hardware can send
M37710_LINE_TIMERA0TICK, M37710_LINE_TIMERA0IN,
M37710_LINE_TIMERA1TICK, M37710_LINE_TIMERA1IN,
M37710_LINE_TIMERA2TICK, M37710_LINE_TIMERA2IN,
M37710_LINE_TIMERA3TICK, M37710_LINE_TIMERA3IN,
M37710_LINE_TIMERA4TICK, M37710_LINE_TIMERA4IN,
M37710_LINE_TIMERB0TICK, M37710_LINE_TIMERB0IN,
M37710_LINE_TIMERB1TICK, M37710_LINE_TIMERB1IN,
M37710_LINE_TIMERB2TICK, 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 M37710_LINE_MAX
}; };
#define M37710_INTERRUPT_MAX (M37710_LINE_RESET + 1)
/* Registers - used by m37710_set_reg() and m37710_get_reg() */ /* Registers - used by m37710_set_reg() and m37710_get_reg() */
enum enum
{ {
@ -178,6 +190,7 @@ private:
uint8_t m_m37710_regs[128]; uint8_t m_m37710_regs[128];
attotime m_reload[8]; attotime m_reload[8];
emu_timer *m_timers[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_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_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; 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 void (m37710_cpu_device::*set_line_func)(int line, int state);
typedef int (m37710_cpu_device::*execute_func)(int cycles); typedef int (m37710_cpu_device::*execute_func)(int cycles);
static const int m37710_irq_levels[M37710_LINE_MAX]; static const int m37710_irq_levels[M37710_INTERRUPT_MAX];
static const int m37710_irq_vectors[M37710_LINE_MAX]; static const int m37710_irq_vectors[M37710_INTERRUPT_MAX];
static const char *const m37710_rnames[128]; static const char *const m37710_rnames[128];
static const char *const m37710_tnames[8]; static const char *const m37710_tnames[8];
static const opcode_func *const m37710i_opcodes[4]; static const opcode_func *const m37710i_opcodes[4];

View File

@ -43,7 +43,7 @@ enum line_state
enum enum
{ {
// input lines // input lines
MAX_INPUT_LINES = 32+3, MAX_INPUT_LINES = 64+3,
INPUT_LINE_IRQ0 = 0, INPUT_LINE_IRQ0 = 0,
INPUT_LINE_IRQ1 = 1, INPUT_LINE_IRQ1 = 1,
INPUT_LINE_IRQ2 = 2, 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) 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) 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) 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) TIMER_DEVICE_CALLBACK_MEMBER(namcos22_state::adillor_trackball_update)