1
/***************************************************************************
3
Sega 16-bit common hardware
5
****************************************************************************
9
Control Board (834-5668):
10
315-5011 -- sprite line comparitor
11
315-5012 -- sprite generator control
12
315-5049 (x2) -- tilemaps
13
315-5107 (PAL x2) -- horizontal timing control
14
315-5108 -- vertical timing control
15
315-5122 (PAL) -- timing
25
Video Side (171-5320):
26
315-5049 (x2) -- tilemaps
27
315-5011 -- sprite line comparitor
28
315-5012 -- sprite generator control
39
Main Board (171-5335):
40
315-5011 -- sprite line comparitor
41
315-5012 -- sprite generator control
42
315-5049 (x2) -- tilemaps
43
315-5107 (PAL) -- display timing
44
315-5108 (PAL) -- display timing
45
315-5141 (PAL) -- Z80 address decoding
46
315-5143 (PAL) -- sprite-related?
47
315-5144 (PAL) -- sprite-related?
48
315-5147 (PAL) -- unknown, DTACK-related
49
315-5149 (PAL) -- video mixing
50
315-5193 (PAL) -- 68000/MCU interface & address decoding
51
315-5202 (PAL) -- 68000/MCU interface & address decoding
55
Bottom Board (171-5307):
56
315-5011 -- sprite line comparitor
57
315-5012 -- sprite generator control
58
315-5049 (x2) -- tilemaps
59
315-5107 (PAL) -- display timing
60
315-5108 (PAL) -- display timing
61
315-5143 (PAL) -- sprite-related?
62
315-5144 (PAL) -- sprite-related?
66
315-5141 (PAL) -- Z80 address decoding
68
315-5149 (PAL) -- video mixing
73
Main Board (171-5357):
74
315-5195 -- memory mapper
75
315-5196 -- sprite generator
76
315-5197 -- tilemap generator
77
315-5213 (PAL) -- sprite-related
78
315-5214 (PAL) -- unknown
87
315-5248 -- hardware multiplier
88
315-5250 -- compare/timer
93
Main Board (171-5873B):
94
315-5242 -- color encoder
97
315-5360 -- memory mapper?
98
315-5361 -- sprite generator
99
315-5362 -- tilemap generator
100
315-5373 (PAL) -- video mixing
101
315-5374 (PAL) -- sprite timing
102
315-5375 (PAL) -- system timing
103
315-5389 (PAL) -- VDP sync
105
315-5391 (PAL) -- Z80 address decoding
107
Main Board (171-5873-02B):
108
315-5242 -- color encoder
111
315-5360 -- memory mapper?
112
315-5361 -- sprite generator
113
315-5362 -- tilemap generator
114
315-5374 (PAL) -- sprite timing
115
315-5375 (PAL) -- system timing
116
315-5389 (PAL) -- VDP sync
117
315-5391 (PAL) -- Z80 address decoding
118
315-5430 (PAL) -- video mixing
120
ROM Board (171-5987A):
121
315-5436 -- tile/sprite banking
126
315-5242 -- color encoder
135
CPU Board 171-5376-01:
136
315-5195 -- memory mapper
137
315-5218 -- PCM sound controller
138
315-5155 (PAL x2) -- road bit extraction
139
315-5222 (PAL) -- road mixing
145
VIDEO Board: (not the same as out run !) 171-5480
146
315-5196 -- sprite generator
147
315-5197 -- tilemap generator
148
315-5213 (PAL) -- sprite-related
149
315-5242 -- color encoder
154
CPU Board 837-6063-01:
155
315-5195 -- memory mapper
156
315-5218 -- PCM sound controller
157
315-5155 (PAL x2) -- road bit extraction
158
315-5222 (PAL) -- road mixing
164
VIDEO Board: 837-6064, 171-5377-01
165
315-5197 -- tilemap generator
166
315-5211 -- sprite generator
169
315-5242 -- color encoder
173
Main Board (317-5964):
174
315-5242 -- color encoder
177
315-5386 -- tilemap generator
178
315-5387 -- sprite generator
179
315-5388 -- video mixing
186
315-5197 -- tilemap generator
187
315-5211A -- sprite generator
188
315-5218 -- PCM sound controller
189
315-5242 -- color encoder
190
315-5248 (x2) -- hardware multiplier
191
315-5249 (x2) -- hardware divider
192
315-5250 (x2) -- compare/timer
193
315-5275 -- road generator
194
315-5278 (PAL) -- sprite ROM bank control
195
315-5279 (PAL) -- video mixing (Afterburner)
196
315-5280 (PAL) -- Z80 address decoding
197
315-5290 (PAL) -- main CPU address decoding
198
315-5291 (PAL) -- main CPU address decoding
199
315-5304 (PAL) -- video mixing (Line of Fire)
203
Main Board (837-6565):
204
315-5218 -- PCM sound controller
205
315-5248 (x3) -- hardware multiplier
206
315-5249 (x3) -- hardware divider
207
315-5280 (PAL) -- Z80 address decoding
216
Video Board (837-6566):
217
315-5196 -- sprite generator
218
315-5213 (PAL) -- sprite-related
219
315-5242 -- color encoder
220
315-5305 -- sprite generator
221
315-5306 (x2) -- video sync and rotation
222
315-5312 -- video mixing
229
SYS1 SYS2 HANG ENDU PR16 S16A S16B SY18 SHNG ORUN XBRD YBRD SYSC SY24 SY32
230
315-5011: xx xx xx xx xx xx -- sprite line comparitor
231
315-5012: xx xx xx xx xx xx -- sprite generator control
232
315-5049: xx x2 x2 x2 x2 -- tilemap generator
233
315-5195: xx xx xx -- memory mapper
234
315-5196: xx xx xx -- sprite genereator
235
315-5197: xx xx xx xx -- tilemap generator
236
315-5211: xx -- sprite generator
237
315-5211A: xx -- sprite generator
238
315-5218: xx xx xx xx -- PCM sound controller
239
315-5242: xx xx xx xx xx xx xx xx -- color encoder
240
315-5248: xx x2 x3 -- hardware multiplier
241
315-5249: x2 x3 -- hardware divider
242
315-5250: xx x2 -- compare/timer
243
315-5275: xx -- road generator
244
315-5296: xx xx xx xx -- I/O chip
246
315-5312: xx -- video mixing
247
315-5313: xx xx -- VDP
248
315-5360: xx -- memory mapper
249
315-5361: xx -- sprite generator
250
315-5362: xx -- tilemap generator
252
315-5386: xx -- tilemap generator
253
315-5387: xx -- sprite generator
254
315-5388: xx -- video mixing
255
315-5436: xx -- sprite/tile banking
258
****************************************************************************
260
Sega system16 and friends hardware
262
CPU Tiles Sprites Priority Color SCPU Sound Other
263
System C 68000 315-5313 315-5242 z80 ym3438 315-5296(IO)
264
Space Harrier 68000x2 (c) z80 ym2203 pcm(b)
265
System 16B 68000 315-5197 315-5196 GAL (c) z80 ym2151 upd7759 315-5195
266
After Burner 68000x2 315-5197 315-5211A GAL 315-5242 z80 ym2151 315-5218 315-5250(a) 315-5248(x2) 315-5249(x2) 315-5275(road)
267
System 18 68000 315-536x 315-536x 315-5242 z80 ym3834(x2) RF5c68(d) 315-3296(IO) 315-5313(vdp)
268
System 24 68000x2 315-5292 315-5293 315-5294 315-5242 ym2151 dac 315-5195(x3) 315-5296(IO)
269
Galaxy Force 68000x3 315-5296+ 315-5312 315-5242 z80 ym2151 315-5218 315-5296(IO)
270
System 32 V60 315-5386A 315-5387 315-5388 315-5242 z80 ym3834(x2) RF5c68(d) 315-5296(IO)
272
a) 315-5250: 68000 glue and address decoding
274
b) 8x8-bit voices entirely in TTL. The 315-5218 is believed to be the
275
integrated version of that
277
c) Resistor network and latches believed to be equivalent to the 315-5242
279
d) Also seen as 315-5476A and ASSP 5c105 and ASSP 5c68a
281
Quick review of the system16 hardware:
284
The first one. Two tilemap planes, one sprite plane, one road
285
plane. The shadow capability doesn't seem to be used, the
286
highlight/shadow switch in the 5242-equivalent is global for all
289
Space harrier hardware:
290
Similar to hang-on, with per-color highlight/shadow selection, and
291
the shadows are used.
293
System16a / Pre-system16:
294
Space harrier without the road generator.
297
4-layer tilemap hardware in two pairs, with selection between each
298
members on the pairs on a 8-lines basis. Slightly better sprites.
301
System 16b plus a genesis vdp.
304
System 16b tilemaps, frame buffered sprites with better zooming
305
capabilities, and a road generator able to handle two roads
309
Outrun lite, with System 16b sprites instead of the frame buffered
310
sprites, and only one of the two roads is actually used.
313
Outrun with a better fillrate and an even more flexible road
317
New design, with two sprite planes and no tilemaps. The back
318
sprite plane has a huge fillrate and the capability to have its
319
frame buffer completely rotated. Also, it has a palette
320
indirection capability to allows for easier palette rotations.
321
The front sprite plane is System 16b.
324
The odd one out. Medium resolution. Entirely ram-based, no
325
graphics roms. 4-layer tilemap hardware in two pairs, selection
326
on a 8-pixels basis. Tile-based sprites(!) organised as a linked
327
list. The tilemap chip has been reused for model1 and model2,
328
probably because they had it handy and it handles medium res.
331
5-layer tilemap hardware consisting of 4 independant rom-based
332
layers with linescroll, lineselection, linezoom and window
333
clipping capability and one simpler ram-based text plane. Mixed
334
ram/rom sprite engine with palette indirection, per-color priority
335
(thankfully not actually used). The sprite list includes jumping
336
and clipping capabilities, and advanced hot-spot positioning. The
337
mixer chip adds totally dynamic priorities, alpha-blending of the
338
tilemaps, per-component color control, and some other funnies we
339
have not been able to decypher.
341
ST-V (also know as Titan or the Saturn console):
342
The ultimate 2D system. Even more advanced tilemaps, with 6-dof
343
roz support, alpha up to the wazoo and other niceties, known as
344
the vdp2. Ths sprite engine, vdp1, allows for any 4-point
345
streching of the sprites, actually giving polygonal 3D
346
capabilities. Interestingly, the mixer capabilities took a hit,
347
with no real per-sprite mixer priority, which could be considered
348
annoying for a 2D system. It still allowed some beauties like
351
***************************************************************************/
354
#include "segaic16.h"
355
#include "video/resnet.h"
359
/*************************************
363
*************************************/
365
#define PRINT_UNUSUAL_MODES (0)
372
/*************************************
376
*************************************/
378
UINT8 segaic16_display_enable;
379
UINT16 *segaic16_tileram_0;
380
UINT16 *segaic16_textram_0;
381
UINT16 *segaic16_roadram_0;
382
UINT16 *segaic16_rotateram_0;
383
UINT16 *segaic16_paletteram;
387
/*************************************
391
*************************************/
393
struct palette_info palette;
394
struct rotate_info rotate[SEGAIC16_MAX_ROTATE];
395
struct tilemap_info bg_tilemap[SEGAIC16_MAX_TILEMAPS];
396
struct road_info road[SEGAIC16_MAX_ROADS];
400
/*************************************
404
*************************************/
406
void segaic16_set_display_enable(running_machine *machine, int enable)
408
enable = (enable != 0);
409
if (segaic16_display_enable != enable)
411
video_screen_update_partial(machine->primary_screen, video_screen_get_vpos(machine->primary_screen));
412
segaic16_display_enable = enable;
418
/*************************************
420
* Palette computation
422
*************************************/
425
Color generation details
427
Each color is made up of 5 bits, connected through one or more resistors like so:
435
Another data bit is connected by a tristate buffer to the color output through a
436
470 ohm resistor. The buffer allows the resistor to have no effect (tristate),
437
halve brightness (pull-down) or double brightness (pull-up). The data bit source
438
is bit 15 of each color RAM entry.
441
void segaic16_palette_init(int entries)
443
static const int resistances_normal[6] = { 3900, 2000, 1000, 1000/2, 1000/4, 0 };
444
static const int resistances_sh[6] = { 3900, 2000, 1000, 1000/2, 1000/4, 470 };
445
double weights[2][6];
448
/* compute the number of palette entries */
449
palette.entries = entries;
451
/* compute weight table for regular palette entries */
452
compute_resistor_weights(0, 255, -1.0,
453
6, resistances_normal, weights[0], 0, 0,
455
0, NULL, NULL, 0, 0);
457
/* compute weight table for shadow/hilight palette entries */
458
compute_resistor_weights(0, 255, -1.0,
459
6, resistances_sh, weights[1], 0, 0,
461
0, NULL, NULL, 0, 0);
463
/* compute R, G, B for each weight */
464
for (i = 0; i < 32; i++)
466
int i4 = (i >> 4) & 1;
467
int i3 = (i >> 3) & 1;
468
int i2 = (i >> 2) & 1;
469
int i1 = (i >> 1) & 1;
470
int i0 = (i >> 0) & 1;
472
palette.normal[i] = combine_6_weights(weights[0], i0, i1, i2, i3, i4, 0);
473
palette.shadow[i] = combine_6_weights(weights[1], i0, i1, i2, i3, i4, 0);
474
palette.hilight[i] = combine_6_weights(weights[1], i0, i1, i2, i3, i4, 1);
480
/*************************************
484
*************************************/
486
WRITE16_HANDLER( segaic16_paletteram_w )
491
/* get the new value */
492
newval = segaic16_paletteram[offset];
493
COMBINE_DATA(&newval);
494
segaic16_paletteram[offset] = newval;
497
/* sBGR BBBB GGGG RRRR */
498
/* x000 4321 4321 4321 */
499
r = ((newval >> 12) & 0x01) | ((newval << 1) & 0x1e);
500
g = ((newval >> 13) & 0x01) | ((newval >> 3) & 0x1e);
501
b = ((newval >> 14) & 0x01) | ((newval >> 7) & 0x1e);
504
palette_set_color_rgb(space->machine, offset + 0 * palette.entries, palette.normal[r], palette.normal[g], palette.normal[b]);
505
palette_set_color_rgb(space->machine, offset + 1 * palette.entries, palette.shadow[r], palette.shadow[g], palette.shadow[b]);
506
palette_set_color_rgb(space->machine, offset + 2 * palette.entries, palette.hilight[r], palette.hilight[g], palette.hilight[b]);
511
/*************************************
513
* Draw a split tilemap in up to
516
*************************************/
518
static void segaic16_draw_virtual_tilemap(running_machine *machine, struct tilemap_info *info, bitmap_t *bitmap, const rectangle *cliprect, UINT16 pages, UINT16 xscroll, UINT16 yscroll, UINT32 flags, UINT32 priority)
520
int leftmin = -1, leftmax = -1, rightmin = -1, rightmax = -1;
521
int topmin = -1, topmax = -1, bottommin = -1, bottommax = -1;
525
int width = video_screen_get_width(machine->primary_screen);
526
int height = video_screen_get_height(machine->primary_screen);
528
/* which half/halves of the virtual tilemap do we intersect in the X direction? */
529
if (xscroll < 64*8 - width)
535
else if (xscroll < 64*8)
538
leftmax = 64*8 - xscroll - 1;
539
rightmin = leftmax + 1;
540
rightmax = width - 1;
542
else if (xscroll < 128*8 - width)
545
rightmax = width - 1;
551
rightmax = 128*8 - xscroll - 1;
552
leftmin = rightmax + 1;
556
/* which half/halves of the virtual tilemap do we intersect in the Y direction? */
557
if (yscroll < 32*8 - height)
563
else if (yscroll < 32*8)
566
topmax = 32*8 - yscroll - 1;
567
bottommin = topmax + 1;
568
bottommax = height - 1;
570
else if (yscroll < 64*8 - height)
573
bottommax = height - 1;
579
bottommax = 64*8 - yscroll - 1;
580
topmin = bottommax + 1;
584
/* if the tilemap is flipped, we need to flip our sense within each quadrant */
590
leftmin = width - 1 - leftmax;
591
leftmax = width - 1 - temp;
596
rightmin = width - 1 - rightmax;
597
rightmax = width - 1 - temp;
602
topmin = height - 1 - topmax;
603
topmax = height - 1 - temp;
607
int temp = bottommin;
608
bottommin = height - 1 - bottommax;
609
bottommax = height - 1 - temp;
613
/* draw the upper-left chunk */
614
if (leftmin != -1 && topmin != -1)
616
pageclip.min_x = (leftmin < cliprect->min_x) ? cliprect->min_x : leftmin;
617
pageclip.max_x = (leftmax > cliprect->max_x) ? cliprect->max_x : leftmax;
618
pageclip.min_y = (topmin < cliprect->min_y) ? cliprect->min_y : topmin;
619
pageclip.max_y = (topmax > cliprect->max_y) ? cliprect->max_y : topmax;
620
if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
622
page = (pages >> 0) & 0xf;
623
tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
624
tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
625
tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
629
/* draw the upper-right chunk */
630
if (rightmin != -1 && topmin != -1)
632
pageclip.min_x = (rightmin < cliprect->min_x) ? cliprect->min_x : rightmin;
633
pageclip.max_x = (rightmax > cliprect->max_x) ? cliprect->max_x : rightmax;
634
pageclip.min_y = (topmin < cliprect->min_y) ? cliprect->min_y : topmin;
635
pageclip.max_y = (topmax > cliprect->max_y) ? cliprect->max_y : topmax;
636
if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
638
page = (pages >> 4) & 0xf;
639
tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
640
tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
641
tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
645
/* draw the lower-left chunk */
646
if (leftmin != -1 && bottommin != -1)
648
pageclip.min_x = (leftmin < cliprect->min_x) ? cliprect->min_x : leftmin;
649
pageclip.max_x = (leftmax > cliprect->max_x) ? cliprect->max_x : leftmax;
650
pageclip.min_y = (bottommin < cliprect->min_y) ? cliprect->min_y : bottommin;
651
pageclip.max_y = (bottommax > cliprect->max_y) ? cliprect->max_y : bottommax;
652
if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
654
page = (pages >> 8) & 0xf;
655
tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
656
tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
657
tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
661
/* draw the lower-right chunk */
662
if (rightmin != -1 && bottommin != -1)
664
pageclip.min_x = (rightmin < cliprect->min_x) ? cliprect->min_x : rightmin;
665
pageclip.max_x = (rightmax > cliprect->max_x) ? cliprect->max_x : rightmax;
666
pageclip.min_y = (bottommin < cliprect->min_y) ? cliprect->min_y : bottommin;
667
pageclip.max_y = (bottommax > cliprect->max_y) ? cliprect->max_y : bottommax;
668
if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
670
page = (pages >> 12) & 0xf;
671
tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
672
tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
673
tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
680
/*******************************************************************************************
682
* Hang On/System 16A-style tilemaps
684
* 4 total pages (Hang On)
685
* 8 total pages (System 16A)
686
* Column/rowscroll enabled via external signals
690
* ??------ -------- Unknown
691
* --b----- -------- Tile bank select
692
* ---p---- -------- Tile priority versus sprites
693
* ----cccc ccc----- Tile color palette
694
* ----nnnn nnnnnnnn Tile index
698
* ????---- -------- Unknown
699
* ----p--- -------- Priority
700
* -----ccc -------- Tile color palette
701
* -------- nnnnnnnn Tile index
705
* E8C -aaa-bbb -ccc-ddd Background tilemap page select (screen flipped)
706
* E8E -aaa-bbb -ccc-ddd Foreground tilemap page select (screen flipped)
707
* E9C -aaa-bbb -ccc-ddd Background tilemap page select
708
* E9E -aaa-bbb -ccc-ddd Foreground tilemap page select
709
* F24 -------- vvvvvvvv Foreground tilemap vertical scroll
710
* F26 -------- vvvvvvvv Background tilemap vertical scroll
711
* F30-F7D -------- vvvvvvvv Foreground tilemap per-16-pixel-column vertical scroll (every 2 words)
712
* F32-F7F -------- vvvvvvvv Background tilemap per-16-pixel-column vertical scroll (every 2 words)
713
* F80-FED -------h hhhhhhhh Foreground tilemap per-8-pixel-row horizontal scroll (every 2 words)
714
* F82-FEF -------h hhhhhhhh Background tilemap per-8-pixel-row horizontal scroll (every 2 words)
715
* FF8 -------h hhhhhhhh Foreground tilemap horizontal scroll
716
* FFA -------h hhhhhhhh Background tilemap horizontal scroll
718
*******************************************************************************************/
720
static TILE_GET_INFO( segaic16_tilemap_16a_tile_info )
722
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
723
UINT16 data = info->rambase[tile_index];
724
int code = ((data >> 1) & 0x1000) | (data & 0xfff);
725
int color = (data >> 5) & 0x7f;
727
SET_TILE_INFO(0, code, color, 0);
728
tileinfo->category = (data >> 12) & 1;
732
static TILE_GET_INFO( segaic16_tilemap_16a_text_info )
734
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
735
UINT16 data = info->rambase[tile_index];
736
int color = (data >> 8) & 0x07;
737
int code = data & 0xff;
739
SET_TILE_INFO(0, code, color, 0);
740
tileinfo->category = (data >> 11) & 1;
744
static void segaic16_tilemap_16a_draw_layer(running_machine *machine, struct tilemap_info *info, bitmap_t *bitmap, const rectangle *cliprect, int which, int flags, int priority)
746
UINT16 *textram = info->textram;
748
/* note that the scrolling for these games can only scroll as much as the top-left */
749
/* page; in order to scroll beyond that they swap pages and reset the scroll value */
750
UINT16 xscroll = textram[0xff8/2 + which] & 0x1ff;
751
UINT16 yscroll = textram[0xf24/2 + which] & 0x0ff;
752
UINT16 pages = textram[(info->flip ? 0xe8e/2 : 0xe9e/2) - which];
755
/* pages are swapped along the X direction, and there are only 8 of them */
756
pages = ((pages >> 4) & 0x0707) | ((pages << 4) & 0x7070);
757
if (info->numpages == 4)
760
/* column AND row scroll */
761
if (info->colscroll && info->rowscroll)
763
if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column AND row scroll\n");
765
/* loop over row chunks */
766
for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
768
int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
769
rectangle rowcolclip;
771
/* adjust to clip this row only */
772
rowcolclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
773
rowcolclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
775
/* loop over column chunks */
776
for (x = cliprect->min_x & ~15; x <= cliprect->max_x; x += 16)
778
UINT16 effxscroll, effyscroll;
780
/* adjust to clip this column only */
781
rowcolclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
782
rowcolclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
784
/* get the effective scroll values */
785
effxscroll = textram[0xf80/2 + rowscrollindex * 2 + which] & 0x1ff;
786
effyscroll = textram[0xf30/2 + (x/16) * 2 + which] & 0x0ff;
788
/* adjust the xscroll for flipped screen */
793
effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
794
effyscroll = effyscroll & 0x1ff;
795
segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowcolclip, pages, effxscroll, effyscroll, flags, priority);
799
else if (info->colscroll)
801
if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column scroll\n");
803
/* loop over column chunks */
804
for (x = cliprect->min_x & ~15; x <= cliprect->max_x; x += 16)
806
rectangle colclip = *cliprect;
807
UINT16 effxscroll, effyscroll;
809
/* adjust to clip this row only */
810
colclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
811
colclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
813
/* get the effective scroll values */
814
effxscroll = xscroll;
815
effyscroll = textram[0xf30/2 + (x/16) * 2 + which] & 0x0ff;
817
/* adjust the xscroll for flipped screen */
822
effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
823
effyscroll = effyscroll & 0x1ff;
824
segaic16_draw_virtual_tilemap(machine, info, bitmap, &colclip, pages, effxscroll, effyscroll, flags, priority);
827
else if (info->rowscroll)
829
if (PRINT_UNUSUAL_MODES) mame_printf_debug("Row scroll\n");
831
/* loop over row chunks */
832
for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
834
int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
835
rectangle rowclip = *cliprect;
836
UINT16 effxscroll, effyscroll;
838
/* adjust to clip this row only */
839
rowclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
840
rowclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
842
/* get the effective scroll values */
843
effxscroll = textram[0xf80/2 + rowscrollindex * 2 + which] & 0x1ff;
844
effyscroll = yscroll;
846
/* adjust the xscroll for flipped screen */
851
effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
852
effyscroll = effyscroll & 0x1ff;
853
segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowclip, pages, effxscroll, effyscroll, flags, priority);
858
/* adjust the xscroll for flipped screen */
861
xscroll = (0xc8 - xscroll + info->xoffs) & 0x3ff;
862
yscroll = yscroll & 0x1ff;
863
segaic16_draw_virtual_tilemap(machine, info, bitmap, cliprect, pages, xscroll, yscroll, flags, priority);
869
/*******************************************************************************************
871
* System 16B-style tilemaps
874
* Column/rowscroll enabled via bits in text layer
875
* Alternate tilemap support
879
* p------- -------- Tile priority versus sprites
880
* -??----- -------- Unknown
881
* ---ccccc cc------ Tile color palette
882
* ---nnnnn nnnnnnnn Tile index
886
* p------- -------- Tile priority versus sprites
887
* -???---- -------- Unknown
888
* ----ccc- -------- Tile color palette
889
* -------n nnnnnnnn Tile index
891
* Alternate tile format:
893
* p------- -------- Tile priority versus sprites
894
* -??----- -------- Unknown
895
* ----cccc ccc----- Tile color palette
896
* ---nnnnn nnnnnnnn Tile index
898
* Alternate text format:
900
* p------- -------- Tile priority versus sprites
901
* -???---- -------- Unknown
902
* -----ccc -------- Tile color palette
903
* -------- nnnnnnnn Tile index
907
* E80 aaaabbbb ccccdddd Foreground tilemap page select
908
* E82 aaaabbbb ccccdddd Background tilemap page select
909
* E84 aaaabbbb ccccdddd Alternate foreground tilemap page select
910
* E86 aaaabbbb ccccdddd Alternate background tilemap page select
911
* E90 c------- -------- Foreground tilemap column scroll enable
912
* -------v vvvvvvvv Foreground tilemap vertical scroll
913
* E92 c------- -------- Background tilemap column scroll enable
914
* -------v vvvvvvvv Background tilemap vertical scroll
915
* E94 -------v vvvvvvvv Alternate foreground tilemap vertical scroll
916
* E96 -------v vvvvvvvv Alternate background tilemap vertical scroll
917
* E98 r------- -------- Foreground tilemap row scroll enable
918
* ------hh hhhhhhhh Foreground tilemap horizontal scroll
919
* E9A r------- -------- Background tilemap row scroll enable
920
* ------hh hhhhhhhh Background tilemap horizontal scroll
921
* E9C ------hh hhhhhhhh Alternate foreground tilemap horizontal scroll
922
* E9E ------hh hhhhhhhh Alternate background tilemap horizontal scroll
923
* F16-F3F -------- vvvvvvvv Foreground tilemap per-16-pixel-column vertical scroll
924
* F56-F7F -------- vvvvvvvv Background tilemap per-16-pixel-column vertical scroll
925
* F80-FB7 a------- -------- Foreground tilemap per-8-pixel-row alternate tilemap enable
926
* -------h hhhhhhhh Foreground tilemap per-8-pixel-row horizontal scroll
927
* FC0-FF7 a------- -------- Background tilemap per-8-pixel-row alternate tilemap enable
928
* -------h hhhhhhhh Background tilemap per-8-pixel-row horizontal scroll
930
*******************************************************************************************/
932
static TILE_GET_INFO( segaic16_tilemap_16b_tile_info )
934
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
935
UINT16 data = info->rambase[tile_index];
936
int color = (data >> 6) & 0x7f;
937
int code = data & 0x1fff;
939
code = info->bank[code / info->banksize] * info->banksize + code % info->banksize;
941
SET_TILE_INFO(0, code, color, 0);
942
tileinfo->category = (data >> 15) & 1;
946
static TILE_GET_INFO( segaic16_tilemap_16b_text_info )
948
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
949
UINT16 data = info->rambase[tile_index];
950
int bank = info->bank[0];
951
int color = (data >> 9) & 0x07;
952
int code = data & 0x1ff;
954
SET_TILE_INFO(0, bank * info->banksize + code, color, 0);
955
tileinfo->category = (data >> 15) & 1;
959
static TILE_GET_INFO( segaic16_tilemap_16b_alt_tile_info )
961
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
962
UINT16 data = info->rambase[tile_index];
963
int color = (data >> 5) & 0x7f;
964
int code = data & 0x1fff;
966
code = info->bank[code / info->banksize] * info->banksize + code % info->banksize;
968
SET_TILE_INFO(0, code, color, 0);
969
tileinfo->category = (data >> 15) & 1;
973
static TILE_GET_INFO( segaic16_tilemap_16b_alt_text_info )
975
const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
976
UINT16 data = info->rambase[tile_index];
977
int bank = info->bank[0];
978
int color = (data >> 8) & 0x07;
979
int code = data & 0xff;
981
SET_TILE_INFO(0, bank * info->banksize + code, color, 0);
982
tileinfo->category = (data >> 15) & 1;
986
static void segaic16_tilemap_16b_draw_layer(running_machine *machine, struct tilemap_info *info, bitmap_t *bitmap, const rectangle *cliprect, int which, int flags, int priority)
988
UINT16 *textram = info->textram;
989
UINT16 xscroll, yscroll, pages;
992
/* get global values */
993
xscroll = info->latched_xscroll[which];
994
yscroll = info->latched_yscroll[which];
995
pages = info->latched_pageselect[which];
998
if (yscroll & 0x8000)
1000
if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column AND row scroll\n");
1002
/* loop over row chunks */
1003
for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
1005
int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
1006
rectangle rowcolclip;
1008
/* adjust to clip this row only */
1009
rowcolclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
1010
rowcolclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
1012
/* loop over column chunks */
1013
for (x = ((cliprect->min_x + 8) & ~15) - 8; x <= cliprect->max_x; x += 16)
1015
UINT16 effxscroll, effyscroll, rowscroll;
1016
UINT16 effpages = pages;
1018
/* adjust to clip this column only */
1019
rowcolclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
1020
rowcolclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
1022
/* get the effective scroll values */
1023
rowscroll = textram[0xf80/2 + 0x40/2 * which + rowscrollindex];
1024
effxscroll = (xscroll & 0x8000) ? rowscroll : xscroll;
1025
effyscroll = textram[0xf16/2 + 0x40/2 * which + (x+8)/16];
1027
/* are we using an alternate? */
1028
if (rowscroll & 0x8000)
1030
effxscroll = info->latched_xscroll[which + 2];
1031
effyscroll = info->latched_yscroll[which + 2];
1032
effpages = info->latched_pageselect[which + 2];
1035
/* draw the chunk */
1036
effxscroll = (0xc0 - effxscroll + info->xoffs) & 0x3ff;
1037
effyscroll = effyscroll & 0x1ff;
1038
segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowcolclip, effpages, effxscroll, effyscroll, flags, priority);
1044
if (PRINT_UNUSUAL_MODES) mame_printf_debug("Row scroll\n");
1046
/* loop over row chunks */
1047
for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
1049
int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
1050
rectangle rowclip = *cliprect;
1051
UINT16 effxscroll, effyscroll, rowscroll;
1052
UINT16 effpages = pages;
1054
/* adjust to clip this row only */
1055
rowclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
1056
rowclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
1058
/* get the effective scroll values */
1059
rowscroll = textram[0xf80/2 + 0x40/2 * which + rowscrollindex];
1060
effxscroll = (xscroll & 0x8000) ? rowscroll : xscroll;
1061
effyscroll = yscroll;
1063
/* are we using an alternate? */
1064
if (rowscroll & 0x8000)
1066
effxscroll = info->latched_xscroll[which + 2];
1067
effyscroll = info->latched_yscroll[which + 2];
1068
effpages = info->latched_pageselect[which + 2];
1071
/* draw the chunk */
1072
effxscroll = (0xc0 - effxscroll + info->xoffs) & 0x3ff;
1073
effyscroll = effyscroll & 0x1ff;
1074
segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowclip, effpages, effxscroll, effyscroll, flags, priority);
1080
static TIMER_CALLBACK( segaic16_tilemap_16b_latch_values )
1082
struct tilemap_info *info = &bg_tilemap[param];
1083
UINT16 *textram = info->textram;
1086
/* latch the scroll and page select values */
1087
for (i = 0; i < 4; i++)
1089
info->latched_pageselect[i] = textram[0xe80/2 + i];
1090
info->latched_yscroll[i] = textram[0xe90/2 + i];
1091
info->latched_xscroll[i] = textram[0xe98/2 + i];
1094
/* set a timer to do this again next frame */
1095
timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, 261, 0), NULL, param, segaic16_tilemap_16b_latch_values);
1099
static void segaic16_tilemap_16b_reset(running_machine *machine, struct tilemap_info *info)
1101
/* set a timer to latch values on scanline 261 */
1102
timer_set(machine, video_screen_get_time_until_pos(machine->primary_screen, 261, 0), NULL, info->index, segaic16_tilemap_16b_latch_values);
1107
/*************************************
1109
* General tilemap initialization
1111
*************************************/
1113
void segaic16_tilemap_init(running_machine *machine, int which, int type, int colorbase, int xoffs, int numbanks)
1115
struct tilemap_info *info = &bg_tilemap[which];
1116
tile_get_info_func get_text_info;
1117
tile_get_info_func get_tile_info;
1121
/* reset the tilemap info */
1122
memset(info, 0, sizeof(*info));
1123
info->index = which;
1125
for (i = 0; i < numbanks; i++)
1127
info->banksize = 0x2000 / numbanks;
1128
info->xoffs = xoffs;
1130
/* set up based on which tilemap */
1134
info->textram = segaic16_textram_0;
1135
info->tileram = segaic16_tileram_0;
1139
fatalerror("Invalid tilemap index specified in segaic16_tilemap_init");
1142
/* determine the parameters of the tilemaps */
1145
case SEGAIC16_TILEMAP_HANGON:
1146
get_text_info = segaic16_tilemap_16a_text_info;
1147
get_tile_info = segaic16_tilemap_16a_tile_info;
1149
info->draw_layer = segaic16_tilemap_16a_draw_layer;
1153
case SEGAIC16_TILEMAP_16A:
1154
get_text_info = segaic16_tilemap_16a_text_info;
1155
get_tile_info = segaic16_tilemap_16a_tile_info;
1157
info->draw_layer = segaic16_tilemap_16a_draw_layer;
1161
case SEGAIC16_TILEMAP_16B:
1162
get_text_info = segaic16_tilemap_16b_text_info;
1163
get_tile_info = segaic16_tilemap_16b_tile_info;
1164
info->numpages = 16;
1165
info->draw_layer = segaic16_tilemap_16b_draw_layer;
1166
info->reset = segaic16_tilemap_16b_reset;
1169
case SEGAIC16_TILEMAP_16B_ALT:
1170
get_text_info = segaic16_tilemap_16b_alt_text_info;
1171
get_tile_info = segaic16_tilemap_16b_alt_tile_info;
1172
info->numpages = 16;
1173
info->draw_layer = segaic16_tilemap_16b_draw_layer;
1174
info->reset = segaic16_tilemap_16b_reset;
1178
fatalerror("Invalid tilemap type specified in segaic16_tilemap_init");
1181
/* create the tilemap for the text layer */
1182
info->textmap = tilemap_create(machine, get_text_info, tilemap_scan_rows, 8,8, 64,28);
1185
info->textmap_info.rambase = info->textram;
1186
info->textmap_info.bank = info->bank;
1187
info->textmap_info.banksize = info->banksize;
1188
tilemap_set_user_data(info->textmap, &info->textmap_info);
1189
tilemap_set_palette_offset(info->textmap, colorbase);
1190
tilemap_set_transparent_pen(info->textmap, 0);
1191
tilemap_set_scrolldx(info->textmap, -192 + xoffs, -170 + xoffs);
1192
tilemap_set_scrolldy(info->textmap, 0, 38);
1194
/* create the tilemaps for the tile pages */
1195
for (pagenum = 0; pagenum < info->numpages; pagenum++)
1197
/* each page is 64x32 */
1198
info->tilemaps[pagenum] = tilemap_create(machine, get_tile_info, tilemap_scan_rows, 8,8, 64,32);
1200
/* configure the tilemap */
1201
info->tmap_info[pagenum].rambase = info->tileram + pagenum * 64*32;
1202
info->tmap_info[pagenum].bank = info->bank;
1203
info->tmap_info[pagenum].banksize = info->banksize;
1204
tilemap_set_user_data(info->tilemaps[pagenum], &info->tmap_info[pagenum]);
1205
tilemap_set_palette_offset(info->tilemaps[pagenum], colorbase);
1206
tilemap_set_transparent_pen(info->tilemaps[pagenum], 0);
1207
tilemap_set_scrolldx(info->tilemaps[pagenum], 0, 22);
1208
tilemap_set_scrolldy(info->tilemaps[pagenum], 0, 38);
1214
/*************************************
1216
* General tilemap rendering
1218
*************************************/
1220
void segaic16_tilemap_draw(running_device *screen, bitmap_t *bitmap, const rectangle *cliprect, int which, int map, int priority, int priority_mark)
1222
running_machine *machine = screen->machine;
1223
struct tilemap_info *info = &bg_tilemap[which];
1225
/* text layer is a special common case */
1226
if (map == SEGAIC16_TILEMAP_TEXT)
1227
tilemap_draw(bitmap, cliprect, info->textmap, priority, priority_mark);
1229
/* other layers are handled differently per-system */
1231
(*info->draw_layer)(machine, info, bitmap, cliprect, map, priority, priority_mark);
1236
/*************************************
1238
* General tilemap reset
1240
*************************************/
1242
void segaic16_tilemap_reset(running_machine *machine, int which)
1244
struct tilemap_info *info = &bg_tilemap[which];
1247
(*info->reset)(machine, info);
1252
/*************************************
1254
* General tilemap banking
1256
*************************************/
1258
void segaic16_tilemap_set_bank(running_machine *machine, int which, int banknum, int offset)
1260
struct tilemap_info *info = &bg_tilemap[which];
1262
if (info->bank[banknum] != offset)
1264
running_device *screen = machine->primary_screen;
1265
video_screen_update_partial(screen, video_screen_get_vpos(screen));
1266
info->bank[banknum] = offset;
1267
tilemap_mark_all_tiles_dirty_all(machine);
1273
/*************************************
1275
* General tilemap screen flipping
1277
*************************************/
1279
void segaic16_tilemap_set_flip(running_machine *machine, int which, int flip)
1281
struct tilemap_info *info = &bg_tilemap[which];
1285
if (info->flip != flip)
1287
running_device *screen = machine->primary_screen;
1288
video_screen_update_partial(screen, video_screen_get_vpos(screen));
1290
tilemap_set_flip(info->textmap, flip ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
1291
for (pagenum = 0; pagenum < info->numpages; pagenum++)
1292
tilemap_set_flip(info->tilemaps[pagenum], flip ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
1298
/*************************************
1300
* General tilemap row scroll enable
1302
*************************************/
1304
void segaic16_tilemap_set_rowscroll(running_machine *machine, int which, int enable)
1306
struct tilemap_info *info = &bg_tilemap[which];
1308
enable = (enable != 0);
1309
if (info->rowscroll != enable)
1311
running_device *screen = machine->primary_screen;
1312
video_screen_update_partial(screen, video_screen_get_vpos(screen));
1313
info->rowscroll = enable;
1319
/*************************************
1321
* General tilemap column scroll enable
1323
*************************************/
1325
void segaic16_tilemap_set_colscroll(running_machine *machine, int which, int enable)
1327
struct tilemap_info *info = &bg_tilemap[which];
1329
enable = (enable != 0);
1330
if (info->colscroll != enable)
1332
running_device *screen = machine->primary_screen;
1333
video_screen_update_partial(screen, video_screen_get_vpos(screen));
1334
info->colscroll = enable;
1340
/*************************************
1342
* General tilemap write handlers
1344
*************************************/
1346
WRITE16_HANDLER( segaic16_tileram_0_w )
1348
COMBINE_DATA(&segaic16_tileram_0[offset]);
1349
tilemap_mark_tile_dirty(bg_tilemap[0].tilemaps[offset / (64*32)], offset % (64*32));
1353
WRITE16_HANDLER( segaic16_textram_0_w )
1355
/* certain ranges need immediate updates */
1356
if (offset >= 0xe80/2)
1357
video_screen_update_partial(space->machine->primary_screen, video_screen_get_vpos(space->machine->primary_screen));
1359
COMBINE_DATA(&segaic16_textram_0[offset]);
1360
tilemap_mark_tile_dirty(bg_tilemap[0].textmap, offset);
1367
/*******************************************************************************************
1369
* Hang On/Space Harrier-style road chip
1373
* 000-1FF ----pp-- -------- road priority versus tilemaps and sprites
1374
* ------s- -------- (Hang On only) Stripe coloring enable (1=enable)
1375
* ------s- -------- (Space Harrier only) Solid color fill (1=solid, 0=from ROM)
1376
* -------m -------- mirror enable (1=enable)
1377
* -------- iiiiiiii index for other tables
1378
* -------- rrrrrrrr road ROM line select
1379
* 200-3FF ----hhhh hhhhhhhh horizontal scroll
1380
* 400-5FF --bbbbbb -------- background color (colorset 0)
1381
* -------- --bbbbbb background color (colorset 1)
1382
* 600-7FF -------- s------- stripe color index (colorset 1)
1383
* -------- -s------ stripe color index (colorset 0)
1384
* -------- --a----- pixel value 2 color index (colorset 1)
1385
* -------- ---a---- pixel value 2 color index (colorset 0)
1386
* -------- ----b--- pixel value 1 color index (colorset 1)
1387
* -------- -----b-- pixel value 1 color index (colorset 0)
1388
* -------- ------c- pixel value 0 color index (colorset 1)
1389
* -------- -------c pixel value 0 color index (colorset 0)
1392
* First, the scanline is used to index into the table at 000-1FF
1394
* The index is taken from the low 8 bits of the table value from 000-1FF
1396
* The horizontal scroll value is looked up using the index in the table at
1399
* The background color information is looked up using the index in the table at 400-5FF.
1401
* The pixel color information is looked up using the index in the table at 600-7FF.
1403
*******************************************************************************************/
1405
static void segaic16_road_hangon_decode(running_machine *machine, struct road_info *info)
1408
const UINT8 *gfx = memory_region(machine, "gfx3");
1409
int len = memory_region_length(machine, "gfx3");
1411
/* allocate memory for the unpacked road data */
1412
info->gfx = auto_alloc_array(machine, UINT8, 256 * 512);
1414
/* loop over rows */
1415
for (y = 0; y < 256; y++)
1417
const UINT8 *src = gfx + ((y & 0xff) * 0x40) % len;
1418
UINT8 *dst = info->gfx + y * 512;
1420
/* loop over columns */
1421
for (x = 0; x < 512; x++)
1422
dst[x] = (((src[x/8] >> (~x & 7)) & 1) << 0) | (((src[x/8 + 0x4000] >> (~x & 7)) & 1) << 1);
1427
static void segaic16_road_hangon_draw(struct road_info *info, bitmap_t *bitmap, const rectangle *cliprect, int priority)
1429
UINT16 *roadram = info->roadram;
1432
/* loop over scanlines */
1433
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
1435
UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
1436
int control = roadram[0x000 + y];
1437
int hpos = roadram[0x100 + (control & 0xff)];
1438
int color0 = roadram[0x200 + (control & 0xff)];
1439
int color1 = roadram[0x300 + (control & 0xff)];
1440
int ff9j1, ff9j2, ctr9m, ctr9n9p, ctr9n9p_ena, ss8j, plycont;
1443
/* the PLYCONT signal controls the road layering */
1444
plycont = (control >> 10) & 3;
1446
/* skip layers we aren't supposed to be drawing */
1447
if ((plycont == 0 && priority != SEGAIC16_ROAD_BACKGROUND) ||
1448
(plycont != 0 && priority != SEGAIC16_ROAD_FOREGROUND))
1451
/* compute the offset of the road graphics for this line */
1452
src = info->gfx + (0x000 + (control & 0xff)) * 512;
1454
/* initialize the 4-bit counter at 9M, which counts bits within each road byte */
1457
/* initialize the two 4-bit counters at 9P (low) and 9N (high), which count road data bytes */
1458
ctr9n9p = (hpos >> 3) & 0xff;
1460
/* initialize the flip-flop at 9J (lower half), which controls the counting direction */
1461
ff9j1 = (hpos >> 11) & 1;
1463
/* initialize the flip-flop at 9J (upper half), which controls the background color */
1466
/* initialize the serial shifter at 8S, which delays several signals after we flip */
1469
/* draw this scanline from the beginning */
1470
for (x = -24; x <= cliprect->max_x; x++)
1472
int md, color, select;
1474
/* ---- the following logic all happens constantly ---- */
1476
/* the enable is controlled by the value in the counter at 9M */
1477
ctr9n9p_ena = (ctr9m == 7);
1479
/* if we carried out of the 9P/9N counters, we will forcibly clear the flip-flop at 9J (lower half) */
1480
if ((ctr9n9p & 0xff) == 0xff)
1483
/* if the control word bit 8 is clear, we will forcibly set the flip-flop at 9J (lower half) */
1484
if (!(control & 0x100))
1487
/* for the Hang On/Super Hang On case only: if the control word bit 9 is clear, we will forcibly */
1488
/* set the flip-flip at 9J (upper half) */
1489
if (info->type == SEGAIC16_ROAD_HANGON && !(control & 0x200))
1492
/* ---- now process the pixel ---- */
1495
/* the Space Harrier/Enduro Racer hardware has a tweak that maps the control word bit 9 to the */
1496
/* /CE line on the road ROM; use this to effectively disable the road data */
1497
if (info->type != SEGAIC16_ROAD_SHARRIER || !(control & 0x200))
1499
/* the /OE line on the road ROM is linked to the AND of bits 2 & 3 of the counter at 9N */
1500
if ((ctr9n9p & 0xc0) == 0xc0)
1502
/* note that the pixel logic is hidden in a custom at 9S; this is just a guess */
1504
md = src[((ctr9n9p & 0x3f) << 3) | ctr9m];
1506
md = src[((ctr9n9p & 0x3f) << 3) | (ctr9m ^ 7)];
1509
/* "select" is a made-up signal that comes from bit 3 of the serial shifter and is */
1510
/* used in several places for color selection */
1511
select = (ss8j >> 3) & 1;
1513
/* check the flip-flop at 9J (upper half) to determine if we should use the background color; */
1514
/* the output of this is ANDed with M0 and M1 so it only affects pixels with a value of 3; */
1515
/* this is done by the AND gates at 9L and 7K */
1516
if (ff9j2 && md == 3)
1518
/* in this case, the "select" signal is used to select which background color to use */
1519
/* since the color0 control word contains two selections */
1520
color = (color0 >> (select ? 0 : 8)) & 0x3f;
1521
color |= info->colorbase2;
1524
/* if we're not using the background color, we select pixel data from an alternate path */
1527
/* the AND gates at 7L, 9K, and 7K clamp the pixel value to 0 if bit 7 of the color 1 */
1528
/* signal is 1 and if the pixel value is 3 (both M0 and M1 == 1) */
1529
if ((color1 & 0x80) && md == 3)
1532
/* the pixel value plus the "select" line combine to form a mux into the low 8 bits of color1 */
1533
color = (color1 >> ((md << 1) | select)) & 1;
1535
/* this value becomes the low bit of the final color; the "select" line itself and the pixel */
1536
/* value form the other bits */
1537
color |= select << 3;
1539
color |= info->colorbase1;
1542
/* write the pixel if we're past the minimum clip */
1543
if (x >= cliprect->min_x)
1546
/* ---- the following logic all happens on the 6M clock ---- */
1548
/* clock the counter at 9M */
1549
ctr9m = (ctr9m + 1) & 7;
1551
/* if enabled, clock on the two cascaded 4-bit counters at 9P and 9N */
1560
/* clock the flip-flop at 9J (upper half) */
1561
ff9j2 = !(!ff9j1 && (ss8j & 0x80));
1563
/* clock the serial shift register at 8J */
1564
ss8j = (ss8j << 1) | ff9j1;
1571
/*******************************************************************************************
1573
* Out Run/X-Board-style road chip
1575
* Road control register:
1577
* -------- -----d-- (X-board only) Direct scanline mode (1) or indirect mode (0)
1578
* -------- ------pp Road enable/priorities:
1579
* 0 = road 0 only visible
1580
* 1 = both roads visible, road 0 has priority
1581
* 2 = both roads visible, road 1 has priority
1582
* 3 = road 1 only visible
1586
* 000-1FF ----s--- -------- Road 0: Solid fill (1) or ROM fill
1587
* -------- -ccccccc Road 0: Solid color (if solid fill)
1588
* -------i iiiiiiii Road 0: Index for other tables (if in indirect mode)
1589
* -------r rrrrrrr- Road 0: Road ROM line select
1590
* 200-3FF ----s--- -------- Road 1: Solid fill (1) or ROM fill
1591
* -------- -ccccccc Road 1: Solid color (if solid fill)
1592
* -------i iiiiiiii Road 1: Index for other tables (if in indirect mode)
1593
* -------r rrrrrrr- Road 1: Road ROM line select
1594
* 400-7FF ----hhhh hhhhhhhh Road 0: horizontal scroll
1595
* 800-BFF ----hhhh hhhhhhhh Road 1: horizontal scroll
1596
* C00-FFF ----bbbb -------- Background color index
1597
* -------- s------- Road 1: stripe color index
1598
* -------- -a------ Road 1: pixel value 2 color index
1599
* -------- --b----- Road 1: pixel value 1 color index
1600
* -------- ---c---- Road 1: pixel value 0 color index
1601
* -------- ----s--- Road 0: stripe color index
1602
* -------- -----a-- Road 0: pixel value 2 color index
1603
* -------- ------b- Road 0: pixel value 1 color index
1604
* -------- -------c Road 0: pixel value 0 color index
1607
* First, the scanline is used to index into the tables at 000-1FF/200-3FF
1608
* - if solid fill, the background is filled with the specified color index
1609
* - otherwise, the remaining tables are used
1611
* If indirect mode is selected, the index is taken from the low 9 bits of the
1612
* table value from 000-1FF/200-3FF
1613
* If direct scanline mode is selected, the index is set equal to the scanline
1614
* for road 0, or the scanline + 256 for road 1
1616
* The horizontal scroll value is looked up using the index in the tables at
1619
* The color information is looked up using the index in the table at C00-FFF. Note
1620
* that the same table is used for both roads.
1623
* Out Run road priorities are controlled by a PAL that maps as indicated below.
1624
* This was used to generate the priority_map. It is assumed that X-board is the
1625
* same, though this logic is locked inside a Sega custom.
1627
* RRC0 = CENTA & (RDA == 3) & !RRC2
1628
* | CENTB & (RDB == 3) & RRC2
1629
* | (RDA == 1) & !RRC2
1630
* | (RDB == 1) & RRC2
1632
* RRC1 = CENTA & (RDA == 3) & !RRC2
1633
* | CENTB & (RDB == 3) & RRC2
1634
* | (RDA == 2) & !RRC2
1635
* | (RDB == 2) & RRC2
1637
* RRC2 = !/HSYNC & IIQ
1639
* | !CENTA & (RDA == 3) & !CENTB & (RDB == 3) & (CTRL == 2)
1640
* | CENTB & (RDB == 3) & (CTRL == 2)
1641
* | !CENTA & (RDA == 3) & !M2 & (CTRL == 2)
1642
* | !CENTA & (RDA == 3) & !M3 & (CTRL == 2)
1643
* | !M0 & (RDB == 0) & (CTRL == 2)
1644
* | !M1 & (RDB == 0) & (CTRL == 2)
1645
* | !CENTA & (RDA == 3) & CENTB & (RDB == 3) & (CTRL == 1)
1646
* | !M0 & CENTB & (RDB == 3) & (CTRL == 1)
1647
* | !M1 & CENTB & (RDB == 3) & (CTRL == 1)
1648
* | !CENTA & M0 & (RDB == 0) & (CTRL == 1)
1649
* | !CENTA & M1 & (RDB == 0) & (CTRL == 1)
1650
* | !CENTA & (RDA == 3) & (RDB == 1) & (CTRL == 1)
1651
* | !CENTA & (RDA == 3) & (RDB == 2) & (CTRL == 1)
1653
* RRC3 = VA11 & VB11
1654
* | VA11 & (CTRL == 0)
1655
* | (CTRL == 3) & VB11
1657
* RRC4 = !CENTA & (RDA == 3) & !CENTB & (RDB == 3)
1659
* | VA11 & (CTRL == 0)
1660
* | (CTRL == 3) & VB11
1661
* | !CENTB & (RDB == 3) & (CTRL == 3)
1662
* | !CENTA & (RDA == 3) & (CTRL == 0)
1664
*******************************************************************************************/
1666
static void segaic16_road_outrun_decode(running_machine *machine, struct road_info *info)
1669
const UINT8 *gfx = memory_region(machine, "gfx3");
1670
int len = memory_region_length(machine, "gfx3");
1672
/* allocate memory for the unpacked road data */
1673
info->gfx = auto_alloc_array(machine, UINT8, (256 * 2 + 1) * 512);
1675
/* loop over rows */
1676
for (y = 0; y < 256 * 2; y++)
1678
const UINT8 *src = gfx + ((y & 0xff) * 0x40 + (y >> 8) * 0x8000) % len;
1679
UINT8 *dst = info->gfx + y * 512;
1681
/* loop over columns */
1682
for (x = 0; x < 512; x++)
1684
dst[x] = (((src[x/8] >> (~x & 7)) & 1) << 0) | (((src[x/8 + 0x4000] >> (~x & 7)) & 1) << 1);
1686
/* pre-mark road data in the "stripe" area with a high bit */
1687
if (x >= 256-8 && x < 256 && dst[x] == 3)
1692
/* set up a dummy road in the last entry */
1693
memset(info->gfx + 256 * 2 * 512, 3, 512);
1697
static void segaic16_road_outrun_draw(struct road_info *info, bitmap_t *bitmap, const rectangle *cliprect, int priority)
1699
UINT16 *roadram = info->buffer;
1702
/* loop over scanlines */
1703
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
1705
static const UINT8 priority_map[2][8] =
1707
{ 0x80,0x81,0x81,0x87,0,0,0,0x00 },
1708
{ 0x81,0x81,0x81,0x8f,0,0,0,0x80 }
1710
// Original guesses from X-board priorities:
1711
// { 0x80,0x81,0x81,0x83,0,0,0,0x00 },
1712
// { 0x81,0x87,0x87,0x8f,0,0,0,0x00 }
1714
UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
1715
int data0 = roadram[0x000 + y];
1716
int data1 = roadram[0x100 + y];
1718
/* background case: look for solid fill scanlines */
1719
if (priority == SEGAIC16_ROAD_BACKGROUND)
1723
/* based on the info->control, we can figure out which sky to draw */
1724
switch (info->control & 3)
1728
color = data0 & 0x7f;
1733
color = data0 & 0x7f;
1734
else if (data1 & 0x800)
1735
color = data1 & 0x7f;
1740
color = data1 & 0x7f;
1741
else if (data0 & 0x800)
1742
color = data0 & 0x7f;
1747
color = data1 & 0x7f;
1751
/* fill the scanline with color */
1754
color |= info->colorbase3;
1755
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
1760
/* foreground case: render from ROM */
1763
int hpos0, hpos1, color0, color1;
1764
int control = info->control & 3;
1765
UINT16 color_table[32];
1769
/* if both roads are low priority, skip */
1770
if ((data0 & 0x800) && (data1 & 0x800))
1773
/* get road 0 data */
1774
src0 = (data0 & 0x800) ? info->gfx + 256 * 2 * 512 : (info->gfx + (0x000 + ((data0 >> 1) & 0xff)) * 512);
1775
hpos0 = (roadram[0x200 + ((info->control & 4) ? y : (data0 & 0x1ff))]) & 0xfff;
1776
color0 = roadram[0x600 + ((info->control & 4) ? y : (data0 & 0x1ff))];
1778
/* get road 1 data */
1779
src1 = (data1 & 0x800) ? info->gfx + 256 * 2 * 512 : (info->gfx + (0x100 + ((data1 >> 1) & 0xff)) * 512);
1780
hpos1 = (roadram[0x400 + ((info->control & 4) ? (0x100 + y) : (data1 & 0x1ff))]) & 0xfff;
1781
color1 = roadram[0x600 + ((info->control & 4) ? (0x100 + y) : (data1 & 0x1ff))];
1783
/* determine the 5 colors for road 0 */
1784
color_table[0x00] = info->colorbase1 ^ 0x00 ^ ((color0 >> 0) & 1);
1785
color_table[0x01] = info->colorbase1 ^ 0x02 ^ ((color0 >> 1) & 1);
1786
color_table[0x02] = info->colorbase1 ^ 0x04 ^ ((color0 >> 2) & 1);
1787
bgcolor = (color0 >> 8) & 0xf;
1788
color_table[0x03] = (data0 & 0x200) ? color_table[0x00] : (info->colorbase2 ^ 0x00 ^ bgcolor);
1789
color_table[0x07] = info->colorbase1 ^ 0x06 ^ ((color0 >> 3) & 1);
1791
/* determine the 5 colors for road 1 */
1792
color_table[0x10] = info->colorbase1 ^ 0x08 ^ ((color1 >> 4) & 1);
1793
color_table[0x11] = info->colorbase1 ^ 0x0a ^ ((color1 >> 5) & 1);
1794
color_table[0x12] = info->colorbase1 ^ 0x0c ^ ((color1 >> 6) & 1);
1795
bgcolor = (color1 >> 8) & 0xf;
1796
color_table[0x13] = (data1 & 0x200) ? color_table[0x10] : (info->colorbase2 ^ 0x10 ^ bgcolor);
1797
color_table[0x17] = info->colorbase1 ^ 0x0e ^ ((color1 >> 7) & 1);
1805
hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
1806
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
1808
int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
1809
dest[x] = color_table[0x00 + pix0];
1810
hpos0 = (hpos0 + 1) & 0xfff;
1815
hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
1816
hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
1817
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
1819
int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
1820
int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
1821
if ((priority_map[0][pix0] >> pix1) & 1)
1822
dest[x] = color_table[0x10 + pix1];
1824
dest[x] = color_table[0x00 + pix0];
1825
hpos0 = (hpos0 + 1) & 0xfff;
1826
hpos1 = (hpos1 + 1) & 0xfff;
1831
hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
1832
hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
1833
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
1835
int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
1836
int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
1837
if ((priority_map[1][pix0] >> pix1) & 1)
1838
dest[x] = color_table[0x10 + pix1];
1840
dest[x] = color_table[0x00 + pix0];
1841
hpos0 = (hpos0 + 1) & 0xfff;
1842
hpos1 = (hpos1 + 1) & 0xfff;
1849
hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
1850
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
1852
int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
1853
dest[x] = color_table[0x10 + pix1];
1854
hpos1 = (hpos1 + 1) & 0xfff;
1864
/*************************************
1866
* General road initialization
1868
*************************************/
1870
void segaic16_road_init(running_machine *machine, int which, int type, int colorbase1, int colorbase2, int colorbase3, int xoffs)
1872
struct road_info *info = &road[which];
1874
/* reset the tilemap info */
1875
memset(info, 0, sizeof(*info));
1876
info->index = which;
1878
info->colorbase1 = colorbase1;
1879
info->colorbase2 = colorbase2;
1880
info->colorbase3 = colorbase3;
1881
info->xoffs = xoffs;
1883
/* set up based on which road generator */
1887
info->roadram = segaic16_roadram_0;
1891
fatalerror("Invalid road index specified in segaic16_road_init");
1894
/* determine the parameters of the road */
1897
case SEGAIC16_ROAD_HANGON:
1898
case SEGAIC16_ROAD_SHARRIER:
1899
info->draw = segaic16_road_hangon_draw;
1900
segaic16_road_hangon_decode(machine, info);
1903
case SEGAIC16_ROAD_OUTRUN:
1904
case SEGAIC16_ROAD_XBOARD:
1905
info->buffer = auto_alloc_array(machine, UINT16, 0x1000/2);
1906
info->draw = segaic16_road_outrun_draw;
1907
segaic16_road_outrun_decode(machine, info);
1911
fatalerror("Invalid road system specified in segaic16_road_init");
1917
/*************************************
1919
* General road drawing
1921
*************************************/
1923
void segaic16_road_draw(int which, bitmap_t *bitmap, const rectangle *cliprect, int priority)
1925
struct road_info *info = &road[which];
1926
(*info->draw)(info, bitmap, cliprect, priority);
1931
/*************************************
1933
* General road control read/write
1935
*************************************/
1937
READ16_HANDLER( segaic16_road_control_0_r )
1939
struct road_info *info = &road[0];
1943
UINT32 *src = (UINT32 *)info->roadram;
1944
UINT32 *dst = (UINT32 *)info->buffer;
1947
/* swap the halves of the road RAM */
1948
for (i = 0; i < 0x1000/4; i++)
1960
WRITE16_HANDLER( segaic16_road_control_0_w )
1962
if (ACCESSING_BITS_0_7)
1964
road[0].control = data & ((road[0].type == SEGAIC16_ROAD_OUTRUN) ? 3 : 7);
1970
/*************************************
1972
* General rotation initialization
1974
*************************************/
1976
void segaic16_rotate_init(running_machine *machine, int which, int type, int colorbase)
1978
struct rotate_info *info = &rotate[which];
1980
/* reset the tilemap info */
1981
memset(info, 0, sizeof(*info));
1982
info->index = which;
1984
info->colorbase = colorbase;
1986
/* set up based on which road generator */
1990
info->rotateram = segaic16_rotateram_0;
1994
fatalerror("Invalid rotate index specified in segaic16_rotate_init");
1997
/* determine the parameters of the rotate */
2000
case SEGAIC16_ROTATE_YBOARD:
2001
info->ramsize = 0x800;
2005
fatalerror("Invalid rotate system specified in segaic16_rotate_init");
2008
/* allocate a buffer for swapping */
2009
info->buffer = auto_alloc_array(machine, UINT16, info->ramsize/2);
2011
state_save_register_item(machine, "segaic16_rot", NULL, which, info->colorbase);
2012
state_save_register_item_pointer(machine, "segaic16_rot", NULL, which, ((UINT8 *) info->buffer), info->ramsize);
2017
/*************************************
2019
* General rotation drawing
2021
*************************************/
2023
void segaic16_rotate_draw(running_machine *machine, int which, bitmap_t *bitmap, const rectangle *cliprect, bitmap_t *srcbitmap)
2025
struct rotate_info *info = &rotate[which];
2026
INT32 currx = (info->buffer[0x3f0] << 16) | info->buffer[0x3f1];
2027
INT32 curry = (info->buffer[0x3f2] << 16) | info->buffer[0x3f3];
2028
INT32 dyy = (info->buffer[0x3f4] << 16) | info->buffer[0x3f5];
2029
INT32 dxx = (info->buffer[0x3f6] << 16) | info->buffer[0x3f7];
2030
INT32 dxy = (info->buffer[0x3f8] << 16) | info->buffer[0x3f9];
2031
INT32 dyx = (info->buffer[0x3fa] << 16) | info->buffer[0x3fb];
2034
/* advance forward based on the clip rect */
2035
currx += dxx * (cliprect->min_x + 27) + dxy * cliprect->min_y;
2036
curry += dyx * (cliprect->min_x + 27) + dyy * cliprect->min_y;
2038
/* loop over screen Y coordinates */
2039
for (y = cliprect->min_y; y <= cliprect->max_y; y++)
2041
UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
2042
UINT16 *src = (UINT16 *)srcbitmap->base;
2043
UINT8 *pri = BITMAP_ADDR8(machine->priority_bitmap, y, 0);
2047
/* loop over screen X coordinates */
2048
for (x = cliprect->min_x; x <= cliprect->max_x; x++)
2050
/* fetch the pixel from the source bitmap */
2051
int sx = (tx >> 14) & 0x1ff;
2052
int sy = (ty >> 14) & 0x1ff;
2053
int pix = src[sy * srcbitmap->rowpixels + sx];
2055
/* non-zero pixels get written; everything else is the scanline color */
2058
*dest++ = (pix & 0x1ff) | ((pix >> 6) & 0x200) | ((pix >> 3) & 0xc00) | 0x1000;
2059
*pri++ = (pix >> 8) | 1;
2063
*dest++ = info->colorbase + sy;
2067
/* advance the source X/Y pointers */
2072
/* advance the source X/Y pointers */
2080
/*************************************
2082
* General road control read/write
2084
*************************************/
2086
READ16_HANDLER( segaic16_rotate_control_0_r )
2088
struct rotate_info *info = &rotate[0];
2092
UINT32 *src = (UINT32 *)info->rotateram;
2093
UINT32 *dst = (UINT32 *)info->buffer;
2096
/* swap the halves of the rotation RAM */
2097
for (i = 0; i < info->ramsize/4; i++)