~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to src/mame/machine/megavdp.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Emmanuel Kasper, Jordi Mallach
  • Date: 2012-06-05 20:02:23 UTC
  • mfrom: (0.3.1) (0.1.4)
  • Revision ID: package-import@ubuntu.com-20120605200223-gnlpogjrg6oqe9md
Tags: 0.146-1
[ Emmanuel Kasper ]
* New upstream release
* Drop patch to fix man pages section and patches to link with flac 
  and jpeg system lib: all this has been pushed upstream by Cesare Falco
* Add DM-Upload-Allowed: yes field.

[ Jordi Mallach ]
* Create a "gnu" TARGETOS stanza that defines NO_AFFINITY_NP.
* Stop setting TARGETOS to "unix" in d/rules. It should be autodetected,
  and set to the appropriate value.
* mame_manpage_section.patch: Change mame's manpage section to 6 (games),
  in the TH declaration.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Megadrive VDP */
 
2
 
 
3
 
 
4
#include "includes/megadriv.h"
 
5
 
 
6
 
 
7
 
 
8
int megadrive_visible_scanlines;
 
9
int megadrive_irq6_scanline;
 
10
int megadrive_z80irq_scanline;
 
11
int megadrive_imode = 0;
 
12
int megadriv_framerate;
 
13
int megadrive_total_scanlines;
 
14
int megadrive_vblank_flag = 0;
 
15
int genesis_scanline_counter = 0;
 
16
int megadrive_irq6_pending = 0;
 
17
int megadrive_irq4_pending = 0;
 
18
 
 
19
static int irq4counter;
 
20
 
 
21
static int megadrive_imode_odd_frame = 0;
 
22
 
 
23
int segac2_bg_pal_lookup[4];
 
24
int segac2_sp_pal_lookup[4];
 
25
 
 
26
// hacks for C2
 
27
int genvdp_use_cram = 0; // c2 uses it's own palette ram
 
28
int genesis_always_irq6 = 0; // c2 never enables the irq6, different source??
 
29
int genesis_other_hacks = 0; // misc hacks
 
30
 
 
31
 
 
32
 
 
33
static UINT8* sprite_renderline;
 
34
static UINT8* highpri_renderline;
 
35
static UINT32* video_renderline;
 
36
UINT16* megadrive_vdp_palette_lookup;
 
37
UINT16* megadrive_vdp_palette_lookup_sprite; // for C2
 
38
UINT16* megadrive_vdp_palette_lookup_shadow;
 
39
UINT16* megadrive_vdp_palette_lookup_highlight;
 
40
UINT16* megadrive_ram;
 
41
static UINT8 megadrive_vram_fill_pending = 0;
 
42
static UINT16 megadrive_vram_fill_length = 0;
 
43
static int megadrive_sprite_collision = 0;
 
44
static int megadrive_max_hposition;
 
45
int megadrive_region_export;
 
46
int megadrive_region_pal;
 
47
 
 
48
 
 
49
 
 
50
 
 
51
/*  The VDP occupies addresses C00000h to C0001Fh.
 
52
 
 
53
 C00000h    -   Data port (8=r/w, 16=r/w)
 
54
 C00002h    -   Data port (mirror)
 
55
 C00004h    -   Control port (8=r/w, 16=r/w)
 
56
 C00006h    -   Control port (mirror)
 
57
 C00008h    -   HV counter (8/16=r/o)
 
58
 C0000Ah    -   HV counter (mirror)
 
59
 C0000Ch    -   HV counter (mirror)
 
60
 C0000Eh    -   HV counter (mirror)
 
61
 C00011h    -   SN76489 PSG (8=w/o)
 
62
 C00013h    -   SN76489 PSG (mirror)
 
63
 C00015h    -   SN76489 PSG (mirror)
 
64
 C00017h    -   SN76489 PSG (mirror)
 
65
*/
 
66
 
 
67
#define MEGADRIV_VDP_VRAM(address) megadrive_vdp_vram[(address)&0x7fff]
 
68
 
 
69
 
 
70
 
 
71
static int megadrive_vdp_command_pending; // 2nd half of command pending..
 
72
static UINT16 megadrive_vdp_command_part1;
 
73
static UINT16 megadrive_vdp_command_part2;
 
74
static UINT8  megadrive_vdp_code;
 
75
static UINT16 megadrive_vdp_address;
 
76
static UINT16 megadrive_vdp_register[0x20];
 
77
static UINT16* megadrive_vdp_vram;
 
78
static UINT16* megadrive_vdp_cram;
 
79
static UINT16* megadrive_vdp_vsram;
 
80
/* The VDP keeps a 0x400 byte on-chip cache of the Sprite Attribute Table
 
81
   to speed up processing */
 
82
static UINT16* megadrive_vdp_internal_sprite_attribute_table;
 
83
 
 
84
/*
 
85
 
 
86
 $00 - Mode Set Register No. 1
 
87
 -----------------------------
 
88
 
 
89
 d7 - No effect
 
90
 d6 - No effect
 
91
 d5 - No effect
 
92
 d4 - IE1 (Horizontal interrupt enable)
 
93
 d3 - 1= Invalid display setting
 
94
 d2 - Palette select
 
95
 d1 - M3 (HV counter latch enable)
 
96
 d0 - Display disable
 
97
 
 
98
 */
 
99
 
 
100
#define MEGADRIVE_REG0_UNUSED          ((megadrive_vdp_register[0x00]&0xc0)>>6)
 
101
#define MEGADRIVE_REG0_BLANK_LEFT      ((megadrive_vdp_register[0x00]&0x20)>>5) // like SMS, not used by any commercial games?
 
102
#define MEGADRIVE_REG0_IRQ4_ENABLE     ((megadrive_vdp_register[0x00]&0x10)>>4)
 
103
#define MEGADRIVE_REG0_INVALID_MODE    ((megadrive_vdp_register[0x00]&0x08)>>3) // invalid display mode, unhandled
 
104
#define MEGADRIVE_REG0_SPECIAL_PAL     ((megadrive_vdp_register[0x00]&0x04)>>2) // strange palette mode, unhandled
 
105
#define MEGADRIVE_REG0_HVLATCH_ENABLE  ((megadrive_vdp_register[0x00]&0x02)>>1) // HV Latch, used by lightgun games
 
106
#define MEGADRIVE_REG0_DISPLAY_DISABLE ((megadrive_vdp_register[0x00]&0x01)>>0)
 
107
 
 
108
/*
 
109
 
 
110
 $01 - Mode Set Register No. 2
 
111
 -----------------------------
 
112
 
 
113
 d7 - TMS9918 / Genesis display select
 
114
 d6 - DISP (Display Enable)
 
115
 d5 - IE0 (Vertical Interrupt Enable)
 
116
 d4 - M1 (DMA Enable)
 
117
 d3 - M2 (PAL / NTSC)
 
118
 d2 - SMS / Genesis display select
 
119
 d1 - 0 (No effect)
 
120
 d0 - 0 (See notes)
 
121
 
 
122
*/
 
123
 
 
124
#define MEGADRIVE_REG01_TMS9918_SELECT  ((megadrive_vdp_register[0x01]&0x80)>>7)
 
125
#define MEGADRIVE_REG01_DISP_ENABLE     ((megadrive_vdp_register[0x01]&0x40)>>6)
 
126
#define MEGADRIVE_REG01_IRQ6_ENABLE     ((megadrive_vdp_register[0x01]&0x20)>>5)
 
127
#define MEGADRIVE_REG01_DMA_ENABLE      ((megadrive_vdp_register[0x01]&0x10)>>4)
 
128
#define MEGADRIVE_REG01_240_LINE        ((megadrive_vdp_register[0x01]&0x08)>>3)
 
129
#define MEGADRIVE_REG01_SMS_SELECT      ((megadrive_vdp_register[0x01]&0x04)>>2)
 
130
#define MEGADRIVE_REG01_UNUSED          ((megadrive_vdp_register[0x01]&0x02)>>1)
 
131
#define MEGADRIVE_REG01_STRANGE_VIDEO   ((megadrive_vdp_register[0x01]&0x01)>>0) // unhandled, does strange things to the display
 
132
 
 
133
#define MEGADRIVE_REG02_UNUSED1         ((megadrive_vdp_register[0x02]&0xc0)>>6)
 
134
#define MEGADRIVE_REG02_PATTERN_ADDR_A  ((megadrive_vdp_register[0x02]&0x38)>>3)
 
135
#define MEGADRIVE_REG02_UNUSED2         ((megadrive_vdp_register[0x02]&0x07)>>0)
 
136
 
 
137
#define MEGADRIVE_REG03_UNUSED1         ((megadrive_vdp_register[0x03]&0xc0)>>6)
 
138
#define MEGADRIVE_REG03_PATTERN_ADDR_W  ((megadrive_vdp_register[0x03]&0x3e)>>1)
 
139
#define MEGADRIVE_REG03_UNUSED2         ((megadrive_vdp_register[0x03]&0x01)>>0)
 
140
 
 
141
#define MEGADRIVE_REG04_UNUSED          ((megadrive_vdp_register[0x04]&0xf8)>>3)
 
142
#define MEGADRIVE_REG04_PATTERN_ADDR_B  ((megadrive_vdp_register[0x04]&0x07)>>0)
 
143
 
 
144
#define MEGADRIVE_REG05_UNUSED          ((megadrive_vdp_register[0x05]&0x80)>>7)
 
145
#define MEGADRIVE_REG05_SPRITE_ADDR     ((megadrive_vdp_register[0x05]&0x7f)>>0)
 
146
 
 
147
/* 6? */
 
148
 
 
149
#define MEGADRIVE_REG07_UNUSED          ((megadrive_vdp_register[0x07]&0xc0)>>6)
 
150
#define MEGADRIVE_REG07_BGCOLOUR        ((megadrive_vdp_register[0x07]&0x3f)>>0)
 
151
 
 
152
/* 8? */
 
153
/* 9? */
 
154
 
 
155
#define MEGADRIVE_REG0A_HINT_VALUE      ((megadrive_vdp_register[0x0a]&0xff)>>0)
 
156
 
 
157
#define MEGADRIVE_REG0B_UNUSED          ((megadrive_vdp_register[0x0b]&0xf0)>>4)
 
158
#define MEGADRIVE_REG0B_IRQ2_ENABLE     ((megadrive_vdp_register[0x0b]&0x08)>>3)
 
159
#define MEGADRIVE_REG0B_VSCROLL_MODE    ((megadrive_vdp_register[0x0b]&0x04)>>2)
 
160
#define MEGADRIVE_REG0B_HSCROLL_MODE    ((megadrive_vdp_register[0x0b]&0x03)>>0)
 
161
 
 
162
#define MEGADRIVE_REG0C_RS0             ((megadrive_vdp_register[0x0c]&0x80)>>7)
 
163
#define MEGADRIVE_REG0C_UNUSED1         ((megadrive_vdp_register[0x0c]&0x40)>>6)
 
164
#define MEGADRIVE_REG0C_SPECIAL         ((megadrive_vdp_register[0x0c]&0x20)>>5)
 
165
#define MEGADRIVE_REG0C_UNUSED2         ((megadrive_vdp_register[0x0c]&0x10)>>4)
 
166
#define MEGADRIVE_REG0C_SHADOW_HIGLIGHT ((megadrive_vdp_register[0x0c]&0x08)>>3)
 
167
#define MEGADRIVE_REG0C_INTERLEAVE      ((megadrive_vdp_register[0x0c]&0x06)>>1)
 
168
#define MEGADRIVE_REG0C_RS1             ((megadrive_vdp_register[0x0c]&0x01)>>0)
 
169
 
 
170
#define MEGADRIVE_REG0D_UNUSED          ((megadrive_vdp_register[0x0d]&0xc0)>>6)
 
171
#define MEGADRIVE_REG0D_HSCROLL_ADDR    ((megadrive_vdp_register[0x0d]&0x3f)>>0)
 
172
 
 
173
/* e? */
 
174
 
 
175
#define MEGADRIVE_REG0F_AUTO_INC        ((megadrive_vdp_register[0x0f]&0xff)>>0)
 
176
 
 
177
#define MEGADRIVE_REG10_UNUSED1        ((megadrive_vdp_register[0x10]&0xc0)>>6)
 
178
#define MEGADRIVE_REG10_VSCROLL_SIZE   ((megadrive_vdp_register[0x10]&0x30)>>4)
 
179
#define MEGADRIVE_REG10_UNUSED2        ((megadrive_vdp_register[0x10]&0x0c)>>2)
 
180
#define MEGADRIVE_REG10_HSCROLL_SIZE   ((megadrive_vdp_register[0x10]&0x03)>>0)
 
181
 
 
182
#define MEGADRIVE_REG11_WINDOW_RIGHT   ((megadrive_vdp_register[0x11]&0x80)>>7)
 
183
#define MEGADRIVE_REG11_UNUSED         ((megadrive_vdp_register[0x11]&0x60)>>5)
 
184
#define MEGADRIVE_REG11_WINDOW_HPOS      ((megadrive_vdp_register[0x11]&0x1f)>>0)
 
185
 
 
186
#define MEGADRIVE_REG12_WINDOW_DOWN    ((megadrive_vdp_register[0x12]&0x80)>>7)
 
187
#define MEGADRIVE_REG12_UNUSED         ((megadrive_vdp_register[0x12]&0x60)>>5)
 
188
#define MEGADRIVE_REG12_WINDOW_VPOS      ((megadrive_vdp_register[0x12]&0x1f)>>0)
 
189
 
 
190
#define MEGADRIVE_REG13_DMALENGTH1     ((megadrive_vdp_register[0x13]&0xff)>>0)
 
191
 
 
192
#define MEGADRIVE_REG14_DMALENGTH2      ((megadrive_vdp_register[0x14]&0xff)>>0)
 
193
 
 
194
#define MEGADRIVE_REG15_DMASOURCE1      ((megadrive_vdp_register[0x15]&0xff)>>0)
 
195
#define MEGADRIVE_REG16_DMASOURCE2      ((megadrive_vdp_register[0x16]&0xff)>>0)
 
196
 
 
197
#define MEGADRIVE_REG17_DMASOURCE3      ((megadrive_vdp_register[0x17]&0xff)>>0)
 
198
#define MEGADRIVE_REG17_DMATYPE         ((megadrive_vdp_register[0x17]&0xc0)>>6)
 
199
#define MEGADRIVE_REG17_UNUSED          ((megadrive_vdp_register[0x17]&0x3f)>>0)
 
200
 
 
201
 
 
202
static void vdp_vram_write(UINT16 data)
 
203
{
 
204
 
 
205
        UINT16 sprite_base_address = MEGADRIVE_REG0C_RS1?((MEGADRIVE_REG05_SPRITE_ADDR&0x7e)<<9):((MEGADRIVE_REG05_SPRITE_ADDR&0x7f)<<9);
 
206
        int spritetable_size = MEGADRIVE_REG0C_RS1?0x400:0x200;
 
207
        int lowlimit = sprite_base_address;
 
208
        int highlimit = sprite_base_address+spritetable_size;
 
209
 
 
210
        if (megadrive_vdp_address&1)
 
211
        {
 
212
                data = ((data&0x00ff)<<8)|((data&0xff00)>>8);
 
213
        }
 
214
 
 
215
        MEGADRIV_VDP_VRAM(megadrive_vdp_address>>1) = data;
 
216
 
 
217
        /* The VDP stores an Internal copy of any data written to the Sprite Attribute Table.
 
218
       This data is _NOT_ invalidated when the Sprite Base Address changes, thus allowing
 
219
       for some funky effects, as used by Castlevania Bloodlines Stage 6-3 */
 
220
        if (megadrive_vdp_address>=lowlimit && megadrive_vdp_address<highlimit)
 
221
        {
 
222
//      mame_printf_debug("spritebase is %04x-%04x vram address is %04x, write %04x\n",lowlimit, highlimit-1, megadrive_vdp_address, data);
 
223
                megadrive_vdp_internal_sprite_attribute_table[(megadrive_vdp_address&(spritetable_size-1))>>1] = data;
 
224
        }
 
225
 
 
226
        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
227
        megadrive_vdp_address &= 0xffff;
 
228
}
 
229
 
 
230
static void vdp_vsram_write(UINT16 data)
 
231
{
 
232
        megadrive_vdp_vsram[(megadrive_vdp_address&0x7e)>>1] = data;
 
233
 
 
234
        //logerror("Wrote to VSRAM addr %04x data %04x\n",megadrive_vdp_address&0xfffe,megadrive_vdp_vsram[megadrive_vdp_address>>1]);
 
235
 
 
236
        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
237
 
 
238
        megadrive_vdp_address &=0xffff;
 
239
}
 
240
 
 
241
static void write_cram_value(running_machine &machine, int offset, int data)
 
242
{
 
243
        megadrive_vdp_cram[offset] = data;
 
244
 
 
245
        //logerror("Wrote to CRAM addr %04x data %04x\n",megadrive_vdp_address&0xfffe,megadrive_vdp_cram[megadrive_vdp_address>>1]);
 
246
        if (genvdp_use_cram)
 
247
        {
 
248
                int r,g,b;
 
249
                r = ((data >> 1)&0x07);
 
250
                g = ((data >> 5)&0x07);
 
251
                b = ((data >> 9)&0x07);
 
252
                palette_set_color_rgb(machine,offset,pal3bit(r),pal3bit(g),pal3bit(b));
 
253
                megadrive_vdp_palette_lookup[offset] = (b<<2) | (g<<7) | (r<<12);
 
254
                megadrive_vdp_palette_lookup_sprite[offset] = (b<<2) | (g<<7) | (r<<12);
 
255
                megadrive_vdp_palette_lookup_shadow[offset] = (b<<1) | (g<<6) | (r<<11);
 
256
                megadrive_vdp_palette_lookup_highlight[offset] = ((b|0x08)<<1) | ((g|0x08)<<6) | ((r|0x08)<<11);
 
257
        }
 
258
}
 
259
 
 
260
static void vdp_cram_write(running_machine &machine, UINT16 data)
 
261
{
 
262
        int offset;
 
263
        offset = (megadrive_vdp_address&0x7e)>>1;
 
264
 
 
265
        write_cram_value(machine, offset,data);
 
266
 
 
267
        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
268
 
 
269
        megadrive_vdp_address &=0xffff;
 
270
}
 
271
 
 
272
 
 
273
static void megadriv_vdp_data_port_w(running_machine &machine, int data)
 
274
{
 
275
        megadrive_vdp_command_pending = 0;
 
276
 
 
277
 /*
 
278
 0000b : VRAM read
 
279
 0001b : VRAM write
 
280
 0011b : CRAM write
 
281
 0100b : VSRAM read
 
282
 0101b : VSRAM write
 
283
 1000b : CRAM read
 
284
 */
 
285
//  logerror("write to vdp data port %04x with code %04x, write address %04x\n",data, megadrive_vdp_code, megadrive_vdp_address );
 
286
 
 
287
        if (megadrive_vram_fill_pending)
 
288
        {
 
289
                int count;
 
290
 
 
291
                megadrive_vdp_address&=0xffff;
 
292
 
 
293
                if (megadrive_vdp_address&1)
 
294
                {
 
295
                        MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))   = (MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))&0xff00) | (data&0x00ff);
 
296
                }
 
297
                else
 
298
                {
 
299
                        MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))   = (MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))&0x00ff) | ((data&0x00ff)<<8);
 
300
                }
 
301
 
 
302
 
 
303
                for (count=0;count<=megadrive_vram_fill_length;count++) // <= for james pond 3
 
304
                {
 
305
                        if (megadrive_vdp_address&1)
 
306
                        {
 
307
                                MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))   = (MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))&0x00ff) | (data&0xff00);
 
308
                        }
 
309
                        else
 
310
                        {
 
311
                                MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))   = (MEGADRIV_VDP_VRAM((megadrive_vdp_address>>1))&0xff00) | ((data&0xff00)>>8);
 
312
                        }
 
313
 
 
314
                        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
315
                        megadrive_vdp_address&=0xffff;
 
316
 
 
317
                }
 
318
 
 
319
                megadrive_vdp_register[0x13] = 0;
 
320
                megadrive_vdp_register[0x14] = 0;
 
321
 
 
322
        //  megadrive_vdp_register[0x15] = (source>>1) & 0xff;
 
323
        //  megadrive_vdp_register[0x16] = (source>>9) & 0xff;
 
324
        //  megadrive_vdp_register[0x17] = (source>>17) & 0xff;
 
325
 
 
326
 
 
327
        }
 
328
        else
 
329
        {
 
330
 
 
331
                switch (megadrive_vdp_code & 0x000f)
 
332
                {
 
333
                        case 0x0000:
 
334
                                logerror("Attempting to WRITE to DATA PORT in VRAM READ MODE\n");
 
335
                                break;
 
336
 
 
337
                        case 0x0001:
 
338
                                vdp_vram_write(data);
 
339
                                break;
 
340
 
 
341
                        case 0x0003:
 
342
                                vdp_cram_write(machine, data);
 
343
                                break;
 
344
 
 
345
                        case 0x0004:
 
346
                                logerror("Attempting to WRITE to DATA PORT in VSRAM READ MODE\n");
 
347
                                break;
 
348
 
 
349
                        case 0x0005:
 
350
                                vdp_vsram_write(data);
 
351
                                break;
 
352
 
 
353
                        case 0x0008:
 
354
                                logerror("Attempting to WRITE to DATA PORT in CRAM READ MODE\n");
 
355
                                break;
 
356
 
 
357
                        default:
 
358
                                logerror("Attempting to WRITE to DATA PORT in #UNDEFINED# MODE %1x %04x\n",megadrive_vdp_code&0xf, data);
 
359
                                break;
 
360
                }
 
361
        }
 
362
 
 
363
 
 
364
 
 
365
}
 
366
 
 
367
 
 
368
 
 
369
static void megadrive_vdp_set_register(running_machine &machine, int regnum, UINT8 value)
 
370
{
 
371
        megadrive_vdp_register[regnum] = value;
 
372
 
 
373
        /* We need special handling for the IRQ enable registers, some games turn
 
374
       off the irqs before they are taken, delaying them until the IRQ is turned
 
375
       back on */
 
376
 
 
377
        if (regnum == 0x00)
 
378
        {
 
379
        //mame_printf_debug("setting reg 0, irq enable is now %d\n",MEGADRIVE_REG0_IRQ4_ENABLE);
 
380
 
 
381
                if (megadrive_irq4_pending)
 
382
                {
 
383
                        if (MEGADRIVE_REG0_IRQ4_ENABLE)
 
384
                                cputag_set_input_line(machine, "maincpu", 4, HOLD_LINE);
 
385
                        else
 
386
                                cputag_set_input_line(machine, "maincpu", 4, CLEAR_LINE);
 
387
                }
 
388
 
 
389
                /* ??? Fatal Rewind needs this but I'm not sure it's accurate behavior
 
390
           it causes flickering in roadrash */
 
391
        //  megadrive_irq6_pending = 0;
 
392
        //  megadrive_irq4_pending = 0;
 
393
 
 
394
        }
 
395
 
 
396
        if (regnum == 0x01)
 
397
        {
 
398
                if (megadrive_irq6_pending)
 
399
                {
 
400
                        if (MEGADRIVE_REG01_IRQ6_ENABLE )
 
401
                                cputag_set_input_line(machine, "maincpu", 6, HOLD_LINE);
 
402
                        else
 
403
                                cputag_set_input_line(machine, "maincpu", 6, CLEAR_LINE);
 
404
                }
 
405
 
 
406
                /* ??? */
 
407
        //  megadrive_irq6_pending = 0;
 
408
        //  megadrive_irq4_pending = 0;
 
409
 
 
410
        }
 
411
 
 
412
 
 
413
//  if (regnum == 0x0a)
 
414
//      mame_printf_debug("Set HINT Reload Register to %d on scanline %d\n",value, genesis_scanline_counter);
 
415
 
 
416
//  mame_printf_debug("%s: Setting VDP Register #%02x to %02x\n",machine.describe_context(), regnum,value);
 
417
}
 
418
 
 
419
static void update_megadrive_vdp_code_and_address(void)
 
420
{
 
421
        megadrive_vdp_code = ((megadrive_vdp_command_part1 & 0xc000) >> 14) |
 
422
                             ((megadrive_vdp_command_part2 & 0x00f0) >> 2);
 
423
 
 
424
        megadrive_vdp_address = ((megadrive_vdp_command_part1 & 0x3fff) >> 0) |
 
425
                            ((megadrive_vdp_command_part2 & 0x0003) << 14);
 
426
}
 
427
 
 
428
UINT16 (*vdp_get_word_from_68k_mem)(running_machine &machine, UINT32 source);
 
429
 
 
430
UINT16 vdp_get_word_from_68k_mem_default(running_machine &machine, UINT32 source)
 
431
{
 
432
        // should we limit the valid areas here?
 
433
        // how does this behave with the segacd etc?
 
434
        // note, the RV bit on 32x is important for this to work, because it causes a normal cart mapping - see tempo
 
435
        address_space *space68k = machine.device<legacy_cpu_device>("maincpu")->space();
 
436
 
 
437
        //printf("vdp_get_word_from_68k_mem_default %08x\n", source);
 
438
 
 
439
        if ( source <= 0x3fffff )
 
440
        {
 
441
                if (_svp_cpu != NULL)
 
442
                {
 
443
                        source -= 2; // the SVP introduces some kind of DMA 'lag', which we have to compensate for, this is obvious even on gfx DMAd from ROM (the Speedometer)
 
444
                }
 
445
 
 
446
                // likewise segaCD, at least when reading wordram?
 
447
                // we might need to check what mode we're in here..
 
448
                if (segacd_wordram_mapped)
 
449
                {
 
450
                        source -= 2;
 
451
                }
 
452
 
 
453
                return space68k->read_word(source);
 
454
        }
 
455
        else if (( source >= 0xe00000 ) && ( source <= 0xffffff ))
 
456
        {
 
457
                return space68k->read_word(source);
 
458
        }
 
459
        else
 
460
        {
 
461
                printf("DMA Read unmapped %06x\n",source);
 
462
                return machine.rand();
 
463
        }
 
464
 
 
465
 
 
466
}
 
467
 
 
468
/*  Table from Charles Macdonald
 
469
 
 
470
 
 
471
    DMA Mode      Width       Display      Transfer Count
 
472
    -----------------------------------------------------
 
473
    68K > VDP     32-cell     Active       16
 
474
                              Blanking     167
 
475
                  40-cell     Active       18
 
476
                              Blanking     205
 
477
    VRAM Fill     32-cell     Active       15
 
478
                              Blanking     166
 
479
                  40-cell     Active       17
 
480
                              Blanking     204
 
481
    VRAM Copy     32-cell     Active       8
 
482
                              Blanking     83
 
483
                  40-cell     Active       9
 
484
                              Blanking     102
 
485
 
 
486
*/
 
487
 
 
488
 
 
489
/* Note, In reality this transfer is NOT instant, the 68k isn't paused
 
490
   as the 68k address bus isn't accessed */
 
491
 
 
492
/* Wani Wani World, James Pond 3, Pirates Gold! */
 
493
static void megadrive_do_insta_vram_copy(UINT32 source, UINT16 length)
 
494
{
 
495
        int x;
 
496
 
 
497
        for (x=0;x<length;x++)
 
498
        {
 
499
                UINT8 source_byte;
 
500
 
 
501
                //mame_printf_debug("vram copy length %04x source %04x dest %04x\n",length, source, megadrive_vdp_address );
 
502
                if (source&1) source_byte = MEGADRIV_VDP_VRAM((source&0xffff)>>1)&0x00ff;
 
503
                else  source_byte = (MEGADRIV_VDP_VRAM((source&0xffff)>>1)&0xff00)>>8;
 
504
 
 
505
                if (megadrive_vdp_address&1)
 
506
                {
 
507
                        MEGADRIV_VDP_VRAM((megadrive_vdp_address&0xffff)>>1) = (MEGADRIV_VDP_VRAM((megadrive_vdp_address&0xffff)>>1)&0xff00) | source_byte;
 
508
                }
 
509
                else
 
510
                {
 
511
                        MEGADRIV_VDP_VRAM((megadrive_vdp_address&0xffff)>>1) = (MEGADRIV_VDP_VRAM((megadrive_vdp_address&0xffff)>>1)&0x00ff) | (source_byte<<8);
 
512
                }
 
513
 
 
514
                source++;
 
515
                megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
516
                megadrive_vdp_address&=0xffff;
 
517
        }
 
518
}
 
519
 
 
520
/* Instant, but we pause the 68k a bit */
 
521
static void megadrive_do_insta_68k_to_vram_dma(running_machine &machine, UINT32 source,int length)
 
522
{
 
523
        int count;
 
524
 
 
525
        if (length==0x00) length = 0xffff;
 
526
 
 
527
        /* This is a hack until real DMA timings are implemented */
 
528
        device_spin_until_time(machine.device("maincpu"), attotime::from_nsec(length * 1000 / 3500));
 
529
 
 
530
        for (count = 0;count<(length>>1);count++)
 
531
        {
 
532
                vdp_vram_write(vdp_get_word_from_68k_mem(machine, source));
 
533
                source+=2;
 
534
                if (source>0xffffff) source = 0xe00000;
 
535
        }
 
536
 
 
537
        megadrive_vdp_address&=0xffff;
 
538
 
 
539
        megadrive_vdp_register[0x13] = 0;
 
540
        megadrive_vdp_register[0x14] = 0;
 
541
 
 
542
        megadrive_vdp_register[0x15] = (source>>1) & 0xff;
 
543
        megadrive_vdp_register[0x16] = (source>>9) & 0xff;
 
544
        megadrive_vdp_register[0x17] = (source>>17) & 0xff;
 
545
}
 
546
 
 
547
 
 
548
static void megadrive_do_insta_68k_to_cram_dma(running_machine &machine,UINT32 source,UINT16 length)
 
549
{
 
550
        int count;
 
551
 
 
552
        if (length==0x00) length = 0xffff;
 
553
 
 
554
        for (count = 0;count<(length>>1);count++)
 
555
        {
 
556
                //if (megadrive_vdp_address>=0x80) return; // abandon
 
557
 
 
558
                write_cram_value(machine, (megadrive_vdp_address&0x7e)>>1, vdp_get_word_from_68k_mem(machine, source));
 
559
                source+=2;
 
560
 
 
561
                if (source>0xffffff) source = 0xfe0000;
 
562
 
 
563
                megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
564
                megadrive_vdp_address&=0xffff;
 
565
        }
 
566
 
 
567
        megadrive_vdp_register[0x13] = 0;
 
568
        megadrive_vdp_register[0x14] = 0;
 
569
 
 
570
        megadrive_vdp_register[0x15] = (source>>1) & 0xff;
 
571
        megadrive_vdp_register[0x16] = (source>>9) & 0xff;
 
572
        megadrive_vdp_register[0x17] = (source>>17) & 0xff;
 
573
 
 
574
}
 
575
 
 
576
static void megadrive_do_insta_68k_to_vsram_dma(running_machine &machine,UINT32 source,UINT16 length)
 
577
{
 
578
        int count;
 
579
 
 
580
        if (length==0x00) length = 0xffff;
 
581
 
 
582
        for (count = 0;count<(length>>1);count++)
 
583
        {
 
584
                if (megadrive_vdp_address>=0x80) return; // abandon
 
585
 
 
586
                megadrive_vdp_vsram[(megadrive_vdp_address&0x7e)>>1] = vdp_get_word_from_68k_mem(machine, source);
 
587
                source+=2;
 
588
 
 
589
                if (source>0xffffff) source = 0xfe0000;
 
590
 
 
591
                megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
592
                megadrive_vdp_address&=0xffff;
 
593
        }
 
594
 
 
595
        megadrive_vdp_register[0x13] = 0;
 
596
        megadrive_vdp_register[0x14] = 0;
 
597
 
 
598
        megadrive_vdp_register[0x15] = (source>>1) & 0xff;
 
599
        megadrive_vdp_register[0x16] = (source>>9) & 0xff;
 
600
        megadrive_vdp_register[0x17] = (source>>17) & 0xff;
 
601
}
 
602
 
 
603
/* This can be simplified quite a lot.. */
 
604
static void handle_dma_bits(running_machine &machine)
 
605
{
 
606
#if 0
 
607
        if (megadrive_vdp_code&0x20)
 
608
        {
 
609
                UINT32 source;
 
610
                UINT16 length;
 
611
                source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8) | ((MEGADRIVE_REG17_DMASOURCE3&0xff)<<16))<<1;
 
612
                length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8))<<1;
 
613
                mame_printf_debug("%s 68k DMAtran set source %06x length %04x dest %04x enabled %01x code %02x %02x\n", machine.describe_context(), source, length, megadrive_vdp_address,MEGADRIVE_REG01_DMA_ENABLE, megadrive_vdp_code,MEGADRIVE_REG0F_AUTO_INC);
 
614
        }
 
615
#endif
 
616
        if (megadrive_vdp_code==0x20)
 
617
        {
 
618
                mame_printf_debug("DMA bit set 0x20 but invalid??\n");
 
619
        }
 
620
        else if (megadrive_vdp_code==0x21 || megadrive_vdp_code==0x31) /* 0x31 used by tecmo cup */
 
621
        {
 
622
                if (MEGADRIVE_REG17_DMATYPE==0x0 || MEGADRIVE_REG17_DMATYPE==0x1)
 
623
                {
 
624
                        UINT32 source;
 
625
                        UINT16 length;
 
626
                        source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8) | ((MEGADRIVE_REG17_DMASOURCE3&0x7f)<<16))<<1;
 
627
                        length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8))<<1;
 
628
 
 
629
                        /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */
 
630
                        //mame_printf_debug("68k->VRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, megadrive_vdp_address,MEGADRIVE_REG01_DMA_ENABLE);
 
631
                        if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vram_dma(machine,source,length);
 
632
 
 
633
                }
 
634
                else if (MEGADRIVE_REG17_DMATYPE==0x2)
 
635
                {
 
636
                        //mame_printf_debug("vram fill length %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
637
                        if (MEGADRIVE_REG01_DMA_ENABLE)
 
638
                        {
 
639
                                megadrive_vram_fill_pending = 1;
 
640
                                megadrive_vram_fill_length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8));
 
641
                        }
 
642
                }
 
643
                else if (MEGADRIVE_REG17_DMATYPE==0x3)
 
644
                {
 
645
                        UINT32 source;
 
646
                        UINT16 length;
 
647
                        source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8)); // source (byte offset)
 
648
                        length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8)); // length in bytes
 
649
                        //mame_printf_debug("setting vram copy mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
650
 
 
651
                        if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_vram_copy(source, length);
 
652
                }
 
653
        }
 
654
        else if (megadrive_vdp_code==0x23)
 
655
        {
 
656
                if (MEGADRIVE_REG17_DMATYPE==0x0 || MEGADRIVE_REG17_DMATYPE==0x1)
 
657
                {
 
658
                        UINT32 source;
 
659
                        UINT16 length;
 
660
                        source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8) | ((MEGADRIVE_REG17_DMASOURCE3&0x7f)<<16))<<1;
 
661
                        length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8))<<1;
 
662
 
 
663
                        /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */
 
664
                        //mame_printf_debug("68k->CRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, megadrive_vdp_address,MEGADRIVE_REG01_DMA_ENABLE);
 
665
                        if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_cram_dma(machine,source,length);
 
666
                }
 
667
                else if (MEGADRIVE_REG17_DMATYPE==0x2)
 
668
                {
 
669
                        //mame_printf_debug("vram fill length %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
670
                        if (MEGADRIVE_REG01_DMA_ENABLE)
 
671
                        {
 
672
                                megadrive_vram_fill_pending = 1;
 
673
                                megadrive_vram_fill_length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8));
 
674
                        }
 
675
                }
 
676
                else if (MEGADRIVE_REG17_DMATYPE==0x3)
 
677
                {
 
678
                        mame_printf_debug("setting vram copy (INVALID?) mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
679
                }
 
680
        }
 
681
        else if (megadrive_vdp_code==0x25)
 
682
        {
 
683
                if (MEGADRIVE_REG17_DMATYPE==0x0 || MEGADRIVE_REG17_DMATYPE==0x1)
 
684
                {
 
685
                        UINT32 source;
 
686
                        UINT16 length;
 
687
                        source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8) | ((MEGADRIVE_REG17_DMASOURCE3&0x7f)<<16))<<1;
 
688
                        length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8))<<1;
 
689
 
 
690
                        /* The 68k is frozen during this transfer, it should be safe to throw a few cycles away and do 'instant' DMA because the 68k can't detect it being in progress (can the z80?) */
 
691
                        //mame_printf_debug("68k->VSRAM DMA transfer source %06x length %04x dest %04x enabled %01x\n", source, length, megadrive_vdp_address,MEGADRIVE_REG01_DMA_ENABLE);
 
692
                        if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_68k_to_vsram_dma(machine,source,length);
 
693
                }
 
694
                else if (MEGADRIVE_REG17_DMATYPE==0x2)
 
695
                {
 
696
                        //mame_printf_debug("vram fill length %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
697
                        if (MEGADRIVE_REG01_DMA_ENABLE)
 
698
                        {
 
699
                                megadrive_vram_fill_pending = 1;
 
700
                                megadrive_vram_fill_length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8));
 
701
                        }
 
702
                }
 
703
                else if (MEGADRIVE_REG17_DMATYPE==0x3)
 
704
                {
 
705
                        mame_printf_debug("setting vram copy (INVALID?) mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
706
                }
 
707
        }
 
708
        else if (megadrive_vdp_code==0x30)
 
709
        {
 
710
                if (MEGADRIVE_REG17_DMATYPE==0x0)
 
711
                {
 
712
                        mame_printf_debug("setting vram 68k->vram (INVALID?) mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
713
                }
 
714
                else if (MEGADRIVE_REG17_DMATYPE==0x1)
 
715
                {
 
716
                        mame_printf_debug("setting vram 68k->vram (INVALID?) mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
717
                }
 
718
                else if (MEGADRIVE_REG17_DMATYPE==0x2)
 
719
                {
 
720
                        mame_printf_debug("setting vram fill (INVALID?) mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
721
                }
 
722
                else if (MEGADRIVE_REG17_DMATYPE==0x3)
 
723
                {
 
724
                        UINT32 source;
 
725
                        UINT16 length;
 
726
                        source = (MEGADRIVE_REG15_DMASOURCE1 | (MEGADRIVE_REG16_DMASOURCE2<<8)); // source (byte offset)
 
727
                        length = (MEGADRIVE_REG13_DMALENGTH1 | (MEGADRIVE_REG14_DMALENGTH2<<8)); // length in bytes
 
728
                        //mame_printf_debug("setting vram copy mode length registers are %02x %02x other regs! %02x %02x %02x(Mode Bits %02x) Enable %02x\n", MEGADRIVE_REG13_DMALENGTH1, MEGADRIVE_REG14_DMALENGTH2, MEGADRIVE_REG15_DMASOURCE1, MEGADRIVE_REG16_DMASOURCE2, MEGADRIVE_REG17_DMASOURCE3, MEGADRIVE_REG17_DMATYPE, MEGADRIVE_REG01_DMA_ENABLE);
 
729
 
 
730
                        if (MEGADRIVE_REG01_DMA_ENABLE) megadrive_do_insta_vram_copy(source, length);
 
731
                }
 
732
        }
 
733
}
 
734
 
 
735
static void megadriv_vdp_ctrl_port_w(running_machine &machine, int data)
 
736
{
 
737
//  logerror("write to vdp control port %04x\n",data);
 
738
        megadrive_vram_fill_pending = 0; // ??
 
739
 
 
740
        if (megadrive_vdp_command_pending)
 
741
        {
 
742
                /* 2nd part of 32-bit command */
 
743
                megadrive_vdp_command_pending = 0;
 
744
                megadrive_vdp_command_part2 = data;
 
745
 
 
746
                update_megadrive_vdp_code_and_address();
 
747
                handle_dma_bits(machine);
 
748
 
 
749
                //logerror("VDP Write Part 2 setting Code %02x Address %04x\n",megadrive_vdp_code, megadrive_vdp_address);
 
750
 
 
751
        }
 
752
        else
 
753
        {
 
754
                if ((data & 0xc000) == 0x8000)
 
755
                {       /* Register Setting Command */
 
756
                        int regnum = (data & 0x3f00) >> 8;
 
757
                        int value  = (data & 0x00ff);
 
758
 
 
759
                        if (regnum &0x20) mame_printf_debug("reg error\n");
 
760
 
 
761
                        megadrive_vdp_set_register(machine, regnum&0x1f,value);
 
762
                        megadrive_vdp_code = 0;
 
763
                        megadrive_vdp_address = 0;
 
764
                }
 
765
                else
 
766
                {
 
767
                        megadrive_vdp_command_pending = 1;
 
768
                        megadrive_vdp_command_part1 = data;
 
769
                        update_megadrive_vdp_code_and_address();
 
770
                        //logerror("VDP Write Part 1 setting Code %02x Address %04x\n",megadrive_vdp_code, megadrive_vdp_address);
 
771
                }
 
772
 
 
773
        }
 
774
}
 
775
 
 
776
WRITE16_HANDLER( megadriv_vdp_w )
 
777
{
 
778
        switch (offset<<1)
 
779
        {
 
780
                case 0x00:
 
781
                case 0x02:
 
782
                        if (!ACCESSING_BITS_8_15)
 
783
                        {
 
784
                                data = (data&0x00ff) | data<<8;
 
785
                        //  mame_printf_debug("8-bit write VDP data port access, offset %04x data %04x mem_mask %04x\n",offset,data,mem_mask);
 
786
                        }
 
787
                        else if (!ACCESSING_BITS_0_7)
 
788
                        {
 
789
                                data = (data&0xff00) | data>>8;
 
790
                        //  mame_printf_debug("8-bit write VDP data port access, offset %04x data %04x mem_mask %04x\n",offset,data,mem_mask);
 
791
                        }
 
792
                        megadriv_vdp_data_port_w(space->machine(), data);
 
793
                        break;
 
794
 
 
795
                case 0x04:
 
796
                case 0x06:
 
797
                        if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit write VDP control port access, offset %04x data %04x mem_mask %04x\n",offset,data,mem_mask);
 
798
                        megadriv_vdp_ctrl_port_w(space->machine(), data);
 
799
                        break;
 
800
 
 
801
                case 0x08:
 
802
                case 0x0a:
 
803
                case 0x0c:
 
804
                case 0x0e:
 
805
                        logerror("Attempt to Write to HV counters!!\n");
 
806
                        break;
 
807
 
 
808
                case 0x10:
 
809
                case 0x12:
 
810
                case 0x14:
 
811
                case 0x16:
 
812
                        if (ACCESSING_BITS_0_7) sn76496_w(space->machine().device("snsnd"), 0, data & 0xff);
 
813
                        //if (ACCESSING_BITS_8_15) sn76496_w(space->machine().device("snsnd"), 0, (data >>8) & 0xff);
 
814
                        break;
 
815
 
 
816
                default:
 
817
                mame_printf_debug("write to unmapped vdp port\n");
 
818
        }
 
819
}
 
820
 
 
821
static UINT16 vdp_vram_r(void)
 
822
{
 
823
        return MEGADRIV_VDP_VRAM((megadrive_vdp_address&0xfffe)>>1);
 
824
}
 
825
 
 
826
static UINT16 vdp_vsram_r(void)
 
827
{
 
828
        return megadrive_vdp_vsram[(megadrive_vdp_address&0x7e)>>1];
 
829
}
 
830
 
 
831
static UINT16 vdp_cram_r(void)
 
832
{
 
833
 
 
834
        return megadrive_vdp_cram[(megadrive_vdp_address&0x7e)>>1];
 
835
}
 
836
 
 
837
static UINT16 megadriv_vdp_data_port_r(running_machine &machine)
 
838
{
 
839
        UINT16 retdata=0;
 
840
 
 
841
        //return machine.rand();
 
842
 
 
843
        megadrive_vdp_command_pending = 0;
 
844
 
 
845
        switch (megadrive_vdp_code & 0x000f)
 
846
        {
 
847
                case 0x0000:
 
848
                        retdata = vdp_vram_r();
 
849
                        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
850
                        megadrive_vdp_address&=0xffff;
 
851
                        break;
 
852
 
 
853
                case 0x0001:
 
854
                        logerror("Attempting to READ from DATA PORT in VRAM WRITE MODE\n");
 
855
                        retdata = machine.rand();
 
856
                        break;
 
857
 
 
858
                case 0x0003:
 
859
                        logerror("Attempting to READ from DATA PORT in CRAM WRITE MODE\n");
 
860
                        retdata = machine.rand();
 
861
                        break;
 
862
 
 
863
                case 0x0004:
 
864
                        retdata = vdp_vsram_r();
 
865
                        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
866
                        megadrive_vdp_address&=0xffff;
 
867
                        break;
 
868
 
 
869
                case 0x0005:
 
870
                        logerror("Attempting to READ from DATA PORT in VSRAM WRITE MODE\n");
 
871
                        break;
 
872
 
 
873
                case 0x0008:
 
874
                        retdata = vdp_cram_r();
 
875
                        megadrive_vdp_address+=MEGADRIVE_REG0F_AUTO_INC;
 
876
                        megadrive_vdp_address&=0xffff;
 
877
                        break;
 
878
 
 
879
                default:
 
880
                        logerror("Attempting to READ from DATA PORT in #UNDEFINED# MODE\n");
 
881
                        retdata = machine.rand();
 
882
                        break;
 
883
        }
 
884
 
 
885
//  mame_printf_debug("vdp_data_port_r %04x %04x %04x\n",megadrive_vdp_code, megadrive_vdp_address, retdata);
 
886
 
 
887
//  logerror("Read VDP Data Port\n");
 
888
        return retdata;
 
889
}
 
890
 
 
891
/*
 
892
 
 
893
 NTSC, 256x224
 
894
 -------------
 
895
 
 
896
 Lines  Description
 
897
 
 
898
 224    Active display
 
899
 8      Bottom border
 
900
 3      Bottom blanking
 
901
 3      Vertical blanking
 
902
 13     Top blanking
 
903
 11     Top border
 
904
 
 
905
 V counter values
 
906
 00-EA, E5-FF
 
907
 
 
908
PAL, 256x224
 
909
 ------------
 
910
 
 
911
 Lines  Description
 
912
 
 
913
 224    Active display
 
914
 32     Bottom border
 
915
 3      Bottom blanking
 
916
 3      Vertical blanking
 
917
 13     Top blanking
 
918
 38     Top border
 
919
 
 
920
 V counter values
 
921
 00-FF, 00-02, CA-FF
 
922
 
 
923
 PAL, 256x240
 
924
 ------------
 
925
 
 
926
 Lines  Description
 
927
 
 
928
 240    Active display
 
929
 24     Bottom border
 
930
 3      Bottom blanking
 
931
 3      Vertical blanking
 
932
 13     Top blanking
 
933
 30     Top border
 
934
 
 
935
 V counter values
 
936
 00-FF, 00-0A, D2-FF
 
937
 
 
938
 
 
939
 
 
940
 Pixels H.Cnt   Description
 
941
  256 : 00-7F : Active display
 
942
   15 : 80-87 : Right border
 
943
    8 : 87-8B : Right blanking
 
944
   26 : 8B-ED : Horizontal sync
 
945
    2 : ED-EE : Left blanking
 
946
   14 : EE-F5 : Color burst
 
947
    8 : F5-F9 : Left blanking
 
948
   13 : F9-FF : Left border
 
949
 
 
950
*/
 
951
 
 
952
 
 
953
 
 
954
static UINT16 megadriv_vdp_ctrl_port_r(void)
 
955
{
 
956
        /* Battletoads is very fussy about the vblank flag
 
957
       it wants it to be 1. in scanline 224 */
 
958
 
 
959
        /* Double Dragon 2 is very sensitive to hblank timing */
 
960
        /* xperts is very fussy too */
 
961
 
 
962
        /* Game no Kanzume Otokuyou (J) [!] is also fussy
 
963
      - it cares about the bits labeled always 0, always 1.. (!)
 
964
     */
 
965
 
 
966
        /* Megalo Mania also fussy - cares about pending flag*/
 
967
 
 
968
        int megadrive_sprite_overflow = 0;
 
969
        int megadrive_odd_frame = megadrive_imode_odd_frame^1;
 
970
        int megadrive_hblank_flag = 0;
 
971
        int megadrive_dma_active = 0;
 
972
        int vblank;
 
973
        int fifo_empty = 1;
 
974
        int fifo_full = 0;
 
975
 
 
976
        UINT16 hpos = get_hposition();
 
977
 
 
978
        if (hpos>400) megadrive_hblank_flag = 1;
 
979
        if (hpos>460) megadrive_hblank_flag = 0;
 
980
 
 
981
        vblank = megadrive_vblank_flag;
 
982
 
 
983
        /* extra case */
 
984
        if (MEGADRIVE_REG01_DISP_ENABLE==0) vblank = 1;
 
985
 
 
986
/*
 
987
 
 
988
// these aren't *always* 0/1 some of them are open bus return
 
989
 d15 - Always 0
 
990
 d14 - Always 0
 
991
 d13 - Always 1
 
992
 d12 - Always 1
 
993
 
 
994
 d11 - Always 0
 
995
 d10 - Always 1
 
996
 d9  - FIFO Empty
 
997
 d8  - FIFO Full
 
998
 
 
999
 d7  - Vertical interrupt pending
 
1000
 d6  - Sprite overflow on current scan line
 
1001
 d5  - Sprite collision
 
1002
 d4  - Odd frame
 
1003
 
 
1004
 d3  - Vertical blanking
 
1005
 d2  - Horizontal blanking
 
1006
 d1  - DMA in progress
 
1007
 d0  - PAL mode flag
 
1008
*/
 
1009
 
 
1010
        return (0<<15) | // ALWAYS 0
 
1011
               (0<<14) | // ALWAYS 0
 
1012
               (1<<13) | // ALWAYS 1
 
1013
               (1<<12) | // ALWAYS 1
 
1014
               (0<<11) | // ALWAYS 0
 
1015
               (1<<10) | // ALWAYS 1
 
1016
               (fifo_empty<<9 ) | // FIFO EMPTY
 
1017
               (fifo_full<<8 ) | // FIFO FULL
 
1018
               (megadrive_irq6_pending << 7) | // exmutants has a tight loop checking this ..
 
1019
               (megadrive_sprite_overflow << 6) |
 
1020
               (megadrive_sprite_collision << 5) |
 
1021
               (megadrive_odd_frame << 4) |
 
1022
               (vblank << 3) |
 
1023
               (megadrive_hblank_flag << 2) |
 
1024
               (megadrive_dma_active << 1 ) |
 
1025
               (megadrive_region_pal<<0); // PAL MODE FLAG checked by striker for region prot..
 
1026
}
 
1027
 
 
1028
static const UINT8 vc_ntsc_224[] =
 
1029
{
 
1030
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,    0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
1031
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,    0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 
1032
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,    0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 
1033
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,    0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 
1034
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,    0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 
1035
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,    0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 
1036
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,    0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 
1037
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 
1038
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,    0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 
1039
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,    0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 
1040
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,    0xab, 0xac, 0xad, 0xae, 0xaf,
 
1041
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,    0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 
1042
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 
1043
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,    0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 
1044
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,/**/0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
 
1045
    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4,    0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
 
1046
    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1047
};
 
1048
 
 
1049
static const UINT8 vc_ntsc_240[] =
 
1050
{
 
1051
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
1052
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 
1053
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 
1054
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 
1055
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 
1056
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 
1057
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 
1058
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 
1059
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 
1060
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 
1061
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 
1062
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 
1063
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 
1064
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 
1065
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 
1066
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1067
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05
 
1068
};
 
1069
 
 
1070
static const UINT8 vc_pal_224[] =
 
1071
{
 
1072
    0x00, 0x01, 0x02,    0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
1073
    0x10, 0x11, 0x12,    0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 
1074
    0x20, 0x21, 0x22,    0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 
1075
    0x30, 0x31, 0x32,    0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 
1076
    0x40, 0x41, 0x42,    0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 
1077
    0x50, 0x51, 0x52,    0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 
1078
    0x60, 0x61, 0x62,    0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 
1079
    0x70, 0x71, 0x72,    0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 
1080
    0x80, 0x81, 0x82,    0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 
1081
    0x90, 0x91, 0x92,    0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 
1082
    0xa0, 0xa1, 0xa2,    0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
 
1083
    0xb0, 0xb1, 0xb2,    0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 
1084
    0xc0, 0xc1, 0xc2,    0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 
1085
    0xd0, 0xd1, 0xd2,    0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 
1086
    0xe0, 0xe1, 0xe2,    0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
 
1087
    0xf0, 0xf1, 0xf2,    0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1088
    0x00, 0x01, 0x02,/**/0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
 
1089
    0xd7, 0xd8, 0xd9,    0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
 
1090
    0xe7, 0xe8, 0xe9,    0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
 
1091
    0xf7, 0xf8, 0xf9,    0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1092
};
 
1093
 
 
1094
static const UINT8 vc_pal_240[] =
 
1095
{
 
1096
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,    0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
 
1097
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a,    0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
 
1098
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a,    0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
 
1099
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a,    0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
 
1100
    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,    0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 
1101
    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,    0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 
1102
    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,    0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 
1103
    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,    0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
 
1104
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,    0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
 
1105
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,    0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
 
1106
    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,    0xab, 0xac, 0xad, 0xae, 0xaf,
 
1107
    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,    0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
 
1108
    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,    0xcb, 0xcc, 0xcd, 0xce, 0xcf,
 
1109
    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,    0xdb, 0xdc, 0xdd, 0xde, 0xdf,
 
1110
    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,    0xeb, 0xec, 0xed, 0xee, 0xef,
 
1111
    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,    0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1112
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,/**/0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
 
1113
    0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1,    0xe2, 0xe3, 0xe4, 0xe5, 0xe6,
 
1114
    0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1,    0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
 
1115
    0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
 
1116
};
 
1117
 
 
1118
 
 
1119
 
 
1120
static UINT16 megadriv_read_hv_counters(void)
 
1121
{
 
1122
        /* Bubble and Squeek wants vcount=0xe0 */
 
1123
        /* Dracula is very sensitive to this */
 
1124
        /* Marvel Land is sensitive to this */
 
1125
 
 
1126
        int vpos = genesis_scanline_counter;
 
1127
        UINT16 hpos = get_hposition();
 
1128
 
 
1129
//  if (hpos>424) vpos++; // fixes dracula, breaks road rash
 
1130
        if (hpos>460) vpos++; // when does vpos increase.. also on sms, check game gear manual..
 
1131
 
 
1132
        /* shouldn't happen.. */
 
1133
        if (vpos<0)
 
1134
        {
 
1135
                vpos = megadrive_total_scanlines;
 
1136
                mame_printf_debug("negative vpos?!\n");
 
1137
        }
 
1138
 
 
1139
        if (MEGADRIVE_REG01_240_LINE)
 
1140
        {
 
1141
                if (!megadrive_region_pal)
 
1142
                {
 
1143
                        vpos = vc_ntsc_240[vpos%megadrive_total_scanlines];
 
1144
                }
 
1145
                else
 
1146
                {
 
1147
                        vpos = vc_pal_240[vpos%megadrive_total_scanlines];
 
1148
                }
 
1149
 
 
1150
        }
 
1151
        else
 
1152
        {
 
1153
                if (!megadrive_region_pal)
 
1154
                {
 
1155
                        vpos = vc_ntsc_224[vpos%megadrive_total_scanlines];
 
1156
                }
 
1157
                else
 
1158
                {
 
1159
                        vpos = vc_pal_224[vpos%megadrive_total_scanlines];
 
1160
                }
 
1161
        }
 
1162
 
 
1163
        if (hpos>0xf7) hpos -=0x49;
 
1164
 
 
1165
        return ((vpos&0xff)<<8)|(hpos&0xff);
 
1166
 
 
1167
}
 
1168
 
 
1169
READ16_HANDLER( megadriv_vdp_r )
 
1170
{
 
1171
        UINT16 retvalue = 0;
 
1172
 
 
1173
 
 
1174
 
 
1175
        switch (offset<<1)
 
1176
        {
 
1177
 
 
1178
                case 0x00:
 
1179
                case 0x02:
 
1180
                        if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read data port access, offset %04x mem_mask %04x\n",offset,mem_mask);
 
1181
                        retvalue = megadriv_vdp_data_port_r(space->machine());
 
1182
                        break;
 
1183
 
 
1184
                case 0x04:
 
1185
                case 0x06:
 
1186
                //  if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read control port access, offset %04x mem_mask %04x\n",offset,mem_mask);
 
1187
                        retvalue = megadriv_vdp_ctrl_port_r();
 
1188
                //  retvalue = space->machine().rand();
 
1189
                //  mame_printf_debug("%06x: Read Control Port at scanline %d hpos %d (return %04x)\n",cpu_get_pc(&space->device()),genesis_scanline_counter, get_hposition(),retvalue);
 
1190
                        break;
 
1191
 
 
1192
                case 0x08:
 
1193
                case 0x0a:
 
1194
                case 0x0c:
 
1195
                case 0x0e:
 
1196
                //  if ((!ACCESSING_BITS_8_15) || (!ACCESSING_BITS_0_7)) mame_printf_debug("8-bit VDP read HV counter port access, offset %04x mem_mask %04x\n",offset,mem_mask);
 
1197
                        retvalue = megadriv_read_hv_counters();
 
1198
                //  retvalue = space->machine().rand();
 
1199
                //  mame_printf_debug("%06x: Read HV counters at scanline %d hpos %d (return %04x)\n",cpu_get_pc(&space->device()),genesis_scanline_counter, get_hposition(),retvalue);
 
1200
                        break;
 
1201
 
 
1202
                case 0x10:
 
1203
                case 0x12:
 
1204
                case 0x14:
 
1205
                case 0x16:
 
1206
                        logerror("Attempting to read PSG!\n");
 
1207
                        retvalue = 0;
 
1208
                        break;
 
1209
        }
 
1210
        return retvalue;
 
1211
}
 
1212
 
 
1213
READ8_DEVICE_HANDLER( megadriv_68k_YM2612_read)
 
1214
{
 
1215
        //mame_printf_debug("megadriv_68k_YM2612_read %02x %04x\n",offset,mem_mask);
 
1216
        if ( (genz80.z80_has_bus==0) && (genz80.z80_is_reset==0) )
 
1217
        {
 
1218
                return ym2612_r(device, offset);
 
1219
        }
 
1220
        else
 
1221
        {
 
1222
                logerror("%s: 68000 attempting to access YM2612 (read) without bus\n", device->machine().describe_context());
 
1223
                return 0;
 
1224
        }
 
1225
 
 
1226
        return -1;
 
1227
}
 
1228
 
 
1229
 
 
1230
// line length = 342
 
1231
 
 
1232
/*
 
1233
 The V counter counts up from 00h to EAh, then it jumps back to E5h and
 
1234
 continues counting up to FFh. This allows it to cover the entire 262 line
 
1235
 display.
 
1236
 
 
1237
 The H counter counts up from 00h to E9h, then it jumps back to 93h and
 
1238
 continues counting up to FFh. This allows it to cover an entire 342 pixel
 
1239
 line.
 
1240
*/
 
1241
 
 
1242
/*
 
1243
 
 
1244
 - The 80th sprite has been drawn in 40-cell mode.
 
1245
 - The 64th sprite has been drawn in 32-cell mode.
 
1246
 - Twenty sprites on the same scanline have been drawn in 40 cell mode.
 
1247
 - Sixteen sprites on the same scanline have been drawn in 32 cell mode.
 
1248
 - 320 pixels worth of sprite data has been drawn on the same scanline
 
1249
   in 40 cell mode.
 
1250
 - 256 pixels worth of sprite data has been drawn on the same scanline
 
1251
   in 32 cell mode.
 
1252
 - The currently drawn sprite has a link field of zero.
 
1253
 
 
1254
*/
 
1255
 
 
1256
/*
 
1257
 
 
1258
 $05 - Sprite Attribute Table Base Address
 
1259
 -----------------------------------------
 
1260
 
 
1261
 Bits 6-0 of this register correspond to bits A15-A09 of the sprite
 
1262
 attribute table.
 
1263
 
 
1264
 In 40-cell mode, A09 is always forced to zero.
 
1265
 
 
1266
*/
 
1267
 
 
1268
static void genesis_render_spriteline_to_spritebuffer(int scanline)
 
1269
{
 
1270
        int screenwidth;
 
1271
        int maxsprites=0;
 
1272
        int maxpixels=0;
 
1273
        UINT16 base_address=0;
 
1274
 
 
1275
 
 
1276
 
 
1277
        screenwidth = MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1);
 
1278
 
 
1279
        switch (screenwidth&3)
 
1280
        {
 
1281
                case 0: maxsprites = 64; maxpixels = 256; base_address = (MEGADRIVE_REG05_SPRITE_ADDR&0x7f)<<9; break;
 
1282
                case 1: maxsprites = 64; maxpixels = 256; base_address = (MEGADRIVE_REG05_SPRITE_ADDR&0x7f)<<9; break;
 
1283
                case 2: maxsprites = 80; maxpixels = 320; base_address = (MEGADRIVE_REG05_SPRITE_ADDR&0x7e)<<9; break;
 
1284
                case 3: maxsprites = 80; maxpixels = 320; base_address = (MEGADRIVE_REG05_SPRITE_ADDR&0x7e)<<9; break;
 
1285
        }
 
1286
 
 
1287
 
 
1288
        /* Clear our Render Buffer */
 
1289
        memset(sprite_renderline, 0, 1024);
 
1290
 
 
1291
 
 
1292
        {
 
1293
                int spritenum;
 
1294
                int ypos,xpos,addr;
 
1295
                int drawypos;
 
1296
                int /*drawwidth,*/ drawheight;
 
1297
                int spritemask = 0;
 
1298
                UINT8 height,width=0,link=0,xflip,yflip,colour,pri;
 
1299
 
 
1300
                /* Get Sprite Attribs */
 
1301
                spritenum = 0;
 
1302
 
 
1303
                //if (scanline==40) mame_printf_debug("spritelist start base %04x\n",base_address);
 
1304
 
 
1305
                do
 
1306
                {
 
1307
                        //UINT16 value1,value2,value3,value4;
 
1308
 
 
1309
                        //value1 = megadrive_vdp_vram[((base_address>>1)+spritenum*4)+0x0];
 
1310
                        //value2 = megadrive_vdp_vram[((base_address>>1)+spritenum*4)+0x1];
 
1311
                        //value3 = megadrive_vdp_vram[((base_address>>1)+spritenum*4)+0x2];
 
1312
                        //value4 = megadrive_vdp_vram[((base_address>>1)+spritenum*4)+0x3];
 
1313
 
 
1314
                        ypos  = (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x0] & 0x01ff)>>0; /* 0x03ff? */ // puyo puyo requires 0x1ff mask, not 0x3ff, see speech bubble corners
 
1315
                        height= (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x1] & 0x0300)>>8;
 
1316
                        width = (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x1] & 0x0c00)>>10;
 
1317
                        link  = (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x1] & 0x007f)>>0;
 
