1 // license:BSD-3-Clause
2 // copyright-holders:Sandro Ronco
3 /***************************************************************************
4
5 SED1520 LCD controller
6
7 TODO:
8 - busy flag
9
10 ***************************************************************************/
11
12 #include "emu.h"
13 #include "video/sed1520.h"
14
15 #include "screen.h"
16
17
18 //**************************************************************************
19 // DEVICE DEFINITIONS
20 //**************************************************************************
21
22 DEFINE_DEVICE_TYPE(SED1520, sed1520_device, "sed1520", "Epson SED1520")
23
24
25 //**************************************************************************
26 // live device
27 //**************************************************************************
28
29 //-------------------------------------------------
30 // sed1520_device - constructor
31 //-------------------------------------------------
32
sed1520_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)33 sed1520_device::sed1520_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
34 device_t(mconfig, SED1520, tag, owner, clock), m_lcd_on(0), m_busy(0), m_page(0), m_column(0), m_old_column(0), m_start_line(0),
35 m_adc(0), m_static_drive(0), m_modify_write(false),
36 m_screen_update_cb(*this)
37 {
38 }
39
40
41 //-------------------------------------------------
42 // device_start - device-specific startup
43 //-------------------------------------------------
44
device_start()45 void sed1520_device::device_start()
46 {
47 m_screen_update_cb.resolve();
48
49 // state saving
50 save_item(NAME(m_lcd_on));
51 save_item(NAME(m_busy));
52 save_item(NAME(m_page));
53 save_item(NAME(m_column));
54 save_item(NAME(m_old_column));
55 save_item(NAME(m_start_line));
56 save_item(NAME(m_adc));
57 save_item(NAME(m_static_drive));
58 save_item(NAME(m_modify_write));
59 save_item(NAME(m_vram));
60 }
61
62 //-------------------------------------------------
63 // device_reset - device-specific reset
64 //-------------------------------------------------
65
device_reset()66 void sed1520_device::device_reset()
67 {
68 m_lcd_on = 0;
69 m_busy = 0;
70 m_page = 3;
71 m_column = 0;
72 m_old_column = 0;
73 m_start_line = 0;
74 m_adc = 1;
75 m_static_drive = 0;
76 m_modify_write = false;
77 memset(m_vram, 0x00, sizeof(m_vram));
78 }
79
80
81 //**************************************************************************
82 // device interface
83 //**************************************************************************
84
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)85 uint32_t sed1520_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
86 {
87 if (m_lcd_on)
88 {
89 if (!m_screen_update_cb.isnull())
90 m_screen_update_cb(bitmap, cliprect, m_vram, m_start_line, m_adc);
91 }
92 else if (m_static_drive)
93 return UPDATE_HAS_NOT_CHANGED;
94 else
95 bitmap.fill(0, cliprect);
96
97 return 0;
98 }
99
read(offs_t offset)100 uint8_t sed1520_device::read(offs_t offset)
101 {
102 if (offset & 0x01)
103 return data_read();
104 else
105 return status_read();
106 }
107
write(offs_t offset,uint8_t data)108 void sed1520_device::write(offs_t offset, uint8_t data)
109 {
110 if (offset & 0x01)
111 data_write(data);
112 else
113 control_write(data);
114 }
115
control_write(uint8_t data)116 void sed1520_device::control_write(uint8_t data)
117 {
118 if((data & 0xfe) == 0xae) // display on/off
119 m_lcd_on = data & 0x01;
120 else if((data & 0xe0) == 0xc0) // set start line
121 m_start_line = data & 0x1f;
122 else if((data & 0xfc) == 0xb8) // set page address
123 m_page = data & 0x03;
124 else if((data & 0x80) == 0x00) // set column address
125 m_column = data % 80;
126 else if((data & 0xfe) == 0xa0) // select ADC
127 m_adc = data & 0x01;
128 else if((data & 0xfe) == 0xa4) // static drive on/off
129 m_static_drive = data & 0x01;
130 else if((data & 0xfe) == 0xa8) // select duty
131 ;
132 else if(data == 0xe0) // read-modify-write on
133 {
134 m_modify_write = true;
135 m_old_column = m_column;
136 }
137 else if(data == 0xee) // read-modify-write off
138 {
139 m_modify_write = false;
140 m_column = m_old_column;
141 }
142 else if(data == 0xe2) // reset
143 {
144 m_start_line = m_column = 0;
145 m_page = 3;
146 }
147 else
148 logerror("%s: invalid SED1520 command: %x\n", tag(), data);
149 }
150
status_read()151 uint8_t sed1520_device::status_read()
152 {
153 uint8_t data = (m_busy << 7) | (m_adc << 6) | (m_lcd_on << 5);
154 return data;
155 }
156
data_write(uint8_t data)157 void sed1520_device::data_write(uint8_t data)
158 {
159 m_vram[(m_page * 80 + m_column) % sizeof(m_vram)] = data;
160 m_column = (m_column + 1) % 80;
161 }
162
data_read()163 uint8_t sed1520_device::data_read()
164 {
165 uint8_t data = m_vram[(m_page * 80 + m_column) % sizeof(m_vram)];
166 if (!m_modify_write)
167 m_column = (m_column + 1) % 80;
168 return data;
169 }
170