diff --git a/scripts/src/cpu.lua b/scripts/src/cpu.lua index c0ef6eac85d..ae338a86b75 100644 --- a/scripts/src/cpu.lua +++ b/scripts/src/cpu.lua @@ -2223,20 +2223,23 @@ end if CPUS["SM510"] then files { MAME_DIR .. "src/devices/cpu/sm510/sm510base.cpp", + MAME_DIR .. "src/devices/cpu/sm510/sm510base.h", MAME_DIR .. "src/devices/cpu/sm510/sm510.h", + MAME_DIR .. "src/devices/cpu/sm510/sm510.cpp", MAME_DIR .. "src/devices/cpu/sm510/sm510op.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm510core.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm511core.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm530.h", - MAME_DIR .. "src/devices/cpu/sm510/sm530op.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm530core.cpp", + MAME_DIR .. "src/devices/cpu/sm510/sm511.h", + MAME_DIR .. "src/devices/cpu/sm510/sm511.cpp", MAME_DIR .. "src/devices/cpu/sm510/sm500.h", + MAME_DIR .. "src/devices/cpu/sm510/sm500.cpp", MAME_DIR .. "src/devices/cpu/sm510/sm500op.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm500core.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm5acore.cpp", + MAME_DIR .. "src/devices/cpu/sm510/sm5a.h", + MAME_DIR .. "src/devices/cpu/sm510/sm5a.cpp", + MAME_DIR .. "src/devices/cpu/sm510/sm530.h", + MAME_DIR .. "src/devices/cpu/sm510/sm530.cpp", + MAME_DIR .. "src/devices/cpu/sm510/sm530op.cpp", MAME_DIR .. "src/devices/cpu/sm510/sm590.h", + MAME_DIR .. "src/devices/cpu/sm510/sm590.cpp", MAME_DIR .. "src/devices/cpu/sm510/sm590op.cpp", - MAME_DIR .. "src/devices/cpu/sm510/sm590core.cpp", } end diff --git a/src/devices/cpu/pps41/pps41base.h b/src/devices/cpu/pps41/pps41base.h index d531b77042b..2d962b5a5d3 100644 --- a/src/devices/cpu/pps41/pps41base.h +++ b/src/devices/cpu/pps41/pps41base.h @@ -4,6 +4,9 @@ Rockwell PPS-4/1 MCU cores + Don't include this file, include the specific device header instead, + for example mm76.h + */ #ifndef MAME_CPU_PPS41_PPS41BASE_H diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500.cpp similarity index 97% rename from src/devices/cpu/sm510/sm500core.cpp rename to src/devices/cpu/sm510/sm500.cpp index cd4bdd7e4c8..e9772a1780c 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500.cpp @@ -147,17 +147,6 @@ void sm500_device::clock_melody() // execute //------------------------------------------------- -void sm500_device::get_opcode_param() -{ - // LBL and prefix opcodes are 2 bytes - if (m_op == 0x5e || m_op == 0x5f) - { - m_icount--; - m_param = m_program->read_byte(m_pc); - increment_pc(); - } -} - void sm500_device::execute_one() { switch (m_op & 0xf0) @@ -248,3 +237,9 @@ void sm500_device::execute_one() } // big switch } + +bool sm500_device::op_argument() +{ + // LBL and prefix opcodes are 2 bytes + return m_op == 0x5e || m_op == 0x5f; +} diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index 6514a6e1b78..c0d097df61e 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -11,7 +11,7 @@ #pragma once -#include "sm510.h" +#include "sm510base.h" // pinout reference @@ -38,31 +38,6 @@ O36 48 | * | 13 K2 1 2 3 4 5 6 7 8 9 10 11 12 O26 O16 R4 R3 R2 R1 GND _T bt al ACL K1 note: bt = beta symbol, al = alpha symbol - - - OS2 OS3 OS4 K4 K3 K2 K1 GND al bt ACL _R1 _Tp NC NC note: on SM5L, pin 31=V1, 32=V2, 33=NC - 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 - ____________________________________________________________ - | | -OS1 46 | | 30 H1 -O41 47 | | 29 H2 -O31 48 | | 28 Vm -O21 49 | | 27 Vdd -O11 50 | | 26 _R2 -O42 51 | | 25 _R3 -O32 52 | SM5A | 24 _R4 -O22 53 | SM5L | 23 OSCin -O12 54 | | 22 OSCout -O43 55 | | 21 _T2 -O33 56 | | 20 _T1 -O23 57 | | 19 O18 -O13 58 | | 18 O28 -O44 59 | | 17 O38 -O34 60 | * | 16 O48 - |____________________________________________________________/ - - 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - O24 O14 O45 O35 O25 O15 O46 GND O36 O26 O16 O47 O37 O27 O17 */ class sm500_device : public sm510_base_device @@ -80,7 +55,7 @@ protected: virtual void device_reset() override; virtual std::unique_ptr create_disassembler() override; virtual void execute_one() override; - virtual void get_opcode_param() override; + virtual bool op_argument() override; virtual void clock_melody() override; virtual void reset_vector() override { do_branch(0, 0xf, 0); } @@ -137,38 +112,6 @@ protected: }; -class sm5a_device : public sm500_device -{ -public: - sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); - -protected: - sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - - void program_1_8k(address_map &map); - void data_5x13x4(address_map &map); - - virtual std::unique_ptr create_disassembler() override; - virtual void execute_one() override; - virtual int get_trs_field() override { return 1; } -}; - -class sm5l_device : public sm5a_device -{ -public: - sm5l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); -}; - -class kb1013vk12_device : public sm5a_device -{ -public: - kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); -}; - - DECLARE_DEVICE_TYPE(SM500, sm500_device) -DECLARE_DEVICE_TYPE(SM5A, sm5a_device) -DECLARE_DEVICE_TYPE(SM5L, sm5l_device) -DECLARE_DEVICE_TYPE(KB1013VK12, kb1013vk12_device) #endif // MAME_CPU_SM510_SM500_H diff --git a/src/devices/cpu/sm510/sm510core.cpp b/src/devices/cpu/sm510/sm510.cpp similarity index 95% rename from src/devices/cpu/sm510/sm510core.cpp rename to src/devices/cpu/sm510/sm510.cpp index b2a8c375499..35c141dcde8 100644 --- a/src/devices/cpu/sm510/sm510core.cpp +++ b/src/devices/cpu/sm510/sm510.cpp @@ -4,9 +4,6 @@ Sharp SM510 MCU core implementation - TODO: - - X - */ #include "emu.h" @@ -49,7 +46,6 @@ std::unique_ptr sm510_device::create_disassembler() } - //------------------------------------------------- // buzzer controller //------------------------------------------------- @@ -80,22 +76,10 @@ void sm510_device::clock_melody() } - //------------------------------------------------- // execute //------------------------------------------------- -void sm510_device::get_opcode_param() -{ - // LBL, TL, TML opcodes are 2 bytes - if (m_op == 0x5f || (m_op & 0xf0) == 0x70) - { - m_icount--; - m_param = m_program->read_byte(m_pc); - increment_pc(); - } -} - void sm510_device::execute_one() { switch (m_op & 0xf0) @@ -174,3 +158,9 @@ void sm510_device::execute_one() // BM high bit is only valid for 1 step m_sbm = (m_op == 0x02); } + +bool sm510_device::op_argument() +{ + // LBL, TL, TML opcodes are 2 bytes + return m_op == 0x5f || (m_op & 0xf0) == 0x70; +} diff --git a/src/devices/cpu/sm510/sm510.h b/src/devices/cpu/sm510/sm510.h index 86240d18c99..c85bd374eb4 100644 --- a/src/devices/cpu/sm510/sm510.h +++ b/src/devices/cpu/sm510/sm510.h @@ -11,22 +11,7 @@ #pragma once -// I/O ports setup - -// when in halt state, any K input going High can wake up the CPU, -// driver is required to use set_input_line(SM510_INPUT_LINE_K, state) -#define SM510_INPUT_LINE_K 0 - -// ACL input pin -#define SM510_INPUT_LINE_ACL INPUT_LINE_RESET - -enum -{ - SM510_PORT_SEGA = 0x00, - SM510_PORT_SEGB = 0x04, - SM510_PORT_SEGBS = 0x08, - SM510_PORT_SEGC = 0x0c -}; +#include "sm510base.h" // pinout reference @@ -59,232 +44,6 @@ S8 60 | * | 16 b16 BA OSCout Vdd */ -class sm510_base_device : public cpu_device -{ -public: - // construction/destruction - sm510_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) - : cpu_device(mconfig, type, tag, owner, clock) - , m_program_config("program", ENDIANNESS_LITTLE, 8, prgwidth, 0, program) - , m_data_config("data", ENDIANNESS_LITTLE, 8, datawidth, 0, data) - , m_prgwidth(prgwidth) - , m_datawidth(datawidth) - , m_stack_levels(stack_levels) - , m_r_mask_option(RMASK_DIRECT) - , m_lcd_ram_a(*this, "lcd_ram_a"), m_lcd_ram_b(*this, "lcd_ram_b"), m_lcd_ram_c(*this, "lcd_ram_c") - , m_write_segs(*this) - , m_melody_rom(*this, "melody") - , m_read_k(*this) - , m_read_ba(*this), m_read_b(*this) - , m_write_s(*this) - , m_write_r(*this) - { } - - // For SM510, SM500, SM5A, R port output is selected with a mask option, - // either from the divider or direct contol. Documented options are: - // SM510/SM5A: direct control, 2(4096Hz meant for alarm sound) - // SM500: 14, 11, 3 (divider f1, f4, f12) - void set_r_mask_option(int bit) { m_r_mask_option = bit; } - static constexpr int RMASK_DIRECT = -1; - - // 4-bit K input port (pull-down) - auto read_k() { return m_read_k.bind(); } - - // 1-bit BA(aka alpha) input pin (pull-up) - auto read_ba() { return m_read_ba.bind(); } - - // 1-bit B(beta) input pin (pull-up) - auto read_b() { return m_read_b.bind(); } - - // 8-bit S strobe output port - auto write_s() { return m_write_s.bind(); } - - // 1/2/4-bit R (buzzer/melody) output port - auto write_r() { return m_write_r.bind(); } - - // LCD segment outputs, SM51X: H1-4 as offset(low), a/b/c 1-16 as data d0-d15, - // bs output is same as above, but only up to 2 bits used. - // SM500/SM5A: H1/2 as a0, O group as a1-a4, O data as d0-d3 - auto write_segs() { return m_write_segs.bind(); } - -protected: - // 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 + m_clk_div - 1) / m_clk_div; } // default 2 cycles per machine cycle - virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * m_clk_div); } // " - 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_set_input(int line, int state) override; - virtual void execute_run() override; - virtual void execute_one() { } // -> child class - - // device_memory_interface overrides - virtual space_config_vector memory_space_config() const override; - - address_space_config m_program_config; - address_space_config m_data_config; - address_space *m_program; - address_space *m_data; - - virtual void reset_vector() { do_branch(3, 7, 0); } - virtual void wakeup_vector() { do_branch(1, 0, 0); } // after halt - - int m_prgwidth; - int m_datawidth; - int m_prgmask; - int m_datamask; - - u16 m_pc, m_prev_pc; - u16 m_op, m_prev_op; - u8 m_param; - int m_stack_levels; - u16 m_stack[4]; // max 4 - int m_icount; - - u8 m_acc; - u8 m_bl; - u8 m_bm; - bool m_sbm; - bool m_sbl; - u8 m_c; - bool m_skip; - u8 m_w; - u8 m_r, m_r_out; - int m_r_mask_option; - bool m_k_active; - bool m_halt; - int m_clk_div; - - // lcd driver - optional_shared_ptr m_lcd_ram_a, m_lcd_ram_b, m_lcd_ram_c; - devcb_write16 m_write_segs; - emu_timer *m_lcd_timer; - u8 m_l, m_x; - u8 m_y; - u8 m_bp; - bool m_bc; - - u16 get_lcd_row(int column, u8* ram); - virtual void lcd_update(); - TIMER_CALLBACK_MEMBER(lcd_timer_cb); - virtual void init_lcd_driver(); - - // melody controller - optional_region_ptr m_melody_rom; - u8 m_melody_rd; - u8 m_melody_step_count; - u8 m_melody_duty_count; - u8 m_melody_duty_index; - u8 m_melody_address; - - virtual void clock_melody() { } - virtual void init_melody() { } - - // interrupt/divider - emu_timer *m_div_timer; - u16 m_div; - bool m_1s; - - virtual bool wake_me_up(); - virtual void init_divider(); - TIMER_CALLBACK_MEMBER(div_timer_cb); - - // other i/o handlers - devcb_read8 m_read_k; - devcb_read_line m_read_ba; - devcb_read_line m_read_b; - devcb_write8 m_write_s; - devcb_write8 m_write_r; - - // misc internal helpers - virtual void increment_pc(); - virtual void get_opcode_param() { } - virtual void update_w_latch() { } - - virtual u8 ram_r(); - virtual void ram_w(u8 data); - void pop_stack(); - void push_stack(); - virtual void do_branch(u8 pu, u8 pm, u8 pl); - u8 bitmask(u16 param); - - // opcode handlers - virtual void op_lb(); - virtual void op_lbl(); - virtual void op_sbl(); - virtual void op_sbm(); - virtual void op_exbla(); - virtual void op_incb(); - virtual void op_decb(); - - virtual void op_atpl(); - virtual void op_rtn0(); - virtual void op_rtn1(); - virtual void op_tl(); - virtual void op_tml(); - virtual void op_tm(); - virtual void op_t(); - - virtual void op_exc(); - virtual void op_bdc(); - virtual void op_exci(); - virtual void op_excd(); - virtual void op_lda(); - virtual void op_lax(); - virtual void op_ptw(); - virtual void op_wr(); - virtual void op_ws(); - - virtual void op_kta(); - virtual void op_atbp(); - virtual void op_atx(); - virtual void op_atl(); - virtual void op_atfc(); - virtual void op_atr(); - - virtual void op_add(); - virtual void op_add11(); - virtual void op_adx(); - virtual void op_coma(); - virtual void op_rot(); - virtual void op_rc(); - virtual void op_sc(); - - virtual void op_tb(); - virtual void op_tc(); - virtual void op_tam(); - virtual void op_tmi(); - virtual void op_ta0(); - virtual void op_tabl(); - virtual void op_tis(); - virtual void op_tal(); - virtual void op_tf1(); - virtual void op_tf4(); - - virtual void op_rm(); - virtual void op_sm(); - - virtual void op_pre(); - virtual void op_sme(); - virtual void op_rme(); - virtual void op_tmel(); - - virtual void op_skip(); - virtual void op_cend(); - virtual void op_idiv(); - virtual void op_dr(); - virtual void op_dta(); - virtual void op_clklo(); - virtual void op_clkhi(); - - void op_illegal(); -}; - - class sm510_device : public sm510_base_device { public: @@ -296,7 +55,7 @@ protected: virtual std::unique_ptr create_disassembler() override; virtual void execute_one() override; - virtual void get_opcode_param() override; + virtual bool op_argument() override; virtual void update_w_latch() override { m_write_s(m_w); } // W is connected directly to S @@ -304,41 +63,6 @@ protected: }; -class sm511_device : public sm510_base_device -{ -public: - sm511_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); - -protected: - sm511_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); - - void program_4k(address_map &map); - void data_96_32x4(address_map &map); - - virtual void device_post_load() override { notify_clock_changed(); } - virtual void device_reset() override; - - virtual std::unique_ptr create_disassembler() override; - virtual void execute_one() override; - virtual void get_opcode_param() override; - - virtual void clock_melody() override; - virtual void init_melody() override; -}; - -class sm512_device : public sm511_device -{ -public: - sm512_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); - -protected: - void data_80_48x4(address_map &map); -}; - - - DECLARE_DEVICE_TYPE(SM510, sm510_device) -DECLARE_DEVICE_TYPE(SM511, sm511_device) -DECLARE_DEVICE_TYPE(SM512, sm512_device) #endif // MAME_CPU_SM510_SM510_H diff --git a/src/devices/cpu/sm510/sm510base.cpp b/src/devices/cpu/sm510/sm510base.cpp index cca35da7730..78913087120 100644 --- a/src/devices/cpu/sm510/sm510base.cpp +++ b/src/devices/cpu/sm510/sm510base.cpp @@ -13,16 +13,10 @@ Default external frequency of these is 32.768kHz, forwarding a clockrate in the MAME machine config is optional. Newer revisions can have an internal oscillator. - TODO: - - source organiziation between files is a mess - - wake up after CEND doesn't work right - - for more, see the *core.cpp file notes - */ #include "emu.h" -#include "sm510.h" +#include "sm510base.h" #include "debugger.h" @@ -38,6 +32,8 @@ enum void sm510_base_device::device_start() { + assert(SM510_INPUT_LINE_K1 == 0); + m_program = &space(AS_PROGRAM); m_data = &space(AS_DATA); m_prgmask = (1 << m_prgwidth) - 1; @@ -52,7 +48,7 @@ void sm510_base_device::device_start() m_write_segs.resolve_safe(); // init/zerofill - memset(m_stack, 0, sizeof(m_stack)); + std::fill_n(m_stack, std::size(m_stack), 0); m_pc = 0; m_prev_pc = 0; m_op = 0; @@ -70,7 +66,9 @@ void sm510_base_device::device_start() m_r_out = 0; m_div = 0; m_1s = false; - m_k_active = false; + m_1s_rise = false; + m_k_rise = false; + std::fill_n(m_k_input, std::size(m_k_input), 0); m_l = 0; m_x = 0; m_y = 0; @@ -103,7 +101,9 @@ void sm510_base_device::device_start() save_item(NAME(m_r_out)); save_item(NAME(m_div)); save_item(NAME(m_1s)); - save_item(NAME(m_k_active)); + save_item(NAME(m_1s_rise)); + save_item(NAME(m_k_rise)); + save_item(NAME(m_k_input)); save_item(NAME(m_l)); save_item(NAME(m_x)); save_item(NAME(m_y)); @@ -138,6 +138,13 @@ void sm510_base_device::device_start() init_melody(); } +device_memory_interface::space_config_vector sm510_base_device::memory_space_config() const +{ + return space_config_vector { + std::make_pair(AS_PROGRAM, &m_program_config), + std::make_pair(AS_DATA, &m_data_config) + }; +} //------------------------------------------------- @@ -165,7 +172,6 @@ void sm510_base_device::device_reset() } - //------------------------------------------------- // lcd driver //------------------------------------------------- @@ -183,14 +189,6 @@ inline u16 sm510_base_device::get_lcd_row(int column, u8* ram) return rowdata; } -device_memory_interface::space_config_vector sm510_base_device::memory_space_config() const -{ - return space_config_vector { - std::make_pair(AS_PROGRAM, &m_program_config), - std::make_pair(AS_DATA, &m_data_config) - }; -} - void sm510_base_device::lcd_update() { // 4 columns @@ -222,44 +220,20 @@ void sm510_base_device::init_lcd_driver() } - //------------------------------------------------- -// interrupt/divider +// divider //------------------------------------------------- -bool sm510_base_device::wake_me_up() -{ - // in halt mode, wake up after 1S signal or K input - if (m_k_active || m_1s) - { - // note: official doc warns that Bl/Bm and the stack are undefined - // after waking up, but we leave it unchanged - m_halt = false; - wakeup_vector(); - - standard_irq_callback(0); - return true; - } - else - return false; -} - -void sm510_base_device::execute_set_input(int line, int state) -{ - if (line != SM510_INPUT_LINE_K) - return; - - // set K input lines active state - m_k_active = (state != 0); -} - TIMER_CALLBACK_MEMBER(sm510_base_device::div_timer_cb) { m_div = (m_div + 1) & 0x7fff; // 1S signal on overflow(falling edge of F1) if (m_div == 0) + { + m_1s_rise = !m_1s; m_1s = true; + } clock_melody(); } @@ -271,6 +245,33 @@ void sm510_base_device::init_divider() } +//------------------------------------------------- +// interrupt +//------------------------------------------------- + +void sm510_base_device::execute_set_input(int line, int state) +{ + if (!valid_wakeup_line(line)) + return; + + // rising edge of any K input + if (state && !m_k_input[line]) + m_k_rise = true; + + m_k_input[line] = state; +} + +void sm510_base_device::do_interrupt() +{ + // note: official doc warns that Bl/Bm and the stack are undefined + // after waking up, but we leave it unchanged + m_icount--; + m_halt = false; + wakeup_vector(); + + standard_irq_callback(0); +} + //------------------------------------------------- // execute @@ -286,17 +287,29 @@ void sm510_base_device::increment_pc() void sm510_base_device::execute_run() { + bool _1s_prev = m_1s_rise; + while (m_icount > 0) { - m_icount--; + // in halt mode, wake up after 1S signal or K input + bool wakeup = m_k_rise || m_1s_rise; + m_k_rise = false; + m_1s_rise = false; - if (m_halt && !wake_me_up()) + if (m_halt) { - // got nothing to do - m_icount = 0; - return; + if (!wakeup) + { + // got nothing to do + m_icount = 0; + return; + } + else + do_interrupt(); } + m_icount--; + // remember previous state m_prev_op = m_op; m_prev_pc = m_pc; @@ -306,7 +319,14 @@ void sm510_base_device::execute_run() debugger_instruction_hook(m_pc); m_op = m_program->read_byte(m_pc); increment_pc(); - get_opcode_param(); + + // 2-byte opcodes + if (op_argument()) + { + m_icount--; + m_param = m_program->read_byte(m_pc); + increment_pc(); + } // handle opcode if it's not skipped if (m_skip) @@ -316,5 +336,10 @@ void sm510_base_device::execute_run() } else execute_one(); + + // if CEND triggered at the same time as 1S signal, make sure it still wakes up + if (m_halt) + m_1s_rise = _1s_prev; + _1s_prev = false; } } diff --git a/src/devices/cpu/sm510/sm510base.h b/src/devices/cpu/sm510/sm510base.h new file mode 100644 index 00000000000..3850089dc28 --- /dev/null +++ b/src/devices/cpu/sm510/sm510base.h @@ -0,0 +1,274 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Sharp SM510 MCU family - base/shared + + Don't include this file, include the specific device header instead, + for example sm510.h + +*/ + +#ifndef MAME_CPU_SM510_SM510BASE_H +#define MAME_CPU_SM510_SM510BASE_H + +#pragma once + +// I/O ports setup + +// when in halt state, any K input going high can wake up the CPU, +// driver is required to use set_input_line(SM510_INPUT_LINE_K1/K2/K3/K4, state) +enum +{ + SM510_INPUT_LINE_K1 = 0, + SM510_INPUT_LINE_K2, + SM510_INPUT_LINE_K3, + SM510_INPUT_LINE_K4 +}; + +// ACL input pin +#define SM510_INPUT_LINE_ACL INPUT_LINE_RESET + +// LCD commons +enum +{ + SM510_PORT_SEGA = 0x00, + SM510_PORT_SEGB = 0x04, + SM510_PORT_SEGBS = 0x08, + SM510_PORT_SEGC = 0x0c +}; + + +class sm510_base_device : public cpu_device +{ +public: + // construction/destruction + sm510_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) + : cpu_device(mconfig, type, tag, owner, clock) + , m_program_config("program", ENDIANNESS_LITTLE, 8, prgwidth, 0, program) + , m_data_config("data", ENDIANNESS_LITTLE, 8, datawidth, 0, data) + , m_prgwidth(prgwidth) + , m_datawidth(datawidth) + , m_stack_levels(stack_levels) + , m_r_mask_option(RMASK_DIRECT) + , m_lcd_ram_a(*this, "lcd_ram_a"), m_lcd_ram_b(*this, "lcd_ram_b"), m_lcd_ram_c(*this, "lcd_ram_c") + , m_write_segs(*this) + , m_melody_rom(*this, "melody") + , m_read_k(*this) + , m_read_ba(*this), m_read_b(*this) + , m_write_s(*this) + , m_write_r(*this) + { } + + // For SM510, SM500, SM5A, R port output is selected with a mask option, + // either from the divider or direct contol. Documented options are: + // SM510/SM5A: direct control, 2(4096Hz meant for alarm sound) + // SM500: 14, 11, 3 (divider f1, f4, f12) + void set_r_mask_option(int bit) { m_r_mask_option = bit; } + static constexpr int RMASK_DIRECT = -1; + + // 4-bit K input port (pull-down) + auto read_k() { return m_read_k.bind(); } + + // 1-bit BA(aka alpha) input pin (pull-up) + auto read_ba() { return m_read_ba.bind(); } + + // 1-bit B(beta) input pin (pull-up) + auto read_b() { return m_read_b.bind(); } + + // 8-bit S strobe output port + auto write_s() { return m_write_s.bind(); } + + // 1/2/4-bit R (buzzer/melody) output port + auto write_r() { return m_write_r.bind(); } + + // LCD segment outputs, SM51X: H1-4 as offset(low), a/b/c 1-16 as data d0-d15, + // bs output is same as above, but only up to 2 bits used. + // SM500/SM5A: H1/2 as a0, O group as a1-a4, O data as d0-d3 + auto write_segs() { return m_write_segs.bind(); } + +protected: + // 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 + m_clk_div - 1) / m_clk_div; } // default 2 cycles per machine cycle + virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * m_clk_div); } // " + virtual u32 execute_min_cycles() const noexcept override { return 1; } + virtual u32 execute_max_cycles() const noexcept override { return 3+1; } + virtual u32 execute_input_lines() const noexcept override { return 4; } + virtual bool execute_input_edge_triggered(int inputnum) const noexcept override { return valid_wakeup_line(inputnum); } + virtual void execute_set_input(int line, int state) override; + virtual void execute_run() override; + + virtual void execute_one() { } // -> child class + virtual bool op_argument() { return false; } + + // device_memory_interface overrides + virtual space_config_vector memory_space_config() const override; + + address_space_config m_program_config; + address_space_config m_data_config; + address_space *m_program; + address_space *m_data; + + virtual void reset_vector() { do_branch(3, 7, 0); } + virtual void wakeup_vector() { do_branch(1, 0, 0); } // after halt + virtual bool valid_wakeup_line(int line) const { return (line >= 0 && line < 4); } + + int m_prgwidth; + int m_datawidth; + int m_prgmask; + int m_datamask; + + u16 m_pc, m_prev_pc; + u16 m_op, m_prev_op; + u8 m_param; + int m_stack_levels; + u16 m_stack[4]; // max 4 + int m_icount; + + u8 m_acc; + u8 m_bl; + u8 m_bm; + bool m_sbm; + bool m_sbl; + u8 m_c; + bool m_skip; + u8 m_w; + u8 m_r; + u8 m_r_out; + int m_r_mask_option; + int m_k_input[4]; + bool m_k_rise; + bool m_halt; + int m_clk_div; + + // lcd driver + optional_shared_ptr m_lcd_ram_a, m_lcd_ram_b, m_lcd_ram_c; + devcb_write16 m_write_segs; + emu_timer *m_lcd_timer; + u8 m_l; + u8 m_x; + u8 m_y; + u8 m_bp; + bool m_bc; + + u16 get_lcd_row(int column, u8* ram); + virtual void lcd_update(); + TIMER_CALLBACK_MEMBER(lcd_timer_cb); + virtual void init_lcd_driver(); + + // melody controller + optional_region_ptr m_melody_rom; + u8 m_melody_rd; + u8 m_melody_step_count; + u8 m_melody_duty_count; + u8 m_melody_duty_index; + u8 m_melody_address; + + virtual void clock_melody() { } + virtual void init_melody() { } + + // divider + emu_timer *m_div_timer; + u16 m_div; + bool m_1s; + bool m_1s_rise; + + virtual void init_divider(); + TIMER_CALLBACK_MEMBER(div_timer_cb); + + // other i/o handlers + devcb_read8 m_read_k; + devcb_read_line m_read_ba; + devcb_read_line m_read_b; + devcb_write8 m_write_s; + devcb_write8 m_write_r; + + // misc internal helpers + virtual void increment_pc(); + virtual void update_w_latch() { } + void do_interrupt(); + + virtual u8 ram_r(); + virtual void ram_w(u8 data); + void pop_stack(); + void push_stack(); + virtual void do_branch(u8 pu, u8 pm, u8 pl); + u8 bitmask(u16 param); + + // opcode handlers + virtual void op_lb(); + virtual void op_lbl(); + virtual void op_sbl(); + virtual void op_sbm(); + virtual void op_exbla(); + virtual void op_incb(); + virtual void op_decb(); + + virtual void op_atpl(); + virtual void op_rtn0(); + virtual void op_rtn1(); + virtual void op_tl(); + virtual void op_tml(); + virtual void op_tm(); + virtual void op_t(); + + virtual void op_exc(); + virtual void op_bdc(); + virtual void op_exci(); + virtual void op_excd(); + virtual void op_lda(); + virtual void op_lax(); + virtual void op_ptw(); + virtual void op_wr(); + virtual void op_ws(); + + virtual void op_kta(); + virtual void op_atbp(); + virtual void op_atx(); + virtual void op_atl(); + virtual void op_atfc(); + virtual void op_atr(); + + virtual void op_add(); + virtual void op_add11(); + virtual void op_adx(); + virtual void op_coma(); + virtual void op_rot(); + virtual void op_rc(); + virtual void op_sc(); + + virtual void op_tb(); + virtual void op_tc(); + virtual void op_tam(); + virtual void op_tmi(); + virtual void op_ta0(); + virtual void op_tabl(); + virtual void op_tis(); + virtual void op_tal(); + virtual void op_tf1(); + virtual void op_tf4(); + + virtual void op_rm(); + virtual void op_sm(); + + virtual void op_pre(); + virtual void op_sme(); + virtual void op_rme(); + virtual void op_tmel(); + + virtual void op_skip(); + virtual void op_cend(); + virtual void op_idiv(); + virtual void op_dr(); + virtual void op_dta(); + virtual void op_clklo(); + virtual void op_clkhi(); + + void op_illegal(); +}; + +#endif // MAME_CPU_SM510_SM510BASE_H diff --git a/src/devices/cpu/sm510/sm510d.h b/src/devices/cpu/sm510/sm510d.h index 2d49cbb5059..b7d51786d4b 100644 --- a/src/devices/cpu/sm510/sm510d.h +++ b/src/devices/cpu/sm510/sm510d.h @@ -154,4 +154,4 @@ private: static const u8 sm590_mnemonic[0x100]; }; -#endif +#endif // MAME_CPU_SM510_SM510D_H diff --git a/src/devices/cpu/sm510/sm510op.cpp b/src/devices/cpu/sm510/sm510op.cpp index 8570f6139b5..8f09d5f3dab 100644 --- a/src/devices/cpu/sm510/sm510op.cpp +++ b/src/devices/cpu/sm510/sm510op.cpp @@ -4,7 +4,7 @@ // SM510 shared opcode handlers #include "emu.h" -#include "sm510.h" +#include "sm510base.h" // internal helpers @@ -52,7 +52,6 @@ u8 sm510_base_device::bitmask(u16 param) } - // instruction set // RAM address instructions @@ -154,7 +153,6 @@ void sm510_base_device::op_tm() } - // Data transfer instructions void sm510_base_device::op_exc() diff --git a/src/devices/cpu/sm510/sm511core.cpp b/src/devices/cpu/sm510/sm511.cpp similarity index 96% rename from src/devices/cpu/sm510/sm511core.cpp rename to src/devices/cpu/sm510/sm511.cpp index 90de18142f7..c678ba975b7 100644 --- a/src/devices/cpu/sm510/sm511core.cpp +++ b/src/devices/cpu/sm510/sm511.cpp @@ -14,7 +14,7 @@ */ #include "emu.h" -#include "sm510.h" +#include "sm511.h" #include "sm510d.h" #include "debugger.h" @@ -67,7 +67,6 @@ sm512_device::sm512_device(const machine_config &mconfig, const char *tag, devic { } - //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- @@ -82,7 +81,6 @@ void sm511_device::device_reset() } - //------------------------------------------------- // melody controller //------------------------------------------------- @@ -158,22 +156,10 @@ void sm511_device::init_melody() } - //------------------------------------------------- // execute //------------------------------------------------- -void sm511_device::get_opcode_param() -{ - // LBL, PRE, TL, TML and prefix opcodes are 2 bytes - if ((m_op >= 0x5f && m_op <= 0x61) || (m_op & 0xf0) == 0x70 || (m_op & 0xfc) == 0x68) - { - m_icount--; - m_param = m_program->read_byte(m_pc); - increment_pc(); - } -} - void sm511_device::execute_one() { switch (m_op & 0xf0) @@ -267,3 +253,9 @@ void sm511_device::execute_one() // BM high bit is only valid for 1 step m_sbm = (m_op == 0x02); } + +bool sm511_device::op_argument() +{ + // LBL, PRE, TL, TML and prefix opcodes are 2 bytes + return (m_op >= 0x5f && m_op <= 0x61) || (m_op & 0xf0) == 0x70 || (m_op & 0xfc) == 0x68; +} diff --git a/src/devices/cpu/sm510/sm511.h b/src/devices/cpu/sm510/sm511.h new file mode 100644 index 00000000000..54066d1d405 --- /dev/null +++ b/src/devices/cpu/sm510/sm511.h @@ -0,0 +1,62 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Sharp SM511 MCU family cores + +*/ + +#ifndef MAME_CPU_SM510_SM511_H +#define MAME_CPU_SM510_SM511_H + +#pragma once + +#include "sm510base.h" + + +// pinout reference + +/* + +SM511: identical to SM510 (see sm510.h) + +SM512: can't be bothered to draw one here, it's 80 pins QFP, a lot of LCD segment pins + +*/ + +class sm511_device : public sm510_base_device +{ +public: + sm511_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); + +protected: + sm511_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); + + void program_4k(address_map &map); + void data_96_32x4(address_map &map); + + virtual void device_post_load() override { notify_clock_changed(); } + virtual void device_reset() override; + + virtual std::unique_ptr create_disassembler() override; + virtual void execute_one() override; + virtual bool op_argument() override; + + virtual void clock_melody() override; + virtual void init_melody() override; +}; + +class sm512_device : public sm511_device +{ +public: + sm512_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); + +protected: + void data_80_48x4(address_map &map); +}; + + +DECLARE_DEVICE_TYPE(SM511, sm511_device) +DECLARE_DEVICE_TYPE(SM512, sm512_device) + +#endif // MAME_CPU_SM510_SM511_H diff --git a/src/devices/cpu/sm510/sm530core.cpp b/src/devices/cpu/sm510/sm530.cpp similarity index 96% rename from src/devices/cpu/sm510/sm530core.cpp rename to src/devices/cpu/sm510/sm530.cpp index 3d3a424ad90..3b73ee036f2 100644 --- a/src/devices/cpu/sm510/sm530core.cpp +++ b/src/devices/cpu/sm510/sm530.cpp @@ -55,7 +55,6 @@ sm531_device::sm531_device(const machine_config &mconfig, const char *tag, devic { } - //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- @@ -67,7 +66,6 @@ void sm530_device::device_start() } - //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- @@ -79,22 +77,10 @@ void sm530_device::device_reset() } - //------------------------------------------------- // execute //------------------------------------------------- -void sm530_device::get_opcode_param() -{ - // LBL, PRE, TL opcodes are 2 bytes - if (m_op == 0x6b || m_op == 0x78 || ((m_op & 0xf8) == 0x60)) - { - m_icount--; - m_param = m_program->read_byte(m_pc); - increment_pc(); - } -} - void sm530_device::execute_one() { switch (m_op & 0xf0) @@ -174,3 +160,9 @@ void sm530_device::execute_one() m_sbl = (m_op == 0x73); m_sbm = (m_op == 0x72); } + +bool sm530_device::op_argument() +{ + // LBL, PRE, TL opcodes are 2 bytes + return m_op == 0x6b || m_op == 0x78 || ((m_op & 0xf8) == 0x60); +} diff --git a/src/devices/cpu/sm510/sm530.h b/src/devices/cpu/sm510/sm530.h index e0c3b4dd769..66136b89904 100644 --- a/src/devices/cpu/sm510/sm530.h +++ b/src/devices/cpu/sm510/sm530.h @@ -11,7 +11,7 @@ #pragma once -#include "sm510.h" +#include "sm511.h" class sm530_device : public sm511_device @@ -32,7 +32,7 @@ protected: virtual u64 execute_clocks_to_cycles(u64 clocks) const noexcept override { return (clocks + 3 - 1) / 3; } // 3 cycles per machine cycle virtual u64 execute_cycles_to_clocks(u64 cycles) const noexcept override { return (cycles * 3); } // " virtual void execute_one() override; - virtual void get_opcode_param() override; + virtual bool op_argument() override; using sm510_base_device::do_branch; virtual void do_branch(u8 pu, u8 pl); // does not have Pm @@ -58,7 +58,6 @@ public: }; - DECLARE_DEVICE_TYPE(SM530, sm530_device) DECLARE_DEVICE_TYPE(SM531, sm531_device) diff --git a/src/devices/cpu/sm510/sm530op.cpp b/src/devices/cpu/sm510/sm530op.cpp index 3aec192b0a0..6beaa8905f4 100644 --- a/src/devices/cpu/sm510/sm530op.cpp +++ b/src/devices/cpu/sm510/sm530op.cpp @@ -16,7 +16,6 @@ void sm530_device::do_branch(u8 pu, u8 pl) } - // instruction set // RAM address instructions diff --git a/src/devices/cpu/sm510/sm590core.cpp b/src/devices/cpu/sm510/sm590.cpp similarity index 91% rename from src/devices/cpu/sm510/sm590core.cpp rename to src/devices/cpu/sm510/sm590.cpp index fd1bca5fc9d..d45fbbe7a82 100644 --- a/src/devices/cpu/sm510/sm590core.cpp +++ b/src/devices/cpu/sm510/sm590.cpp @@ -61,6 +61,7 @@ std::unique_ptr sm590_device::create_disassembler() //------------------------------------------------- // device_reset - device-specific reset //------------------------------------------------- + void sm590_device::device_reset() { // ACL @@ -76,27 +77,11 @@ void sm590_device::device_reset() //m_write_r(0); // TODO: are the four ports zeroed on reset? } -//------------------------------------------------- -// wake from suspend mode -//------------------------------------------------- -bool sm590_device::wake_me_up() -{ - // in halt mode, wake up after R2.2 goes high - if (m_rports[2]&0x4) - { - m_halt = false; - do_branch(0, 1, 0); // field 0, page 1, step 0 - - standard_irq_callback(0); - return true; - } - else - return false; -} //------------------------------------------------- // execute //------------------------------------------------- + void sm590_device::increment_pc() { // PL(program counter low 7 bits) is a simple LFSR: newbit = (bit0==bit1) @@ -105,17 +90,6 @@ void sm590_device::increment_pc() m_pc = feed | (m_pc >> 1 & 0x3f) | (m_pc & ~0x7f); } -void sm590_device::get_opcode_param() -{ - // TL, TLS(TML) opcodes are 2 bytes - if ((m_op & 0xf8) == 0x78) - { - m_icount--; - m_param = m_program->read_byte(m_pc); - increment_pc(); - } -} - void sm590_device::execute_one() { switch (m_op & 0xf0) // opcodes with 4 bit params @@ -184,3 +158,9 @@ void sm590_device::execute_one() } // big switch } + +bool sm590_device::op_argument() +{ + // TL, TLS(TML) opcodes are 2 bytes + return (m_op & 0xf8) == 0x78; +} diff --git a/src/devices/cpu/sm510/sm590.h b/src/devices/cpu/sm510/sm590.h index 5a3bd33ad37..f6b7416d044 100644 --- a/src/devices/cpu/sm510/sm590.h +++ b/src/devices/cpu/sm510/sm590.h @@ -9,12 +9,13 @@ #ifndef MAME_CPU_SM510_SM590_H #define MAME_CPU_SM510_SM590_H -#include "sm510.h" +#include "sm510base.h" // I/O ports setup -// .. +// It does not have K pins, but can wake up after halt on R2.2 +#define SM590_INPUT_LINE_R22 SM510_INPUT_LINE_K3 // pinout reference @@ -89,7 +90,6 @@ R3.3/CL2 => |_|6 15|_| <> R1.3 GND -- |_|10 11|_| <> R1.0 |____________| - */ class sm590_device : public sm510_base_device @@ -105,17 +105,17 @@ protected: virtual void device_reset() override; virtual std::unique_ptr create_disassembler() override; - virtual bool wake_me_up() override; virtual void init_divider() override { } virtual void init_lcd_driver() override { } virtual void init_melody() override { } virtual void increment_pc() override; virtual void execute_one() override; - virtual void get_opcode_param() override; + virtual bool op_argument() override; virtual void do_branch(u8 pu, u8 pm, u8 pl) override; virtual void reset_vector() override { do_branch(0, 0, 0); } virtual void wakeup_vector() override { do_branch(0, 1, 0); } + virtual bool valid_wakeup_line(int line) const override { return (line == SM590_INPUT_LINE_R22); } // opcode handlers // 00-3f diff --git a/src/devices/cpu/sm510/sm590op.cpp b/src/devices/cpu/sm510/sm590op.cpp index c9ead123360..ff0b902c697 100644 --- a/src/devices/cpu/sm510/sm590op.cpp +++ b/src/devices/cpu/sm510/sm590op.cpp @@ -15,6 +15,7 @@ void sm590_device::do_branch(u8 pu, u8 pm, u8 pl) m_pc = (((u16)pu << 9 & 0x200) | ((u16)pm << 7 & 0x180) | (pl & 0x07f)) & m_prgmask; } + // instruction set void sm590_device::op_adx() diff --git a/src/devices/cpu/sm510/sm5acore.cpp b/src/devices/cpu/sm510/sm5a.cpp similarity index 99% rename from src/devices/cpu/sm510/sm5acore.cpp rename to src/devices/cpu/sm510/sm5a.cpp index a48ffb8110d..a6dbf24edab 100644 --- a/src/devices/cpu/sm510/sm5acore.cpp +++ b/src/devices/cpu/sm510/sm5a.cpp @@ -10,7 +10,7 @@ */ #include "emu.h" -#include "sm500.h" +#include "sm5a.h" #include "sm510d.h" #include "debugger.h" diff --git a/src/devices/cpu/sm510/sm5a.h b/src/devices/cpu/sm510/sm5a.h new file mode 100644 index 00000000000..de7128078d6 --- /dev/null +++ b/src/devices/cpu/sm510/sm5a.h @@ -0,0 +1,79 @@ +// license:BSD-3-Clause +// copyright-holders:hap +/* + + Sharp SM5A MCU family cores + +*/ + +#ifndef MAME_CPU_SM510_SM5A_H +#define MAME_CPU_SM510_SM5A_H + +#pragma once + +#include "sm500.h" + + +// pinout reference + +/* + + OS2 OS3 OS4 K4 K3 K2 K1 GND al bt ACL _R1 _Tp NC NC note: on SM5L, pin 31=V1, 32=V2, 33=NC + 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 + ____________________________________________________________ + | | +OS1 46 | | 30 H1 +O41 47 | | 29 H2 +O31 48 | | 28 Vm +O21 49 | | 27 Vdd +O11 50 | | 26 _R2 +O42 51 | | 25 _R3 +O32 52 | SM5A | 24 _R4 +O22 53 | SM5L | 23 OSCin +O12 54 | | 22 OSCout +O43 55 | | 21 _T2 +O33 56 | | 20 _T1 +O23 57 | | 19 O18 +O13 58 | | 18 O28 +O44 59 | | 17 O38 +O34 60 | * | 16 O48 + |____________________________________________________________/ + + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + O24 O14 O45 O35 O25 O15 O46 GND O36 O26 O16 O47 O37 O27 O17 +*/ + +class sm5a_device : public sm500_device +{ +public: + sm5a_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); + +protected: + sm5a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_pins, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); + + void program_1_8k(address_map &map); + void data_5x13x4(address_map &map); + + virtual std::unique_ptr create_disassembler() override; + virtual void execute_one() override; + virtual int get_trs_field() override { return 1; } +}; + +class sm5l_device : public sm5a_device +{ +public: + sm5l_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); +}; + +class kb1013vk12_device : public sm5a_device +{ +public: + kb1013vk12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32768); +}; + + +DECLARE_DEVICE_TYPE(SM5A, sm5a_device) +DECLARE_DEVICE_TYPE(SM5L, sm5l_device) +DECLARE_DEVICE_TYPE(KB1013VK12, kb1013vk12_device) + +#endif // MAME_CPU_SM510_SM5A_H diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp index a38baa95b92..1017968ab56 100644 --- a/src/mame/drivers/hh_sm510.cpp +++ b/src/mame/drivers/hh_sm510.cpp @@ -277,9 +277,6 @@ void hh_sm510_state::sm500_lcd_segment_w(offs_t offset, u16 data) // generic input handlers - usually S output is input mux, and K input for buttons -#define PORT_CHANGED_CB(x) \ - PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, x, 0) - u8 hh_sm510_state::read_inputs(int columns, int fixed) { u8 ret = 0; @@ -298,7 +295,9 @@ u8 hh_sm510_state::read_inputs(int columns, int fixed) void hh_sm510_state::update_k_line() { // this is necessary because the MCU can wake up on K input activity - m_maincpu->set_input_line(SM510_INPUT_LINE_K, input_r() ? ASSERT_LINE : CLEAR_LINE); + u8 input = input_r(); + for (int i = 0; i < 4; i++) + m_maincpu->set_input_line(i, BIT(input, i) ? ASSERT_LINE : CLEAR_LINE); } INPUT_CHANGED_MEMBER(hh_sm510_state::input_changed) diff --git a/src/mame/drivers/rzone.cpp b/src/mame/drivers/rzone.cpp index 4631779e9ec..9a24b067a3b 100644 --- a/src/mame/drivers/rzone.cpp +++ b/src/mame/drivers/rzone.cpp @@ -40,6 +40,9 @@ // internal artwork #include "rzone.lh" + +namespace { + class rzone_state : public hh_sm510_state { public: @@ -53,6 +56,9 @@ public: void rztoshden(machine_config &config); void rzindy500(machine_config &config); +protected: + virtual void machine_start() override; + private: output_finder<> m_led_out; required_device m_led_off; @@ -75,8 +81,6 @@ private: void t2_update_audio(); void t2_write_r(u8 data); void t2_write_s(u8 data); - - virtual void machine_start() override; }; @@ -102,9 +106,7 @@ void rzone_state::machine_start() /*************************************************************************** - - I/O - + I/O ***************************************************************************/ // console @@ -214,47 +216,43 @@ void rzone_state::t2_write_s(u8 data) /*************************************************************************** - - Inputs - + Inputs ***************************************************************************/ static INPUT_PORTS_START( rzone ) PORT_START("IN.0") - PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, input_changed, 0) - PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) - PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) - PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON1 ) // A - PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON2 ) // B - PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON3 ) // C - PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_BUTTON4 ) // D - PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_VOLUME_DOWN ) PORT_NAME("Sound") - PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_SELECT ) - PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_POWER_OFF ) - PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Pause") - PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_POWER_ON ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_CHANGED_CB(input_changed) // A + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_CHANGED_CB(input_changed) // B + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_CHANGED_CB(input_changed) // C + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_CHANGED_CB(input_changed) // D + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_VOLUME_DOWN ) PORT_CHANGED_CB(input_changed) PORT_NAME("Sound") + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_POWER_OFF ) PORT_CHANGED_CB(input_changed) + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_CHANGED_CB(input_changed) PORT_NAME("Pause") + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_START ) PORT_CHANGED_CB(input_changed) INPUT_PORTS_END /*************************************************************************** - - Machine Config - + Machine Configs ***************************************************************************/ void rzone_state::rzbatfor(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware SM512(config, m_maincpu); // no external XTAL m_maincpu->write_segs().set(FUNC(rzone_state::sm510_lcd_segment_w)); m_maincpu->read_k().set(FUNC(rzone_state::input_r)); m_maincpu->write_s().set(FUNC(rzone_state::t2_write_s)); m_maincpu->write_r().set(FUNC(rzone_state::t2_write_r)); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); screen.set_refresh_hz(60); screen.set_size(1368, 1080); @@ -263,14 +261,14 @@ void rzone_state::rzbatfor(machine_config &config) TIMER(config, m_led_off).configure_generic(FUNC(rzone_state::led_off_callback)); config.set_default_layout(layout_rzone); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); } void rzone_state::rztoshden(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware SM510(config, m_maincpu); m_maincpu->set_r_mask_option(sm510_base_device::RMASK_DIRECT); m_maincpu->write_segs().set(FUNC(rzone_state::sm510_lcd_segment_w)); @@ -278,7 +276,7 @@ void rzone_state::rztoshden(machine_config &config) m_maincpu->write_s().set(FUNC(rzone_state::t1_write_s)); m_maincpu->write_r().set(FUNC(rzone_state::t1_write_r)); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); screen.set_refresh_hz(60); screen.set_size(1392, 1080); @@ -287,14 +285,14 @@ void rzone_state::rztoshden(machine_config &config) TIMER(config, m_led_off).configure_generic(FUNC(rzone_state::led_off_callback)); config.set_default_layout(layout_rzone); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); } void rzone_state::rzindy500(machine_config &config) { - /* basic machine hardware */ + // basic machine hardware SM510(config, m_maincpu); // no external XTAL m_maincpu->set_r_mask_option(sm510_base_device::RMASK_DIRECT); // confirmed m_maincpu->write_segs().set(FUNC(rzone_state::sm510_lcd_segment_w)); @@ -302,7 +300,7 @@ void rzone_state::rzindy500(machine_config &config) m_maincpu->write_s().set(FUNC(rzone_state::t1_write_s)); m_maincpu->write_r().set(FUNC(rzone_state::t1_write_r)); - /* video hardware */ + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG)); screen.set_refresh_hz(60); screen.set_size(1425, 1080); @@ -311,7 +309,7 @@ void rzone_state::rzindy500(machine_config &config) TIMER(config, m_led_off).configure_generic(FUNC(rzone_state::led_off_callback)); config.set_default_layout(layout_rzone); - /* sound hardware */ + // sound hardware SPEAKER(config, "mono").front_center(); SPEAKER_SOUND(config, m_speaker).add_route(ALL_OUTPUTS, "mono", 0.25); } @@ -319,9 +317,7 @@ void rzone_state::rzindy500(machine_config &config) /*************************************************************************** - - Game driver(s) - + ROM Definitions ***************************************************************************/ ROM_START( rzbatfor ) @@ -351,6 +347,13 @@ ROM_START( rzindy500 ) ROM_LOAD( "rzindy500.svg", 0, 533411, CRC(cfc85677) SHA1(014b9123d81fba1488b4a22a6b6fd0c09e22c1ea) ) ROM_END +} // anonymous namespace + + + +/*************************************************************************** + Drivers +***************************************************************************/ // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS CONS( 1995, rzbatfor, 0, 0, rzbatfor, rzone, rzone_state, empty_init, "Tiger Electronics", "R-Zone: Batman Forever", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/hh_sm510.h b/src/mame/includes/hh_sm510.h index 37b56c338f2..133a39c5061 100644 --- a/src/mame/includes/hh_sm510.h +++ b/src/mame/includes/hh_sm510.h @@ -9,10 +9,18 @@ #ifndef MAME_INCLUDES_HH_SM510_H #define MAME_INCLUDES_HH_SM510_H +#pragma once + #include "cpu/sm510/sm510.h" +#include "cpu/sm510/sm511.h" +#include "cpu/sm510/sm5a.h" #include "sound/spkrdev.h" +#define PORT_CHANGED_CB(x) \ + PORT_CHANGED_MEMBER(DEVICE_SELF, hh_sm510_state, x, 0) + + class hh_sm510_state : public driver_device { public: