hlcd0515: finished device (nw)

This commit is contained in:
hap 2017-01-21 05:23:55 +01:00
parent aea2c5e14a
commit 854d1e12be
3 changed files with 185 additions and 8 deletions

View File

@ -5,7 +5,9 @@
Hughes HLCD 0515/0569 LCD Driver Hughes HLCD 0515/0569 LCD Driver
TODO: TODO:
- x - What's the difference between 0515 and 0569? For now assume 0569 is a cost-reduced chip,
lacking the data out pin.
- MAME bitmap update callback when needed
*/ */
@ -20,12 +22,14 @@ const device_type HLCD0569 = &device_creator<hlcd0569_device>;
//------------------------------------------------- //-------------------------------------------------
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, HLCD0515, "HLCD 0515 LCD Driver", tag, owner, clock, "hlcd0515", __FILE__) : device_t(mconfig, HLCD0515, "HLCD 0515 LCD Driver", tag, owner, clock, "hlcd0515", __FILE__),
m_write_cols(*this), m_write_data(*this)
{ {
} }
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source) hlcd0515_device::hlcd0515_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source)
: device_t(mconfig, type, name, tag, owner, clock, shortname, source) : device_t(mconfig, type, name, tag, owner, clock, shortname, source),
m_write_cols(*this), m_write_data(*this)
{ {
} }
@ -43,15 +47,40 @@ hlcd0569_device::hlcd0569_device(const machine_config &mconfig, const char *tag,
void hlcd0515_device::device_start() void hlcd0515_device::device_start()
{ {
// resolve callbacks // resolve callbacks
m_write_cols.resolve_safe();
m_write_data.resolve_safe();
// timer
m_lcd_timer = timer_alloc();
m_lcd_timer->adjust(attotime::from_hz(clock() / 2), 0, attotime::from_hz(clock() / 2));
// zerofill // zerofill
m_cs = 0; m_cs = 0;
m_clock = 0;
m_data = 0;
m_count = 0;
m_control = 0;
m_blank = false;
m_rowmax = 0;
m_rowout = 0;
m_rowsel = 0;
memset(m_ram, 0, sizeof(m_ram));
// register for savestates // register for savestates
save_item(NAME(m_cs)); save_item(NAME(m_cs));
save_item(NAME(m_clock));
save_item(NAME(m_data));
save_item(NAME(m_count));
save_item(NAME(m_control));
save_item(NAME(m_blank));
save_item(NAME(m_rowmax));
save_item(NAME(m_rowout));
save_item(NAME(m_rowsel));
save_item(NAME(m_ram));
} }
//------------------------------------------------- //-------------------------------------------------
// device_reset - device-specific reset // device_reset - device-specific reset
//------------------------------------------------- //-------------------------------------------------
@ -62,6 +91,88 @@ void hlcd0515_device::device_reset()
//-------------------------------------------------
// device_timer - handler timer events
//-------------------------------------------------
void hlcd0515_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
if (m_rowout > m_rowmax)
m_rowout = 0;
// write to COL/ROW pins
m_write_cols(m_rowout, m_blank ? m_ram[m_rowout] : 0, 0xffffffff);
m_rowout++;
}
//------------------------------------------------- //-------------------------------------------------
// handlers // handlers
//------------------------------------------------- //-------------------------------------------------
WRITE_LINE_MEMBER(hlcd0515_device::write_cs)
{
state = (state) ? 1 : 0;
// start serial sequence on falling edge
if (!state && m_cs)
{
m_count = 0;
m_control = 0;
}
m_cs = state;
}
WRITE_LINE_MEMBER(hlcd0515_device::write_clock)
{
state = (state) ? 1 : 0;
// clock/shift data on falling edge
if (!m_cs && m_count < 30 && !state && m_clock)
{
if (m_count < 5)
{
// 5-bit mode/control
m_control = m_control << 1 | m_data;
if (m_count == 4)
{
// clock 0,1,2: row select
// clock 3: initialize
// clock 4: read/write
m_rowsel = m_control >> 2 & 7;
if (m_control & 2)
{
m_rowmax = m_rowsel;
m_blank = bool(m_control & 1);
}
}
}
else
{
if (m_control & 1)
{
// read data, output
m_write_data(m_ram[m_rowsel] >> (m_count - 5) & 1);
}
else
{
// write data
u32 mask = 1 << (m_count - 5);
m_ram[m_rowsel] = (m_ram[m_rowsel] & ~mask) | (m_data ? mask : 0);
}
}
m_count++;
}
m_clock = state;
}
WRITE_LINE_MEMBER(hlcd0515_device::write_data)
{
m_data = (state) ? 1 : 0;
}

View File

