summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/cpu.lua2
-rw-r--r--src/devices/cpu/tlcs900/tlcs900.cpp2
-rw-r--r--src/devices/cpu/tlcs900/tlcs900.h7
-rw-r--r--src/devices/cpu/tlcs900/tmp94c241.cpp1332
-rw-r--r--src/devices/cpu/tlcs900/tmp94c241.h279
-rw-r--r--src/devices/cpu/tlcs900/tmp95c061.cpp67
-rw-r--r--src/devices/cpu/tlcs900/tmp95c061.h3
-rw-r--r--src/devices/cpu/tlcs900/tmp95c063.cpp65
-rw-r--r--src/devices/cpu/tlcs900/tmp95c063.h3
-rw-r--r--src/mame/matsushita/kn5000.cpp75
10 files changed, 1745 insertions, 90 deletions
diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua
index 99bb9efb18b..51d8e1b17b5 100644
--- a/scripts/src/cpu.lua
+++ b/scripts/src/cpu.lua
@@ -2982,6 +2982,8 @@ if CPUS["TLCS900"] then
MAME_DIR .. "src/devices/cpu/tlcs900/tlcs900.h",
MAME_DIR .. "src/devices/cpu/tlcs900/900tbl.hxx",
MAME_DIR .. "src/devices/cpu/tlcs900/900htbl.hxx",
+ MAME_DIR .. "src/devices/cpu/tlcs900/tmp94c241.cpp",
+ MAME_DIR .. "src/devices/cpu/tlcs900/tmp94c241.h",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.cpp",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c061.h",
MAME_DIR .. "src/devices/cpu/tlcs900/tmp95c063.cpp",
diff --git a/src/devices/cpu/tlcs900/tlcs900.cpp b/src/devices/cpu/tlcs900/tlcs900.cpp
index 2b2c4653b3c..ac8bfaf78fc 100644
--- a/src/devices/cpu/tlcs900/tlcs900.cpp
+++ b/src/devices/cpu/tlcs900/tlcs900.cpp
@@ -138,7 +138,7 @@ void tlcs900_device::device_start()
save_item( NAME(m_dmac) );
save_item( NAME(m_dmam) );
save_item( NAME(m_timer_pre) );
- save_item( NAME(m_timer) );
+ save_item( NAME(m_timer_8) );
save_item( NAME(m_timer_change) );
save_item( NAME(m_level) );
save_item( NAME(m_check_irqs) );
diff --git a/src/devices/cpu/tlcs900/tlcs900.h b/src/devices/cpu/tlcs900/tlcs900.h
index a3ce3d5fa67..36feca4e7b1 100644
--- a/src/devices/cpu/tlcs900/tlcs900.h
+++ b/src/devices/cpu/tlcs900/tlcs900.h
@@ -20,6 +20,9 @@ enum tlcs900_inputs
TLCS900_INT6,
TLCS900_INT7,
TLCS900_INT8,
+ TLCS900_INT9,
+ TLCS900_INTA,
+ TLCS900_INTB,
TLCS900_TIO,
TLCS900_NUM_INPUTS
};
@@ -102,8 +105,8 @@ protected:
/* Internal timers, irqs, etc */
uint32_t m_timer_pre;
- uint8_t m_timer[6];
- int m_timer_change[4];
+ uint8_t m_timer_8[6];
+ int m_timer_change[8];
bool m_prefetch_clear;
uint8_t m_prefetch_index;
uint8_t m_prefetch[4];
diff --git a/src/devices/cpu/tlcs900/tmp94c241.cpp b/src/devices/cpu/tlcs900/tmp94c241.cpp
new file mode 100644
index 00000000000..bf76eaa5897
--- /dev/null
+++ b/src/devices/cpu/tlcs900/tmp94c241.cpp
@@ -0,0 +1,1332 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR,Felipe Sanches
+/****************************************************************************
+
+ Toshiba TMP94C241 microcontroller
+
+****************************************************************************/
+
+#include "emu.h"
+#include "tmp94c241.h"
+#include "dasm900.h"
+
+//**************************************************************************
+// GLOBAL VARIABLES
+//**************************************************************************
+
+// device type definition
+DEFINE_DEVICE_TYPE(TMP94C241, tmp94c241_device, "tmp94c241", "Toshiba TMP94C241")
+
+enum
+{
+ INTE45,
+ INTE67,
+ INTE89,
+ INTEAB,
+ INTET01,
+ INTET23,
+ INTET45,
+ INTET67,
+ INTET89,
+ INTETAB,
+ INTES0,
+ INTES1,
+ INTETC01,
+ INTETC23,
+ INTETC45,
+ INTETC67,
+ INTE0AD,
+ INTNMWDT
+};
+
+static const struct {
+ uint8_t reg;
+ uint8_t iff;
+ uint8_t vector;
+ uint8_t dma_start_vector;
+} tmp94c241_irq_vector_map[] =
+{
+ { INTE0AD, 0x08, 0x28, 0x0a}, // INT0 Pin
+ { INTE45, 0x08, 0x2c, 0x0b}, // INT4 Pin
+ { INTE45, 0x80, 0x30, 0x0c}, // INT5 Pin
+ { INTE67, 0x08, 0x34, 0x0d}, // INT6 Pin
+ { INTE67, 0x80, 0x38, 0x0e}, // INT7 Pin
+ // 0x3c - reserved
+ { INTE89, 0x08, 0x40, 0x10}, // INT8 Pin
+ { INTE89, 0x80, 0x44, 0x11}, // INT9 Pin
+ { INTEAB, 0x08, 0x48, 0x12}, // INTA Pin
+ { INTEAB, 0x80, 0x4c, 0x13}, // INTB Pin
+ { INTET01, 0x08, 0x50, 0x14}, // INTT0: 8-bit timer (Timer 0)
+ { INTET01, 0x80, 0x54, 0x15}, // INTT1: 8-bit timer (Timer 1)
+ { INTET23, 0x08, 0x58, 0x16}, // INTT2: 8-bit timer (Timer 2)
+ { INTET23, 0x80, 0x5c, 0x17}, // INTT3: 8-bit timer (Timer 3)
+ { INTET45, 0x08, 0x60, 0x18}, // INTTR4: 16-bit timer (Treg 4)
+ { INTET45, 0x80, 0x64, 0x19}, // INTTR5: 16-bit timer (Treg 5)
+ { INTET67, 0x08, 0x68, 0x1a}, // INTTR6: 16-bit timer (Treg 6)
+ { INTET67, 0x80, 0x6c, 0x1b}, // INTTR7: 16-bit timer (Treg 7)
+ { INTET89, 0x08, 0x70, 0x1c}, // INTTR8: 16-bit timer (Treg 8)
+ { INTET89, 0x80, 0x74, 0x1d}, // INTTR9: 16-bit timer (Treg 9)
+ { INTETAB, 0x08, 0x78, 0x1e}, // INTTRA: 16-bit timer (Treg A)
+ { INTETAB, 0x80, 0x7c, 0x1f}, // INTTRB: 16-bit timer (Treg B)
+ { INTES0, 0x08, 0x80, 0x20}, // INTRX0: Serial receive 0
+ { INTES0, 0x80, 0x84, 0x21}, // INTTX0: Serial send 0
+ { INTES1, 0x08, 0x88, 0x22}, // INTRX1: Serial receive 1
+ { INTES1, 0x80, 0x8c, 0x23}, // INTTX1: Serial send 1
+ { INTE0AD, 0x80, 0x90, 0x24}, // INTAD: AD conversion completion
+ { INTETC01, 0x08, 0x94, 0x25}, // INTTC0: micro-DMA completion Ch.0
+ { INTETC01, 0x80, 0x98, 0x26}, // INTTC1: micro-DMA completion Ch.1
+ { INTETC23, 0x08, 0x9c, 0x27}, // INTTC2: micro-DMA completion Ch.2
+ { INTETC23, 0x80, 0xa0, 0x28}, // INTTC3: micro-DMA completion Ch.3
+ { INTETC45, 0x08, 0xa4, 0x29}, // INTTC4: micro-DMA completion Ch.4
+ { INTETC45, 0x80, 0xa8, 0x2a}, // INTTC5: micro-DMA completion Ch.5
+ { INTETC67, 0x08, 0xac, 0x2b}, // INTTC6: micro-DMA completion Ch.6
+ { INTETC67, 0x80, 0xb0, 0x2c}, // INTTC7: micro-DMA completion Ch.7
+ /* 0xb4 ... 0xfc (Reserved) */
+};
+static constexpr u8 NUM_MASKABLE_IRQS = sizeof(tmp94c241_irq_vector_map) / 4;
+
+
+//**************************************************************************
+// DEVICE CONSTRUCTION AND INITIALIZATION
+//**************************************************************************
+
+//-------------------------------------------------
+// tmp94c241_device - constructor
+//-------------------------------------------------
+
+tmp94c241_device::tmp94c241_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ tlcs900h_device(mconfig, TMP94C241, tag, owner, clock),
+ m_an_read(*this, 0),
+ m_port_read(*this, 0),
+ m_port_write(*this),
+ m_port_latch{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_port_control{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_port_function{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_timer_flipflops{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_t8run(0),
+ m_t01mod(0),
+ m_t23mod(0),
+ m_t4mod(0),
+ m_t6mod(0),
+ m_t8mod(0),
+ m_tamod(0),
+ m_tffcr(0),
+ m_t4ffcr(0),
+ m_t6ffcr(0),
+ m_t8ffcr(0),
+ m_taffcr(0),
+ m_trdc(0),
+ m_t16run(0),
+ m_treg_8{ 0, 0, 0, 0 },
+ m_treg_16{ 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_t16_cap{ 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_timer_16{ 0, 0, 0, 0 },
+ m_watchdog_mode(0),
+ m_serial_control{ 0, 0 },
+ m_serial_mode{ 0, 0 },
+ m_baud_rate{ 0, 0 },
+ m_od_enable(0),
+ m_ad_mode1(0),
+ m_ad_mode2(0),
+ m_ad_result{ 0, 0, 0, 0 },
+ m_int_reg{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ m_iimc(0),
+ m_dma_vector{ 0, 0, 0, 0 },
+ m_block_cs{ 0, 0, 0, 0 },
+ m_external_cs(0),
+ m_msar{ 0, 0, 0, 0, 0, 0 },
+ m_mamr{ 0, 0, 0, 0, 0, 0 },
+ m_dram_refresh{ 0, 0 },
+ m_dram_access{ 0, 0 },
+ m_da_drive(0)
+{
+}
+
+//-------------------------------------------------
+// device_config_complete - device-specific startup
+//-------------------------------------------------
+
+void tmp94c241_device::device_config_complete()
+{
+ if (m_am8_16 == 0)
+ m_program_config = address_space_config("program", ENDIANNESS_LITTLE, 16, 24, 0, address_map_constructor(FUNC(tmp94c241_device::internal_mem), this));
+ else
+ m_program_config = address_space_config("program", ENDIANNESS_LITTLE, 8, 24, 0, address_map_constructor(FUNC(tmp94c241_device::internal_mem), this));
+}
+
+
+void tmp94c241_device::device_resolve_objects()
+{
+ m_nmi_state = CLEAR_LINE;
+ for (int i = 0; i < TLCS900_NUM_INPUTS; i++)
+ {
+ m_level[i] = CLEAR_LINE;
+ }
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void tmp94c241_device::device_start()
+{
+ tlcs900h_device::device_start();
+
+ save_item(NAME(m_port_latch));
+ save_item(NAME(m_port_control));
+ save_item(NAME(m_port_function));
+ save_item(NAME(m_timer_flipflops));
+ save_item(NAME(m_t8run));
+ save_item(NAME(m_t01mod));
+ save_item(NAME(m_t23mod));
+ save_item(NAME(m_t4mod));
+ save_item(NAME(m_t6mod));
+ save_item(NAME(m_t8mod));
+ save_item(NAME(m_tamod));
+ save_item(NAME(m_trdc));
+ save_item(NAME(m_treg_8));
+ save_item(NAME(m_treg_16));
+ save_item(NAME(m_t16_cap));
+ save_item(NAME(m_tffcr));
+ save_item(NAME(m_t4ffcr));
+ save_item(NAME(m_t6ffcr));
+ save_item(NAME(m_t8ffcr));
+ save_item(NAME(m_taffcr));
+ save_item(NAME(m_t16run));
+ save_item(NAME(m_watchdog_mode));
+ save_item(NAME(m_serial_control));
+ save_item(NAME(m_serial_mode));
+ save_item(NAME(m_baud_rate));
+ save_item(NAME(m_od_enable));
+ save_item(NAME(m_ad_mode1));
+ save_item(NAME(m_ad_mode2));
+ save_item(NAME(m_ad_result));
+ save_item(NAME(m_int_reg));
+ save_item(NAME(m_iimc));
+ save_item(NAME(m_dma_vector));
+ save_item(NAME(m_block_cs));
+ save_item(NAME(m_external_cs));
+ save_item(NAME(m_msar));
+ save_item(NAME(m_mamr));
+ save_item(NAME(m_dram_refresh));
+ save_item(NAME(m_dram_access));
+ save_item(NAME(m_da_drive));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void tmp94c241_device::device_reset()
+{
+ tlcs900h_device::device_reset();
+
+ m_ad_cycles_left = 0;
+ m_timer_pre = 0;
+
+ m_port_latch[PORT_0] = 0x00;
+ m_port_latch[PORT_1] = 0x00;
+ m_port_latch[PORT_2] = 0x00;
+ m_port_latch[PORT_3] = 0x00;
+ m_port_latch[PORT_4] = 0x00;
+ m_port_latch[PORT_5] = 0x00;
+ m_port_latch[PORT_6] = 0x00;
+ m_port_latch[PORT_7] = 0x7f;
+ m_port_latch[PORT_8] = 0x3b;
+ m_port_latch[PORT_A] = 0x1f;
+ m_port_latch[PORT_B] = 0x1f;
+ m_port_latch[PORT_C] = 0x00;
+ m_port_latch[PORT_D] = 0x00;
+ m_port_latch[PORT_E] = 0x00;
+ m_port_latch[PORT_F] = 0x00;
+ m_port_latch[PORT_H] = 0x00;
+ m_port_latch[PORT_Z] = 0x00;
+
+ m_port_function[PORT_0] = 0x01;
+ m_port_function[PORT_1] = 0x01;
+ m_port_function[PORT_2] = 0x01;
+ m_port_function[PORT_3] = 0x01;
+ m_port_function[PORT_4] = 0xff;
+ m_port_function[PORT_5] = 0xff;
+ m_port_function[PORT_6] = 0xff;
+ m_port_function[PORT_7] = 0x01;
+ m_port_function[PORT_8] = 0x00;
+ m_port_function[PORT_A] = 0x00;
+ m_port_function[PORT_B] = 0x00;
+ m_port_function[PORT_C] = 0x00;
+ m_port_function[PORT_D] = 0x00;
+ m_port_function[PORT_E] = 0x00;
+ m_port_function[PORT_F] = 0x00;
+ m_port_function[PORT_H] = 0x00;
+ m_port_function[PORT_Z] = 0x00;
+
+ std::fill_n(&m_port_control[0], NUM_PORTS, 0x00);
+ std::fill_n(&m_timer_flipflops[0], 12, 0x00);
+ m_t8run = 0x00;
+ m_trdc = 0x00;
+ m_t01mod = 0x00;
+ m_t23mod = 0x00;
+ m_t4mod = 0x00;
+ m_t6mod = 0x00;
+ m_t8mod = 0x00;
+ m_tamod = 0x00;
+ m_tffcr = 0x00;
+ m_t4ffcr = 0x00;
+ m_t6ffcr = 0x00;
+ m_t8ffcr = 0x00;
+ m_taffcr = 0x00;
+ std::fill_n(&m_timer_change[0], 8, 0x00);
+ std::fill_n(&m_timer_8[0], 4, 0x00);
+ std::fill_n(&m_timer_16[0], 4, 0x00);
+ m_watchdog_mode = 0x80;
+ for (int i = 0; i < 2; i++)
+ {
+ m_serial_control[i] &= 0x80;
+ m_serial_mode[i] &= 0x80;
+ m_baud_rate[i] = 0x00;
+ }
+ m_od_enable = 0x00;
+ m_ad_mode1 = 0x00;
+ m_ad_mode2 = 0x00;
+ std::fill_n(&m_int_reg[0], 18, 0x00);
+ m_iimc = 0x00;
+ std::fill_n(&m_dma_vector[0], 4, 0x00);
+ m_block_cs[0] = 0x0000;
+ m_block_cs[1] = 0x0000;
+ m_block_cs[2] = 0x1000; //FIXME!
+ m_block_cs[3] = 0x0000;
+ m_block_cs[4] = 0x0000;
+ m_block_cs[5] = 0x0000;
+ m_external_cs = 0x0000;
+ std::fill_n(&m_msar[0], 6, 0xff);
+ std::fill_n(&m_mamr[0], 6, 0xff);
+ std::fill_n(&m_dram_refresh[0], 2, 0x00);
+ std::fill_n(&m_dram_access[0], 2, 0x80);
+ m_da_drive = 0x00;
+}
+
+uint8_t tmp94c241_device::inte_r(offs_t offset)
+{
+ return m_int_reg[offset];
+}
+
+void tmp94c241_device::inte_w(offs_t offset, uint8_t data)
+{
+ if (data & 0x80)
+ data = (data & 0x7f) | (m_int_reg[offset] & 0x80);
+ if (data & 0x08)
+ data = (data & 0xf7) | (m_int_reg[offset] & 0x08);
+
+ m_int_reg[offset] = data;
+ m_check_irqs = 1;
+}
+
+uint8_t tmp94c241_device::intnmwdt_r(offs_t offset)
+{
+ return m_int_reg[INTNMWDT];
+}
+
+void tmp94c241_device::intnmwdt_w(offs_t offset, uint8_t data)
+{
+ if (data & 0x80)
+ data = (data & 0x7f) | (m_int_reg[INTNMWDT] & 0x80);
+ if ( data & 0x08 )
+ data = (data & 0xf7) | (m_int_reg[INTNMWDT] & 0x08);
+
+ m_int_reg[INTNMWDT] = data;
+ m_check_irqs = 1;
+}
+
+void tmp94c241_device::iimc_w(uint8_t data)
+{
+ m_iimc = data;
+ m_check_irqs = 1;
+}
+
+void tmp94c241_device::intclr_w(uint8_t data)
+{
+ for (int i = 0; i < NUM_MASKABLE_IRQS; i++)
+ {
+ if (data == tmp94c241_irq_vector_map[i].dma_start_vector)
+ {
+ // clear interrupt request
+ m_int_reg[tmp94c241_irq_vector_map[i].reg] &= ~ tmp94c241_irq_vector_map[i].iff;
+ return;
+ }
+ }
+}
+
+void tmp94c241_device::dmav_w(offs_t offset, uint8_t data)
+{
+ m_dma_vector[offset] = data;
+}
+
+template <uint8_t N>
+void tmp94c241_device::bNcs_w(offs_t offset, uint16_t data, uint16_t mem_mask)
+{
+ COMBINE_DATA(&m_block_cs[N]);
+}
+
+template <uint8_t N>
+void tmp94c241_device::mamr_w(uint8_t data)
+{
+ m_mamr[N] = data;
+}
+
+template <uint8_t N>
+void tmp94c241_device::msar_w(uint8_t data)
+{
+ m_msar[N] = data;
+}
+
+template <uint8_t N>
+uint8_t tmp94c241_device::mamr_r()
+{
+ return m_mamr[N];
+}
+
+template <uint8_t N>
+uint8_t tmp94c241_device::msar_r()
+{
+ return m_msar[N];
+}
+
+uint8_t tmp94c241_device::t8run_r()
+{
+ return m_t8run;
+}
+
+void tmp94c241_device::t8run_w(uint8_t data)
+{
+ m_t8run = data;
+ for (int i = 0; i < 4; i++)
+ {
+ // These correspond to UP_COUNTER and TIMER_CHANGE for 8-bit timers 0, 1, 2 and 3
+ if (!BIT(m_t8run, i)) // Timer isn't running
+ {
+ m_timer_8[i] = 0;
+ m_timer_change[i] = 0;
+ }
+ }
+}
+
+uint8_t tmp94c241_device::t01mod_r()
+{
+ return m_t01mod;
+}
+
+void tmp94c241_device::t01mod_w(uint8_t data)
+{
+ m_t01mod = data;
+}
+
+uint8_t tmp94c241_device::tffcr_r()
+{
+ return m_tffcr;
+}
+
+enum
+{
+ FF_INVERT,
+ FF_SET,
+ FF_CLEAR,
+ FF_DONTCARE
+};
+
+void tmp94c241_device::change_timer_flipflop(uint8_t flipflop, uint8_t operation)
+{
+ /* First we update the timer flip-flop */
+ bool &ff_state = m_timer_flipflops[flipflop];
+
+ switch (operation)
+ {
+ case FF_INVERT:
+ ff_state = !ff_state;
+ break;
+ case FF_SET:
+ ff_state = true;
+ break;
+ case FF_CLEAR:
+ ff_state = false;
+ break;
+ default:
+ // invalid operation
+ return;
+ }
+
+ /* The value of the flipflop is only exposed to a pin in certain modes of operation
+ determined by fields of the port function registers.
+
+ So here we bail out if the flipflop is not routed to its corresponding port bit:
+ */
+ switch (flipflop)
+ {
+ case 0x1:
+ if (!BIT(m_port_function[PORT_C], 0) || BIT(m_port_control[PORT_C], 0)) return;
+ break;
+ case 0x7:
+ if (!BIT(m_port_function[PORT_C], 0) || !BIT(m_port_control[PORT_C], 0)) return;
+ break;
+ case 0x3:
+ if (!BIT(m_port_function[PORT_C], 1) || BIT(m_port_control[PORT_C], 1)) return;
+ break;
+ case 0xb:
+ if (!BIT(m_port_function[PORT_C], 1) || !BIT(m_port_control[PORT_C], 1)) return;
+ break;
+ case 0x4:
+ if (!BIT(m_port_function[PORT_D], 0)) return;
+ break;
+ case 0x6:
+ if (!BIT(m_port_function[PORT_D], 4)) return;
+ break;
+ case 0x8:
+ if (!BIT(m_port_function[PORT_E], 0)) return;
+ break;
+ case 0xA:
+ if (!BIT(m_port_function[PORT_E], 4)) return;
+ break;
+ default:
+ // invalid flip flop
+ return;
+ }
+
+ // And here we actually send the value to the corresponding pin
+ uint8_t new_port_value = 0;
+ switch (flipflop)
+ {
+ case 0x1:
+ case 0x7:
+ new_port_value = m_port_latch[PORT_C] & 0xfe;
+ if (ff_state) new_port_value |= 0x01;
+ port_w<PORT_C>(new_port_value);
+ break;
+ case 0x3:
+ case 0xb:
+ new_port_value = m_port_latch[PORT_C] & 0xfd;
+ if (ff_state) new_port_value |= 0x02;
+ port_w<PORT_C>(new_port_value);
+ break;
+ case 0x4:
+ new_port_value = m_port_latch[PORT_D] & 0xfe;
+ if (ff_state) new_port_value |= 0x01;
+ port_w<PORT_D>(new_port_value);
+ break;
+ case 0x6:
+ new_port_value = m_port_latch[PORT_D] & 0xef;
+ if (ff_state) new_port_value |= 0x10;
+ port_w<PORT_D>(new_port_value);
+ break;
+ case 0x8:
+ new_port_value = m_port_latch[PORT_E] & 0xfe;
+ if (ff_state) new_port_value |= 0x01;
+ port_w<PORT_E>(new_port_value);
+ break;
+ case 0xa:
+ new_port_value = m_port_latch[PORT_E] & 0xef;
+ if (ff_state) new_port_value |= 0x10;
+ port_w<PORT_E>(new_port_value);
+ break;
+ }
+}
+
+void tmp94c241_device::tffcr_w(uint8_t data)
+{
+ change_timer_flipflop( 1, (data >> 2) & 3 );
+ change_timer_flipflop( 3, (data >> 6) & 3 );
+ m_tffcr = data | 0xcc;
+}
+
+uint8_t tmp94c241_device::t23mod_r()
+{
+ return m_t23mod;
+}
+
+void tmp94c241_device::t23mod_w(uint8_t data)
+{
+ m_t23mod = data;
+}
+
+uint8_t tmp94c241_device::trdc_r()
+{
+ return m_trdc;
+}
+
+void tmp94c241_device::trdc_w(uint8_t data)
+{
+ m_trdc = data;
+}
+
+template <uint8_t Timer>
+void tmp94c241_device::treg_8_w(uint8_t data)
+{
+ m_treg_8[Timer] = data;
+}
+
+template <uint8_t Timer>
+void tmp94c241_device::treg_16_w(uint16_t data)
+{
+ m_treg_16[Timer] = data;
+}
+
+uint8_t tmp94c241_device::t4mod_r()
+{
+ return m_t4mod;
+}
+
+void tmp94c241_device::t4mod_w(uint8_t data)
+{
+ m_t4mod = data;
+}
+
+uint8_t tmp94c241_device::t6mod_r()
+{
+ return m_t6mod;
+}
+
+void tmp94c241_device::t6mod_w(uint8_t data)
+{
+ m_t6mod = data;
+}
+
+uint8_t tmp94c241_device::t8mod_r()
+{
+ return m_t8mod;
+}
+
+void tmp94c241_device::t8mod_w(uint8_t data)
+{
+ m_t8mod = data;
+}
+
+uint8_t tmp94c241_device::tamod_r()
+{
+ return m_tamod;
+}
+
+void tmp94c241_device::tamod_w(uint8_t data)
+{
+ m_tamod = data;
+}
+
+uint8_t tmp94c241_device::t4ffcr_r()
+{
+ return m_t4ffcr;
+}
+
+void tmp94c241_device::t4ffcr_w(uint8_t data)
+{
+ change_timer_flipflop( 4, data & 3 );
+ change_timer_flipflop( 5, (data >> 6) & 3 );
+ m_t4ffcr = data | 0xc3;
+}
+
+uint8_t tmp94c241_device::t6ffcr_r()
+{
+ return m_t6ffcr;
+}
+
+void tmp94c241_device::t6ffcr_w(uint8_t data)
+{
+ change_timer_flipflop( 6, data & 3 );
+ change_timer_flipflop( 7, (data >> 6) & 3 );
+ m_t6ffcr = data | 0xc3;
+}
+
+uint8_t tmp94c241_device::t8ffcr_r()
+{
+ return m_t8ffcr;
+}
+
+void tmp94c241_device::t8ffcr_w(uint8_t data)
+{
+ change_timer_flipflop( 8, data & 3 );
+ change_timer_flipflop( 9, (data >> 6) & 3 );
+ m_t8ffcr = data | 0xc3;
+}
+
+uint8_t tmp94c241_device::taffcr_r()
+{
+ return m_taffcr;
+}
+
+void tmp94c241_device::taffcr_w(uint8_t data)
+{
+ change_timer_flipflop( 0xa, data & 3 );
+ change_timer_flipflop( 0xb, (data >> 6) & 3 );
+ m_taffcr = data | 0xc3;
+}
+
+uint8_t tmp94c241_device::t16run_r()
+{
+ return m_t16run;
+}
+
+void tmp94c241_device::t16run_w(uint8_t data)
+{
+ m_t16run = data;
+ for (int i = 0; i < 4; i++)
+ {
+ if (!BIT(m_t16run, i)) // Timer isn't running
+ {
+ // These correspond to UP_COUNTER and TIMER_CHANGE for 16-bit timers 4, 6, 8 and A
+ m_timer_16[i] = 0;
+ m_timer_change[4 + i] = 0;
+ }
+ }
+}
+
+template <uint8_t Timer>
+uint16_t tmp94c241_device::cap_r()
+{
+ return m_t16_cap[Timer];
+}
+
+uint8_t tmp94c241_device::wdmod_r()
+{
+ return m_watchdog_mode;
+}
+
+void tmp94c241_device::wdmod_w(uint8_t data)
+{
+ m_watchdog_mode = data;
+}
+
+void tmp94c241_device::wdcr_w(uint8_t data)
+{
+}
+
+template <uint8_t Channel>
+uint8_t tmp94c241_device::scNbuf_r()
+{
+ return 0;
+}
+
+template <uint8_t Channel>
+void tmp94c241_device::scNbuf_w(uint8_t data)
+{
+ // Fake finish sending data
+ m_int_reg[(Channel == 0) ? INTES0 : INTES1] |= 0x80;
+ m_check_irqs = 1;
+ logerror("sc%dbuf write: %02X\n", Channel, data);
+ //machine().debugger().debug_break();
+}
+
+template <uint8_t Channel>
+uint8_t tmp94c241_device::scNcr_r()
+{
+ uint8_t reg = m_serial_control[Channel];
+ if (!machine().side_effects_disabled())
+ m_serial_control[Channel] &= 0xe3;
+ return reg;
+}
+
+template <uint8_t Channel>
+void tmp94c241_device::scNcr_w(uint8_t data)
+{
+ m_serial_control[Channel] = data;
+}
+
+template <uint8_t Channel>
+uint8_t tmp94c241_device::scNmod_r()
+{
+ return m_serial_mode[Channel];
+}
+
+template <uint8_t Channel>
+void tmp94c241_device::scNmod_w(uint8_t data)
+{
+ m_serial_mode[Channel] = data;
+}
+
+template <uint8_t Channel>
+uint8_t tmp94c241_device::brNcr_r()
+{
+ return m_baud_rate[Channel];
+}
+
+template <uint8_t Channel>
+void tmp94c241_device::brNcr_w(uint8_t data)
+{
+ m_baud_rate[Channel] = data;
+}
+
+uint8_t tmp94c241_device::ode_r()
+{
+ return m_od_enable;
+}
+
+void tmp94c241_device::ode_w(uint8_t data)
+{
+ m_od_enable = data;
+}
+
+uint8_t tmp94c241_device::admod1_r()
+{
+ return m_ad_mode1;
+}
+
+void tmp94c241_device::admod1_w(uint8_t data)
+{
+ // Preserve read-only bits
+ data = (m_ad_mode1 & 0xc0) | ( data & 0x34 );
+
+ // Check for A/D conversion start
+ if (data & 0x04)
+ {
+ data &= ~0x04;
+ data |= 0x40;
+
+ switch ((m_ad_mode2 >> 4) & 3)
+ {
+ case 0: m_ad_cycles_left = 160; break;
+ case 1: m_ad_cycles_left = 320; break;
+ case 2: m_ad_cycles_left = 640; break;
+ case 3: m_ad_cycles_left = 1280; break;
+ }
+ }
+
+ m_ad_mode1 = data;
+}
+
+uint8_t tmp94c241_device::admod2_r()
+{
+ return m_ad_mode2;
+}
+
+void tmp94c241_device::admod2_w(uint8_t data)
+{
+ m_ad_mode2 = data;
+}
+
+uint8_t tmp94c241_device::adreg_r(offs_t offset)
+{
+ if (BIT(offset, 0))
+ return m_ad_result[offset >> 1] >> 2;
+ else
+ return m_ad_result[offset >> 1] << 6 | 0x3f;
+}
+
+uint8_t tmp94c241_device::dadrv_r()
+{
+ return m_da_drive;
+}
+
+void tmp94c241_device::dadrv_w(uint8_t data)
+{
+ m_da_drive = data;
+}
+
+void tmp94c241_device::dareg_w(offs_t offset, uint8_t data)
+{
+}
+
+template <uint8_t P>
+void tmp94c241_device::port_w(uint8_t data)
+{
+ m_port_latch[P] = data;
+ m_port_write[P](0, data, 0xff);
+}
+
+template <uint8_t P>
+uint8_t tmp94c241_device::port_r()
+{
+ return m_port_read[P](0);
+}
+
+template <uint8_t P>
+void tmp94c241_device::port_cr_w(uint8_t data)
+{
+ m_port_control[P] = data;
+}
+
+template <uint8_t P>
+void tmp94c241_device::port_fc_w(uint8_t data)
+{
+ m_port_function[P] = data;
+}
+
+//**************************************************************************
+// INTERNAL REGISTERS
+//**************************************************************************
+
+//-------------------------------------------------
+// internal_mem - memory map for internal RAM and
+// I/O registers
+//-------------------------------------------------
+
+void tmp94c241_device::internal_mem(address_map &map)
+{
+ map(0x000000, 0x000000).rw(FUNC(tmp94c241_device::port_r<PORT_0>), FUNC(tmp94c241_device::port_w<PORT_0>));
+ map(0x000002, 0x000002).w(FUNC(tmp94c241_device::port_cr_w<PORT_0>));
+ map(0x000003, 0x000003).w(FUNC(tmp94c241_device::port_fc_w<PORT_0>));
+ map(0x000004, 0x000004).rw(FUNC(tmp94c241_device::port_r<PORT_1>), FUNC(tmp94c241_device::port_w<PORT_1>));
+ map(0x000006, 0x000006).w(FUNC(tmp94c241_device::port_cr_w<PORT_1>));
+ map(0x000007, 0x000007).w(FUNC(tmp94c241_device::port_fc_w<PORT_1>));
+ map(0x000008, 0x000008).rw(FUNC(tmp94c241_device::port_r<PORT_2>), FUNC(tmp94c241_device::port_w<PORT_2>));
+ map(0x00000a, 0x00000a).w(FUNC(tmp94c241_device::port_cr_w<PORT_2>));
+ map(0x00000b, 0x00000b).w(FUNC(tmp94c241_device::port_fc_w<PORT_2>));
+ map(0x00000c, 0x00000c).rw(FUNC(tmp94c241_device::port_r<PORT_3>), FUNC(tmp94c241_device::port_w<PORT_3>));
+ map(0x00000e, 0x00000e).w(FUNC(tmp94c241_device::port_cr_w<PORT_3>));
+ map(0x00000f, 0x00000f).w(FUNC(tmp94c241_device::port_fc_w<PORT_3>));
+ map(0x000010, 0x000010).rw(FUNC(tmp94c241_device::port_r<PORT_4>), FUNC(tmp94c241_device::port_w<PORT_4>));
+ map(0x000012, 0x000012).w(FUNC(tmp94c241_device::port_cr_w<PORT_4>));
+ map(0x000013, 0x000013).w(FUNC(tmp94c241_device::port_fc_w<PORT_4>));
+ map(0x000014, 0x000014).rw(FUNC(tmp94c241_device::port_r<PORT_5>), FUNC(tmp94c241_device::port_w<PORT_5>));
+ map(0x000016, 0x000016).w(FUNC(tmp94c241_device::port_cr_w<PORT_5>));
+ map(0x000017, 0x000017).w(FUNC(tmp94c241_device::port_fc_w<PORT_5>));
+ map(0x000018, 0x000018).rw(FUNC(tmp94c241_device::port_r<PORT_6>), FUNC(tmp94c241_device::port_w<PORT_6>));
+ map(0x00001a, 0x00001a).w(FUNC(tmp94c241_device::port_cr_w<PORT_6>));
+ map(0x00001b, 0x00001b).w(FUNC(tmp94c241_device::port_fc_w<PORT_6>));
+ map(0x00001c, 0x00001c).rw(FUNC(tmp94c241_device::port_r<PORT_7>), FUNC(tmp94c241_device::port_w<PORT_7>));
+ map(0x00001e, 0x00001e).w(FUNC(tmp94c241_device::port_cr_w<PORT_7>));
+ map(0x00001f, 0x00001f).w(FUNC(tmp94c241_device::port_fc_w<PORT_7>));
+ map(0x000020, 0x000020).rw(FUNC(tmp94c241_device::port_r<PORT_8>), FUNC(tmp94c241_device::port_w<PORT_8>));
+ map(0x000022, 0x000022).w(FUNC(tmp94c241_device::port_cr_w<PORT_8>));
+ map(0x000023, 0x000023).w(FUNC(tmp94c241_device::port_fc_w<PORT_8>));
+ map(0x000028, 0x000028).rw(FUNC(tmp94c241_device::port_r<PORT_A>), FUNC(tmp94c241_device::port_w<PORT_A>));
+ map(0x00002b, 0x00002b).w(FUNC(tmp94c241_device::port_fc_w<PORT_A>));
+ map(0x00002c, 0x00002c).rw(FUNC(tmp94c241_device::port_r<PORT_B>), FUNC(tmp94c241_device::port_w<PORT_B>));
+ map(0x00002f, 0x00002f).w(FUNC(tmp94c241_device::port_fc_w<PORT_B>));
+ map(0x000030, 0x000030).rw(FUNC(tmp94c241_device::port_r<PORT_C>), FUNC(tmp94c241_device::port_w<PORT_C>));
+ map(0x000032, 0x000032).w(FUNC(tmp94c241_device::port_cr_w<PORT_C>));
+ map(0x000033, 0x000033).w(FUNC(tmp94c241_device::port_fc_w<PORT_C>));
+ map(0x000034, 0x000034).rw(FUNC(tmp94c241_device::port_r<PORT_D>), FUNC(tmp94c241_device::port_w<PORT_D>));
+ map(0x000036, 0x000036).w(FUNC(tmp94c241_device::port_cr_w<PORT_D>));
+ map(0x000037, 0x000037).w(FUNC(tmp94c241_device::port_fc_w<PORT_D>));
+ map(0x000038, 0x000038).rw(FUNC(tmp94c241_device::port_r<PORT_E>), FUNC(tmp94c241_device::port_w<PORT_E>));
+ map(0x00003a, 0x00003a).w(FUNC(tmp94c241_device::port_cr_w<PORT_E>));
+ map(0x00003b, 0x00003b).w(FUNC(tmp94c241_device::port_fc_w<PORT_E>));
+ map(0x00003c, 0x00003c).rw(FUNC(tmp94c241_device::port_r<PORT_F>), FUNC(tmp94c241_device::port_w<PORT_F>));
+ map(0x00003e, 0x00003e).w(FUNC(tmp94c241_device::port_cr_w<PORT_F>));
+ map(0x00003f, 0x00003f).w(FUNC(tmp94c241_device::port_fc_w<PORT_F>));
+ map(0x000040, 0x000040).r(FUNC(tmp94c241_device::port_r<PORT_G>));
+ map(0x000044, 0x000044).rw(FUNC(tmp94c241_device::port_r<PORT_H>), FUNC(tmp94c241_device::port_w<PORT_H>));
+ map(0x000046, 0x000046).w(FUNC(tmp94c241_device::port_cr_w<PORT_H>));
+ map(0x000047, 0x000047).w(FUNC(tmp94c241_device::port_fc_w<PORT_H>));
+ map(0x000068, 0x000068).rw(FUNC(tmp94c241_device::port_r<PORT_Z>), FUNC(tmp94c241_device::port_w<PORT_Z>));
+ map(0x00006a, 0x00006a).w(FUNC(tmp94c241_device::port_cr_w<PORT_Z>));
+ map(0x000080, 0x000080).rw(FUNC(tmp94c241_device::t8run_r), FUNC(tmp94c241_device::t8run_w));
+ map(0x000081, 0x000081).rw(FUNC(tmp94c241_device::trdc_r), FUNC(tmp94c241_device::trdc_w));
+ map(0x000082, 0x000082).rw(FUNC(tmp94c241_device::tffcr_r), FUNC(tmp94c241_device::tffcr_w));
+ map(0x000084, 0x000084).rw(FUNC(tmp94c241_device::t01mod_r), FUNC(tmp94c241_device::t01mod_w));
+ map(0x000085, 0x000085).rw(FUNC(tmp94c241_device::t23mod_r), FUNC(tmp94c241_device::t23mod_w));
+ map(0x000088, 0x000088).w(FUNC(tmp94c241_device::treg_8_w<TREG0>));
+ map(0x000089, 0x000089).w(FUNC(tmp94c241_device::treg_8_w<TREG1>));
+ map(0x00008a, 0x00008a).w(FUNC(tmp94c241_device::treg_8_w<TREG2>));
+ map(0x00008b, 0x00008b).w(FUNC(tmp94c241_device::treg_8_w<TREG3>));
+ map(0x000090, 0x000091).w(FUNC(tmp94c241_device::treg_16_w<TREG4>));
+ map(0x000092, 0x000093).w(FUNC(tmp94c241_device::treg_16_w<TREG5>));
+ map(0x000094, 0x000095).r(FUNC(tmp94c241_device::cap_r<CAP4>));
+ map(0x000096, 0x000097).r(FUNC(tmp94c241_device::cap_r<CAP5>));
+ map(0x000098, 0x000098).rw(FUNC(tmp94c241_device::t4mod_r), FUNC(tmp94c241_device::t4mod_w));
+ map(0x000099, 0x000099).rw(FUNC(tmp94c241_device::t4ffcr_r), FUNC(tmp94c241_device::t4ffcr_w));
+ map(0x00009e, 0x00009e).rw(FUNC(tmp94c241_device::t16run_r), FUNC(tmp94c241_device::t16run_w));
+ map(0x0000a0, 0x0000a1).w(FUNC(tmp94c241_device::treg_16_w<TREG6>));
+ map(0x0000a2, 0x0000a3).w(FUNC(tmp94c241_device::treg_16_w<TREG7>));
+ map(0x0000a4, 0x0000a5).r(FUNC(tmp94c241_device::cap_r<CAP6>));
+ map(0x0000a6, 0x0000a7).r(FUNC(tmp94c241_device::cap_r<CAP7>));
+ map(0x0000a8, 0x0000a8).rw(FUNC(tmp94c241_device::t6mod_r), FUNC(tmp94c241_device::t6mod_w));
+ map(0x0000a9, 0x0000a9).rw(FUNC(tmp94c241_device::t6ffcr_r), FUNC(tmp94c241_device::t6ffcr_w));
+ map(0x0000b0, 0x0000b1).w(FUNC(tmp94c241_device::treg_16_w<TREG8>));
+ map(0x0000b2, 0x0000b3).w(FUNC(tmp94c241_device::treg_16_w<TREG9>));
+ map(0x0000b4, 0x0000b5).r(FUNC(tmp94c241_device::cap_r<CAP8>));
+ map(0x0000b6, 0x0000b7).r(FUNC(tmp94c241_device::cap_r<CAP9>));
+ map(0x0000b8, 0x0000b8).rw(FUNC(tmp94c241_device::t8mod_r), FUNC(tmp94c241_device::t8mod_w));
+ map(0x0000b9, 0x0000b9).rw(FUNC(tmp94c241_device::t8ffcr_r), FUNC(tmp94c241_device::t8ffcr_w));
+ map(0x0000c0, 0x0000c1).w(FUNC(tmp94c241_device::treg_16_w<TREGA>));
+ map(0x0000c2, 0x0000c3).w(FUNC(tmp94c241_device::treg_16_w<TREGB>));
+ map(0x0000c4, 0x0000c5).r(FUNC(tmp94c241_device::cap_r<CAPA>));
+ map(0x0000c6, 0x0000c7).r(FUNC(tmp94c241_device::cap_r<CAPB>));
+ map(0x0000c8, 0x0000c8).rw(FUNC(tmp94c241_device::tamod_r), FUNC(tmp94c241_device::tamod_w));
+ map(0x0000c9, 0x0000c9).rw(FUNC(tmp94c241_device::taffcr_r), FUNC(tmp94c241_device::taffcr_w));
+ map(0x0000d0, 0x0000d0).rw(FUNC(tmp94c241_device::scNbuf_r<0>), FUNC(tmp94c241_device::scNbuf_w<0>));
+ map(0x0000d1, 0x0000d1).rw(FUNC(tmp94c241_device::scNcr_r<0>), FUNC(tmp94c241_device::scNcr_w<0>));
+ map(0x0000d2, 0x0000d2).rw(FUNC(tmp94c241_device::scNmod_r<0>), FUNC(tmp94c241_device::scNmod_w<0>));
+ map(0x0000d3, 0x0000d3).rw(FUNC(tmp94c241_device::brNcr_r<0>), FUNC(tmp94c241_device::brNcr_w<0>));
+ map(0x0000d4, 0x0000d4).rw(FUNC(tmp94c241_device::scNbuf_r<1>), FUNC(tmp94c241_device::scNbuf_w<1>));
+ map(0x0000d5, 0x0000d5).rw(FUNC(tmp94c241_device::scNcr_r<1>), FUNC(tmp94c241_device::scNcr_w<1>));
+ map(0x0000d6, 0x0000d6).rw(FUNC(tmp94c241_device::scNmod_r<1>), FUNC(tmp94c241_device::scNmod_w<1>));
+ map(0x0000d7, 0x0000d7).rw(FUNC(tmp94c241_device::brNcr_r<1>), FUNC(tmp94c241_device::brNcr_w<1>));
+ map(0x0000e0, 0x0000f0).rw(FUNC(tmp94c241_device::inte_r), FUNC(tmp94c241_device::inte_w));
+ map(0x0000f6, 0x0000f6).w(FUNC(tmp94c241_device::iimc_w));
+ map(0x0000f7, 0x0000f7).rw(FUNC(tmp94c241_device::intnmwdt_r), FUNC(tmp94c241_device::intnmwdt_w));
+ map(0x0000f8, 0x0000f8).w(FUNC(tmp94c241_device::intclr_w));
+ map(0x000100, 0x000103).w(FUNC(tmp94c241_device::dmav_w));
+ map(0x000110, 0x000110).rw(FUNC(tmp94c241_device::wdmod_r), FUNC(tmp94c241_device::wdmod_w));
+ map(0x000111, 0x000111).w(FUNC(tmp94c241_device::wdcr_w));
+ map(0x000120, 0x000127).r(FUNC(tmp94c241_device::adreg_r));
+ map(0x000128, 0x000128).rw(FUNC(tmp94c241_device::admod1_r), FUNC(tmp94c241_device::admod1_w));
+ map(0x000129, 0x000129).rw(FUNC(tmp94c241_device::admod2_r), FUNC(tmp94c241_device::admod2_w));
+ map(0x000130, 0x000131).w(FUNC(tmp94c241_device::dareg_w));
+ map(0x000132, 0x000132).rw(FUNC(tmp94c241_device::dadrv_r), FUNC(tmp94c241_device::dadrv_w));
+ map(0x000140, 0x000141).w(FUNC(tmp94c241_device::bNcs_w<0>));
+ map(0x000142, 0x000142).rw(FUNC(tmp94c241_device::mamr_r<0>), FUNC(tmp94c241_device::mamr_w<0>));
+ map(0x000143, 0x000143).rw(FUNC(tmp94c241_device::msar_r<0>), FUNC(tmp94c241_device::msar_w<0>));
+ map(0x000144, 0x000145).w(FUNC(tmp94c241_device::bNcs_w<1>));
+ map(0x000146, 0x000146).rw(FUNC(tmp94c241_device::mamr_r<1>), FUNC(tmp94c241_device::mamr_w<1>));
+ map(0x000147, 0x000147).rw(FUNC(tmp94c241_device::msar_r<1>), FUNC(tmp94c241_device::msar_w<1>));
+ map(0x000148, 0x000149).w(FUNC(tmp94c241_device::bNcs_w<2>));
+ map(0x00014a, 0x00014a).rw(FUNC(tmp94c241_device::mamr_r<2>), FUNC(tmp94c241_device::mamr_w<2>));
+ map(0x00014b, 0x00014b).rw(FUNC(tmp94c241_device::msar_r<2>), FUNC(tmp94c241_device::msar_w<2>));
+ map(0x00014c, 0x00014d).w(FUNC(tmp94c241_device::bNcs_w<3>));
+ map(0x00014e, 0x00014e).rw(FUNC(tmp94c241_device::mamr_r<3>), FUNC(tmp94c241_device::mamr_w<3>));
+ map(0x00014f, 0x00014f).rw(FUNC(tmp94c241_device::msar_r<3>), FUNC(tmp94c241_device::msar_w<3>));
+ map(0x000150, 0x000151).w(FUNC(tmp94c241_device::bNcs_w<4>));
+ map(0x000152, 0x000152).rw(FUNC(tmp94c241_device::mamr_r<4>), FUNC(tmp94c241_device::mamr_w<4>));
+ map(0x000153, 0x000153).rw(FUNC(tmp94c241_device::msar_r<4>), FUNC(tmp94c241_device::msar_w<4>));
+ map(0x000154, 0x000155).w(FUNC(tmp94c241_device::bNcs_w<5>));
+ map(0x000156, 0x000156).rw(FUNC(tmp94c241_device::mamr_r<5>), FUNC(tmp94c241_device::mamr_w<5>));
+ map(0x000157, 0x000157).rw(FUNC(tmp94c241_device::msar_r<5>), FUNC(tmp94c241_device::msar_w<5>));
+ map(0x000400, 0x000bff).ram();
+}
+
+//**************************************************************************
+// EXECUTION CALLBACKS
+//**************************************************************************
+
+//-------------------------------------------------
+// tlcs900_check_hdma -
+//-------------------------------------------------
+
+void tmp94c241_device::tlcs900_check_hdma()
+{
+}
+
+
+//-------------------------------------------------
+// tlcs900_check_irqs -
+//-------------------------------------------------
+
+void tmp94c241_device::tlcs900_check_irqs()
+{
+ // Check for NMI
+ if (m_nmi_state == ASSERT_LINE)
+ {
+ m_xssp.d -= 4;
+ WRMEML(m_xssp.d, m_pc.d);
+ m_xssp.d -= 2;
+ WRMEMW(m_xssp.d, m_sr.w.l);
+ m_pc.d = RDMEML( 0xffff00 + 0x20 );
+ m_cycles += 18;
+ m_prefetch_clear = true;
+ m_halted = 0;
+ m_nmi_state = CLEAR_LINE;
+ return;
+ }
+
+ /* Check regular IRQs
+ The smaller the vector value, the higher the priority. */
+ int irq_vectors[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
+ for (int i = NUM_MASKABLE_IRQS - 1; i >= 0; i--)
+ {
+ if (m_int_reg[tmp94c241_irq_vector_map[i].reg] & tmp94c241_irq_vector_map[i].iff)
+ {
+ switch (tmp94c241_irq_vector_map[i].iff)
+ {
+ case 0x80:
+ irq_vectors[(m_int_reg[tmp94c241_irq_vector_map[i].reg] >> 4) & 0x07] = i;
+ break;
+ case 0x08:
+ irq_vectors[m_int_reg[tmp94c241_irq_vector_map[i].reg] & 0x07] = i;
+ break;
+ }
+ }
+ }
+
+ // Check highest allowed priority IRQ
+ int irq = -1;
+ int level = 0;
+ for (int i = std::max(1, (m_sr.b.h & 0x70) >> 4); i < 7; i++)
+ {
+ if (irq_vectors[i] >= 0)
+ {
+ irq = irq_vectors[i];
+ level = i + 1;
+ }
+ }
+
+ // Take IRQ
+ if (irq >= 0)
+ {
+ uint8_t vector = tmp94c241_irq_vector_map[irq].vector;
+
+ m_xssp.d -= 4;
+ WRMEML(m_xssp.d, m_pc.d);
+ m_xssp.d -= 2;
+ WRMEMW(m_xssp.d, m_sr.w.l);
+
+ // Mask off any lower priority interrupts
+ m_sr.b.h = (m_sr.b.h & 0x8f) | (level << 4);
+
+ m_pc.d = RDMEML(0xffff00 + vector);
+
+ m_cycles += 18;
+ m_prefetch_clear = true;
+
+ m_halted = 0;
+
+ // Clear taken IRQ
+ m_int_reg[tmp94c241_irq_vector_map[irq].reg] &= ~ tmp94c241_irq_vector_map[irq].iff;
+ }
+}
+
+
+//-------------------------------------------------
+// tlcs900_handle_ad -
+//-------------------------------------------------
+
+void tmp94c241_device::tlcs900_handle_ad()
+{
+}
+
+
+//-------------------------------------------------
+// tlcs900_handle_timers -
+//-------------------------------------------------
+
+// Prescaler shift amounts corresponding to each possible timer input clock source:
+static constexpr uint8_t T1 = 3;
+static constexpr uint8_t T4 = 5;
+static constexpr uint8_t T16 = 7;
+static constexpr uint8_t T256 = 11;
+
+void tmp94c241_device::tlcs900_handle_timers()
+{
+ auto const update_timer_count =
+ [this, old_pre = m_timer_pre] (
+ uint8_t timer_index,
+ uint8_t input_clk_select,
+ uint8_t s1,
+ uint8_t s2,
+ uint8_t s3)
+ {
+ switch (input_clk_select)
+ {
+ case 0:
+ /* Not yet implemented.
+ - For the 8 bit timers: TIO, TO0TRG, invalid and TO2TRG
+ - For all 16 bit timers: TIA
+ */
+ break;
+ case 1: m_timer_change[timer_index] += ((m_timer_pre >> s1) - (old_pre >> s1)); break;
+ case 2: m_timer_change[timer_index] += ((m_timer_pre >> s2) - (old_pre >> s2)); break;
+ case 3: m_timer_change[timer_index] += ((m_timer_pre >> s3) - (old_pre >> s3)); break;
+ }
+ };
+
+ auto const timer_8bits =
+ [this] (
+ uint8_t timer_index,
+ uint8_t timer_reg,
+ uint8_t interrupt,
+ uint8_t interrupt_mask,
+ uint8_t operating_mode,
+ bool invert)
+ {
+ for ( ; m_timer_change[timer_index] > 0; m_timer_change[timer_index]--)
+ {
+ m_timer_8[timer_index]++;
+ if (m_timer_8[timer_index] == m_treg_8[timer_reg])
+ {
+ if (BIT(timer_index, 0) == 0)
+ {
+ if (operating_mode == 0) // mode == MODE_8BIT_TIMER
+ m_timer_change[timer_index | 1]++;
+
+ // In 16-bit timer mode the timer should not be reset
+ if (operating_mode != 1) // mode != MODE_16BIT_TIMER
+ {
+ m_timer_8[timer_index] = 0;
+ m_int_reg[interrupt] |= interrupt_mask;
+ m_check_irqs = 1;
+ }
+ }
+ else
+ {
+ m_timer_8[timer_index] = 0;
+ m_int_reg[interrupt] |= interrupt_mask;
+ m_check_irqs = 1;
+
+ // In 16-bit timer mode also reset its 8-bit counterpart (timer N-1)
+ if (operating_mode == 1) // mode == MODE_16BIT_TIMER
+ m_timer_8[timer_index & ~1] = 0;
+ }
+
+ if (invert)
+ change_timer_flipflop(timer_index | 1, FF_INVERT);
+ }
+ }
+ };
+
+ auto const timer_16bits =
+ [this] (
+ uint8_t timer_id,
+ uint8_t timer_reg_low,
+ uint8_t timer_reg_high,
+ uint8_t tffcr,
+ uint8_t interrupt)
+ {
+ /*
+ timer_id 4 => m_timer_16[0] m_timer_change[4]
+ timer_id 6 => m_timer_16[1] m_timer_change[5]
+ timer_id 8 => m_timer_16[2] m_timer_change[6]
+ timer_id A => m_timer_16[3] m_timer_change[7]
+ */
+ uint8_t timer_index = (timer_id - 4)/2;
+
+ for ( ; m_timer_change[timer_index + 4] > 0; m_timer_change[timer_index + 4]--)
+ {
+ m_timer_16[timer_index]++;
+ // TODO: also check for criteria of up counter matching CAPn registers
+ if (((m_timer_16[timer_index] == m_treg_16[timer_reg_high]) && BIT(tffcr, 3)) ||
+ ((m_timer_16[timer_index] == m_treg_16[timer_reg_low]) && BIT(tffcr, 2)) )
+ {
+ change_timer_flipflop(timer_id, FF_INVERT);
+ m_timer_16[timer_index] = 0;
+ m_int_reg[interrupt] |= 0x08;
+ m_check_irqs = 1;
+ }
+ }
+ };
+
+ if (BIT(m_t16run, 7)) // prescaler is active
+ m_timer_pre += m_cycles;
+
+ if (BIT(m_t8run, 0)) // Timer 0 is running
+ {
+ update_timer_count(0, m_t01mod & 3, T1, T4, T16);
+ timer_8bits(
+ 0, TREG0, INTET01, 0x08,
+ (m_t01mod >> 6) & 3, // TO1_OPERATING_MODE
+ (m_tffcr & 3) == 2); // "FF1 Invert Enable" && "Invert by 8-bit timer 0"
+ }
+
+ if (BIT(m_t8run, 1)) // Timer 1 is running
+ {
+ update_timer_count(1, (m_t01mod >> 2) & 3, T1, T16, T256);
+ timer_8bits(
+ 1, TREG1, INTET01, 0x80,
+ (m_t01mod >> 6) & 3, // TO1_OPERATING_MODE
+ (m_tffcr & 3) == 3); // "FF1 Invert Enable" && "Invert by 8-bit timer 1"
+ }
+
+ if (BIT(m_t8run, 2)) // Timer 2 is running
+ {
+ update_timer_count(2, m_t23mod & 3, T1, T4, T16);
+ timer_8bits(
+ 2, TREG2, INTET23, 0x08,
+ (m_t23mod >> 6) & 3, // T23_OPERATING_MODE
+ ((m_tffcr >> 4) & 3) == 2); // "FF3 Invert Enable" && "Invert by 8-bit timer 2"
+ }
+
+ if (BIT(m_t8run, 3)) // Timer 3 is running
+ {
+ update_timer_count(3, (m_t23mod >> 2) & 3, T1, T16, T256);
+ timer_8bits(
+ 3, TREG3, INTET23, 0x80,
+ (m_t23mod >> 6) & 3, // T23_OPERATING_MODE
+ ((m_tffcr >> 4) & 3) == 3); // "FF3 Invert Enable" && "Invert by 8-bit timer 3"
+ }
+
+ if (BIT(m_t16run, 0)) // Timer 4 is running
+ {
+ update_timer_count(4, m_t4mod & 3, T1, T4, T16);
+ timer_16bits(4, TREG4, TREG5, m_t4ffcr, INTET45);
+ }
+
+ if (BIT(m_t16run, 1)) // Timer 6 is running
+ {
+ update_timer_count(5, m_t6mod & 3, T1, T4, T16);
+ timer_16bits(6, TREG6, TREG7, m_t6ffcr, INTET67);
+ }
+
+ if (BIT(m_t16run, 2)) // Timer 8 is running
+ {
+ update_timer_count(6, m_t8mod & 3, T1, T4, T16);
+ timer_16bits(8, TREG8, TREG9, m_t8ffcr, INTET89);
+ }
+
+ if (BIT(m_t16run, 3)) // Timer A is running
+ {
+ update_timer_count(7, m_tamod & 3, T1, T4, T16);
+ timer_16bits(0xa, TREGA, TREGB, m_taffcr, INTETAB);
+ }
+
+ m_timer_pre &= 0xffffff;
+}
+
+
+//-------------------------------------------------
+// execute_set_input - called when a synchronized
+// input is changed
+//-------------------------------------------------
+
+void tmp94c241_device::execute_set_input(int input, int level)
+{
+ auto const update_int_reg =
+ [this, level, input] (uint8_t reg, uint8_t mask)
+ {
+ if (level != m_level[input])
+ {
+ m_level[input] = level;
+ if (level == ASSERT_LINE)
+ m_int_reg[reg] |= mask;
+ else
+ m_int_reg[reg] &= ~mask;
+ }
+ };
+
+ switch (input)
+ {
+ case INPUT_LINE_NMI:
+ case TLCS900_NMI:
+ if (level != m_level[TLCS900_NMI])
+ {
+ m_level[TLCS900_NMI] = level;
+ if (level == ASSERT_LINE)
+ m_nmi_state = ASSERT_LINE;
+ }
+ break;
+
+ case TLCS900_INTWD:
+ break;
+
+ case TLCS900_INT0:
+ if (m_iimc & 0x02)
+ {
+ // Rising edge detect
+ if (level != m_level[TLCS900_INT0] && level == ASSERT_LINE)
+ {
+ // Leave HALT state
+ m_halted = 0;
+ m_int_reg[INTE0AD] |= 0x08;
+ }
+ m_level[TLCS900_INT0] = level;
+ }
+ else
+ {
+ // Level detect
+ update_int_reg(INTE0AD, 0x08);
+ }
+ break;
+
+ case TLCS900_INT4: update_int_reg(INTE45, 0x08); break;
+ case TLCS900_INT5: update_int_reg(INTE45, 0x80); break;
+ case TLCS900_INT6: update_int_reg(INTE67, 0x08); break;
+ case TLCS900_INT7: update_int_reg(INTE67, 0x80); break;
+ case TLCS900_INT8: update_int_reg(INTE89, 0x08); break;
+ case TLCS900_INT9: update_int_reg(INTE89, 0x80); break;
+ case TLCS900_INTA: update_int_reg(INTEAB, 0x08); break;
+ case TLCS900_INTB: update_int_reg(INTEAB, 0x80); break;
+
+ default:
+ // invalid
+ return;
+ }
+ m_check_irqs = 1;
+}
+
+std::unique_ptr<util::disasm_interface> tmp94c241_device::create_disassembler()
+{
+ return std::make_unique<tlcs900_disassembler>();
+}
diff --git a/src/devices/cpu/tlcs900/tmp94c241.h b/src/devices/cpu/tlcs900/tmp94c241.h
new file mode 100644
index 00000000000..bb83a748f73
--- /dev/null
+++ b/src/devices/cpu/tlcs900/tmp94c241.h
@@ -0,0 +1,279 @@
+// license:BSD-3-Clause
+// copyright-holders:AJR,Felipe Sanches
+/****************************************************************************
+
+ Toshiba TMP94C241 microcontroller
+
+****************************************************************************/
+
+#ifndef MAME_CPU_TLCS900_TMP94C241_H
+#define MAME_CPU_TLCS900_TMP94C241_H
+
+#pragma once
+
+#include "tlcs900.h"
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> tmp94c241_device
+
+class tmp94c241_device : public tlcs900h_device
+{
+ static constexpr uint8_t PORT_0 = 0; // 8 bit I/O. Shared with d0-d7
+ static constexpr uint8_t PORT_1 = 1; // 8 bit I/O. Shared with d8-d15
+ static constexpr uint8_t PORT_2 = 2; // 8 bit I/O. Shared with d16-d23
+ static constexpr uint8_t PORT_3 = 3; // 8 bit I/O. Shared with d24-d31
+ static constexpr uint8_t PORT_4 = 4; // 8 bit I/O. Shared with a0-a7
+ static constexpr uint8_t PORT_5 = 5; // 8 bit I/O. Shared with a8-a15
+ static constexpr uint8_t PORT_6 = 6; // 8 bit I/O. Shared with a16-a23
+ static constexpr uint8_t PORT_7 = 7; // 8 bit I/O. Shared with external memory & bus signals
+ static constexpr uint8_t PORT_8 = 8; // 7 bit I/O. Shared with chip-select signals
+ static constexpr uint8_t PORT_A = 9; // 5 bit I/O. Shared with external DRAM (channel 0)
+ static constexpr uint8_t PORT_B = 10; // 5 bit I/O. Shared with external DRAM (channel 1)
+ static constexpr uint8_t PORT_C = 11; // 2 bit I/O. Shared with outputs for 8-bit or 16-bit timers
+ static constexpr uint8_t PORT_D = 12; // 6 bit I/O. Shared with 16-bit timer I/O and interrupt input
+ static constexpr uint8_t PORT_E = 13; // 6 bit I/O. Shared with 8-bit or 16-bit timer output and interrupt input
+ static constexpr uint8_t PORT_F = 14; // 6 bit I/O. Shared with I/O functions of serial interface
+ static constexpr uint8_t PORT_G = 15; // 8 bit input-only. Shared with AD converter.
+ static constexpr uint8_t PORT_H = 16; // 5 bit I/O. Shared with /INT0 and micro DMA
+ static constexpr uint8_t PORT_Z = 17; // 8 bit I/O.
+ static constexpr uint8_t NUM_PORTS = 18;
+
+ static constexpr uint8_t TREG0 = 0;
+ static constexpr uint8_t TREG1 = 1;
+ static constexpr uint8_t TREG2 = 2;
+ static constexpr uint8_t TREG3 = 3;
+ static constexpr uint8_t TREG4 = 0;
+ static constexpr uint8_t TREG5 = 1;
+ static constexpr uint8_t TREG6 = 2;
+ static constexpr uint8_t TREG7 = 3;
+ static constexpr uint8_t TREG8 = 4;
+ static constexpr uint8_t TREG9 = 5;
+ static constexpr uint8_t TREGA = 6;
+ static constexpr uint8_t TREGB = 7;
+
+ static constexpr uint8_t CAP4 = 0;
+ static constexpr uint8_t CAP5 = 1;
+ static constexpr uint8_t CAP6 = 2;
+ static constexpr uint8_t CAP7 = 3;
+ static constexpr uint8_t CAP8 = 4;
+ static constexpr uint8_t CAP9 = 5;
+ static constexpr uint8_t CAPA = 6;
+ static constexpr uint8_t CAPB = 7;
+
+public:
+ // device type constructor
+ tmp94c241_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+ // configuration helpers
+ auto port0_read() { return m_port_read[PORT_0].bind(); }
+ auto port0_write() { return m_port_write[PORT_0].bind(); }
+ auto port1_read() { return m_port_read[PORT_1].bind(); }
+ auto port1_write() { return m_port_write[PORT_1].bind(); }
+ auto port2_read() { return m_port_read[PORT_2].bind(); }
+ auto port2_write() { return m_port_write[PORT_2].bind(); }
+ auto port3_read() { return m_port_read[PORT_3].bind(); }
+ auto port3_write() { return m_port_write[PORT_3].bind(); }
+ auto port4_read() { return m_port_read[PORT_4].bind(); }
+ auto port4_write() { return m_port_write[PORT_4].bind(); }
+ auto port5_read() { return m_port_read[PORT_5].bind(); }
+ auto port5_write() { return m_port_write[PORT_5].bind(); }
+ auto port6_read() { return m_port_read[PORT_6].bind(); }
+ auto port6_write() { return m_port_write[PORT_6].bind(); }
+ auto port7_read() { return m_port_read[PORT_7].bind(); }
+ auto port7_write() { return m_port_write[PORT_7].bind(); }
+ auto port8_read() { return m_port_read[PORT_8].bind(); }
+ auto port8_write() { return m_port_write[PORT_8].bind(); }
+ auto porta_read() { return m_port_read[PORT_A].bind(); }
+ auto porta_write() { return m_port_write[PORT_A].bind(); }
+ auto portb_read() { return m_port_read[PORT_B].bind(); }
+ auto portb_write() { return m_port_write[PORT_B].bind(); }
+ auto portc_read() { return m_port_read[PORT_C].bind(); }
+ auto portc_write() { return m_port_write[PORT_C].bind(); }
+ auto portd_read() { return m_port_read[PORT_D].bind(); }
+ auto portd_write() { return m_port_write[PORT_D].bind(); }
+ auto porte_read() { return m_port_read[PORT_E].bind(); }
+ auto porte_write() { return m_port_write[PORT_E].bind(); }
+ auto portf_read() { return m_port_read[PORT_F].bind(); }
+ auto portf_write() { return m_port_write[PORT_F].bind(); }
+ auto portg_read() { return m_port_read[PORT_G].bind(); }
+ auto porth_read() { return m_port_read[PORT_H].bind(); }
+ auto porth_write() { return m_port_write[PORT_H].bind(); }
+ auto portz_read() { return m_port_read[PORT_Z].bind(); }
+ auto portz_write() { return m_port_write[PORT_Z].bind(); }
+
+protected:
+ // device_t implementation
+ virtual void device_config_complete() override ATTR_COLD;
+ virtual void device_resolve_objects() override ATTR_COLD;
+ virtual void device_start() override ATTR_COLD;
+ virtual void device_reset() override ATTR_COLD;
+
+ // device_execute_interface overrides
+ virtual void execute_set_input(int inputnum, int state) override;
+
+ // tlcs900_device overrides
+ virtual void tlcs900_check_hdma() override;
+ virtual void tlcs900_check_irqs() override;
+ virtual void tlcs900_handle_ad() override;
+ virtual void tlcs900_handle_timers() override;
+
+ // device_disasm_interface overrides
+ virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
+
+private:
+ void change_timer_flipflop(uint8_t flipflop, uint8_t operation);
+
+ // Ports
+ template <uint8_t P> uint8_t port_r();
+ template <uint8_t P> void port_w(uint8_t data);
+ template <uint8_t P> void port_cr_w(uint8_t data);
+ template <uint8_t P> void port_fc_w(uint8_t data);
+
+ // Special Function Registers
+ template <uint8_t N> void bNcs_w(offs_t offset, uint16_t data, uint16_t mem_mask);
+ template <uint8_t Timer> uint16_t cap_r();
+ template <uint8_t N> uint8_t mamr_r();
+ template <uint8_t N> void mamr_w(uint8_t data);
+ template <uint8_t N> uint8_t msar_r();
+ template <uint8_t N> void msar_w(uint8_t data);
+ template <uint8_t Timer> void treg_8_w(uint8_t data);
+ template <uint8_t Timer> void treg_16_w(uint16_t data);
+ template <uint8_t Channel> uint8_t scNbuf_r();
+ template <uint8_t Channel> void scNbuf_w(uint8_t data);
+ template <uint8_t Channel> uint8_t scNcr_r();
+ template <uint8_t Channel> void scNcr_w(uint8_t data);
+ template <uint8_t Channel> uint8_t scNmod_r();
+ template <uint8_t Channel> void scNmod_w(uint8_t data);
+ template <uint8_t Channel> uint8_t brNcr_r();
+ template <uint8_t Channel> void brNcr_w(uint8_t data);
+ uint8_t t8run_r();
+ void t8run_w(uint8_t data);
+ uint8_t t01mod_r();
+ void t01mod_w(uint8_t data);
+ uint8_t tffcr_r();
+ void tffcr_w(uint8_t data);
+ uint8_t t23mod_r();
+ void t23mod_w(uint8_t data);
+ uint8_t trdc_r();
+ void trdc_w(uint8_t data);
+ uint8_t t4mod_r();
+ uint8_t t6mod_r();
+ uint8_t t8mod_r();
+ uint8_t tamod_r();
+ void t4mod_w(uint8_t data);
+ void t6mod_w(uint8_t data);
+ void t8mod_w(uint8_t data);
+ void tamod_w(uint8_t data);
+ uint8_t t4ffcr_r();
+ void t4ffcr_w(uint8_t data);
+ uint8_t t8ffcr_r();
+ void t8ffcr_w(uint8_t data);
+ uint8_t t6ffcr_r();
+ void t6ffcr_w(uint8_t data);
+ uint8_t taffcr_r();
+ void taffcr_w(uint8_t data);
+ uint8_t t16run_r();
+ void t16run_w(uint8_t data);
+ uint8_t wdmod_r();
+ void wdmod_w(uint8_t data);
+ void wdcr_w(uint8_t data);
+ uint8_t ode_r();
+ void ode_w(uint8_t data);
+ uint8_t admod1_r();
+ void admod1_w(uint8_t data);
+ uint8_t admod2_r();
+ void admod2_w(uint8_t data);
+ uint8_t adreg_r(offs_t offset);
+ uint8_t inte_r(offs_t offset);
+ void inte_w(offs_t offset, uint8_t data);
+ uint8_t intnmwdt_r(offs_t offset);
+ void intnmwdt_w(offs_t offset, uint8_t data);
+ void iimc_w(uint8_t data);
+ void intclr_w(uint8_t data);
+ void dmav_w(offs_t offset, uint8_t data);
+ uint8_t drefcr1_r();
+ void drefcr1_w(uint8_t data);
+ uint8_t dmemcr1_r();
+ void dmemcr1_w(uint8_t data);
+ uint8_t drefcr3_r();
+ void drefcr3_w(uint8_t data);
+ uint8_t dmemcr3_r();
+ void dmemcr3_w(uint8_t data);
+ uint8_t dadrv_r();
+ void dadrv_w(uint8_t data);
+ void dareg_w(offs_t offset, uint8_t data);
+
+ void internal_mem(address_map &map);
+
+ // analogue inputs, sampled at 10 bits
+ devcb_read16::array<8> m_an_read;
+
+ // I/O Ports
+ devcb_read8::array<NUM_PORTS> m_port_read;
+ devcb_write8::array<NUM_PORTS> m_port_write;
+ uint8_t m_port_latch[NUM_PORTS];
+ uint8_t m_port_control[NUM_PORTS];
+ uint8_t m_port_function[NUM_PORTS];
+
+ // Timer Control
+ bool m_timer_flipflops[12];
+ uint8_t m_t8run;
+ uint8_t m_t01mod;
+ uint8_t m_t23mod;
+ uint8_t m_t4mod;
+ uint8_t m_t6mod;
+ uint8_t m_t8mod;
+ uint8_t m_tamod;
+ uint8_t m_tffcr;
+ uint8_t m_t4ffcr;
+ uint8_t m_t6ffcr;
+ uint8_t m_t8ffcr;
+ uint8_t m_taffcr;
+ uint8_t m_trdc;
+ uint8_t m_t16run;
+ uint8_t m_treg_8[4]; // TREG0 - TREG3
+ uint16_t m_treg_16[8]; //TREG4 - TREGB
+ uint16_t m_t16_cap[8]; //CAP4 - CAPB
+ uint16_t m_timer_16[4]; // UPCOUNTERA - UPCOUNTERB
+
+ // Watchdog Timer
+ uint8_t m_watchdog_mode;
+
+ // Serial Channel
+ uint8_t m_serial_control[2];
+ uint8_t m_serial_mode[2];
+ uint8_t m_baud_rate[2];
+ uint8_t m_od_enable;
+
+ // A/D Converter Control
+ uint8_t m_ad_mode1;
+ uint8_t m_ad_mode2;
+ uint16_t m_ad_result[4];
+
+ // Interrupt Control
+ uint8_t m_int_reg[18];
+ uint8_t m_iimc;
+ uint8_t m_dma_vector[4];
+
+ // Chip Select/Wait Control
+ uint16_t m_block_cs[6];
+ uint8_t m_external_cs;
+ uint8_t m_msar[6];
+ uint8_t m_mamr[6];
+
+ // DRAM Control
+ uint8_t m_dram_refresh[2];
+ uint8_t m_dram_access[2];
+
+ // D/A Converter Control
+ uint8_t m_da_drive;
+};
+
+// device type declaration
+DECLARE_DEVICE_TYPE(TMP94C241, tmp94c241_device)
+
+#endif // MAME_CPU_TLCS900_TMP94C241_H
diff --git a/src/devices/cpu/tlcs900/tmp95c061.cpp b/src/devices/cpu/tlcs900/tmp95c061.cpp
index 55c591cc745..e6dbf029ac8 100644
--- a/src/devices/cpu/tlcs900/tmp95c061.cpp
+++ b/src/devices/cpu/tlcs900/tmp95c061.cpp
@@ -191,6 +191,15 @@ void tmp95c061_device::device_config_complete()
}
+void tmp95c061_device::device_resolve_objects()
+{
+ m_nmi_state = CLEAR_LINE;
+ for( int i = 0; i < TLCS900_NUM_INPUTS; i++ )
+ {
+ m_level[i] = CLEAR_LINE;
+ }
+}
+
void tmp95c061_device::device_start()
{
@@ -239,7 +248,6 @@ void tmp95c061_device::device_reset()
m_to3 = 0;
m_ad_cycles_left = 0;
- m_nmi_state = CLEAR_LINE;
m_timer_pre = 0;
m_timer_change[0] = 0;
m_timer_change[1] = 0;
@@ -289,11 +297,6 @@ void tmp95c061_device::device_reset()
std::fill_n(&m_mem_start_mask[0], 4, 0xff);
m_dram_refresh = 0x00;
m_dram_access = 0x80;
-
- for (int i = 0; i < TLCS900_NUM_INPUTS; i++)
- {
- m_level[i] = CLEAR_LINE;
- }
}
enum
@@ -492,11 +495,6 @@ void tmp95c061_device::tlcs900_check_hdma()
void tmp95c061_device::tlcs900_check_irqs()
{
- int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
- int level = 0;
- int irq = -1;
- int i;
-
/* Check for NMI */
if ( m_nmi_state == ASSERT_LINE )
{
@@ -516,7 +514,8 @@ void tmp95c061_device::tlcs900_check_irqs()
}
/* Check regular irqs */
- for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
+ int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ for( int i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c061_irq_vector_map[i].reg] & tmp95c061_irq_vector_map[i].iff )
{
@@ -533,7 +532,9 @@ void tmp95c061_device::tlcs900_check_irqs()
}
/* Check highest allowed priority irq */
- for ( i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
+ int irq = -1;
+ int level = 0;
+ for ( int i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
{
if ( irq_vectors[i] >= 0 )
{
@@ -690,8 +691,8 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[0] > 0; m_timer_change[0]-- )
{
- m_timer[0] += 1;
- if ( m_timer[0] == m_t8_reg[0] )
+ m_timer_8[0] += 1;
+ if ( m_timer_8[0] == m_t8_reg[0] )
{
if ( ( m_trun & 0x02 ) && ( m_t8_mode[0] & 0x0c ) == 0x00 )
{
@@ -701,7 +702,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
m_int_reg[INTET10] |= 0x08;
}
}
@@ -728,10 +729,10 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[1] > 0; m_timer_change[1]-- )
{
- m_timer[1] += 1;
- if ( m_timer[1] == m_t8_reg[1] )
+ m_timer_8[1] += 1;
+ if ( m_timer_8[1] == m_t8_reg[1] )
{
- m_timer[1] = 0;
+ m_timer_8[1] = 0;
m_int_reg[INTET10] |= 0x80;
if ( m_t8_invert & 0x02 )
@@ -742,7 +743,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 0 */
if ( ( m_t8_mode[0] & 0xc0 ) == 0x40 )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
}
}
}
@@ -767,8 +768,8 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[2] > 0; m_timer_change[2]-- )
{
- m_timer[2] += 1;
- if ( m_timer[2] == m_t8_reg[2] )
+ m_timer_8[2] += 1;
+ if ( m_timer_8[2] == m_t8_reg[2] )
{
if ( ( m_trun & 0x08 ) && ( m_t8_mode[1] & 0x0c ) == 0x00 )
{
@@ -778,7 +779,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
m_int_reg[INTET32] |= 0x08;
}
}
@@ -805,10 +806,10 @@ void tmp95c061_device::tlcs900_handle_timers()
for( ; m_timer_change[3] > 0; m_timer_change[3]-- )
{
- m_timer[3] += 1;
- if ( m_timer[3] == m_t8_reg[3] )
+ m_timer_8[3] += 1;
+ if ( m_timer_8[3] == m_t8_reg[3] )
{
- m_timer[3] = 0;
+ m_timer_8[3] = 0;
m_int_reg[INTET32] |= 0x80;
if ( m_t8_invert & 0x20 )
@@ -819,7 +820,7 @@ void tmp95c061_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 2 */
if ( ( m_t8_mode[1] & 0xc0 ) == 0x40 )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
}
}
}
@@ -916,28 +917,28 @@ void tmp95c061_device::trun_w(uint8_t data)
{
if ( ! ( data & 0x01 ) )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
m_timer_change[0] = 0;
}
if ( ! ( data & 0x02 ) )
{
- m_timer[1] = 0;
+ m_timer_8[1] = 0;
m_timer_change[1] = 0;
}
if ( ! ( data & 0x04 ) )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
m_timer_change[2] = 0;
}
if ( ! ( data & 0x08 ) )
{
- m_timer[3] = 0;
+ m_timer_8[3] = 0;
m_timer_change[3] = 0;
}
if ( ! ( data & 0x10 ) )
- m_timer[4] = 0;
+ m_timer_8[4] = 0;
if ( ! ( data & 0x20 ) )
- m_timer[5] = 0;
+ m_timer_8[5] = 0;
m_trun = data;
}
diff --git a/src/devices/cpu/tlcs900/tmp95c061.h b/src/devices/cpu/tlcs900/tmp95c061.h
index 7b52057fa2d..031ba79f727 100644
--- a/src/devices/cpu/tlcs900/tmp95c061.h
+++ b/src/devices/cpu/tlcs900/tmp95c061.h
@@ -47,7 +47,8 @@ public:
template <size_t Bit> auto an_read() { return m_an_read[Bit].bind(); }
protected:
- virtual void device_config_complete() override;
+ virtual void device_config_complete() override ATTR_COLD;
+ virtual void device_resolve_objects() override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
diff --git a/src/devices/cpu/tlcs900/tmp95c063.cpp b/src/devices/cpu/tlcs900/tmp95c063.cpp
index 05b79834eb5..23f4025a411 100644
--- a/src/devices/cpu/tlcs900/tmp95c063.cpp
+++ b/src/devices/cpu/tlcs900/tmp95c063.cpp
@@ -271,8 +271,8 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[0] > 0; m_timer_change[0]-- )
{
- m_timer[0] += 1;
- if ( m_timer[0] == m_t8_reg[0] )
+ m_timer_8[0] += 1;
+ if ( m_timer_8[0] == m_t8_reg[0] )
{
if ( ( m_t8run & 0x02 ) && ( m_t8_mode[0] & 0x0c ) == 0x00 )
{
@@ -282,7 +282,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[0] & 0xc0 ) != 0x40 )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
m_int_reg[INTET01] |= 0x08;
}
}
@@ -309,10 +309,10 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[1] > 0; m_timer_change[1]-- )
{
- m_timer[1] += 1;
- if ( m_timer[1] == m_t8_reg[1] )
+ m_timer_8[1] += 1;
+ if ( m_timer_8[1] == m_t8_reg[1] )
{
- m_timer[1] = 0;
+ m_timer_8[1] = 0;
m_int_reg[INTET01] |= 0x80;
if ( m_t8_invert[0] & 0x02 )
@@ -323,7 +323,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 0 */
if ( ( m_t8_mode[0] & 0xc0 ) == 0x40 )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
}
}
}
@@ -348,8 +348,8 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[2] > 0; m_timer_change[2]-- )
{
- m_timer[2] += 1;
- if ( m_timer[2] == m_t8_reg[2] )
+ m_timer_8[2] += 1;
+ if ( m_timer_8[2] == m_t8_reg[2] )
{
if ( ( m_t8run & 0x08 ) && ( m_t8_mode[1] & 0x0c ) == 0x00 )
{
@@ -359,7 +359,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode the timer should not be reset */
if ( ( m_t8_mode[1] & 0xc0 ) != 0x40 )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
m_int_reg[INTET23] |= 0x08;
}
}
@@ -386,10 +386,10 @@ void tmp95c063_device::tlcs900_handle_timers()
for( ; m_timer_change[3] > 0; m_timer_change[3]-- )
{
- m_timer[3] += 1;
- if ( m_timer[3] == m_t8_reg[3] )
+ m_timer_8[3] += 1;
+ if ( m_timer_8[3] == m_t8_reg[3] )
{
- m_timer[3] = 0;
+ m_timer_8[3] = 0;
m_int_reg[INTET23] |= 0x80;
if ( m_t8_invert[1] & 0x20 )
@@ -400,7 +400,7 @@ void tmp95c063_device::tlcs900_handle_timers()
/* In 16bit timer mode also reset timer 2 */
if ( ( m_t8_mode[1] & 0xc0 ) == 0x40 )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
}
}
}
@@ -416,11 +416,6 @@ void tmp95c063_device::tlcs900_check_hdma()
void tmp95c063_device::tlcs900_check_irqs()
{
- int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
- int level = 0;
- int irq = -1;
- int i;
-
/* Check for NMI */
if ( m_nmi_state == ASSERT_LINE )
{
@@ -440,7 +435,8 @@ void tmp95c063_device::tlcs900_check_irqs()
}
/* Check regular irqs */
- for( i = 0; i < NUM_MASKABLE_IRQS; i++ )
+ int irq_vectors[9] = { -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ for( int i = 0; i < NUM_MASKABLE_IRQS; i++ )
{
if ( m_int_reg[tmp95c063_irq_vector_map[i].reg] & tmp95c063_irq_vector_map[i].iff )
{
@@ -457,7 +453,9 @@ void tmp95c063_device::tlcs900_check_irqs()
}
/* Check highest allowed priority irq */
- for ( i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
+ int irq = -1;
+ int level = 0;
+ for ( int i = std::max( 1, ( ( m_sr.b.h & 0x70 ) >> 4 ) ); i < 7; i++ )
{
if ( irq_vectors[i] >= 0 )
{
@@ -557,6 +555,15 @@ void tmp95c063_device::tlcs900_handle_ad()
}
+void tmp95c063_device::device_resolve_objects()
+{
+ m_nmi_state = CLEAR_LINE;
+ for( int i = 0; i < TLCS900_NUM_INPUTS; i++ )
+ {
+ m_level[i] = CLEAR_LINE;
+ }
+}
+
void tmp95c063_device::device_start()
{
tlcs900h_device::device_start();
@@ -602,7 +609,6 @@ void tmp95c063_device::device_reset()
tlcs900h_device::device_reset();
m_ad_cycles_left = 0;
- m_nmi_state = CLEAR_LINE;
m_timer_pre = 0;
m_timer_change[0] = 0;
m_timer_change[1] = 0;
@@ -655,9 +661,6 @@ void tmp95c063_device::device_reset()
std::fill_n(&m_dram_refresh[0], 2, 0x00);
std::fill_n(&m_dram_access[0], 2, 0x80);
m_da_drive = 0x00;
-
- for (int i = 0; i < TLCS900_NUM_INPUTS; i++)
- m_level[i] = CLEAR_LINE;
}
uint8_t tmp95c063_device::t8run_r()
@@ -669,28 +672,28 @@ void tmp95c063_device::t8run_w(uint8_t data)
{
if ( ! ( data & 0x01 ) )
{
- m_timer[0] = 0;
+ m_timer_8[0] = 0;
m_timer_change[0] = 0;
}
if ( ! ( data & 0x02 ) )
{
- m_timer[1] = 0;
+ m_timer_8[1] = 0;
m_timer_change[1] = 0;
}
if ( ! ( data & 0x04 ) )
{
- m_timer[2] = 0;
+ m_timer_8[2] = 0;
m_timer_change[2] = 0;
}
if ( ! ( data & 0x08 ) )
{
- m_timer[3] = 0;
+ m_timer_8[3] = 0;
m_timer_change[3] = 0;
}
if ( ! ( data & 0x10 ) )
- m_timer[4] = 0;
+ m_timer_8[4] = 0;
if ( ! ( data & 0x20 ) )
- m_timer[5] = 0;
+ m_timer_8[5] = 0;
m_t8run = data;
}
diff --git a/src/devices/cpu/tlcs900/tmp95c063.h b/src/devices/cpu/tlcs900/tmp95c063.h
index acbcfc10f3c..32033aad155 100644
--- a/src/devices/cpu/tlcs900/tmp95c063.h
+++ b/src/devices/cpu/tlcs900/tmp95c063.h
@@ -57,7 +57,8 @@ public:
template <size_t Bit> auto an_read() { return m_an_read[Bit].bind(); }
protected:
- virtual void device_config_complete() override;
+ virtual void device_config_complete() override ATTR_COLD;
+ virtual void device_resolve_objects() override ATTR_COLD;
virtual void device_start() override ATTR_COLD;
virtual void device_reset() override ATTR_COLD;
diff --git a/src/mame/matsushita/kn5000.cpp b/src/mame/matsushita/kn5000.cpp
index 64023b65aaa..d6678bdad5b 100644
--- a/src/mame/matsushita/kn5000.cpp
+++ b/src/mame/matsushita/kn5000.cpp
@@ -7,7 +7,7 @@
******************************************************************************/
#include "emu.h"
-#include "cpu/tlcs900/tmp95c061.h" // TODO: tmp94c241.h
+#include "cpu/tlcs900/tmp94c241.h"
#include "imagedev/floppy.h"
#include "machine/gen_latch.h"
#include "machine/upd765.h"
@@ -109,8 +109,8 @@ public:
void kn5000(machine_config &config);
private:
- required_device<tmp95c061_device> m_maincpu;
- required_device<tmp95c061_device> m_subcpu;
+ required_device<tmp94c241_device> m_maincpu;
+ required_device<tmp94c241_device> m_subcpu;
required_device<generic_latch_8_device> m_maincpu_latch;
required_device<generic_latch_8_device> m_subcpu_latch;
required_device<upd72067_device> m_fdc;
@@ -197,6 +197,37 @@ static INPUT_PORTS_START(kn5000)
PORT_DIPSETTING( 0xb0, "PC2")
PORT_DIPSETTING( 0x70, "Mac")
+ PORT_START("AREA")
+ PORT_DIPNAME(0x06, 0x06, "Area Selection")
+ PORT_DIPSETTING( 0x02, "Thailand, Indonesia, Iran, U.A.E., Panama, Argentina, Peru, Brazil")
+ PORT_DIPSETTING( 0x04, "USA, Mexico")
+ PORT_DIPSETTING( 0x06, "Other")
+
+/*
+ Actual full list of regions (but it is unclear if there's any
+ other hardware difference among them):
+
+ PORT_DIPSETTING( 0x04, "(M): U.S.A.")
+ PORT_DIPSETTING( 0x06, "(MC): Canada")
+ PORT_DIPSETTING( 0x04, "(XM): Mexico")
+ PORT_DIPSETTING( 0x06, "(EN): Norway, Sweden, Denmark, Finland")
+ PORT_DIPSETTING( 0x06, "(EH): Holland, Belgium")
+ PORT_DIPSETTING( 0x06, "(EF): France, Italy")
+ PORT_DIPSETTING( 0x06, "(EZ): Germany")
+ PORT_DIPSETTING( 0x06, "(EW): Switzerland")
+ PORT_DIPSETTING( 0x06, "(EA): Austria")
+ PORT_DIPSETTING( 0x06, "(EP): Spain, Portugal, Greece, South Africa")
+ PORT_DIPSETTING( 0x06, "(EK): United Kingdom")
+ PORT_DIPSETTING( 0x06, "(XL): New Zealand")
+ PORT_DIPSETTING( 0x06, "(XR): Australia")
+ PORT_DIPSETTING( 0x06, "(XS): Malaysia")
+ PORT_DIPSETTING( 0x06, "(MD): Saudi Arabia, Hong Kong, Kuwait")
+ PORT_DIPSETTING( 0x06, "(XT): Taiwan")
+ PORT_DIPSETTING( 0x02, "(X): Thailand, Indonesia, Iran, U.A.E., Panama, Argentina, Peru, Brazil")
+ PORT_DIPSETTING( 0x06, "(XP): Philippines")
+ PORT_DIPSETTING( 0x06, "(XW): Singapore")
+*/
+
PORT_START("CPR_SEG0")
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
@@ -604,7 +635,7 @@ void kn5000_state::machine_reset()
void kn5000_state::kn5000(machine_config &config)
{
// Note: The CPU has an internal clock doubler
- TMP95C061(config, m_maincpu, 2 * 8_MHz_XTAL); // actual cpu is TMP94C241F @ IC5
+ TMP94C241(config, m_maincpu, 2 * 8_MHz_XTAL); // TMP94C241F @ IC5
// Address bus is set to 32 bits by the pins AM1=+5v and AM0=GND
m_maincpu->set_addrmap(AS_PROGRAM, &kn5000_state::maincpu_mem);
// Interrupt 4: FDCINT
@@ -636,14 +667,16 @@ void kn5000_state::kn5000(machine_config &config)
// MAINCPU PORT C:
// bit 0 (input) = "check terminal" switch
// bit 1 (output) = "check terminal" LED
- // TODO: m_maincpu->portc_read().set([this] { return ioport("CN11")->read(); });
- // TODO: m_maincpu->portc_write().set([this] (u8 data) { m_checking_device_led_cn11 = (BIT(data, 1) == 0); });
+ m_maincpu->portc_read().set_ioport("CN11");
+ m_maincpu->portc_write().set([this] (u8 data) {
+ m_checking_device_led_cn11 = (BIT(data, 1) == 0);
+ });
// MAINCPU PORT D:
// bit 0 (output) = FDCRST
// bit 6 (input) = FD.I/O
- // TODO: m_maincpu->portd_write().set([this] (u8 data) { m_fdc->reset_w(BIT(data, 0)); });
+ m_maincpu->portd_write().set(m_fdc, FUNC(upd72067_device::reset_w)).bit(0);
// TODO: bit 6!
@@ -651,7 +684,7 @@ void kn5000_state::kn5000(machine_config &config)
// bit 0 (input) = +5v
// bit 2 (input) = HDDRDY
// bit 4 (?) = MICSNS
- // TODO: m_maincpu->porte_read().set([] { return 1; }); //checked at EF05A6 (v10 ROM)
+ m_maincpu->porte_read().set_constant(1); //checked at EF05A6 (v10 ROM)
// FIXME: Bit 0 should only be 1 if the
// optional hard-drive extension board is disabled;
@@ -670,10 +703,7 @@ void kn5000_state::kn5000(machine_config &config)
// MAINCPU PORT H:
- // bit 1 = TC1 Terminal count - microDMA
- // TODO: m_maincpu->porth_read().set([] { return 2; }); // area/region detection: checked at EF083E (v10 ROM)
- // FIXME: These are resistors on the pcb, but could be declared
- // in the driver as a 2 bit DIP-Switch for area/region selection.
+ m_maincpu->porth_read().set_ioport("AREA"); // checked at EF083E (v10 ROM)
// MAINCPU PORT Z:
@@ -701,15 +731,18 @@ void kn5000_state::kn5000(machine_config &config)
// AN1 = AFT
// Note: The CPU has an internal clock doubler
- TMP95C061(config, m_subcpu, 2*10_MHz_XTAL); // actual cpu is TMP94C241F @ IC27
+ TMP94C241(config, m_subcpu, 2*10_MHz_XTAL); // TMP94C241F @ IC27
// Address bus is set to 8 bits by the pins AM1=GND and AM0=GND
m_subcpu->set_addrmap(AS_PROGRAM, &kn5000_state::subcpu_mem);
// SUBCPU PORT C:
// bit 0 (input) = "check terminal" switch
// bit 1 (output) = "check terminal" LED
- // TODO: m_subcpu->portc_read().set([this] { return ioport("CN12")->read(); });
- // TODO: m_subcpu->portc_write().set([this] (u8 data) { m_checking_device_led_cn12 = (BIT(data, 1) == 0); });
+ m_subcpu->portc_read().set_ioport("CN12");
+ m_subcpu->portc_write().set([this] (u8 data) {
+ m_checking_device_led_cn12 = (BIT(data, 1) == 0);
+ });
+
// SUBCPU PORT D:
// bit 0 = (output) SSTAT0
@@ -717,12 +750,12 @@ void kn5000_state::kn5000(machine_config &config)
// bit 2 = (input) MSTAT0
// bit 3 (not used)
// bit 4 = (input) MSTAT1
- // TODO: m_subcpu->portd_read().set([this] {
- // TODO: return (BIT(m_mstat, 0) << 2) | (BIT(m_mstat, 1) << 4);
- // TODO: });
- // TODO: m_subcpu->portd_write().set([this] (u8 data) {
- // TODO: m_sstat = data & 3;
- // TODO: });
+ m_subcpu->portd_read().set([this] {
+ return (BIT(m_mstat, 0) << 2) | (BIT(m_mstat, 1) << 4);
+ });
+ m_subcpu->portd_write().set([this] (u8 data) {
+ m_sstat = data & 3;
+ });
GENERIC_LATCH_8(config, m_maincpu_latch); // @ IC23