1318
                        xpos  = (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x3) & 0x01ff)>>0; /* 0x03ff? */ // pirates gold has a sprite with co-ord 0x200...
 
1319
 
 
1320
                        if(megadrive_imode==3)
 
1321
                        {
 
1322
                                ypos  = (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x0] & 0x03ff)>>0; /* 0x3ff requried in interlace mode (sonic 2 2 player) */
 
1323
                                drawypos = ypos - 256;
 
1324
                                drawheight = (height+1)*16;
 
1325
                        }
 
1326
                        else
 
1327
                        {
 
1328
                                ypos  = (megadrive_vdp_internal_sprite_attribute_table[(spritenum*4)+0x0] & 0x01ff)>>0; /* 0x03ff? */ // puyo puyo requires 0x1ff mask, not 0x3ff, see speech bubble corners
 
1329
                                drawypos = ypos - 128;
 
1330
                                drawheight = (height+1)*8;
 
1331
                        }
 
1332
 
 
1333
 
 
1334
 
 
1335
                        //if (scanline==40) mame_printf_debug("xpos %04x ypos %04x\n",xpos,ypos);
 
1336
 
 
1337
                        if ((drawypos<=scanline) && ((drawypos+drawheight)>scanline))
 
1338
                        {
 
1339
 
 
1340
                                addr  = (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x2) & 0x07ff)>>0;
 
1341
                                xflip = (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x2) & 0x0800)>>11;
 
1342
                                yflip = (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x2) & 0x1000)>>12;
 
1343
                                colour= (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x2) & 0x6000)>>13;
 
1344
                                pri   = (MEGADRIV_VDP_VRAM(((base_address>>1)+spritenum*4)+0x2) & 0x8000)>>15;
 
1345
 
 
1346
                                if(megadrive_imode==3)
 
1347
                                {
 
1348
                                        addr<<=1;
 
1349
                                        addr &=0x7ff;
 
1350
                                }
 
1351
 
 
1352
                                //drawwidth = (width+1)*8;
 
1353
                                if (pri==1) pri = 0x80;
 
1354
                                else pri = 0x40;
 
1355
 
 
1356
                                /* todo: fix me, I'm sure this isn't right but sprite 0 + other sprite seem to do something..
 
1357
                   maybe spritemask|=2 should be set for anything < 0x40 ?*/
 
1358
                                if (xpos==0x00) spritemask|=1;
 
1359
 
 
1360
                                //if (xpos==0x01) spritemask|=2;
 
1361
                                //if (xpos==0x04) spritemask|=2;  // sonic 2 title screen
 
1362
                                //if (xpos==0x08) spritemask|=2;  // rocket night adventures
 
1363
                                //if (xpos==0x10) spritemask|=2;  // mercs l1 boss
 
1364
                                //if (xpos==0x0a) spritemask|=2;  // legend of galahad
 
1365
                                //if (xpos==0x21) spritemask|=2;  // shadow of the beast?
 
1366
                                if ((xpos>0) && (xpos<0x40)) spritemask|=2;
 
1367
 
 
1368
                                if (spritemask==0x3)
 
1369
                                        return;
 
1370
                                /* end todo: */
 
