diff options
Diffstat (limited to 'src/mame/drivers/intellec4.cpp')
-rw-r--r-- | src/mame/drivers/intellec4.cpp | 536 |
1 files changed, 469 insertions, 67 deletions
diff --git a/src/mame/drivers/intellec4.cpp b/src/mame/drivers/intellec4.cpp index 8451e8f270d..75955064eec 100644 --- a/src/mame/drivers/intellec4.cpp +++ b/src/mame/drivers/intellec4.cpp @@ -14,6 +14,8 @@ #include "cpu/mcs40/mcs40.h" #include "machine/bankdev.h" +#include "intlc440.lh" + namespace { @@ -24,11 +26,15 @@ public: : driver_device(mconfig, type, tag) , m_cpu(*this, "maincpu") , m_program_banks(*this, "prgbank") - , m_io_banks(*this, "iobank") + , m_rom_port_banks(*this, "rpbank") + , m_ram_port_banks(*this, "mpbank") , m_bus(*this, "bus") , m_tty(*this, "tty") , m_ram(*this, "ram") , m_sw_mode(*this, "MODE") + , m_sw_control(*this, "CONTROL") + , m_sw_addr_data(*this, "ADDRDAT") + , m_sw_passes(*this, "PASSES") { } @@ -45,6 +51,7 @@ public: DECLARE_WRITE8_MEMBER(ram0_out); DECLARE_WRITE8_MEMBER(ram1_out); + void bus_cycle(mcs40_cpu_device_base::phase step, u8 sync, u8 data); DECLARE_WRITE_LINE_MEMBER(stp_ack); // universal slot outputs @@ -53,13 +60,20 @@ public: DECLARE_WRITE_LINE_MEMBER(bus_reset_4002); DECLARE_WRITE_LINE_MEMBER(bus_user_reset); - // edge-sensitive front-panel switches + // front panel switches DECLARE_INPUT_CHANGED_MEMBER(sw_stop); DECLARE_INPUT_CHANGED_MEMBER(sw_single_step); DECLARE_INPUT_CHANGED_MEMBER(sw_reset); DECLARE_INPUT_CHANGED_MEMBER(sw_mon); DECLARE_INPUT_CHANGED_MEMBER(sw_ram); DECLARE_INPUT_CHANGED_MEMBER(sw_prom); + DECLARE_INPUT_CHANGED_MEMBER(sw_run); + DECLARE_INPUT_CHANGED_MEMBER(sw_next_inst); + DECLARE_INPUT_CHANGED_MEMBER(sw_decr); + DECLARE_INPUT_CHANGED_MEMBER(sw_incr); + DECLARE_INPUT_CHANGED_MEMBER(sw_load); + DECLARE_INPUT_CHANGED_MEMBER(sw_cma_enable); + DECLARE_INPUT_CHANGED_MEMBER(sw_cma_write); protected: virtual void driver_start() override; @@ -82,7 +96,15 @@ private: BIT_SW_RESET, BIT_SW_MON, BIT_SW_RAM, - BIT_SW_PROM + BIT_SW_PROM, + + BIT_SW_RUN = 0, + BIT_SW_NEXT_INST, + BIT_SW_DECR, + BIT_SW_INCR, + BIT_SW_LOAD, + BIT_SW_CMA_ENABLE, + BIT_SW_CMA_WRITE }; enum : ioport_value { @@ -91,22 +113,34 @@ private: MASK_SW_RESET = 1U << BIT_SW_RESET, MASK_SW_MON = 1U << BIT_SW_MON, MASK_SW_RAM = 1U << BIT_SW_RAM, - MASK_SW_PROM = 1U << BIT_SW_PROM + MASK_SW_PROM = 1U << BIT_SW_PROM, + + MASK_SW_DECR = 1U << BIT_SW_DECR, + MASK_SW_INCR = 1U << BIT_SW_INCR, + MASK_SW_LOAD = 1U << BIT_SW_LOAD, + MASK_SW_CMA_ENABLE = 1U << BIT_SW_CMA_ENABLE, + MASK_SW_CMA_WRITE = 1U << BIT_SW_CMA_WRITE }; TIMER_CALLBACK_MEMBER(single_step_expired); TIMER_CALLBACK_MEMBER(reset_expired); void trigger_reset(); - - required_device<cpu_device> m_cpu; - required_device<address_map_bank_device> m_program_banks, m_io_banks; + void reset_panel(); + void display_address(u16 value, u16 mask); + void display_instruction(u8 value, u8 mask); + void display_active_bank(u8 value); + void display_execution(u8 value, u8 mask); + void display_pointer(u8 value, u8 mask); + + required_device<mcs40_cpu_device_base> m_cpu; + required_device<address_map_bank_device> m_program_banks, m_rom_port_banks, m_ram_port_banks; required_device<bus::intellec4::univ_bus_device> m_bus; required_device<rs232_port_device> m_tty; required_shared_ptr<u8> m_ram; - required_ioport m_sw_mode; + required_ioport m_sw_mode, m_sw_control, m_sw_addr_data, m_sw_passes; emu_timer *m_single_step_timer = nullptr; emu_timer *m_reset_timer = nullptr; @@ -116,9 +150,18 @@ private: bool m_ram_write = false; // control board state - bool m_stp_ack = false, m_single_step = false; + bool m_stp_ack = false, m_single_step = false, m_cpu_reset = false; bool m_ff_mon = true, m_ff_ram = false, m_ff_prom = false; + // front panel state + u16 m_latched_addr = 0U, m_display_addr = 0U; + u8 m_display_instr = 0U, m_display_bank = 0U, m_display_exec = 0U, m_display_ptr = 0U; + u8 m_pass_counter = 0U; + bool m_panel_reset = false; + bool m_next_inst = false, m_adr_cmp_latch = false, m_search_complete = false; + bool m_src = false, m_pointer_valid = false; + bool m_cma_enable = false, m_cma_write = false; + // current state of signals from bus bool m_bus_stop = false, m_bus_reset_4002 = false, m_bus_user_reset = false; @@ -126,6 +169,7 @@ private: bool m_sw_stop = false; bool m_sw_reset = false; bool m_sw_mon = false, m_sw_ram = false, m_sw_prom = false; + bool m_sw_run = false; }; @@ -196,6 +240,83 @@ WRITE8_MEMBER(intellec4_40_state::ram1_out) m_tty->write_rts(BIT(~data, 0)); } +void intellec4_40_state::bus_cycle(mcs40_cpu_device_base::phase step, u8 sync, u8 data) +{ + switch (step) + { + case mcs40_cpu_device_base::phase::A1: + if (m_cma_enable) + { + display_address(m_latched_addr, 0x0fffU); + display_instruction(m_ram[m_latched_addr], 0xffU); + } + else if (!m_search_complete) + { + display_address(u16(data), 0x000fU); + m_src = false; + } + if (m_cma_write) + { + m_ram[m_latched_addr] = u8(~m_sw_addr_data->read() & 0x00ffU); + m_cma_write = false; + } + break; + case mcs40_cpu_device_base::phase::A2: + if (!m_search_complete && !m_cma_enable) + display_address(u16(data) << 4, 0x00f0U); + break; + case mcs40_cpu_device_base::phase::A3: + if (!m_search_complete && !m_cma_enable) + { + display_address(u16(data) << 8, 0x0f00U); + display_active_bank(~m_cpu->get_cm_ram()); + } + break; + case mcs40_cpu_device_base::phase::M1: + if (!m_search_complete && !m_cma_enable) + display_instruction(data << 4, 0xf0U); + break; + case mcs40_cpu_device_base::phase::M2: + if (!m_search_complete && !m_cma_enable) + display_instruction(data, 0x0fU); + break; + case mcs40_cpu_device_base::phase::X1: + // not connected to anything + break; + case mcs40_cpu_device_base::phase::X2: + if (!m_search_complete && !m_cma_enable) + { + display_execution(data << 4, 0xf0U); + m_src = BIT(~m_cpu->get_cm_rom(), 0); + if (m_src) + display_pointer(data << 4, 0xf0U); + } + break; + case mcs40_cpu_device_base::phase::X3: + if (m_search_complete != m_adr_cmp_latch) + machine().output().set_value("led_status_search", m_search_complete = m_adr_cmp_latch); + if (!m_search_complete && !m_cma_enable) + { + display_execution(data, 0x0fU); + if (m_src) + { + display_pointer(data, 0x0fU); + if (!m_panel_reset && !m_pointer_valid) + machine().output().set_value("led_status_ptr_valid", m_pointer_valid = true); + } + } + if (!m_panel_reset && !m_adr_cmp_latch) + m_adr_cmp_latch = (m_latched_addr == m_display_addr) && !((m_pass_counter ^ m_sw_passes->read()) & 0x0fU); + if (!m_search_complete && !m_panel_reset && !m_cma_enable && !m_sw_run && (m_latched_addr == m_display_addr)) + m_pass_counter = (m_pass_counter + 1U) & 0x0fU; + if (m_adr_cmp_latch && !m_next_inst && !m_search_complete) + machine().output().set_value("led_status_search", m_search_complete = true); + if (!m_cpu_reset && !m_cma_enable && !m_sw_run) + m_panel_reset = false; + break; + } +} + WRITE_LINE_MEMBER(intellec4_40_state::stp_ack) { // resets the single-step monostable @@ -287,7 +408,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_mon) if (!m_ff_mon) { m_program_banks->set_bank(BANK_PRG_MON); - m_io_banks->set_bank(BANK_IO_MON); + m_rom_port_banks->set_bank(BANK_IO_MON); + m_ram_port_banks->set_bank(BANK_IO_MON); machine().output().set_value("led_mode_mon", m_ff_mon = true); } trigger_reset(); @@ -295,7 +417,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_mon) else { m_program_banks->set_bank(BANK_PRG_NONE); - m_io_banks->set_bank(BANK_IO_NEITHER); + m_rom_port_banks->set_bank(BANK_IO_NEITHER); + m_ram_port_banks->set_bank(BANK_IO_NEITHER); } if (m_ff_ram) machine().output().set_value("led_mode_ram", m_ff_ram = false); @@ -314,7 +437,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_ram) if (!m_ff_ram) { m_program_banks->set_bank(BANK_PRG_RAM); - m_io_banks->set_bank(BANK_IO_NEITHER); + m_rom_port_banks->set_bank(BANK_IO_NEITHER); + m_ram_port_banks->set_bank(BANK_IO_NEITHER); machine().output().set_value("led_mode_ram", m_ff_ram = true); } trigger_reset(); @@ -322,7 +446,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_ram) else { m_program_banks->set_bank(BANK_PRG_NONE); - m_io_banks->set_bank(BANK_IO_NEITHER); + m_rom_port_banks->set_bank(BANK_IO_NEITHER); + m_ram_port_banks->set_bank(BANK_IO_NEITHER); } if (m_ff_mon) machine().output().set_value("led_mode_mon", m_ff_mon = false); @@ -341,7 +466,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_prom) if (!m_ff_prom) { m_program_banks->set_bank(BANK_PRG_PROM); - m_io_banks->set_bank(BANK_IO_PROM); + m_rom_port_banks->set_bank(BANK_IO_PROM); + m_ram_port_banks->set_bank(BANK_IO_PROM); machine().output().set_value("led_mode_prom", m_ff_prom = true); } trigger_reset(); @@ -349,7 +475,8 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_prom) else { m_program_banks->set_bank(BANK_PRG_NONE); - m_io_banks->set_bank(BANK_IO_NEITHER); + m_rom_port_banks->set_bank(BANK_IO_NEITHER); + m_ram_port_banks->set_bank(BANK_IO_NEITHER); } if (m_ff_mon) machine().output().set_value("led_mode_mon", m_ff_mon = false); @@ -359,6 +486,61 @@ INPUT_CHANGED_MEMBER(intellec4_40_state::sw_prom) m_sw_prom = !bool(newval); } +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_run) +{ + m_sw_run = !bool(newval); + if (m_sw_run) + reset_panel(); +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_next_inst) +{ + m_next_inst = !bool(newval); +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_decr) +{ + // connected to a pulse generator circuit + if (newval && !oldval) + { + m_latched_addr = (m_latched_addr - 1U) & 0x0fffU; + reset_panel(); + } +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_incr) +{ + // connected to a pulse generator circuit + if (newval && !oldval) + { + m_latched_addr = (m_latched_addr + 1U) & 0x0fffU; + reset_panel(); + } +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_load) +{ + // connected to a pulse generator circuit + if (newval && !oldval) + { + m_latched_addr = ~m_sw_addr_data->read() & 0x0fffU; + reset_panel(); + } +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_cma_enable) +{ + m_cma_enable = bool(newval); + if (m_cma_enable) + reset_panel(); +} + +INPUT_CHANGED_MEMBER(intellec4_40_state::sw_cma_write) +{ + if (newval && !oldval) + m_cma_write = m_cma_enable; +} + void intellec4_40_state::driver_start() { @@ -371,10 +553,27 @@ void intellec4_40_state::driver_start() save_item(NAME(m_stp_ack)); save_item(NAME(m_single_step)); + save_item(NAME(m_cpu_reset)); save_item(NAME(m_ff_mon)); save_item(NAME(m_ff_ram)); save_item(NAME(m_ff_prom)); + save_item(NAME(m_latched_addr)); + save_item(NAME(m_display_addr)); + save_item(NAME(m_display_instr)); + save_item(NAME(m_display_bank)); + save_item(NAME(m_display_exec)); + save_item(NAME(m_display_ptr)); + save_item(NAME(m_pass_counter)); + save_item(NAME(m_next_inst)); + save_item(NAME(m_panel_reset)); + save_item(NAME(m_adr_cmp_latch)); + save_item(NAME(m_search_complete)); + save_item(NAME(m_src)); + save_item(NAME(m_pointer_valid)); + save_item(NAME(m_cma_enable)); + save_item(NAME(m_cma_write)); + save_item(NAME(m_bus_stop)); save_item(NAME(m_bus_reset_4002)); save_item(NAME(m_bus_user_reset)); @@ -383,6 +582,7 @@ void intellec4_40_state::driver_start() save_item(NAME(m_sw_reset)); save_item(NAME(m_sw_mon)); save_item(NAME(m_sw_ram)); + save_item(NAME(m_sw_run)); m_stp_ack = m_single_step = false; m_ff_mon = true; @@ -392,15 +592,26 @@ void intellec4_40_state::driver_start() void intellec4_40_state::driver_reset() { // set stuff according to initial state of front panel - ioport_value const sw_mode(m_sw_mode->read()); - m_sw_stop = BIT(~sw_mode, BIT_SW_STOP); - m_sw_reset = BIT(~sw_mode, BIT_SW_RESET); - m_sw_mon = BIT(~sw_mode, BIT_SW_MON); - m_sw_ram = BIT(~sw_mode, BIT_SW_RAM); - m_sw_prom = BIT(~sw_mode, BIT_SW_PROM); + ioport_value const sw_mode(m_sw_mode->read()), sw_control(m_sw_control->read()); + m_sw_stop = BIT(~sw_mode, BIT_SW_STOP); + m_sw_reset = BIT(~sw_mode, BIT_SW_RESET); + m_sw_mon = BIT(~sw_mode, BIT_SW_MON); + m_sw_ram = BIT(~sw_mode, BIT_SW_RAM); + m_sw_prom = BIT(~sw_mode, BIT_SW_PROM); + m_sw_run = BIT(~sw_control, BIT_SW_RUN); + m_next_inst = BIT(~sw_control, BIT_SW_NEXT_INST); + m_cma_enable = BIT( sw_control, BIT_SW_CMA_ENABLE); m_ff_mon = m_ff_mon && !m_sw_ram && !m_sw_prom; m_ff_ram = m_ff_ram && !m_sw_mon && !m_sw_prom; m_ff_prom = m_ff_prom && !m_sw_mon && !m_sw_ram; + m_panel_reset = m_panel_reset || m_cma_enable || m_sw_run; + if (m_panel_reset) + { + m_pass_counter = 0U; + m_adr_cmp_latch = false; + m_search_complete = m_search_complete && m_next_inst; + m_pointer_valid = false; + } // ensure we're consistent with the state of the bus m_bus_stop = 0 == m_bus->stop_out(); @@ -408,16 +619,20 @@ void intellec4_40_state::driver_reset() m_bus_user_reset = 0 == m_bus->user_reset_out(); // ensure device inputs are all in the correct state + m_cpu->set_input_line(INPUT_LINE_RESET, m_cpu_reset ? ASSERT_LINE : CLEAR_LINE); m_cpu->set_input_line(I4040_TEST_LINE, m_bus->test_out() ? CLEAR_LINE : ASSERT_LINE); m_cpu->set_input_line(I4040_STP_LINE, ((m_sw_stop && !m_single_step) || m_bus_stop) ? ASSERT_LINE : CLEAR_LINE); m_bus->test_in(1); m_bus->stop_in((m_sw_stop && !m_single_step) ? 0 : 1); + m_bus->cpu_reset_in(m_cpu_reset ? 0 : 1); // set front panel LEDs - machine().output().set_value("led_status_run", !m_stp_ack); - machine().output().set_value("led_mode_mon", m_ff_mon); - machine().output().set_value("led_mode_ram", m_ff_ram); - machine().output().set_value("led_mode_prom", m_ff_prom); + machine().output().set_value("led_status_ptr_valid", m_pointer_valid); + machine().output().set_value("led_status_run", !m_stp_ack); + machine().output().set_value("led_status_search", m_search_complete); + machine().output().set_value("led_mode_mon", m_ff_mon); + machine().output().set_value("led_mode_ram", m_ff_ram); + machine().output().set_value("led_mode_prom", m_ff_prom); } @@ -434,9 +649,13 @@ TIMER_CALLBACK_MEMBER(intellec4_40_state::single_step_expired) TIMER_CALLBACK_MEMBER(intellec4_40_state::reset_expired) { - m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); - m_bus->cpu_reset_in(1); - // FIXME: can cause 4002 reset as well + if (m_cpu_reset) + { + m_cpu_reset = false; + m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE); + m_bus->cpu_reset_in(1); + // FIXME: can cause 4002 reset as well + } } void intellec4_40_state::trigger_reset() @@ -447,14 +666,143 @@ void intellec4_40_state::trigger_reset() // 9602 with Rx = 27kΩ, Cx = 0.1µF // K * Rx(kΩ) * Cx(pF) * (1 + (1 / Rx(kΩ))) = 0.34 * 27 * 100000 * (1 + (1 / 27)) = 952000ns m_reset_timer->adjust(attotime::from_usec(952)); - m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); - m_bus->cpu_reset_in(0); - // FIXME: can cause 4002 reset as well + if (!m_cpu_reset) + { + m_cpu_reset = true; + m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE); + m_bus->cpu_reset_in(0); + reset_panel(); + // FIXME: can cause 4002 reset as well + } } } +void intellec4_40_state::reset_panel() +{ + if (!m_panel_reset) + { + m_pass_counter = 0U; + m_panel_reset = true; + m_adr_cmp_latch = false; + if (m_search_complete && !m_next_inst) + machine().output().set_value("led_status_search", m_search_complete = false); + if (m_pointer_valid) + machine().output().set_value("led_status_ptr_valid", m_pointer_valid = false); + } +} + +void intellec4_40_state::display_address(u16 value, u16 mask) +{ + u16 const diff((value ^ m_display_addr) & mask); + m_display_addr ^= diff; + if (BIT(diff, 0)) + machine().output().set_value("led_address_a1_0", BIT(value, 0)); + if (BIT(diff, 1)) + machine().output().set_value("led_address_a1_1", BIT(value, 1)); + if (BIT(diff, 2)) + machine().output().set_value("led_address_a1_2", BIT(value, 2)); + if (BIT(diff, 3)) + machine().output().set_value("led_address_a1_3", BIT(value, 3)); + if (BIT(diff, 4)) + machine().output().set_value("led_address_a2_0", BIT(value, 4)); + if (BIT(diff, 5)) + machine().output().set_value("led_address_a2_1", BIT(value, 5)); + if (BIT(diff, 6)) + machine().output().set_value("led_address_a2_2", BIT(value, 6)); + if (BIT(diff, 7)) + machine().output().set_value("led_address_a2_3", BIT(value, 7)); + if (BIT(diff, 8)) + machine().output().set_value("led_address_a3_0", BIT(value, 8)); + if (BIT(diff, 9)) + machine().output().set_value("led_address_a3_1", BIT(value, 9)); + if (BIT(diff, 10)) + machine().output().set_value("led_address_a3_2", BIT(value, 10)); + if (BIT(diff, 11)) + machine().output().set_value("led_address_a3_3", BIT(value, 11)); +} + +void intellec4_40_state::display_instruction(u8 value, u8 mask) +{ + u16 const diff((value ^ m_display_instr) & mask); + m_display_instr ^= diff; + if (BIT(diff, 0)) + machine().output().set_value("led_instruction_m2_0", BIT(value, 0)); + if (BIT(diff, 1)) + machine().output().set_value("led_instruction_m2_1", BIT(value, 1)); + if (BIT(diff, 2)) + machine().output().set_value("led_instruction_m2_2", BIT(value, 2)); + if (BIT(diff, 3)) + machine().output().set_value("led_instruction_m2_3", BIT(value, 3)); + if (BIT(diff, 4)) + machine().output().set_value("led_instruction_m1_0", BIT(value, 4)); + if (BIT(diff, 5)) + machine().output().set_value("led_instruction_m1_1", BIT(value, 5)); + if (BIT(diff, 6)) + machine().output().set_value("led_instruction_m1_2", BIT(value, 6)); + if (BIT(diff, 7)) + machine().output().set_value("led_instruction_m1_3", BIT(value, 7)); +} + +void intellec4_40_state::display_active_bank(u8 value) +{ + u8 const diff((value ^ m_display_bank) & 0x0fU); + m_display_bank ^= diff; + if (BIT(diff, 0)) + machine().output().set_value("led_active_bank_0", BIT(value, 0)); + if (BIT(diff, 1)) + machine().output().set_value("led_active_bank_1", BIT(value, 1)); + if (BIT(diff, 2)) + machine().output().set_value("led_active_bank_2", BIT(value, 2)); + if (BIT(diff, 3)) + machine().output().set_value("led_active_bank_3", BIT(value, 3)); +} -ADDRESS_MAP_START(mod40_program_banks, AS_OPCODES, 8, intellec4_40_state) +void intellec4_40_state::display_execution(u8 value, u8 mask) +{ + u16 const diff((value ^ m_display_exec) & mask); + m_display_exec ^= diff; + if (BIT(diff, 0)) + machine().output().set_value("led_execution_x3_0", BIT(value, 0)); + if (BIT(diff, 1)) + machine().output().set_value("led_execution_x3_1", BIT(value, 1)); + if (BIT(diff, 2)) + machine().output().set_value("led_execution_x3_2", BIT(value, 2)); + if (BIT(diff, 3)) + machine().output().set_value("led_execution_x3_3", BIT(value, 3)); + if (BIT(diff, 4)) + machine().output().set_value("led_execution_x2_0", BIT(value, 4)); + if (BIT(diff, 5)) + machine().output().set_value("led_execution_x2_1", BIT(value, 5)); + if (BIT(diff, 6)) + machine().output().set_value("led_execution_x2_2", BIT(value, 6)); + if (BIT(diff, 7)) + machine().output().set_value("led_execution_x2_3", BIT(value, 7)); +} + +void intellec4_40_state::display_pointer(u8 value, u8 mask) +{ + u16 const diff((value ^ m_display_ptr) & mask); + m_display_ptr ^= diff; + if (BIT(diff, 0)) + machine().output().set_value("led_last_ptr_x3_0", BIT(value, 0)); + if (BIT(diff, 1)) + machine().output().set_value("led_last_ptr_x3_1", BIT(value, 1)); + if (BIT(diff, 2)) + machine().output().set_value("led_last_ptr_x3_2", BIT(value, 2)); + if (BIT(diff, 3)) + machine().output().set_value("led_last_ptr_x3_3", BIT(value, 3)); + if (BIT(diff, 4)) + machine().output().set_value("led_last_ptr_x2_0", BIT(value, 4)); + if (BIT(diff, 5)) + machine().output().set_value("led_last_ptr_x2_1", BIT(value, 5)); + if (BIT(diff, 6)) + machine().output().set_value("led_last_ptr_x2_2", BIT(value, 6)); + if (BIT(diff, 7)) + machine().output().set_value("led_last_ptr_x2_3", BIT(value, 7)); +} + + +ADDRESS_MAP_START(mod40_program_banks, mcs40_cpu_device_base::AS_ROM, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW // 0x0000...0x0fff MON @@ -468,57 +816,73 @@ ADDRESS_MAP_START(mod40_program_banks, AS_OPCODES, 8, intellec4_40_state) // 0x3000...0x3fff unmapped in case someone presses two mode switches at once ADDRESS_MAP_END -ADDRESS_MAP_START(mod40_io_banks, AS_PROGRAM, 8, intellec4_40_state) +ADDRESS_MAP_START(mod40_rom_port_banks, mcs40_cpu_device_base::AS_ROM_PORTS, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW - // 0x0000...0x0fff ROM ports - MON - AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x6700) AM_READ(rom0_in) - AM_RANGE(0x00e0, 0x00ef) AM_MIRROR(0x6700) AM_READWRITE(rome_in, rome_out) - AM_RANGE(0x00f0, 0x00ff) AM_MIRROR(0x6700) AM_READWRITE(romf_in, romf_out) + // 0x0000...0x0fff MON + AM_RANGE(0x0000, 0x000f) AM_MIRROR(0x3700) AM_READ(rom0_in) + AM_RANGE(0x00e0, 0x00ef) AM_MIRROR(0x3700) AM_READWRITE(rome_in, rome_out) + AM_RANGE(0x00f0, 0x00ff) AM_MIRROR(0x3700) AM_READWRITE(romf_in, romf_out) + + // 0x1000...0x1fff neither - // 0x1000...0x1fff RAM ports - MON - AM_RANGE(0x1000, 0x103f) AM_MIRROR(0x6800) AM_WRITE(ram0_out) - AM_RANGE(0x1040, 0x107f) AM_MIRROR(0x6800) AM_WRITE(ram1_out) + // 0x2000...0x2fff PROM - // 0x2000...0x2fff ROM ports - neither + // 0x3000...0x3fff unused +ADDRESS_MAP_END - // 0x3000...0x3fff RAM ports - neither +ADDRESS_MAP_START(mod40_ram_port_banks, mcs40_cpu_device_base::AS_RAM_PORTS, 8, intellec4_40_state) + // 0x00...0x1f MON + AM_RANGE(0x00, 0x00) AM_MIRROR(0x60) AM_WRITE(ram0_out) + AM_RANGE(0x00, 0x01) AM_MIRROR(0x60) AM_WRITE(ram1_out) - // 0x4000...0x4fff ROM ports - PROM + // 0x20...0x3f neither - // 0x5000...0x5fff RAM ports - PROM + // 0x40...0x5f PROM - // 0x6000...0x7fff unused + // 0x60...0x7f unused ADDRESS_MAP_END -ADDRESS_MAP_START(mod40_program, AS_PROGRAM, 8, intellec4_40_state) +ADDRESS_MAP_START(mod40_rom, mcs40_cpu_device_base::AS_ROM, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW - AM_RANGE(0x0000, 0x01ff) AM_READWRITE(pm_read, pm_write) + AM_RANGE(0x0000, 0x0fff) AM_DEVICE("prgbank", address_map_bank_device, amap8) ADDRESS_MAP_END -ADDRESS_MAP_START(mod40_data, AS_DATA, 8, intellec4_40_state) +ADDRESS_MAP_START(mod40_ram_memory, mcs40_cpu_device_base::AS_RAM_MEMORY, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW AM_RANGE(0x0000, 0x00ff) AM_RAM // 4 * 4002 ADDRESS_MAP_END -ADDRESS_MAP_START(mod40_io, AS_IO, 8, intellec4_40_state) +ADDRESS_MAP_START(mod40_rom_ports, mcs40_cpu_device_base::AS_ROM_PORTS, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW - AM_RANGE(0x0000, 0x1fff) AM_DEVICE("iobank", address_map_bank_device, amap8) + AM_RANGE(0x0000, 0x0fff) AM_DEVICE("rpbank", address_map_bank_device, amap8) ADDRESS_MAP_END -ADDRESS_MAP_START(mod40_opcodes, AS_OPCODES, 8, intellec4_40_state) +ADDRESS_MAP_START(mod40_ram_status, mcs40_cpu_device_base::AS_RAM_STATUS, 8, intellec4_40_state) ADDRESS_MAP_UNMAP_LOW - AM_RANGE(0x0000, 0x0fff) AM_DEVICE("prgbank", address_map_bank_device, amap8) + AM_RANGE(0x0000, 0x003f) AM_RAM // 4 * 4002 +ADDRESS_MAP_END + +ADDRESS_MAP_START(mod40_ram_ports, mcs40_cpu_device_base::AS_RAM_PORTS, 8, intellec4_40_state) + AM_RANGE(0x00, 0x1f) AM_DEVICE("mpbank", address_map_bank_device, amap8) +ADDRESS_MAP_END + +ADDRESS_MAP_START(mod40_program_memory, mcs40_cpu_device_base::AS_PROGRAM_MEMORY, 8, intellec4_40_state) + ADDRESS_MAP_UNMAP_LOW + AM_RANGE(0x0000, 0x01ff) AM_READWRITE(pm_read, pm_write) ADDRESS_MAP_END MACHINE_CONFIG_START(intlc440) MCFG_CPU_ADD("maincpu", I4040, 5185000. / 7) - MCFG_CPU_PROGRAM_MAP(mod40_program) - MCFG_CPU_DATA_MAP(mod40_data) - MCFG_CPU_IO_MAP(mod40_io) - MCFG_CPU_DECRYPTED_OPCODES_MAP(mod40_opcodes) + MCFG_I4040_ROM_MAP(mod40_rom) + MCFG_I4040_RAM_MEMORY_MAP(mod40_ram_memory) + MCFG_I4040_ROM_PORTS_MAP(mod40_rom_ports) + MCFG_I4040_RAM_STATUS_MAP(mod40_ram_status) + MCFG_I4040_RAM_PORTS_MAP(mod40_ram_ports) + MCFG_I4040_PROGRAM_MEMORY_MAP(mod40_program_memory) + MCFG_I4040_BUS_CYCLE_CB(FUNC(intellec4_40_state, bus_cycle)); MCFG_I4040_SYNC_CB(DEVWRITELINE("bus", bus::intellec4::univ_bus_device, sync_in)) MCFG_I4040_STP_ACK_CB(WRITELINE(intellec4_40_state, stp_ack)) @@ -529,12 +893,19 @@ MACHINE_CONFIG_START(intlc440) MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) - MCFG_DEVICE_ADD("iobank", ADDRESS_MAP_BANK, 0) - MCFG_DEVICE_PROGRAM_MAP(mod40_io_banks) + MCFG_DEVICE_ADD("rpbank", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(mod40_rom_port_banks) MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) - MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(15) - MCFG_ADDRESS_MAP_BANK_STRIDE(0x2000) + MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(14) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000) + + MCFG_DEVICE_ADD("mpbank", ADDRESS_MAP_BANK, 0) + MCFG_DEVICE_PROGRAM_MAP(mod40_ram_port_banks) + MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_LITTLE) + MCFG_ADDRESS_MAP_BANK_DATABUS_WIDTH(8) + MCFG_ADDRESS_MAP_BANK_ADDRBUS_WIDTH(7) + MCFG_ADDRESS_MAP_BANK_STRIDE(0x20) MCFG_RS232_PORT_ADD("tty", default_rs232_devices, "terminal") @@ -556,17 +927,48 @@ MACHINE_CONFIG_START(intlc440) MCFG_INTELLEC4_UNIV_SLOT_ADD("bus", "j17", 518000. / 7, intellec4_univ_cards, nullptr) MCFG_INTELLEC4_UNIV_SLOT_ADD("bus", "j18", 518000. / 7, intellec4_univ_cards, nullptr) MCFG_INTELLEC4_UNIV_SLOT_ADD("bus", "j19", 518000. / 7, intellec4_univ_cards, nullptr) + + MCFG_DEFAULT_LAYOUT(layout_intlc440) MACHINE_CONFIG_END INPUT_PORTS_START(intlc440) PORT_START("MODE") - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_TOGGLE PORT_NAME("STOP") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_stop, 0) - PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("SINGLE STEP") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_single_step, 0) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("RESET") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_reset, 0) - PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("MON") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_mon, 0) - PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("RAM") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_ram, 0) - PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("PROM") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_prom, 0) + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("STOP") PORT_CODE(KEYCODE_LEFT) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_stop, 0) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("SINGLE STEP") PORT_CODE(KEYCODE_RIGHT) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_single_step, 0) + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_reset, 0) + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("MON") PORT_CODE(KEYCODE_1_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_mon, 0) + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RAM") PORT_CODE(KEYCODE_2_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_ram, 0) + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("PROM") PORT_CODE(KEYCODE_3_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_prom, 0) + + PORT_START("CONTROL") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("RUN") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_run, 0) + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("NEXT INST") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_next_inst, 0) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("DECR") PORT_CODE(KEYCODE_MINUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_decr, 0) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("INCR") PORT_CODE(KEYCODE_PLUS_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_incr, 0) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("LOAD") PORT_CODE(KEYCODE_ENTER_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_load, 0) + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("CMA ENABLE") PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_cma_enable, 0) + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("CMA WRITE") PORT_CODE(KEYCODE_SLASH_PAD) PORT_CHANGED_MEMBER(DEVICE_SELF, intellec4_40_state, sw_cma_write, 0) + + PORT_START("ADDRDAT") + PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 0") + PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 1") + PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 2") + PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 3") + PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 4") + PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 5") + PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 6") + PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 7") + PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 8") + PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 9") + PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 10") + PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("ADDRESS/DATA 11") + + PORT_START("PASSES") + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 0") + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 1") + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 2") + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_TOGGLE PORT_NAME("PASSES 3") INPUT_PORTS_END @@ -588,4 +990,4 @@ ROM_END } // anonymous namespace // YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS -COMP( 1974?, intlc440, 0, 0, intlc440, intlc440, intellec4_40_state, 0, "Intel", "INTELLEC 4/MOD40", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_SUPPORTS_SAVE ) +COMP( 1974?, intlc440, 0, 0, intlc440, intlc440, intellec4_40_state, 0, "Intel", "INTELLEC 4/MOD40", MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW | MACHINE_CLICKABLE_ARTWORK | MACHINE_SUPPORTS_SAVE ) |