sm510: fix wakeup after CEND, reorganize files a bit

This commit is contained in:
hap 2021-12-21 17:45:10 +01:00
parent 9a72f4594d
commit a44de917e1
23 changed files with 606 additions and 537 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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<util::disasm_interface> 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<util::disasm_interface> 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

View File

@ -4,9 +4,6 @@
Sharp SM510 MCU core implementation
TODO:
- X
*/
#include "emu.h"
@ -49,7 +46,6 @@ std::unique_ptr<util::disasm_interface> 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;
}

View File

@ -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<u8> 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<u8> 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<util::disasm_interface> 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<util::disasm_interface> 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

View File

@ -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;
}
}

View File

@ -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<u8> 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<u8> 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

View File

@ -154,4 +154,4 @@ private:
static const u8 sm590_mnemonic[0x100];
};
#endif
#endif // MAME_CPU_SM510_SM510D_H

View File

@ -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()

View File

@ -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;
}

View File

@ -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<util::disasm_interface> 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

View File

@ -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);
}

View File

@ -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)

View File

@ -16,7 +16,6 @@ void sm530_device::do_branch(u8 pu, u8 pl)
}
// instruction set
// RAM address instructions

View File

@ -61,6 +61,7 @@ std::unique_ptr<util::disasm_interface> 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;
}

View File

@ -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<util::disasm_interface> 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

View File

@ -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()

View File

@ -10,7 +10,7 @@
*/
#include "emu.h"
#include "sm500.h"
#include "sm5a.h"
#include "sm510d.h"
#include "debugger.h"

View File

@ -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<util::disasm_interface> 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

View File

@ -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)

View File

@ -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<timer_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 )

View File

@ -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: