1 /***************************************************************************************
2 * Genesis Plus
3 * Video Display Processor (68k & Z80 CPU interface)
4 *
5 * Support for SG-1000 (TMS99xx & 315-5066), Master System (315-5124 & 315-5246), Game Gear & Mega Drive VDP
6 *
7 * Copyright (C) 1998-2003 Charles Mac Donald (original code)
8 * Copyright (C) 2007-2017 Eke-Eke (Genesis Plus GX)
9 *
10 * Redistribution and use of this code or any derivative works are permitted
11 * provided that the following conditions are met:
12 *
13 * - Redistributions may not be sold, nor may they be used in a commercial
14 * product or activity.
15 *
16 * - Redistributions that are modified from the original source must include the
17 * complete source code, including the source code for all components used by a
18 * binary built from the modified sources. However, as a special exception, the
19 * source code distributed need not include anything that is normally distributed
20 * (in either source or binary form) with the major components (compiler, kernel,
21 * and so on) of the operating system on which the executable runs, unless that
22 * component itself accompanies the executable.
23 *
24 * - Redistributions must reproduce the above copyright notice, this list of
25 * conditions and the following disclaimer in the documentation and/or other
26 * materials provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 ****************************************************************************************/
41
42 #include "shared.h"
43 #include "hvc.h"
44
45 extern int8 reset_do_not_clear_buffers;
46 static int8 do_not_invalidate_tile_cache;
47
48 static void vdp_set_all_vram(const uint8 *src);
49
50 /* Mark a pattern as modified */
51 #define MARK_BG_DIRTY(addr) \
52 { \
53 name = (addr >> 5) & 0x7FF; \
54 if (bg_name_dirty[name] == 0) \
55 { \
56 bg_name_list[bg_list_index++] = name; \
57 } \
58 bg_name_dirty[name] |= (1 << ((addr >> 2) & 7)); \
59 }
60
61 /* VDP context */
62 uint8 ALIGNED_(4) sat[0x400]; /* Internal copy of sprite attribute table */
63 uint8 ALIGNED_(4) vram[0x10000]; /* Video RAM (64K x 8-bit) */
64 uint8 ALIGNED_(4) cram[0x80]; /* On-chip color RAM (64 x 9-bit) */
65 uint8 ALIGNED_(4) vsram[0x80]; /* On-chip vertical scroll RAM (40 x 11-bit) */
66 uint8 reg[0x20]; /* Internal VDP registers (23 x 8-bit) */
67 uint8 hint_pending; /* 0= Line interrupt is pending */
68 uint8 vint_pending; /* 1= Frame interrupt is pending */
69 uint16 status; /* VDP status flags */
70 uint32 dma_length; /* DMA remaining length */
71
72 /* Global variables */
73 uint16 ntab; /* Name table A base address */
74 uint16 ntbb; /* Name table B base address */
75 uint16 ntwb; /* Name table W base address */
76 uint16 satb; /* Sprite attribute table base address */
77 uint16 hscb; /* Horizontal scroll table base address */
78 uint8 bg_name_dirty[0x800]; /* 1= This pattern is dirty */
79 uint16 bg_name_list[0x800]; /* List of modified pattern indices */
80 uint16 bg_list_index; /* # of modified patterns in list */
81 uint8 hscroll_mask; /* Horizontal Scrolling line mask */
82 uint8 playfield_shift; /* Width of planes A, B (in bits) */
83 uint8 playfield_col_mask; /* Playfield column mask */
84 uint16 playfield_row_mask; /* Playfield row mask */
85 uint16 vscroll; /* Latched vertical scroll value */
86 uint8 odd_frame; /* 1: odd field, 0: even field */
87 uint8 im2_flag; /* 1= Interlace mode 2 is being used */
88 uint8 interlaced; /* 1: Interlaced mode 1 or 2 */
89 uint8 vdp_pal; /* 1: PAL , 0: NTSC (default) */
90 uint8 h_counter; /* Horizontal counter */
91 uint16 v_counter; /* Vertical counter */
92 uint16 vc_max; /* Vertical counter overflow value */
93 uint16 lines_per_frame; /* PAL: 313 lines, NTSC: 262 lines */
94 uint16 max_sprite_pixels; /* Max. sprites pixels per line (parsing & rendering) */
95 int32 fifo_write_cnt; /* VDP FIFO write count */
96 uint32 fifo_slots; /* VDP FIFO access slot count */
97 uint32 hvc_latch; /* latched HV counter */
98 const uint8 *hctab; /* pointer to H Counter table */
99
100 /* Function pointers */
101 void (*vdp_68k_data_w)(unsigned int data);
102 void (*vdp_z80_data_w)(unsigned int data);
103 unsigned int (*vdp_68k_data_r)(void);
104 unsigned int (*vdp_z80_data_r)(void);
105
106 /* Function prototypes */
107 static void vdp_68k_data_w_m4(unsigned int data);
108 static void vdp_68k_data_w_m5(unsigned int data);
109 static unsigned int vdp_68k_data_r_m4(void);
110 static unsigned int vdp_68k_data_r_m5(void);
111 static void vdp_z80_data_w_m4(unsigned int data);
112 static void vdp_z80_data_w_m5(unsigned int data);
113 static unsigned int vdp_z80_data_r_m4(void);
114 static unsigned int vdp_z80_data_r_m5(void);
115 static void vdp_z80_data_w_ms(unsigned int data);
116 static void vdp_z80_data_w_gg(unsigned int data);
117 static void vdp_z80_data_w_sg(unsigned int data);
118 static void vdp_bus_w(unsigned int data);
119 static void vdp_fifo_update(unsigned int cycles);
120 static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles);
121 static void vdp_dma_68k_ext(unsigned int length);
122 static void vdp_dma_68k_ram(unsigned int length);
123 static void vdp_dma_68k_io(unsigned int length);
124 static void vdp_dma_copy(unsigned int length);
125 static void vdp_dma_fill(unsigned int length);
126
127 /* Tables that define the playfield layout */
128 static const uint8 hscroll_mask_table[] = { 0x00, 0x07, 0xF8, 0xFF };
129 static const uint8 shift_table[] = { 6, 7, 0, 8 };
130 static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F };
131 static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF };
132
133 static uint8 border; /* Border color index */
134 static uint8 pending; /* Pending write flag */
135 static uint8 code; /* Code register */
136 static uint8 dma_type; /* DMA mode */
137 static uint16 addr; /* Address register */
138 static uint16 addr_latch; /* Latched A15, A14 of address */
139 static uint16 sat_base_mask; /* Base bits of SAT */
140 static uint16 sat_addr_mask; /* Index bits of SAT */
141 static uint16 dma_src; /* DMA source address */
142 static uint32 dma_endCycles; /* 68k cycles to DMA end */
143 static int dmafill; /* DMA Fill pending flag */
144 static int cached_write; /* 2nd part of 32-bit CTRL port write (Genesis mode) or LSB of CRAM data (Game Gear mode) */
145 static uint16 fifo[4]; /* FIFO ring-buffer */
146 static int fifo_idx; /* FIFO write index */
147 static int fifo_byte_access; /* FIFO byte access flag */
148 static uint32 fifo_cycles; /* FIFO next access cycle */
149 static int *fifo_timing; /* FIFO slots timing table */
150
151 /* set Z80 or 68k interrupt lines */
152 static void (*set_irq_line)(unsigned int level);
153 static void (*set_irq_line_delay)(unsigned int level);
154
155 /* Vertical counter overflow values (see hvc.h) */
156 static const uint16 vc_table[4][2] =
157 {
158 /* NTSC, PAL */
159 {0xDA , 0xF2}, /* Mode 4 (192 lines) */
160 {0xEA , 0x102}, /* Mode 5 (224 lines) */
161 {0xDA , 0xF2}, /* Mode 4 (192 lines) */
162 {0x106, 0x10A} /* Mode 5 (240 lines) */
163 };
164
165 /* FIFO access slots timings */
166 static const int fifo_timing_h32[16+4] =
167 {
168 230, 510, 810, 970, 1130, 1450, 1610, 1770, 2090, 2250, 2410, 2730, 2890, 3050, 3350, 3370,
169 MCYCLES_PER_LINE + 230, MCYCLES_PER_LINE + 510, MCYCLES_PER_LINE + 810, MCYCLES_PER_LINE + 970,
170 };
171
172 static const int fifo_timing_h40[18+4] =
173 {
174 352, 820, 948, 1076, 1332, 1460, 1588, 1844, 1972, 2100, 2356, 2484, 2612, 2868, 2996, 3124, 3364, 3380,
175 MCYCLES_PER_LINE + 352, MCYCLES_PER_LINE + 820, MCYCLES_PER_LINE + 948, MCYCLES_PER_LINE + 1076,
176 };
177
178 /* DMA Timings (number of access slots per line) */
179 static const uint8 dma_timing[2][2] =
180 {
181 /* H32, H40 */
182 {16 , 18}, /* active display */
183 {166, 204} /* blank display */
184 };
185
186 /* DMA processing functions (set by VDP register 23 high nibble) */
187 static void (*const dma_func[16])(unsigned int length) =
188 {
189 /* 0x0-0x3 : DMA from 68k bus $000000-$7FFFFF (external area) */
190 vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,vdp_dma_68k_ext,
191
192 /* 0x4-0x7 : DMA from 68k bus $800000-$FFFFFF (internal RAM & I/O) */
193 vdp_dma_68k_ram, vdp_dma_68k_io,vdp_dma_68k_ram,vdp_dma_68k_ram,
194
195 /* 0x8-0xB : DMA Fill */
196 vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,vdp_dma_fill,
197
198 /* 0xC-0xF : DMA Copy */
199 vdp_dma_copy,vdp_dma_copy,vdp_dma_copy,vdp_dma_copy
200 };
201
202 /* BG rendering functions */
203 static void (*const render_bg_modes[16])(int line) =
204 {
205 render_bg_m0, /* Graphics I */
206 render_bg_m2, /* Graphics II */
207 render_bg_m4, /* Mode 4 */
208 render_bg_m4, /* Mode 4 */
209 render_bg_m3, /* Multicolor */
210 render_bg_m3x, /* Multicolor (Extended PG) */
211 render_bg_m4, /* Mode 4 */
212 render_bg_m4, /* Mode 4 */
213 render_bg_m1, /* Text */
214 render_bg_m1x, /* Text (Extended PG) */
215 render_bg_m4, /* Mode 4 */
216 render_bg_m4, /* Mode 4 */
217 render_bg_inv, /* Invalid (1+3) */
218 render_bg_inv, /* Invalid (1+2+3) */
219 render_bg_m4, /* Mode 4 */
220 render_bg_m4, /* Mode 4 */
221 };
222
223 /*--------------------------------------------------------------------------*/
224 /* Init, reset, context functions */
225 /*--------------------------------------------------------------------------*/
226
vdp_init(void)227 void vdp_init(void)
228 {
229 /* PAL/NTSC timings */
230 lines_per_frame = vdp_pal ? 313: 262;
231
232 /* CPU interrupt line(s)*/
233 if ((system_hw & SYSTEM_PBC) == SYSTEM_MD)
234 {
235 /* 68k cpu */
236 set_irq_line = m68k_set_irq;
237 set_irq_line_delay = m68k_set_irq_delay;
238 }
239 else
240 {
241 /* Z80 cpu */
242 set_irq_line = z80_set_irq_line;
243 set_irq_line_delay = z80_set_irq_line;
244 }
245 }
246
vdp_reset(void)247 void vdp_reset(void)
248 {
249 int i;
250 if (!reset_do_not_clear_buffers)
251 {
252 memset((char *)sat, 0, sizeof(sat));
253 memset((char *)vram, 0, sizeof(vram));
254 memset((char *)cram, 0, sizeof(cram));
255 memset((char *)vsram, 0, sizeof(vsram));
256 }
257 memset((char *)reg, 0, sizeof(reg));
258
259 addr = 0;
260 addr_latch = 0;
261 code = 0;
262 pending = 0;
263 border = 0;
264 hint_pending = 0;
265 vint_pending = 0;
266 dmafill = 0;
267 dma_src = 0;
268 dma_type = 0;
269 dma_length = 0;
270 dma_endCycles = 0;
271 odd_frame = 0;
272 im2_flag = 0;
273 interlaced = 0;
274 fifo_write_cnt = 0;
275 fifo_cycles = 0;
276 fifo_slots = 0;
277 fifo_idx = 0;
278 cached_write = -1;
279 fifo_byte_access = 1;
280
281 ntab = 0;
282 ntbb = 0;
283 ntwb = 0;
284 satb = 0;
285 hscb = 0;
286
287 vscroll = 0;
288
289 hscroll_mask = 0x00;
290 playfield_shift = 6;
291 playfield_col_mask = 0x0F;
292 playfield_row_mask = 0x0FF;
293 sat_base_mask = 0xFE00;
294 sat_addr_mask = 0x01FF;
295
296 /* reset pattern cache changes */
297 if (!reset_do_not_clear_buffers)
298 {
299 /* Loadstate clears these */
300 bg_list_index = 0;
301 memset((char *)bg_name_dirty, 0, sizeof(bg_name_dirty));
302 memset((char *)bg_name_list, 0, sizeof(bg_name_list));
303 }
304 /* default Window clipping */
305 window_clip(0,0);
306
307 /* reset VDP status (FIFO empty flag is set) */
308 if (system_hw & SYSTEM_MD)
309 {
310 status = vdp_pal | 0x200;
311 }
312 else
313 {
314 status = 0;
315 }
316
317 /* default display area */
318 bitmap.viewport.w = 256;
319 bitmap.viewport.h = 192;
320 bitmap.viewport.ow = 256;
321 bitmap.viewport.oh = 192;
322
323 /* default HVC */
324 hvc_latch = 0x10000;
325 hctab = cycle2hc32;
326 vc_max = vc_table[0][vdp_pal];
327 v_counter = bitmap.viewport.h;
328 h_counter = 0xff;
329
330 /* default sprite pixel width */
331 max_sprite_pixels = 256;
332
333 /* default FIFO access slots timings */
334 fifo_timing = (int *)fifo_timing_h32;
335
336 /* default overscan area */
337 if ((system_hw == SYSTEM_GG) && !config.gg_extra)
338 {
339 /* Display area reduced to 160x144 if overscan is disabled */
340 bitmap.viewport.x = (config.overscan & 2) ? 14 : -48;
341 bitmap.viewport.y = (config.overscan & 1) ? (24 * (vdp_pal + 1)) : -24;
342 }
343 else
344 {
345 bitmap.viewport.x = (config.overscan & 2) * 7;
346 bitmap.viewport.y = (config.overscan & 1) * 24 * (vdp_pal + 1);
347 }
348
349 /* default rendering mode */
350 update_bg_pattern_cache = update_bg_pattern_cache_m4;
351 if (system_hw < SYSTEM_MD)
352 {
353 /* Mode 0 */
354 render_bg = render_bg_m0;
355 render_obj = render_obj_tms;
356 parse_satb = parse_satb_tms;
357 }
358 else
359 {
360 /* Mode 4 */
361 render_bg = render_bg_m4;
362 render_obj = render_obj_m4;
363 parse_satb = parse_satb_m4;
364 }
365
366 /* default 68k bus interface (Mega Drive VDP only) */
367 vdp_68k_data_w = vdp_68k_data_w_m4;
368 vdp_68k_data_r = vdp_68k_data_r_m4;
369
370 /* default Z80 bus interface */
371 switch (system_hw)
372 {
373 case SYSTEM_SG:
374 case SYSTEM_SGII:
375 {
376 /* SG-1000 (TMS99xx) or SG-1000 II (315-5066) VDP */
377 vdp_z80_data_w = vdp_z80_data_w_sg;
378 vdp_z80_data_r = vdp_z80_data_r_m4;
379 break;
380 }
381
382 case SYSTEM_GG:
383 {
384 /* Game Gear VDP */
385 vdp_z80_data_w = vdp_z80_data_w_gg;
386 vdp_z80_data_r = vdp_z80_data_r_m4;
387 break;
388 }
389
390 case SYSTEM_MARKIII:
391 case SYSTEM_SMS:
392 case SYSTEM_SMS2:
393 case SYSTEM_GGMS:
394 {
395 /* Master System or Game Gear (in MS compatibility mode) VDP */
396 vdp_z80_data_w = vdp_z80_data_w_ms;
397 vdp_z80_data_r = vdp_z80_data_r_m4;
398 break;
399 }
400
401 default:
402 {
403 /* Mega Drive VDP (in MS compatibility mode) */
404 vdp_z80_data_w = vdp_z80_data_w_m4;
405 vdp_z80_data_r = vdp_z80_data_r_m4;
406 break;
407 }
408 }
409
410 /* H-INT is disabled on startup (verified on VA4 MD1 with 315-5313 VDP) */
411 reg[10] = 0xFF;
412
413 /* Master System specific */
414 if ((system_hw & SYSTEM_SMS) && (!(config.bios & 1) || !(system_bios & SYSTEM_SMS)))
415 {
416 /* force registers initialization (normally done by BOOT ROM on all Master System models) */
417 vdp_reg_w(0 , 0x36, 0);
418 vdp_reg_w(1 , 0x80, 0);
419 vdp_reg_w(2 , 0xFF, 0);
420 vdp_reg_w(3 , 0xFF, 0);
421 vdp_reg_w(4 , 0xFF, 0);
422 vdp_reg_w(5 , 0xFF, 0);
423 vdp_reg_w(6 , 0xFF, 0);
424
425 /* Mode 4 */
426 render_bg = render_bg_m4;
427 render_obj = render_obj_m4;
428 parse_satb = parse_satb_m4;
429 }
430
431 /* Mega Drive specific */
432 else if (((system_hw == SYSTEM_MD) || (system_hw == SYSTEM_MCD)) && (config.bios & 1) && !(system_bios & SYSTEM_MD))
433 {
434 /* force registers initialization (normally done by BOOT ROM, only on Mega Drive model with TMSS) */
435 vdp_reg_w(0 , 0x04, 0);
436 vdp_reg_w(1 , 0x04, 0);
437 vdp_reg_w(12, 0x81, 0);
438 vdp_reg_w(15, 0x02, 0);
439 }
440
441 /* reset color palette */
442 for(i = 0; i < 0x20; i ++)
443 {
444 color_update_m4(i, 0x00);
445 }
446 color_update_m4(0x40, 0x00);
447 }
448
vdp_context_save(uint8 * state)449 int vdp_context_save(uint8 *state)
450 {
451 int bufferptr = 0;
452
453 save_param(sat, sizeof(sat));
454 save_param(vram, sizeof(vram));
455 save_param(cram, sizeof(cram));
456 save_param(vsram, sizeof(vsram));
457 save_param(reg, sizeof(reg));
458 save_param(&addr, sizeof(addr));
459 save_param(&addr_latch, sizeof(addr_latch));
460 save_param(&code, sizeof(code));
461 save_param(&pending, sizeof(pending));
462 save_param(&status, sizeof(status));
463 save_param(&dmafill, sizeof(dmafill));
464 save_param(&fifo_idx, sizeof(fifo_idx));
465 save_param(&fifo, sizeof(fifo));
466 save_param(&h_counter, sizeof(h_counter));
467 save_param(&hint_pending, sizeof(hint_pending));
468 save_param(&vint_pending, sizeof(vint_pending));
469 save_param(&dma_length, sizeof(dma_length));
470 save_param(&dma_type, sizeof(dma_type));
471 save_param(&dma_src, sizeof(dma_src));
472 save_param(&cached_write, sizeof(cached_write));
473 return bufferptr;
474 }
475
vdp_context_load(uint8 * state)476 int vdp_context_load(uint8 *state)
477 {
478 int i, bufferptr = 0;
479 uint8 temp_reg[0x20];
480 /* Pointer to VRAM block within the savestate */
481 uint8 *state_vram_ptr;
482 /* Save number of dirty tiles before calls to register writes */
483 int bg_list_index_save = bg_list_index;
484 /* Prevent register write code from invalidating the tile cache */
485 do_not_invalidate_tile_cache = true;
486
487 load_param(sat, sizeof(sat));
488 state_vram_ptr = &state[bufferptr];
489 bufferptr += sizeof(vram);
490 load_param(cram, sizeof(cram));
491 load_param(vsram, sizeof(vsram));
492 load_param(temp_reg, sizeof(temp_reg));
493
494 /* restore VDP registers */
495 if (system_hw < SYSTEM_MD)
496 {
497 if (system_hw >= SYSTEM_MARKIII)
498 {
499 for (i=0;i<0x10;i++)
500 {
501 pending = 1;
502 addr_latch = temp_reg[i];
503 vdp_sms_ctrl_w(0x80 | i);
504 }
505 }
506 else
507 {
508 /* TMS-99xx registers are updated directly to prevent spurious 4K->16K VRAM switching */
509 for (i=0;i<0x08;i++)
510 {
511 reg[i] = temp_reg[i];
512 }
513
514 /* Rendering mode */
515 render_bg = render_bg_modes[((reg[0] & 0x02) | (reg[1] & 0x18)) >> 1];
516 }
517 }
518 else
519 {
520 for (i=0;i<0x20;i++)
521 {
522 vdp_reg_w(i, temp_reg[i], 0);
523 }
524 }
525
526 load_param(&addr, sizeof(addr));
527 load_param(&addr_latch, sizeof(addr_latch));
528 load_param(&code, sizeof(code));
529 load_param(&pending, sizeof(pending));
530 load_param(&status, sizeof(status));
531 load_param(&dmafill, sizeof(dmafill));
532 load_param(&fifo_idx, sizeof(fifo_idx));
533 load_param(&fifo, sizeof(fifo));
534 load_param(&h_counter, sizeof(h_counter));
535 load_param(&hint_pending, sizeof(hint_pending));
536 load_param(&vint_pending, sizeof(vint_pending));
537 load_param(&dma_length, sizeof(dma_length));
538 load_param(&dma_type, sizeof(dma_type));
539 load_param(&dma_src, sizeof(dma_src));
540 load_param(&cached_write, sizeof(cached_write));
541
542 /* restore FIFO byte access flag */
543 fifo_byte_access = ((code & 0x0F) < 0x03);
544
545 /* restore current NTSC/PAL mode */
546 if (system_hw & SYSTEM_MD)
547 {
548 status = (status & ~1) | vdp_pal;
549 }
550
551 if (reg[1] & 0x04)
552 {
553 /* Mode 5 */
554 bg_list_index = 0x800;
555
556 /* reinitialize palette */
557 color_update_m5(0, *(uint16 *)&cram[border << 1]);
558 for(i = 1; i < 0x40; i++)
559 {
560 color_update_m5(i, *(uint16 *)&cram[i << 1]);
561 }
562 }
563 else
564 {
565 /* Modes 0,1,2,3,4 */
566 bg_list_index = 0x200;
567
568 /* reinitialize palette */
569 for(i = 0; i < 0x20; i ++)
570 {
571 color_update_m4(i, *(uint16 *)&cram[i << 1]);
572 }
573 color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]);
574 }
575
576 /* If we have a tile cache with any clean tiles */
577 if (bg_list_index_save != bg_list_index)
578 {
579 /* Restore index value */
580 bg_list_index = bg_list_index_save;
581 /* Copy all VRAM and update dirty tile flags */
582 vdp_set_all_vram(state_vram_ptr);
583 }
584 else
585 {
586 /* Copy all vram */
587 memcpy(vram, state_vram_ptr, sizeof(vram));
588 /* invalidate the tile cache */
589 for (i = 0; i < bg_list_index; i++)
590 {
591 bg_name_list[i] = i;
592 bg_name_dirty[i] = 0xFF;
593 }
594 }
595
596 do_not_invalidate_tile_cache = false;
597
598 return bufferptr;
599 }
600
601
602 /*--------------------------------------------------------------------------*/
603 /* DMA update function (Mega Drive VDP only) */
604 /*--------------------------------------------------------------------------*/
605
vdp_dma_update(unsigned int cycles)606 void vdp_dma_update(unsigned int cycles)
607 {
608 unsigned int dma_cycles, dma_bytes;
609
610 /* DMA transfer rate (bytes per line)
611
612 DMA Mode Width Display Transfer Count
613 -----------------------------------------------------
614 68K > VDP 32-cell Active 16
615 Blanking 166
616 40-cell Active 18
617 Blanking 204
618 VRAM Fill 32-cell Active 15
619 Blanking 165
620 40-cell Active 17
621 Blanking 203
622 VRAM Copy 32-cell Active 8
623 Blanking 83
624 40-cell Active 9
625 Blanking 102
626
627 'Active' is the active display period, 'Blanking' is either the vertical
628 blanking period or when the display is forcibly blanked via register #1.
629
630 The above transfer counts are all in bytes, unless the destination is
631 CRAM or VSRAM for a 68K > VDP transfer, in which case it is in words.
632 */
633 unsigned int rate = dma_timing[(status & 8) || !(reg[1] & 0x40)][reg[12] & 1];
634
635 /* Adjust for 68k bus DMA to VRAM (one word = 2 access) or DMA Copy (one read + one write = 2 access) */
636 rate = rate >> (dma_type & 1);
637
638 /* Remaining DMA cycles */
639 if (status & 8)
640 {
641 /* Process DMA until the end of VBLANK */
642 /* NOTE: DMA timings can not change during VBLANK because active display width cannot be modified. */
643 /* Indeed, writing VDP registers during DMA is either impossible (when doing DMA from 68k bus, CPU */
644 /* is locked) or will abort DMA operation (in case of DMA Fill or Copy). */
645 dma_cycles = ((lines_per_frame - bitmap.viewport.h - 1) * MCYCLES_PER_LINE) - cycles;
646 }
647 else
648 {
649 /* Process DMA until the end of current line */
650 dma_cycles = (mcycles_vdp + MCYCLES_PER_LINE) - cycles;
651 }
652
653 /* Remaining DMA bytes for that line */
654 dma_bytes = (dma_cycles * rate) / MCYCLES_PER_LINE;
655
656 #ifdef LOGVDP
657 error("[%d(%d)][%d(%d)] DMA type %d (%d access/line)(%d cycles left)-> %d access (%d remaining) (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE,dma_type, rate, dma_cycles, dma_bytes, dma_length, m68k_get_reg(M68K_REG_PC));
658 #endif
659
660 /* Check if DMA can be finished before the end of current line */
661 if (dma_length < dma_bytes)
662 {
663 /* Adjust remaining DMA bytes */
664 dma_bytes = dma_length;
665 dma_cycles = (dma_bytes * MCYCLES_PER_LINE) / rate;
666 }
667
668 /* Update DMA timings */
669 if (dma_type < 2)
670 {
671 /* 68K is frozen during DMA from 68k bus */
672 m68k.cycles = cycles + dma_cycles;
673 #ifdef LOGVDP
674 error("-->CPU frozen for %d cycles\n", dma_cycles);
675 #endif
676 }
677 else
678 {
679 /* Set DMA Busy flag */
680 status |= 0x02;
681
682 /* 68K is still running, set DMA end cycle */
683 dma_endCycles = cycles + dma_cycles;
684 #ifdef LOGVDP
685 error("-->DMA ends in %d cycles\n", dma_cycles);
686 #endif
687 }
688
689 /* Process DMA */
690 if (dma_bytes)
691 {
692 /* Update DMA length */
693 dma_length -= dma_bytes;
694
695 /* Process DMA operation */
696 dma_func[reg[23] >> 4](dma_bytes);
697
698 /* Check if DMA is finished */
699 if (!dma_length)
700 {
701 /* DMA source address registers are incremented during DMA (even DMA Fill) */
702 uint16 end = reg[21] + (reg[22] << 8) + reg[19] + (reg[20] << 8);
703 reg[21] = end & 0xff;
704 reg[22] = end >> 8;
705
706 /* DMA length registers are decremented during DMA */
707 reg[19] = reg[20] = 0;
708
709 /* perform cached write, if any */
710 if (cached_write >= 0)
711 {
712 vdp_68k_ctrl_w(cached_write);
713 cached_write = -1;
714 }
715 }
716 }
717 }
718
719
720 /*--------------------------------------------------------------------------*/
721 /* Control port access functions */
722 /*--------------------------------------------------------------------------*/
723
vdp_68k_ctrl_w(unsigned int data)724 void vdp_68k_ctrl_w(unsigned int data)
725 {
726 /* Check pending flag */
727 if (pending == 0)
728 {
729 /* A single long word write instruction could have started DMA with the first word */
730 if (dma_length)
731 {
732 /* 68k is frozen during 68k bus DMA */
733 /* Second word should be written after DMA completion */
734 /* See Formula One & Kawasaki Superbike Challenge */
735 if (dma_type < 2)
736 {
737 /* Latch second control word for later */
738 cached_write = data;
739 return;
740 }
741 }
742
743 /* Check CD0-CD1 bits */
744 if ((data & 0xC000) == 0x8000)
745 {
746 /* VDP register write */
747 vdp_reg_w((data >> 8) & 0x1F, data & 0xFF, m68k.cycles);
748 }
749 else
750 {
751 /* Set pending flag (Mode 5 only) */
752 pending = reg[1] & 4;
753 }
754
755 /* Update address and code registers */
756 addr = addr_latch | (data & 0x3FFF);
757 code = ((code & 0x3C) | ((data >> 14) & 0x03));
758 }
759 else
760 {
761 /* Clear pending flag */
762 pending = 0;
763
764 /* Save address bits A15 and A14 */
765 addr_latch = (data & 3) << 14;
766
767 /* Update address and code registers */
768 addr = addr_latch | (addr & 0x3FFF);
769 code = ((code & 0x03) | ((data >> 2) & 0x3C));
770
771 /* Detect DMA operation (CD5 bit set) */
772 if (code & 0x20)
773 {
774 /* DMA must be enabled */
775 if (reg[1] & 0x10)
776 {
777 /* DMA type */
778 switch (reg[23] >> 6)
779 {
780 case 2:
781 {
782 /* DMA Fill */
783 dma_type = 2;
784
785 /* DMA is pending until next DATA port write */
786 dmafill = 1;
787
788 /* Set DMA Busy flag */
789 status |= 0x02;
790
791 /* DMA end cycle is not initialized yet (this prevents DMA Busy flag from being cleared on VDP status read) */
792 dma_endCycles = 0xffffffff;
793 break;
794 }
795
796 case 3:
797 {
798 /* DMA Copy */
799 dma_type = 3;
800
801 /* DMA length */
802 dma_length = (reg[20] << 8) | reg[19];
803
804 /* Zero DMA length (pre-decrementing counter) */
805 if (!dma_length)
806 {
807 dma_length = 0x10000;
808 }
809
810 /* DMA source address */
811 dma_src = (reg[22] << 8) | reg[21];
812
813 /* Trigger DMA */
814 vdp_dma_update(m68k.cycles);
815 break;
816 }
817
818 default:
819 {
820 /* DMA from 68k bus */
821 dma_type = (code & 0x06) ? 0 : 1;
822
823 /* DMA length */
824 dma_length = (reg[20] << 8) | reg[19];
825
826 /* Zero DMA length (pre-decrementing counter) */
827 if (!dma_length)
828 {
829 dma_length = 0x10000;
830 }
831
832 /* DMA source address */
833 dma_src = (reg[22] << 8) | reg[21];
834
835 /* Transfer from SVP ROM/RAM ($000000-$3fffff) or CD Word-RAM ($200000-$3fffff/$600000-$7fffff) */
836 if (((system_hw == SYSTEM_MCD) && ((reg[23] & 0x70) == ((scd.cartridge.boot >> 1) + 0x10))) || (svp && !(reg[23] & 0x60)))
837 {
838 /* source data is available with one cycle delay, i.e first word written by VDP is */
839 /* previous data being held on 68k bus at that time, then source words are written */
840 /* normally to VDP RAM, with only last source word being ignored */
841 addr += reg[15];
842 dma_length--;
843 }
844
845 /* Trigger DMA */
846 vdp_dma_update(m68k.cycles);
847 break;
848 }
849 }
850 }
851 }
852 }
853
854 /*
855 FIFO emulation (Chaos Engine/Soldier of Fortune, Double Clutch, Sol Deace)
856 --------------------------------------------------------------------------
857 Each VRAM access is byte wide, so one VRAM write (word) need two slot access.
858
859 NOTE: Invalid code 0x02 (register write) should not behave the same as VRAM
860 access, i.e data is ignored and only one access slot is used for each word,
861 BUT a few games ("Clue", "Microcosm") which accidentally corrupt code value
862 will have issues when emulating FIFO timings. They likely work fine on real
863 hardware because of periodical 68k wait-states which have been observed and
864 would naturaly add some delay between writes. Until those wait-states are
865 accurately measured and emulated, delay is forced when invalid code value
866 is being used.
867 */
868 fifo_byte_access = ((code & 0x0F) <= 0x02);
869 }
870
871 /* Mega Drive VDP control port specific (MS compatibility mode) */
vdp_z80_ctrl_w(unsigned int data)872 void vdp_z80_ctrl_w(unsigned int data)
873 {
874 switch (pending)
875 {
876 case 0:
877 {
878 /* Latch LSB */
879 addr_latch = data;
880
881 /* Set LSB pending flag */
882 pending = 1;
883 return;
884 }
885
886 case 1:
887 {
888 /* Update address and code registers */
889 addr = (addr & 0xC000) | ((data & 0x3F) << 8) | addr_latch ;
890 code = ((code & 0x3C) | ((data >> 6) & 0x03));
891
892 if ((code & 0x03) == 0x02)
893 {
894 /* VDP register write */
895 vdp_reg_w(data & 0x1F, addr_latch, Z80.cycles);
896
897 /* Clear pending flag */
898 pending = 0;
899 return;
900 }
901
902 /* Set Mode 5 pending flag */
903 pending = (reg[1] & 4) >> 1;
904
905 if (!pending && !(code & 0x03))
906 {
907 /* Process VRAM read */
908 fifo[0] = vram[addr & 0x3FFF];
909
910 /* Increment address register */
911 addr += (reg[15] + 1);
912 }
913 return;
914 }
915
916 case 2:
917 {
918 /* Latch LSB */
919 addr_latch = data;
920
921 /* Set LSB pending flag */
922 pending = 3;
923 return;
924 }
925
926 case 3:
927 {
928 /* Clear pending flag */
929 pending = 0;
930
931 /* Update address and code registers */
932 addr = ((addr_latch & 3) << 14) | (addr & 0x3FFF);
933 code = ((code & 0x03) | ((addr_latch >> 2) & 0x3C));
934
935 /* Detect DMA operation (CD5 bit set) */
936 if (code & 0x20)
937 {
938 /* DMA should be enabled */
939 if (reg[1] & 0x10)
940 {
941 /* DMA type */
942 switch (reg[23] >> 6)
943 {
944 case 2:
945 {
946 /* DMA Fill */
947 dma_type = 2;
948
949 /* DMA is pending until next DATA port write */
950 dmafill = 1;
951
952 /* Set DMA Busy flag */
953 status |= 0x02;
954
955 /* DMA end cycle is not initialized yet (this prevents DMA Busy flag from being cleared on VDP status read) */
956 dma_endCycles = 0xffffffff;
957 break;
958 }
959
960 case 3:
961 {
962 /* DMA copy */
963 dma_type = 3;
964
965 /* DMA length */
966 dma_length = (reg[20] << 8) | reg[19];
967
968 /* Zero DMA length (pre-decrementing counter) */
969 if (!dma_length)
970 {
971 dma_length = 0x10000;
972 }
973
974 /* DMA source address */
975 dma_src = (reg[22] << 8) | reg[21];
976
977 /* Trigger DMA */
978 vdp_dma_update(Z80.cycles);
979 break;
980 }
981
982 default:
983 {
984 /* DMA from 68k bus does not work when Z80 is in control */
985 break;
986 }
987 }
988 }
989 }
990 }
991 return;
992 }
993 }
994
995 /* Master System & Game Gear VDP control port specific */
vdp_sms_ctrl_w(unsigned int data)996 void vdp_sms_ctrl_w(unsigned int data)
997 {
998 if (pending == 0)
999 {
1000 /* Update address register LSB */
1001 addr = (addr & 0x3F00) | (data & 0xFF);
1002
1003 /* Latch LSB */
1004 addr_latch = data;
1005
1006 /* Set LSB pending flag */
1007 pending = 1;
1008 }
1009 else
1010 {
1011 /* Update address and code registers */
1012 code = (data >> 6) & 3;
1013 addr = (data << 8 | addr_latch) & 0x3FFF;
1014
1015 /* Clear pending flag */
1016 pending = 0;
1017
1018 if (code == 0)
1019 {
1020 /* Process VRAM read */
1021 fifo[0] = vram[addr & 0x3FFF];
1022
1023 /* Increment address register */
1024 addr = (addr + 1) & 0x3FFF;
1025 return;
1026 }
1027
1028 if (code == 2)
1029 {
1030 /* Save current VDP mode */
1031 int mode, prev = (reg[0] & 0x06) | (reg[1] & 0x18);
1032
1033 /* Write VDP register 0-15 */
1034 vdp_reg_w(data & 0x0F, addr_latch, Z80.cycles);
1035
1036 /* Check VDP mode changes */
1037 mode = (reg[0] & 0x06) | (reg[1] & 0x18);
1038 prev ^= mode;
1039
1040 if (prev)
1041 {
1042 /* Check for extended modes */
1043 if (system_hw > SYSTEM_SMS)
1044 {
1045 int height;
1046
1047 if (mode == 0x0E) /* M1=0,M2=1,M3=1,M4=1 */
1048 {
1049 /* Mode 4 extended (240 lines) */
1050 height = 240;
1051
1052 /* Update vertical counter max value */
1053 vc_max = vc_table[3][vdp_pal];
1054 }
1055 else if (mode == 0x16) /* M1=1,M2=1,M3=0,M4=1 */
1056 {
1057 /* Mode 4 extended (224 lines) */
1058 height = 224;
1059
1060 /* Update vertical counter max value */
1061 vc_max = vc_table[1][vdp_pal];
1062 }
1063 else
1064 {
1065 /* Mode 4 default (224 lines) */
1066 height = 192;
1067
1068 /* Default vertical counter max value */
1069 vc_max = vc_table[0][vdp_pal];
1070 }
1071
1072 /* viewport changes should be applied on next frame */
1073 if (height != bitmap.viewport.h)
1074 {
1075 bitmap.viewport.changed |= 2;
1076 }
1077 }
1078
1079 /* Rendering mode */
1080 render_bg = render_bg_modes[mode>>1];
1081
1082 /* Mode switching */
1083 if (prev & 0x04)
1084 {
1085 int i;
1086
1087 if (mode & 0x04)
1088 {
1089 /* Mode 4 sprites */
1090 parse_satb = parse_satb_m4;
1091 render_obj = render_obj_m4;
1092
1093 /* force BG cache update*/
1094 bg_list_index = 0x200;
1095 }
1096 else
1097 {
1098 /* TMS-mode sprites */
1099 parse_satb = parse_satb_tms;
1100 render_obj = render_obj_tms;
1101
1102 /* BG cache is not used */
1103 bg_list_index = 0;
1104 }
1105
1106 /* reinitialize palette */
1107 for(i = 0; i < 0x20; i ++)
1108 {
1109 color_update_m4(i, *(uint16 *)&cram[i << 1]);
1110 }
1111 color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]);
1112 }
1113 }
1114 }
1115 }
1116 }
1117
1118 /* SG-1000 VDP (TMS99xx) control port specific */
vdp_tms_ctrl_w(unsigned int data)1119 void vdp_tms_ctrl_w(unsigned int data)
1120 {
1121 if (pending == 0)
1122 {
1123 /* Latch LSB */
1124 addr_latch = data;
1125
1126 /* Set LSB pending flag */
1127 pending = 1;
1128 }
1129 else
1130 {
1131 /* Update address and code registers */
1132 code = (data >> 6) & 3;
1133 addr = (data << 8 | addr_latch) & 0x3FFF;
1134
1135 /* Clear pending flag */
1136 pending = 0;
1137
1138 if (code == 0)
1139 {
1140 /* Process VRAM read */
1141 fifo[0] = vram[addr & 0x3FFF];
1142
1143 /* Increment address register */
1144 addr = (addr + 1) & 0x3FFF;
1145 return;
1146 }
1147
1148 if (code & 2)
1149 {
1150 /* VDP register index (0-7) */
1151 data &= 0x07;
1152
1153 /* Write VDP register */
1154 vdp_reg_w(data, addr_latch, Z80.cycles);
1155
1156 /* Check VDP mode changes */
1157 if (data < 2)
1158 {
1159 /* Rendering mode */
1160 render_bg = render_bg_modes[((reg[0] & 0x02) | (reg[1] & 0x18)) >> 1];
1161 }
1162 }
1163 }
1164 }
1165
1166 /*
1167 * Status register
1168 *
1169 * Bits
1170 * 0 NTSC(0)/PAL(1)
1171 * 1 DMA Busy
1172 * 2 During HBlank
1173 * 3 During VBlank
1174 * 4 0:1 even:odd field (interlaced modes only)
1175 * 5 Sprite collision
1176 * 6 Too many sprites per line
1177 * 7 v interrupt occurred
1178 * 8 Write FIFO full
1179 * 9 Write FIFO empty
1180 * 10 - 15 Open Bus
1181 */
vdp_68k_ctrl_r(unsigned int cycles)1182 unsigned int vdp_68k_ctrl_r(unsigned int cycles)
1183 {
1184 unsigned int temp;
1185
1186 /* Cycle-accurate VDP status read (adjust CPU time with current instruction execution time) */
1187 cycles += m68k_cycles();
1188
1189 /* Update FIFO status flags if not empty */
1190 if (fifo_write_cnt)
1191 {
1192 vdp_fifo_update(cycles);
1193 }
1194
1195 /* Check if DMA Busy flag is set */
1196 if (status & 2)
1197 {
1198 /* Check if DMA is finished */
1199 if (!dma_length && (cycles >= dma_endCycles))
1200 {
1201 /* Clear DMA Busy flag */
1202 status &= 0xFFFD;
1203 }
1204 }
1205
1206 /* Return VDP status */
1207 temp = status;
1208
1209 /* Clear pending flag */
1210 pending = 0;
1211
1212 /* Clear SOVR & SCOL flags */
1213 status &= 0xFF9F;
1214
1215 /* VBLANK flag is set when display is disabled */
1216 if (!(reg[1] & 0x40))
1217 {
1218 temp |= 0x08;
1219 }
1220
1221 /* Cycle-accurate VINT flag (Ex-Mutants, Tyrant / Mega-Lo-Mania, Marvel Land) */
1222 /* this allows VINT flag to be read just before vertical interrupt is being triggered */
1223 if ((v_counter == bitmap.viewport.h) && (cycles >= (mcycles_vdp + 788)))
1224 {
1225 /* check Z80 interrupt state to assure VINT has not already been triggered (and flag cleared) */
1226 if (Z80.irq_state != ASSERT_LINE)
1227 {
1228 temp |= 0x80;
1229 }
1230 }
1231
1232 /* Cycle-accurate HBLANK flag (Sonic 3 & Sonic 2 "VS Modes", Bugs Bunny Double Trouble, Lemmings 2, Mega Turrican, V.R Troopers, Gouketsuji Ichizoku,...) */
1233 /* NB: this is not 100% accurate (see hvc.h for horizontal events timings in H32 and H40 mode) but is close enough to make no noticeable difference for games */
1234 if ((cycles % MCYCLES_PER_LINE) < 588)
1235 {
1236 temp |= 0x04;
1237 }
1238
1239 #ifdef LOGVDP
1240 error("[%d(%d)][%d(%d)] VDP 68k status read -> 0x%x (0x%x) (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, temp, status, m68k_get_reg(M68K_REG_PC));
1241 #endif
1242 return (temp);
1243 }
1244
vdp_z80_ctrl_r(unsigned int cycles)1245 unsigned int vdp_z80_ctrl_r(unsigned int cycles)
1246 {
1247 unsigned int temp;
1248
1249 /* Check if DMA busy flag is set (Mega Drive VDP specific) */
1250 if (status & 2)
1251 {
1252 /* Check if DMA is finished */
1253 if (!dma_length && (cycles >= dma_endCycles))
1254 {
1255 /* Clear DMA Busy flag */
1256 status &= 0xFD;
1257 }
1258 }
1259
1260 /* Check if we are already on next line */
1261 if ((cycles - mcycles_vdp) >= MCYCLES_PER_LINE)
1262 {
1263 /* check vertical position */
1264 if (v_counter == bitmap.viewport.h)
1265 {
1266 /* update VCounter to indicate VINT flag has been cleared & VINT should not be triggered */
1267 v_counter++;
1268
1269 /* cycle-accurate VINT flag (immediately cleared after being read) */
1270 status |= 0x80;
1271 }
1272 else
1273 {
1274 /* update line counter */
1275 int line = (v_counter + 1) % lines_per_frame;
1276
1277 /* check if we are within active display range */
1278 if ((line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special & HW_3D_GLASSES))
1279 {
1280 /* update VCounter to indicate next line has already been rendered */
1281 v_counter = line;
1282
1283 /* render next line (cycle-accurate SCOL & SOVR flags) */
1284 render_line(line);
1285 }
1286 }
1287 }
1288
1289 /* Return VDP status */
1290 temp = status;
1291
1292 /* Clear pending flag */
1293 pending = 0;
1294
1295 /* Clear VINT, SOVR & SCOL flags */
1296 status &= 0xFF1F;
1297
1298 /* Mega Drive VDP specific */
1299 if (system_hw & SYSTEM_MD)
1300 {
1301 /* Display OFF: VBLANK flag is set */
1302 if (!(reg[1] & 0x40))
1303 {
1304 temp |= 0x08;
1305 }
1306
1307 /* HBLANK flag */
1308 if ((cycles % MCYCLES_PER_LINE) < 588)
1309 {
1310 temp |= 0x04;
1311 }
1312 }
1313 else if (reg[0] & 0x04)
1314 {
1315 /* Mode 4 unused bits (fixes PGA Tour Golf) */
1316 temp |= 0x1F;
1317 }
1318
1319 /* Cycle-accurate SCOL flag */
1320 if ((temp & 0x20) && (v_counter == (spr_col >> 8)))
1321 {
1322 if (system_hw & SYSTEM_MD)
1323 {
1324 /* COL flag is set at HCount 0xFF on MD */
1325 if ((cycles % MCYCLES_PER_LINE) < 105)
1326 {
1327 status |= 0x20;
1328 temp &= ~0x20;
1329 }
1330 }
1331 else
1332 {
1333 /* COL flag is set at the pixel it occurs */
1334 uint8 hc = hctab[(cycles + SMS_CYCLE_OFFSET + 15) % MCYCLES_PER_LINE];
1335 if ((hc < (spr_col & 0xff)) || (hc > 0xf3))
1336 {
1337 status |= 0x20;
1338 temp &= ~0x20;
1339 }
1340 }
1341 }
1342
1343 /* Clear HINT & VINT pending flags */
1344 hint_pending = vint_pending = 0;
1345
1346 /* Clear Z80 interrupt */
1347 Z80.irq_state = CLEAR_LINE;
1348
1349 #ifdef LOGVDP
1350 error("[%d(%d)][%d(%d)] VDP Z80 status read -> 0x%x (0x%x) (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, temp, status, Z80.pc.w.l);
1351 #endif
1352 return (temp);
1353 }
1354
1355 /*--------------------------------------------------------------------------*/
1356 /* HV Counters */
1357 /*--------------------------------------------------------------------------*/
1358
vdp_hvc_r(unsigned int cycles)1359 unsigned int vdp_hvc_r(unsigned int cycles)
1360 {
1361 int vc;
1362 unsigned int data = hvc_latch;
1363
1364 /* Check if HVC latch is enabled */
1365 if (data)
1366 {
1367 /* Mode 5: HV counters are frozen (cf. lightgun games, Sunset Riders logo) */
1368 if (reg[1] & 0x04)
1369 {
1370 #ifdef LOGVDP
1371 error("[%d(%d)][%d(%d)] HVC latch read -> 0x%x (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data & 0xffff, m68k_get_reg(M68K_REG_PC));
1372 #endif
1373 /* return latched HVC value */
1374 return (data & 0xffff);
1375 }
1376 else
1377 {
1378 /* Mode 4: by default, VCounter runs normally & HCounter is frozen */
1379 data &= 0xff;
1380 }
1381 }
1382 else
1383 {
1384 /* Cycle-accurate HCounter (Striker, Mickey Mania, Skitchin, Road Rash I,II,III, Sonic 3D Blast...) */
1385 data = hctab[cycles % MCYCLES_PER_LINE];
1386 }
1387
1388 /* Cycle-accurate VCounter */
1389 vc = v_counter;
1390 if ((cycles - mcycles_vdp) >= MCYCLES_PER_LINE)
1391 {
1392 vc = (vc + 1) % lines_per_frame;
1393 }
1394
1395 /* VCounter overflow */
1396 if (vc > vc_max)
1397 {
1398 vc -= lines_per_frame;
1399 }
1400
1401 /* Interlaced modes */
1402 if (interlaced)
1403 {
1404 /* Interlace mode 2 (Sonic the Hedgehog 2, Combat Cars) */
1405 vc <<= im2_flag;
1406
1407 /* Replace bit 0 with bit 8 */
1408 vc = (vc & ~1) | ((vc >> 8) & 1);
1409 }
1410
1411 /* return HCounter in LSB & VCounter in MSB */
1412 data |= ((vc & 0xff) << 8);
1413
1414 #ifdef LOGVDP
1415 error("[%d(%d)][%d(%d)] HVC read -> 0x%x (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, data, m68k_get_reg(M68K_REG_PC));
1416 #endif
1417 return (data);
1418 }
1419
1420
1421 /*--------------------------------------------------------------------------*/
1422 /* Test registers */
1423 /*--------------------------------------------------------------------------*/
1424
vdp_test_w(unsigned int data)1425 void vdp_test_w(unsigned int data)
1426 {
1427 #ifdef LOGERROR
1428 error("Unused VDP Write 0x%x (%08x)\n", data, m68k_get_reg(M68K_REG_PC));
1429 #endif
1430 }
1431
1432
1433 /*--------------------------------------------------------------------------*/
1434 /* 68k interrupt handler (TODO: check how interrupts are handled in Mode 4) */
1435 /*--------------------------------------------------------------------------*/
1436
vdp_68k_irq_ack(int int_level)1437 int vdp_68k_irq_ack(int int_level)
1438 {
1439 #ifdef LOGVDP
1440 error("[%d(%d)][%d(%d)] INT Level %d ack (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE,int_level, m68k_get_reg(M68K_REG_PC));
1441 #endif
1442
1443 /* VINT has higher priority (Fatal Rewind) */
1444 if (reg[1] & vint_pending)
1445 {
1446 #ifdef LOGVDP
1447 error("---> VINT cleared\n");
1448 #endif
1449
1450 /* Clear VINT pending flag */
1451 vint_pending = 0;
1452 status &= ~0x80;
1453
1454 /* Update IRQ status */
1455 if (reg[0] & hint_pending)
1456 {
1457 m68k_set_irq(4);
1458 }
1459 else
1460 {
1461 m68k_set_irq(0);
1462 }
1463 }
1464 else
1465 {
1466 #ifdef LOGVDP
1467 error("---> HINT cleared\n");
1468 #endif
1469
1470 /* Clear HINT pending flag */
1471 hint_pending = 0;
1472
1473 /* Update IRQ status */
1474 m68k_set_irq(0);
1475 }
1476
1477 return M68K_INT_ACK_AUTOVECTOR;
1478 }
1479
1480
1481 /*--------------------------------------------------------------------------*/
1482 /* VDP registers update function */
1483 /*--------------------------------------------------------------------------*/
1484
vdp_reg_w(unsigned int r,unsigned int d,unsigned int cycles)1485 static void vdp_reg_w(unsigned int r, unsigned int d, unsigned int cycles)
1486 {
1487 #ifdef LOGVDP
1488 error("[%d(%d)][%d(%d)] VDP register %d write -> 0x%x (%x)\n", v_counter, (v_counter + (cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, cycles, cycles%MCYCLES_PER_LINE, r, d, m68k_get_reg(M68K_REG_PC));
1489 #endif
1490
1491 /* VDP registers #11 to #23 cannot be updated in Mode 4 (Captain Planet & Avengers, Bass Master Classic Pro Edition) */
1492 if (!(reg[1] & 4) && (r > 10))
1493 {
1494 return;
1495 }
1496
1497 switch(r)
1498 {
1499 case 0: /* CTRL #1 */
1500 {
1501 /* Look for changed bits */
1502 r = d ^ reg[0];
1503 reg[0] = d;
1504
1505 /* Line Interrupt */
1506 if (r & hint_pending)
1507 {
1508 /* Update IRQ status */
1509 if (reg[1] & vint_pending)
1510 {
1511 set_irq_line(6);
1512 }
1513 else if (d & 0x10)
1514 {
1515 set_irq_line_delay(4);
1516 }
1517 else
1518 {
1519 set_irq_line(0);
1520 }
1521 }
1522
1523 /* Palette selection */
1524 if (r & 0x04)
1525 {
1526 /* Mega Drive VDP only */
1527 if (system_hw & SYSTEM_MD)
1528 {
1529 /* Reset color palette */
1530 int i;
1531 if (reg[1] & 0x04)
1532 {
1533 /* Mode 5 */
1534 color_update_m5(0x00, *(uint16 *)&cram[border << 1]);
1535 for (i = 1; i < 0x40; i++)
1536 {
1537 color_update_m5(i, *(uint16 *)&cram[i << 1]);
1538 }
1539 }
1540 else
1541 {
1542 /* Mode 4 */
1543 for (i = 0; i < 0x20; i++)
1544 {
1545 color_update_m4(i, *(uint16 *)&cram[i << 1]);
1546 }
1547 color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]);
1548 }
1549 }
1550 }
1551
1552 /* HVC latch (Sunset Riders, Lightgun games) */
1553 if (r & 0x02)
1554 {
1555 /* Mega Drive VDP only */
1556 if (system_hw & SYSTEM_MD)
1557 {
1558 /* Mode 5 only */
1559 if (reg[1] & 0x04)
1560 {
1561 if (d & 0x02)
1562 {
1563 /* Latch current HVC */
1564 hvc_latch = vdp_hvc_r(cycles) | 0x10000;
1565 }
1566 else
1567 {
1568 /* Free-running HVC */
1569 hvc_latch = 0;
1570 }
1571 }
1572 }
1573 }
1574 break;
1575 }
1576
1577 case 1: /* CTRL #2 */
1578 {
1579 /* Look for changed bits */
1580 r = d ^ reg[1];
1581 reg[1] = d;
1582
1583 /* 4K/16K address decoding */
1584 if (r & 0x80)
1585 {
1586 /* original TMS99xx hardware only (fixes Magical Kid Wiz) */
1587 if (system_hw == SYSTEM_SG)
1588 {
1589 int i;
1590
1591 /* make temporary copy of 16KB VRAM */
1592 memcpy(vram + 0x4000, vram, 0x4000);
1593
1594 /* re-arrange 16KB VRAM address decoding */
1595 if (d & 0x80)
1596 {
1597 /* 4K->16K address decoding */
1598 for (i=0; i<0x4000; i+=2)
1599 {
1600 *(uint16 *)(vram + ((i & 0x203F) | ((i << 6) & 0x1000) | ((i >> 1) & 0xFC0))) = *(uint16 *)(vram + 0x4000 + i);
1601 }
1602 }
1603 else
1604 {
1605 /* 16K->4K address decoding */
1606 for (i=0; i<0x4000; i+=2)
1607 {
1608 *(uint16 *)(vram + ((i & 0x203F) | ((i >> 6) & 0x40) | ((i << 1) & 0x1F80))) = *(uint16 *)(vram + 0x4000 + i);
1609 }
1610 }
1611 }
1612 }
1613
1614 /* Display status (modified during active display) */
1615 if ((r & 0x40) && (v_counter < bitmap.viewport.h))
1616 {
1617 /* Cycle offset vs HBLANK */
1618 int offset = cycles - mcycles_vdp;
1619 if (offset <= 860)
1620 {
1621 /* Sprite rendering is limited if display was disabled during HBLANK (Mickey Mania 3d level, Overdrive Demo) */
1622 if (d & 0x40)
1623 {
1624 /* NB: This is not 100% accurate. On real hardware, the maximal number of rendered sprites pixels */
1625 /* for the current line (normally 256 or 320 pixels) but also the maximal number of pre-processed */
1626 /* sprites for the next line (normally 64 or 80 sprites) are both reduced depending on the amount */
1627 /* of cycles spent with display disabled. Here we only reduce them by a fixed amount when display */
1628 /* has been reenabled after a specific point within HBLANK. */
1629 if (offset > 360)
1630 {
1631 max_sprite_pixels = 128;
1632 }
1633 }
1634
1635 /* Redraw entire line (Legend of Galahad, Lemmings 2, Formula One, Kawasaki Super Bike, Deadly Moves,...) */
1636 render_line(v_counter);
1637
1638 /* Restore default */
1639 max_sprite_pixels = 256 + ((reg[12] & 1) << 6);
1640 }
1641 else if (system_hw & SYSTEM_MD)
1642 {
1643 /* Active pixel offset */
1644 if (reg[12] & 1)
1645 {
1646 /* dot clock = MCLK / 8 */
1647 offset = ((offset - 860) / 8) + 16;
1648 }
1649 else
1650 {
1651 /* dot clock = MCLK / 10 */
1652 offset = ((offset - 860) / 10) + 16;
1653 }
1654
1655 /* Line is partially blanked (Nigel Mansell's World Championship Racing , Ren & Stimpy Show, ...) */
1656 if (offset < bitmap.viewport.w)
1657 {
1658 if (d & 0x40)
1659 {
1660 render_line(v_counter);
1661 blank_line(v_counter, 0, offset);
1662 }
1663 else
1664 {
1665 blank_line(v_counter, offset, bitmap.viewport.w - offset);
1666 }
1667 }
1668 }
1669 }
1670
1671 /* Frame Interrupt */
1672 if (r & vint_pending)
1673 {
1674 /* Update IRQ status */
1675 if (d & 0x20)
1676 {
1677 set_irq_line_delay(6);
1678 }
1679 else if (reg[0] & hint_pending)
1680 {
1681 set_irq_line(4);
1682 }
1683 else
1684 {
1685 set_irq_line(0);
1686 }
1687 }
1688
1689 /* Active display height */
1690 if (r & 0x08)
1691 {
1692 /* Mega Drive VDP only */
1693 if (system_hw & SYSTEM_MD)
1694 {
1695 /* Mode 5 only */
1696 if (d & 0x04)
1697 {
1698 /* Changes should be applied on next frame */
1699 bitmap.viewport.changed |= 2;
1700
1701 /* Update vertical counter max value */
1702 vc_max = vc_table[(d >> 2) & 3][vdp_pal];
1703 }
1704 }
1705 }
1706
1707 /* Rendering mode */
1708 if (r & 0x04)
1709 {
1710 /* Mega Drive VDP only */
1711 if (system_hw & SYSTEM_MD)
1712 {
1713 int i;
1714 if (d & 0x04)
1715 {
1716 /* Mode 5 rendering */
1717 parse_satb = parse_satb_m5;
1718 update_bg_pattern_cache = update_bg_pattern_cache_m5;
1719 if (im2_flag)
1720 {
1721 render_bg = (reg[11] & 0x04) ? render_bg_m5_im2_vs : render_bg_m5_im2;
1722 render_obj = (reg[12] & 0x08) ? render_obj_m5_im2_ste : render_obj_m5_im2;
1723 }
1724 else
1725 {
1726 render_bg = (reg[11] & 0x04) ? render_bg_m5_vs : render_bg_m5;
1727 render_obj = (reg[12] & 0x08) ? render_obj_m5_ste : render_obj_m5;
1728 }
1729
1730 /* Reset color palette */
1731 color_update_m5(0x00, *(uint16 *)&cram[border << 1]);
1732 for (i = 1; i < 0x40; i++)
1733 {
1734 color_update_m5(i, *(uint16 *)&cram[i << 1]);
1735 }
1736
1737 /* Mode 5 bus access */
1738 vdp_68k_data_w = vdp_68k_data_w_m5;
1739 vdp_z80_data_w = vdp_z80_data_w_m5;
1740 vdp_68k_data_r = vdp_68k_data_r_m5;
1741 vdp_z80_data_r = vdp_z80_data_r_m5;
1742
1743 /* Clear HVC latched value */
1744 hvc_latch = 0;
1745
1746 /* Check if HVC latch bit is set */
1747 if (reg[0] & 0x02)
1748 {
1749 /* Latch current HVC */
1750 hvc_latch = vdp_hvc_r(cycles) | 0x10000;
1751 }
1752
1753 /* max tiles to invalidate */
1754 bg_list_index = 0x800;
1755 }
1756 else
1757 {
1758 /* Mode 4 rendering */
1759 parse_satb = parse_satb_m4;
1760 update_bg_pattern_cache = update_bg_pattern_cache_m4;
1761 render_bg = render_bg_m4;
1762 render_obj = render_obj_m4;
1763
1764 /* Reset color palette */
1765 for (i = 0; i < 0x20; i++)
1766 {
1767 color_update_m4(i, *(uint16 *)&cram[i << 1]);
1768 }
1769 color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (border & 0x0F)) << 1]);
1770
1771 /* Mode 4 bus access */
1772 vdp_68k_data_w = vdp_68k_data_w_m4;
1773 vdp_z80_data_w = vdp_z80_data_w_m4;
1774 vdp_68k_data_r = vdp_68k_data_r_m4;
1775 vdp_z80_data_r = vdp_z80_data_r_m4;
1776
1777 /* Latch current HVC */
1778 hvc_latch = vdp_hvc_r(cycles) | 0x10000;
1779
1780 /* max tiles to invalidate */
1781 bg_list_index = 0x200;
1782 }
1783
1784 if (!do_not_invalidate_tile_cache)
1785 {
1786 /* Invalidate pattern cache */
1787 for (i = 0; i < bg_list_index; i++)
1788 {
1789 bg_name_list[i] = i;
1790 bg_name_dirty[i] = 0xFF;
1791 }
1792 }
1793
1794 /* Update vertical counter max value */
1795 vc_max = vc_table[(d >> 2) & 3][vdp_pal];
1796
1797 /* Display height change should be applied on next frame */
1798 bitmap.viewport.changed |= 2;
1799 }
1800 else
1801 {
1802 /* No effect (cleared to avoid mode 5 detection elsewhere) */
1803 reg[1] &= ~0x04;
1804 }
1805 }
1806 break;
1807 }
1808
1809 case 2: /* Plane A Name Table Base */
1810 {
1811 reg[2] = d;
1812 ntab = (d << 10) & 0xE000;
1813
1814 /* Plane A Name Table Base changed during HBLANK */
1815 if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860)))
1816 {
1817 /* render entire line */
1818 render_line(v_counter);
1819 }
1820 break;
1821 }
1822
1823 case 3: /* Window Plane Name Table Base */
1824 {
1825 reg[3] = d;
1826 if (reg[12] & 0x01)
1827 {
1828 ntwb = (d << 10) & 0xF000;
1829 }
1830 else
1831 {
1832 ntwb = (d << 10) & 0xF800;
1833 }
1834
1835 /* Window Plane Name Table Base changed during HBLANK */
1836 if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860)))
1837 {
1838 /* render entire line */
1839 render_line(v_counter);
1840 }
1841 break;
1842 }
1843
1844 case 4: /* Plane B Name Table Base */
1845 {
1846 reg[4] = d;
1847 ntbb = (d << 13) & 0xE000;
1848
1849 /* Plane B Name Table Base changed during HBLANK (Adventures of Batman & Robin) */
1850 if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (cycles <= (mcycles_vdp + 860)))
1851 {
1852 /* render entire line */
1853 render_line(v_counter);
1854 }
1855
1856 break;
1857 }
1858
1859 case 5: /* Sprite Attribute Table Base */
1860 {
1861 reg[5] = d;
1862 satb = (d << 9) & sat_base_mask;
1863 break;
1864 }
1865
1866 case 7: /* Backdrop color */
1867 {
1868 reg[7] = d;
1869
1870 /* Check if backdrop color changed */
1871 d &= 0x3F;
1872
1873 if (d != border)
1874 {
1875 /* Update backdrop color */
1876 border = d;
1877
1878 /* Reset palette entry */
1879 if (reg[1] & 4)
1880 {
1881 /* Mode 5 */
1882 color_update_m5(0x00, *(uint16 *)&cram[d << 1]);
1883 }
1884 else
1885 {
1886 /* Mode 4 */
1887 color_update_m4(0x40, *(uint16 *)&cram[(0x10 | (d & 0x0F)) << 1]);
1888 }
1889
1890 /* Backdrop color modified during HBLANK (Road Rash 1,2,3)*/
1891 if ((v_counter < bitmap.viewport.h) && (cycles <= (mcycles_vdp + 860)))
1892 {
1893 /* remap entire line */
1894 remap_line(v_counter);
1895 }
1896 }
1897 break;
1898 }
1899
1900 case 8: /* Horizontal Scroll (Mode 4 only) */
1901 {
1902 /* H-Scroll is latched at HCount 0xF3, HCount 0xF6 on MD */
1903 /* Line starts at HCount 0xF4, HCount 0xF6 on MD */
1904 if (system_hw < SYSTEM_MD)
1905 {
1906 cycles = cycles + 15;
1907 }
1908
1909 /* Check if H-Scroll has already been latched */
1910 if ((cycles - mcycles_vdp) >= MCYCLES_PER_LINE)
1911 {
1912 /* update line counter */
1913 int line = (v_counter + 1) % lines_per_frame;
1914
1915 /* check if we are within active display range */
1916 if ((line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special & HW_3D_GLASSES))
1917 {
1918 /* update VCounter to indicate next line has already been rendered */
1919 v_counter = line;
1920
1921 /* render next line before updating H-Scroll */
1922 render_line(line);
1923 }
1924 }
1925
1926 reg[8] = d;
1927 break;
1928 }
1929
1930 case 11: /* CTRL #3 */
1931 {
1932 reg[11] = d;
1933
1934 /* Horizontal scrolling mode */
1935 hscroll_mask = hscroll_mask_table[d & 0x03];
1936
1937 /* Vertical Scrolling mode */
1938 if (d & 0x04)
1939 {
1940 render_bg = im2_flag ? render_bg_m5_im2_vs : render_bg_m5_vs;
1941 }
1942 else
1943 {
1944 render_bg = im2_flag ? render_bg_m5_im2 : render_bg_m5;
1945 }
1946 break;
1947 }
1948
1949 case 12: /* CTRL #4 */
1950 {
1951 /* Look for changed bits */
1952 r = d ^ reg[12];
1953 reg[12] = d;
1954
1955 /* Shadow & Highlight mode */
1956 if (r & 0x08)
1957 {
1958 /* Reset color palette */
1959 int i;
1960 color_update_m5(0x00, *(uint16 *)&cram[border << 1]);
1961 for (i = 1; i < 0x40; i++)
1962 {
1963 color_update_m5(i, *(uint16 *)&cram[i << 1]);
1964 }
1965
1966 /* Update sprite rendering function */
1967 if (d & 0x08)
1968 {
1969 render_obj = im2_flag ? render_obj_m5_im2_ste : render_obj_m5_ste;
1970 }
1971 else
1972 {
1973 render_obj = im2_flag ? render_obj_m5_im2 : render_obj_m5;
1974 }
1975 }
1976
1977 /* Interlaced modes */
1978 if (r & 0x06)
1979 {
1980 /* changes should be applied on next frame */
1981 bitmap.viewport.changed |= 2;
1982 }
1983
1984 /* Active display width */
1985 if (r & 0x01)
1986 {
1987 /* FIFO access slots timings depend on active width */
1988 if (fifo_slots)
1989 {
1990 /* Synchronize VDP FIFO */
1991 vdp_fifo_update(cycles);
1992 }
1993
1994 if (d & 0x01)
1995 {
1996 /* Update display-dependant registers */
1997 ntwb = (reg[3] << 10) & 0xF000;
1998 satb = (reg[5] << 9) & 0xFC00;
1999 sat_base_mask = 0xFC00;
2000 sat_addr_mask = 0x03FF;
2001
2002 /* Update HC table */
2003 hctab = cycle2hc40;
2004
2005 /* Update clipping */
2006 window_clip(reg[17], 1);
2007
2008 /* Update max sprite pixels per line*/
2009 max_sprite_pixels = 320;
2010
2011 /* FIFO access slots timings */
2012 fifo_timing = (int *)fifo_timing_h40;
2013 }
2014 else
2015 {
2016 /* Update display-dependant registers */
2017 ntwb = (reg[3] << 10) & 0xF800;
2018 satb = (reg[5] << 9) & 0xFE00;
2019 sat_base_mask = 0xFE00;
2020 sat_addr_mask = 0x01FF;
2021
2022 /* Update HC table */
2023 hctab = cycle2hc32;
2024
2025 /* Update clipping */
2026 window_clip(reg[17], 0);
2027
2028 /* Update max sprite pixels per line*/
2029 max_sprite_pixels = 256;
2030
2031 /* FIFO access slots timings */
2032 fifo_timing = (int *)fifo_timing_h32;
2033 }
2034
2035 /* Active screen width modified during VBLANK will be applied on upcoming frame */
2036 if (v_counter >= bitmap.viewport.h)
2037 {
2038 bitmap.viewport.w = max_sprite_pixels;
2039 }
2040
2041 /* Allow active screen width to be modified during first two lines (Bugs Bunny in Double Trouble) */
2042 else if (v_counter <= 1)
2043 {
2044 bitmap.viewport.w = max_sprite_pixels;
2045
2046 /* Redraw lines */
2047 render_line(0);
2048 if (v_counter)
2049 {
2050 render_line(1);
2051 }
2052 }
2053 else
2054 {
2055 /* Screen width changes during active display (Golden Axe 3 intro, Ultraverse Prime) */
2056 /* should be applied on next frame since backend rendered framebuffer width is fixed */
2057 /* and can not be modified mid-frame. This is not 100% accurate but games generally */
2058 /* do this when the screen is blanked so it is likely unnoticeable. */
2059 bitmap.viewport.changed |= 2;
2060 }
2061 }
2062 break;
2063 }
2064
2065 case 13: /* HScroll Base Address */
2066 {
2067 reg[13] = d;
2068 hscb = (d << 10) & 0xFC00;
2069 break;
2070 }
2071
2072 case 16: /* Playfield size */
2073 {
2074 reg[16] = d;
2075 playfield_shift = shift_table[(d & 3)];
2076 playfield_col_mask = col_mask_table[(d & 3)];
2077 playfield_row_mask = row_mask_table[(d >> 4) & 3];
2078 break;
2079 }
2080
2081 case 17: /* Window/Plane A vertical clipping */
2082 {
2083 reg[17] = d;
2084 window_clip(d, reg[12] & 1);
2085 break;
2086 }
2087
2088 default:
2089 {
2090 reg[r] = d;
2091 break;
2092 }
2093 }
2094 }
2095
2096 /*--------------------------------------------------------------------------*/
2097 /* FIFO emulation (Mega Drive VDP specific) */
2098 /* ---------------------------------------- */
2099 /* */
2100 /* CPU access to VRAM, CRAM & VSRAM is limited during active display: */
2101 /* H32 mode -> 16 access per line */
2102 /* H40 mode -> 18 access per line */
2103 /* */
2104 /* with fixed access slots timings detailled below. */
2105 /* */
2106 /* Each VRAM access is byte wide, so one VRAM write (word) need two slots. */
2107 /* */
2108 /*--------------------------------------------------------------------------*/
2109
vdp_fifo_update(unsigned int cycles)2110 static void vdp_fifo_update(unsigned int cycles)
2111 {
2112 int fifo_read_cnt, line_slots = 0;
2113
2114 /* number of access slots up to current line */
2115 int total_slots = dma_timing[0][reg[12] & 1] * ((v_counter + 1) % lines_per_frame);
2116
2117 /* number of access slots within current line */
2118 cycles -= mcycles_vdp;
2119 while (fifo_timing[line_slots] <= cycles)
2120 {
2121 line_slots++;
2122 }
2123
2124 /* number of processed FIFO entries since last access (byte access needs two slots to process one FIFO word) */
2125 fifo_read_cnt = (total_slots + line_slots - fifo_slots) >> fifo_byte_access;
2126
2127 if (fifo_read_cnt > 0)
2128 {
2129 /* process FIFO entries */
2130 fifo_write_cnt -= fifo_read_cnt;
2131
2132 /* Clear FIFO full flag */
2133 status &= 0xFEFF;
2134
2135 if (fifo_write_cnt <= 0)
2136 {
2137 /* No more FIFO entries */
2138 fifo_write_cnt = 0;
2139
2140 /* Set FIFO empty flag */
2141 status |= 0x200;
2142
2143 /* Reinitialize FIFO access slot counter */
2144 fifo_slots = total_slots + line_slots;
2145 }
2146 else
2147 {
2148 /* Update FIFO access slot counter */
2149 fifo_slots += (fifo_read_cnt << fifo_byte_access);
2150 }
2151 }
2152
2153 /* next FIFO update cycle */
2154 fifo_cycles = mcycles_vdp + fifo_timing[fifo_slots - total_slots + fifo_byte_access];
2155 }
2156
2157
2158 /*--------------------------------------------------------------------------*/
2159 /* Internal 16-bit data bus access function (Mode 5 only) */
2160 /*--------------------------------------------------------------------------*/
vdp_bus_w(unsigned int data)2161 static void vdp_bus_w(unsigned int data)
2162 {
2163 /* write data to next FIFO entry */
2164 fifo[fifo_idx] = data;
2165
2166 /* increment FIFO write pointer */
2167 fifo_idx = (fifo_idx + 1) & 3;
2168
2169 /* Check destination code (CD0-CD3) */
2170 switch (code & 0x0F)
2171 {
2172 case 0x01: /* VRAM */
2173 {
2174 /* VRAM address */
2175 int index = addr & 0xFFFE;
2176
2177 /* Pointer to VRAM */
2178 uint16 *p = (uint16 *)&vram[index];
2179
2180 /* Byte-swap data if A0 is set */
2181 if (addr & 1)
2182 {
2183 data = ((data >> 8) | (data << 8)) & 0xFFFF;
2184 }
2185
2186 /* Intercept writes to Sprite Attribute Table */
2187 if ((index & sat_base_mask) == satb)
2188 {
2189 /* Update internal SAT */
2190 *(uint16 *) &sat[index & sat_addr_mask] = data;
2191 }
2192
2193 /* Only write unique data to VRAM */
2194 if (data != *p)
2195 {
2196 int name;
2197
2198 /* Write data to VRAM */
2199 *p = data;
2200
2201 /* Update pattern cache */
2202 MARK_BG_DIRTY (index);
2203 }
2204
2205 #ifdef LOGVDP
2206 error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2207 #endif
2208 break;
2209 }
2210
2211 case 0x03: /* CRAM */
2212 {
2213 /* Pointer to CRAM 9-bit word */
2214 uint16 *p = (uint16 *)&cram[addr & 0x7E];
2215
2216 /* Pack 16-bit bus data (BBB0GGG0RRR0) to 9-bit CRAM data (BBBGGGRRR) */
2217 data = ((data & 0xE00) >> 3) | ((data & 0x0E0) >> 2) | ((data & 0x00E) >> 1);
2218
2219 /* Check if CRAM data is being modified */
2220 if (data != *p)
2221 {
2222 /* CRAM index (64 words) */
2223 int index = (addr >> 1) & 0x3F;
2224
2225 /* Write CRAM data */
2226 *p = data;
2227
2228 /* Color entry 0 of each palette is never displayed (transparent pixel) */
2229 if (index & 0x0F)
2230 {
2231 /* Update color palette */
2232 color_update_m5(index, data);
2233 }
2234
2235 /* Update backdrop color */
2236 if (index == border)
2237 {
2238 color_update_m5(0x00, data);
2239 }
2240
2241 /* CRAM modified during HBLANK (Striker, Zero the Kamikaze, etc) */
2242 if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (m68k.cycles <= (mcycles_vdp + 860)))
2243 {
2244 /* Remap current line */
2245 remap_line(v_counter);
2246 }
2247 }
2248 #ifdef LOGVDP
2249 error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2250 #endif
2251 break;
2252 }
2253
2254 case 0x05: /* VSRAM */
2255 {
2256 *(uint16 *)&vsram[addr & 0x7E] = data;
2257
2258 /* 2-cell Vscroll mode */
2259 if (reg[11] & 0x04)
2260 {
2261 /* VSRAM writes during HBLANK (Adventures of Batman & Robin) */
2262 if ((v_counter < bitmap.viewport.h) && (reg[1] & 0x40) && (m68k.cycles <= (mcycles_vdp + 860)))
2263 {
2264 /* Redraw entire line */
2265 render_line(v_counter);
2266 }
2267 }
2268 #ifdef LOGVDP
2269 error("[%d(%d)][%d(%d)] VSRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2270 #endif
2271 break;
2272 }
2273
2274 default:
2275 {
2276 /* add some delay until 68k periodical wait-states are accurately emulated ("Clue", "Microcosm") */
2277 m68k.cycles += 2;
2278 #ifdef LOGERROR
2279 error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, code, addr, data, m68k_get_reg(M68K_REG_PC));
2280 #endif
2281 break;
2282 }
2283 }
2284
2285 /* Increment address register */
2286 addr += reg[15];
2287 }
2288
2289
2290 /*--------------------------------------------------------------------------*/
2291 /* 68k bus interface (Mega Drive VDP only) */
2292 /*--------------------------------------------------------------------------*/
2293
vdp_68k_data_w_m4(unsigned int data)2294 static void vdp_68k_data_w_m4(unsigned int data)
2295 {
2296 /* Clear pending flag */
2297 pending = 0;
2298
2299 /* Restricted VDP writes during active display */
2300 if (!(status & 8) && (reg[1] & 0x40))
2301 {
2302 /* Update VDP FIFO */
2303 vdp_fifo_update(m68k.cycles);
2304
2305 /* Clear FIFO empty flag */
2306 status &= 0xFDFF;
2307
2308 /* up to 4 words can be stored */
2309 if (fifo_write_cnt < 4)
2310 {
2311 /* Increment FIFO counter */
2312 fifo_write_cnt++;
2313
2314 /* Set FIFO full flag if 4 words are stored */
2315 status |= ((fifo_write_cnt & 4) << 6);
2316 }
2317 else
2318 {
2319 /* CPU is halted until next FIFO entry processing */
2320 m68k.cycles = fifo_cycles;
2321
2322 /* Update FIFO access slot counter */
2323 fifo_slots += (fifo_byte_access + 1);
2324 }
2325 }
2326
2327 /* Check destination code */
2328 if (code & 0x02)
2329 {
2330 /* CRAM index (32 words) */
2331 int index = addr & 0x1F;
2332
2333 /* Pointer to CRAM 9-bit word */
2334 uint16 *p = (uint16 *)&cram[index << 1];
2335
2336 /* Pack 16-bit data (xxx000BBGGRR) to 9-bit CRAM data (xxxBBGGRR) */
2337 data = ((data & 0xE00) >> 3) | (data & 0x3F);
2338
2339 /* Check if CRAM data is being modified */
2340 if (data != *p)
2341 {
2342 /* Write CRAM data */
2343 *p = data;
2344
2345 /* Update color palette */
2346 color_update_m4(index, data);
2347
2348 /* Update backdrop color */
2349 if (index == (0x10 | (border & 0x0F)))
2350 {
2351 color_update_m4(0x40, data);
2352 }
2353 }
2354 }
2355 else
2356 {
2357 /* VRAM address (interleaved format) */
2358 int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00);
2359
2360 /* Pointer to VRAM */
2361 uint16 *p = (uint16 *)&vram[index];
2362
2363 /* Byte-swap data if A0 is set */
2364 if (addr & 1)
2365 {
2366 data = ((data >> 8) | (data << 8)) & 0xFFFF;
2367 }
2368
2369 /* Only write unique data to VRAM */
2370 if (data != *p)
2371 {
2372 int name;
2373
2374 /* Write data to VRAM */
2375 *p = data;
2376
2377 /* Update the pattern cache */
2378 MARK_BG_DIRTY (index);
2379 }
2380 }
2381
2382 /* Increment address register (TODO: check how address is incremented in Mode 4) */
2383 addr += (reg[15] + 1);
2384 }
2385
vdp_68k_data_w_m5(unsigned int data)2386 static void vdp_68k_data_w_m5(unsigned int data)
2387 {
2388 /* Clear pending flag */
2389 pending = 0;
2390
2391 /* Restricted VDP writes during active display */
2392 if (!(status & 8) && (reg[1] & 0x40))
2393 {
2394 /* Update VDP FIFO */
2395 vdp_fifo_update(m68k.cycles);
2396
2397 /* Clear FIFO empty flag */
2398 status &= 0xFDFF;
2399
2400 /* up to 4 words can be stored */
2401 if (fifo_write_cnt < 4)
2402 {
2403 /* Increment FIFO counter */
2404 fifo_write_cnt++;
2405
2406 /* Set FIFO full flag if 4 words are stored */
2407 status |= ((fifo_write_cnt & 4) << 6);
2408 }
2409 else
2410 {
2411 /* CPU is halted until next FIFO entry processing (Chaos Engine / Soldiers of Fortune, Double Clutch, Titan Overdrive Demo) */
2412 m68k.cycles = fifo_cycles;
2413
2414 /* Update FIFO access slot counter */
2415 fifo_slots += (fifo_byte_access + 1);
2416 }
2417 }
2418
2419 /* Write data */
2420 vdp_bus_w(data);
2421
2422 /* Check if DMA Fill is pending */
2423 if (dmafill)
2424 {
2425 /* Clear DMA Fill pending flag */
2426 dmafill = 0;
2427
2428 /* DMA length */
2429 dma_length = (reg[20] << 8) | reg[19];
2430
2431 /* Zero DMA length (pre-decrementing counter) */
2432 if (!dma_length)
2433 {
2434 dma_length = 0x10000;
2435 }
2436
2437 /* Trigger DMA */
2438 vdp_dma_update(m68k.cycles);
2439 }
2440 }
2441
vdp_68k_data_r_m4(void)2442 static unsigned int vdp_68k_data_r_m4(void)
2443 {
2444 /* VRAM address (interleaved format) */
2445 int index = ((addr << 1) & 0x3FC) | ((addr & 0x200) >> 8) | (addr & 0x3C00);
2446
2447 /* Clear pending flag */
2448 pending = 0;
2449
2450 /* Increment address register (TODO: check how address is incremented in Mode 4) */
2451 addr += (reg[15] + 1);
2452
2453 /* Read VRAM data */
2454 return *(uint16 *) &vram[index];
2455 }
2456
vdp_68k_data_r_m5(void)2457 static unsigned int vdp_68k_data_r_m5(void)
2458 {
2459 uint16 data = 0;
2460
2461 /* Clear pending flag */
2462 pending = 0;
2463
2464 /* Check destination code (CD0-CD3) & CD4 */
2465 switch (code & 0x1F)
2466 {
2467 case 0x00:
2468 {
2469 /* read two bytes from VRAM */
2470 data = *(uint16 *)&vram[addr & 0xFFFE];
2471
2472 #ifdef LOGVDP
2473 error("[%d(%d)][%d(%d)] VRAM 0x%x read -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2474 #endif
2475 break;
2476 }
2477
2478 case 0x04:
2479 {
2480 /* VSRAM index */
2481 int index = addr & 0x7E;
2482
2483 /* Check against VSRAM max size (80 x 11-bits) */
2484 if (index >= 0x50)
2485 {
2486 /* Wrap to address 0 (TODO: check if still true with Genesis 3 model) */
2487 index = 0;
2488 }
2489
2490 /* Read 11-bit word from VSRAM */
2491 data = *(uint16 *)&vsram[index] & 0x7FF;
2492
2493 /* Unused bits are set using data from next available FIFO entry */
2494 data |= (fifo[fifo_idx] & ~0x7FF);
2495
2496 #ifdef LOGVDP
2497 error("[%d(%d)][%d(%d)] VSRAM 0x%x read -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2498 #endif
2499 break;
2500 }
2501
2502 case 0x08:
2503 {
2504 /* Read 9-bit word from CRAM */
2505 data = *(uint16 *)&cram[addr & 0x7E];
2506
2507 /* Unpack 9-bit CRAM data (BBBGGGRRR) to 16-bit bus data (BBB0GGG0RRR0) */
2508 data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1);
2509
2510 /* Unused bits are set using data from next available FIFO entry */
2511 data |= (fifo[fifo_idx] & ~0xEEE);
2512
2513 #ifdef LOGVDP
2514 error("[%d(%d)][%d(%d)] CRAM 0x%x read -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2515 #endif
2516 break;
2517 }
2518
2519 case 0x0c: /* undocumented 8-bit VRAM read */
2520 {
2521 /* Read one byte from VRAM adjacent address */
2522 data = READ_BYTE(vram, addr ^ 1);
2523
2524 /* Unused bits are set using data from next available FIFO entry */
2525 data |= (fifo[fifo_idx] & ~0xFF);
2526
2527 #ifdef LOGVDP
2528 error("[%d(%d)][%d(%d)] 8-bit VRAM 0x%x read -> 0x%x (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, addr, data, m68k_get_reg(M68K_REG_PC));
2529 #endif
2530 break;
2531 }
2532
2533 default:
2534 {
2535 /* Invalid code value (normally locks VDP, hard reset required) */
2536 #ifdef LOGERROR
2537 error("[%d(%d)][%d(%d)] Invalid (%d) 0x%x read (%x)\n", v_counter, (v_counter + (m68k.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, m68k.cycles, m68k.cycles%MCYCLES_PER_LINE, code, addr, m68k_get_reg(M68K_REG_PC));
2538 #endif
2539 break;
2540 }
2541 }
2542
2543 /* Increment address register */
2544 addr += reg[15];
2545
2546 /* Return data */
2547 return data;
2548 }
2549
2550
2551 /*--------------------------------------------------------------------------*/
2552 /* Z80 bus interface (Mega Drive VDP in Master System compatibility mode) */
2553 /*--------------------------------------------------------------------------*/
2554
vdp_z80_data_w_m4(unsigned int data)2555 static void vdp_z80_data_w_m4(unsigned int data)
2556 {
2557 /* Clear pending flag */
2558 pending = 0;
2559
2560 /* Check destination code */
2561 if (code & 0x02)
2562 {
2563 /* CRAM index (32 words) */
2564 int index = addr & 0x1F;
2565
2566 /* Pointer to CRAM word */
2567 uint16 *p = (uint16 *)&cram[index << 1];
2568
2569 /* Check if CRAM data is being modified */
2570 if (data != *p)
2571 {
2572 /* Write CRAM data */
2573 *p = data;
2574
2575 /* Update color palette */
2576 color_update_m4(index, data);
2577
2578 /* Update backdrop color */
2579 if (index == (0x10 | (border & 0x0F)))
2580 {
2581 color_update_m4(0x40, data);
2582 }
2583 }
2584 }
2585 else
2586 {
2587 /* VRAM address */
2588 int index = addr & 0x3FFF;
2589
2590 /* Only write unique data to VRAM */
2591 if (data != vram[index])
2592 {
2593 int name;
2594
2595 /* Write data */
2596 vram[index] = data;
2597
2598 /* Update pattern cache */
2599 MARK_BG_DIRTY(index);
2600 }
2601 }
2602
2603 /* Increment address register (TODO: check how address is incremented in Mode 4) */
2604 addr += (reg[15] + 1);
2605 }
2606
vdp_z80_data_w_m5(unsigned int data)2607 static void vdp_z80_data_w_m5(unsigned int data)
2608 {
2609 /* Clear pending flag */
2610 pending = 0;
2611
2612 /* Push byte into FIFO */
2613 fifo[fifo_idx] = data << 8;
2614 fifo_idx = (fifo_idx + 1) & 3;
2615
2616 /* Check destination code (CD0-CD3) */
2617 switch (code & 0x0F)
2618 {
2619 case 0x01: /* VRAM */
2620 {
2621 /* VRAM address (write low byte to even address & high byte to odd address) */
2622 int index = addr ^ 1;
2623
2624 /* Intercept writes to Sprite Attribute Table */
2625 if ((index & sat_base_mask) == satb)
2626 {
2627 /* Update internal SAT */
2628 WRITE_BYTE(sat, index & sat_addr_mask, data);
2629 }
2630
2631 /* Only write unique data to VRAM */
2632 if (data != READ_BYTE(vram, index))
2633 {
2634 int name;
2635
2636 /* Write data */
2637 WRITE_BYTE(vram, index, data);
2638
2639 /* Update pattern cache */
2640 MARK_BG_DIRTY (index);
2641 }
2642 break;
2643 }
2644
2645 case 0x03: /* CRAM */
2646 {
2647 /* Pointer to CRAM word */
2648 uint16 *p = (uint16 *)&cram[addr & 0x7E];
2649
2650 /* Pack 8-bit value into 9-bit CRAM data */
2651 if (addr & 1)
2652 {
2653 /* Write high byte (0000BBB0 -> BBBxxxxxx) */
2654 data = (*p & 0x3F) | ((data & 0x0E) << 5);
2655 }
2656 else
2657 {
2658 /* Write low byte (GGG0RRR0 -> xxxGGGRRR) */
2659 data = (*p & 0x1C0) | ((data & 0x0E) >> 1)| ((data & 0xE0) >> 2);
2660 }
2661
2662 /* Check if CRAM data is being modified */
2663 if (data != *p)
2664 {
2665 /* CRAM index (64 words) */
2666 int index = (addr >> 1) & 0x3F;
2667
2668 /* Write CRAM data */
2669 *p = data;
2670
2671 /* Color entry 0 of each palette is never displayed (transparent pixel) */
2672 if (index & 0x0F)
2673 {
2674 /* Update color palette */
2675 color_update_m5(index, data);
2676 }
2677
2678 /* Update backdrop color */
2679 if (index == border)
2680 {
2681 color_update_m5(0x00, data);
2682 }
2683 }
2684 break;
2685 }
2686
2687 case 0x05: /* VSRAM */
2688 {
2689 /* Write low byte to even address & high byte to odd address */
2690 WRITE_BYTE(vsram, (addr & 0x7F) ^ 1, data);
2691 break;
2692 }
2693 }
2694
2695 /* Increment address register */
2696 addr += reg[15];
2697
2698 /* Check if DMA Fill is pending */
2699 if (dmafill)
2700 {
2701 /* Clear DMA Fill pending flag */
2702 dmafill = 0;
2703
2704 /* DMA length */
2705 dma_length = (reg[20] << 8) | reg[19];
2706
2707 /* Zero DMA length (pre-decrementing counter) */
2708 if (!dma_length)
2709 {
2710 dma_length = 0x10000;
2711 }
2712
2713 /* Trigger DMA */
2714 vdp_dma_update(Z80.cycles);
2715 }
2716 }
2717
vdp_z80_data_r_m4(void)2718 static unsigned int vdp_z80_data_r_m4(void)
2719 {
2720 /* Read buffer */
2721 unsigned int data = fifo[0];
2722
2723 /* Clear pending flag */
2724 pending = 0;
2725
2726 /* Process next read */
2727 fifo[0] = vram[addr & 0x3FFF];
2728
2729 /* Increment address register (TODO: check how address is incremented with Mega Drive VDP in Mode 4) */
2730 addr += (reg[15] + 1);
2731
2732 /* Return data */
2733 return data;
2734 }
2735
vdp_z80_data_r_m5(void)2736 static unsigned int vdp_z80_data_r_m5(void)
2737 {
2738 unsigned int data = 0;
2739
2740 /* Clear pending flag */
2741 pending = 0;
2742
2743 /* Check destination code (CD0-CD3) & CD4 */
2744 switch (code & 0x1F)
2745 {
2746 case 0x00: /* VRAM */
2747 {
2748 /* Return low byte from even address & high byte from odd address */
2749 data = READ_BYTE(vram, addr ^ 1);
2750 break;
2751 }
2752
2753 case 0x04: /* VSRAM */
2754 {
2755 /* Return low byte from even address & high byte from odd address */
2756 data = READ_BYTE(vsram, (addr & 0x7F) ^ 1);
2757 break;
2758 }
2759
2760 case 0x08: /* CRAM */
2761 {
2762 /* Read CRAM data */
2763 data = *(uint16 *)&cram[addr & 0x7E];
2764
2765 /* Unpack 9-bit CRAM data (BBBGGGRRR) to 16-bit data (BBB0GGG0RRR0) */
2766 data = ((data & 0x1C0) << 3) | ((data & 0x038) << 2) | ((data & 0x007) << 1);
2767
2768 /* Return low byte from even address & high byte from odd address */
2769 if (addr & 1)
2770 {
2771 data = data >> 8;
2772 }
2773
2774 data &= 0xFF;
2775 break;
2776 }
2777 }
2778
2779 /* Increment address register */
2780 addr += reg[15];
2781
2782 /* Return data */
2783 return data;
2784 }
2785
2786
2787 /*-----------------------------------------------------------------------------*/
2788 /* Z80 bus interface (Master System, Game Gear & SG-1000 VDP) */
2789 /*-----------------------------------------------------------------------------*/
2790
vdp_z80_data_w_ms(unsigned int data)2791 static void vdp_z80_data_w_ms(unsigned int data)
2792 {
2793 /* Clear pending flag */
2794 pending = 0;
2795
2796 if (code < 3)
2797 {
2798 int index;
2799
2800 /* Check if we are already on next line */
2801 if ((Z80.cycles - mcycles_vdp) >= MCYCLES_PER_LINE)
2802 {
2803 /* update line counter */
2804 int line = (v_counter + 1) % lines_per_frame;
2805
2806 /* check if we are within active display range */
2807 if ((line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special & HW_3D_GLASSES))
2808 {
2809 /* update VCounter to indicate next line has already been rendered */
2810 v_counter = line;
2811
2812 /* render next line */
2813 render_line(line);
2814 }
2815 }
2816
2817 /* VRAM address */
2818 index = addr & 0x3FFF;
2819
2820 /* VRAM write */
2821 if (data != vram[index])
2822 {
2823 int name;
2824 vram[index] = data;
2825 MARK_BG_DIRTY(index);
2826 }
2827
2828 #ifdef LOGVDP
2829 error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (Z80.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l);
2830 #endif
2831 }
2832 else
2833 {
2834 /* CRAM address */
2835 int index = addr & 0x1F;
2836
2837 /* Pointer to CRAM word */
2838 uint16 *p = (uint16 *)&cram[index << 1];
2839
2840 /* Check if CRAM data is being modified */
2841 if (data != *p)
2842 {
2843 /* Write CRAM data */
2844 *p = data;
2845
2846 /* Update color palette */
2847 color_update_m4(index, data);
2848
2849 /* Update backdrop color */
2850 if (index == (0x10 | (border & 0x0F)))
2851 {
2852 color_update_m4(0x40, data);
2853 }
2854 }
2855 #ifdef LOGVDP
2856 error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (Z80.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l);
2857 #endif
2858 }
2859
2860 /* Update read buffer */
2861 fifo[0] = data;
2862
2863 /* Update address register */
2864 addr++;
2865 }
2866
vdp_z80_data_w_gg(unsigned int data)2867 static void vdp_z80_data_w_gg(unsigned int data)
2868 {
2869 /* Clear pending flag */
2870 pending = 0;
2871
2872 if (code < 3)
2873 {
2874 int index;
2875
2876 /* Check if we are already on next line */
2877 if ((Z80.cycles - mcycles_vdp) >= MCYCLES_PER_LINE)
2878 {
2879 /* update line counter */
2880 int line = (v_counter + 1) % lines_per_frame;
2881
2882 /* check if we are within active display range */
2883 if ((line < bitmap.viewport.h) && !(work_ram[0x1ffb] & cart.special & HW_3D_GLASSES))
2884 {
2885 /* update VCounter to indicate next line has already been rendered */
2886 v_counter = line;
2887
2888 /* render next line */
2889 render_line(line);
2890 }
2891 }
2892
2893 /* VRAM address */
2894 index = addr & 0x3FFF;
2895
2896 /* VRAM write */
2897 if (data != vram[index])
2898 {
2899 int name;
2900 vram[index] = data;
2901 MARK_BG_DIRTY(index);
2902 }
2903 #ifdef LOGVDP
2904 error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (Z80.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l);
2905 #endif
2906 }
2907 else
2908 {
2909 if (addr & 1)
2910 {
2911 /* Pointer to CRAM word */
2912 uint16 *p = (uint16 *)&cram[addr & 0x3E];
2913
2914 /* 12-bit data word */
2915 data = (data << 8) | cached_write;
2916
2917 /* Check if CRAM data is being modified */
2918 if (data != *p)
2919 {
2920 /* Color index (0-31) */
2921 int index = (addr >> 1) & 0x1F;
2922
2923 /* Write CRAM data */
2924 *p = data;
2925
2926 /* Update color palette */
2927 color_update_m4(index, data);
2928
2929 /* Update backdrop color */
2930 if (index == (0x10 | (border & 0x0F)))
2931 {
2932 color_update_m4(0x40, data);
2933 }
2934 }
2935 }
2936 else
2937 {
2938 /* Latch LSB */
2939 cached_write = data;
2940 }
2941 #ifdef LOGVDP
2942 error("[%d(%d)][%d(%d)] CRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (Z80.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, addr, data, Z80.pc.w.l);
2943 #endif
2944 }
2945
2946 /* Update read buffer */
2947 fifo[0] = data;
2948
2949 /* Update address register */
2950 addr++;
2951 }
2952
vdp_z80_data_w_sg(unsigned int data)2953 static void vdp_z80_data_w_sg(unsigned int data)
2954 {
2955 /* VRAM address */
2956 int index = addr & 0x3FFF;
2957
2958 /* Clear pending flag */
2959 pending = 0;
2960
2961 /* VRAM write */
2962 vram[index] = data;
2963
2964 /* Update address register */
2965 addr++;
2966
2967 #ifdef LOGVDP
2968 error("[%d(%d)][%d(%d)] VRAM 0x%x write -> 0x%x (%x)\n", v_counter, (v_counter + (Z80.cycles - mcycles_vdp)/MCYCLES_PER_LINE)%lines_per_frame, Z80.cycles, Z80.cycles%MCYCLES_PER_LINE, index, data, Z80.pc.w.l);
2969 #endif
2970 }
2971
2972 /*--------------------------------------------------------------------------*/
2973 /* DMA operations (Mega Drive VDP only) */
2974 /*--------------------------------------------------------------------------*/
2975
2976 /* DMA from 68K bus: $000000-$7FFFFF (external area) */
vdp_dma_68k_ext(unsigned int length)2977 static void vdp_dma_68k_ext(unsigned int length)
2978 {
2979 uint16 data;
2980
2981 /* 68k bus source address */
2982 uint32 source = (reg[23] << 17) | (dma_src << 1);
2983
2984 do
2985 {
2986 /* Read data word from 68k bus */
2987 if (m68k.memory_map[source>>16].read16)
2988 {
2989 data = m68k.memory_map[source>>16].read16(source);
2990 }
2991 else
2992 {
2993 data = *(uint16 *)(m68k.memory_map[source>>16].base + (source & 0xFFFF));
2994 }
2995
2996 /* Increment source address */
2997 source += 2;
2998
2999 /* 128k DMA window */
3000 source = (reg[23] << 17) | (source & 0x1FFFF);
3001
3002 /* Write data word to VRAM, CRAM or VSRAM */
3003 vdp_bus_w(data);
3004 }
3005 while (--length);
3006
3007 /* Update DMA source address */
3008 dma_src = (source >> 1) & 0xffff;
3009 }
3010
3011 /* DMA from 68K bus: $800000-$FFFFFF (internal area) except I/O area */
vdp_dma_68k_ram(unsigned int length)3012 static void vdp_dma_68k_ram(unsigned int length)
3013 {
3014 uint16 data;
3015
3016 /* 68k bus source address */
3017 uint32 source = (reg[23] << 17) | (dma_src << 1);
3018
3019 do
3020 {
3021 /* access Work-RAM by default */
3022 data = *(uint16 *)(work_ram + (source & 0xFFFF));
3023
3024 /* Increment source address */
3025 source += 2;
3026
3027 /* 128k DMA window */
3028 source = (reg[23] << 17) | (source & 0x1FFFF);
3029
3030 /* Write data word to VRAM, CRAM or VSRAM */
3031 vdp_bus_w(data);
3032 }
3033 while (--length);
3034
3035 /* Update DMA source address */
3036 dma_src = (source >> 1) & 0xffff;
3037 }
3038
3039 /* DMA from 68K bus: $A00000-$A1FFFF (I/O area) specific */
vdp_dma_68k_io(unsigned int length)3040 static void vdp_dma_68k_io(unsigned int length)
3041 {
3042 uint16 data;
3043
3044 /* 68k bus source address */
3045 uint32 source = (reg[23] << 17) | (dma_src << 1);
3046
3047 do
3048 {
3049 /* Z80 area */
3050 if (source <= 0xA0FFFF)
3051 {
3052 /* Return $FFFF only when the Z80 isn't hogging the Z-bus.
3053 (e.g. Z80 isn't reset and 68000 has the bus) */
3054 data = ((zstate ^ 3) ? *(uint16 *)(work_ram + (source & 0xFFFF)) : 0xFFFF);
3055 }
3056
3057 /* The I/O chip and work RAM try to drive the data bus which results
3058 in both values being combined in random ways when read.
3059 We return the I/O chip values which seem to have precedence, */
3060 else if (source <= 0xA1001F)
3061 {
3062 data = io_68k_read((source >> 1) & 0x0F);
3063 data = (data << 8 | data);
3064 }
3065
3066 /* All remaining locations access work RAM */
3067 else
3068 {
3069 data = *(uint16 *)(work_ram + (source & 0xFFFF));
3070 }
3071
3072 /* Increment source address */
3073 source += 2;
3074
3075 /* 128k DMA window */
3076 source = (reg[23] << 17) | (source & 0x1FFFF);
3077
3078 /* Write data to VRAM, CRAM or VSRAM */
3079 vdp_bus_w(data);
3080 }
3081 while (--length);
3082
3083 /* Update DMA source address */
3084 dma_src = (source >> 1) & 0xffff;
3085 }
3086
3087 /* VRAM Copy */
vdp_dma_copy(unsigned int length)3088 static void vdp_dma_copy(unsigned int length)
3089 {
3090 /* CD4 should be set (CD0-CD3 ignored) otherwise VDP locks (hard reset needed) */
3091 if (code & 0x10)
3092 {
3093 int name;
3094 uint8 data;
3095
3096 /* VRAM source address */
3097 uint16 source = dma_src;
3098
3099 do
3100 {
3101 /* Read byte from adjacent VRAM source address */
3102 data = READ_BYTE(vram, source ^ 1);
3103
3104 /* Intercept writes to Sprite Attribute Table */
3105 if ((addr & sat_base_mask) == satb)
3106 {
3107 /* Update internal SAT */
3108 WRITE_BYTE(sat, (addr & sat_addr_mask) ^ 1, data);
3109 }
3110
3111 /* Write byte to adjacent VRAM destination address */
3112 WRITE_BYTE(vram, addr ^ 1, data);
3113
3114 /* Update pattern cache */
3115 MARK_BG_DIRTY(addr);
3116
3117 /* Increment VRAM source address */
3118 source++;
3119
3120 /* Increment VRAM destination address */
3121 addr += reg[15];
3122 }
3123 while (--length);
3124
3125 /* Update DMA source address */
3126 dma_src = source;
3127 }
3128 }
3129
3130 /* DMA Fill */
vdp_dma_fill(unsigned int length)3131 static void vdp_dma_fill(unsigned int length)
3132 {
3133 /* Check destination code (CD0-CD3) */
3134 switch (code & 0x0F)
3135 {
3136 case 0x01: /* VRAM */
3137 {
3138 int name;
3139
3140 /* Get source data from last written FIFO entry */
3141 uint8 data = fifo[(fifo_idx+3)&3] >> 8;
3142
3143 do
3144 {
3145 /* Intercept writes to Sprite Attribute Table */
3146 if ((addr & sat_base_mask) == satb)
3147 {
3148 /* Update internal SAT */
3149 WRITE_BYTE(sat, (addr & sat_addr_mask) ^ 1, data);
3150 }
3151
3152 /* Write byte to adjacent VRAM address */
3153 WRITE_BYTE(vram, addr ^ 1, data);
3154
3155 /* Update pattern cache */
3156 MARK_BG_DIRTY (addr);
3157
3158 /* Increment VRAM address */
3159 addr += reg[15];
3160 }
3161 while (--length);
3162 break;
3163 }
3164
3165 case 0x03: /* CRAM */
3166 {
3167 /* Get source data from next available FIFO entry */
3168 uint16 data = fifo[fifo_idx];
3169
3170 /* Pack 16-bit bus data (BBB0GGG0RRR0) to 9-bit CRAM data (BBBGGGRRR) */
3171 data = ((data & 0xE00) >> 3) | ((data & 0x0E0) >> 2) | ((data & 0x00E) >> 1);
3172
3173 do
3174 {
3175 /* Pointer to CRAM 9-bit word */
3176 uint16 *p = (uint16 *)&cram[addr & 0x7E];
3177
3178 /* Check if CRAM data is being modified */
3179 if (data != *p)
3180 {
3181 /* CRAM index (64 words) */
3182 int index = (addr >> 1) & 0x3F;
3183
3184 /* Write CRAM data */
3185 *p = data;
3186
3187 /* Color entry 0 of each palette is never displayed (transparent pixel) */
3188 if (index & 0x0F)
3189 {
3190 /* Update color palette */
3191 color_update_m5(index, data);
3192 }
3193
3194 /* Update backdrop color */
3195 if (index == border)
3196 {
3197 color_update_m5(0x00, data);
3198 }
3199 }
3200
3201 /* Increment CRAM address */
3202 addr += reg[15];
3203 }
3204 while (--length);
3205 break;
3206 }
3207
3208 case 0x05: /* VSRAM */
3209 {
3210 /* Get source data from next available FIFO entry */
3211 uint16 data = fifo[fifo_idx];
3212
3213 do
3214 {
3215 /* Write VSRAM data */
3216 *(uint16 *)&vsram[addr & 0x7E] = data;
3217
3218 /* Increment VSRAM address */
3219 addr += reg[15];
3220 }
3221 while (--length);
3222 break;
3223 }
3224
3225 default:
3226 {
3227 /* invalid destination does nothing (Williams Greatest Hits after soft reset) */
3228
3229 /* address is still incremented */
3230 addr += reg[15] * length;
3231 }
3232 }
3233 }
3234
vdp_set_all_vram(const uint8 * src)3235 static void vdp_set_all_vram(const uint8 *src)
3236 {
3237 /* Copies entire vram area from a savestate, and updates the dirty tile flags */
3238 int name = 0;
3239 int addr = 0;
3240
3241 for (addr = 0; addr < sizeof(vram); addr += 32)
3242 {
3243 if (0 != memcmp(vram + addr, src + addr, 32))
3244 {
3245 name = addr >> 5;
3246 if (bg_name_dirty[name] == 0)
3247 {
3248 bg_name_list[bg_list_index++] = name;
3249 }
3250 bg_name_dirty[name] |= 0xFF;
3251 memcpy(vram + addr, src + addr, 32);
3252 }
3253 }
3254 }
3255