~ubuntu-branches/ubuntu/raring/mame/raring-proposed

« back to all changes in this revision

Viewing changes to mess/src/mame/video/amiga.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    Amiga hardware
4
 
 
5
 
    Driver by: Ernesto Corvi, Mariusz Wojcieszek, Aaron Giles
6
 
 
7
 
***************************************************************************/
8
 
 
9
 
#include "emu.h"
10
 
#include "includes/amiga.h"
11
 
 
12
 
 
13
 
 
14
 
/*************************************
15
 
 *
16
 
 *  Macros
17
 
 *
18
 
 *************************************/
19
 
 
20
 
#define COPPER_CYCLES_TO_PIXELS(x)              (4 * (x))
21
 
 
22
 
 
23
 
 
24
 
/*************************************
25
 
 *
26
 
 *  Tables
27
 
 *
28
 
 *************************************/
29
 
 
30
 
/* expand an 8-bit bit pattern into 16 bits, every other bit */
31
 
const UINT16 amiga_expand_byte[256] =
32
 
{
33
 
        0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015,
34
 
        0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055,
35
 
        0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115,
36
 
        0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155,
37
 
        0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415,
38
 
        0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455,
39
 
        0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515,
40
 
        0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555,
41
 
        0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015,
42
 
        0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055,
43
 
        0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115,
44
 
        0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155,
45
 
        0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415,
46
 
        0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455,
47
 
        0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515,
48
 
        0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555,
49
 
 
50
 
        0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015,
51
 
        0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055,
52
 
        0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115,
53
 
        0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155,
54
 
        0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415,
55
 
        0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455,
56
 
        0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515,
57
 
        0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555,
58
 
        0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015,
59
 
        0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055,
60
 
        0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115,
61
 
        0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155,
62
 
        0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415,
63
 
        0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455,
64
 
        0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515,
65
 
        0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555
66
 
};
67
 
 
68
 
const UINT16 delay[256] =
69
 
{
70
 
        1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,        /* 0x000 - 0x03e */
71
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                                                /* 0x040 - 0x05e */
72
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                                                /* 0x060 - 0x07e */
73
 
        0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,                                                /* 0x080 - 0x09e */
74
 
        1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,        /* 0x0a0 - 0x0de */
75
 
        /* BPLxPTH/BPLxPTL */
76
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                                                /* 0x0e0 - 0x0fe */
77
 
        /* BPLCON0-3,BPLMOD1-2 */
78
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,                                                /* 0x100 - 0x11e */
79
 
        /* SPRxPTH/SPRxPTL */
80
 
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,                                                /* 0x120 - 0x13e */
81
 
        /* SPRxPOS/SPRxCTL/SPRxDATA/SPRxDATB */
82
 
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,        /* 0x140 - 0x17e */
83
 
        /* COLORxx */
84
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,        /* 0x180 - 0x1be */
85
 
        /* RESERVED */
86
 
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* 0x1c0 - 0x1fe */
87
 
};
88
 
 
89
 
 
90
 
 
91
 
/*************************************
92
 
 *
93
 
 *  4-4-4 palette init
94
 
 *
95
 
 *************************************/
96
 
 
97
 
PALETTE_INIT( amiga )
98
 
{
99
 
        int i;
100
 
 
101
 
        for (i = 0; i < 0x1000; i++)
102
 
                palette_set_color_rgb(machine, i, pal4bit(i >> 8), pal4bit(i >> 4), pal4bit(i));
103
 
}
104
 
 
105
 
 
106
 
 
107
 
/*************************************
108
 
 *
109
 
 *  Video startup
110
 
 *
111
 
 *************************************/
112
 
 
113
 
VIDEO_START( amiga )
114
 
{
115
 
        amiga_state *state = machine.driver_data<amiga_state>();
116
 
        int j;
117
 
 
118
 
        /* generate tables that produce the correct playfield color for dual playfield mode */
119
 
        for (j = 0; j < 64; j++)
120
 
        {
121
 
                int pf1pix = ((j >> 0) & 1) | ((j >> 1) & 2) | ((j >> 2) & 4);
122
 
                int pf2pix = ((j >> 1) & 1) | ((j >> 2) & 2) | ((j >> 3) & 4);
123
 
 
124
 
                state->m_separate_bitplanes[0][j] = (pf1pix || !pf2pix) ? pf1pix : (pf2pix + 8);
125
 
                state->m_separate_bitplanes[1][j] = pf2pix ? (pf2pix + 8) : pf1pix;
126
 
        }
127
 
 
128
 
#if GUESS_COPPER_OFFSET
129
 
        state->m_wait_offset = 3;
130
 
#endif
131
 
 
132
 
        /* reset the genlock color */
133
 
        state->m_genlock_color = 0xffff;
134
 
 
135
 
        state->m_sprite_ctl_written = 0;
136
 
}
137
 
 
138
 
 
139
 
 
140
 
/*************************************
141
 
 *
142
 
 *  Beam position
143
 
 *
144
 
 *************************************/
145
 
 
146
 
UINT32 amiga_gethvpos(screen_device &screen)
147
 
{
148
 
        amiga_state *state = screen.machine().driver_data<amiga_state>();
149
 
        UINT32 hvpos = (state->m_last_scanline << 8) | (screen.hpos() >> 2);
150
 
        UINT32 latchedpos = input_port_read_safe(screen.machine(), "HVPOS", 0);
151
 
 
152
 
        /* if there's no latched position, or if we are in the active display area */
153
 
        /* but before the latching point, return the live HV position */
154
 
        if ((CUSTOM_REG(REG_BPLCON0) & 0x0008) == 0 || latchedpos == 0 || (state->m_last_scanline >= 20 && hvpos < latchedpos))
155
 
                return hvpos;
156
 
 
157
 
        /* otherwise, return the latched position */
158
 
        return latchedpos;
159
 
}
160
 
 
161
 
 
162
 
 
163
 
/*************************************
164
 
 *
165
 
 *  Genlock interaction
166
 
 *
167
 
 *************************************/
168
 
 
169
 
void amiga_set_genlock_color(running_machine &machine, UINT16 color)
170
 
{
171
 
        amiga_state *state = machine.driver_data<amiga_state>();
172
 
 
173
 
        state->m_genlock_color = color;
174
 
}
175
 
 
176
 
 
177
 
 
178
 
/*************************************
179
 
 *
180
 
 *  Copper emulation
181
 
 *
182
 
 *************************************/
183
 
 
184
 
void amiga_copper_setpc(running_machine &machine, UINT32 pc)
185
 
{
186
 
        amiga_state *state = machine.driver_data<amiga_state>();
187
 
 
188
 
        if (LOG_COPPER)
189
 
                logerror("copper_setpc(%06x)\n", pc);
190
 
 
191
 
        state->m_copper_pc = pc;
192
 
        state->m_copper_waiting = FALSE;
193
 
}
194
 
 
195
 
 
196
 
int amiga_copper_execute_next(running_machine &machine, int xpos)
197
 
{
198
 
        amiga_state *state = machine.driver_data<amiga_state>();
199
 
        int word0, word1;
200
 
 
201
 
        /* bail if not enabled */
202
 
        if ((CUSTOM_REG(REG_DMACON) & (DMACON_COPEN | DMACON_DMAEN)) != (DMACON_COPEN | DMACON_DMAEN))
203
 
                return 511;
204
 
 
205
 
        /* flush any pending writes */
206
 
        if (state->m_copper_pending_offset)
207
 
        {
208
 
                if (LOG_COPPER)
209
 
                        logerror("%02X.%02X: Write to %s = %04x\n", state->m_last_scanline, xpos / 2, amiga_custom_names[state->m_copper_pending_offset & 0xff], state->m_copper_pending_data);
210
 
                amiga_custom_w(machine.device("maincpu")->memory().space(AS_PROGRAM), state->m_copper_pending_offset, state->m_copper_pending_data, 0xffff);
211
 
                state->m_copper_pending_offset = 0;
212
 
        }
213
 
 
214
 
        /* if we're waiting, check for a breakthrough */
215
 
        if (state->m_copper_waiting)
216
 
        {
217
 
                int curpos = (state->m_last_scanline << 8) | (xpos >> 1);
218
 
 
219
 
                /* if we're past the wait time, stop it and hold up 2 cycles */
220
 
                if ((curpos & state->m_copper_waitmask) >= (state->m_copper_waitval & state->m_copper_waitmask) &&
221
 
                        (!state->m_copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY)))
222
 
                {
223
 
                        state->m_copper_waiting = FALSE;
224
 
#if GUESS_COPPER_OFFSET
225
 
                        return xpos + COPPER_CYCLES_TO_PIXELS(1 + state->m_wait_offset);
226
 
#else
227
 
                        return xpos + COPPER_CYCLES_TO_PIXELS(1 + 3);
228
 
#endif
229
 
                }
230
 
 
231
 
                /* otherwise, see if this line is even a possibility; if not, punt */
232
 
                if (((curpos | 0xff) & state->m_copper_waitmask) < (state->m_copper_waitval & state->m_copper_waitmask))
233
 
                        return 511;
234
 
 
235
 
                /* else just advance another pixel */
236
 
                xpos += COPPER_CYCLES_TO_PIXELS(1);
237
 
                return xpos;
238
 
        }
239
 
 
240
 
        /* fetch the first data word */
241
 
        word0 = (*state->m_chip_ram_r)(state, state->m_copper_pc);
242
 
        state->m_copper_pc += 2;
243
 
        xpos += COPPER_CYCLES_TO_PIXELS(1);
244
 
 
245
 
        /* fetch the second data word */
246
 
        word1 = (*state->m_chip_ram_r)(state, state->m_copper_pc);
247
 
        state->m_copper_pc += 2;
248
 
        xpos += COPPER_CYCLES_TO_PIXELS(1);
249
 
 
250
 
        if (LOG_COPPER)
251
 
                logerror("%02X.%02X: Copper inst @ %06x = %04x %04x\n", state->m_last_scanline, xpos / 2, state->m_copper_pc, word0, word1);
252
 
 
253
 
        /* handle a move */
254
 
        if ((word0 & 1) == 0)
255
 
        {
256
 
                int min = (CUSTOM_REG(REG_COPCON) & 2) ? 0x20 : 0x40;
257
 
 
258
 
                /* do the write if we're allowed */
259
 
                word0 = (word0 >> 1) & 0xff;
260
 
                if (word0 >= min)
261
 
                {
262
 
                        if (delay[word0] == 0)
263
 
                        {
264
 
                                if (LOG_COPPER)
265
 
                                        logerror("%02X.%02X: Write to %s = %04x\n", state->m_last_scanline, xpos / 2, amiga_custom_names[word0 & 0xff], word1);
266
 
                                amiga_custom_w(machine.device("maincpu")->memory().space(AS_PROGRAM), word0, word1, 0xffff);
267
 
                        }
268
 
                        else    // additional 2 cycles needed for non-Agnus registers
269
 
                        {
270
 
                                state->m_copper_pending_offset = word0;
271
 
                                state->m_copper_pending_data = word1;
272
 
                        }
273
 
                }
274
 
 
275
 
                /* illegal writes suspend until next frame */
276
 
                else
277
 
                {
278
 
                        if (LOG_COPPER)
279
 
                                logerror("%02X.%02X: Aborting copper on illegal write\n", state->m_last_scanline, xpos / 2);
280
 
 
281
 
                        state->m_copper_waitval = 0xffff;
282
 
                        state->m_copper_waitmask = 0xffff;
283
 
                        state->m_copper_waitblit = FALSE;
284
 
                        state->m_copper_waiting = TRUE;
285
 
                        return 511;
286
 
                }
287
 
        }
288
 
        else
289
 
        {
290
 
                /* extract common wait/skip values */
291
 
                state->m_copper_waitval = word0 & 0xfffe;
292
 
                state->m_copper_waitmask = word1 | 0x8001;
293
 
                state->m_copper_waitblit = (~word1 >> 15) & 1;
294
 
 
295
 
                /* handle a wait */
296
 
                if ((word1 & 1) == 0)
297
 
                {
298
 
                        if (LOG_COPPER)
299
 
                                logerror("  Waiting for %04x & %04x (currently %04x)\n", state->m_copper_waitval, state->m_copper_waitmask, (state->m_last_scanline << 8) | (xpos >> 1));
300
 
 
301
 
                        state->m_copper_waiting = TRUE;
302
 
                }
303
 
 
304
 
                /* handle a skip */
305
 
                else
306
 
                {
307
 
                        int curpos = (state->m_last_scanline << 8) | (xpos >> 1);
308
 
 
309
 
                        if (LOG_COPPER)
310
 
                                logerror("  Skipping if %04x & %04x (currently %04x)\n", state->m_copper_waitval, state->m_copper_waitmask, (state->m_last_scanline << 8) | (xpos >> 1));
311
 
 
312
 
                        /* if we're past the wait time, stop it and hold up 2 cycles */
313
 
                        if ((curpos & state->m_copper_waitmask) >= (state->m_copper_waitval & state->m_copper_waitmask) &&
314
 
                                (!state->m_copper_waitblit || !(CUSTOM_REG(REG_DMACON) & DMACON_BBUSY)))
315
 
                        {
316
 
                                if (LOG_COPPER)
317
 
                                        logerror("  Skipped\n");
318
 
 
319
 
                                /* count the cycles it out have taken to fetch the next instruction */
320
 
                                state->m_copper_pc += 4;
321
 
                                xpos += COPPER_CYCLES_TO_PIXELS(2);
322
 
                        }
323
 
                }
324
 
        }
325
 
 
326
 
        /* advance and consume 8 cycles */
327
 
        return xpos;
328
 
}
329
 
 
330
 
 
331
 
 
332
 
/*************************************
333
 
 *
334
 
 *  External sprite controls
335
 
 *
336
 
 *************************************/
337
 
 
338
 
void amiga_sprite_dma_reset(running_machine &machine, int which)
339
 
{
340
 
        amiga_state *state = machine.driver_data<amiga_state>();
341
 
 
342
 
        if (LOG_SPRITE_DMA) logerror("sprite %d dma reset\n", which );
343
 
        state->m_sprite_dma_reload_mask |= 1 << which;
344
 
        state->m_sprite_dma_live_mask |= 1 << which;
345
 
}
346
 
 
347
 
 
348
 
void amiga_sprite_enable_comparitor(running_machine &machine, int which, int enable)
349
 
{
350
 
        amiga_state *state = machine.driver_data<amiga_state>();
351
 
 
352
 
        if (LOG_SPRITE_DMA) logerror("sprite %d comparitor %sable\n", which, enable ? "en" : "dis" );
353
 
        if (enable)
354
 
        {
355
 
                state->m_sprite_comparitor_enable_mask |= 1 << which;
356
 
                state->m_sprite_dma_live_mask &= ~(1 << which);
357
 
        }
358
 
        else
359
 
        {
360
 
                state->m_sprite_comparitor_enable_mask &= ~(1 << which);
361
 
                state->m_sprite_ctl_written |= (1 << which);
362
 
        }
363
 
}
364
 
 
365
 
 
366
 
 
367
 
/*************************************
368
 
 *
369
 
 *  Per-scanline sprite fetcher
370
 
 *
371
 
 *************************************/
372
 
 
373
 
INLINE void fetch_sprite_data(amiga_state *state, int scanline, int sprite)
374
 
{
375
 
        CUSTOM_REG(REG_SPR0DATA + 4 * sprite) = (*state->m_chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 0);
376
 
        CUSTOM_REG(REG_SPR0DATB + 4 * sprite) = (*state->m_chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) + 2);
377
 
        CUSTOM_REG_LONG(REG_SPR0PTH + 2 * sprite) += 4;
378
 
        if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: data=%04X-%04X\n", scanline, sprite, CUSTOM_REG(REG_SPR0DATA + 4 * sprite), CUSTOM_REG(REG_SPR0DATB + 4 * sprite));
379
 
}
380
 
 
381
 
static void update_sprite_dma(amiga_state *state, int scanline)
382
 
