trunk/src/mess/video/a7800.c
r22865 | r22866 | |
35 | 35 | |
36 | 36 | /********** Maria ***********/ |
37 | 37 | |
38 | | #define DPPH 0x2c |
39 | | #define DPPL 0x30 |
40 | | |
41 | 38 | /*************************************************************************** |
42 | 39 | |
43 | 40 | Start the video hardware emulation. |
r22865 | r22866 | |
125 | 122 | unsigned int graph_adr,data_addr; |
126 | 123 | int width,pal,ind; |
127 | 124 | UINT8 hpos; |
128 | | int xpos; |
129 | 125 | unsigned int dl; |
130 | | int x, d, c, i, j, pixel_cell, cells; |
| 126 | int x, d, c, i, pixel_cell, cells; |
131 | 127 | int maria_cycles; |
132 | 128 | |
133 | 129 | maria_cycles = 0; |
134 | 130 | cells = 0; |
135 | 131 | |
136 | | /* clear active line ram buffer */ |
137 | | for (i = 0; i < 160; i++) |
138 | | m_line_ram[m_active_buffer][i] = 0; |
139 | | |
140 | 132 | /* Process this DLL entry */ |
141 | 133 | dl = m_maria_dl; |
142 | 134 | |
r22865 | r22866 | |
168 | 160 | maria_cycles += 8; |
169 | 161 | } |
170 | 162 | |
171 | | /*logerror("%x DL: ADR=%x width=%x hpos=%x pal=%x mode=%x ind=%x\n",m_screen->vpos(),graph_adr,width,hpos,pal,mode,ind );*/ |
| 163 | /*logerror("%x DL: ADR=%x width=%x hpos=%x pal=%x mode=%x ind=%x\n",m_screen->vpos(),graph_adr,width,hpos,pal,m_maria_write_mode,ind );*/ |
172 | 164 | |
173 | 165 | for (x=0; x<width; x++) |
174 | 166 | { |
r22865 | r22866 | |
176 | 168 | if (ind) |
177 | 169 | { |
178 | 170 | c = READ_MEM(graph_adr + x) & 0xFF; |
179 | | maria_cycles += 3; // 3 Maria cycles |
| 171 | maria_cycles += 3; |
180 | 172 | data_addr = (m_maria_charbase | c) + (m_maria_offset << 8); |
181 | 173 | if (is_holey(data_addr)) |
182 | 174 | continue; |
r22865 | r22866 | |
186 | 178 | hpos += cells; |
187 | 179 | cells = write_line_ram(data_addr+1, hpos, pal); |
188 | 180 | hpos += cells; |
| 181 | maria_cycles += 6; |
189 | 182 | } |
190 | 183 | else |
191 | 184 | { |
192 | 185 | cells = write_line_ram(data_addr, hpos, pal); |
193 | 186 | hpos += cells; |
| 187 | maria_cycles += 3; |
194 | 188 | } |
195 | 189 | } |
196 | 190 | else // direct mode |
r22865 | r22866 | |
200 | 194 | continue; |
201 | 195 | cells = write_line_ram(data_addr, hpos, pal); |
202 | 196 | hpos += cells; |
| 197 | maria_cycles += 3; |
203 | 198 | } |
204 | 199 | } |
205 | 200 | } |
206 | | |
207 | | /* render scanline */ |
| 201 | m_maincpu->eat_cycles(maria_cycles/4); // Maria clock rate is 4 times that of CPU |
| 202 | |
| 203 | // draw line buffer to screen |
208 | 204 | m_active_buffer = !m_active_buffer; // switch buffers |
209 | 205 | UINT16 *scanline; |
210 | 206 | scanline = &m_bitmap.pix16(m_screen->vpos()); |
211 | | for (i = 0; i < 320; i++) |
212 | | scanline[i] = m_maria_palette[0]; |
213 | 207 | |
214 | | xpos = 0; |
215 | | i=0; |
216 | 208 | |
217 | | while ( i<160 ) |
218 | | |
219 | | switch (m_maria_rm | m_maria_write_mode) |
| 209 | for ( i = 0; i<160; i++ ) |
| 210 | { |
| 211 | switch (m_maria_rm) |
220 | 212 | { |
221 | | case 0x00: /* 160A (160x2) */ |
222 | | case 0x01: /* 160A (160x2) */ |
223 | | for (j = 0; j<4; j++, xpos+=2) |
224 | | { |
225 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
226 | | scanline[xpos] = m_maria_palette[pixel_cell]; |
227 | | scanline[xpos+1] = m_maria_palette[pixel_cell]; |
228 | | } |
229 | | i += 4; |
| 213 | case 0x00: /* 160A, 160B */ |
| 214 | case 0x01: /* 160A, 160B */ |
| 215 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 216 | scanline[2*i] = m_maria_palette[pixel_cell]; |
| 217 | scanline[2*i+1] = m_maria_palette[pixel_cell]; |
230 | 218 | break; |
231 | 219 | |
232 | | case 0x02: /* 320D used by Jinks! */ |
233 | | for (j = 0; j<4; j++, xpos+=2) |
234 | | { |
235 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
236 | | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); |
237 | | scanline[xpos] = m_maria_palette[d]; |
238 | | |
239 | | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); |
240 | | scanline[xpos+1] = m_maria_palette[d]; |
241 | | } |
242 | | i += 4; |
| 220 | case 0x02: /* 320B, 320D */ |
| 221 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 222 | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); // b4 0 0 b1 b3 |
| 223 | scanline[2*i] = m_maria_palette[d]; |
| 224 | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); // b4 0 0 b0 b2 |
| 225 | scanline[2*i+1] = m_maria_palette[d]; |
243 | 226 | break; |
244 | 227 | |
245 | | case 0x03: /* MODE 320A */ |
246 | | for (j = 0; j<4; j++, xpos+=2) |
247 | | { |
248 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
249 | | d = (pixel_cell & 0x1C) | (pixel_cell & 0x02); |
250 | | scanline[xpos] = m_maria_palette[d]; |
251 | | |
252 | | d = (pixel_cell & 0x1C) | ((pixel_cell << 1) & 0x02); |
253 | | scanline[xpos+1] = m_maria_palette[d]; |
254 | | } |
255 | | i += 4; |
| 228 | case 0x03: /* 320A, 320C */ |
| 229 | pixel_cell = m_line_ram[m_active_buffer][i]; |
| 230 | d = (pixel_cell & 0x1C) | (pixel_cell & 0x02); // b4 b3 b2 b1 0 |
| 231 | scanline[2*i] = m_maria_palette[d]; |
| 232 | d = (pixel_cell & 0x1C) | ((pixel_cell << 1) & 0x02); // b4 b3 b2 b0 0 |
| 233 | scanline[2*i+1] = m_maria_palette[d]; |
256 | 234 | break; |
| 235 | } |
| 236 | } |
257 | 237 | |
258 | | case 0x04: /* 160B (160x4) */ |
259 | | case 0x05: /* 160B (160x4) */ |
260 | | for (j = 0; j<2; j++, xpos+=2) |
261 | | { |
262 | | d = m_line_ram[m_active_buffer][i+j]; |
263 | | scanline[xpos] = m_maria_palette[d]; |
264 | | scanline[xpos+1] = m_maria_palette[d]; |
265 | | } |
266 | | i += 2; |
267 | | break; |
268 | | |
269 | | case 0x06: /* MODE 320B */ |
270 | | for (j = 0; j<2; j++, xpos+=2) |
271 | | { |
272 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
273 | | |
274 | | d = (pixel_cell & 0x10) | (pixel_cell & 0x02) | ((pixel_cell >> 3) & 1); |
275 | | scanline[xpos] = m_maria_palette[d]; |
276 | | |
277 | | d = (pixel_cell & 0x10) | ((pixel_cell << 1) & 0x02) | ((pixel_cell >> 2) & 1); |
278 | | scanline[xpos+1] = m_maria_palette[d]; |
279 | | } |
280 | | i += 2; |
281 | | break; |
282 | | |
283 | | case 0x07: /* MODE 320C */ |
284 | | for (j = 0; j<2; j++, xpos+=2) |
285 | | { |
286 | | pixel_cell = m_line_ram[m_active_buffer][i+j]; |
287 | | |
288 | | d = pixel_cell & 0x1E; |
289 | | scanline[xpos] = m_maria_palette[d]; |
290 | | |
291 | | d = (pixel_cell & 0x1C) | ((pixel_cell & 0x01) << 1); |
292 | | scanline[xpos+1] = m_maria_palette[d]; |
293 | | } |
294 | | i += 2; |
295 | | break; |
296 | | |
297 | | } /* endswitch (mode) */ |
298 | | |
299 | | m_maincpu->adjust_icount(-maria_cycles/4); // Maria clock rate is 4 times that of CPU |
| 238 | for(i=0; i<160; i++) // buffer automaticaly cleared once displayed |
| 239 | m_line_ram[m_active_buffer][i] = 0; |
300 | 240 | } |
301 | 241 | |
302 | 242 | |
303 | 243 | |
304 | 244 | TIMER_DEVICE_CALLBACK_MEMBER(a7800_state::a7800_interrupt) |
305 | 245 | { |
| 246 | // DMA Begins 7 cycles after hblank |
306 | 247 | machine().scheduler().timer_set(m_maincpu->cycles_to_attotime(7), timer_expired_delegate(FUNC(a7800_state::a7800_maria_startdma),this)); |
307 | 248 | if( m_maria_wsync ) |
308 | 249 | { |
r22865 | r22866 | |
337 | 278 | m_maria_dl = (READ_MEM(m_maria_dll+1) << 8) | READ_MEM(m_maria_dll+2); |
338 | 279 | m_maria_offset = READ_MEM(m_maria_dll) & 0x0f; |
339 | 280 | m_maria_holey = (READ_MEM(m_maria_dll) & 0x60) >> 5; |
340 | | logerror("holey %d", m_maria_holey); |
341 | | if ( READ_MEM(m_maria_dll) & 0x80 ) |
342 | | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
343 | | m_maincpu->adjust_icount(-6); // 24 Maria cycles minimum (DMA startup + shutdown list-list fetch) |
| 281 | m_maria_nmi = READ_MEM(m_maria_dll) & 0x80; |
| 282 | m_maincpu->eat_cycles(6); // 24 Maria cycles minimum (DMA startup + shutdown list-list fetch) |
344 | 283 | /* logerror("DLL=%x\n",m_maria_dll); */ |
345 | | /* logerror("DLL: DL = %x dllctrl = %x\n",m_maria_dl,ROM[m_maria_dll]); */ |
346 | 284 | } |
347 | 285 | |
348 | 286 | |
r22865 | r22866 | |
356 | 294 | m_maria_dl = (READ_MEM(m_maria_dll+1) << 8) | READ_MEM(m_maria_dll+2); |
357 | 295 | m_maria_offset = READ_MEM(m_maria_dll) & 0x0f; |
358 | 296 | m_maria_holey = (READ_MEM(m_maria_dll) & 0x60) >> 5; |
359 | | logerror("holey %d", m_maria_holey); |
360 | | if ( READ_MEM(m_maria_dll) & 0x80 ) |
361 | | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
362 | | m_maincpu->adjust_icount(-5); // 20 Maria cycles (DMA startup + shutdown) |
| 297 | m_maincpu->eat_cycles(5); // 20 Maria cycles (DMA startup + shutdown) |
| 298 | if ( READ_MEM(m_maria_dll & 0x10) ) |
| 299 | logerror("dll bit 5 set!\n"); |
| 300 | m_maria_nmi = READ_MEM(m_maria_dll) & 0x80; |
363 | 301 | } |
364 | 302 | else |
365 | 303 | { |
366 | 304 | m_maria_offset--; |
367 | 305 | } |
368 | 306 | } |
| 307 | |
| 308 | if( m_maria_nmi ) |
| 309 | { |
| 310 | m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 311 | m_maria_nmi = 0; |
| 312 | } |
369 | 313 | } |
370 | 314 | |
371 | 315 | /*************************************************************************** |
r22865 | r22866 | |
406 | 350 | switch (offset) |
407 | 351 | { |
408 | 352 | case 0x00: |
409 | | // 0x04 etc. necessary for 320 modes (pixels with color of 00 should display as background color) |
| 353 | // all color ram addresses with 00 for their least significant bits point to the background color |
410 | 354 | for (i = 0; i<8; i++) |
411 | 355 | m_maria_palette[4*i] = data; |
412 | 356 | break; |