1371
 
 
1372
                                {
 
1373
                                        //int xdraw;
 
1374
                                        int xtile;
 
1375
                                        int yline = scanline - drawypos;
 
1376
 
 
1377
                                        for (xtile=0;xtile<width+1;xtile++)
 
1378
                                        {
 
1379
                                                int dat;
 
1380
 
 
1381
                                                if (!xflip)
 
1382
                                                {
 
1383
                                                        UINT16 base_addr;
 
1384
                                                        int xxx;
 
1385
                                                        UINT32 gfxdata;
 
1386
                                                        int loopcount;
 
1387
 
 
1388
                                                        if(megadrive_imode==3)
 
1389
                                                        {
 
1390
                                                                if (!yflip) base_addr = (addr<<4)+(xtile*((height+1)*(2*16)))+(yline*2);
 
1391
                                                                else base_addr = (addr<<4)+(xtile*((height+1)*(2*16)))+((((height+1)*16)-yline-1)*2);
 
1392
                                                        }
 
1393
                                                        else
 
1394
                                                        {
 
1395
                                                                if (!yflip) base_addr = (addr<<4)+(xtile*((height+1)*(2*8)))+(yline*2);
 
1396
                                                                else base_addr = (addr<<4)+(xtile*((height+1)*(2*8)))+((((height+1)*8)-yline-1)*2);
 
1397
                                                        }
 
1398
 
 
1399
                                                        xxx = (xpos+xtile*8)&0x1ff;
 
1400
 
 
1401
                                                        gfxdata = MEGADRIV_VDP_VRAM(base_addr+1) | (MEGADRIV_VDP_VRAM(base_addr+0)<<16);
 
1402
 
 
1403
                                                        for(loopcount=0;loopcount<8;loopcount++)
 
1404
                                                        {
 
1405
                                                                dat = (gfxdata & 0xf0000000)>>28; gfxdata <<=4;
 
1406
                                                                if (dat) { if (!sprite_renderline[xxx]) { sprite_renderline[xxx] = dat | (colour<<4)| pri; } else { megadrive_sprite_collision = 1; } }
 
1407
                                                                xxx++;xxx&=0x1ff;
 
1408
                                                                if (--maxpixels == 0x00) return;
 
1409
                                                        }
 
1410
 
 
1411
                                                }
 
1412
                                                else
 
1413
                                                {
 
1414
                                                        UINT16 base_addr;
 
1415
                                                        int xxx;
 
1416
                                                        UINT32 gfxdata;
 
1417
 
 
1418
                                                        int loopcount;
 
1419
 
 
1420
                                                        if(megadrive_imode==3)
 
1421
                                                        {
 
1422
                                                                if (!yflip) base_addr = (addr<<4)+(((width-xtile))*((height+1)*(2*16)))+(yline*2);
 
1423
                                                                else base_addr =      (addr<<4)+(((width-xtile))*((height+1)*(2*16)))+((((height+1)*16)-yline-1)*2);
 
1424
 
 
1425
                                                        }
 
1426
                                                        else
 
1427
                                                        {
 
1428
                                                                if (!yflip) base_addr = (addr<<4)+(((width-xtile))*((height+1)*(2*8)))+(yline*2);
 
1429
                                                                else base_addr =        (addr<<4)+(((width-xtile))*((height+1)*(2*8)))+((((height+1)*8)-yline-1)*2);
 
1430
                                                        }
 
1431
 
 
1432
                                                        xxx = (xpos+xtile*8)&0x1ff;
 
1433
 
 
1434
                                                        gfxdata = MEGADRIV_VDP_VRAM((base_addr+1)&0x7fff) | (MEGADRIV_VDP_VRAM((base_addr+0)&0x7fff)<<16);
 
1435
 
 
1436
                                                        for(loopcount=0;loopcount<8;loopcount++)
 
1437
                                                        {
 
1438
                                                                dat = (gfxdata & 0x0000000f)>>0; gfxdata >>=4;
 
1439
                                                                if (dat) { if (!sprite_renderline[xxx]) { sprite_renderline[xxx] = dat | (colour<<4)| pri; } else { megadrive_sprite_collision = 1; } }
 
1440
                                                                xxx++;xxx&=0x1ff;
 
1441
                                                                if (--maxpixels == 0x00) return;
 
1442
                                                        }
 
1443
 
 
1444
                                                }
 
1445
                                        }
 
1446
                                }
 
1447
                        }
 
1448
 
 
1449
                        spritenum = link;
 
1450
                        maxsprites--;
 
1451
                }
 
1452
                while ((maxsprites>=0) && (link!=0));
 
1453
 
 
1454
 
 
1455
        }
 
1456
}
 
1457
 
 
1458
/* Clean up this function (!) */
 
1459
static void genesis_render_videoline_to_videobuffer(int scanline)
 
1460
{
 
1461
        UINT16 base_a;
 
1462
        UINT16 base_w=0;
 
1463
        UINT16 base_b;
 
1464
 
 
1465
        UINT16 size;
 
1466
        UINT16 hsize = 64;
 
1467
        UINT16 vsize = 64;
 
1468
        UINT16 window_right;
 
1469
//  UINT16 window_hpos;
 
1470
        UINT16 window_down;
 
1471
//  UINT16 window_vpos;
 
1472
        UINT16 hscroll_base;
 
1473
//  UINT8  vscroll_mode;
 
1474
//  UINT8  hscroll_mode;
 
1475
        int window_firstline;
 
1476
        int window_lastline;
 
1477
        int window_firstcol;
 
1478
        int window_lastcol;
 
1479
        int screenwidth;
 
1480
        int numcolumns = 0;
 
1481
        int hscroll_a = 0;
 
1482
        int hscroll_b = 0;
 
1483
        int x;
 
1484
        int window_hsize=0;
 
1485
        int window_vsize=0;
 
1486
        int window_is_bugged = 0;
 
1487
        int non_window_firstcol;
 
1488
        int non_window_lastcol;
 
1489
        int screenheight = MEGADRIVE_REG01_240_LINE?240:224;
 
1490
 
 
1491
        /* Clear our Render Buffer */
 
1492
        for (x=0;x<320;x++)
 
1493
        {
 
1494
                video_renderline[x]=MEGADRIVE_REG07_BGCOLOUR | 0x20000; // mark as BG
 
1495
        }
 
1496
 
 
1497
        memset(highpri_renderline, 0, 320);
 
1498
 
 
1499
        /* is this line enabled? */
 
1500
        if (!MEGADRIVE_REG01_DISP_ENABLE)
 
1501
        {
 
1502
                //mame_printf_debug("line disabled %d\n",scanline);
 
1503
                return;
 
1504
        }
 
1505
 
 
1506
        /* looks different? */
 
1507
        if (MEGADRIVE_REG0_DISPLAY_DISABLE)
 
1508
        {
 
1509
                return;
 
1510
        }
 
1511
 
 
1512
 
 
1513
 
 
1514
        base_a = MEGADRIVE_REG02_PATTERN_ADDR_A << 13;
 
1515
 
 
1516
        base_b = MEGADRIVE_REG04_PATTERN_ADDR_B << 13;
 
1517
        size  = MEGADRIVE_REG10_HSCROLL_SIZE | (MEGADRIVE_REG10_VSCROLL_SIZE<<4);
 
1518
        window_right = MEGADRIVE_REG11_WINDOW_RIGHT;
 
1519
//  window_hpos = MEGADRIVE_REG11_WINDOW_HPOS;
 
1520
        window_down = MEGADRIVE_REG12_WINDOW_DOWN;
 
1521
//  window_vpos = MEGADRIVE_REG12_WINDOW_VPOS;
 
1522
 
 
1523
        screenwidth = MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1);
 
1524
 
 
1525
        switch (screenwidth)
 
1526
        {
 
1527
                case 0: numcolumns = 32; window_hsize = 32; window_vsize = 32; base_w = (MEGADRIVE_REG03_PATTERN_ADDR_W&0x1f) << 11; break;
 
1528
                case 1: numcolumns = 32; window_hsize = 32; window_vsize = 32; base_w = (MEGADRIVE_REG03_PATTERN_ADDR_W&0x1f) << 11; break;
 
1529
                case 2: numcolumns = 40; window_hsize = 64; window_vsize = 32; base_w = (MEGADRIVE_REG03_PATTERN_ADDR_W&0x1e) << 11; break;
 
1530
                case 3: numcolumns = 40; window_hsize = 64; window_vsize = 32; base_w = (MEGADRIVE_REG03_PATTERN_ADDR_W&0x1e) << 11; break; // talespin cares about base mask, used for status bar
 
1531
        }
 
1532
 
 
1533
        //mame_printf_debug("screenwidth %d\n",screenwidth);
 
1534
 
 
1535
        //base_w = Machine->rand()&0xff;
 
1536
 
 
1537
        /* Calculate Exactly where we're going to draw the Window, and if the Window Bug applies */
 
1538
        window_is_bugged = 0;
 
1539
        if (window_right)
 
1540
        {
 
1541
                window_firstcol = MEGADRIVE_REG11_WINDOW_HPOS*16;
 
1542
                window_lastcol = numcolumns*8;
 
1543
                if (window_firstcol>window_lastcol) window_firstcol = window_lastcol;
 
1544
 
 
1545
                non_window_firstcol = 0;
 
1546
                non_window_lastcol = window_firstcol;
 
1547
        }
 
1548
        else
 
1549
        {
 
1550
                window_firstcol = 0;
 
1551
                window_lastcol = MEGADRIVE_REG11_WINDOW_HPOS*16;
 
1552
                if (window_lastcol>numcolumns*8) window_lastcol = numcolumns*8;
 
1553
 
 
1554
                non_window_firstcol = window_lastcol;
 
1555
                non_window_lastcol = numcolumns*8;
 
1556
 
 
1557
                if (window_lastcol!=0) window_is_bugged=1;
 
1558
        }
 
1559
 
 
1560
        if (window_down)
 
1561
        {
 
1562
                window_firstline = MEGADRIVE_REG12_WINDOW_VPOS*8;
 
1563
                window_lastline = screenheight; // 240 in PAL?
 
1564
                if (window_firstline>screenheight) window_firstline = screenheight;
 
1565
        }
 
1566
        else
 
1567
        {
 
1568
                window_firstline = 0;
 
1569
                window_lastline = MEGADRIVE_REG12_WINDOW_VPOS*8;
 
1570
                if (window_lastline>screenheight) window_lastline = screenheight;
 
1571
        }
 
1572
 
 
1573
        /* if we're on a window scanline between window_firstline and window_lastline the window is the full width of the screen */
 
1574
        if (scanline>=window_firstline && scanline < window_lastline)
 
1575
        {
 
1576
                window_firstcol = 0; window_lastcol = numcolumns*8; // window is full-width of the screen
 
1577
                non_window_firstcol = 0; non_window_lastcol=0; // disable non-window
 
1578
        }
 
1579
 
 
1580
 
 
1581
//    vscroll_mode = MEGADRIVE_REG0B_VSCROLL_MODE;
 
1582
//    hscroll_mode = MEGADRIVE_REG0B_HSCROLL_MODE;
 
1583
    hscroll_base = MEGADRIVE_REG0D_HSCROLL_ADDR<<10;
 
1584
 
 
1585
        switch (size)
 
1586
        {
 
1587
                case 0x00: hsize = 32; vsize = 32; break;
 
1588
                case 0x01: hsize = 64; vsize = 32; break;
 
1589
                case 0x02: hsize = 64; vsize = 1; /* mame_printf_debug("Invalid HSize! %02x\n",size);*/ break;
 
1590
                case 0x03: hsize = 128;vsize = 32; break;
 
1591
 
 
1592
                case 0x10: hsize = 32; vsize = 64; break;
 
1593
                case 0x11: hsize = 64; vsize = 64; break;
 
1594
                case 0x12: hsize = 64; vsize = 1; /*mame_printf_debug("Invalid HSize! %02x\n",size);*/ break;
 
1595
                case 0x13: hsize = 128;vsize = 32;/*mame_printf_debug("Invalid Total Size! %02x\n",size);*/break;
 
1596
 
 
1597
                case 0x20: hsize = 32; vsize = 64; mame_printf_debug("Invalid VSize!\n"); break;
 
1598
                case 0x21: hsize = 64; vsize = 64; mame_printf_debug("Invalid VSize!\n"); break;
 
1599
                case 0x22: hsize = 64; vsize = 1; /*mame_printf_debug("Invalid HSize & Invalid VSize!\n");*/ break;
 
1600
                case 0x23: hsize = 128;vsize = 64; mame_printf_debug("Invalid VSize!\n"); break;
 
1601
 
 
1602
                case 0x30: hsize = 32; vsize = 128; break;
 
1603
                case 0x31: hsize = 64; vsize = 64; /*mame_printf_debug("Invalid Total Size! %02x\n",size);*/break; // super skidmarks attempts this..
 
1604
                case 0x32: hsize = 64; vsize = 1; /*mame_printf_debug("Invalid HSize & Invalid Total Size!\n");*/ break;
 
1605
                case 0x33: hsize = 128;vsize = 128; mame_printf_debug("Invalid Total Size! %02x\n",size);break;
 
1606
        }
 
1607
 
 
1608
        switch (MEGADRIVE_REG0B_HSCROLL_MODE)
 
1609
        {
 
1610
                case 0x00: // Full Screen Scroll
 
1611
                        hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0);
 
1612
                        hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1);
 
1613
                        break;
 
1614
 
 
1615
                case 0x01: // 'Broken' Line Scroll
 
1616
                        if(megadrive_imode==3)
 
1617
                        {
 
1618
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+((scanline>>1)&7)*2);
 
1619
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+((scanline>>1)&7)*2);
 
1620
                        }
 
1621
                        else
 
1622
                        {
 
1623
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+(scanline&7)*2);
 
1624
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+(scanline&7)*2);
 
1625
                        }
 
1626
                        break;
 
1627
 
 
1628
                case 0x02: // Cell Scroll
 
1629
                        if(megadrive_imode==3)
 
1630
                        {
 
1631
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+((scanline>>1)&~7)*2);
 
1632
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+((scanline>>1)&~7)*2);
 
1633
                        }
 
1634
                        else
 
1635
                        {
 
1636
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+(scanline&~7)*2);
 
1637
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+(scanline&~7)*2);
 
1638
                        }
 
1639
                        break;
 
1640
 
 
1641
                case 0x03: // Full Line Scroll
 
1642
                        if(megadrive_imode==3)
 
1643
                        {
 
1644
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+(scanline>>1)*2);
 
1645
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+(scanline>>1)*2);
 
1646
                        }
 
1647
                        else
 
1648
                        {
 
1649
                                hscroll_a = MEGADRIV_VDP_VRAM((hscroll_base>>1)+0+scanline*2);
 
1650
                                hscroll_b = MEGADRIV_VDP_VRAM((hscroll_base>>1)+1+scanline*2);
 
1651
                        }
 
1652
                        break;
 
1653
        }
 
1654
 
 
1655
        /* Low Priority B Tiles */
 
