summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author hap <happppp@users.noreply.github.com>2022-08-16 01:24:37 +0200
committer hap <happppp@users.noreply.github.com>2022-08-16 01:24:37 +0200
commit179e9b16a0665e7e98cafb38dda7e0a3d3219131 (patch)
treeb1806d4f4c9fd86fd7c52b786d8faf189e2999e8
parent57635c250c6da23a2358d846754d7329a53fc2cf (diff)
tms2100: add interrupt pin
-rw-r--r--src/devices/cpu/tms1000/tms2100.cpp72
-rw-r--r--src/devices/cpu/tms1000/tms2100.h14
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;