-cmi2x: Fixed channel card memory tests. [Ryan Holtz]

This commit is contained in:
therealmogminer@gmail.com 2016-09-16 13:18:14 +02:00
parent 1927ba1ce1
commit 636a2bbbf4
3 changed files with 85 additions and 38 deletions

View File

@ -115,7 +115,7 @@ void ptm6840_device::device_start()
save_item(NAME(m_t3_divisor)); save_item(NAME(m_t3_divisor));
save_item(NAME(m_t3_scaler)); save_item(NAME(m_t3_scaler));
save_item(NAME(m_internal_clock)); save_item(NAME(m_internal_clock));
save_item(NAME(m_IRQ)); save_item(NAME(m_irq));
save_item(NAME(m_control_reg)); save_item(NAME(m_control_reg));
save_item(NAME(m_output)); save_item(NAME(m_output));
@ -142,7 +142,7 @@ void ptm6840_device::device_reset()
m_status_reg = 0; m_status_reg = 0;
m_t3_divisor = 1; m_t3_divisor = 1;
m_status_read_since_int = 0; m_status_read_since_int = 0;
m_IRQ = 0; m_irq = 0;
m_t3_scaler = 0; m_t3_scaler = 0;
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
{ {
@ -175,7 +175,7 @@ void ptm6840_device::subtract_from_counter(int counter, int count)
double clock; double clock;
// Determine the clock frequency for this timer // Determine the clock frequency for this timer
if (m_control_reg[counter] & 0x02) if (m_control_reg[counter] & INTERNAL_CLK_EN)
{ {
clock = m_internal_clock; clock = m_internal_clock;
} }
@ -185,7 +185,7 @@ void ptm6840_device::subtract_from_counter(int counter, int count)
} }
// Dual-byte mode // Dual-byte mode
if (m_control_reg[counter] & 0x04) if (m_control_reg[counter] & COUNT_MODE_8BIT)
{ {
int lsb = m_counter[counter] & 0xff; int lsb = m_counter[counter] & 0xff;
int msb = m_counter[counter] >> 8; int msb = m_counter[counter] >> 8;
@ -279,24 +279,24 @@ void ptm6840_device::tick(int counter, int count)
void ptm6840_device::update_interrupts() void ptm6840_device::update_interrupts()
{ {
int new_state = ((m_status_reg & 0x01) && (m_control_reg[0] & 0x40)) || int new_state = ((m_status_reg & TIMER1_IRQ) && (m_control_reg[0] & INTERRUPT_EN)) ||
((m_status_reg & 0x02) && (m_control_reg[1] & 0x40)) || ((m_status_reg & TIMER2_IRQ) && (m_control_reg[1] & INTERRUPT_EN)) ||
((m_status_reg & 0x04) && (m_control_reg[2] & 0x40)); ((m_status_reg & TIMER3_IRQ) && (m_control_reg[2] & INTERRUPT_EN));
if (new_state != m_IRQ) if (new_state != m_irq)
{ {
m_IRQ = new_state; m_irq = new_state;
if (m_IRQ) if (m_irq)
{ {
m_status_reg |= 0x80; m_status_reg |= ANY_IRQ;
} }
else else
{ {
m_status_reg &= ~0x80; m_status_reg &= ~ANY_IRQ;
} }
m_irq_cb(m_IRQ); m_irq_cb(m_irq);
} }
} }
@ -318,7 +318,7 @@ UINT16 ptm6840_device::compute_counter( int counter ) const
} }
// determine the clock frequency for this timer // determine the clock frequency for this timer
if (m_control_reg[counter] & 0x02) if (m_control_reg[counter] & INTERNAL_CLK_EN)
{ {
clock = m_internal_clock; clock = m_internal_clock;
PLOG(("MC6840 #%s: %d internal clock freq %f \n", tag(), counter, clock)); PLOG(("MC6840 #%s: %d internal clock freq %f \n", tag(), counter, clock));
@ -332,7 +332,7 @@ UINT16 ptm6840_device::compute_counter( int counter ) const
int remaining = (m_timer[counter]->remaining() * clock).as_double(); int remaining = (m_timer[counter]->remaining() * clock).as_double();
// Adjust the count for dual byte mode // Adjust the count for dual byte mode
if (m_control_reg[counter] & 0x04) if (m_control_reg[counter] & COUNT_MODE_8BIT)
{ {
int divisor = (m_counter[counter] & 0xff) + 1; int divisor = (m_counter[counter] & 0xff) + 1;
int msb = remaining / divisor; int msb = remaining / divisor;
@ -356,8 +356,12 @@ void ptm6840_device::reload_count(int idx)
// Copy the latched value in // Copy the latched value in
m_counter[idx] = m_latch[idx]; m_counter[idx] = m_latch[idx];
// If reset is held, don't start counting
if (m_control_reg[0] & RESET_TIMERS)
return;
// Determine the clock frequency for this timer // Determine the clock frequency for this timer
if (m_control_reg[idx] & 0x02) if (m_control_reg[idx] & INTERNAL_CLK_EN)
{ {
clock = m_internal_clock; clock = m_internal_clock;
PLOG(("MC6840 #%s: %d internal clock freq %f \n", tag(), idx, clock)); PLOG(("MC6840 #%s: %d internal clock freq %f \n", tag(), idx, clock));
@ -370,7 +374,7 @@ void ptm6840_device::reload_count(int idx)
// Determine the number of clock periods before we expire // Determine the number of clock periods before we expire
int count = m_counter[idx]; int count = m_counter[idx];
if (m_control_reg[idx] & 0x04) if (m_control_reg[idx] & COUNT_MODE_8BIT)
{ {
count = ((count >> 8) + 1) * ((count & 0xff) + 1); count = ((count >> 8) + 1) * ((count & 0xff) + 1);
} }
@ -410,7 +414,7 @@ void ptm6840_device::reload_count(int idx)
PLOG(("MC6840 #%s: reload_count(%d): output = %f\n", tag(), idx, duration.as_double())); PLOG(("MC6840 #%s: reload_count(%d): output = %f\n", tag(), idx, duration.as_double()));
#if 0 #if 0
if (!(m_control_reg[idx] & 0x02)) if (!(m_control_reg[idx] & INTERNAL_CLK_EN))
{ {
if (!m_external_clock[idx]) if (!m_external_clock[idx])
{ {
@ -504,9 +508,9 @@ WRITE8_MEMBER( ptm6840_device::write )
case PTM_6840_CTRL1: case PTM_6840_CTRL1:
case PTM_6840_CTRL2: case PTM_6840_CTRL2:
{ {
int idx = (offset == 1) ? 1 : (m_control_reg[1] & 0x01) ? 0 : 2; int idx = (offset == 1) ? 1 : (m_control_reg[1] & CR1_SELECT) ? 0 : 2;
UINT8 diffs = data ^ m_control_reg[idx]; UINT8 diffs = data ^ m_control_reg[idx];
m_t3_divisor = (m_control_reg[2] & 0x01) ? 8 : 1; m_t3_divisor = (m_control_reg[2] & T3_PRESCALE_EN) ? 8 : 1;
m_mode[idx] = (data >> 3) & 0x07; m_mode[idx] = (data >> 3) & 0x07;
m_control_reg[idx] = data; m_control_reg[idx] = data;
@ -515,7 +519,10 @@ WRITE8_MEMBER( ptm6840_device::write )
PLOG(("value = %04X\n", m_control_reg[idx])); PLOG(("value = %04X\n", m_control_reg[idx]));
PLOG(("t3divisor = %d\n", m_t3_divisor)); PLOG(("t3divisor = %d\n", m_t3_divisor));
if (!(m_control_reg[idx] & 0x80 )) if (diffs & INTERRUPT_EN)
update_interrupts();
if (!(m_control_reg[idx] & COUNT_OUT_EN))
{ {
// Output cleared // Output cleared
switch (idx) switch (idx)
@ -531,11 +538,12 @@ WRITE8_MEMBER( ptm6840_device::write )
break; break;
} }
} }
// Reset? // Reset?
if (idx == 0 && (diffs & 0x01)) if (idx == 0 && (diffs & RESET_TIMERS))
{ {
// Holding reset down // Holding reset down
if (data & 0x01) if (data & RESET_TIMERS)
{ {
PLOG(("MC6840 #%s : Timer reset\n", tag())); PLOG(("MC6840 #%s : Timer reset\n", tag()));
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
@ -555,12 +563,12 @@ WRITE8_MEMBER( ptm6840_device::write )
m_status_reg = 0; m_status_reg = 0;
update_interrupts(); update_interrupts();
}
// Changing the clock source? (e.g. Zwackery) // Changing the clock source? (e.g. Zwackery)
if (diffs & 0x02) if (diffs & INTERNAL_CLK_EN)
{ {
reload_count(idx); reload_count(idx);
}
} }
break; break;
} }
@ -611,9 +619,9 @@ void ptm6840_device::timeout(int idx)
m_status_read_since_int &= ~(1 << idx); m_status_read_since_int &= ~(1 << idx);
update_interrupts(); update_interrupts();
if ( m_control_reg[idx] & 0x80 ) if (m_control_reg[idx] & COUNT_OUT_EN)
{ {
if ((m_mode[idx] == 0)||(m_mode[idx] == 2)) if (m_mode[idx] == 0 || m_mode[idx] == 2)
{ {
m_output[idx] = m_output[idx] ? 0 : 1; m_output[idx] = m_output[idx] ? 0 : 1;
PLOG(("**ptm6840 %s t%d output %d **\n", tag(), idx, m_output[idx])); PLOG(("**ptm6840 %s t%d output %d **\n", tag(), idx, m_output[idx]));
@ -694,7 +702,7 @@ void ptm6840_device::set_clock(int idx, int state)
{ {
m_clk[idx] = state; m_clk[idx] = state;
if (!(m_control_reg[idx] & 0x02)) if (!(m_control_reg[idx] & INTERNAL_CLK_EN))
{ {
if (state) if (state)
{ {
@ -716,7 +724,7 @@ void ptm6840_device::set_ext_clock(int counter, double clock)
{ {
m_external_clock[counter] = clock; m_external_clock[counter] = clock;
if (!(m_control_reg[counter] & 0x02)) if (!(m_control_reg[counter] & INTERNAL_CLK_EN))
{ {
if (!m_external_clock[counter]) if (!m_external_clock[counter])
{ {
@ -732,7 +740,7 @@ void ptm6840_device::set_ext_clock(int counter, double clock)
// Determine the number of clock periods before we expire // Determine the number of clock periods before we expire
count = m_counter[counter]; count = m_counter[counter];
if (m_control_reg[counter] & 0x04) if (m_control_reg[counter] & COUNT_MODE_8BIT)
{ {
count = ((count >> 8) + 1) * ((count & 0xff) + 1); count = ((count >> 8) + 1) * ((count & 0xff) + 1);
} }

View File

@ -59,7 +59,7 @@ public:
template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<ptm6840_device &>(device).m_irq_cb.set_callback(object); } template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<ptm6840_device &>(device).m_irq_cb.set_callback(object); }
int status(int clock) const { return m_enabled[clock]; } // get whether timer is enabled int status(int clock) const { return m_enabled[clock]; } // get whether timer is enabled
int irq_state() const { return m_IRQ; } // get IRQ state int irq_state() const { return m_irq; } // get IRQ state
UINT16 count(int counter) const { return compute_counter(counter); } // get counter value UINT16 count(int counter) const { return compute_counter(counter); } // get counter value
void set_ext_clock(int counter, double clock); // set clock frequency void set_ext_clock(int counter, double clock); // set clock frequency
int ext_clock(int counter) const { return m_external_clock[counter]; } // get clock frequency int ext_clock(int counter) const { return m_external_clock[counter]; } // get clock frequency
@ -108,6 +108,25 @@ private:
PTM_6840_LSB3 = 7 PTM_6840_LSB3 = 7
}; };
enum
{
RESET_TIMERS = 0x01,
CR1_SELECT = 0x01,
T3_PRESCALE_EN = 0x01,
INTERNAL_CLK_EN = 0x02,
COUNT_MODE_8BIT = 0x04,
INTERRUPT_EN = 0x40,
COUNT_OUT_EN = 0x80
};
enum
{
TIMER1_IRQ = 0x01,
TIMER2_IRQ = 0x02,
TIMER3_IRQ = 0x04,
ANY_IRQ = 0x80
};
double m_internal_clock; double m_internal_clock;
double m_external_clock[3]; double m_external_clock[3];
@ -125,7 +144,7 @@ private:
UINT8 m_fired[3]; UINT8 m_fired[3];
UINT8 m_t3_divisor; UINT8 m_t3_divisor;
UINT8 m_t3_scaler; UINT8 m_t3_scaler;
UINT8 m_IRQ; UINT8 m_irq;
UINT8 m_status_reg; UINT8 m_status_reg;
UINT8 m_status_read_since_int; UINT8 m_status_read_since_int;
UINT8 m_lsb_buffer; UINT8 m_lsb_buffer;

View File

@ -290,6 +290,8 @@ MACHINE_CONFIG_FRAGMENT( cmi01a_device )
MCFG_DEVICE_ADD("cmi01a_pia_0", PIA6821, 0) // pia_cmi01a_1_config MCFG_DEVICE_ADD("cmi01a_pia_0", PIA6821, 0) // pia_cmi01a_1_config
MCFG_PIA_CA2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_ca2_w)) MCFG_PIA_CA2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_ca2_w))
MCFG_PIA_CB2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_cb2_w)) MCFG_PIA_CB2_HANDLER(WRITELINE(cmi01a_device, cmi01a_1_cb2_w))
MCFG_PIA_IRQA_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_DEVICE_ADD("cmi01a_pia_1", PIA6821, 0) // pia_cmi01a_2_config MCFG_DEVICE_ADD("cmi01a_pia_1", PIA6821, 0) // pia_cmi01a_2_config
MCFG_PIA_READCA1_HANDLER(READLINE(cmi01a_device, zx_r)) MCFG_PIA_READCA1_HANDLER(READLINE(cmi01a_device, zx_r))
@ -300,7 +302,10 @@ MACHINE_CONFIG_FRAGMENT( cmi01a_device )
MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, ch_int)) MCFG_PIA_IRQB_HANDLER(WRITELINE(cmi01a_device, ch_int))
MCFG_DEVICE_ADD("cmi01a_ptm", PTM6840, 0) // ptm_cmi01a_config MCFG_DEVICE_ADD("cmi01a_ptm", PTM6840, 0) // ptm_cmi01a_config
MCFG_PTM6840_INTERNAL_CLOCK(2000000)
MCFG_PTM6840_EXTERNAL_CLOCKS(250000, 500000, 500000)
MCFG_PTM6840_OUT0_CB(WRITE8(cmi01a_device, cmi01a_ptm_c0)) MCFG_PTM6840_OUT0_CB(WRITE8(cmi01a_device, cmi01a_ptm_c0))
MCFG_PTM6840_IRQ_CB(WRITELINE(cmi01a_device, ch_int))
MACHINE_CONFIG_END MACHINE_CONFIG_END
machine_config_constructor cmi01a_device::device_mconfig_additions() const machine_config_constructor cmi01a_device::device_mconfig_additions() const
@ -477,6 +482,7 @@ public:
DECLARE_READ8_MEMBER( cmi02_r ); DECLARE_READ8_MEMBER( cmi02_r );
DECLARE_WRITE8_MEMBER( cmi02_w ); DECLARE_WRITE8_MEMBER( cmi02_w );
DECLARE_WRITE8_MEMBER( master_tune_w ); DECLARE_WRITE8_MEMBER( master_tune_w );
DECLARE_WRITE_LINE_MEMBER( cmi02_ptm_irq );
// Alphanumeric keyboard // Alphanumeric keyboard
DECLARE_READ8_MEMBER( ank_col_r ); DECLARE_READ8_MEMBER( ank_col_r );
@ -644,6 +650,9 @@ private:
// Alphanumeric keyboard // Alphanumeric keyboard
int m_ank_irqa; int m_ank_irqa;
int m_ank_irqb; int m_ank_irqb;
// Master card (CMI-02)
int m_cmi02_ptm_irq;
}; };
/************************************** /**************************************
@ -1639,7 +1648,7 @@ WRITE_LINE_MEMBER( cmi01a_device::cmi01a_1_ca2_w )
WRITE_LINE_MEMBER( cmi01a_device::ch_int ) WRITE_LINE_MEMBER( cmi01a_device::ch_int )
{ {
// printf("CH%d INT: %x %x\n", ch, state, m_int_state[0]); //printf("CH%d INT: %x\n", m_channel, state);
dynamic_cast<cmi_state*>(owner())->set_interrupt(CPU_1, ch_int_levels[m_channel], state ? ASSERT_LINE : CLEAR_LINE); dynamic_cast<cmi_state*>(owner())->set_interrupt(CPU_1, ch_int_levels[m_channel], state ? ASSERT_LINE : CLEAR_LINE);
} }
@ -1819,7 +1828,7 @@ WRITE8_MEMBER( cmi01a_device::write )
int a1 = (m_ptm_output && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2)); int a1 = (m_ptm_output && BIT(offset, 3)) || (!BIT(offset, 3) && BIT(offset, 2));
int a2 = BIT(offset, 1); int a2 = BIT(offset, 1);
//printf("CH%d PTM: [%x] %x\n", ch, (a2 << 2) | (a1 << 1) | a0, data); //printf("CH%d PTM: [%x] %x, %d %d %d, %02x\n", m_channel, (a2 << 2) | (a1 << 1) | a0, data, a2, a1, a0, offset);
m_ptm->write(space, (a2 << 2) | (a1 << 1) | a0, data); m_ptm->write(space, (a2 << 2) | (a1 << 1) | a0, data);
break; break;
} }
@ -1877,6 +1886,13 @@ WRITE8_MEMBER( cmi01a_device::cmi01a_ptm_c0 )
m_ptm_output = data; m_ptm_output = data;
} }
WRITE_LINE_MEMBER( cmi_state::cmi02_ptm_irq )
{
m_cmi02_ptm_irq = state;
set_interrupt(CPU_1, IRQ_TIMINT_LEVEL, m_cmi02_ptm_irq ? ASSERT_LINE : CLEAR_LINE);
//printf("CMI-02 PTM IRQ: %d\n", state);
}
READ8_MEMBER( cmi_state::cmi02_r ) READ8_MEMBER( cmi_state::cmi02_r )
{ {
if (offset <= 0x1f) if (offset <= 0x1f)
@ -1886,7 +1902,9 @@ READ8_MEMBER( cmi_state::cmi02_r )
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
if (ch_mask & (1 << i)) if (ch_mask & (1 << i))
return m_channels[i]->read(space, i, offset & 0x1f); {
return m_channels[i]->read(space, offset & 0x1f, 0xff);
}
} }
return 0xff; return 0xff;
@ -2509,6 +2527,7 @@ void cmi_state::machine_reset()
m_ank_irqa = 0; m_ank_irqa = 0;
m_ank_irqb = 0; m_ank_irqb = 0;
m_q133_acia_irq = 0; m_q133_acia_irq = 0;
m_cmi02_ptm_irq = 0;
} }
void cmi_state::machine_start() void cmi_state::machine_start()
@ -2636,6 +2655,7 @@ static MACHINE_CONFIG_START( cmi2x, cmi_state )
MCFG_DEVICE_ADD("cmi02_ptm", PTM6840, 0) // ptm_cmi02_config MCFG_DEVICE_ADD("cmi02_ptm", PTM6840, 0) // ptm_cmi02_config
MCFG_PTM6840_INTERNAL_CLOCK(2000000) // TODO MCFG_PTM6840_INTERNAL_CLOCK(2000000) // TODO
MCFG_PTM6840_IRQ_CB(WRITELINE(cmi_state, cmi02_ptm_irq))
MCFG_DEVICE_ADD("mkbd_acia_clock", CLOCK, 9600*16) MCFG_DEVICE_ADD("mkbd_acia_clock", CLOCK, 9600*16)
MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(cmi_state, mkbd_acia_clock)) MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(cmi_state, mkbd_acia_clock))