1656
        {
 
1657
                int column;
 
1658
                int vscroll;
 
1659
 
 
1660
                for (column=0;column<numcolumns/2;column++)
 
1661
                {       /* 20x 16x1 blocks */
 
1662
                        int vcolumn;
 
1663
                        int dpos;
 
1664
 
 
1665
                        /* Get V Scroll Value for this block */
 
1666
 
 
1667
                        dpos = column*16;
 
1668
 
 
1669
                        {
 
1670
                                /* hscroll is not divisible by 8, this segment will contain 3 tiles, 1 partial, 1 whole, 1 partial */
 
1671
                                int hscroll_part = 8-(hscroll_b%8);
 
1672
                                int hcolumn;
 
1673
                                int tile_base;
 
1674
                                int tile_dat;
 
1675
                                int tile_addr;
 
1676
                                int tile_xflip;
 
1677
                                int tile_yflip;
 
1678
                                int tile_colour;
 
1679
                                int tile_pri;
 
1680
                                int dat;
 
1681
 
 
1682
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
1683
                                {
 
1684
                                        if (hscroll_b&0xf) vscroll = megadrive_vdp_vsram[((column-1)*2+1)&0x3f];
 
1685
                                        else vscroll = megadrive_vdp_vsram[((column)*2+1)&0x3f];
 
1686
                                }
 
1687
                                else
 
1688
                                {
 
1689
                                        vscroll = megadrive_vdp_vsram[1];
 
1690
                                }
 
1691
 
 
1692
                                hcolumn = ((column*2-1)-(hscroll_b>>3))&(hsize-1);
 
1693
 
 
1694
                                if(megadrive_imode==3)
 
1695
                                {
 
1696
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
1697
                                        tile_base = (base_b>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
1698
 
 
1699
                                }
 
1700
                                else
 
1701
                                {
 
1702
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
1703
                                        tile_base = (base_b>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
1704
                                }
 
1705
 
 
1706
 
 
1707
                                tile_base &=0x7fff;
 
1708
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
1709
                                tile_xflip = (tile_dat&0x0800);
 
1710
                                tile_yflip = (tile_dat&0x1000);
 
1711
                                tile_colour =(tile_dat&0x6000)>>13;
 
1712
                                tile_pri = (tile_dat&0x8000)>>15;
 
1713
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
1714
 
 
1715
                                if(megadrive_imode==3)
 
1716
                                {
 
1717
                                        tile_addr <<=1;
 
1718
                                        tile_addr &=0x7fff;
 
1719
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
1720
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
1721
                                }
 
1722
                                else
 
1723
                                {
 
1724
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
1725
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
1726
                                }
 
1727
 
 
1728
                                if (!tile_xflip)
 
1729
                                {
 
1730
                                        /* 8 pixels */
 
1731
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1732
                                        int shift;
 
1733
 
 
1734
                                        for (shift=hscroll_part;shift<8;shift++)
 
1735
                                        {
 
1736
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1737
                                                dpos++;
 
1738
                                        }
 
1739
                                }
 
1740
                                else
 
1741
                                {
 
1742
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1743
                                        int shift;
 
1744
                                        for (shift=hscroll_part;shift<8;shift++)
 
1745
                                        {
 
1746
                                                dat = (gfxdata>>(shift*4) )&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1747
                                                dpos++;
 
1748
                                        }
 
1749
                                }
 
1750
 
 
1751
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
1752
                                {
 
1753
                                        if (hscroll_b&0xf) vscroll = megadrive_vdp_vsram[((column-1)*2+1)&0x3f];
 
1754
                                        else vscroll = megadrive_vdp_vsram[((column)*2+1)&0x3f];
 
1755
                                }
 
1756
                                else
 
1757
                                {
 
1758
                                        vscroll = megadrive_vdp_vsram[1];
 
1759
                                }
 
1760
 
 
1761
                                hcolumn = ((column*2)-(hscroll_b>>3))&(hsize-1);
 
1762
 
 
1763
                                if(megadrive_imode==3)
 
1764
                                {
 
1765
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
1766
                                        tile_base = (base_b>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
1767
                                }
 
1768
                                else
 
1769
                                {
 
1770
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
1771
                                        tile_base = (base_b>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
1772
                                }
 
1773
 
 
1774
                                tile_base &=0x7fff;
 
1775
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
1776
                                tile_xflip = (tile_dat&0x0800);
 
1777
                                tile_yflip = (tile_dat&0x1000);
 
1778
                                tile_colour =(tile_dat&0x6000)>>13;
 
1779
                                tile_pri = (tile_dat&0x8000)>>15;
 
1780
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
1781
 
 
1782
                                if(megadrive_imode==3)
 
1783
                                {
 
1784
                                        tile_addr <<=1;
 
1785
                                        tile_addr &=0x7fff;
 
1786
 
 
1787
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
1788
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
1789
                                }
 
1790
                                else
 
1791
                                {
 
1792
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
1793
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
1794
                                }
 
1795
 
 
1796
                                if (!tile_xflip)
 
1797
                                {
 
1798
                                        /* 8 pixels */
 
1799
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1800
                                        int shift;
 
1801
 
 
1802
                                        for (shift=0;shift<8;shift++)
 
1803
                                        {
 
1804
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1805
                                                dpos++;
 
1806
                                        }
 
1807
                                }
 
1808
                                else
 
1809
                                {
 
1810
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1811
                                        int shift;
 
1812
                                        for (shift=0;shift<8;shift++)
 
1813
                                        {
 
1814
                                                dat = (gfxdata>>(shift*4))&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1815
                                                dpos++;
 
1816
                                        }
 
1817
                                }
 
1818
 
 
1819
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
1820
                                {
 
1821
                                        vscroll = megadrive_vdp_vsram[((column)*2+1)&0x3f];
 
1822
                                }
 
1823
                                else
 
1824
                                {
 
1825
                                        vscroll = megadrive_vdp_vsram[1];
 
1826
                                }
 
1827
 
 
1828
                                hcolumn = ((column*2+1)-(hscroll_b>>3))&(hsize-1);
 
1829
 
 
1830
                                if(megadrive_imode==3)
 
1831
                                {
 
1832
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
1833
                                        tile_base = (base_b>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
1834
                                }
 
1835
                                else
 
1836
                                {
 
1837
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
1838
                                        tile_base = (base_b>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
1839
                                }
 
1840
 
 
1841
                                tile_base &=0x7fff;
 
1842
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
1843
                                tile_xflip = (tile_dat&0x0800);
 
1844
                                tile_yflip = (tile_dat&0x1000);
 
1845
                                tile_colour =(tile_dat&0x6000)>>13;
 
1846
                                tile_pri = (tile_dat&0x8000)>>15;
 
1847
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
1848
 
 
1849
                                if(megadrive_imode==3)
 
1850
                                {
 
1851
                                        tile_addr <<=1;
 
1852
                                        tile_addr &=0x7fff;
 
1853
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
1854
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
1855
                                }
 
1856
                                else
 
1857
                                {
 
1858
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
1859
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
1860
                                }
 
1861
 
 
1862
 
 
1863
                                if (!tile_xflip)
 
1864
                                {
 
1865
                                        /* 8 pixels */
 
1866
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1867
                                        int shift;
 
1868
 
 
1869
                                        for (shift=0;shift<(hscroll_part);shift++)
 
1870
                                        {
 
1871
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1872
                                                dpos++;
 
1873
                                        }
 
1874
                                }
 
1875
                                else
 
1876
                                {
 
1877
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1878
                                        int shift;
 
1879
                                        for (shift=0;shift<(hscroll_part);shift++)
 
1880
                                        {
 
1881
                                                dat = (gfxdata>>(shift*4) )&0x000f;  if (!tile_pri) { if(dat) video_renderline[dpos] = dat | (tile_colour<<4); }  else highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1882
                                                dpos++;
 
1883
                                        }
 
1884
                                }
 
1885
                        }
 
1886
                }
 
1887
                /* END */
 
1888
        }
 
1889
        /* Low Priority A Tiles + Window(!) */
 
1890
 
 
1891
        {
 
1892
                int column;
 
1893
                int vscroll;
 
1894
 
 
1895
                for (column=window_firstcol/16;column<window_lastcol/16;column++)
 
1896
                {
 
1897
                        int vcolumn;
 
1898
                        int dpos;
 
1899
 
 
1900
                        int hcolumn;
 
1901
                        int tile_base;
 
1902
                        int tile_dat;
 
1903
                        int tile_addr;
 
1904
                        int tile_xflip;
 
1905
                        int tile_yflip;
 
1906
                        int tile_colour;
 
1907
                        int tile_pri;
 
1908
                        int dat;
 
1909
 
 
1910
                        vcolumn = scanline&((window_vsize*8)-1);
 
1911
                        dpos = column*16;
 
1912
                        hcolumn = (column*2)&(window_hsize-1);
 
1913
 
 
1914
                        if(megadrive_imode==3)
 
1915
                        {
 
1916
                                tile_base = (base_w>>1)+((vcolumn>>4)*window_hsize)+hcolumn;
 
1917
                        }
 
1918
                        else
 
1919
                        {
 
1920
                                tile_base = (base_w>>1)+((vcolumn>>3)*window_hsize)+hcolumn;
 
1921
                        }
 
1922
 
 
1923
                        tile_base &=0x7fff;
 
1924
                        tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
1925
                        tile_xflip = (tile_dat&0x0800);
 
1926
                        tile_yflip = (tile_dat&0x1000);
 
1927
                        tile_colour =(tile_dat&0x6000)>>13;
 
1928
                        tile_pri = (tile_dat&0x8000)>>15;
 
1929
                        tile_addr = ((tile_dat&0x07ff)<<4);
 
1930
 
 
1931
                        if(megadrive_imode==3)
 
1932
                        {
 
1933
                                tile_addr <<=1;
 
1934
                                tile_addr &=0x7fff;
 
1935
                        }
 
1936
 
 
1937
                        if(megadrive_imode==3)
 
1938
                        {
 
1939
                                if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
1940
                                else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
1941
                        }
 
1942
                        else
 
1943
                        {
 
1944
                                if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
1945
                                else tile_addr+=((7-vcolumn)&7)*2;
 
1946
                        }
 
1947
 
 
1948
                        if (!tile_xflip)
 
1949
                        {
 
1950
                                /* 8 pixels */
 
1951
                                UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1952
                                int shift;
 
1953
 
 
1954
                                for (shift=0;shift<8;shift++)
 
1955
                                {
 
1956
                                        dat = (gfxdata>>(28-(shift*4)))&0x000f;
 
1957
                                        if (!tile_pri)
 
1958
                                        {
 
1959
                                                if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
1960
                                        }
 
1961
                                        else
 
1962
                                        {
 
1963
                                                if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1964
                                                else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
1965
                                        }
 
1966
                                        dpos++;
 
1967
                                }
 
1968
                        }
 
1969
                        else
 
1970
                        {
 
1971
                                UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
1972
                                int shift;
 
1973
                                for (shift=0;shift<8;shift++)
 
1974
                                {
 
1975
                                        dat = (gfxdata>>(shift*4) )&0x000f;
 
1976
                                        if (!tile_pri)
 
1977
                                        {
 
1978
                                                if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
1979
                                        }
 
1980
                                        else
 
1981
                                        {
 
1982
                                                if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
1983
                                                else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
1984
                                        }
 
1985
                                        dpos++;
 
1986
 
 
1987
                                }
 
1988
                        }
 
1989
 
 
1990
 
 
1991
                        hcolumn = (column*2+1)&(window_hsize-1);
 
1992
                        if(megadrive_imode==3)
 
1993
                        {
 
1994
                                tile_base = (base_w>>1)+((vcolumn>>4)*window_hsize)+hcolumn;
 
1995
                        }
 
1996
                        else
 
1997
                        {
 
1998
                                tile_base = (base_w>>1)+((vcolumn>>3)*window_hsize)+hcolumn;
 
1999
                        }
 
2000
                        tile_base &=0x7fff;
 
2001
                        tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
2002
                        tile_xflip = (tile_dat&0x0800);
 
2003
                        tile_yflip = (tile_dat&0x1000);
 
2004
                        tile_colour =(tile_dat&0x6000)>>13;
 
2005
                        tile_pri = (tile_dat&0x8000)>>15;
 
2006
                        tile_addr = ((tile_dat&0x07ff)<<4);
 
2007
 
 
2008
                        if(megadrive_imode==3)
 
2009
                        {
 
2010
                                tile_addr <<=1;
 
2011
                                tile_addr &=0x7fff;
 
2012
                        }
 
2013
 
 
2014
                        if(megadrive_imode==3)
 
2015
                        {
 
2016
                                if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
2017
                                else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
2018
                        }
 
2019
                        else
 
2020
                        {
 
2021
                                if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
2022
                                else tile_addr+=((7-vcolumn)&7)*2;
 
2023
                        }
 
2024
 
 
2025
                        if (!tile_xflip)
 
2026
                        {
 
2027
                                /* 8 pixels */
 
2028
                                UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2029
                                int shift;
 
2030
 
 
2031
                                for (shift=0;shift<8;shift++)
 
2032
                                {
 
2033
                                        dat = (gfxdata>>(28-(shift*4)))&0x000f;
 
2034
                                        if (!tile_pri)
 
2035
                                        {
 
2036
                                                if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2037
                                        }
 
2038
                                        else
 
2039
                                        {
 
2040
                                                if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2041
                                                else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2042
                                        }
 
2043
                                        dpos++;
 
2044
                                }
 
2045
                        }
 
2046
                        else
 
2047
                        {
 
2048
                                UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2049
                                int shift;
 
2050
                                for (shift=0;shift<8;shift++)
 
2051
                                {
 
2052
                                        dat = (gfxdata>>(shift*4) )&0x000f;
 
2053
                                        if (!tile_pri)
 
2054
                                        {
 
2055
                                                if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2056
                                        }
 
2057
                                        else
 
2058
                                        {
 
2059
                                                if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2060
                                                else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2061
                                        }
 
2062
                                        dpos++;
 
2063
                                }
 
2064
                        }
 
2065
                }
 
2066
 
 
2067
                /* Non Window Part */
 
2068
 
 
2069
                for (column=non_window_firstcol/16;column<non_window_lastcol/16;column++)
 
2070
                {       /* 20x 16x1 blocks */
 
2071
                //  int xx;
 
2072
                        int vcolumn;
 
2073
                        int dpos;
 
2074
 
 
2075
                        dpos = column*16;
 
2076
 
 
2077
                        {       /* hscroll is not divisible by 8, this segment will contain 3 tiles, 1 partial, 1 whole, 1 partial */
 
2078
                                int hscroll_part = 8-(hscroll_a%8);
 
2079
                                int hcolumn;
 
2080
                                int tile_base;
 
2081
                                int tile_dat;
 
2082
                                int tile_addr;
 
2083
                                int tile_xflip;
 
2084
                                int tile_yflip;
 
2085
                                int tile_colour;
 
2086
                                int tile_pri;
 
2087
                                int dat;
 
2088
 
 
2089
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
2090
                                {
 
2091
                                        if (hscroll_a&0xf) vscroll = megadrive_vdp_vsram[((column-1)*2+0)&0x3f];
 
2092
                                        else vscroll = megadrive_vdp_vsram[((column)*2+0)&0x3f];
 
2093
                                }
 
2094
                                else
 
2095
                                {
 
2096
                                        vscroll = megadrive_vdp_vsram[0];
 
2097
                                }
 
2098
 
 
2099
 
 
2100
                                if ((!window_is_bugged) || ((hscroll_a&0xf)==0) || (column>non_window_firstcol/16)) hcolumn = ((column*2-1)-(hscroll_a>>3))&(hsize-1);
 
2101
                                else hcolumn = ((column*2+1)-(hscroll_a>>3))&(hsize-1);
 
2102
 
 
2103
                                if(megadrive_imode==3)
 
2104
                                {
 
2105
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
2106
                                }
 
2107
                                else
 
2108
                                {
 
2109
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
2110
                                }
 
2111
 
 
2112
                                if(megadrive_imode==3)
 
2113
                                {
 
2114
                                        tile_base = (base_a>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
2115
                                }
 
2116
                                else
 
2117
                                {
 
2118
                                        tile_base = (base_a>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
2119
                                }
 
2120
 
 
2121
 
 
2122
                                tile_base &=0x7fff;
 
2123
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
2124
                                tile_xflip = (tile_dat&0x0800);
 
2125
                                tile_yflip = (tile_dat&0x1000);
 
2126
                                tile_colour =(tile_dat&0x6000)>>13;
 
2127
                                tile_pri = (tile_dat&0x8000)>>15;
 
2128
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
2129
 
 
2130
                                if(megadrive_imode==3)
 
2131
                                {
 
2132
                                        tile_addr <<=1;
 
2133
                                        tile_addr &=0x7fff;
 
2134
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
2135
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
2136
                                }
 
2137
                                else
 
2138
                                {
 
2139
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
2140
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
2141
                                }
 
2142
 
 
2143
                                if (!tile_xflip)
 
2144
                                {
 
2145
                                        /* 8 pixels */
 
2146
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2147
                                        int shift;
 
2148
 
 
2149
                                        for (shift=hscroll_part;shift<8;shift++)
 
2150
                                        {
 
2151
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;
 
2152
                                                if (!tile_pri)
 
2153
                                                {
 
2154
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2155
                                                }
 
2156
                                                else
 
2157
                                                {
 
2158
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2159
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2160
                                                }
 
2161
                                                dpos++;
 
2162
                                        }
 
2163
                                }
 
2164
                                else
 
2165
                                {
 
2166
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2167
                                        int shift;
 
2168
                                        for (shift=hscroll_part;shift<8;shift++)
 
2169
                                        {
 
2170
                                                dat = (gfxdata>>(shift*4) )&0x000f;
 
2171
                                                if (!tile_pri)
 
2172
                                                {
 
2173
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2174
                                                }
 
2175
                                                else
 
2176
                                                {
 
2177
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2178
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2179
                                                }
 
2180
                                                dpos++;
 
2181
                                        }
 
2182
                                }
 
2183
 
 
2184
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
2185
                                {
 
2186
                                        if (hscroll_a&0xf) vscroll = megadrive_vdp_vsram[((column-1)*2+0)&0x3f];
 
2187
                                        else vscroll = megadrive_vdp_vsram[((column)*2+0)&0x3f];
 
2188
                                }
 
2189
                                else
 
2190
                                {
 
2191
                                        vscroll = megadrive_vdp_vsram[0];
 
2192
                                }
 
2193
 
 
2194
                                if ((!window_is_bugged) || ((hscroll_a&0xf)==0) || (column>non_window_firstcol/16)) hcolumn = ((column*2)-(hscroll_a>>3))&(hsize-1); // not affected by bug?
 
2195
                                else
 
2196
                                {
 
2197
                                        if ((hscroll_a&0xf)<8) hcolumn = ((column*2)-(hscroll_a>>3))&(hsize-1);
 
2198
                                        else hcolumn = ((column*2+2)-(hscroll_a>>3))&(hsize-1);
 
2199
                                }
 
2200
 
 
2201
 
 
2202
                                if(megadrive_imode==3)
 
2203
                                {
 
2204
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
2205
                                        tile_base = (base_a>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
2206
                                }
 
2207
                                else
 
2208
                                {
 
2209
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
2210
                                        tile_base = (base_a>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
2211
                                }
 
2212
 
 
2213
                                tile_base &=0x7fff;
 
2214
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
2215
                                tile_xflip = (tile_dat&0x0800);
 
2216
                                tile_yflip = (tile_dat&0x1000);
 
2217
                                tile_colour =(tile_dat&0x6000)>>13;
 
2218
                                tile_pri = (tile_dat&0x8000)>>15;
 
2219
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
2220
 
 
2221
 
 
2222
                                if(megadrive_imode==3)
 
2223
                                {
 
2224
                                        tile_addr <<=1;
 
2225
                                        tile_addr &=0x7fff;
 
2226
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
2227
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
2228
                                }
 
2229
                                else
 
2230
                                {
 
2231
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
2232
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
2233
                                }
 
2234
 
 
2235
                                if (!tile_xflip)
 
2236
                                {
 
2237
                                        /* 8 pixels */
 
2238
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2239
                                        int shift;
 
2240
 
 
2241
                                        for (shift=0;shift<8;shift++)
 
2242
                                        {
 
2243
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;
 
2244
                                                if (!tile_pri)
 
2245
                                                {
 
2246
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2247
                                                }
 
2248
                                                else
 
2249
                                                {
 
2250
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2251
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2252
                                                }
 
2253
                                                dpos++;
 
2254
                                        }
 
2255
                                }
 
2256
                                else
 
2257
                                {
 
2258
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2259
                                        int shift;
 
2260
                                        for (shift=0;shift<8;shift++)
 
2261
                                        {
 
2262
                                                dat = (gfxdata>>(shift*4) )&0x000f;
 
2263
                                                if (!tile_pri)
 
2264
                                                {
 
2265
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2266
                                                }
 
2267
                                                else
 
2268
                                                {
 
2269
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2270
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2271
                                                }
 
2272
                                                dpos++;
 
2273
                                        }
 
2274
                                }
 
2275
 
 
2276
                                if (MEGADRIVE_REG0B_VSCROLL_MODE)
 
2277
                                {
 
2278
                                        vscroll = megadrive_vdp_vsram[((column)*2+0)&0x3f];
 
2279
                                }
 
2280
                                else
 
2281
                                {
 
2282
                                        vscroll = megadrive_vdp_vsram[0];
 
2283
                                }
 
2284
 
 
2285
                                if ((!window_is_bugged) || ((hscroll_a&0xf)==0) || (column>non_window_firstcol/16)) hcolumn = ((column*2+1)-(hscroll_a>>3))&(hsize-1);
 
2286
                                else hcolumn = ((column*2+1)-(hscroll_a>>3))&(hsize-1);
 
2287
 
 
2288
                                if(megadrive_imode==3)
 
2289
                                {
 
2290
                                        vcolumn = (vscroll + scanline)&((vsize*16)-1);
 
2291
                                        tile_base = (base_a>>1)+((vcolumn>>4)*hsize)+hcolumn;
 
2292
                                }
 
2293
                                else
 
2294
                                {
 
2295
                                        vcolumn = (vscroll + scanline)&((vsize*8)-1);
 
2296
                                        tile_base = (base_a>>1)+((vcolumn>>3)*hsize)+hcolumn;
 
2297
                                }
 
2298
                                tile_base &=0x7fff;
 
2299
                                tile_dat = MEGADRIV_VDP_VRAM(tile_base);
 
2300
                                tile_xflip = (tile_dat&0x0800);
 
2301
                                tile_yflip = (tile_dat&0x1000);
 
2302
                                tile_colour =(tile_dat&0x6000)>>13;
 
2303
                                tile_pri = (tile_dat&0x8000)>>15;
 
2304
                                tile_addr = ((tile_dat&0x07ff)<<4);
 
2305
 
 
2306
                                if(megadrive_imode==3)
 
2307
                                {
 
2308
                                        tile_addr <<=1;
 
2309
                                        tile_addr &=0x7fff;
 
2310
                                }
 
2311
 
 
2312
                                if(megadrive_imode==3)
 
2313
                                {
 
2314
                                        if (!tile_yflip) tile_addr+=(vcolumn&0xf)*2;
 
2315
                                        else tile_addr+=((0xf-vcolumn)&0xf)*2;
 
2316
                                }
 
2317
                                else
 
2318
                                {
 
2319
                                        if (!tile_yflip) tile_addr+=(vcolumn&7)*2;
 
2320
                                        else tile_addr+=((7-vcolumn)&7)*2;
 
2321
                                }
 
2322
 
 
2323
                                if (!tile_xflip)
 
2324
                                {
 
2325
                                        /* 8 pixels */
 
2326
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2327
                                        int shift;
 
2328
 
 
2329
                                        for (shift=0;shift<(hscroll_part);shift++)
 
2330
                                        {
 
2331
                                                dat = (gfxdata>>(28-(shift*4)))&0x000f;
 
2332
                                                if (!tile_pri)
 
2333
                                                {
 
2334
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2335
                                                }
 
2336
                                                else
 
2337
                                                {
 
2338
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2339
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2340
                                                }
 
2341
                                                dpos++;
 
2342
                                        }
 
2343
                                }
 
2344
                                else
 
2345
                                {
 
2346
                                        UINT32 gfxdata = (MEGADRIV_VDP_VRAM(tile_addr+0)<<16)|MEGADRIV_VDP_VRAM(tile_addr+1);
 
2347
                                        int shift;
 
2348
                                        for (shift=0;shift<(hscroll_part);shift++)
 
2349
                                        {
 
2350
                                                dat = (gfxdata>>(shift*4) )&0x000f;
 
2351
                                                if (!tile_pri)
 
2352
                                                {
 
2353
                                                        if(dat) video_renderline[dpos] = dat | (tile_colour<<4);
 
2354
                                                }
 
2355
                                                else
 
2356
                                                {
 
2357
                                                        if (dat) highpri_renderline[dpos]  = dat | (tile_colour<<4) | 0x80;
 
2358
                                                        else highpri_renderline[dpos] = highpri_renderline[dpos]|0x80;
 
2359
                                                }
 
2360
                                                dpos++;
 
2361
                                        }
 
2362
                                }
 
2363
                        }
 
2364
                }
 
2365
        }
 
2366
                /* END */
 
2367
 
 
2368
/* MEGADRIVE_REG0C_SHADOW_HIGLIGHT */
 
2369
                /* Low Priority Sprites */
 
2370
                for (x=0;x<320;x++)
 
2371
                {
 
2372
                        if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
 
2373
                        {
 
2374
                                if (sprite_renderline[x+128] & 0x40)
 
2375
                                {
 
2376
                                        video_renderline[x] = sprite_renderline[x+128]&0x3f;
 
2377
                                        video_renderline[x] |= 0x10000; // mark as sprite pixel
 
2378
                                }
 
2379
                        }
 
2380
                        else
 
2381
                        {       /* Special Shadow / Highlight processing */
 
2382
 
 
2383
                                if (sprite_renderline[x+128] & 0x40)
 
2384
                                {
 
2385
                                        UINT8 spritedata;
 
2386
                                        spritedata = sprite_renderline[x+128]&0x3f;
 
2387
 
 
2388
                                        if ((spritedata==0x0e) || (spritedata==0x1e) || (spritedata==0x2e))
 
2389
                                        {
 
2390
                                                /* BUG in sprite chip, these colours are always normal intensity */
 
2391
                                                video_renderline[x] = spritedata | 0x4000;
 
2392
                                                video_renderline[x] |= 0x10000; // mark as sprite pixel
 
2393
                                        }
 
2394
                                        else if (spritedata==0x3e)
 
2395
                                        {
 
2396
                                                /* Everything below this is half colour, mark with 0x8000 to mark highlight' */
 
2397
                                                video_renderline[x] = video_renderline[x]|0x8000; // spiderwebs..
 
2398
                                        }
 
2399
                                        else if (spritedata==0x3f)
 
2400
                                        {
 
2401
                                                /* This is a Shadow operator, but everything below is already low pri, no effect */
 
2402
                                                video_renderline[x] = video_renderline[x]|0x2000;
 
2403
 
 
2404
                                        }
 
2405
                                        else
 
2406
                                        {
 
2407
                                                video_renderline[x] = spritedata;
 
2408
                                                video_renderline[x] |= 0x10000; // mark as sprite pixel
 
2409
                                        }
 
2410
 
 
2411
                                }
 
2412
                        }
 
2413
                }
 
2414
                /* High Priority A+B Tiles */
 
2415
                for (x=0;x<320;x++)
 
2416
                {
 
2417
                        if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
 
2418
                        {
 
2419
                                /* Normal Processing */
 
2420
                                int dat;
 
2421
                                dat = highpri_renderline[x];
 
2422
 
 
2423
                                if (dat&0x80)
 
2424
                                {
 
2425
                                         if (dat&0x0f) video_renderline[x] = highpri_renderline[x]&0x3f;
 
2426
                                }
 
2427
                        }
 
2428
                        else
 
2429
                        {
 
2430
                                /* Shadow / Highlight Mode */
 
2431
                                int dat;
 
2432
                                dat = highpri_renderline[x];
 
2433
 
 
2434
                                if (dat&0x80)
 
2435
                                {
 
2436
                                         if (dat&0x0f) video_renderline[x] = (highpri_renderline[x]&0x3f) | 0x4000;
 
2437
                                         else video_renderline[x] = video_renderline[x] | 0x4000; // set 'normal'
 
2438
                                }
 
2439
                        }
 
2440
                }
 
2441
 
 
2442
                /* High Priority Sprites */
 
2443
                for (x=0;x<320;x++)
 
2444
                {
 
2445
                        if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
 
2446
                        {
 
2447
                                /* Normal */
 
2448
                                if (sprite_renderline[x+128] & 0x80)
 
2449
                                {
 
2450
                                        video_renderline[x] = sprite_renderline[x+128]&0x3f;
 
2451
                                        video_renderline[x] |= 0x10000; // mark as sprite pixel
 
2452
                                }
 
2453
                        }
 
2454
                        else
 
2455
                        {
 
2456
                                if (sprite_renderline[x+128] & 0x80)
 
2457
                                {
 
2458
                                        UINT8 spritedata;
 
2459
                                        spritedata = sprite_renderline[x+128]&0x3f;
 
2460
 
 
2461
                                        if (spritedata==0x3e)
 
2462
                                        {
 
2463
                                                /* set flag 0x8000 to indicate highlight */
 
2464
                                                video_renderline[x] = video_renderline[x]|0x8000;
 
2465
                                        }
 
2466
                                        else if (spritedata==0x3f)
 
2467
                                        {
 
2468
                                                /* This is a Shadow operator set shadow bit */
 
2469
                                                video_renderline[x] = video_renderline[x]|0x2000;
 
2470
                                        }
 
2471
                                        else
 
2472
                                        {
 
2473
                                                video_renderline[x] = spritedata | 0x4000;
 
2474
                                                video_renderline[x] |= 0x10000; // mark as sprite pixel
 
2475
                                        }
 
2476
                                }
 
2477
                        }
 
2478
                }
 
2479
}
 
2480
 
 
2481
 
 
2482
/* This converts our render buffer to real screen colours */
 
2483
static void genesis_render_videobuffer_to_screenbuffer(running_machine &machine, int scanline)
 
2484
{
 
2485
        UINT16*lineptr;
 
2486
        int x;
 
2487
        lineptr = &megadriv_render_bitmap->pix16(scanline);
 
2488
 
 
2489
        UINT32* _32x_linerender = _32x_render_videobuffer_to_screenbuffer_helper(machine, scanline);
 
2490
 
 
2491
 
 
2492
 
 
2493
        if (!MEGADRIVE_REG0C_SHADOW_HIGLIGHT)
 
2494
        {
 
2495
 
 
2496
                for (x=0;x<320;x++)
 
2497
                {
 
2498
                        UINT32 dat;
 
2499
                        dat = video_renderline[x];
 
2500
                        int drawn = 0;
 
2501
 
 
2502
                        // low priority 32x - if it's the bg pen, we have a 32x, and it's display is enabled...
 
2503
                        if ((dat&0x20000) && (_32x_is_connected) && (_32x_displaymode != 0))
 
2504
                        {
 
2505
                                if (!_32x_videopriority)
 
2506
                                {
 
2507
                                        if (!(_32x_linerender[x]&0x8000))
 
2508
                                        {
 
2509
                                                lineptr[x] = _32x_linerender[x]&0x7fff;
 
2510
                                                drawn = 1;
 
2511
                                        }
 
2512
                                }
 
2513
                                else
 
2514
                                {
 
2515
                                        if ((_32x_linerender[x]&0x8000))
 
2516
                                        {
 
2517
                                                lineptr[x] = _32x_linerender[x]&0x7fff;
 
2518
                                                drawn = 1;
 
2519
                                        }
 
2520
                                }
 
2521
                        }
 
2522
 
 
2523
 
 
2524
                        if (drawn==0)
 
2525
                        {
 
2526
                                if (dat&0x10000)
 
2527
                                        lineptr[x] = megadrive_vdp_palette_lookup_sprite[(dat&0x0f) | segac2_sp_pal_lookup[(dat&0x30)>>4]];
 
2528
                                else
 
2529
                                        lineptr[x] = megadrive_vdp_palette_lookup[(dat&0x0f) | segac2_bg_pal_lookup[(dat&0x30)>>4]];
 
2530
                        }
 
2531
 
 
2532
 
 
2533
 
 
2534
                }
 
2535
        }
 
2536
        else
 
2537
        {
 
2538
 
 
2539
                for (x=0;x<320;x++)
 
2540
                {
 
2541
                        UINT32 dat;
 
2542
                        dat = video_renderline[x];
 
2543
 
 
2544
                        int drawn = 0;
 
2545
 
 
2546
                        // low priority 32x - if it's the bg pen, we have a 32x, and it's display is enabled...
 
2547
                        if ((dat&0x20000) && (_32x_is_connected) && (_32x_displaymode != 0))
 
2548
                        {
 
2549
                                if (!_32x_videopriority)
 
2550
                                {
 
2551
                                        if (!(_32x_linerender[x]&0x8000))
 
2552
                                        {
 
2553
                                                lineptr[x] = _32x_linerender[x]&0x7fff;
 
2554
                                                drawn = 1;
 
2555
                                        }
 
2556
                                }
 
2557
                                else
 
2558
                                {
 
2559
                                        if ((_32x_linerender[x]&0x8000))
 
2560
                                        {
 
2561
                                                lineptr[x] = _32x_linerender[x]&0x7fff;
 
2562
                                                drawn = 1;
 
2563
                                        }
 
2564
                                }
 
2565
                        }
 
2566
 
 
2567
 
 
2568
                        if (drawn==0)
 
2569
                        {
 
2570
                                /* Verify my handling.. I'm not sure all cases are correct */
 
2571
                                switch (dat&0x1e000)
 
2572
                                {
 
2573
                                        case 0x00000: // low priority, no shadow sprite, no highlight = shadow
 
2574
                                        case 0x02000: // low priority, shadow sprite, no highlight = shadow
 
2575
                                        case 0x06000: // normal pri,   shadow sprite, no highlight = shadow?
 
2576
                                        case 0x10000: // (sprite) low priority, no shadow sprite, no highlight = shadow
 
2577
                                        case 0x12000: // (sprite) low priority, shadow sprite, no highlight = shadow
 
2578
                                        case 0x16000: // (sprite) normal pri,   shadow sprite, no highlight = shadow?
 
2579
                                                lineptr[x] = megadrive_vdp_palette_lookup_shadow[(dat&0x0f)  | segac2_bg_pal_lookup[(dat&0x30)>>4]];
 
2580
                                                break;
 
2581
 
 
2582
                                        case 0x4000: // normal pri, no shadow sprite, no highlight = normal;
 
2583
                                        case 0x8000: // low pri, highlight sprite = normal;
 
2584
                                                lineptr[x] = megadrive_vdp_palette_lookup[(dat&0x0f)  | segac2_bg_pal_lookup[(dat&0x30)>>4]];
 
2585
                                                break;
 
2586
 
 
2587
                                        case 0x14000: // (sprite) normal pri, no shadow sprite, no highlight = normal;
 
2588
                                        case 0x18000: // (sprite) low pri, highlight sprite = normal;
 
2589
                                                lineptr[x] = megadrive_vdp_palette_lookup_sprite[(dat&0x0f)  | segac2_sp_pal_lookup[(dat&0x30)>>4]];
 
2590
                                                break;
 
2591
 
 
2592
 
 
2593
                                        case 0x0c000: // normal pri, highlight set = highlight?
 
2594
                                        case 0x1c000: // (sprite) normal pri, highlight set = highlight?
 
2595
                                                lineptr[x] = megadrive_vdp_palette_lookup_highlight[(dat&0x0f) | segac2_bg_pal_lookup[(dat&0x30)>>4]];
 
2596
                                                break;
 
2597
 
 
2598
                                        case 0x0a000: // shadow set, highlight set - not possible
 
2599
                                        case 0x0e000: // shadow set, highlight set, normal set, not possible
 
2600
                                        case 0x1a000: // (sprite)shadow set, highlight set - not possible
 
2601
                                        case 0x1e000: // (sprite)shadow set, highlight set, normal set, not possible
 
2602
                                        default:
 
2603
                                                lineptr[x] = machine.rand()&0x3f;
 
2604
                                        break;
 
2605
                                }
 
2606
                        }
 
2607
 
 
2608
 
 
2609
 
 
2610
                }
 
2611
 
 
2612
        }
 
2613
 
 
2614
 
 
2615
        // high priority 32x
 
2616
        if ((_32x_is_connected) && (_32x_displaymode != 0))
 
2617
        {
 
2618
                for (x=0;x<320;x++)
 
2619
                {
 
2620
                        if (!_32x_videopriority)
 
2621
                        {
 
2622
                                if ((_32x_linerender[x]&0x8000))
 
2623
                                        lineptr[x] = _32x_linerender[x]&0x7fff;
 
2624
                        }
 
2625
                        else
 
2626
                        {
 
2627
                                if (!(_32x_linerender[x]&0x8000))
 
2628
                                        lineptr[x] = _32x_linerender[x]&0x7fff;
 
2629
                        }
 
2630
                }
 
2631
        }
 
2632
}
 
2633
 
 
2634
static void genesis_render_scanline(running_machine &machine, int scanline)
 
2635
{
 
2636
        //if (MEGADRIVE_REG01_DMA_ENABLE==0) mame_printf_debug("off\n");
 
2637
        genesis_render_spriteline_to_spritebuffer(genesis_scanline_counter);
 
2638
        genesis_render_videoline_to_videobuffer(scanline);
 
2639
        genesis_render_videobuffer_to_screenbuffer(machine, scanline);
 
2640
}
 
2641
 
 
2642
UINT16 get_hposition(void)
 
2643
{
 
2644
//  static int lowest = 99999;
 
2645
//  static int highest = -99999;
 
2646
 
 
2647
        attotime time_elapsed_since_megadriv_scanline_timer;
 
2648
        UINT16 value4;
 
2649
 
 
2650
        time_elapsed_since_megadriv_scanline_timer = megadriv_scanline_timer->time_elapsed();
 
2651
 
 
2652
        if (time_elapsed_since_megadriv_scanline_timer.attoseconds<(ATTOSECONDS_PER_SECOND/megadriv_framerate /megadrive_total_scanlines))
 
2653
        {
 
2654
                value4 = (UINT16)(megadrive_max_hposition*((double)(time_elapsed_since_megadriv_scanline_timer.attoseconds) / (double)(ATTOSECONDS_PER_SECOND/megadriv_framerate /megadrive_total_scanlines)));
 
2655
        }
 
2656
        else /* in some cases (probably due to rounding errors) we get some stupid results (the odd huge value where the time elapsed is much higher than the scanline time??!).. hopefully by clamping the result to the maximum we limit errors */
 
2657
        {
 
2658
                value4 = megadrive_max_hposition;
 
2659
        }
 
2660
 
 
2661
//  if (value4>highest) highest = value4;
 
2662
//  if (value4<lowest) lowest = value4;
 
2663
 
 
2664
        //mame_printf_debug("%d low %d high %d scancounter %d\n", value4, lowest, highest,genesis_scanline_counter);
 
2665
 
 
2666
        return value4;
 
2667
}
 
2668
 
 
2669
 
 
2670
VIDEO_START(megadriv)
 
2671
{
 
2672
        int x;
 
2673
 
 
2674
        megadriv_render_bitmap = auto_bitmap_ind16_alloc(machine, machine.primary_screen->width(), machine.primary_screen->height());
 
2675
 
 
2676
        megadrive_vdp_vram  = auto_alloc_array(machine, UINT16, 0x10000/2);
 
2677
        megadrive_vdp_cram  = auto_alloc_array(machine, UINT16, 0x80/2);
 
2678
        megadrive_vdp_vsram = auto_alloc_array(machine, UINT16, 0x80/2);
 
2679
        megadrive_vdp_internal_sprite_attribute_table = auto_alloc_array(machine, UINT16, 0x400/2);
 
2680
 
 
2681
        for (x=0;x<0x20;x++)
 
2682
                megadrive_vdp_register[x]=0;
 
2683
//  memset(megadrive_vdp_vram, 0xff, 0x10000);
 
2684
//  memset(megadrive_vdp_cram, 0xff, 0x80);
 
2685
//  memset(megadrive_vdp_vsram, 0xff, 0x80);
 
2686
 
 
2687
        memset(megadrive_vdp_vram, 0x00, 0x10000);
 
2688
        memset(megadrive_vdp_cram, 0x00, 0x80);
 
2689
        memset(megadrive_vdp_vsram, 0x00, 0x80);
 
2690
        memset(megadrive_vdp_internal_sprite_attribute_table, 0x00, 0x400);
 
2691
 
 
2692
        megadrive_max_hposition = 480;
 
2693
 
 
2694
        sprite_renderline = auto_alloc_array(machine, UINT8, 1024);
 
2695
        highpri_renderline = auto_alloc_array(machine, UINT8, 320);
 
2696
        video_renderline = auto_alloc_array(machine, UINT32, 320);
 
2697
 
 
2698
        megadrive_vdp_palette_lookup = auto_alloc_array(machine, UINT16, 0x40);
 
2699
        megadrive_vdp_palette_lookup_sprite = auto_alloc_array(machine, UINT16, 0x40);
 
2700
 
 
2701
        megadrive_vdp_palette_lookup_shadow = auto_alloc_array(machine, UINT16, 0x40);
 
2702
        megadrive_vdp_palette_lookup_highlight = auto_alloc_array(machine, UINT16, 0x40);
 
2703
 
 
2704
        memset(megadrive_vdp_palette_lookup,0x00,0x40*2);
 
2705
        memset(megadrive_vdp_palette_lookup_sprite,0x00,0x40*2);
 
2706
 
 
2707
        memset(megadrive_vdp_palette_lookup_shadow,0x00,0x40*2);
 
2708
        memset(megadrive_vdp_palette_lookup_highlight,0x00,0x40*2);
 
2709
 
 
2710
        /* no special lookups */
 
2711
        segac2_bg_pal_lookup[0] = 0x00;
 
2712
        segac2_bg_pal_lookup[1] = 0x10;
 
2713
        segac2_bg_pal_lookup[2] = 0x20;
 
2714
        segac2_bg_pal_lookup[3] = 0x30;
 
2715
 
 
2716
        segac2_sp_pal_lookup[0] = 0x00;
 
2717
        segac2_sp_pal_lookup[1] = 0x10;
 
2718
        segac2_sp_pal_lookup[2] = 0x20;
 
2719
        segac2_sp_pal_lookup[3] = 0x30;
 
2720
}
 
2721
 
 
2722
 
 
2723
TIMER_DEVICE_CALLBACK( megadriv_scanline_timer_callback )
 
2724
{
 
2725
        /* This function is called at the very start of every scanline starting at the very
 
2726
       top-left of the screen.  The first scanline is scanline 0 (we set scanline to -1 in
 
2727
       VIDEO_EOF) */
 
2728
 
 
2729
        timer.machine().scheduler().synchronize();
 
2730
        /* Compensate for some rounding errors
 
2731
 
 
2732
       When the counter reaches 261 we should have reached the end of the frame, however due
 
2733
       to rounding errors in the timer calculation we're not quite there.  Let's assume we are
 
2734
       still in the previous scanline for now.
 
2735
    */
 
2736
 
 
2737
        if (genesis_scanline_counter!=(megadrive_total_scanlines-1))
 
2738
        {
 
2739
                genesis_scanline_counter++;
 
2740
//      mame_printf_debug("scanline %d\n",genesis_scanline_counter);
 
2741
                megadriv_scanline_timer->adjust(attotime::from_hz(megadriv_framerate) / megadrive_total_scanlines);
 
2742
                megadriv_render_timer->adjust(attotime::from_usec(1));
 
2743
 
 
2744
                if (genesis_scanline_counter==megadrive_irq6_scanline )
 
2745
                {
 
2746
                //  mame_printf_debug("x %d",genesis_scanline_counter);
 
2747
                        irq6_on_timer->adjust(attotime::from_usec(6));
 
2748
                        megadrive_irq6_pending = 1;
 
2749
                        megadrive_vblank_flag = 1;
 
2750
 
 
2751
                        // 32x interrupt!
 
2752
                        if (_32x_is_connected)
 
2753
                        {
 
2754
                                _32x_scanline_cb0(timer.machine());
 
2755
                        }
 
2756
 
 
2757
                }
 
2758
 
 
2759
 
 
2760
 
 
2761
                _32x_check_framebuffer_swap();
 
2762
 
 
2763
 
 
2764
        //  if (genesis_scanline_counter==0) irq4counter = MEGADRIVE_REG0A_HINT_VALUE;
 
2765
                // irq4counter = MEGADRIVE_REG0A_HINT_VALUE;
 
2766
 
 
2767
                if (genesis_scanline_counter<=224)
 
2768
                {
 
2769
                        irq4counter--;
 
2770
 
 
2771
                        if (irq4counter==-1)
 
2772
                        {
 
2773
                                if (megadrive_imode==3) irq4counter = MEGADRIVE_REG0A_HINT_VALUE*2;
 
2774
                                else irq4counter=MEGADRIVE_REG0A_HINT_VALUE;
 
2775
 
 
2776
                                megadrive_irq4_pending = 1;
 
2777
 
 
2778
                                if (MEGADRIVE_REG0_IRQ4_ENABLE)
 
2779
                                {
 
2780
                                        irq4_on_timer->adjust(attotime::from_usec(1));
 
2781
                                        //mame_printf_debug("irq4 on scanline %d reload %d\n",genesis_scanline_counter,MEGADRIVE_REG0A_HINT_VALUE);
 
2782
                                }
 
2783
                        }
 
2784
                }
 
2785
                else
 
2786
                {
 
2787
                        if (megadrive_imode==3) irq4counter = MEGADRIVE_REG0A_HINT_VALUE*2;
 
2788
                        else irq4counter=MEGADRIVE_REG0A_HINT_VALUE;
 
2789
                }
 
2790
 
 
2791
                //if (genesis_scanline_counter==0) irq4_on_timer->adjust(attotime::from_usec(2));
 
2792
 
 
2793
                if(_32x_is_connected)
 
2794
                {
 
2795
                        _32x_scanline_cb1();
 
2796
                }
 
2797
 
 
2798
 
 
2799
                if (timer.machine().device("genesis_snd_z80") != NULL)
 
2800
                {
 
2801
                        if (genesis_scanline_counter == megadrive_z80irq_scanline)
 
2802
                        {
 
2803
                                if ((genz80.z80_has_bus == 1) && (genz80.z80_is_reset == 0))
 
2804
                                        cputag_set_input_line(timer.machine(), "genesis_snd_z80", 0, HOLD_LINE);
 
2805
                        }
 
2806
                        if (genesis_scanline_counter == megadrive_z80irq_scanline + 1)
 
2807
                        {
 
2808
                                cputag_set_input_line(timer.machine(), "genesis_snd_z80", 0, CLEAR_LINE);
 
2809
                        }
 
2810
                }
 
2811
 
 
2812
        }
 
2813
        else /* pretend we're still on the same scanline to compensate for rounding errors */
 
2814
        {
 
2815
                genesis_scanline_counter = megadrive_total_scanlines - 1;
 
2816
        }
 
2817
 
 
2818
}
 
2819
 
 
2820
TIMER_DEVICE_CALLBACK( irq6_on_callback )
 
2821
{
 
2822
        //mame_printf_debug("irq6 active on %d\n",genesis_scanline_counter);
 
2823
 
 
2824
        {
 
2825
//      megadrive_irq6_pending = 1;
 
2826
                if (MEGADRIVE_REG01_IRQ6_ENABLE || genesis_always_irq6)
 
2827
                        cputag_set_input_line(timer.machine(), "maincpu", 6, HOLD_LINE);
 
2828
        }
 
2829
}
 
2830
 
 
2831
 
 
2832
SCREEN_VBLANK(megadriv)
 
2833
{
 
2834
        // rising edge
 
2835
        if (vblank_on)
 
2836
        {
 
2837
                rectangle visarea;
 
2838
                int scr_width = 320;
 
2839
 
 
2840
                megadrive_vblank_flag = 0;
 
2841
                //megadrive_irq6_pending = 0; /* NO! (breaks warlock) */
 
2842
 
 
2843
                /* Set it to -1 here, so it becomes 0 when the first timer kicks in */
 
2844
                genesis_scanline_counter = -1;
 
2845
                megadrive_sprite_collision=0;//? when to reset this ..
 
2846
                megadrive_imode = MEGADRIVE_REG0C_INTERLEAVE; // can't change mid-frame..
 
2847
                megadrive_imode_odd_frame^=1;
 
2848
//      cputag_set_input_line(machine, "genesis_snd_z80", 0, CLEAR_LINE); // if the z80 interrupt hasn't happened by now, clear it..
 
2849
 
 
2850
                if (screen.machine().root_device().ioport("RESET")->read_safe(0x00) & 0x01)
 
2851
                        cputag_set_input_line(screen.machine(), "maincpu", INPUT_LINE_RESET, PULSE_LINE);
 
2852
 
 
2853
 
 
2854
                if (MEGADRIVE_REG01_240_LINE)
 
2855
                {
 
2856
                        if (!megadrive_region_pal)
 
2857
                        {
 
2858
                                /* this is invalid! */
 
2859
                                megadrive_visible_scanlines = 240;
 
2860
                                megadrive_total_scanlines = 262;
 
2861
                                megadrive_irq6_scanline = 240;
 
2862
                                megadrive_z80irq_scanline = 240;
 
2863
                        }
 
2864
                        else
 
2865
                        {
 
2866
                                megadrive_visible_scanlines = 240;
 
2867
                                megadrive_total_scanlines = 313;
 
2868
                                megadrive_irq6_scanline = 240;
 
2869
                                megadrive_z80irq_scanline = 240;
 
2870
                        }
 
2871
                }
 
2872
                else
 
2873
                {
 
2874
                        if (!megadrive_region_pal)
 
2875
                        {
 
2876
                                megadrive_visible_scanlines = 224;
 
2877
                                megadrive_total_scanlines=262;
 
2878
                                megadrive_irq6_scanline = 224;
 
2879
                                megadrive_z80irq_scanline = 224;
 
2880
                        }
 
2881
                        else
 
2882
                        {
 
2883
                                megadrive_visible_scanlines = 224;
 
2884
                                megadrive_total_scanlines=313;
 
2885
                                megadrive_irq6_scanline = 224;
 
2886
                                megadrive_z80irq_scanline = 224;
 
2887
                        }
 
2888
                }
 
2889
 
 
2890
                if (megadrive_imode==3)
 
2891
                {
 
2892
                        megadrive_visible_scanlines<<=1;
 
2893
                        megadrive_total_scanlines<<=1;
 
2894
                        megadrive_irq6_scanline <<=1;
 
2895
                        megadrive_z80irq_scanline <<=1;
 
2896
                }
 
2897
 
 
2898
 
 
2899
                //get_hposition();
 
2900
                switch (MEGADRIVE_REG0C_RS0 | (MEGADRIVE_REG0C_RS1 << 1))
 
2901
                {
 
2902
                         /* note, add 240 mode + init new timings! */
 
2903
                        case 0:scr_width = 256;break;// configure_screen(0, 256-1, megadrive_visible_scanlines-1,(double)megadriv_framerate); break;
 
2904
                        case 1:scr_width = 256;break;// configure_screen(0, 256-1, megadrive_visible_scanlines-1,(double)megadriv_framerate); mame_printf_debug("invalid screenmode!\n"); break;
 
2905
                        case 2:scr_width = 320;break;// configure_screen(0, 320-1, megadrive_visible_scanlines-1,(double)megadriv_framerate); break; /* technically invalid, but used in rare cases */
 
2906
                        case 3:scr_width = 320;break;// configure_screen(0, 320-1, megadrive_visible_scanlines-1,(double)megadriv_framerate); break;
 
2907
                }
 
2908
//      mame_printf_debug("my mode %02x", megadrive_vdp_register[0x0c]);
 
2909
 
 
2910
                visarea.set(0, scr_width-1, 0, megadrive_visible_scanlines-1);
 
2911
 
 
2912
                screen.machine().primary_screen->configure(scr_width, megadrive_visible_scanlines, visarea, HZ_TO_ATTOSECONDS(megadriv_framerate));
 
2913
 
 
2914
                megadriv_scanline_timer->adjust(attotime::zero);
 
2915
 
 
2916
                if(_32x_is_connected)
 
2917
                        _32x_hcount_compare_val = -1;
 
2918
        }
 
2919
}
 
2920
 
 
2921
timer_device* megadriv_render_timer;
 
2922
 
 
2923
TIMER_DEVICE_CALLBACK( megadriv_render_timer_callback )
 
2924
{
 
2925
        if (genesis_scanline_counter>=0 && genesis_scanline_counter<megadrive_visible_scanlines)
 
2926
        {
 
2927
                genesis_render_scanline(timer.machine(), genesis_scanline_counter);
 
2928
        }
 
2929
}
 
2930
 
 
2931
void megadriv_reset_vdp(void)
 
2932
{
 
2933
        megadrive_imode = 0;
 
2934
        irq4counter = -1;
 
2935
        megadrive_total_scanlines = 262;
 
2936
        megadrive_visible_scanlines = 224;
 
2937
        megadrive_irq6_scanline = 224;
 
2938
        megadrive_z80irq_scanline = 226;
 
2939
}