diff options
-rw-r--r-- | src/devices/cpu/tms1000/tms2100.cpp | 72 | ||||
-rw-r--r-- | src/devices/cpu/tms1000/tms2100.h | 14 |
2 files changed, 58 insertions, 28 deletions
diff --git a/src/devices/cpu/tms1000/tms2100.cpp b/src/devices/cpu/tms1000/tms2100.cpp index fc9b16bb3bc..1205431ab34 100644 --- a/src/devices/cpu/tms1000/tms2100.cpp +++ b/src/devices/cpu/tms1000/tms2100.cpp @@ -22,10 +22,10 @@ Extra functions are controlled with the R register (not mapped to pins): - R24: enable interrupts TODO: -- external interrupt (INT pin) - event counter (EC1 pin) - R0-R3 I/O, TRA opcode - A/D converter, TADM opcode +- what happens if decrementer is loaded when IVR is 0? */ @@ -92,9 +92,10 @@ void tms2100_cpu_device::device_start() // zerofill m_ac2 = 0; - m_ivr = 0; + m_ivr = 0xff; m_dec = 0xff; m_il = 0; + m_int_pin = 0; m_int_pending = false; m_r_prev = 0; @@ -113,6 +114,7 @@ void tms2100_cpu_device::device_start() save_item(NAME(m_ivr)); save_item(NAME(m_dec)); save_item(NAME(m_il)); + save_item(NAME(m_int_pin)); save_item(NAME(m_int_pending)); save_item(NAME(m_r_prev)); @@ -147,6 +149,47 @@ void tms2100_cpu_device::device_reset() // interrupt/timer +void tms2100_cpu_device::execute_set_input(int line, int state) +{ + if (line == TMS2100_INPUT_LINE_INT) + { + if (state && !m_int_pin) + { + // load decrementer if it's not counting + if (BIT(m_r, 15) && m_dec == 0xff) + m_dec = m_ivr; + } + m_int_pin = state; + } +} + +void tms2100_cpu_device::clock_decrementer() +{ + if (m_dec != 0xff && --m_dec == 0) + { + // possible pending interrupt + m_int_pending = true; + + // reload decrementer + m_dec = BIT(m_r, 23) ? m_ivr : 0xff; + } +} + +TIMER_CALLBACK_MEMBER(tms2100_cpu_device::prescaler_timeout) +{ + // clock decrementer if internal timer is enabled + if (!BIT(m_r, 18)) + clock_decrementer(); +} + +void tms2100_cpu_device::reset_prescaler() +{ + // prescaler divider is a mask option + static const u16 div[4] = { 32, 128, 256, 1024 }; + attotime period = attotime::from_ticks(div[m_option_dec_div & 3] * 6, clock()); + m_prescaler->adjust(period, 0, period); +} + void tms2100_cpu_device::read_opcode() { // return from interrupt @@ -204,31 +247,8 @@ void tms2100_cpu_device::interrupt() m_cb = 0; m_status = 1; m_il |= 1; -} - -TIMER_CALLBACK_MEMBER(tms2100_cpu_device::prescaler_timeout) -{ - // clock decrementer if internal timer is enabled - if (!BIT(m_r, 18) && m_dec != 0xff) - { - if (--m_dec == 0) - { - // possible pending interrupt - m_int_pending = true; - // reload decrementer - if (BIT(m_r, 23)) - m_dec = m_ivr; - } - } -} - -void tms2100_cpu_device::reset_prescaler() -{ - // prescaler divider is a mask option - static const u16 div[4] = { 32, 128, 256, 1024 }; - attotime period = attotime::from_ticks(div[m_option_dec_div & 3] * 6, clock()); - m_prescaler->adjust(period, 0, period); + standard_irq_callback(0); } diff --git a/src/devices/cpu/tms1000/tms2100.h b/src/devices/cpu/tms1000/tms2100.h index 7d45a0c82c0..7da5a58d1c4 100644 --- a/src/devices/cpu/tms1000/tms2100.h +++ b/src/devices/cpu/tms1000/tms2100.h @@ -13,6 +13,11 @@ #include "tms1100.h" +enum +{ + TMS2100_INPUT_LINE_INT = 0 +}; + // pinout reference @@ -74,12 +79,16 @@ protected: virtual void device_add_mconfig(machine_config &config) override; virtual void device_clock_changed() override { reset_prescaler(); } + virtual u32 execute_input_lines() const noexcept override { return 1; } + virtual void execute_set_input(int line, int state) override; + virtual std::unique_ptr<util::disasm_interface> create_disassembler() override; - virtual void read_opcode() override; - void interrupt(); + void clock_decrementer(); TIMER_CALLBACK_MEMBER(prescaler_timeout); void reset_prescaler(); + virtual void read_opcode() override; + void interrupt(); virtual u8 read_k_input() override; virtual void write_r_output(u32 data) override; @@ -100,6 +109,7 @@ protected: u8 m_ivr; // 8-bit initial value register u8 m_dec; // 8-bit decrementer counter u8 m_il; // interrupt latch(es) + int m_int_pin; // INT pin state bool m_int_pending; u32 m_r_prev; |