{
383
 
        int dmaenable = (CUSTOM_REG(REG_DMACON) & (DMACON_SPREN | DMACON_DMAEN)) == (DMACON_SPREN | DMACON_DMAEN);
384
 
        int num, maxdma;
385
 
 
386
 
        /* channels are limited by DDFSTART */
387
 
        maxdma = (CUSTOM_REG(REG_DDFSTRT) - 0x14) / 4;
388
 
        if (maxdma > 8)
389
 
                maxdma = 8;
390
 
 
391
 
        /* loop over sprite channels */
392
 
        for (num = 0; num < maxdma; num++)
393
 
        {
394
 
                int bitmask = 1 << num;
395
 
                int vstart, vstop;
396
 
 
397
 
                /* if we are == VSTOP, fetch new control words */
398
 
                if (dmaenable && (state->m_sprite_dma_live_mask & bitmask) && (state->m_sprite_dma_reload_mask & bitmask))
399
 
                {
400
 
                        /* disable the sprite */
401
 
                        state->m_sprite_comparitor_enable_mask &= ~bitmask;
402
 
                        state->m_sprite_dma_reload_mask &= ~bitmask;
403
 
 
404
 
                        /* fetch data into the control words */
405
 
                        CUSTOM_REG(REG_SPR0POS + 4 * num) = (*state->m_chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 0);
406
 
                        CUSTOM_REG(REG_SPR0CTL + 4 * num) = (*state->m_chip_ram_r)(state, CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) + 2);
407
 
                        CUSTOM_REG_LONG(REG_SPR0PTH + 2 * num) += 4;
408
 
                        if (LOG_SPRITE_DMA) logerror("%3d:sprite %d fetch: pos=%04X ctl=%04X\n", scanline, num, CUSTOM_REG(REG_SPR0POS + 4 * num), CUSTOM_REG(REG_SPR0CTL + 4 * num));
409
 
                }
410
 
 
411
 
                /* compute vstart/vstop */
412
 
                vstart = (CUSTOM_REG(REG_SPR0POS + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 6) & 0x100);
413
 
                vstop = (CUSTOM_REG(REG_SPR0CTL + 4 * num) >> 8) | ((CUSTOM_REG(REG_SPR0CTL + 4 * num) << 7) & 0x100);
414
 
 
415
 
                /* if we hit vstart, enable the comparitor */
416
 
                if (scanline == vstart)
417
 
                {
418
 
                        state->m_sprite_comparitor_enable_mask |= 1 << num;
419
 
                        if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor enable\n", scanline, num);
420
 
                }
421
 
 
422
 
                /* if we hit vstop, disable the comparitor and trigger a reload for the next scanline */
423
 
                if (scanline == vstop)
424
 
                {
425
 
                        state->m_sprite_ctl_written &= ~bitmask;
426
 
                        state->m_sprite_comparitor_enable_mask &= ~bitmask;
427
 
                        state->m_sprite_dma_reload_mask |= 1 << num;
428
 
                        CUSTOM_REG(REG_SPR0DATA + 4 * num) = 0;         /* just a guess */
429
 
                        CUSTOM_REG(REG_SPR0DATB + 4 * num) = 0;
430
 
                        if (LOG_SPRITE_DMA) logerror("%3d:sprite %d comparitor disable, prepare for reload\n", scanline, num);
431
 
                }
432
 
 
433
 
                /* fetch data if this sprite is enabled */
434
 
                if (dmaenable && (state->m_sprite_dma_live_mask & bitmask) && (state->m_sprite_comparitor_enable_mask & bitmask))
435
 
                {
436
 
                        fetch_sprite_data(state, scanline, num);
437
 
                }
438
 
        }
439
 
}
440
 
 
441
 
 
442
 
 
443
 
/*************************************
444
 
 *
445
 
 *  Per-pixel sprite computations
446
 
 *
447
 
 *************************************/
448
 
 
449
 
INLINE UINT32 interleave_sprite_data(UINT16 lobits, UINT16 hibits)
450
 
{
451
 
        return (amiga_expand_byte[lobits & 0xff] << 0) | (amiga_expand_byte[lobits >> 8] << 16) |
452
 
                   (amiga_expand_byte[hibits & 0xff] << 1) | (amiga_expand_byte[hibits >> 8] << 17);
453
 
}
454
 
 
455
 
 
456
 
static int get_sprite_pixel(amiga_state *state, int x)
457
 
{
458
 
        int pixels = 0;
459
 
        int num, pair;
460
 
 
461
 
        /* loop over sprite channels */
462
 
        for (num = 0; num < 8; num++)
463
 
                if (state->m_sprite_comparitor_enable_mask & (1 << num))
464
 
                {
465
 
                        /* if we're not currently clocking, check against hstart */
466
 
                        if (state->m_sprite_remain[num] == 0)
467
 
                        {
468
 
                                int hstart = ((CUSTOM_REG(REG_SPR0POS + 4 * num) & 0xff) << 1) | (CUSTOM_REG(REG_SPR0CTL + 4 * num) & 1);
469
 
                                if (hstart == x)
470
 
                                {
471
 
                                        state->m_sprite_remain[num] = 16;
472
 
                                        state->m_sprite_shiftreg[num] = interleave_sprite_data(CUSTOM_REG(REG_SPR0DATA + 4 * num), CUSTOM_REG(REG_SPR0DATB + 4 * num));
473
 
                                }
474
 
                        }
475
 
 
476
 
                        /* clock the next pixel if we're doing it */
477
 
                        if (state->m_sprite_remain[num] != 0)
478
 
                        {
479
 
                                state->m_sprite_remain[num]--;
480
 
                                pixels |= (state->m_sprite_shiftreg[num] & 0xc0000000) >> (16 + 2 * (7 - num));
481
 
                                state->m_sprite_shiftreg[num] <<= 2;
482
 
                        }
483
 
                }
484
 
 
485
 
        /* if we have pixels, determine the actual color and get out */
486
 
        if (pixels)
487
 
        {
488
 
                static const UINT16 ormask[16] =
489
 
                {
490
 
                        0x0000, 0x000c, 0x00c0, 0x00cc, 0x0c00, 0x0c0c, 0x0cc0, 0x0ccc,
491
 
                        0xc000, 0xc00c, 0xc0c0, 0xc0cc, 0xcc00, 0xcc0c, 0xccc0, 0xcccc
492
 
                };
493
 
                static const UINT16 spritecollide[16] =
494
 
                {
495
 
                        0x0000, 0x0000, 0x0000, 0x0200, 0x0000, 0x0400, 0x1000, 0x1600,
496
 
                        0x0000, 0x0800, 0x2000, 0x2a00, 0x4000, 0x4c00, 0x7000, 0x7e00
497
 
                };
498
 
                int collide;
499
 
                const int esprm = 0x10, osprm = 0x10;
500
 
 
501
 
                /* OR the two sprite bits together so we only have 1 bit per sprite */
502
 
                collide = pixels | (pixels >> 1);
503
 
 
504
 
                /* based on the CLXCON, merge even/odd sprite results */
505
 
                collide |= (collide & ormask[CUSTOM_REG(REG_CLXCON) >> 12]) >> 2;
506
 
 
507
 
                /* collapse down to a 4-bit final "sprite present" mask */
508
 
                collide = (collide & 1) | ((collide >> 3) & 2) | ((collide >> 6) & 4) | ((collide >> 9) & 8);
509
 
 
510
 
                /* compute sprite-sprite collisions */
511
 
                CUSTOM_REG(REG_CLXDAT) |= spritecollide[collide];
512
 
 
513
 
                /* now determine the actual color */
514
 
                for (pair = 0; pixels; pair++, pixels >>= 4)
515
 
                        if (pixels & 0x0f)
516
 
                        {
517
 
                                /* final result is:
518
 
                    topmost sprite color in bits 0-5
519
 
                    sprite present bitmask in bits 6-9
520
 
                    topmost sprite pair index in bits 10-11
521
 
                */
522
 
                                UINT32 result = (collide << 6) | (pair << 10);
523
 
 
524
 
                                /* attached case */
525
 
                                if (CUSTOM_REG(REG_SPR1CTL + 8 * pair) & 0x0080)
526
 
                                        return (pixels & 0xf) | osprm | result;
527
 
 
528
 
                                /* lower-numbered sprite of pair */
529
 
                                else if (pixels & 3)
530
 
                                        return (pixels & 3) | esprm | (pair << 2) | result;
531
 
 
532
 
                                /* higher-numbered sprite of pair */
533
 
                                else
534
 
                                        return ((pixels >> 2) & 3) | osprm | (pair << 2) | result;
535
 
                        }
536
 
        }
537
 
 
538
 
        return 0;
539
 
}
540
 
 
541
 
 
542
 
 
543
 
/*************************************
544
 
 *
545
 
 *  Bitplane assembly
546
 
 *
547
 
 *************************************/
548
 
 
549
 
INLINE UINT8 assemble_odd_bitplanes(amiga_state *state, int planes, int obitoffs)
550
 
{
551
 
        UINT8 pix = (CUSTOM_REG(REG_BPL1DAT) >> obitoffs) & 1;
552
 
        if (planes >= 3)
553
 
        {
554
 
                pix |= ((CUSTOM_REG(REG_BPL3DAT) >> obitoffs) & 1) << 2;
555
 
                if (planes >= 5)
556
 
                        pix |= ((CUSTOM_REG(REG_BPL5DAT) >> obitoffs) & 1) << 4;
557
 
        }
558
 
        return pix;
559
 
}
560
 
 
561
 
 
562
 
INLINE UINT8 assemble_even_bitplanes(amiga_state *state, int planes, int ebitoffs)
563
 
{
564
 
        UINT8 pix = 0;
565
 
        if (planes >= 2)
566
 
        {
567
 
                pix |= ((CUSTOM_REG(REG_BPL2DAT) >> ebitoffs) & 1) << 1;
568
 
                if (planes >= 4)
569
 
                {
570
 
                        pix |= ((CUSTOM_REG(REG_BPL4DAT) >> ebitoffs) & 1) << 3;
571
 
                        if (planes >= 6)
572
 
                                pix |= ((CUSTOM_REG(REG_BPL6DAT) >> ebitoffs) & 1) << 5;
573
 
                }
574
 
        }
575
 
        return pix;
576
 
}
577
 
 
578
 
INLINE void fetch_bitplane_data(amiga_state *state, int plane)
579
 
{
580
 
        CUSTOM_REG(REG_BPL1DAT + plane) = (*state->m_chip_ram_r)(state, CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2));
581
 
        CUSTOM_REG_LONG(REG_BPL1PTH + plane * 2) += 2;
582
 
}
583
 
 
584
 
 
585
 
/*************************************
586
 
 *
587
 
 *  Hold and modify pixel computations
588
 
 *
589
 
 *************************************/
590
 
 
591
 
INLINE int update_ham(amiga_state *state, int newpix)
592
 
{
593
 
        switch (newpix >> 4)
594
 
        {
595
 
                case 0:
596
 
                        state->m_ham_color = CUSTOM_REG(REG_COLOR00 + (newpix & 0xf));
597
 
                        break;
598
 
 
599
 
                case 1:
600
 
                        state->m_ham_color = (state->m_ham_color & 0xff0) | ((newpix & 0xf) << 0);
601
 
                        break;
602
 
 
603
 
                case 2:
604
 
                        state->m_ham_color = (state->m_ham_color & 0x0ff) | ((newpix & 0xf) << 8);
605
 
                        break;
606
 
 
607
 
                case 3:
608
 
                        state->m_ham_color = (state->m_ham_color & 0xf0f) | ((newpix & 0xf) << 4);
609
 
                        break;
610
 
        }
611
 
        return state->m_ham_color;
612
 
}
613
 
 
614
 
 
615
 
 
616
 
/*************************************
617
 
 *
618
 
 *  Single scanline rasterizer
619
 
 *
620
 
 *************************************/
621
 
 
622
 
void amiga_render_scanline(running_machine &machine, bitmap_t *bitmap, int scanline)
623
 
