diff options
author | 2015-07-09 16:18:50 +0200 | |
---|---|---|
committer | 2015-07-09 16:18:50 +0200 | |
commit | ad25e3afcf50097366d40b38fc9bea3ea5408433 (patch) | |
tree | 8e12653b2a80ddf8ad498b9158c5fb09f64219f4 /src/emu/cpu | |
parent | 72db110754846df1531e599b8ead000fe311513a (diff) |
added lcd driver
Diffstat (limited to 'src/emu/cpu')
-rw-r--r-- | src/emu/cpu/sm510/sm510.c | 58 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm510.h | 60 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm510core.c | 3 | ||||
-rw-r--r-- | src/emu/cpu/sm510/sm511core.c | 7 |
4 files changed, 106 insertions, 22 deletions
diff --git a/src/emu/cpu/sm510/sm510.c b/src/emu/cpu/sm510/sm510.c index 7f0fe7900f2..c2c282b373f 100644 --- a/src/emu/cpu/sm510/sm510.c +++ b/src/emu/cpu/sm510/sm510.c @@ -12,6 +12,7 @@ TODO: - proper support for LFSR program counter in debugger + - callback for lcd screen as MAME bitmap (when needed) */ @@ -36,9 +37,6 @@ void sm510_base_device::device_start() m_prgmask = (1 << m_prgwidth) - 1; m_datamask = (1 << m_datawidth) - 1; - m_div_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sm510_base_device::div_timer_cb), this)); - reset_divider(); - // resolve callbacks m_read_k.resolve_safe(0); m_read_ba.resolve_safe(1); @@ -46,6 +44,10 @@ void sm510_base_device::device_start() m_write_s.resolve_safe(); m_write_r.resolve_safe(); + m_write_sega.resolve_safe(); + m_write_segb.resolve_safe(); + m_write_segc.resolve_safe(); + // zerofill memset(m_stack, 0, sizeof(m_stack)); m_pc = 0; @@ -59,7 +61,7 @@ void sm510_base_device::device_start() m_c = 0; m_skip = false; m_w = 0; -// m_div = 0; + m_div = 0; m_1s = false; m_k_active = false; m_bp = false; @@ -98,6 +100,9 @@ void sm510_base_device::device_start() state_add(STATE_GENFLAGS, "GENFLAGS", m_c).formatstr("%1s").noshow(); m_icountptr = &m_icount; + + init_divider(); + init_lcd_driver(); } @@ -125,6 +130,45 @@ void sm510_base_device::device_reset() //------------------------------------------------- +// lcd driver +//------------------------------------------------- + +inline UINT16 sm510_base_device::get_lcd_row(int column, UINT8* ram) +{ + // output 0 if lcd blackpate/bleeder is off, or in case row doesn't exist + if (ram == NULL || m_bc || !m_bp) + return 0; + + UINT16 rowdata = 0; + for (int i = 0; i < 0x10; i++) + rowdata |= (ram[i] >> column & 1) << i; + + return rowdata; +} + +TIMER_CALLBACK_MEMBER(sm510_base_device::lcd_timer_cb) +{ + // 4 columns, 16 segments per row + for (int h = 0; h < 4; h++) + { + m_write_sega(h | SM510_PORT_SEGA, get_lcd_row(h, m_lcd_ram_a), 0xffff); + m_write_segb(h | SM510_PORT_SEGB, get_lcd_row(h, m_lcd_ram_b), 0xffff); + m_write_segc(h | SM510_PORT_SEGC, get_lcd_row(h, m_lcd_ram_c), 0xffff); + } + + // schedule next timeout + m_lcd_timer->adjust(attotime::from_ticks(0x200, unscaled_clock())); +} + +void sm510_base_device::init_lcd_driver() +{ + m_lcd_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sm510_base_device::lcd_timer_cb), this)); + m_lcd_timer->adjust(attotime::from_ticks(0x200, unscaled_clock())); // 64hz default +} + + + +//------------------------------------------------- // interrupt/timer //------------------------------------------------- @@ -175,6 +219,12 @@ void sm510_base_device::reset_divider() m_div_timer->adjust(attotime::from_ticks(0x800, unscaled_clock())); } +void sm510_base_device::init_divider() +{ + m_div_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sm510_base_device::div_timer_cb), this)); + reset_divider(); +} + //------------------------------------------------- diff --git a/src/emu/cpu/sm510/sm510.h b/src/emu/cpu/sm510/sm510.h index 30f6a837364..1428e22d823 100644 --- a/src/emu/cpu/sm510/sm510.h +++ b/src/emu/cpu/sm510/sm510.h @@ -17,6 +17,9 @@ // 4-bit K input port (pull-down) #define MCFG_SM510_READ_K_CB(_devcb) \ sm510_base_device::set_read_k_callback(*device, DEVCB_##_devcb); +// when in halt state, any K input going High can wake up the CPU, +// driver is required to use execute_set_input(SM510_INPUT_LINE_K, state) +#define SM510_INPUT_LINE_K 0 // 1-bit BA input pin (pull-up) #define MCFG_SM510_READ_BA_CB(_devcb) \ @@ -34,9 +37,20 @@ #define MCFG_SM510_WRITE_R_CB(_devcb) \ sm510_base_device::set_write_r_callback(*device, DEVCB_##_devcb); -// when in halt state, any K input going High can wake up the CPU, -// driver is required to use execute_set_input(SM510_INPUT_LINE_K, state) -#define SM510_INPUT_LINE_K 0 +// LCD segment outputs: H1-4 as offset(low), a/b/c 1-16 as data d0-d15 +#define MCFG_SM510_WRITE_SEGA_CB(_devcb) \ + sm510_base_device::set_write_sega_callback(*device, DEVCB_##_devcb); +#define MCFG_SM510_WRITE_SEGB_CB(_devcb) \ + sm510_base_device::set_write_segb_callback(*device, DEVCB_##_devcb); +#define MCFG_SM510_WRITE_SEGC_CB(_devcb) \ + sm510_base_device::set_write_segc_callback(*device, DEVCB_##_devcb); + +enum +{ + SM510_PORT_SEGA = 0x10, + SM510_PORT_SEGB = 0x20, + SM510_PORT_SEGC = 0x30 +}; // pinout reference @@ -53,13 +67,13 @@ public: : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source) , m_program_config("program", ENDIANNESS_LITTLE, 8, prgwidth, 0, program) , m_data_config("data", ENDIANNESS_LITTLE, 8, datawidth, 0, data) - , m_lcd_ram(*this, "lcd_ram") , m_prgwidth(prgwidth) , m_datawidth(datawidth) , m_stack_levels(stack_levels) + , 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_sega(*this), m_write_segb(*this), m_write_segc(*this) , m_read_k(*this) - , m_read_ba(*this) - , m_read_b(*this) + , m_read_ba(*this), m_read_b(*this) , m_write_s(*this) , m_write_r(*this) { } @@ -71,6 +85,10 @@ public: template<class _Object> static devcb_base &set_write_s_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_s.set_callback(object); } template<class _Object> static devcb_base &set_write_r_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_r.set_callback(object); } + template<class _Object> static devcb_base &set_write_sega_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_sega.set_callback(object); } + template<class _Object> static devcb_base &set_write_segb_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_segb.set_callback(object); } + template<class _Object> static devcb_base &set_write_segc_callback(device_t &device, _Object object) { return downcast<sm510_base_device &>(device).m_write_segc.set_callback(object); } + protected: // device-level overrides virtual void device_start(); @@ -97,7 +115,6 @@ protected: address_space_config m_data_config; address_space *m_program; address_space *m_data; - required_shared_ptr<UINT8> m_lcd_ram; int m_prgwidth; int m_datawidth; @@ -110,7 +127,6 @@ protected: int m_stack_levels; UINT16 m_stack[2]; int m_icount; - emu_timer *m_div_timer; UINT8 m_acc; UINT8 m_bl; @@ -118,14 +134,31 @@ protected: UINT8 m_c; bool m_skip; UINT8 m_w; - UINT16 m_div; - bool m_1s; bool m_k_active; + bool m_halt; + + // lcd driver + optional_shared_ptr<UINT8> m_lcd_ram_a, m_lcd_ram_b, m_lcd_ram_c; + devcb_write16 m_write_sega, m_write_segb, m_write_segc; + emu_timer *m_lcd_timer; bool m_bp; bool m_bc; - bool m_halt; - // i/o handlers + UINT16 get_lcd_row(int column, UINT8* ram); + TIMER_CALLBACK_MEMBER(lcd_timer_cb); + virtual void init_lcd_driver(); + + // clock divider + emu_timer *m_div_timer; + UINT16 m_div; + bool m_1s; + + TIMER_CALLBACK_MEMBER(div_timer_cb); + void wake_me_up(); + virtual void reset_divider(); + void init_divider(); + + // other i/o handlers devcb_read8 m_read_k; devcb_read_line m_read_ba; devcb_read_line m_read_b; @@ -134,9 +167,6 @@ protected: // misc internal helpers void increment_pc(); - TIMER_CALLBACK_MEMBER(div_timer_cb); - void wake_me_up(); - virtual void reset_divider(); virtual void get_opcode_param() { } // -> child class UINT8 ram_r(); diff --git a/src/emu/cpu/sm510/sm510core.c b/src/emu/cpu/sm510/sm510core.c index fe25e9abdbd..0ac9d7d3caf 100644 --- a/src/emu/cpu/sm510/sm510core.c +++ b/src/emu/cpu/sm510/sm510core.c @@ -24,7 +24,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(data_96_32x4, AS_DATA, 8, sm510_base_device) AM_RANGE(0x00, 0x5f) AM_RAM - AM_RANGE(0x60, 0x7f) AM_RAM AM_SHARE("lcd_ram") + AM_RANGE(0x60, 0x6f) AM_RAM AM_SHARE("lcd_ram_a") + AM_RANGE(0x70, 0x7f) AM_RAM AM_SHARE("lcd_ram_b") ADDRESS_MAP_END diff --git a/src/emu/cpu/sm510/sm511core.c b/src/emu/cpu/sm510/sm511core.c index 8905b4c3239..11f6808e5a4 100644 --- a/src/emu/cpu/sm510/sm511core.c +++ b/src/emu/cpu/sm510/sm511core.c @@ -22,12 +22,15 @@ ADDRESS_MAP_END static ADDRESS_MAP_START(data_96_32x4, AS_DATA, 8, sm510_base_device) AM_RANGE(0x00, 0x5f) AM_RAM - AM_RANGE(0x60, 0x7f) AM_RAM AM_SHARE("lcd_ram") + AM_RANGE(0x60, 0x6f) AM_RAM AM_SHARE("lcd_ram_a") + AM_RANGE(0x70, 0x7f) AM_RAM AM_SHARE("lcd_ram_b") ADDRESS_MAP_END static ADDRESS_MAP_START(data_80_48x4, AS_DATA, 8, sm510_base_device) AM_RANGE(0x00, 0x4f) AM_RAM - AM_RANGE(0x50, 0x7f) AM_RAM AM_SHARE("lcd_ram") + AM_RANGE(0x50, 0x5f) AM_RAM AM_SHARE("lcd_ram_c") + AM_RANGE(0x60, 0x6f) AM_RAM AM_SHARE("lcd_ram_a") + AM_RANGE(0x70, 0x7f) AM_RAM AM_SHARE("lcd_ram_b") ADDRESS_MAP_END |