mirror of
https://github.com/holub/mame
synced 2025-06-24 13:26:36 +03:00
hlcd0515: couple of accuracy improvements (nw)
This commit is contained in:
parent
194460c362
commit
5830838f26
@ -3,10 +3,12 @@
|
||||
/*
|
||||
|
||||
Hughes HLCD 0515/0569 LCD Driver
|
||||
|
||||
0515: 25 columns(also size of buffer/ram)
|
||||
0569: 24 columns, no DATA OUT pin, display blank has no effect
|
||||
|
||||
TODO:
|
||||
- What's the difference between 0515 and 0569? For now assume 0569 is a cost-reduced chip,
|
||||
lacking the data out pin.
|
||||
- read mode is untested
|
||||
- MAME bitmap update callback when needed
|
||||
|
||||
*/
|
||||
@ -21,20 +23,19 @@ const device_type HLCD0569 = &device_creator<hlcd0569_device>;
|
||||
// constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
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__),
|
||||
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, u8 colmax, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_colmax(colmax), 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)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_write_cols(*this), m_write_data(*this)
|
||||
hlcd0515_device::hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: hlcd0515_device(mconfig, HLCD0515, "HLCD 0515 LCD Driver", tag, owner, clock, 25, "hlcd0515", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
hlcd0569_device::hlcd0569_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: hlcd0515_device(mconfig, HLCD0569, "HLCD 0569 LCD Driver", tag, owner, clock, "hlcd0569", __FILE__)
|
||||
: hlcd0515_device(mconfig, HLCD0569, "HLCD 0569 LCD Driver", tag, owner, clock, 24, "hlcd0569", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
@ -64,6 +65,7 @@ void hlcd0515_device::device_start()
|
||||
m_rowmax = 0;
|
||||
m_rowout = 0;
|
||||
m_rowsel = 0;
|
||||
m_buffer = 0;
|
||||
memset(m_ram, 0, sizeof(m_ram));
|
||||
|
||||
// register for savestates
|
||||
@ -76,6 +78,7 @@ void hlcd0515_device::device_start()
|
||||
save_item(NAME(m_rowmax));
|
||||
save_item(NAME(m_rowout));
|
||||
save_item(NAME(m_rowsel));
|
||||
save_item(NAME(m_buffer));
|
||||
save_item(NAME(m_ram));
|
||||
}
|
||||
|
||||
@ -101,7 +104,7 @@ void hlcd0515_device::device_timer(emu_timer &timer, device_timer_id id, int par
|
||||
m_rowout = 0;
|
||||
|
||||
// write to COL/ROW pins
|
||||
m_write_cols(m_rowout, m_blank ? m_ram[m_rowout] : 0, 0xffffffff);
|
||||
m_write_cols(m_rowout, m_blank ? 0 : m_ram[m_rowout], 0xffffffff);
|
||||
m_rowout++;
|
||||
}
|
||||
|
||||
@ -111,68 +114,92 @@ void hlcd0515_device::device_timer(emu_timer &timer, device_timer_id id, int par
|
||||
// handlers
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER(hlcd0515_device::write_cs)
|
||||
void hlcd0515_device::set_control()
|
||||
{
|
||||
state = (state) ? 1 : 0;
|
||||
// clock 0,1,2: row select
|
||||
m_rowsel = m_control >> 2 & 7;
|
||||
|
||||
// start serial sequence on falling edge
|
||||
if (!state && m_cs)
|
||||
// clock 3(,4): initialize
|
||||
if (m_control & 2)
|
||||
{
|
||||
m_count = 0;
|
||||
m_control = 0;
|
||||
m_rowmax = m_rowsel;
|
||||
m_blank = bool(~m_control & 1);
|
||||
}
|
||||
|
||||
m_cs = state;
|
||||
// clock 4: read/write mode
|
||||
if (m_control & 1)
|
||||
m_buffer = m_ram[m_rowsel];
|
||||
}
|
||||
|
||||
void hlcd0569_device::set_control()
|
||||
{
|
||||
hlcd0515_device::set_control();
|
||||
m_blank = false; // 0569 doesn't support display blanking
|
||||
}
|
||||
|
||||
|
||||
void hlcd0515_device::clock_data(int col)
|
||||
{
|
||||
if (m_control & 1)
|
||||
{
|
||||
if (col < m_colmax)
|
||||
m_buffer <<= 1;
|
||||
|
||||
m_write_data(m_buffer >> m_colmax & 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (col < m_colmax)
|
||||
m_buffer >>= 1;
|
||||
|
||||
// always write last column
|
||||
u32 mask = 1 << (m_colmax - 1);
|
||||
m_buffer = (m_buffer & ~mask) | (m_data ? mask : 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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_cs && !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);
|
||||
}
|
||||
}
|
||||
set_control();
|
||||
}
|
||||
|
||||
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++;
|
||||
clock_data(m_count - 5);
|
||||
|
||||
if (m_count < (m_colmax + 5))
|
||||
m_count++;
|
||||
}
|
||||
|
||||
m_clock = state;
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(hlcd0515_device::write_data)
|
||||
|
||||
WRITE_LINE_MEMBER(hlcd0515_device::write_cs)
|
||||
{
|
||||
m_data = (state) ? 1 : 0;
|
||||
state = (state) ? 1 : 0;
|
||||
|
||||
// finish serial sequence on rising edge
|
||||
if (state && !m_cs)
|
||||
{
|
||||
// transfer to ram
|
||||
if (~m_control & 1)
|
||||
m_ram[m_rowsel] = m_buffer;
|
||||
|
||||
m_count = 0;
|
||||
m_control = 0;
|
||||
m_buffer = 0;
|
||||
}
|
||||
|
||||
m_cs = state;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define MCFG_HLCD0515_WRITE_COLS_CB(_devcb) \
|
||||
hlcd0515_device::set_write_cols_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
// DATA OUT pin
|
||||
// DATA OUT pin, don't use on HLCD0569
|
||||
#define MCFG_HLCD0515_WRITE_DATA_CB(_devcb) \
|
||||
hlcd0515_device::set_write_data_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
@ -46,6 +46,8 @@
|
||||
COL11 19 | | 22 COL13
|
||||
GND 20 |___________| 21 COL12
|
||||
|
||||
HLCD 0569 doesn't have DATA OUT, instead it has what seems like OSC OUT on pin 34.
|
||||
|
||||
OSC is tied to a capacitor, the result frequency is 50000 * cap(in uF), eg. 0.01uF cap = 500Hz.
|
||||
Internally, this is divided by 2, and by number of rows to get display refresh frequency.
|
||||
*/
|
||||
@ -54,15 +56,15 @@ class hlcd0515_device : public device_t
|
||||
{
|
||||
public:
|
||||
hlcd0515_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
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, u8 colmax, const char *shortname, const char *source);
|
||||
|
||||
// static configuration helpers
|
||||
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_clock);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_data);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_cs);
|
||||
DECLARE_WRITE_LINE_MEMBER(write_data) { m_data = (state) ? 1 : 0; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -70,6 +72,11 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
virtual void set_control();
|
||||
void clock_data(int col);
|
||||
|
||||
u8 m_colmax; // number of column pins
|
||||
|
||||
int m_cs; // input pin state
|
||||
int m_clock; // "
|
||||
int m_data; // "
|
||||
@ -79,7 +86,8 @@ protected:
|
||||
u8 m_rowmax; // number of rows output by lcd (max 8)
|
||||
u8 m_rowout; // current row for lcd output
|
||||
u8 m_rowsel; // current row for data in/out
|
||||
u32 m_ram[8]; // 8x25bit ram
|
||||
u32 m_buffer; // data in/out shift register
|
||||
u32 m_ram[8]; // internal lcd ram, 8 rows
|
||||
|
||||
emu_timer *m_lcd_timer;
|
||||
|
||||
@ -93,6 +101,9 @@ class hlcd0569_device : public hlcd0515_device
|
||||
{
|
||||
public:
|
||||
hlcd0569_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
protected:
|
||||
virtual void set_control() override;
|
||||
};
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
@CP0904A TMS0970 1977, Milton Bradley Comp IV
|
||||
@MP0905B TMS0970 1977, Parker Brothers Codename Sector
|
||||
*MP0057 TMS1000 1978, APH Student Speech+ (same ROM contents as TSI Speech+?)
|
||||
*MP0154 TMS1000 1979, Fonas 2 Player Baseball
|
||||
@MP0158 TMS1000 1979, Entex Soccer (6003)
|
||||
@MP0163 TMS1000 1979, A-One LSI Match Number/LJN Electronic Concentration
|
||||
@MP0168 TMS1000 1979, Conic Multisport/Tandy Sports Arena (model 60-2158)
|
||||
@ -4823,7 +4824,6 @@ WRITE16_MEMBER(comp4_state::write_o)
|
||||
// O0: leds common
|
||||
// other bits: N/C
|
||||
m_o = data;
|
||||
display_matrix(11, 1, m_r, m_o);
|
||||
}
|
||||
|
||||
READ8_MEMBER(comp4_state::read_k)
|
||||
|
Loading…
Reference in New Issue
Block a user