diff --git a/src/devices/machine/6840ptm.cpp b/src/devices/machine/6840ptm.cpp index bbf9a57ce18..5117531c767 100644 --- a/src/devices/machine/6840ptm.cpp +++ b/src/devices/machine/6840ptm.cpp @@ -115,7 +115,7 @@ void ptm6840_device::device_start() save_item(NAME(m_t3_divisor)); save_item(NAME(m_t3_scaler)); 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_output)); @@ -142,7 +142,7 @@ void ptm6840_device::device_reset() m_status_reg = 0; m_t3_divisor = 1; m_status_read_since_int = 0; - m_IRQ = 0; + m_irq = 0; m_t3_scaler = 0; for (int i = 0; i < 3; i++) { @@ -175,7 +175,7 @@ void ptm6840_device::subtract_from_counter(int counter, int count) double clock; // 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; } @@ -185,7 +185,7 @@ void ptm6840_device::subtract_from_counter(int counter, int count) } // Dual-byte mode - if (m_control_reg[counter] & 0x04) + if (m_control_reg[counter] & COUNT_MODE_8BIT) { int lsb = m_counter[counter] & 0xff; int msb = m_counter[counter] >> 8; @@ -279,24 +279,24 @@ void ptm6840_device::tick(int counter, int count) void ptm6840_device::update_interrupts() { - int new_state = ((m_status_reg & 0x01) && (m_control_reg[0] & 0x40)) || - ((m_status_reg & 0x02) && (m_control_reg[1] & 0x40)) || - ((m_status_reg & 0x04) && (m_control_reg[2] & 0x40)); + int new_state = ((m_status_reg & TIMER1_IRQ) && (m_control_reg[0] & INTERRUPT_EN)) || + ((m_status_reg & TIMER2_IRQ) && (m_control_reg[1] & INTERRUPT_EN)) || + ((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 { - 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 - if (m_control_reg[counter] & 0x02) + if (m_control_reg[counter] & INTERNAL_CLK_EN) { clock = m_internal_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(); // 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 msb = remaining / divisor; @@ -356,8 +356,12 @@ void ptm6840_device::reload_count(int idx) // Copy the latched value in 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 - if (m_control_reg[idx] & 0x02) + if (m_control_reg[idx] & INTERNAL_CLK_EN) { clock = m_internal_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 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); } @@ -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())); #if 0 - if (!(m_control_reg[idx] & 0x02)) + if (!(m_control_reg[idx] & INTERNAL_CLK_EN)) { if (!m_external_clock[idx]) { @@ -504,9 +508,9 @@ WRITE8_MEMBER( ptm6840_device::write ) case PTM_6840_CTRL1: 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]; - 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_control_reg[idx] = data; @@ -515,7 +519,10 @@ WRITE8_MEMBER( ptm6840_device::write ) PLOG(("value = %04X\n", m_control_reg[idx])); 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 switch (idx) @@ -531,11 +538,12 @@ WRITE8_MEMBER( ptm6840_device::write ) break; } } + // Reset? - if (idx == 0 && (diffs & 0x01)) + if (idx == 0 && (diffs & RESET_TIMERS)) { // Holding reset down - if (data & 0x01) + if (data & RESET_TIMERS) { PLOG(("MC6840 #%s : Timer reset\n", tag())); for (int i = 0; i < 3; i++) @@ -555,12 +563,12 @@ WRITE8_MEMBER( ptm6840_device::write ) m_status_reg = 0; update_interrupts(); + } - // Changing the clock source? (e.g. Zwackery) - if (diffs & 0x02) - { - reload_count(idx); - } + // Changing the clock source? (e.g. Zwackery) + if (diffs & INTERNAL_CLK_EN) + { + reload_count(idx); } break; } @@ -611,9 +619,9 @@ void ptm6840_device::timeout(int idx) m_status_read_since_int &= ~(1 << idx); 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; 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; - if (!(m_control_reg[idx] & 0x02)) + if (!(m_control_reg[idx] & INTERNAL_CLK_EN)) { if (state) { @@ -716,7 +724,7 @@ void ptm6840_device::set_ext_clock(int counter, double 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]) { @@ -732,7 +740,7 @@ void ptm6840_device::set_ext_clock(int counter, double clock) // Determine the number of clock periods before we expire 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); } diff --git a/src/devices/machine/6840ptm.h b/src/devices/machine/6840ptm.h index 5eb1cdd211c..4165bf5db28 100644 --- a/src/devices/machine/6840ptm.h +++ b/src/devices/machine/6840ptm.h @@ -59,7 +59,7 @@ public: template static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast(device).m_irq_cb.set_callback(object); } 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 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 @@ -108,6 +108,25 @@ private: 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_external_clock[3]; @@ -125,7 +144,7 @@ private: UINT8 m_fired[3]; UINT8 m_t3_divisor; UINT8 m_t3_scaler; - UINT8 m_IRQ; + UINT8 m_irq; UINT8 m_status_reg; UINT8 m_status_read_since_int; UINT8 m_lsb_buffer; diff --git a/src/mame/drivers/cmi.cpp b/src/mame/drivers/cmi.cpp index f69e736e861..2279fe5477d 100644 --- a/src/mame/drivers/cmi.cpp +++ b/src/mame/drivers/cmi.cpp @@ -290,6 +290,8 @@ MACHINE_CONFIG_FRAGMENT( cmi01a_device ) 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_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_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_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_IRQ_CB(WRITELINE(cmi01a_device, ch_int)) MACHINE_CONFIG_END machine_config_constructor cmi01a_device::device_mconfig_additions() const @@ -477,6 +482,7 @@ public: DECLARE_READ8_MEMBER( cmi02_r ); DECLARE_WRITE8_MEMBER( cmi02_w ); DECLARE_WRITE8_MEMBER( master_tune_w ); + DECLARE_WRITE_LINE_MEMBER( cmi02_ptm_irq ); // Alphanumeric keyboard DECLARE_READ8_MEMBER( ank_col_r ); @@ -644,6 +650,9 @@ private: // Alphanumeric keyboard int m_ank_irqa; 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 ) { -// printf("CH%d INT: %x %x\n", ch, state, m_int_state[0]); + //printf("CH%d INT: %x\n", m_channel, state); dynamic_cast(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 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); break; } @@ -1877,6 +1886,13 @@ WRITE8_MEMBER( cmi01a_device::cmi01a_ptm_c0 ) 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 ) { if (offset <= 0x1f) @@ -1886,7 +1902,9 @@ READ8_MEMBER( cmi_state::cmi02_r ) for (int i = 0; i < 8; ++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; @@ -2509,6 +2527,7 @@ void cmi_state::machine_reset() m_ank_irqa = 0; m_ank_irqb = 0; m_q133_acia_irq = 0; + m_cmi02_ptm_irq = 0; } 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_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_CLOCK_SIGNAL_HANDLER(WRITELINE(cmi_state, mkbd_acia_clock))