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