{
624
 
        amiga_state *state = machine.driver_data<amiga_state>();
625
 
        UINT16 save_color0 = CUSTOM_REG(REG_COLOR00);
626
 
        int ddf_start_pixel = 0, ddf_stop_pixel = 0;
627
 
        int hires = 0, dualpf = 0, ham = 0;
628
 
        int hstart = 0, hstop = 0;
629
 
        int vstart = 0, vstop = 0;
630
 
        int pf1pri = 0, pf2pri = 0;
631
 
        int planes = 0;
632
 
 
633
 
        int x;
634
 
        UINT16 *dst = NULL;
635
 
        int ebitoffs = 0, obitoffs = 0;
636
 
        int ecolmask = 0, ocolmask = 0;
637
 
        int edelay = 0, odelay = 0;
638
 
        int next_copper_x;
639
 
        int pl;
640
 
        const int defbitoffs = 15;
641
 
 
642
 
        state->m_last_scanline = scanline;
643
 
 
644
 
        /* on the first scanline, reset the COPPER and HAM color */
645
 
        if (scanline == 0)
646
 
        {
647
 
                amiga_copper_setpc(machine, CUSTOM_REG_LONG(REG_COP1LCH));
648
 
                state->m_ham_color = CUSTOM_REG(REG_COLOR00);
649
 
        }
650
 
 
651
 
        /* update sprite data fetching */
652
 
        update_sprite_dma(state, scanline);
653
 
 
654
 
        /* start of a new line, signal we're not done with it and fill up vars */
655
 
        if (bitmap != NULL)
656
 
                dst = BITMAP_ADDR16(bitmap, scanline, 0);
657
 
 
658
 
        /* all sprites off at the start of the line */
659
 
        memset(state->m_sprite_remain, 0, sizeof(state->m_sprite_remain));
660
 
 
661
 
        /* temporary set color 0 to the genlock color */
662
 
        if (state->m_genlock_color != 0xffff)
663
 
                CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
664
 
 
665
 
        /* loop over the line */
666
 
        next_copper_x = 0;
667
 
        for (x = 0; x < 0xe4*2; x++)
668
 
        {
669
 
                int sprpix;
670
 
 
671
 
                /* time to execute the copper? */
672
 
                if (x == next_copper_x)
673
 
                {
674
 
                        /* execute the next batch, restoring and re-saving color 0 around it */
675
 
                        CUSTOM_REG(REG_COLOR00) = save_color0;
676
 
                        next_copper_x = amiga_copper_execute_next(machine, x);
677
 
                        save_color0 = CUSTOM_REG(REG_COLOR00);
678
 
                        if (state->m_genlock_color != 0xffff)
679
 
                                CUSTOM_REG(REG_COLOR00) = state->m_genlock_color;
680
 
 
681
 
                        /* compute update-related register values */
682
 
                        planes = (CUSTOM_REG(REG_BPLCON0) & (BPLCON0_BPU0 | BPLCON0_BPU1 | BPLCON0_BPU2)) >> 12;
683
 
                        hires = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HIRES;
684
 
                        ham = CUSTOM_REG(REG_BPLCON0) & BPLCON0_HOMOD;
685
 
                        dualpf = CUSTOM_REG(REG_BPLCON0) & BPLCON0_DBLPF;
686
 
//          lace = CUSTOM_REG(REG_BPLCON0) & BPLCON0_LACE;
687
 
 
688
 
                        /* compute the pixel fetch parameters */
689
 
                        ddf_start_pixel = ( CUSTOM_REG(REG_DDFSTRT) & 0xfc ) * 2 + (hires ? 9 : 17);
690
 
                        ddf_stop_pixel = ( CUSTOM_REG(REG_DDFSTOP) & 0xfc ) * 2 + (hires ? (9 + defbitoffs) : (17 + defbitoffs));
691
 
 
692
 
                        if ( ( CUSTOM_REG(REG_DDFSTRT) ^ CUSTOM_REG(REG_DDFSTOP) ) & 0x04 )
693
 
                                ddf_stop_pixel += 8;
694
 
 
695
 
                        /* compute the horizontal start/stop */
696
 
                        hstart = CUSTOM_REG(REG_DIWSTRT) & 0xff;
697
 
                        hstop = (CUSTOM_REG(REG_DIWSTOP) & 0xff);
698
 
                        hstop |= 0x100;
699
 
 
700
 
                        /* compute the vertical start/stop */
701
 
                        vstart = CUSTOM_REG(REG_DIWSTRT) >> 8;
702
 
                        vstop = (CUSTOM_REG(REG_DIWSTOP) >> 8);
703
 
                        vstop |= ((~CUSTOM_REG(REG_DIWSTOP) >> 7) & 0x100);
704
 
 
705
 
                        /* extract playfield priorities */
706
 
                        pf1pri = CUSTOM_REG(REG_BPLCON2) & 7;
707
 
                        pf2pri = (CUSTOM_REG(REG_BPLCON2) >> 3) & 7;
708
 
 
709
 
                        /* extract collision masks */
710
 
                        ocolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x15;
711
 
                        ecolmask = (CUSTOM_REG(REG_CLXCON) >> 6) & 0x2a;
712
 
                }
713
 
 
714
 
                /* clear the target pixels to the background color as a starting point */
715
 
                if (dst != NULL)
716
 
                        dst[x*2+0] =
717
 
                        dst[x*2+1] = CUSTOM_REG(REG_COLOR00);
718
 
 
719
 
                /* if we hit the first fetch pixel, reset the counters and latch the delays */
720
 
                if (x == ddf_start_pixel)
721
 
                {
722
 
                        odelay = CUSTOM_REG(REG_BPLCON1) & 0xf;
723
 
                        edelay = ( CUSTOM_REG(REG_BPLCON1) >> 4 ) & 0x0f;
724
 
 
725
 
                        if ( hires )
726
 
                        {
727
 
                                obitoffs = defbitoffs + ( odelay << 1 );
728
 
                                ebitoffs = defbitoffs + ( edelay << 1 );
729
 
                        }
730
 
                        else
731
 
                        {
732
 
                                if ( CUSTOM_REG(REG_DDFSTRT) & 0x04 )
733
 
                                {
734
 
                                        odelay = ( odelay + 8 ) & 0x0f;
735
 
                                        edelay = ( edelay + 8 ) & 0x0f;
736
 
                                }
737
 
 
738
 
                                obitoffs = defbitoffs + odelay;
739
 
                                ebitoffs = defbitoffs + edelay;
740
 
                        }
741
 
 
742
 
                        for (pl = 0; pl < 6; pl++)
743
 
                                CUSTOM_REG(REG_BPL1DAT + pl) = 0;
744
 
                }
745
 
 
746
 
                /* need to run the sprite engine every pixel to ensure display */
747
 
                sprpix = get_sprite_pixel(state, x);
748
 
 
749
 
                /* to render, we must have bitplane DMA enabled, at least 1 plane, and be within the */
750
 
                /* vertical display window */
751
 
                if ((CUSTOM_REG(REG_DMACON) & (DMACON_BPLEN | DMACON_DMAEN)) == (DMACON_BPLEN | DMACON_DMAEN) &&
752
 
                        planes > 0 && scanline >= vstart && scanline < vstop)
753
 
                {
754
 
                        int pfpix0 = 0, pfpix1 = 0, collide;
755
 
 
756
 
                        /* fetch the odd bits if we are within the fetching region */
757
 
                        if (x >= ddf_start_pixel && x <= ddf_stop_pixel + odelay)
758
 
                        {
759
 
                                /* if we need to fetch more data, do it now */
760
 
                                if (obitoffs == defbitoffs)
761
 
                                {
762
 
                                        for (pl = 0; pl < planes; pl += 2)
763
 
                                        {
764
 
                                                fetch_bitplane_data(state, pl);
765
 
                                        }
766
 
                                }
767
 
 
768
 
                                /* now assemble the bits */
769
 
                                pfpix0 |= assemble_odd_bitplanes(state, planes, obitoffs);
770
 
                                obitoffs--;
771
 
 
772
 
                                /* for high res, assemble a second set of bits */
773
 
                                if (hires)
774
 
                                {
775
 
                                        /* reset bit offsets and fetch more data if needed */
776
 
                                        if (obitoffs < 0)
777
 
                                        {
778
 
                                                obitoffs = defbitoffs;
779
 
 
780
 
                                                for (pl = 0; pl < planes; pl += 2)
781
 
                                                {
782
 
                                                        fetch_bitplane_data(state, pl);
783
 
                                                }
784
 
                                        }
785
 
 
786
 
                                        pfpix1 |= assemble_odd_bitplanes(state, planes, obitoffs);
787
 
                                        obitoffs--;
788
 
                                }
789
 
                                else
790
 
                                        pfpix1 |= pfpix0 & 0x15;
791
 
 
792
 
                                /* reset bit offsets if needed */
793
 
                                if (obitoffs < 0)
794
 
                                        obitoffs = defbitoffs;
795
 
                        }
796
 
 
797
 
                        /* fetch the even bits if we are within the fetching region */
798
 
                        if (x >= ddf_start_pixel && x <= ddf_stop_pixel + edelay)
799
 
                        {
800
 
                                /* if we need to fetch more data, do it now */
801
 
                                if (ebitoffs == defbitoffs)
802
 
                                {
803
 
                                        for (pl = 1; pl < planes; pl += 2)
804
 
                                        {
805
 
                                                fetch_bitplane_data(state, pl);
806
 
                                        }
807
 
                                }
808
 
 
809
 
                                /* now assemble the bits */
810
 
                                pfpix0 |= assemble_even_bitplanes(state, planes, ebitoffs);
811
 
                                ebitoffs--;
812
 
 
813
 
                                /* for high res, assemble a second set of bits */
814
 
                                if (hires)
815
 
                                {
816
 
                                        /* reset bit offsets and fetch more data if needed */
817
 
                                        if (ebitoffs < 0)
818
 
                                        {
819
 
                                                ebitoffs = defbitoffs;
820
 
 
821
 
                                                for (pl = 1; pl < planes; pl += 2)
822
 
                                                {
823
 
                                                        fetch_bitplane_data(state, pl);
824
 
                                                }
825
 
                                        }
826
 
 
827
 
                                        pfpix1 |= assemble_even_bitplanes(state, planes, ebitoffs);
828
 
                                        ebitoffs--;
829
 
                                }
830
 
                                else
831
 
                                        pfpix1 |= pfpix0 & 0x2a;
832
 
 
833
 
                                /* reset bit offsets if needed */
834
 
                                if (ebitoffs < 0)
835
 
                                        ebitoffs = defbitoffs;
836
 
                        }
837
 
 
838
 
                        /* compute playfield/sprite collisions for first pixel */
839
 
                        collide = pfpix0 ^ CUSTOM_REG(REG_CLXCON);
840
 
                        if ((collide & ocolmask) == 0)
841
 
                                CUSTOM_REG(REG_CLXDAT) |= (sprpix >> 5) & 0x01e;
842
 
                        if ((collide & ecolmask) == 0)
843
 
                                CUSTOM_REG(REG_CLXDAT) |= (sprpix >> 1) & 0x1e0;
844
 
                        if ((collide & (ecolmask | ocolmask)) == 0)
845
 
                                CUSTOM_REG(REG_CLXDAT) |= 0x001;
846
 
 
847
 
                        /* compute playfield/sprite collisions for second pixel */
848
 
                        collide = pfpix1 ^ CUSTOM_REG(REG_CLXCON);
849
 
                        if ((collide & ocolmask) == 0)
850
 
                                CUSTOM_REG(REG_CLXDAT) |= (sprpix >> 5) & 0x01e;
851
 
                        if ((collide & ecolmask) == 0)
852
 
                                CUSTOM_REG(REG_CLXDAT) |= (sprpix >> 1) & 0x1e0;
853
 
                        if ((collide & (ecolmask | ocolmask)) == 0)
854
 
                                CUSTOM_REG(REG_CLXDAT) |= 0x001;
855
 
 
856
 
                        /* if we are within the display region, render */
857
 
                        if (dst != NULL && x >= hstart && x < hstop)
858
 
                        {
859
 
                                int pix, pri;
860
 
 
861
 
                                /* hold-and-modify mode -- assume low-res (hi-res not supported by the hardware) */
862
 
                                if (ham)
863
 
                                {
864
 
                                        /* update the HAM color */
865
 
                                        pfpix0 = update_ham(state, pfpix0);
866
 
 
867
 
                                        pix = sprpix & 0x1f;
868
 
                                        pri = (sprpix >> 10);
869
 
 
870
 
                                        /* sprite has priority */
871
 
                                        if (sprpix && pf1pri > pri)
872
 
                                        {
873
 
                                                dst[x*2+0] =
874
 
                                                dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix);
875
 
                                        }
876
 
 
877
 
                                        /* playfield has priority */
878
 
                                        else
879
 
                                        {
880
 
                                                dst[x*2+0] =
881
 
                                                dst[x*2+1] = pfpix0;
882
 
                                        }
883
 
                                }
884
 
 
885
 
                                /* dual playfield mode */
886
 
                                else if (dualpf)
887
 
                                {
888
 
                                        /* mask out the sprite if it doesn't have priority */
889
 
                                        pix = sprpix & 0x1f;
890
 
                                        pri = (sprpix >> 10);
891
 
                                        if (pix)
892
 
                                        {
893
 
                                                if ((pfpix0 & 0x15) && pf1pri <= pri)
894
 
                                                        pix = 0;
895
 
                                                if ((pfpix0 & 0x2a) && pf2pri <= pri)
896
 
                                                        pix = 0;
897
 
                                        }
898
 
 
899
 
                                        /* write out the left pixel */
900
 
                                        if (pix)
901
 
                                                dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + pix);
902
 
                                        else
903
 
                                                dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix0]);
904
 
 
905
 
                                        /* mask out the sprite if it doesn't have priority */
906
 
                                        pix = sprpix & 0x1f;
907
 
                                        if (pix)
908
 
                                        {
909
 
                                                if ((pfpix1 & 0x15) && pf1pri <= pri)
910
 
                                                        pix = 0;
911
 
                                                if ((pfpix1 & 0x2a) && pf2pri <= pri)
912
 
                                                        pix = 0;
913
 
                                        }
914
 
 
915
 
                                        /* write out the right pixel */
916
 
                                        if (pix)
917
 
                                                dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix);