@ -12,6 +12,44 @@
#include "emu.h" #include "emu.h"
// COL/ROW pins (offset for ROW)
#define MCFG_HLCD0515_WRITE_COLS_CB(_devcb) \
hlcd0515_device::set_write_cols_callback(*device, DEVCB_##_devcb);
// DATA OUT pin
#define MCFG_HLCD0515_WRITE_DATA_CB(_devcb) \
hlcd0515_device::set_write_data_callback(*device, DEVCB_##_devcb);
// pinout reference
/*
____ ____
ROW0 1 |* \_/ | 40 VDD
ROW1 2 | | 39 OSC
ROW2 3 | | 38 CLOCK
ROW3 4 | | 37 DATA IN
ROW4 5 | | 36 _CS
ROW5 6 | | 35 DATA OUT
ROW6 7 | | 34 COL25
ROW7 8 | | 33 COL24
COL1 9 | | 32 COL23
COL2 10 | HLCD 0515 | 31 COL22
COL3 11 | | 30 COL21
COL4 12 | | 29 COL20
COL5 13 | | 28 COL19
COL6 14 | | 27 COL18
COL7 15 | | 26 COL17
COL8 16 | | 25 COL16
COL9 17 | | 24 COL15
COL10 18 | | 23 COL14
COL11 19 | | 22 COL13
GND 20 |___________| 21 COL12
OSC is tied to a capacitor, the result frequency is 50000 * cap(in uF),
eg. 0.01uF cap = 500Hz.
*/
class hlcd0515_device : public device_t class hlcd0515_device : public device_t
{ {
public: public:
@ -19,19 +57,35 @@ public:
hlcd0515_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source); hlcd0515_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
// static configuration helpers // static configuration helpers
//template<class _Object> static devcb_base &set_write_x_callback(device_t &device, _Object object) { return downcast<hlcd0515_device &>(device).m_write_x.set_callback(object); } template<class _Object> static devcb_base &set_write_cols_callback(device_t &device, _Object object) { return downcast<hlcd0515_device &>(device).m_write_cols.set_callback(object); }
template<class _Object> static devcb_base &set_write_data_callback(device_t &device, _Object object) { return downcast<hlcd0515_device &>(device).m_write_data.set_callback(object); }
//DECLARE_WRITE_LINE_MEMBER(write_cs); DECLARE_WRITE_LINE_MEMBER(write_cs);
DECLARE_WRITE_LINE_MEMBER(write_clock);
DECLARE_WRITE_LINE_MEMBER(write_data);
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
int m_cs; int m_cs;
int m_clock;
int m_data;
int m_count;
u8 m_control;
bool m_blank;
u8 m_rowmax;
u8 m_rowout;
u8 m_rowsel;
u32 m_ram[8];
emu_timer *m_lcd_timer;
// callbacks // callbacks
//devcb_write32 m_write_x; devcb_write32 m_write_cols;
devcb_write_line m_write_data;
}; };

View File

@ -4460,20 +4460,30 @@ class horseran_state : public hh_tms1k_state
{ {
public: public:
horseran_state(const machine_config &mconfig, device_type type, const char *tag) horseran_state(const machine_config &mconfig, device_type type, const char *tag)
: hh_tms1k_state(mconfig, type, tag) : hh_tms1k_state(mconfig, type, tag),
m_lcd(*this, "lcd")
{ } { }
required_device<hlcd0569_device> m_lcd;
DECLARE_WRITE32_MEMBER(lcd_output_w);
DECLARE_WRITE16_MEMBER(write_r); DECLARE_WRITE16_MEMBER(write_r);
DECLARE_READ8_MEMBER(read_k); DECLARE_READ8_MEMBER(read_k);
}; };
// handlers // handlers
WRITE32_MEMBER(horseran_state::lcd_output_w)
{
}
WRITE16_MEMBER(horseran_state::write_r) WRITE16_MEMBER(horseran_state::write_r)
{ {
// R0: HLCD0569 clock // R0: HLCD0569 clock
// R1: HLCD0569 data in // R1: HLCD0569 data in
// R2: HLCD0569 _CS // R2: HLCD0569 _CS
m_lcd->write_cs(data >> 2 & 1);
m_lcd->write_data(data >> 1 & 1);
m_lcd->write_clock(data & 1);
// R3-R10: input mux // R3-R10: input mux
m_inp_mux = data >> 3 & 0xff; m_inp_mux = data >> 3 & 0xff;
@ -4557,7 +4567,9 @@ static MACHINE_CONFIG_START( horseran, horseran_state )
MCFG_TMS1XXX_WRITE_R_CB(WRITE16(horseran_state, write_r)) MCFG_TMS1XXX_WRITE_R_CB(WRITE16(horseran_state, write_r))
/* video hardware */ /* video hardware */
MCFG_DEVICE_ADD("lcd", HLCD0569, 1115) // 223nf cap MCFG_DEVICE_ADD("lcd", HLCD0569, 1100) // C=0.022uf
MCFG_HLCD0515_WRITE_COLS_CB(WRITE32(horseran_state, lcd_output_w))
MCFG_DEFAULT_LAYOUT(layout_hh_tms1k_test)
//MCFG_DEFAULT_LAYOUT(layout_horseran) //MCFG_DEFAULT_LAYOUT(layout_horseran)
/* no sound! */ /* no sound! */