1 /***************************************************************************
2
3 vidhrdw.c
4
5 Functions to emulate the video hardware of the machine.
6
7 d800-dbff foreground: char low bits (1 screen * 1024 chars/screen)
8 dc00-dfff foreground attribute: 7 ?
9 6543 color
10 21 ?
11 0 char hi bit
12
13
14 e000-e0ff spriteram: 64 sprites (4 bytes/sprite)
15 offset : 0 1 2 3
16 meaning: ypos(lo) sprite(lo) attribute xpos(lo)
17 7 flipy
18 6 flipx
19 5-2 color
20 1 sprite(hi)
21 0 xpos(hi)
22
23
24 background: 0x4000 bytes of ROM: 76543210 tile code low bits
25 0x4000 bytes of ROM: 7 ?
26 6543 color
27 2 ?
28 10 tile code high bits
29
30 ***************************************************************************/
31
32 #include "driver.h"
33 #include "vidhrdw/generic.h"
34
35 static unsigned char scrollx[2], scrolly[2];
36
37 /* Layers has only bits 5-6 active.
38 6 selects background off/on
39 5 is unknown (active only on title screen,
40 not for scores or push start nor game)
41 */
42
43 static int flipscreen, layers;
44
45 static struct tilemap *bg_tilemap, *tx_tilemap;
46
47 static const unsigned char *spritepalettebank;
48 static int ninjemak_dispdisable;
49
50
51
52 /***************************************************************************
53
54 Convert the color PROMs into a more useable format.
55
56 ***************************************************************************/
57
PALETTE_INIT(galivan)58 PALETTE_INIT( galivan )
59 {
60 int i;
61 #define TOTAL_COLORS(gfxn) (Machine->gfx[gfxn]->total_colors * Machine->gfx[gfxn]->color_granularity)
62 #define COLOR(gfxn,offs) (colortable[Machine->drv->gfxdecodeinfo[gfxn].color_codes_start + offs])
63
64 for (i = 0;i < Machine->drv->total_colors;i++)
65 {
66 int bit0,bit1,bit2,bit3,r,g,b;
67
68 bit0 = (color_prom[0] >> 0) & 0x01;
69 bit1 = (color_prom[0] >> 1) & 0x01;
70 bit2 = (color_prom[0] >> 2) & 0x01;
71 bit3 = (color_prom[0] >> 3) & 0x01;
72 r = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
73 bit0 = (color_prom[Machine->drv->total_colors] >> 0) & 0x01;
74 bit1 = (color_prom[Machine->drv->total_colors] >> 1) & 0x01;
75 bit2 = (color_prom[Machine->drv->total_colors] >> 2) & 0x01;
76 bit3 = (color_prom[Machine->drv->total_colors] >> 3) & 0x01;
77 g = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
78 bit0 = (color_prom[2*Machine->drv->total_colors] >> 0) & 0x01;
79 bit1 = (color_prom[2*Machine->drv->total_colors] >> 1) & 0x01;
80 bit2 = (color_prom[2*Machine->drv->total_colors] >> 2) & 0x01;
81 bit3 = (color_prom[2*Machine->drv->total_colors] >> 3) & 0x01;
82 b = 0x0e * bit0 + 0x1f * bit1 + 0x43 * bit2 + 0x8f * bit3;
83
84 palette_set_color(i,r,g,b);
85 color_prom++;
86 }
87
88 color_prom += 2*Machine->drv->total_colors;
89 /* color_prom now points to the beginning of the lookup tables */
90
91
92 /* characters use colors 0-127 */
93 for (i = 0;i < TOTAL_COLORS(0);i++)
94 COLOR(0,i) = i;
95
96 /* I think that */
97 /* background tiles use colors 192-255 in four banks */
98 /* the bottom two bits of the color code select the palette bank for */
99 /* pens 0-7; the top two bits for pens 8-15. */
100 for (i = 0;i < TOTAL_COLORS(1);i++)
101 {
102 if (i & 8) COLOR(1,i) = 192 + (i & 0x0f) + ((i & 0xc0) >> 2);
103 else COLOR(1,i) = 192 + (i & 0x0f) + ((i & 0x30) >> 0);
104 }
105
106
107 /* sprites use colors 128-191 in four banks */
108 /* The lookup table tells which colors to pick from the selected bank */
109 /* the bank is selected by another PROM and depends on the top 7 bits of */
110 /* the sprite code. The PROM selects the bank *separately* for pens 0-7 and */
111 /* 8-15 (like for tiles). */
112 for (i = 0;i < TOTAL_COLORS(2)/16;i++)
113 {
114 int j;
115
116 for (j = 0;j < 16;j++)
117 {
118 if (i & 8)
119 COLOR(2,i + j * (TOTAL_COLORS(2)/16)) = 128 + ((j & 0x0c) << 2) + (*color_prom & 0x0f);
120 else
121 COLOR(2,i + j * (TOTAL_COLORS(2)/16)) = 128 + ((j & 0x03) << 4) + (*color_prom & 0x0f);
122 }
123
124 color_prom++;
125 }
126
127 /* color_prom now points to the beginning of the sprite palette bank table */
128 spritepalettebank = color_prom; /* we'll need it at run time */
129 }
130
131
132
133 /***************************************************************************
134
135 Callbacks for the TileMap code
136
137 ***************************************************************************/
138
get_bg_tile_info(int tile_index)139 static void get_bg_tile_info(int tile_index)
140 {
141 unsigned char *BGROM = memory_region(REGION_GFX4);
142 int attr = BGROM[tile_index + 0x4000];
143 int code = BGROM[tile_index] | ((attr & 0x03) << 8);
144 SET_TILE_INFO(
145 1,
146 code,
147 (attr & 0x78) >> 3, /* seems correct */
148 0)
149 }
150
get_tx_tile_info(int tile_index)151 static void get_tx_tile_info(int tile_index)
152 {
153 int attr = colorram[tile_index];
154 int code = videoram[tile_index] | ((attr & 0x01) << 8);
155 SET_TILE_INFO(
156 0,
157 code,
158 (attr & 0xe0) >> 5, /* not sure */
159 0)
160 tile_info.priority = attr & 8 ? 0 : 1; /* wrong */
161 }
162
ninjemak_get_bg_tile_info(int tile_index)163 static void ninjemak_get_bg_tile_info(int tile_index)
164 {
165 unsigned char *BGROM = memory_region(REGION_GFX4);
166 int attr = BGROM[tile_index + 0x4000];
167 int code = BGROM[tile_index] | ((attr & 0x03) << 8);
168 SET_TILE_INFO(
169 1,
170 code,
171 ((attr & 0x60) >> 3) | ((attr & 0x0c) >> 2), /* seems correct */
172 0)
173 }
174
ninjemak_get_tx_tile_info(int tile_index)175 static void ninjemak_get_tx_tile_info(int tile_index)
176 {
177 int attr = colorram[tile_index];
178 int code = videoram[tile_index] | ((attr & 0x03) << 8);
179 SET_TILE_INFO(
180 0,
181 code,
182 (attr & 0x1c) >> 2, /* seems correct ? */
183 0)
184 }
185
186
187
188 /***************************************************************************
189
190 Start the video hardware emulation.
191
192 ***************************************************************************/
193
VIDEO_START(galivan)194 VIDEO_START( galivan )
195 {
196 bg_tilemap = tilemap_create(get_bg_tile_info,tilemap_scan_rows,TILEMAP_OPAQUE, 16,16,128,128);
197 tx_tilemap = tilemap_create(get_tx_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
198
199 if (!bg_tilemap || !tx_tilemap)
200 return 1;
201
202 tilemap_set_transparent_pen(tx_tilemap,15);
203
204 return 0;
205 }
206
VIDEO_START(ninjemak)207 VIDEO_START( ninjemak )
208 {
209 bg_tilemap = tilemap_create(ninjemak_get_bg_tile_info,tilemap_scan_cols,TILEMAP_OPAQUE, 16,16,512,32);
210 tx_tilemap = tilemap_create(ninjemak_get_tx_tile_info,tilemap_scan_cols,TILEMAP_TRANSPARENT,8,8,32,32);
211
212 if (!bg_tilemap || !tx_tilemap)
213 return 1;
214
215 tilemap_set_transparent_pen(tx_tilemap,15);
216
217 return 0;
218 }
219
220
221
222 /***************************************************************************
223
224 Memory handlers
225
226 ***************************************************************************/
227
WRITE_HANDLER(galivan_videoram_w)228 WRITE_HANDLER( galivan_videoram_w )
229 {
230 if (videoram[offset] != data)
231 {
232 videoram[offset] = data;
233 tilemap_mark_tile_dirty(tx_tilemap,offset);
234 }
235 }
236
WRITE_HANDLER(galivan_colorram_w)237 WRITE_HANDLER( galivan_colorram_w )
238 {
239 if (colorram[offset] != data)
240 {
241 colorram[offset] = data;
242 tilemap_mark_tile_dirty(tx_tilemap,offset);
243 }
244 }
245
246 /* Written through port 40 */
WRITE_HANDLER(galivan_gfxbank_w)247 WRITE_HANDLER( galivan_gfxbank_w )
248 {
249 /* bits 0 and 1 coin counters */
250 coin_counter_w(0,data & 1);
251 coin_counter_w(1,data & 2);
252
253 /* bit 2 flip screen */
254 flipscreen = data & 0x04;
255 tilemap_set_flip (bg_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
256 tilemap_set_flip (tx_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
257
258 /* bit 7 selects one of two ROM banks for c000-dfff */
259 {
260 int bank = (data & 0x80) >> 7;
261 unsigned char *RAM = memory_region(REGION_CPU1);
262
263 cpu_setbank(1,&RAM[0x10000 + 0x2000 * bank]);
264 }
265
266 /* log_cb(RETRO_LOG_DEBUG, LOGPRE "Address: %04X - port 40 = %02x\n",activecpu_get_pc(),data); */
267 }
268
WRITE_HANDLER(ninjemak_gfxbank_w)269 WRITE_HANDLER( ninjemak_gfxbank_w )
270 {
271 /* bits 0 and 1 coin counters */
272 coin_counter_w(0,data & 1);
273 coin_counter_w(1,data & 2);
274
275 /* bit 2 flip screen */
276 flipscreen = data & 0x04;
277 tilemap_set_flip (bg_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
278 tilemap_set_flip (tx_tilemap, flipscreen ? TILEMAP_FLIPX|TILEMAP_FLIPY : 0);
279
280 /* bit 3 text bank flag ??? */
281 if (data & 0x08)
282 {
283 /* This is a temporary condition specification. */
284
285 int offs;
286
287 log_cb(RETRO_LOG_DEBUG, LOGPRE "%04x: write %02x to port 80\n",activecpu_get_pc(),data);
288
289 for (offs = 0; offs < videoram_size; offs++)
290 {
291 galivan_videoram_w(offs, 0x20);
292 }
293 for (offs = 0; offs < videoram_size; offs++)
294 {
295 galivan_colorram_w(offs, 0x03);
296 }
297 }
298
299 /* bit 4 background disable flag */
300 ninjemak_dispdisable = data & 0x10;
301
302 /* bit 5 sprite flag ??? */
303
304 /* bit 6, 7 ROM bank select */
305 {
306 int bank = (data & 0xc0) >> 6;
307 unsigned char *RAM = memory_region(REGION_CPU1);
308
309 cpu_setbank(1,&RAM[0x10000 + 0x2000 * bank]);
310 }
311
312 #if 0
313 {
314 char mess[80];
315 int btz[8];
316 int offs;
317
318 for (offs = 0; offs < 8; offs++) btz[offs] = (((data >> offs) & 0x01) ? 1 : 0);
319
320 sprintf(mess, "BK:%01X%01X S:%01X B:%01X T:%01X FF:%01X C2:%01X C1:%01X", btz[7], btz[6], btz[5], btz[4], btz[3], btz[2], btz[1], btz[0]);
321 usrintf_showmessage(mess);
322 }
323 #endif
324 }
325
326
327
328 /* Written through port 41-42 */
WRITE_HANDLER(galivan_scrollx_w)329 WRITE_HANDLER( galivan_scrollx_w )
330 {
331 static int up = 0;
332 if (offset == 1) {
333 if (data & 0x80)
334 up = 1;
335 else if (up) {
336 layers = data & 0x60;
337 up = 0;
338 }
339 }
340 scrollx[offset] = data;
341 }
342
343 /* Written through port 43-44 */
WRITE_HANDLER(galivan_scrolly_w)344 WRITE_HANDLER( galivan_scrolly_w )
345 {
346 scrolly[offset] = data;
347 }
348
349
WRITE_HANDLER(ninjemak_scrollx_w)350 WRITE_HANDLER( ninjemak_scrollx_w )
351 {
352 scrollx[offset] = data;
353 }
354
WRITE_HANDLER(ninjemak_scrolly_w)355 WRITE_HANDLER( ninjemak_scrolly_w )
356 {
357 scrolly[offset] = data;
358 }
359
360
361
362 /***************************************************************************
363
364 Display refresh
365
366 ***************************************************************************/
367
draw_sprites(struct mame_bitmap * bitmap,const struct rectangle * cliprect)368 static void draw_sprites(struct mame_bitmap *bitmap, const struct rectangle *cliprect)
369 {
370 int offs;
371
372 /* draw the sprites */
373 for (offs = 0;offs < spriteram_size;offs += 4)
374 {
375 int code;
376 int attr = spriteram[offs+2];
377 int color = (attr & 0x3c) >> 2;
378 int flipx = attr & 0x40;
379 int flipy = attr & 0x80;
380 int sx,sy;
381
382 sx = (spriteram[offs+3] - 0x80) + 256 * (attr & 0x01);
383 sy = 240 - spriteram[offs];
384 if (flipscreen)
385 {
386 sx = 240 - sx;
387 sy = 240 - sy;
388 flipx = !flipx;
389 flipy = !flipy;
390 }
391
392 /* code = spriteram[offs+1] + ((attr & 0x02) << 7);*/
393 code = spriteram[offs+1] + ((attr & 0x06) << 7); /* for ninjemak, not sure ?*/
394
395 drawgfx(bitmap,Machine->gfx[2],
396 code,
397 color + 16 * (spritepalettebank[code >> 2] & 0x0f),
398 flipx,flipy,
399 sx,sy,
400 cliprect,TRANSPARENCY_PEN,15);
401 }
402 }
403
404
VIDEO_UPDATE(galivan)405 VIDEO_UPDATE( galivan )
406 {
407 tilemap_set_scrollx(bg_tilemap,0,scrollx[0] + 256 * (scrollx[1] & 0x07));
408 tilemap_set_scrolly(bg_tilemap,0,scrolly[0] + 256 * (scrolly[1] & 0x07));
409
410 if (layers & 0x40)
411 fillbitmap(bitmap,Machine->pens[0],cliprect);
412 else
413 tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
414
415 tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
416
417 draw_sprites(bitmap,cliprect);
418
419 tilemap_draw(bitmap,cliprect,tx_tilemap,1,0);
420 }
421
VIDEO_UPDATE(ninjemak)422 VIDEO_UPDATE( ninjemak )
423 {
424 /* (scrollx[1] & 0x40) does something */
425 tilemap_set_scrollx(bg_tilemap,0,scrollx[0] + 256 * (scrollx[1] & 0x1f));
426 tilemap_set_scrolly(bg_tilemap,0,scrolly[0] + 256 * (scrolly[1] & 0xff));
427
428 if (ninjemak_dispdisable)
429 fillbitmap(bitmap,Machine->pens[0],cliprect);
430 else
431 tilemap_draw(bitmap,cliprect,bg_tilemap,0,0);
432
433 draw_sprites(bitmap,cliprect);
434
435 tilemap_draw(bitmap,cliprect,tx_tilemap,0,0);
436 }
437