918
 
                                        else
919
 
                                                dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + state->m_separate_bitplanes[(CUSTOM_REG(REG_BPLCON2) >> 6) & 1][pfpix1]);
920
 
                                }
921
 
 
922
 
                                /* single playfield mode */
923
 
                                else
924
 
                                {
925
 
                                        pix = sprpix & 0x1f;
926
 
                                        pri = (sprpix >> 10);
927
 
 
928
 
                                        /* sprite has priority */
929
 
                                        if (sprpix && pf1pri > pri)
930
 
                                        {
931
 
                                                dst[x*2+0] =
932
 
                                                dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pix);
933
 
                                        }
934
 
 
935
 
                                        /* playfield has priority */
936
 
                                        else
937
 
                                        {
938
 
                                                dst[x*2+0] = CUSTOM_REG(REG_COLOR00 + pfpix0);
939
 
                                                dst[x*2+1] = CUSTOM_REG(REG_COLOR00 + pfpix1);
940
 
                                        }
941
 
                                }
942
 
                        }
943
 
                }
944
 
        }
945
 
 
946
 
#if 0
947
 
        if ( machine.primary_screen->frame_number() % 64 == 0 && scanline == 100 )
948
 
        {
949
 
                const char *m_lores = "LORES";
950
 
                const char *m_hires = "HIRES";
951
 
                const char *m_ham = "HAM";
952
 
                const char *m_dualpf = "DUALPF";
953
 
                const char *m_lace = "LACE";
954
 
                const char *m_hilace = "HI-LACE";
955
 
                const char *p = m_lores;
956
 
 
957
 
                if ( hires ) p = m_hires;
958
 
                if ( ham ) p = m_ham;
959
 
                if ( dualpf ) p = m_dualpf;
960
 
                if ( lace ) p = m_lace;
961
 
 
962
 
                if ( hires && lace ) p = m_hilace;
963
 
 
964
 
                popmessage("%s(%d pl od=%04x ed=%04x start=%04x stop=%04x)", p, planes, odelay, edelay, CUSTOM_REG(REG_DDFSTRT), CUSTOM_REG(REG_DDFSTOP) );
965
 
        }
