OSDN Git Service

[VM][UPD7810] Fix FTBFS.
[csp-qt/common_source_project-fm7.git] / source / src / vm / hd44102.cpp
1 /*
2         Skelton for retropc emulator
3
4         Origin : MAME
5         Author : Takeda.Toshiya
6         Date   : 2017.03.07-
7
8         [ HD44102 ]
9 */
10
11 #include "hd44102.h"
12
13 #define CONTROL_DISPLAY_OFF         0x38
14 #define CONTROL_DISPLAY_ON          0x39
15 #define CONTROL_COUNT_DOWN_MODE     0x3a
16 #define CONTROL_COUNT_UP_MODE       0x3b
17 #define CONTROL_Y_ADDRESS_MASK      0x3f
18 #define CONTROL_X_ADDRESS_MASK      0xc0
19 #define CONTROL_DISPLAY_START_PAGE  0x3e
20
21 #define STATUS_BUSY                 0x80    /* not supported */
22 #define STATUS_COUNT_UP             0x40
23 #define STATUS_DISPLAY_OFF          0x20
24 #define STATUS_RESET                0x10    /* not supported */
25
26 //**************************************************************************
27 //  INLINE HELPERS
28 //**************************************************************************
29
30 //-------------------------------------------------
31 //  count_up_or_down -
32 //-------------------------------------------------
33
34 inline void HD44102::count_up_or_down()
35 {
36         m_output = m_ram[m_x][m_y];
37         
38         if (m_status & STATUS_COUNT_UP)
39         {
40                 if (++m_y > 49) m_y = 0;
41         }
42         else
43         {
44                 if (--m_y < 0) m_y = 49;
45         }
46 }
47
48 //**************************************************************************
49 //  LIVE DEVICE
50 //**************************************************************************
51
52 //-------------------------------------------------
53 //  hd44102_device - constructor
54 //-------------------------------------------------
55
56 void HD44102::initialize()
57 {
58         DEVICE::initialize();
59         _SCREEN_WIDTH = osd->get_feature_int_value(_T("SCREEN_WIDTH"));
60         _SCREEN_HEIGHT = osd->get_feature_int_value(_T("SCREEN_HEIGHT"));
61 //      m_cs2 = 0;
62         m_page = 0;
63         m_x = 0;
64         m_y = 0;
65         memset(m_ram, 0, sizeof(m_ram));
66 }
67
68 //-------------------------------------------------
69 //  device_reset - device-specific reset
70 //-------------------------------------------------
71
72 void HD44102::reset()
73 {
74         m_status = STATUS_DISPLAY_OFF | STATUS_COUNT_UP;
75 }
76
77 //-------------------------------------------------
78 //  read - register read
79 //-------------------------------------------------
80
81 uint8_t HD44102::read(uint32_t offset)
82 {
83         uint8_t data = 0;
84
85 //      if (m_cs2)
86         {
87                 data = (offset & 0x01) ? data_r() : status_r();
88         }
89
90         return data;
91 }
92
93 //-------------------------------------------------
94 //  write - register write
95 //-------------------------------------------------
96
97 void HD44102::write(uint32_t offset, uint8_t data)
98 {
99 //      if (m_cs2)
100         {
101                 (offset & 0x01) ? data_w(data) : control_w(data);
102         }
103 }
104
105 //-------------------------------------------------
106 //  status_r - status read
107 //-------------------------------------------------
108
109 uint8_t HD44102::status_r()
110 {
111         return m_status;
112 }
113
114 //-------------------------------------------------
115 //  control_w - control write
116 //-------------------------------------------------
117
118 void HD44102::control_w(uint8_t data)
119 {
120         if (m_status & STATUS_BUSY) return;
121
122         switch (data)
123         {
124         case CONTROL_DISPLAY_OFF:
125 //              if (LOG) logerror("HD44102 '%s' Display Off\n", tag());
126
127                 m_status |= STATUS_DISPLAY_OFF;
128                 break;
129
130         case CONTROL_DISPLAY_ON:
131 //              if (LOG) logerror("HD44102 '%s' Display On\n", tag());
132
133                 m_status &= ~STATUS_DISPLAY_OFF;
134                 break;
135
136         case CONTROL_COUNT_DOWN_MODE:
137 //              if (LOG) logerror("HD44102 '%s' Count Down Mode\n", tag());
138
139                 m_status &= ~STATUS_COUNT_UP;
140                 break;
141
142         case CONTROL_COUNT_UP_MODE:
143 //              if (LOG) logerror("HD44102 '%s' Count Up Mode\n", tag());
144
145                 m_status |= STATUS_COUNT_UP;
146                 break;
147
148         default:
149                 {
150                 int x = (data & CONTROL_X_ADDRESS_MASK) >> 6;
151                 int y = data & CONTROL_Y_ADDRESS_MASK;
152
153                 if ((data & CONTROL_Y_ADDRESS_MASK) == CONTROL_DISPLAY_START_PAGE)
154                 {
155 //                      if (LOG) logerror("HD44102 '%s' Display Start Page %u\n", tag(), x);
156
157                         m_page = x;
158                 }
159                 else if (y > 49)
160                 {
161 //                      logerror("HD44102 '%s' Invalid Address X %u Y %u (%02x)!\n", tag(), data, x, y);
162                 }
163                 else
164                 {
165 //                      if (LOG) logerror("HD44102 '%s' Address X %u Y %u (%02x)\n", tag(), data, x, y);
166
167                         m_x = x;
168                         m_y = y;
169                 }
170                 }
171         }
172 }
173
174 //-------------------------------------------------
175 //  data_r - data read
176 //-------------------------------------------------
177
178 uint8_t HD44102::data_r()
179 {
180         uint8_t data = m_output;
181
182 //      m_output = m_ram[m_x][m_y];
183
184         count_up_or_down();
185
186         return data;
187 }
188
189 //-------------------------------------------------
190 //  data_w - data write
191 //-------------------------------------------------
192
193 void HD44102::data_w(uint8_t data)
194 {
195         m_ram[m_x][m_y] = data;
196
197         count_up_or_down();
198 }
199
200 //-------------------------------------------------
201 //  cs2_w - chip select 2 write
202 //-------------------------------------------------
203
204 //void HD44102::write_signal(int id, uint32_t data, uint32_t mask)
205 //{
206 //      if(id == SIG_HD44102_CS2) {
207 //              m_cs2 = data & mask;
208 //      }
209 //}
210
211 //-------------------------------------------------
212 //  update_screen - update screen
213 //-------------------------------------------------
214
215 void HD44102::screen_update(int m_sx, int m_sy, bool reverse)
216 {
217         scrntype_t color_on   = RGB_COLOR( 48,  56,  16);       // dot on
218 //      scrntype_t color_off  = RGB_COLOR(144, 150, 144);       // dot off
219         scrntype_t color_back = RGB_COLOR(160, 168, 160);       // back
220         
221         for (int x = 0; x < 50; x++)
222         {
223                 for (int y = 0; y < 4; y++)
224                 {
225                         int sy = (m_page + y) % 4;
226                         int sx = reverse ? (49 - x) : x;
227                         
228                         uint8_t data = m_ram[sy][x];
229                         
230                         for (int b = 0; b < 8; b++)
231                         {
232                                 int dy = m_sy + 8 * sy + b;
233                                 int dx = m_sx + sx;
234                                 
235                                 if(dx >= 0 && dx < _SCREEN_WIDTH && dy >= 0 && dy < _SCREEN_HEIGHT) {
236                                         int color = (m_status & STATUS_DISPLAY_OFF) ? 0 : ((data >> b) & 0x01);
237                                         //scrntype_t *dest = emu->get_screen_buffer(m_sy + sy * 8 + b) + (m_sx + sx);
238                                         scrntype_t *dest = osd->get_vm_screen_buffer(m_sy + sy * 8 + b) + (m_sx + sx);
239                                         *dest = color ? color_on : color_back;
240                                 }
241                         }
242                 }
243         }
244 }
245
246 #define STATE_VERSION   1
247
248 bool HD44102::process_state(FILEIO* state_fio, bool loading)
249 {
250         if(!state_fio->StateCheckUint32(STATE_VERSION)) {
251                 return false;
252         }
253         if(!state_fio->StateCheckInt32(this_device_id)) {
254                 return false;
255         }
256         state_fio->StateBuffer(m_ram, sizeof(m_ram), 1);
257         state_fio->StateUint8(m_status);
258         state_fio->StateUint8(m_output);
259 //      state_fio->StateInt32(m_cs2);
260         state_fio->StateInt32(m_page);
261         state_fio->StateInt32(m_x);
262         state_fio->StateInt32(m_y);
263         return true;
264 }