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