966
 
#endif
967
 
 
968
 
        /* end of the line: time to add the modulos */
969
 
        if (scanline >= vstart && scanline < vstop)
970
 
        {
971
 
                /* update odd planes */
972
 
                for (pl = 0; pl < planes; pl += 2)
973
 
                        CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += CUSTOM_REG_SIGNED(REG_BPL1MOD);
974
 
 
975
 
                /* update even planes */
976
 
                for (pl = 1; pl < planes; pl += 2)
977
 
                        CUSTOM_REG_LONG(REG_BPL1PTH + pl * 2) += CUSTOM_REG_SIGNED(REG_BPL2MOD);
978
 
        }
979
 
 
980
 
        /* restore color00 */
981
 
        CUSTOM_REG(REG_COLOR00) = save_color0;
982
 
 
983
 
#if GUESS_COPPER_OFFSET
984
 
        if (machine.primary_screen->frame_number() % 64 == 0 && scanline == 0)
985
 
        {
986
 
                if (machine.input().code_pressed(KEYCODE_Q))
987
 
                        popmessage("%d", state->m_wait_offset -= 1);
988
 
                if (machine.input().code_pressed(KEYCODE_W))
989
 
                        popmessage("%d", state->m_wait_offset += 1);
990
 
        }
991
 
#endif
992
 
}
993
 
 
994
 
 
995
 
 
996
 
/*************************************
997
 
 *
998
 
 *  Update
999
 
 *
1000
 
 *************************************/
1001
 
 
1002
 
SCREEN_UPDATE( amiga )
1003
 
{
1004
 
        int y;
1005
 
 
1006
 
        /* render each scanline in the visible region */
1007
 
        for (y = cliprect->min_y; y <= cliprect->max_y; y++)
1008
 
                amiga_render_scanline(screen->machine(), bitmap, y);
1009
 
 
1010
 
        return 0;
1011
 
}
1012