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

« back to all changes in this revision

Viewing changes to src/mame/video/exidy440.c

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach, Emmanuel Kasper, Félix Arreola Rodríguez, Jordi Mallach
  • Date: 2011-05-11 21:06:50 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110511210650-jizvh8a6x117y9hr
Tags: 0.142-1
[ Emmanuel Kasper ]
* New upstream release
* Set NOWERROR=1 to allow compiling with gcc-4.6
* Remove fix_powerpc_build.patch, as upstream has taken it in this release
* Add gnome-video-arcade front end as a suggested package

[ Félix Arreola Rodríguez ]
* Add kfreebsd-build.patch to quilt series, to fix build on kfreebsd

[ Jordi Mallach ]
* Remove unneeded and bogus addition of --with-quilt to the dh invocation.
* Add Cesare Falco (long time Ubuntu maintainer) to Uploaders, and wrap
  them into multiple lines.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
#define SPRITE_COUNT            (0x28)
27
27
 
28
28
 
29
 
/* globals */
30
 
UINT8 *exidy440_scanline;
31
 
UINT8 *exidy440_imageram;
32
 
UINT8  exidy440_firq_vblank;
33
 
UINT8  exidy440_firq_beam;
34
 
UINT8 *topsecex_yscroll;
35
 
 
36
 
/* local allocated storage */
37
 
static UINT8 exidy440_latched_x;
38
 
static UINT8 *local_videoram;
39
 
static UINT8 *local_paletteram;
40
 
 
41
 
/* local variables */
42
 
static UINT8 firq_enable;
43
 
static UINT8 firq_select;
44
 
static UINT8 palettebank_io;
45
 
static UINT8 palettebank_vis;
46
 
 
47
29
/* function prototypes */
48
 
static void exidy440_update_firq(running_machine *machine);
 
30
static void exidy440_update_firq(running_machine &machine);
49
31
 
50
32
 
51
33
 
57
39
 
58
40
static VIDEO_START( exidy440 )
59
41
{
 
42
        exidy440_state *state = machine.driver_data<exidy440_state>();
60
43
        /* reset the system */
61
 
        firq_enable = 0;
62
 
        firq_select = 0;
63
 
        palettebank_io = 0;
64
 
        palettebank_vis = 0;
65
 
        exidy440_firq_vblank = 0;
66
 
        exidy440_firq_beam = 0;
 
44
        state->m_firq_enable = 0;
 
45
        state->m_firq_select = 0;
 
46
        state->m_palettebank_io = 0;
 
47
        state->m_palettebank_vis = 0;
 
48
        state->m_firq_vblank = 0;
 
49
        state->m_firq_beam = 0;
67
50
 
68
51
        /* allocate a buffer for VRAM */
69
 
        local_videoram = auto_alloc_array(machine, UINT8, 256 * 256 * 2);
70
 
        memset(local_videoram, 0, 256 * 256 * 2);
 
52
        state->m_local_videoram = auto_alloc_array(machine, UINT8, 256 * 256 * 2);
 
53
        memset(state->m_local_videoram, 0, 256 * 256 * 2);
71
54
 
72
55
        /* allocate a buffer for palette RAM */
73
 
        local_paletteram = auto_alloc_array(machine, UINT8, 512 * 2);
74
 
        memset(local_paletteram, 0, 512 * 2);
 
56
        state->m_local_paletteram = auto_alloc_array(machine, UINT8, 512 * 2);
 
57
        memset(state->m_local_paletteram, 0, 512 * 2);
75
58
}
76
59
 
77
60
 
78
61
static VIDEO_START( topsecex )
79
62
{
 
63
        exidy440_state *state = machine.driver_data<exidy440_state>();
80
64
        VIDEO_START_CALL(exidy440);
81
65
 
82
 
        *topsecex_yscroll = 0;
 
66
        *state->m_topsecex_yscroll = 0;
83
67
}
84
68
 
85
69
 
92
76
 
93
77
READ8_HANDLER( exidy440_videoram_r )
94
78
{
95
 
        UINT8 *base = &local_videoram[(*exidy440_scanline * 256 + offset) * 2];
 
79
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
 
80
        UINT8 *base = &state->m_local_videoram[(*state->m_scanline * 256 + offset) * 2];
96
81
 
97
82
        /* combine the two pixel values into one byte */
98
83
        return (base[0] << 4) | base[1];
101
86
 
102
87
WRITE8_HANDLER( exidy440_videoram_w )
103
88
{
104
 
        UINT8 *base = &local_videoram[(*exidy440_scanline * 256 + offset) * 2];
 
89
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
 
90
        UINT8 *base = &state->m_local_videoram[(*state->m_scanline * 256 + offset) * 2];
105
91
 
106
92
        /* expand the two pixel values into two bytes */
107
93
        base[0] = (data >> 4) & 15;
118
104
 
119
105
READ8_HANDLER( exidy440_paletteram_r )
120
106
{
121
 
        return local_paletteram[palettebank_io * 512 + offset];
 
107
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
 
108
        return state->m_local_paletteram[state->m_palettebank_io * 512 + offset];
122
109
}
123
110
 
124
111
 
125
112
WRITE8_HANDLER( exidy440_paletteram_w )
126
113
{
 
114
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
127
115
        /* update palette ram in the I/O bank */
128
 
        local_paletteram[palettebank_io * 512 + offset] = data;
 
116
        state->m_local_paletteram[state->m_palettebank_io * 512 + offset] = data;
129
117
 
130
118
        /* if we're modifying the active palette, change the color immediately */
131
 
        if (palettebank_io == palettebank_vis)
 
119
        if (state->m_palettebank_io == state->m_palettebank_vis)
132
120
        {
133
121
                int word;
134
122
 
135
123
                /* combine two bytes into a word */
136
 
                offset = palettebank_vis * 512 + (offset & 0x1fe);
137
 
                word = (local_paletteram[offset] << 8) + local_paletteram[offset + 1];
 
124
                offset = state->m_palettebank_vis * 512 + (offset & 0x1fe);
 
125
                word = (state->m_local_paletteram[offset] << 8) + state->m_local_paletteram[offset + 1];
138
126
 
139
127
                /* extract the 5-5-5 RGB colors */
140
 
                palette_set_color_rgb(space->machine, offset / 2, pal5bit(word >> 10), pal5bit(word >> 5), pal5bit(word >> 0));
 
128
                palette_set_color_rgb(space->machine(), offset / 2, pal5bit(word >> 10), pal5bit(word >> 5), pal5bit(word >> 0));
141
129
        }
142
130
}
143
131
 
151
139
 
152
140
READ8_HANDLER( exidy440_horizontal_pos_r )
153
141
{
 
142
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
154
143
        /* clear the FIRQ on a read here */
155
 
        exidy440_firq_beam = 0;
156
 
        exidy440_update_firq(space->machine);
 
144
        state->m_firq_beam = 0;
 
145
        exidy440_update_firq(space->machine());
157
146
 
158
147
        /* according to the schems, this value is only latched on an FIRQ
159
148
     * caused by collision or beam */
160
 
        return exidy440_latched_x;
 
149
        return state->m_latched_x;
161
150
}
162
151
 
163
152
 
169
158
     * caused by collision or beam, ORed together with CHRCLK,
170
159
     * which probably goes off once per scanline; for now, we just
171
160
     * always return the current scanline */
172
 
        result = space->machine->primary_screen->vpos();
 
161
        result = space->machine().primary_screen->vpos();
173
162
        return (result < 255) ? result : 255;
174
163
}
175
164
 
183
172
 
184
173
WRITE8_HANDLER( exidy440_spriteram_w )
185
174
{
186
 
        space->machine->primary_screen->update_partial(space->machine->primary_screen->vpos());
187
 
        space->machine->generic.spriteram.u8[offset] = data;
 
175
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
 
176
        space->machine().primary_screen->update_partial(space->machine().primary_screen->vpos());
 
177
        state->m_spriteram[offset] = data;
188
178
}
189
179
 
190
180
 
197
187
 
198
188
WRITE8_HANDLER( exidy440_control_w )
199
189
{
200
 
        int oldvis = palettebank_vis;
 
190
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
 
191
        int oldvis = state->m_palettebank_vis;
201
192
 
202
193
        /* extract the various bits */
203
 
        exidy440_bank_select(space->machine, data >> 4);
204
 
        firq_enable = (data >> 3) & 1;
205
 
        firq_select = (data >> 2) & 1;
206
 
        palettebank_io = (data >> 1) & 1;
207
 
        palettebank_vis = data & 1;
 
194
        exidy440_bank_select(space->machine(), data >> 4);
 
195
        state->m_firq_enable = (data >> 3) & 1;
 
196
        state->m_firq_select = (data >> 2) & 1;
 
197
        state->m_palettebank_io = (data >> 1) & 1;
 
198
        state->m_palettebank_vis = data & 1;
208
199
 
209
200
        /* update the FIRQ in case we enabled something */
210
 
        exidy440_update_firq(space->machine);
 
201
        exidy440_update_firq(space->machine());
211
202
 
212
203
        /* if we're swapping palettes, change all the colors */
213
 
        if (oldvis != palettebank_vis)
 
204
        if (oldvis != state->m_palettebank_vis)
214
205
        {
215
206
                int i;
216
207
 
217
208
                /* pick colors from the visible bank */
218
 
                offset = palettebank_vis * 512;
 
209
                offset = state->m_palettebank_vis * 512;
219
210
                for (i = 0; i < 256; i++, offset += 2)
220
211
                {
221
212
                        /* extract a word and the 5-5-5 RGB components */
222
 
                        int word = (local_paletteram[offset] << 8) + local_paletteram[offset + 1];
223
 
                        palette_set_color_rgb(space->machine, i, pal5bit(word >> 10), pal5bit(word >> 5), pal5bit(word >> 0));
 
213
                        int word = (state->m_local_paletteram[offset] << 8) + state->m_local_paletteram[offset + 1];
 
214
                        palette_set_color_rgb(space->machine(), i, pal5bit(word >> 10), pal5bit(word >> 5), pal5bit(word >> 0));
224
215
                }
225
216
        }
226
217
}
228
219
 
229
220
WRITE8_HANDLER( exidy440_interrupt_clear_w )
230
221
{
 
222
        exidy440_state *state = space->machine().driver_data<exidy440_state>();
231
223
        /* clear the VBLANK FIRQ on a write here */
232
 
        exidy440_firq_vblank = 0;
233
 
        exidy440_update_firq(space->machine);
 
224
        state->m_firq_vblank = 0;
 
225
        exidy440_update_firq(space->machine());
234
226
}
235
227
 
236
228
 
241
233
 *
242
234
 *************************************/
243
235
 
244
 
static void exidy440_update_firq(running_machine *machine)
 
236
static void exidy440_update_firq(running_machine &machine)
245
237
{
246
 
        if (exidy440_firq_vblank || (firq_enable && exidy440_firq_beam))
 
238
        exidy440_state *state = machine.driver_data<exidy440_state>();
 
239
        if (state->m_firq_vblank || (state->m_firq_enable && state->m_firq_beam))
247
240
                cputag_set_input_line(machine, "maincpu", 1, ASSERT_LINE);
248
241
        else
249
242
                cputag_set_input_line(machine, "maincpu", 1, CLEAR_LINE);
252
245
 
253
246
INTERRUPT_GEN( exidy440_vblank_interrupt )
254
247
{
 
248
        exidy440_state *state = device->machine().driver_data<exidy440_state>();
255
249
        /* set the FIRQ line on a VBLANK */
256
 
        exidy440_firq_vblank = 1;
257
 
        exidy440_update_firq(device->machine);
 
250
        state->m_firq_vblank = 1;
 
251
        exidy440_update_firq(device->machine());
258
252
}
259
253
 
260
254
 
267
261
 
268
262
static TIMER_CALLBACK( beam_firq_callback )
269
263
{
 
264
        exidy440_state *state = machine.driver_data<exidy440_state>();
270
265
        /* generate the interrupt, if we're selected */
271
 
        if (firq_select && firq_enable)
 
266
        if (state->m_firq_select && state->m_firq_enable)
272
267
        {
273
 
                exidy440_firq_beam = 1;
 
268
                state->m_firq_beam = 1;
274
269
                exidy440_update_firq(machine);
275
270
        }
276
271
 
278
273
        param = (param + 1) / 2;
279
274
 
280
275
        /* latch the x value; this convolution comes from the read routine */
281
 
        exidy440_latched_x = (param + 3) ^ 2;
 
276
        state->m_latched_x = (param + 3) ^ 2;
282
277
}
283
278
 
284
279
 
285
280
static TIMER_CALLBACK( collide_firq_callback )
286
281
{
 
282
        exidy440_state *state = machine.driver_data<exidy440_state>();
287
283
        /* generate the interrupt, if we're selected */
288
 
        if (!firq_select && firq_enable)
 
284
        if (!state->m_firq_select && state->m_firq_enable)
289
285
        {
290
 
                exidy440_firq_beam = 1;
 
286
                state->m_firq_beam = 1;
291
287
                exidy440_update_firq(machine);
292
288
        }
293
289
 
295
291
        param = (param + 1) / 2;
296
292
 
297
293
        /* latch the x value; this convolution comes from the read routine */
298
 
        exidy440_latched_x = (param + 3) ^ 2;
 
294
        state->m_latched_x = (param + 3) ^ 2;
299
295
}
300
296
 
301
297
 
309
305
static void draw_sprites(screen_device &screen, bitmap_t *bitmap, const rectangle *cliprect,
310
306
                                                 int scroll_offset, int check_collision)
311
307
{
 
308
        exidy440_state *state = screen.machine().driver_data<exidy440_state>();
312
309
        int i;
313
310
 
314
311
        /* get a pointer to the palette to look for collision flags */
315
 
        UINT8 *palette = &local_paletteram[palettebank_vis * 512];
 
312
        UINT8 *palette = &state->m_local_paletteram[state->m_palettebank_vis * 512];
316
313
        int count = 0;
317
314
 
318
315
        /* draw the sprite images, checking for collisions along the way */
319
 
        UINT8 *sprite = screen.machine->generic.spriteram.u8 + (SPRITE_COUNT - 1) * 4;
 
316
        UINT8 *sprite = state->m_spriteram + (SPRITE_COUNT - 1) * 4;
320
317
 
321
318
        for (i = 0; i < SPRITE_COUNT; i++, sprite -= 4)
322
319
        {
331
328
                        continue;
332
329
 
333
330
                /* get a pointer to the source image */
334
 
                src = &exidy440_imageram[image * 128];
 
331
                src = &state->m_imageram[image * 128];
335
332
 
336
333
                /* account for large positive offsets meaning small negative values */
337
334
                if (xoffs >= 0x1ff - 16)
354
351
                        /* only draw scanlines that are in this cliprect */
355
352
                        if (yoffs <= cliprect->max_y)
356
353
                        {
357
 
                                UINT8 *old = &local_videoram[sy * 512 + xoffs];
 
354
                                UINT8 *old = &state->m_local_videoram[sy * 512 + xoffs];
358
355
                                int currx = xoffs;
359
356
 
360
357
                                /* loop over x */
374
371
 
375
372
                                                /* check the collisions bit */
376
373
                                                if (check_collision && (palette[2 * pen] & 0x80) && (count++ < 128))
377
 
                                                        timer_set(screen.machine, screen.time_until_pos(yoffs, currx), NULL, currx, collide_firq_callback);
 
374
                                                        screen.machine().scheduler().timer_set(screen.time_until_pos(yoffs, currx), FUNC(collide_firq_callback), currx);
378
375
                                        }
379
376
                                        currx++;
380
377
 
387
384
 
388
385
                                                /* check the collisions bit */
389
386
                                                if (check_collision && (palette[2 * pen] & 0x80) && (count++ < 128))
390
 
                                                        timer_set(screen.machine, screen.time_until_pos(yoffs, currx), NULL, currx, collide_firq_callback);
 
387
                                                        screen.machine().scheduler().timer_set(screen.time_until_pos(yoffs, currx), FUNC(collide_firq_callback), currx);
391
388
                                        }
392
389
                                        currx++;
393
390
                                }
409
406
static void update_screen(screen_device &screen, bitmap_t *bitmap, const rectangle *cliprect,
410
407
                                                  int scroll_offset, int check_collision)
411
408
{
 
409
        exidy440_state *state = screen.machine().driver_data<exidy440_state>();
412
410
        int y, sy;
413
411
 
414
412
        /* draw any dirty scanlines from the VRAM directly */
420
418
                        sy -= (VBSTART - VBEND);
421
419
 
422
420
                /* draw line */
423
 
                draw_scanline8(bitmap, 0, y, (HBSTART - HBEND), &local_videoram[sy * 512], NULL);
 
421
                draw_scanline8(bitmap, 0, y, (HBSTART - HBEND), &state->m_local_videoram[sy * 512], NULL);
424
422
        }
425
423
 
426
424
        /* draw the sprites */
435
433
 *
436
434
 *************************************/
437
435
 
438
 
static VIDEO_UPDATE( exidy440 )
 
436
static SCREEN_UPDATE( exidy440 )
439
437
{
440
438
        /* redraw the screen */
441
439
        update_screen(*screen, bitmap, cliprect, 0, TRUE);
445
443
        {
446
444
                int i;
447
445
 
448
 
                int beamx = ((input_port_read(screen->machine, "AN0") & 0xff) * (HBSTART - HBEND)) >> 8;
449
 
                int beamy = ((input_port_read(screen->machine, "AN1") & 0xff) * (VBSTART - VBEND)) >> 8;
 
446
                int beamx = ((input_port_read(screen->machine(), "AN0") & 0xff) * (HBSTART - HBEND)) >> 8;
 
447
                int beamy = ((input_port_read(screen->machine(), "AN1") & 0xff) * (VBSTART - VBEND)) >> 8;
450
448
 
451
449
                /* The timing of this FIRQ is very important. The games look for an FIRQ
452
450
            and then wait about 650 cycles, clear the old FIRQ, and wait a
454
452
            From this, it appears that they are expecting to get beams over
455
453
            a 12 scanline period, and trying to pick roughly the middle one.
456
454
            This is how it is implemented. */
457
 
                attoseconds_t increment = attotime_to_attoseconds(screen->scan_period());
458
 
                attotime time = attotime_sub(screen->time_until_pos(beamy, beamx), attotime_make(0, increment * 6));
 
455
                attotime increment = screen->scan_period();
 
456
                attotime time = screen->time_until_pos(beamy, beamx) - increment * 6;
459
457
                for (i = 0; i <= 12; i++)
460
458
                {
461
 
                        timer_set(screen->machine, time, NULL, beamx, beam_firq_callback);
462
 
                        time = attotime_add(time, attotime_make(0, increment));
 
459
                        screen->machine().scheduler().timer_set(time, FUNC(beam_firq_callback), beamx);
 
460
                        time += increment;
463
461
                }
464
462
        }
465
463
 
467
465
}
468
466
 
469
467
 
470
 
static VIDEO_UPDATE( topsecex )
 
468
static SCREEN_UPDATE( topsecex )
471
469
{
 
470
        exidy440_state *state = screen->machine().driver_data<exidy440_state>();
472
471
        /* redraw the screen */
473
 
        update_screen(*screen, bitmap, cliprect, *topsecex_yscroll, FALSE);
 
472
        update_screen(*screen, bitmap, cliprect, *state->m_topsecex_yscroll, FALSE);
474
473
 
475
474
        return 0;
476
475
}
486
485
MACHINE_CONFIG_FRAGMENT( exidy440_video )
487
486
        MCFG_VIDEO_ATTRIBUTES(VIDEO_ALWAYS_UPDATE)
488
487
        MCFG_VIDEO_START(exidy440)
489
 
        MCFG_VIDEO_UPDATE(exidy440)
490
488
        MCFG_PALETTE_LENGTH(256)
491
489
 
492
490
        MCFG_SCREEN_ADD("screen", RASTER)
493
491
        MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
494
492
        MCFG_SCREEN_RAW_PARAMS(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, VBSTART)
 
493
        MCFG_SCREEN_UPDATE(exidy440)
495
494
MACHINE_CONFIG_END
496
495
 
497
496
 
498
497
MACHINE_CONFIG_FRAGMENT( topsecex_video )
499
498
        MCFG_VIDEO_ATTRIBUTES(0)
500
499
        MCFG_VIDEO_START(topsecex)
501
 
        MCFG_VIDEO_UPDATE(topsecex)
502
500
 
503
501
        MCFG_SCREEN_MODIFY("screen")
504
502
        MCFG_SCREEN_RAW_PARAMS(PIXEL_CLOCK, HTOTAL, HBEND, HBSTART, VTOTAL, VBEND, TOPSECEX_VBSTART)
 
503
        MCFG_SCREEN_UPDATE(topsecex)
505
504
MACHINE_CONFIG_END