summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/mcs40/mcs40.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/mcs40/mcs40.h')
-rw-r--r--src/devices/cpu/mcs40/mcs40.h307
1 files changed, 307 insertions, 0 deletions
diff --git a/src/devices/cpu/mcs40/mcs40.h b/src/devices/cpu/mcs40/mcs40.h
new file mode 100644
index 00000000000..fe7c9e3352e
--- /dev/null
+++ b/src/devices/cpu/mcs40/mcs40.h
@@ -0,0 +1,307 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+#ifndef MAME_CPU_I4004_I4004_H
+#define MAME_CPU_I4004_I4004_H
+
+#pragma once
+
+
+/***********************************************************************
+ CONSTANTS
+***********************************************************************/
+
+enum
+{
+ I4004_A = 1,
+ I4004_R01, I4004_R23, I4004_R45, I4004_R67, I4004_R89, I4004_RAB, I4004_RCD, I4004_REF,
+ I4040_RGH, I4040_RIJ, I4040_RKL, I4040_RMN,
+ I4004_ADDR0, I4004_ADDR1, I4004_ADDR2, I4004_ADDR3,
+ I4040_ADDR4, I4040_ADDR5, I4040_ADDR6, I4040_ADDR7,
+ I4004_CR, I4004_RC, I4004_RCN,
+ I4040_SRC
+};
+
+enum
+{
+ I4004_TEST_LINE = 0,
+
+ I4040_TEST_LINE = I4004_TEST_LINE,
+ I4040_INT_LINE = 1,
+ I4040_STP_LINE = 2
+};
+
+
+
+/***********************************************************************
+ CONFIGURATION MACROS
+***********************************************************************/
+
+#define MCFG_I4004_SYNC_CB(obj) \
+ devcb = &i4004_cpu_device::set_sync_cb(*device, DEVCB_##obj);
+
+#define MCFG_I4004_CM_ROM_CB(obj) \
+ devcb = &i4004_cpu_device::set_cm_rom_cb(*device, DEVCB_##obj);
+
+#define MCFG_I4004_CM_RAM0_CB(obj) \
+ devcb = &i4004_cpu_device::set_cm_ram_cb<0>(*device, DEVCB_##obj);
+
+#define MCFG_I4004_CM_RAM1_CB(obj) \
+ devcb = &i4004_cpu_device::set_cm_ram_cb<1>(*device, DEVCB_##obj);
+
+#define MCFG_I4004_CM_RAM2_CB(obj) \
+ devcb = &i4004_cpu_device::set_cm_ram_cb<2>(*device, DEVCB_##obj);
+
+#define MCFG_I4004_CM_RAM3_CB(obj) \
+ devcb = &i4004_cpu_device::set_cm_ram_cb<3>(*device, DEVCB_##obj);
+
+
+#define MCFG_I4040_SYNC_CB(obj) \
+ devcb = &i4040_cpu_device::set_sync_cb(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_ROM0_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_rom_cb<0>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_ROM1_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_rom_cb<1>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_RAM0_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_ram_cb<0>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_RAM1_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_ram_cb<1>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_RAM2_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_ram_cb<2>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CM_RAM3_CB(obj) \
+ devcb = &i4040_cpu_device::set_cm_ram_cb<3>(*device, DEVCB_##obj);
+
+#define MCFG_I4040_CY_CB(obj) \
+ devcb = &i4040_cpu_device::set_cy_cb(*device, DEVCB_##obj);
+
+
+
+/***********************************************************************
+ TYPE DEFINITIONS
+***********************************************************************/
+
+class mcs40_cpu_device_base : public cpu_device
+{
+protected:
+ enum class cycle { OP, IM, IN };
+
+ mcs40_cpu_device_base(
+ machine_config const &mconfig,
+ device_type type,
+ char const *tag,
+ device_t *owner,
+ uint32_t clock,
+ bool extended_cm,
+ unsigned rom_width,
+ unsigned stack_ptr_mask,
+ unsigned index_reg_cnt,
+ unsigned cr_mask);
+
+ // device_t implementation
+ void device_start() override;
+ void device_reset() override;
+
+ // device_execute_interface implementation
+ virtual void execute_run() override;
+
+ // device_memory_interface configuration
+ virtual address_space_config const *memory_space_config(address_spacenum spacenum) const override;
+
+ // device_state_interface implementation
+ virtual void state_import(device_state_entry const &entry) override;
+ virtual void state_export(device_state_entry const &entry) override;
+ virtual void state_string_export(device_state_entry const &entry, std::string &str) const override;
+
+ // device_disasm_interface implementation
+ virtual u32 disasm_min_opcode_bytes() const override;
+ virtual u32 disasm_max_opcode_bytes() const override;
+
+ // instruction execution
+ virtual bool is_io_op(u8 opr) = 0;
+ virtual cycle do_cycle1(u8 opr, u8 opa) = 0;
+ virtual void do_cycle2(u8 opr, u8 opa, u8 arg) = 0;
+ virtual void do_io(u8 opr, u8 opa) = 0;
+
+ // register access
+ u8 get_a() const;
+ u8 get_c() const;
+ void set_a(u8 val);
+ void set_c(u8 val);
+ void set_a_c(u8 val);
+ void set_pc(u16 addr, u16 mask);
+ void push_pc();
+ void pop_pc();
+ u8 &index_reg_pair(unsigned n);
+ u8 get_index_reg(unsigned n);
+ void set_index_reg(unsigned n, u8 val);
+ void set_index_reg_bank(u8 val);
+
+ // I/O control
+ void set_rom_addr(u16 addr, u16 mask);
+ u8 get_cr();
+ void set_cr(u8 val, u8 mask);
+ void set_pending_rom_bank(u8 val);
+ void set_rc(u8 val);
+ u8 read_memory();
+ void write_memory(u8 val);
+ u8 read_status();
+ void write_status(u8 val);
+ u8 read_rom_port();
+ void write_rom_port(u8 val);
+ void write_memory_port(u8 val);
+
+ // input lines
+ bool get_test();
+ void set_test(int state);
+
+ // configuration helpers
+ template <typename Obj> devcb_base &set_sync_cb(Obj &&cb)
+ { return m_sync_cb.set_callback(std::forward<Obj>(cb)); }
+ template <unsigned N, typename Obj> devcb_base &set_cm_rom_cb(Obj &&cb)
+ { return m_cm_rom_cb[N].set_callback(std::forward<Obj>(cb)); }
+ template <unsigned N, typename Obj> devcb_base &set_cm_ram_cb(Obj &&cb)
+ { return m_cm_ram_cb[N].set_callback(std::forward<Obj>(cb)); }
+ template <typename Obj> devcb_base &set_cy_cb(Obj &&cb)
+ { return m_cy_cb.set_callback(std::forward<Obj>(cb)); }
+
+private:
+ enum class phase { A1, A2, A3, M1, M2, X1, X2, X3 };
+
+ // internal helpers
+ u16 &pc() { return m_addr_stack[m_stack_ptr]; }
+ u16 rom_bank() const { return BIT(m_cr, 3) ? 0x1000U : 0x0000U; }
+ void update_cm_rom(u8 val);
+ void update_cm_ram(u8 val);
+ void update_cy(u8 val);
+
+ // address spaces
+ address_space_config m_program_config, m_data_config, m_io_config;
+ address_space *m_program, *m_data, *m_io;
+ direct_read_data *m_direct;
+
+ // output callbacks
+ devcb_write_line m_sync_cb;
+ devcb_write_line m_cm_rom_cb[2], m_cm_ram_cb[4];
+ devcb_write_line m_cy_cb;
+
+ // configuration
+ bool const m_extended_cm;
+ u8 const m_stack_ptr_mask;
+ u8 const m_index_reg_cnt;
+ u8 const m_cr_mask;
+ u16 const m_pc_mask;
+
+ // machine/instruction phase
+ int m_icount;
+ phase m_phase;
+ cycle m_cycle;
+ bool m_io_pending;
+
+ // instruction ROM fetch/decode
+ u16 m_rom_bank, m_rom_addr;
+ u8 m_opr, m_opa, m_arg;
+
+ // ALU registers
+ u8 m_a, m_c;
+
+ // address stack
+ std::unique_ptr<u16 []> m_addr_stack;
+ u8 m_stack_ptr;
+
+ // index registers
+ std::unique_ptr<u8 []> m_index_regs;
+ u8 m_index_reg_bank;
+
+ // RAM/I/O control
+ u8 m_cr, m_pending_cr3, m_latched_rc, m_new_rc, m_src;
+ bool m_rc_pending;
+
+ // input/output lines
+ int m_test;
+ u8 m_cm_rom, m_cm_ram, m_cy;
+
+ // state export/import
+ u16 m_pc, m_pcbase;
+ u8 m_genflags;
+};
+
+
+class i4004_cpu_device : public mcs40_cpu_device_base
+{
+public:
+ // configuration helpers
+ template <typename Obj> static devcb_base &set_sync_cb(device_t &device, Obj &&cb)
+ { return downcast<i4004_cpu_device &>(device).set_sync_cb(std::forward<Obj>(cb)); }
+ template <typename Obj> static devcb_base &set_cm_rom_cb(device_t &device, Obj &&cb)
+ { return downcast<i4004_cpu_device &>(device).set_cm_rom_cb<0>(std::forward<Obj>(cb)); }
+ template <unsigned N, typename Obj> static devcb_base &set_cm_ram_cb(device_t &device, Obj &&cb)
+ { return downcast<i4004_cpu_device &>(device).set_cm_ram_cb<N>(std::forward<Obj>(cb)); }
+
+ i4004_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ using mcs40_cpu_device_base::mcs40_cpu_device_base;
+
+ // device_execute_interface implementation
+ u32 execute_input_lines() const override;
+ virtual void execute_set_input(int inputnum, int state) override;
+
+ // device_disasm_interface implementation
+ virtual offs_t disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ uint8_t const *oprom,
+ uint8_t const *opram,
+ uint32_t options) override;
+
+ // mcs40_cpu_device_base implementation
+ virtual bool is_io_op(u8 opr) override;
+ virtual cycle do_cycle1(u8 opr, u8 opa) override;
+ virtual void do_cycle2(u8 opr, u8 opa, u8 arg) override;
+ virtual void do_io(u8 opr, u8 opa) override;
+};
+
+
+class i4040_cpu_device : public i4004_cpu_device
+{
+public:
+ // configuration helpers
+ template <typename Obj> static devcb_base &set_sync_cb(device_t &device, Obj &&cb)
+ { return downcast<i4040_cpu_device &>(device).set_sync_cb(std::forward<Obj>(cb)); }
+ template <unsigned N, typename Obj> static devcb_base &set_cm_rom_cb(device_t &device, Obj &&cb)
+ { return downcast<i4040_cpu_device &>(device).set_cm_rom_cb<N>(std::forward<Obj>(cb)); }
+ template <unsigned N, typename Obj> static devcb_base &set_cm_ram_cb(device_t &device, Obj &&cb)
+ { return downcast<i4040_cpu_device &>(device).set_cm_ram_cb<N>(std::forward<Obj>(cb)); }
+ template <typename Obj> static devcb_base &set_cy_cb(device_t &device, Obj &&cb)
+ { return downcast<i4040_cpu_device &>(device).set_cy_cb(std::forward<Obj>(cb)); }
+
+ i4040_cpu_device(machine_config const &mconfig, char const *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device_disasm_interface implementation
+ virtual offs_t disasm_disassemble(
+ std::ostream &stream,
+ offs_t pc,
+ uint8_t const *oprom,
+ uint8_t const *opram,
+ uint32_t options) override;
+
+ // mcs40_cpu_device_base implementation
+ virtual cycle do_cycle1(u8 opr, u8 opa) override;
+};
+
+
+
+/***********************************************************************
+ DEVICE TYPE DECLARATIONS
+***********************************************************************/
+
+DECLARE_DEVICE_TYPE(I4004, i4004_cpu_device)
+DECLARE_DEVICE_TYPE(I4040, i4040_cpu_device)
+
+#endif // MAME_CPU_I4004_I4004_H