// license:BSD-3-Clause // copyright-holders:hap /* AMI S2000-family MCU cores */ #ifndef MAME_CPU_AMIS2000_AMIS2000_H #define MAME_CPU_AMIS2000_AMIS2000_H #pragma once class amis2000_base_device : public cpu_device { public: // generic input pins (4 bits each) auto read_k() { return m_read_k.bind(); } auto read_i() { return m_read_i.bind(); } // 8-bit external databus coupled as input/output pins auto read_d() { return m_read_d.bind(); } auto write_d() { return m_write_d.bind(); } // 13-bit external address bus coupled as output pins auto write_a() { return m_write_a.bind(); } // F_out pin (only for S2152) auto write_f() { return m_write_f.bind(); } // S2000 has a hardcoded 7seg table, that (unlike S2200) is officially // uncustomizable, but wildfire proves to be an exception to that rule. void set_7seg_table(const u8 *ptr) { m_7seg_table = ptr; } // d0=A, d1=B, etc. void data_64x4(address_map &map); void data_80x4(address_map &map); void program_1_5k(address_map &map); void program_1k(address_map &map); protected: // construction/destruction amis2000_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u8 bu_bits, u8 callstack_bits, u8 callstack_depth, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : cpu_device(mconfig, type, tag, owner, clock) , m_program_config("program", ENDIANNESS_BIG, 8, prgwidth, 0, program) , m_data_config("data", ENDIANNESS_BIG, 8, datawidth, 0, data) , m_bu_bits(bu_bits) , m_callstack_bits(callstack_bits) , m_callstack_depth(callstack_depth) , m_7seg_table(nullptr) , m_read_k(*this) , m_read_i(*this) , m_read_d(*this) , m_write_d(*this) , m_write_a(*this) , m_write_f(*this) { } // device-level overrides virtual void device_start() override; virtual void device_reset() override; // device_execute_interface overrides virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 4 - 1) / 4; } // 4 cycles per machine cycle virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 4); } // " virtual u32 execute_min_cycles() const noexcept override { return 1; } virtual u32 execute_max_cycles() const noexcept override { return 2; } virtual u32 execute_input_lines() const noexcept override { return 1; } virtual void execute_run() override; // device_memory_interface overrides virtual space_config_vector memory_space_config() const override; // device_disasm_interface overrides virtual std::unique_ptr create_disassembler() override; // device_state_interface overrides virtual void state_string_export(const device_state_entry &entry, std::string &str) const override; address_space_config m_program_config; address_space_config m_data_config; address_space *m_program; address_space *m_data; u8 m_bu_bits; u16 m_bu_mask; u8 m_callstack_bits; // number of program counter bits held in callstack u16 m_callstack_mask; u8 m_callstack_depth; // callstack levels: 3 on 2000/2150, 5 on 2200/2400 u16 m_callstack[5]; // max 5 int m_icount; u16 m_pc; // 13-bit program counter u8 m_ppr; // prepared page register (PP 1) u8 m_pbr; // prepared bank register (PP 2) bool m_skip; // skip next opcode, including PP prefixes u8 m_op; u8 m_prev_op; // previous opcode, needed for PP, LAI, LB* u8 m_f; // generic flags: 2 on 2000/2150, 6 on 2200/2400 u8 m_carry; // carry flag u8 m_bl; // 4-bit ram index x u8 m_bu; // 2/3-bit ram index y u8 m_acc; // 4-bit accumulator u8 m_e; // 4-bit generic register u8 m_ki_mask; // 4-bit k/i-pins select latch u8 m_d; // 8-bit d-pins latch bool m_d_active; // d-pins available for direct i/o(floating), or outputting d-latch u8 m_d_polarity; // invert d-latch output u16 m_a; // 13-bit a-pins latch (master strobe latch) // i/o handlers const u8 *m_7seg_table; devcb_read8 m_read_k; devcb_read8 m_read_i; devcb_read8 m_read_d; devcb_write8 m_write_d; devcb_write16 m_write_a; devcb_write_line m_write_f; // misc internal helpers u8 ram_r(); void ram_w(u8 data); void pop_callstack(); void push_callstack(); void d_latch_out(bool active); // opcode handlers virtual void op_lai(); virtual void op_lab(); virtual void op_lae(); virtual void op_xab(); virtual void op_xabu(); virtual void op_xae(); virtual void op_lbe(); virtual void op_lbep(); virtual void op_lbz(); virtual void op_lbf(); virtual void op_lam(); virtual void op_xc(); virtual void op_xci(); virtual void op_xcd(); virtual void op_stm(); virtual void op_rsm(); virtual void op_inp(); virtual void op_out(); virtual void op_disb(); virtual void op_disn(); virtual void op_mvs(); virtual void op_psh(); virtual void op_psl(); virtual void op_eur(); virtual void op_pp(); virtual void op_jmp(); virtual void op_jms(); virtual void op_rt(); virtual void op_rts(); virtual void op_nop(); virtual void op_halt(); virtual void op_szc(); virtual void op_szm(); virtual void op_szi(); virtual void op_szk(); virtual void op_sbe(); virtual void op_sam(); virtual void op_sos(); virtual void op_tf1(); virtual void op_tf2(); virtual void op_adcs(); virtual void op_adis(); virtual void op_add(); virtual void op_and(); virtual void op_xor(); virtual void op_stc(); virtual void op_rsc(); virtual void op_cma(); virtual void op_sf1(); virtual void op_rf1(); virtual void op_sf2(); virtual void op_rf2(); }; class amis2000_cpu_device : public amis2000_base_device { public: amis2000_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; class amis2150_cpu_device : public amis2000_base_device { public: amis2150_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); }; class amis2152_cpu_device : public amis2000_base_device { public: amis2152_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); protected: // device-level overrides virtual void device_start() override; virtual void device_reset() override; // digital-to-frequency converter u8 m_d2f_latch; emu_timer *m_d2f_timer; int m_fout_state; void d2f_timer_clock(); TIMER_CALLBACK_MEMBER(d2f_timer_cb); // opcode handlers virtual void op_szk() override; }; DECLARE_DEVICE_TYPE(AMI_S2000, amis2000_cpu_device) DECLARE_DEVICE_TYPE(AMI_S2150, amis2150_cpu_device) DECLARE_DEVICE_TYPE(AMI_S2152, amis2152_cpu_device) #endif // MAME_CPU_AMIS2000_AMIS2000_H