diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/emu/emu.mak | 1 | ||||
-rw-r--r-- | src/emu/video/msm6255.c | 452 | ||||
-rw-r--r-- | src/emu/video/msm6255.h | 134 |
3 files changed, 587 insertions, 0 deletions
diff --git a/src/emu/emu.mak b/src/emu/emu.mak index 539b3314a74..cbad586196b 100644 --- a/src/emu/emu.mak +++ b/src/emu/emu.mak @@ -234,6 +234,7 @@ EMUVIDEOOBJS = \ $(EMUVIDEO)/hd61830.o \ $(EMUVIDEO)/hd63484.o \ $(EMUVIDEO)/mc6845.o \ + $(EMUVIDEO)/msm6255.o \ $(EMUVIDEO)/pc_vga.o \ $(EMUVIDEO)/pc_video.o \ $(EMUVIDEO)/poly.o \ diff --git a/src/emu/video/msm6255.c b/src/emu/video/msm6255.c new file mode 100644 index 00000000000..9b0b078a7c3 --- /dev/null +++ b/src/emu/video/msm6255.c @@ -0,0 +1,452 @@ +/********************************************************************** + + OKI MSM6255 Dot Matrix LCD Controller implementation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#include "emu.h" +#include "msm6255.h" +#include "machine/devhelpr.h" + + + +//************************************************************************** +// MACROS / CONSTANTS +//************************************************************************** + +#define LOG 0 + + +// registers +enum +{ + REGISTER_MOR = 0, + REGISTER_PR, + REGISTER_HNR, + REGISTER_DVR, + REGISTER_CPR, + REGISTER_SLR, + REGISTER_SUR, + REGISTER_CLR, + REGISTER_CUR +}; + + +#define MOR_GRAPHICS 0x01 +#define MOR_4_BIT_PARALLEL 0x02 +#define MOR_2_BIT_PARALLEL 0x04 +#define MOR_DISPLAY_ON 0x08 +#define MOR_CURSOR_BLINK 0x10 +#define MOR_CURSOR_ON 0x20 +#define MOR_BLINK_TIME_16 0x40 + + +#define PR_HP_4 0x03 +#define PR_HP_5 0x04 +#define PR_HP_6 0x05 +#define PR_HP_7 0x06 +#define PR_HP_8 0x07 +#define PR_HP_MASK 0x07 +#define PR_VP_MASK 0xf0 + + +#define HNR_HN_MASK 0x7f + + +#define DVR_DN_MASK 0x7f + + +#define CPR_CPD_MASK 0x0f +#define CPR_CPU_MASK 0xf0 + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +// devices +const device_type MSM6255 = msm6255_device_config::static_alloc_device_config; + + + +//************************************************************************** +// DEVICE CONFIGURATION +//************************************************************************** + +GENERIC_DEVICE_CONFIG_SETUP(msm6255, "MSM6255") + + +//------------------------------------------------- +// device_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void msm6255_device_config::device_config_complete() +{ + // inherit a copy of the static data + const msm6255_interface *intf = reinterpret_cast<const msm6255_interface *>(static_config()); + if (intf != NULL) + { + *static_cast<msm6255_interface *>(this) = *intf; + + m_char_ram_r = intf->m_char_ram_r; + } + // or initialize to defaults if none provided + else + { + fatalerror("Interface not specified!"); + } +} + + + +//************************************************************************** +// INLINE HELPERS +//************************************************************************** + +//------------------------------------------------- +// read_video_data - read video ROM/RAM +//------------------------------------------------- + +inline UINT8 msm6255_device::read_video_data(UINT16 ma, UINT8 ra) +{ + return m_config.m_char_ram_r(this, ma, ra); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// msm6255_device - constructor +//------------------------------------------------- + +msm6255_device::msm6255_device(running_machine &_machine, const msm6255_device_config &config) + : device_t(_machine, config), + m_cursor(0), + m_config(config) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void msm6255_device::device_start() +{ + // find screen + m_screen = machine->device<screen_device>(m_config.m_screen_tag); + + // register for state saving + save_item(NAME(m_ir)); + save_item(NAME(m_mor)); + save_item(NAME(m_pr)); + save_item(NAME(m_hnr)); + save_item(NAME(m_dvr)); + save_item(NAME(m_cpr)); + save_item(NAME(m_slr)); + save_item(NAME(m_sur)); + save_item(NAME(m_clr)); + save_item(NAME(m_cur)); + save_item(NAME(m_cursor)); + save_item(NAME(m_frame)); +} + + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void msm6255_device::device_reset() +{ + m_frame = 0; +} + + +//------------------------------------------------- +// read - register read +//------------------------------------------------- + +READ8_MEMBER( msm6255_device::read ) +{ + UINT8 data = 0; + + if (offset & 0x01) + { + return m_ir; + } + else + { + switch (m_ir) + { + case REGISTER_MOR: + break; // write-only + + case REGISTER_PR: + data = m_pr; + break; + + case REGISTER_HNR: + data = m_hnr; + break; + + case REGISTER_DVR: + break; // write-only + + case REGISTER_CPR: + data = m_cpr; + break; + + case REGISTER_SLR: + data = m_slr; + break; + + case REGISTER_SUR: + data = m_sur; + break; + + case REGISTER_CLR: + data = m_clr; + break; + + case REGISTER_CUR: + data = m_cur; + break; + } + } + + return data; +} + + +//------------------------------------------------- +// write - register write +//------------------------------------------------- + +WRITE8_MEMBER( msm6255_device::write ) +{ + if (offset & 0x01) + { + m_ir = data & 0x0f; + } + else + { + switch (m_ir) + { + case REGISTER_MOR: + m_mor = data & 0x7f; + break; + + case REGISTER_PR: + m_pr = data & 0xf7; + break; + + case REGISTER_HNR: + m_hnr = data & 0x7f; + break; + + case REGISTER_DVR: + m_dvr = data; + break; + + case REGISTER_CPR: + m_cpr = data; + break; + + case REGISTER_SLR: + m_slr = data; + break; + + case REGISTER_SUR: + m_sur = data; + break; + + case REGISTER_CLR: + m_clr = data; + break; + + case REGISTER_CUR: + m_cur = data; + break; + } + } +} + + +//------------------------------------------------- +// update_cursor - +//------------------------------------------------- + +void msm6255_device::update_cursor() +{ + if (m_mor & MOR_CURSOR_ON) + { + if (m_mor & MOR_CURSOR_BLINK) + { + if (m_mor & MOR_BLINK_TIME_16) + { + if (m_frame == 16) + { + m_cursor = !m_cursor; + m_frame = 0; + } + else + { + m_frame++; + } + } + else + { + if (m_frame == 32) + { + m_cursor = !m_cursor; + m_frame = 0; + } + else + { + m_frame++; + } + } + } + else + { + m_cursor = 1; + } + } + else + { + m_cursor = 0; + } +} + + +//------------------------------------------------- +// draw_scanline - +//------------------------------------------------- + +void msm6255_device::draw_scanline(bitmap_t *bitmap, const rectangle *cliprect, int y, UINT16 ma, UINT8 ra) +{ + UINT8 hp = (m_pr & PR_HP_MASK) + 1; + UINT8 hn = (m_hnr & HNR_HN_MASK) + 1; + UINT8 cpu = m_cpr & CPR_CPU_MASK; + UINT8 cpd = m_cpr & CPR_CPD_MASK; + UINT16 car = (m_cur << 8) | m_clr; + + int sx, x; + + for (sx = 0; sx < hn; sx++) + { + UINT8 data = read_video_data(ma, ra); + + if (m_cursor) + { + if (ma == car) + { + if (ra >= cpu && ra <= cpd) + { + data ^= 0xff; + } + } + } + + for (x = 0; x < hp; x++) + { + *BITMAP_ADDR16(bitmap, y, (sx * hp) + x) = BIT(data, 7); + + data <<= 1; + } + + ma++; + } +} + + +//------------------------------------------------- +// update_graphics - +//------------------------------------------------- + +void msm6255_device::update_graphics(bitmap_t *bitmap, const rectangle *cliprect) +{ + UINT8 hn = (m_hnr & HNR_HN_MASK) + 1; + UINT8 nx = (m_dvr & DVR_DN_MASK) + 1; + UINT16 sar = (m_sur << 8) | m_slr; + + int y; + + m_cursor = 0; + m_frame = 0; + + for (y = 0; y < nx; y++) + { + // draw upper half scanline + UINT16 ma = sar + (y * hn); + draw_scanline(bitmap, cliprect, y, ma, 0); + + // draw lower half scanline + ma = sar + ((y + nx) * hn); + draw_scanline(bitmap, cliprect, y + nx, ma, 0); + } +} + + +//------------------------------------------------- +// update_text - +//------------------------------------------------- + +void msm6255_device::update_text(bitmap_t *bitmap, const rectangle *cliprect) +{ + UINT8 hn = (m_hnr & HNR_HN_MASK) + 1; + UINT8 vp = (m_pr & PR_VP_MASK) + 1; + UINT8 nx = (m_dvr & DVR_DN_MASK) + 1; + UINT16 sar = (m_sur << 8) | m_slr; + + int sy, y; + + update_cursor(); + + for (sy = 0; sy < nx; sy++) + { + for (y = 0; y < vp; y++) + { + // draw upper half scanline + UINT16 ma = sar + ((sy * vp) + y) * hn; + draw_scanline(bitmap, cliprect, (sy * vp) + y, ma, y); + + // draw lower half scanline + ma = sar + (((sy + nx) * vp) + y) * hn; + draw_scanline(bitmap, cliprect, (sy * vp) + y, ma, y); + } + } +} + + +//------------------------------------------------- +// update_screen - update screen +//------------------------------------------------- + +void msm6255_device::update_screen(bitmap_t *bitmap, const rectangle *cliprect) +{ + if (m_mor & MOR_DISPLAY_ON) + { + if (m_mor & MOR_GRAPHICS) + { + update_graphics(bitmap, cliprect); + } + else + { + update_text(bitmap, cliprect); + } + } + else + { + bitmap_fill(bitmap, cliprect, get_black_pen(machine)); + } +} diff --git a/src/emu/video/msm6255.h b/src/emu/video/msm6255.h new file mode 100644 index 00000000000..074acec56a5 --- /dev/null +++ b/src/emu/video/msm6255.h @@ -0,0 +1,134 @@ +/********************************************************************** + + OKI MSM6255 Dot Matrix LCD Controller implementation + + Copyright MESS Team. + Visit http://mamedev.org for licensing and usage restrictions. + +**********************************************************************/ + +#pragma once + +#ifndef __MSM6255__ +#define __MSM6255__ + +#include "emu.h" + + + +///************************************************************************* +// INTERFACE CONFIGURATION MACROS +///************************************************************************* + +#define MCFG_MSM6255_ADD(_tag, _clock, _config) \ + MCFG_DEVICE_ADD(_tag, MSM6255, _clock) \ + MCFG_DEVICE_CONFIG(_config) + + +#define MSM6255_INTERFACE(name) \ + const msm6255_interface (name) = + + +#define MSM6255_CHAR_RAM_READ(_name) \ + UINT8 _name(device_t *device, UINT16 ma, UINT8 ra) + + + +///************************************************************************* +// TYPE DEFINITIONS +///************************************************************************* + +// ======================> msm6255_char_ram_read_func + +typedef UINT8 (*msm6255_char_ram_read_func)(device_t *device, UINT16 ma, UINT8 ra); + + +// ======================> msm6255_interface + +struct msm6255_interface +{ + const char *m_screen_tag; + + int m_character_clock; + + // ROM/RAM data read function + msm6255_char_ram_read_func m_char_ram_r; +}; + + +// ======================> msm6255_device_config + +class msm6255_device_config : public device_config, + public msm6255_interface +{ + friend class msm6255_device; + + // construction/destruction + msm6255_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + +public: + // allocators + static device_config *static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock); + virtual device_t *alloc_device(running_machine &machine) const; + +protected: + // device_config overrides + virtual void device_config_complete(); + + msm6255_char_ram_read_func m_char_ram_r; +}; + + +// ======================> msm6255_device + +class msm6255_device : public device_t +{ + friend class msm6255_device_config; + + // construction/destruction + msm6255_device(running_machine &_machine, const msm6255_device_config &_config); + +public: + DECLARE_READ8_MEMBER( read ); + DECLARE_WRITE8_MEMBER( write ); + + void update_screen(bitmap_t *bitmap, const rectangle *cliprect); + +protected: + // device-level overrides + virtual void device_start(); + virtual void device_reset(); + +private: + inline UINT8 read_video_data(UINT16 ma, UINT8 ra); + void update_cursor(); + void draw_scanline(bitmap_t *bitmap, const rectangle *cliprect, int y, UINT16 ma, UINT8 ra); + void update_graphics(bitmap_t *bitmap, const rectangle *cliprect); + void update_text(bitmap_t *bitmap, const rectangle *cliprect); + + screen_device *m_screen; + + UINT8 m_ir; // instruction register + UINT8 m_mor; // mode control register + UINT8 m_pr; // character pitch register + UINT8 m_hnr; // horizontal character number register + UINT8 m_dvr; // duty number register + UINT8 m_cpr; // cursor form register + UINT8 m_slr; // start address (lower) register + UINT8 m_sur; // start address (upper) register + UINT8 m_clr; // cursor address (lower) register + UINT8 m_cur; // cursor address (upper) register + + int m_cursor; // is cursor displayed + int m_frame; // frame counter + + const msm6255_device_config &m_config; +}; + + +// device type definition +extern const device_type MSM6255; + + + +#endif |