1 // license:BSD-3-Clause
2 // copyright-holders:Yochizo
3 /***************************************************************************
4
5 Functions to emulate the video hardware of the machine.
6
7
8 BG RAM format [Argus and Butasan]
9 -----------------------------------------------------------------------------
10 +0 +1
11 xxxx xxxx ---- ---- = 1st - 8th bits of tile number
12 ---- ---- xx-- ---- = 9th and 10th bit of tile number
13 ---- ---- --x- ---- = flip y
14 ---- ---- ---x ---- = flip x
15 ---- ---- ---- xxxx = color
16
17 BG RAM format [Valtric]
18 -----------------------------------------------------------------------------
19 +0 +1
20 xxxx xxxx ---- ---- = 1st - 8th bits of tile number
21 ---- ---- xx-- ---- = 9th and 10th bit of tile number
22 ---- ---- --x- ---- = 11th bit of tile number
23 ---- ---- ---- xxxx = color
24
25
26 Text RAM format [Argus, Valtric and Butasan]
27 -----------------------------------------------------------------------------
28 +0 +1
29 xxxx xxxx ---- ---- = low bits of tile number
30 ---- ---- xx-- ---- = high bits of tile number
31 ---- ---- --x- ---- = flip y
32 ---- ---- ---x ---- = flip x
33 ---- ---- ---- xxxx = color
34
35
36 Sprite RAM format [Argus]
37 -----------------------------------------------------------------------------
38 +11 +12 +13 +14 +15
39 xxxx xxxx ---- ---- ---- ---- ---- ---- ---- ---- = sprite y
40 ---- ---- xxxx xxxx ---- ---- ---- ---- ---- ---- = low bits of sprite x
41 ---- ---- ---- ---- xx-- ---- ---- ---- ---- ---- = high bits of tile number
42 ---- ---- ---- ---- --x- ---- ---- ---- ---- ---- = flip y
43 ---- ---- ---- ---- ---x ---- ---- ---- ---- ---- = flip x
44 ---- ---- ---- ---- ---- --x- ---- ---- ---- ---- = high bit of sprite y
45 ---- ---- ---- ---- ---- ---x ---- ---- ---- ---- = high bit of sprite x
46 ---- ---- ---- ---- ---- ---- xxxx xxxx ---- ---- = low bits of tile number
47 ---- ---- ---- ---- ---- ---- ---- ---- ---- x--- = BG1 / sprite priority (Argus only)
48 ---- ---- ---- ---- ---- ---- ---- ---- ---- -xxx = color
49
50 Sprite RAM format [Valtric]
51 -----------------------------------------------------------------------------
52 +11 +12 +13 +14 +15
53 xxxx xxxx ---- ---- ---- ---- ---- ---- ---- ---- = sprite y
54 ---- ---- xxxx xxxx ---- ---- ---- ---- ---- ---- = low bits of sprite x
55 ---- ---- ---- ---- xx-- ---- ---- ---- ---- ---- = high bits of tile number
56 ---- ---- ---- ---- --x- ---- ---- ---- ---- ---- = flip y
57 ---- ---- ---- ---- ---x ---- ---- ---- ---- ---- = flip x
58 ---- ---- ---- ---- ---- --x- ---- ---- ---- ---- = high bit of sprite y
59 ---- ---- ---- ---- ---- ---x ---- ---- ---- ---- = high bit of sprite x
60 ---- ---- ---- ---- ---- ---- xxxx xxxx ---- ---- = low bits of tile number
61 ---- ---- ---- ---- ---- ---- ---- ---- ---- xxxx = color
62
63 Sprite RAM format [Butasan]
64 -----------------------------------------------------------------------------
65 +8 +9 +10 +11 +12
66 ---- -x-- ---- ---- ---- ---- ---- ---- ---- ---- = flip y
67 ---- ---x ---- ---- ---- ---- ---- ---- ---- ---- = flip x
68 ---- ---- ---- xxxx ---- ---- ---- ---- ---- ---- = color ($00 - $0B)
69 ---- ---- ---- ---- xxxx xxxx ---- ---- ---- ---- = low bits of sprite x
70 ---- ---- ---- ---- ---- ---- ---- ---x ---- ---- = top bit of sprite x
71 ---- ---- ---- ---- ---- ---- ---- ---- xxxx xxxx = low bits of sprite y
72 +13 +14 +15
73 ---- ---x ---- ---- ---- ---- = top bit of sprite y
74 ---- ---- xxxx xxxx ---- ---- = low bits of tile number
75 ---- ---- ---- ---- ---- xxxx = top bits of tile number
76
77 (*) Sprite size is defined by its offset.
78 $F000 - $F0FF : 16x32 $F100 - $F2FF : 16x16
79 $F300 - $F3FF : 16x32 $F400 - $F57F : 16x16
80 $F580 - $F61F : 32x32 $F620 - $F67F : 64x64
81
82
83 Scroll RAM of X and Y coordinates [Argus, Valtric and Butasan]
84 -----------------------------------------------------------------------------
85 +0 +1
86 xxxx xxxx ---- ---- = scroll value
87 ---- ---- ---- ---x = top bit of scroll value
88
89
90 Video effect RAM ( $C30C )
91 -----------------------------------------------------------------------------
92 +0
93 ---- ---x = BG enable bit
94 ---- --x- = grey scale effect or tile bank select.
95
96
97 Flip screen controller
98 -----------------------------------------------------------------------------
99 +0
100 x--- ---- = flip screen
101
102
103 BG0 palette intensity ( $C47F, $C4FF )
104 -----------------------------------------------------------------------------
105 +0 (c47f) +1 (c4ff)
106 xxxx ---- ---- ---- = red intensity
107 ---- xxxx ---- ---- = green intensity
108 ---- ---- xxxx ---- = blue intensity
109
110
111 (*) Things which are not emulated.
112 - Color $000 - 00f, $01e, $02e ... are half transparent color.
113 - Sprite priority bit may be present in Butasan. But I don't know
114 what happens when it is set.
115
116 ***************************************************************************/
117
118 #include "emu.h"
119 #include "includes/argus.h"
120
121
122 /***************************************************************************
123 Callbacks for the tilemap code
124 ***************************************************************************/
125
126 template<int Gfx>
TILE_GET_INFO_MEMBER(argus_common_state::get_tx_tile_info)127 TILE_GET_INFO_MEMBER(argus_common_state::get_tx_tile_info)
128 {
129 tile_index <<= 1;
130
131 u8 lo = m_txram[tile_index];
132 u8 hi = m_txram[tile_index + 1];
133
134 tileinfo.set(Gfx,
135 ((hi & 0xc0) << 2) | lo,
136 hi & 0x0f,
137 TILE_FLIPYX((hi & 0x30) >> 4));
138 }
139
TILE_GET_INFO_MEMBER(argus_state::get_bg0_tile_info)140 TILE_GET_INFO_MEMBER(argus_state::get_bg0_tile_info)
141 {
142 // logical width is 65536(4096*16) but we load only 1024 pixel each
143 // for reduce RAM usage
144 tile_index = (((m_vrom_offset << 9) + tile_index) & 0x1ffff) << 1;
145 int vrom_offset = (tile_index >> 3);
146 tile_index = (m_vrom[0][vrom_offset & ~1] << 4) | ((m_vrom[0][vrom_offset | 1] & 0x7) << 12) | (tile_index & 0xf);
147
148 u8 lo = m_vrom[1][tile_index];
149 u8 hi = m_vrom[1][tile_index | 1];
150
151 tileinfo.set(1,
152 ((hi & 0xc0) << 2) | lo,
153 hi & 0x0f,
154 TILE_FLIPYX((hi & 0x30) >> 4));
155 }
156
TILE_GET_INFO_MEMBER(argus_state::get_bg1_tile_info)157 TILE_GET_INFO_MEMBER(argus_state::get_bg1_tile_info)
158 {
159 tile_index <<= 1;
160
161 u8 lo = m_bg1ram[tile_index];
162 u8 hi = m_bg1ram[tile_index + 1];
163
164 tileinfo.set(2,
165 lo,
166 hi & 0x0f,
167 TILE_FLIPYX((hi & 0x30) >> 4));
168 }
169
TILE_GET_INFO_MEMBER(valtric_state::get_bg_tile_info)170 TILE_GET_INFO_MEMBER(valtric_state::get_bg_tile_info)
171 {
172 tile_index <<= 1;
173
174 u8 lo = m_bg1ram[tile_index];
175 u8 hi = m_bg1ram[tile_index + 1];
176
177 tileinfo.set(1,
178 ((hi & 0xc0) << 2) | ((hi & 0x20) << 5) | lo,
179 hi & 0x0f,
180 0);
181 }
182
TILE_GET_INFO_MEMBER(butasan_state::get_tx_tile_info)183 TILE_GET_INFO_MEMBER(butasan_state::get_tx_tile_info)
184 {
185 tile_index <<= 1;
186
187 u8 lo = m_butasan_txram[tile_index];
188 u8 hi = m_butasan_txram[tile_index + 1];
189
190 tileinfo.set(3,
191 ((hi & 0xc0) << 2) | lo,
192 hi & 0x0f,
193 TILE_FLIPYX((hi & 0x30) >> 4));
194 }
195
TILE_GET_INFO_MEMBER(butasan_state::get_bg0_tile_info)196 TILE_GET_INFO_MEMBER(butasan_state::get_bg0_tile_info)
197 {
198 tile_index <<= 1;
199
200 u8 lo = m_butasan_bg0ram[tile_index];
201 u8 hi = m_butasan_bg0ram[tile_index + 1];
202
203 tileinfo.set(1,
204 ((hi & 0xc0) << 2) | lo,
205 hi & 0x0f,
206 TILE_FLIPYX((hi & 0x30) >> 4));
207 }
208
TILE_GET_INFO_MEMBER(butasan_state::get_bg1_tile_info)209 TILE_GET_INFO_MEMBER(butasan_state::get_bg1_tile_info)
210 {
211 int const tile = m_butasan_bg1ram[tile_index] | ((m_butasan_bg1_status & 2) << 7);
212
213 tileinfo.set(2,
214 tile,
215 (tile & 0x80) >> 7,
216 0);
217 }
218
TILEMAP_MAPPER_MEMBER(butasan_state::bg_scan)219 TILEMAP_MAPPER_MEMBER(butasan_state::bg_scan)
220 {
221 /* logical (col,row) -> memory offset */
222 return (col & 0x0f) | ((row ^ 0x0f) << 4) | ((col & 0x10) << 5);
223 }
224
TILEMAP_MAPPER_MEMBER(butasan_state::tx_scan)225 TILEMAP_MAPPER_MEMBER(butasan_state::tx_scan)
226 {
227 /* logical (col,row) -> memory offset */
228 return (col & 0x1f) | ((row ^ 0x1f) << 5);
229 }
230
231 /***************************************************************************
232 Initialize and destroy video hardware emulation
233 ***************************************************************************/
234
reset_common()235 void argus_common_state::reset_common()
236 {
237 m_bg_status = 0x01;
238 m_flipscreen = 0;
239 m_palette_intensity = 0;
240 }
241
video_start()242 void argus_state::video_start()
243 {
244 /* info offset w h col row */
245 // m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(argus_state::get_bg0_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 4096, 32); // full 65536 width tilemap
246 m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(argus_state::get_bg0_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 1024/16, 32);
247 m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(argus_state::get_bg1_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
248 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(argus_state::get_tx_tile_info<3>)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
249
250 m_bg_tilemap[1]->set_transparent_pen(15);
251 m_tx_tilemap->set_transparent_pen(15);
252
253 save_item(NAME(m_bg_status));
254 save_item(NAME(m_flipscreen));
255 save_item(NAME(m_palette_intensity));
256 }
257
video_reset()258 void argus_state::video_reset()
259 {
260 m_bg_scrollx[0][0] = 0;
261 m_bg_scrollx[0][1] = 0;
262 reset_common();
263 }
264
video_start()265 void valtric_state::video_start()
266 {
267 /* info offset w h col row */
268 m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(valtric_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
269 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(valtric_state::get_tx_tile_info<2>)), TILEMAP_SCAN_COLS, 8, 8, 32, 32);
270
271 m_tx_tilemap->set_transparent_pen(15);
272
273 m_screen->register_screen_bitmap(m_mosaicbitmap);
274
275 save_item(NAME(m_bg_status));
276 save_item(NAME(m_flipscreen));
277 save_item(NAME(m_palette_intensity));
278 save_item(NAME(m_valtric_mosaic));
279 save_item(NAME(m_valtric_unknown));
280 save_item(NAME(m_mosaic));
281 }
282
video_reset()283 void valtric_state::video_reset()
284 {
285 m_valtric_mosaic = 0x0f;
286 reset_common();
287 }
288
video_start()289 void butasan_state::video_start()
290 {
291 /* info offset w h col row */
292 m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(butasan_state::get_bg0_tile_info)), tilemap_mapper_delegate(*this, FUNC(butasan_state::bg_scan)), 16, 16, 32, 32);
293 m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(butasan_state::get_bg1_tile_info)), tilemap_mapper_delegate(*this, FUNC(butasan_state::bg_scan)), 16, 16, 32, 32);
294 m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(butasan_state::get_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(butasan_state::tx_scan)), 8, 8, 32, 32);
295
296 m_bg_tilemap[1]->set_transparent_pen(15);
297 m_tx_tilemap->set_transparent_pen(15);
298
299 m_butasan_pagedram[0] = std::make_unique<u8[]>(0x1000);
300 m_butasan_pagedram[1] = std::make_unique<u8[]>(0x1000);
301
302 m_butasan_bg0ram = &m_butasan_pagedram[0][0x000];
303 m_butasan_bg0backram = &m_butasan_pagedram[0][0x800];
304 m_butasan_txram = &m_butasan_pagedram[1][0x000];
305 m_butasan_txbackram = &m_butasan_pagedram[1][0x800];
306
307 save_item(NAME(m_bg_status));
308 save_item(NAME(m_flipscreen));
309 save_item(NAME(m_palette_intensity));
310 save_pointer(NAME(m_butasan_pagedram[0]), 0x1000);
311 save_pointer(NAME(m_butasan_pagedram[1]), 0x1000);
312 save_item(NAME(m_butasan_page_latch));
313 save_item(NAME(m_butasan_bg1_status));
314 save_item(NAME(m_butasan_unknown));
315 }
316
video_reset()317 void butasan_state::video_reset()
318 {
319 m_butasan_page_latch = 0;
320 m_butasan_bg1_status = 0x01;
321 memset(m_butasan_pagedram[0].get(), 0, 0x1000);
322 memset(m_butasan_pagedram[1].get(), 0, 0x1000);
323 reset_common();
324 }
325
326
327 /***************************************************************************
328 Functions for handler of MAP roms in Argus and palette color
329 ***************************************************************************/
330
change_palette(int color,int lo_offs,int hi_offs)331 void argus_common_state::change_palette(int color, int lo_offs, int hi_offs)
332 {
333 u8 lo = m_paletteram[lo_offs];
334 u8 hi = m_paletteram[hi_offs];
335 m_palette->set_pen_color(color, rgb_t(hi & 0x0f, pal4bit(lo >> 4), pal4bit(lo), pal4bit(hi >> 4)));
336 }
337
change_bg_palette(int color,int lo_offs,int hi_offs)338 void argus_common_state::change_bg_palette(int color, int lo_offs, int hi_offs)
339 {
340 u8 r,g,b,lo,hi,ir,ig,ib,ix;
341 rgb_t rgb,irgb;
342
343 /* red,green,blue intensities */
344 ir = pal4bit(m_palette_intensity >> 12);
345 ig = pal4bit(m_palette_intensity >> 8);
346 ib = pal4bit(m_palette_intensity >> 4);
347 ix = m_palette_intensity & 0x0f;
348
349 irgb = rgb_t(ir,ig,ib);
350
351 lo = m_paletteram[lo_offs];
352 hi = m_paletteram[hi_offs];
353
354 /* red,green,blue component */
355 r = pal4bit(lo >> 4);
356 g = pal4bit(lo);
357 b = pal4bit(hi >> 4);
358
359 /* Grey background enable */
360 if (m_bg_status & 2)
361 {
362 u8 val = (r + g + b) / 3;
363 rgb = rgb_t(val,val,val);
364 }
365 else
366 {
367 rgb = rgb_t(r,g,b);
368 }
369
370 rgb = m_blend->func(rgb,irgb,ix);
371
372 m_palette->set_pen_color(color,rgb);
373 }
374
375
376 /***************************************************************************
377 Memory handler
378 ***************************************************************************/
379
mosaic_w(u8 data)380 void valtric_state::mosaic_w(u8 data)
381 {
382 m_valtric_mosaic = data;
383 }
384
txram_w(offs_t offset,u8 data)385 void argus_common_state::txram_w(offs_t offset, u8 data)
386 {
387 m_txram[offset] = data;
388 m_tx_tilemap->mark_tile_dirty(offset >> 1);
389 }
390
bg1ram_w(offs_t offset,u8 data)391 void argus_common_state::bg1ram_w(offs_t offset, u8 data)
392 {
393 m_bg1ram[offset] = data;
394 m_bg_tilemap[1]->mark_tile_dirty(offset >> 1);
395 }
396
bg_status_w(u8 data)397 void argus_state::bg_status_w(u8 data)
398 {
399 if (m_bg_status != data)
400 {
401 m_bg_status = data;
402
403 /* Gray / purple scale */
404 if (m_bg_status & 2)
405 {
406 int offs;
407
408 for (offs = 0x400; offs < 0x500; offs++)
409 {
410 change_bg_palette((offs - 0x400) + 0x080, offs, offs + 0x400);
411 }
412 }
413 }
414 }
415
bg_status_w(u8 data)416 void valtric_state::bg_status_w(u8 data)
417 {
418 if (m_bg_status != data)
419 {
420 m_bg_status = data;
421
422 /* Gray / purple scale */
423 if (m_bg_status & 2)
424 {
425 int offs;
426
427 for (offs = 0x400; offs < 0x600; offs += 2)
428 {
429 change_bg_palette(((offs - 0x400) >> 1) + 0x100, offs & ~1, offs | 1);
430 }
431 }
432 }
433 }
434
bg0_status_w(u8 data)435 void butasan_state::bg0_status_w(u8 data)
436 {
437 m_bg_status = data;
438 }
439
bg1_status_w(u8 data)440 void butasan_state::bg1_status_w(u8 data)
441 {
442 if (m_butasan_bg1_status != data)
443 {
444 m_butasan_bg1_status = data;
445
446 /* Bank changed */
447 m_bg_tilemap[1]->mark_all_dirty();
448 }
449 }
450
flipscreen_w(u8 data)451 void argus_common_state::flipscreen_w(u8 data)
452 {
453 m_flipscreen = data & 0x80;
454 }
455
paletteram_w(offs_t offset,u8 data)456 void argus_state::paletteram_w(offs_t offset, u8 data)
457 {
458 int offs;
459
460 m_paletteram[offset] = data;
461
462 if (offset <= 0x0ff) /* sprite color */
463 {
464 offset &= 0x07f;
465
466 change_palette(offset, offset, offset + 0x080);
467
468 if (offset == 0x07f || offset == 0x0ff)
469 {
470 m_palette_intensity = m_paletteram[0x0ff] | (m_paletteram[0x07f] << 8);
471
472 for (offs = 0x400; offs < 0x500; offs++)
473 change_bg_palette((offs & 0xff) + 0x080, offs, offs + 0x400);
474 }
475 }
476 else if ((offset >= 0x400 && offset <= 0x4ff) ||
477 (offset >= 0x800 && offset <= 0x8ff)) /* BG0 color */
478 {
479 offs = offset & 0xff;
480 offset = offs | 0x400;
481
482 change_bg_palette(offs + 0x080, offset, offset + 0x400);
483 }
484 else if ((offset >= 0x500 && offset <= 0x5ff) ||
485 (offset >= 0x900 && offset <= 0x9ff)) /* BG1 color */
486 {
487 offs = offset & 0xff;
488 offset = offs | 0x500;
489
490 change_palette(offs + 0x180, offset, offset + 0x400);
491 }
492 else if ((offset >= 0x700 && offset <= 0x7ff) ||
493 (offset >= 0xb00 && offset <= 0xbff)) /* text color */
494 {
495 offs = offset & 0xff;
496 offset = offs | 0x700;
497
498 change_palette(offs + 0x280, offset, offset + 0x400);
499 }
500 }
501
paletteram_w(offs_t offset,u8 data)502 void valtric_state::paletteram_w(offs_t offset, u8 data)
503 {
504 m_paletteram[offset] = data;
505
506 if (offset <= 0x1ff) /* Sprite color */
507 {
508 change_palette(offset >> 1, offset & ~1, offset | 1);
509
510 if (offset == 0x1fe || offset == 0x1ff)
511 {
512 int offs;
513
514 m_palette_intensity = m_paletteram[0x1ff] | (m_paletteram[0x1fe] << 8);
515
516 for (offs = 0x400; offs < 0x600; offs += 2)
517 change_bg_palette(((offs & 0x1ff) >> 1) + 0x100, offs & ~1, offs | 1);
518 }
519 }
520 else if (offset >= 0x400 && offset <= 0x5ff) /* BG color */
521 {
522 change_bg_palette(((offset & 0x1ff) >> 1) + 0x100, offset & ~1, offset | 1);
523 }
524 else if (offset >= 0x600 && offset <= 0x7ff) /* Text color */
525 {
526 change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
527 }
528 }
529
paletteram_w(offs_t offset,u8 data)530 void butasan_state::paletteram_w(offs_t offset, u8 data)
531 {
532 m_paletteram[offset] = data;
533
534 if (offset <= 0x1ff) /* BG0 color */
535 {
536 change_palette((offset >> 1) + 0x100, offset & ~1, offset | 1);
537 }
538 else if (offset <= 0x23f) /* BG1 color */
539 {
540 change_palette(((offset & 0x3f) >> 1) + 0x0c0, offset & ~1, offset | 1);
541 }
542 else if (offset >= 0x400 && offset <= 0x47f) /* Sprite color */
543 { /* 16 colors */
544 change_palette((offset & 0x7f) >> 1, offset & ~1, offset | 1);
545 }
546 else if (offset >= 0x480 && offset <= 0x4ff) /* Sprite color */
547 { /* 8 colors */
548 int offs = (offset & 0x070) | ((offset & 0x00f) >> 1);
549
550 change_palette(offs + 0x040, offset & ~1, offset | 1);
551 change_palette(offs + 0x048, offset & ~1, offset | 1);
552 }
553 else if (offset >= 0x600 && offset <= 0x7ff) /* Text color */
554 {
555 change_palette(((offset & 0x1ff) >> 1) + 0x200, offset & ~1, offset | 1);
556 }
557 else if (offset >= 0x240 && offset <= 0x25f) // dummy
558 change_palette(((offset & 0x1f) >> 1) + 0xe0, offset & ~1, offset | 1);
559 else if (offset >= 0x500 && offset <= 0x51f) // dummy
560 change_palette(((offset & 0x1f) >> 1) + 0xf0, offset & ~1, offset | 1);
561 }
562
bg1ram_w(offs_t offset,u8 data)563 void butasan_state::bg1ram_w(offs_t offset, u8 data)
564 {
565 m_butasan_bg1ram[offset] = data;
566 m_bg_tilemap[1]->mark_tile_dirty(offset);
567 }
568
pageselect_w(u8 data)569 void butasan_state::pageselect_w(u8 data)
570 {
571 m_butasan_page_latch = data & 1;
572 }
573
pagedram_r(offs_t offset)574 u8 butasan_state::pagedram_r(offs_t offset)
575 {
576 if (offset <= 0x07ff)
577 return m_butasan_pagedram[m_butasan_page_latch][offset];
578 else
579 return m_butasan_pagedram[0][offset];
580 }
581
pagedram_w(offs_t offset,u8 data)582 void butasan_state::pagedram_w(offs_t offset, u8 data)
583 {
584 m_butasan_pagedram[m_butasan_page_latch][offset] = data;
585
586 if (!m_butasan_page_latch)
587 {
588 if (offset <= 0x07ff)
589 m_bg_tilemap[0]->mark_tile_dirty(offset >> 1);
590 }
591 else
592 {
593 if (offset <= 0x07ff)
594 m_tx_tilemap->mark_tile_dirty(offset >> 1);
595 }
596 }
597
unknown_w(u8 data)598 void valtric_state::unknown_w(u8 data)
599 {
600 m_valtric_unknown = data;
601 }
602
unknown_w(u8 data)603 void butasan_state::unknown_w(u8 data)
604 {
605 m_butasan_unknown = data;
606 }
607
608
609 /***************************************************************************
610 Screen refresh
611 ***************************************************************************/
612
613 #define bg_scrollx(layer) (m_bg_scrollx[layer][0] | (m_bg_scrollx[layer][1] << 8))
614 #define bg_scrolly(layer) (m_bg_scrolly[layer][0] | (m_bg_scrolly[layer][1] << 8))
615
bg_setting()616 void argus_common_state::bg_setting()
617 {
618 machine().tilemap().set_flip_all(m_flipscreen ? TILEMAP_FLIPY|TILEMAP_FLIPX : 0);
619
620 if (!m_flipscreen)
621 {
622 if (m_bg_tilemap[0] != nullptr)
623 {
624 if ((m_vrom[0] != nullptr) && (m_vrom[1] != nullptr))
625 {
626 if (m_vrom_offset != m_bg_scrollx[0][1])
627 {
628 m_vrom_offset = m_bg_scrollx[0][1];
629 m_bg_tilemap[0]->mark_all_dirty();
630 }
631 m_bg_tilemap[0]->set_scrollx(0, m_bg_scrollx[0][0]);
632 m_bg_tilemap[0]->set_scrolly(0, bg_scrolly(0));
633 }
634 else
635 {
636 m_bg_tilemap[0]->set_scrollx(0, bg_scrollx(0));
637 m_bg_tilemap[0]->set_scrolly(0, bg_scrolly(0));
638 }
639 }
640 m_bg_tilemap[1]->set_scrollx(0, bg_scrollx(1) & 0x1ff);
641 m_bg_tilemap[1]->set_scrolly(0, bg_scrolly(1) & 0x1ff);
642 }
643 else
644 {
645 if (m_bg_tilemap[0] != nullptr)
646 {
647 if ((m_vrom[0] != nullptr) && (m_vrom[1] != nullptr))
648 {
649 if (m_vrom_offset != ((m_bg_scrollx[0][1] + 1) & 0xff))
650 {
651 m_vrom_offset = ((m_bg_scrollx[0][1] + 1) & 0xff);
652 m_bg_tilemap[0]->mark_all_dirty();
653 }
654 m_bg_tilemap[0]->set_scrollx(0, m_bg_scrollx[0][0]);
655 m_bg_tilemap[0]->set_scrolly(0, (bg_scrolly(0) + 256));
656 }
657 else
658 {
659 m_bg_tilemap[0]->set_scrollx(0, (bg_scrollx(0) + 256));
660 m_bg_tilemap[0]->set_scrolly(0, (bg_scrolly(0) + 256));
661 }
662 }
663 m_bg_tilemap[1]->set_scrollx(0, (bg_scrollx(1) + 256) & 0x1ff);
664 m_bg_tilemap[1]->set_scrolly(0, (bg_scrolly(1) + 256) & 0x1ff);
665 }
666 }
667
draw_sprites(bitmap_rgb32 & bitmap,const rectangle & cliprect,int priority)668 void argus_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect, int priority)
669 {
670 /* Draw the sprites */
671 for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
672 {
673 if (!(m_spriteram[offs+15] == 0 && m_spriteram[offs+11] == 0xf0))
674 {
675 int sx, sy, tile, flipx, flipy, color, pri;
676
677 sx = m_spriteram[offs+12]; if (m_spriteram[offs+13] & 0x01) sx -= 256;
678 sy = m_spriteram[offs+11]; if (!(m_spriteram[offs+13] & 0x02)) sy -= 256;
679
680 tile = m_spriteram[offs+14] | ((m_spriteram[offs+13] & 0xc0) << 2);
681 flipx = m_spriteram[offs+13] & 0x10;
682 flipy = m_spriteram[offs+13] & 0x20;
683 color = m_spriteram[offs+15] & 0x07;
684 pri = (m_spriteram[offs+15] & 0x08) >> 3;
685
686 if (m_flipscreen)
687 {
688 sx = 240 - sx;
689 sy = 240 - sy;
690 flipx = !flipx;
691 flipy = !flipy;
692 }
693
694 if (priority != pri)
695 m_blend->drawgfx(
696 *m_palette,
697 bitmap,cliprect,m_gfxdecode->gfx(0),
698 tile,
699 color,
700 flipx, flipy,
701 sx, sy,
702 15);
703 }
704 }
705 }
706
707 #if 1
draw_mosaic(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)708 void valtric_state::draw_mosaic(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
709 {
710 if (m_valtric_mosaic!=0x80)
711 {
712 m_mosaic=0x0f-(m_valtric_mosaic&0x0f);
713 if (m_mosaic!=0) m_mosaic++;
714 if (m_valtric_mosaic&0x80) m_mosaic*=-1;
715 }
716
717 if (m_mosaic==0)
718 m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
719 else
720 {
721 m_bg_tilemap[1]->draw(screen, m_mosaicbitmap, cliprect, 0, 0);
722 int step=m_mosaic;
723 int c=0;
724 int width = screen.width();
725 int height = screen.height();
726
727 if (m_mosaic<0)step*=-1;
728
729 for (int y=0;y<width+step;y+=step)
730 for (int x=0;x<height+step;x+=step)
731 {
732 if (y < height && x < width)
733 c=m_mosaicbitmap.pix(y, x);
734
735 if (m_mosaic<0)
736 if (y+step-1<height && x+step-1< width)
737 c = m_mosaicbitmap.pix(y+step-1, x+step-1);
738
739 for (int yy=0;yy<step;yy++)
740 for (int xx=0;xx<step;xx++)
741 {
742 if (xx+x < width && yy+y<height)
743 bitmap.pix(y+yy, x+xx) = c;
744 }
745 }
746 }
747 }
748 #else
draw_mosaic(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)749 void valtric_state::draw_mosaic(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
750 {
751 int step = 0x10 - (m_valtric_mosaic & 0x0f);
752
753 if (step == 1)
754 m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
755 else
756 {
757 m_bg_tilemap[1]->draw(screen, m_mosaicbitmap, cliprect, 0, 0);
758 int c=0;
759 int width = screen.width();
760 int height = screen.height();
761
762 for (int y = 0; y < width+step; y += step)
763 for (int x = 0; x < height+step; x += step)
764 {
765 if (y < height && x < width)
766 c = m_mosaicbitmap.pix(y, x);
767
768 if (m_valtric_mosaic & 0x80)
769 if (y+step-1 < height && x+step-1 < width)
770 c = m_mosaicbitmap.pix(y+step-1, x+step-1);
771
772 for (int yy = 0; yy < step; yy++)
773 for (int xx = 0; xx < step; xx++)
774 {
775 if (xx+x < width && yy+y < height)
776 bitmap.pix(y+yy, x+xx) = c;
777 }
778 }
779 }
780 }
781 #endif
782
draw_sprites(bitmap_rgb32 & bitmap,const rectangle & cliprect)783 void valtric_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
784 {
785 /* Draw the sprites */
786 for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
787 {
788 if (!(m_spriteram[offs+15] == 0 && m_spriteram[offs+11] == 0xf0))
789 {
790 int sx, sy, tile, flipx, flipy, color;
791
792 sx = m_spriteram[offs+12]; if (m_spriteram[offs+13] & 0x01) sx -= 256;
793 sy = m_spriteram[offs+11]; if (!(m_spriteram[offs+13] & 0x02)) sy -= 256;
794
795 tile = m_spriteram[offs+14] | ((m_spriteram[offs+13] & 0xc0) << 2);
796 flipx = m_spriteram[offs+13] & 0x10;
797 flipy = m_spriteram[offs+13] & 0x20;
798 color = m_spriteram[offs+15] & 0x0f;
799
800 if (m_flipscreen)
801 {
802 sx = 240 - sx;
803 sy = 240 - sy;
804 flipx = !flipx;
805 flipy = !flipy;
806 }
807
808 m_blend->drawgfx(*m_palette,
809 bitmap,cliprect,m_gfxdecode->gfx(0),
810 tile,
811 color,
812 flipx, flipy,
813 sx, sy,
814 15);
815 }
816 }
817 }
818
draw_sprites(bitmap_rgb32 & bitmap,const rectangle & cliprect)819 void butasan_state::draw_sprites(bitmap_rgb32 &bitmap, const rectangle &cliprect)
820 {
821 /* Draw the sprites */
822 for (int offs = 0; offs < m_spriteram.bytes(); offs += 16)
823 {
824 int sx, sy, tile, flipx, flipy, color;
825 int fx, fy;
826
827 tile = m_spriteram[offs+14] | ((m_spriteram[offs+15] & 0x0f) << 8);
828 flipx = m_spriteram[offs+8] & 0x01;
829 flipy = m_spriteram[offs+8] & 0x04;
830 color = m_spriteram[offs+9] & 0x0f;
831
832 sx = m_spriteram[offs+10];
833 sy = m_spriteram[offs+12];
834
835 if (m_spriteram[offs+11] & 0x01) sx-=256;
836 if (m_spriteram[offs+13] & 0x01) sy-=256;
837
838 sy = 240 - sy;
839
840 if (m_flipscreen)
841 {
842 sx = 240 - sx;
843 sy = 240 - sy;
844 flipx = !flipx;
845 flipy = !flipy;
846 }
847
848 fx = flipx;
849 fy = flipy;
850
851 {
852 int i, j, td;
853
854 if ((offs >= 0x100 && offs <= 0x2ff) || (offs >= 0x400 && offs <= 0x57f))
855 {
856 m_blend->drawgfx(*m_palette,
857 bitmap,cliprect,m_gfxdecode->gfx(0),
858 tile,
859 color,
860 flipx, flipy,
861 sx, sy,
862 7);
863 }
864 else if ((offs >= 0x000 && offs <= 0x0ff) || (offs >= 0x300 && offs <= 0x3ff))
865 {
866 for (i = 0; i <= 1; i++)
867 {
868 td = (fx) ? (1 - i) : i;
869
870 m_blend->drawgfx(*m_palette,
871 bitmap,cliprect,m_gfxdecode->gfx(0),
872 tile + td,
873 color,
874 flipx, flipy,
875 sx + i * 16, sy,
876 7);
877 }
878 }
879 else if (offs >= 0x580 && offs <= 0x61f)
880 {
881 for (i = 0; i <= 1; i++)
882 {
883 for (j = 0; j <= 1; j++)
884 {
885 if (fy)
886 td = (fx) ? ((1 - i) * 2) + 1 - j : (1 - i) * 2 + j;
887 else
888 td = (fx) ? (i * 2) + 1 - j : i * 2 + j;
889
890 m_blend->drawgfx(*m_palette,
891 bitmap,cliprect,m_gfxdecode->gfx(0),
892 tile + td,
893 color,
894 flipx, flipy,
895 sx + j * 16, sy - i * 16,
896 7);
897 }
898 }
899 }
900 else if (offs >= 0x620 && offs <= 0x67f)
901 {
902 for (i = 0; i <= 3; i++)
903 {
904 for (j = 0; j <= 3; j++)
905 {
906 if (fy)
907 td = (fx) ? ((3 - i) * 4) + 3 - j : (3 - i) * 4 + j;
908 else
909 td = (fx) ? (i * 4) + 3 - j : i * 4 + j;
910
911 m_blend->drawgfx(*m_palette,
912 bitmap,cliprect,m_gfxdecode->gfx(0),
913 tile + td,
914 color,
915 flipx, flipy,
916 sx + j * 16, sy - i * 16,
917 7);
918 }
919 }
920 }
921 }
922 }
923 }
924
925
log_vram()926 void butasan_state::log_vram()
927 {
928 #ifdef MAME_DEBUG
929 int offs;
930
931 if (machine().input().code_pressed(KEYCODE_M))
932 {
933 u8 *spriteram = &m_spriteram[0];
934 int i;
935 logerror("\nSprite RAM\n");
936 logerror("---------------------------------------\n");
937 logerror(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
938 for (offs = 0; offs < m_spriteram.bytes(); offs += 16)
939 {
940 for (i = 0; i < 16; i++)
941 {
942 if (i == 0)
943 {
944 logerror("%04x : ", offs + 0xf000);
945 logerror("%02x ", spriteram[offs]);
946 }
947 else if (i == 7)
948 logerror("%02x ", spriteram[offs + 7]);
949 else if (i == 15)
950 logerror("%02x\n", spriteram[offs + 15]);
951 else
952 logerror("%02x ", spriteram[offs + i]);
953 }
954 }
955 logerror("\nColor RAM\n");
956 logerror("---------------------------------------\n");
957 logerror(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f\n");
958 for (offs = 0; offs < 0xbf0; offs += 16)
959 {
960 for (i = 0; i < 16; i++)
961 {
962 if (i == 0)
963 {
964 logerror("%04x : ", offs + 0xc400);
965 logerror("%02x ", m_paletteram[offs]);
966 }
967 else if (i == 7)
968 logerror("%02x ", m_paletteram[offs + 7]);
969 else if (i == 15)
970 logerror("%02x\n", m_paletteram[offs + 15]);
971 else
972 logerror("%02x ", m_paletteram[offs + i]);
973 }
974 }
975 }
976 #endif
977 }
978
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)979 u32 argus_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
980 {
981 bg_setting();
982
983 m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
984 draw_sprites(bitmap, cliprect, 0);
985 if (m_bg_status & 1) /* Background enable */
986 m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
987 draw_sprites(bitmap, cliprect, 1);
988 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
989 return 0;
990 }
991
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)992 u32 valtric_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
993 {
994 bg_setting();
995
996 if (m_bg_status & 1) /* Background enable */
997 draw_mosaic(screen, bitmap, cliprect);
998 else
999 bitmap.fill(m_palette->black_pen(), cliprect);
1000 draw_sprites(bitmap, cliprect);
1001 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
1002 return 0;
1003 }
1004
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)1005 u32 butasan_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
1006 {
1007 bg_setting();
1008
1009 if (m_bg_status & 1) /* Background enable */
1010 m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
1011 else
1012 bitmap.fill(m_palette->black_pen(), cliprect);
1013 if (m_butasan_bg1_status & 1) m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
1014 draw_sprites(bitmap, cliprect);
1015 m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
1016
1017 log_vram();
1018 return 0;
1019 }
1020