From d09534c380bc6da8d2846e3ba3680cce374787ba Mon Sep 17 00:00:00 2001 From: hap Date: Sat, 24 Jun 2017 21:26:23 +0200 Subject: [PATCH] sm500: added lcd output (nw) --- src/devices/cpu/sm510/sm500.h | 14 +++- src/devices/cpu/sm510/sm500core.cpp | 28 ++++++- src/mame/drivers/hh_sm510.cpp | 39 +++++++++- src/mame/layout/hh_sm500_test.lay | 110 ++++++++++++++++++++++++++++ 4 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 src/mame/layout/hh_sm500_test.lay diff --git a/src/devices/cpu/sm510/sm500.h b/src/devices/cpu/sm510/sm500.h index ce7f57a5586..5a5e38924a5 100644 --- a/src/devices/cpu/sm510/sm500.h +++ b/src/devices/cpu/sm510/sm500.h @@ -16,6 +16,10 @@ // I/O ports setup +// LCD segment outputs: H1/2 as a4, O group as a0-a3, O data as d0-d3 +#define MCFG_SM500_WRITE_O_CB(_devcb) \ + devcb = &sm500_device::set_write_o_callback(*device, DEVCB_##_devcb); + // see sm510.h for ACL, K, R, alpha, beta @@ -75,6 +79,9 @@ class sm500_device : public sm510_base_device public: sm500_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + // static configuration helpers + template static devcb_base &set_write_o_callback(device_t &device, Object &&cb) { return downcast(device).m_write_o.set_callback(std::forward(cb)); } + protected: sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data); @@ -88,11 +95,16 @@ protected: virtual void reset_vector() override { do_branch(0, 0xf, 0); } virtual void wakeup_vector() override { do_branch(0, 0, 0); } + // lcd driver + devcb_write8 m_write_o; + virtual void lcd_update() override; + int m_o_mask; // number of 4-bit O pins minus 1 u8 m_ox[9]; // W' latch, max 9 u8 m_o[9]; // W latch u8 m_cn; u8 m_mx; + u8 m_cb; u8 m_s; bool m_rsub; @@ -102,7 +114,7 @@ protected: void set_su(u8 su) { m_stack[0] = (m_stack[0] & ~0x3c0) | (su << 6); } u8 get_su() { return m_stack[0] >> 6 & 0xf; } virtual int get_trs_field() { return 0; } - + // opcode handlers virtual void op_lb() override; virtual void op_incb() override; diff --git a/src/devices/cpu/sm510/sm500core.cpp b/src/devices/cpu/sm510/sm500core.cpp index 11cc9759115..6491a5a7aff 100644 --- a/src/devices/cpu/sm510/sm500core.cpp +++ b/src/devices/cpu/sm510/sm500core.cpp @@ -7,6 +7,7 @@ TODO: - EXKSA, EXKFA opcodes - SM500 data book suggests that R1 divider output is selectable, but how? + - unknown which H/O pin is which W output, guessed for now - ACL doesn't work right? */ @@ -41,6 +42,7 @@ sm500_device::sm500_device(const machine_config &mconfig, const char *tag, devic sm500_device::sm500_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, int stack_levels, int o_mask, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data) : sm510_base_device(mconfig, type, tag, owner, clock, stack_levels, prgwidth, program, datawidth, data), + m_write_o(*this), m_o_mask(o_mask) { } @@ -54,7 +56,10 @@ void sm500_device::device_start() { // common init (not everything is used though) sm510_base_device::device_start(); - + + // resolve callbacks + m_write_o.resolve_safe(); + // init/zerofill memset(m_ox, 0, sizeof(m_ox)); memset(m_o, 0, sizeof(m_o)); @@ -103,6 +108,27 @@ offs_t sm500_device::disasm_disassemble(std::ostream &stream, offs_t pc, const u } + +//------------------------------------------------- +// lcd driver +//------------------------------------------------- + +void sm500_device::lcd_update() +{ + // 2 columns + for (int h = 0; h < 2; h++) + { + for (int o = 0; o <= m_o_mask; o++) + { + // 4 segments per group + u8 seg = h ? m_o[o] : m_ox[o]; + m_write_o(h << 4 | o, m_bp ? seg : 0, 0xff); + } + } +} + + + //------------------------------------------------- // buzzer controller //------------------------------------------------- diff --git a/src/mame/drivers/hh_sm510.cpp b/src/mame/drivers/hh_sm510.cpp index f8eb1ee8558..8c2ed47442e 100644 --- a/src/mame/drivers/hh_sm510.cpp +++ b/src/mame/drivers/hh_sm510.cpp @@ -1,8 +1,9 @@ // license:BSD-3-Clause // copyright-holders:hap, Sean Riddle +// thanks-to:Igor /*************************************************************************** - Sharp SM510/SM511 handhelds. + Sharp SM5xx family handhelds. TODO: - gnw_mc25 emulation is preliminary @@ -29,6 +30,7 @@ #include "gnw_dualv.lh" #include "gnw_dualh.lh" //#include "hh_sm510_test.lh" // common test-layout - use external artwork +#include "hh_sm500_test.lh" // " class hh_sm510_state : public driver_device @@ -58,6 +60,7 @@ public: virtual DECLARE_INPUT_CHANGED_MEMBER(input_changed); virtual DECLARE_INPUT_CHANGED_MEMBER(acl_button); virtual DECLARE_WRITE16_MEMBER(sm510_lcd_segment_w); + virtual DECLARE_WRITE8_MEMBER(sm500_lcd_segment_w); virtual DECLARE_READ8_MEMBER(input_r); virtual DECLARE_WRITE8_MEMBER(input_w); virtual DECLARE_WRITE8_MEMBER(piezo_r1_w); @@ -121,6 +124,28 @@ WRITE16_MEMBER(hh_sm510_state::sm510_lcd_segment_w) } } +WRITE8_MEMBER(hh_sm510_state::sm500_lcd_segment_w) +{ + for (int seg = 0; seg < 4; seg++) + { + int index = offset << 2 | seg; + u8 state = data >> seg & 1; + + if (state != m_lcd_output_cache[index]) + { + // output to row.seg.H, where: + // row = O group (0-*) + // seg = O data (0-3) + // H = H1/H2 (0/1) + char buf[0x10]; + sprintf(buf, "%d.%d.%d", offset & 0xf, seg, offset >> 4); + output().set_value(buf, state); + + m_lcd_output_cache[index] = state; + } + } +} + // generic input handlers - usually S output is input mux, and K input for buttons @@ -530,9 +555,16 @@ MACHINE_CONFIG_END /*************************************************************************** - Nintendo Game & Watch: Mickey Mouse (model MC-25) + Nintendo Game & Watch: Mickey Mouse (model MC-25), Egg (model EG-26) * Sharp SM5A label ? + MC-25 and EG-26 are the same game, it's assumed that the latter was for + regions where Nintendo wasn't able to license from Disney. + + In 1984, Elektronika(USSR) released a clone, Nu, Pogodi! This was followed + by several other games that were the same under the hood, only differing + in graphics. + ***************************************************************************/ class mc25_state : public hh_sm510_state @@ -574,11 +606,12 @@ static MACHINE_CONFIG_START( mc25 ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", SM5A, XTAL_32_768kHz) + MCFG_SM500_WRITE_O_CB(WRITE8(hh_sm510_state, sm500_lcd_segment_w)) MCFG_SM510_READ_K_CB(READ8(hh_sm510_state, input_r)) MCFG_SM510_WRITE_R_CB(WRITE8(hh_sm510_state, piezo_input_w)) /* video hardware */ - // .. + MCFG_DEFAULT_LAYOUT(layout_hh_sm500_test) /* sound hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") diff --git a/src/mame/layout/hh_sm500_test.lay b/src/mame/layout/hh_sm500_test.lay new file mode 100644 index 00000000000..4ad1c920600 --- /dev/null +++ b/src/mame/layout/hh_sm500_test.lay @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +