/src/mame/video/segaic16.c

https://github.com/yoshisuga/MAME4iOS · C · 2122 lines · 974 code · 294 blank · 854 comment · 175 complexity · 3404b624a11d32c09b4a2269e4f0b9dd MD5 · raw file

  1. /***************************************************************************
  2. Sega 16-bit common hardware
  3. ****************************************************************************
  4. Hang On
  5. -------
  6. Control Board (834-5668):
  7. 315-5011 -- sprite line comparitor
  8. 315-5012 -- sprite generator control
  9. 315-5049 (x2) -- tilemaps
  10. 315-5107 (PAL x2) -- horizontal timing control
  11. 315-5108 -- vertical timing control
  12. 315-5122 (PAL) -- timing
  13. Enduro Racer
  14. ------------
  15. CPU Side (171-5319):
  16. 315-5164 (PAL)
  17. 315-5165 (PAL)
  18. 315-5166 (PAL)
  19. 315-5167 (PAL)
  20. Video Side (171-5320):
  21. 315-5049 (x2) -- tilemaps
  22. 315-5011 -- sprite line comparitor
  23. 315-5012 -- sprite generator control
  24. 315-5106 (PAL)
  25. 315-5107 (PAL)
  26. 315-5108 (PAL)
  27. 315-5168 (PAL)
  28. 315-5170 (PAL)
  29. 315-5171 (PAL)
  30. 315-5172 (PAL)
  31. Pre-System 16
  32. -------------
  33. Main Board (171-5335):
  34. 315-5011 -- sprite line comparitor
  35. 315-5012 -- sprite generator control
  36. 315-5049 (x2) -- tilemaps
  37. 315-5107 (PAL) -- display timing
  38. 315-5108 (PAL) -- display timing
  39. 315-5141 (PAL) -- Z80 address decoding
  40. 315-5143 (PAL) -- sprite-related?
  41. 315-5144 (PAL) -- sprite-related?
  42. 315-5147 (PAL) -- unknown, DTACK-related
  43. 315-5149 (PAL) -- video mixing
  44. 315-5193 (PAL) -- 68000/MCU interface & address decoding
  45. 315-5202 (PAL) -- 68000/MCU interface & address decoding
  46. Sega System 16A
  47. ---------------
  48. Bottom Board (171-5307):
  49. 315-5011 -- sprite line comparitor
  50. 315-5012 -- sprite generator control
  51. 315-5049 (x2) -- tilemaps
  52. 315-5107 (PAL) -- display timing
  53. 315-5108 (PAL) -- display timing
  54. 315-5143 (PAL) -- sprite-related?
  55. 315-5144 (PAL) -- sprite-related?
  56. 315-5145 (PAL)
  57. Top Board (171-5306):
  58. 315-5141 (PAL) -- Z80 address decoding
  59. 315-5142 (PAL)
  60. 315-5149 (PAL) -- video mixing
  61. 315-5150 (PAL)
  62. Sega System 16B
  63. ---------------
  64. Main Board (171-5357):
  65. 315-5195 -- memory mapper
  66. 315-5196 -- sprite generator
  67. 315-5197 -- tilemap generator
  68. 315-5213 (PAL) -- sprite-related
  69. 315-5214 (PAL) -- unknown
  70. ROM Board (171-5521):
  71. 315-5298 (PAL)
  72. ROM Board (171-5704):
  73. 315-5298 (PAL)
  74. ROM Board (171-5797):
  75. 315-5248 -- hardware multiplier
  76. 315-5250 -- compare/timer
  77. 315-5298 (PAL)
  78. Sega System 18
  79. --------------
  80. Main Board (171-5873B):
  81. 315-5242 -- color encoder
  82. 315-5296 -- I/O chip
  83. 315-5313 -- VDP
  84. 315-5360 -- memory mapper?
  85. 315-5361 -- sprite generator
  86. 315-5362 -- tilemap generator
  87. 315-5373 (PAL) -- video mixing
  88. 315-5374 (PAL) -- sprite timing
  89. 315-5375 (PAL) -- system timing
  90. 315-5389 (PAL) -- VDP sync
  91. 315-5390 (PAL)
  92. 315-5391 (PAL) -- Z80 address decoding
  93. Main Board (171-5873-02B):
  94. 315-5242 -- color encoder
  95. 315-5296 -- I/O chip
  96. 315-5313 -- VDP
  97. 315-5360 -- memory mapper?
  98. 315-5361 -- sprite generator
  99. 315-5362 -- tilemap generator
  100. 315-5374 (PAL) -- sprite timing
  101. 315-5375 (PAL) -- system timing
  102. 315-5389 (PAL) -- VDP sync
  103. 315-5391 (PAL) -- Z80 address decoding
  104. 315-5430 (PAL) -- video mixing
  105. ROM Board (171-5987A):
  106. 315-5436 -- tile/sprite banking
  107. Sega System C
  108. -------------
  109. Main Board:
  110. 315-5242 -- color encoder
  111. 315-5296 -- I/O chip
  112. 315-5313 -- VDP
  113. 315-5393 (PAL)
  114. 315-5394 (PAL)
  115. 315-5395 (PAL)
  116. Super Hang On
  117. -------------
  118. CPU Board 171-5376-01:
  119. 315-5195 -- memory mapper
  120. 315-5218 -- PCM sound controller
  121. 315-5155 (PAL x2) -- road bit extraction
  122. 315-5222 (PAL) -- road mixing
  123. 315-5223a (PAL)
  124. 315-5224 (PAL)
  125. 315-5225 (PAL)
  126. 315-5226 (PAL)
  127. VIDEO Board: (not the same as out run !) 171-5480
  128. 315-5196 -- sprite generator
  129. 315-5197 -- tilemap generator
  130. 315-5213 (PAL) -- sprite-related
  131. 315-5242 -- color encoder
  132. 315-5251 (PAL)
  133. Out Run
  134. -------
  135. CPU Board 837-6063-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
  140. 315-5223a (PAL)
  141. 315-5224 (PAL)
  142. 315-5225 (PAL)
  143. 315-5226 (PAL)
  144. VIDEO Board: 837-6064, 171-5377-01
  145. 315-5197 -- tilemap generator
  146. 315-5211 -- sprite generator
  147. 315-5227a (PAL)
  148. 315-5228 (PAL)
  149. 315-5242 -- color encoder
  150. Sega System 32
  151. --------------
  152. Main Board (317-5964):
  153. 315-5242 -- color encoder
  154. 315-5296 -- I/O chip
  155. 315-5385
  156. 315-5386 -- tilemap generator
  157. 315-5387 -- sprite generator
  158. 315-5388 -- video mixing
  159. 315-5441 (PAL)
  160. 315-5476
  161. X-Board
  162. -------
  163. Main Board:
  164. 315-5197 -- tilemap generator
  165. 315-5211A -- sprite generator
  166. 315-5218 -- PCM sound controller
  167. 315-5242 -- color encoder
  168. 315-5248 (x2) -- hardware multiplier
  169. 315-5249 (x2) -- hardware divider
  170. 315-5250 (x2) -- compare/timer
  171. 315-5275 -- road generator
  172. 315-5278 (PAL) -- sprite ROM bank control
  173. 315-5279 (PAL) -- video mixing (Afterburner)
  174. 315-5280 (PAL) -- Z80 address decoding
  175. 315-5290 (PAL) -- main CPU address decoding
  176. 315-5291 (PAL) -- main CPU address decoding
  177. 315-5304 (PAL) -- video mixing (Line of Fire)
  178. Y-Board
  179. -------
  180. Main Board (837-6565):
  181. 315-5218 -- PCM sound controller
  182. 315-5248 (x3) -- hardware multiplier
  183. 315-5249 (x3) -- hardware divider
  184. 315-5280 (PAL) -- Z80 address decoding
  185. 315-5296 -- I/O chip
  186. 315-5314 (PAL)
  187. 315-5315 (PAL)
  188. 315-5316 (PAL)
  189. 315-5317 (PAL)
  190. 315-5318 (PAL)
  191. 315-5328 (PAL)
  192. Video Board (837-6566):
  193. 315-5196 -- sprite generator
  194. 315-5213 (PAL) -- sprite-related
  195. 315-5242 -- color encoder
  196. 315-5305 -- sprite generator
  197. 315-5306 (x2) -- video sync and rotation
  198. 315-5312 -- video mixing
  199. 315-5319 (PAL)
  200. 315-5325 (PAL)
  201. Custom parts
  202. ------------
  203. SYS1 SYS2 HANG ENDU PR16 S16A S16B SY18 SHNG ORUN XBRD YBRD SYSC SY24 SY32
  204. 315-5011: xx xx xx xx xx xx -- sprite line comparitor
  205. 315-5012: xx xx xx xx xx xx -- sprite generator control
  206. 315-5049: xx x2 x2 x2 x2 -- tilemap generator
  207. 315-5195: xx xx xx -- memory mapper
  208. 315-5196: xx xx xx -- sprite genereator
  209. 315-5197: xx xx xx xx -- tilemap generator
  210. 315-5211: xx -- sprite generator
  211. 315-5211A: xx -- sprite generator
  212. 315-5218: xx xx xx xx -- PCM sound controller
  213. 315-5242: xx xx xx xx xx xx xx xx -- color encoder
  214. 315-5248: xx x2 x3 -- hardware multiplier
  215. 315-5249: x2 x3 -- hardware divider
  216. 315-5250: xx x2 -- compare/timer
  217. 315-5275: xx -- road generator
  218. 315-5296: xx xx xx xx -- I/O chip
  219. 315-5305: xx --
  220. 315-5312: xx -- video mixing
  221. 315-5313: xx xx -- VDP
  222. 315-5360: xx -- memory mapper
  223. 315-5361: xx -- sprite generator
  224. 315-5362: xx -- tilemap generator
  225. 315-5385: xx -- ???
  226. 315-5386: xx -- tilemap generator
  227. 315-5387: xx -- sprite generator
  228. 315-5388: xx -- video mixing
  229. 315-5436: xx -- sprite/tile banking
  230. 315-5476: xx -- ????
  231. ****************************************************************************
  232. Sega system16 and friends hardware
  233. CPU Tiles Sprites Priority Color SCPU Sound Other
  234. System C 68000 315-5313 315-5242 z80 ym3438 315-5296(IO)
  235. Space Harrier 68000x2 (c) z80 ym2203 pcm(b)
  236. System 16B 68000 315-5197 315-5196 GAL (c) z80 ym2151 upd7759 315-5195
  237. 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)
  238. System 18 68000 315-536x 315-536x 315-5242 z80 ym3834(x2) RF5c68(d) 315-3296(IO) 315-5313(vdp)
  239. System 24 68000x2 315-5292 315-5293 315-5294 315-5242 ym2151 dac 315-5195(x3) 315-5296(IO)
  240. Galaxy Force 68000x3 315-5296+ 315-5312 315-5242 z80 ym2151 315-5218 315-5296(IO)
  241. System 32 V60 315-5386A 315-5387 315-5388 315-5242 z80 ym3834(x2) RF5c68(d) 315-5296(IO)
  242. a) 315-5250: 68000 glue and address decoding
  243. b) 8x8-bit voices entirely in TTL. The 315-5218 is believed to be the
  244. integrated version of that
  245. c) Resistor network and latches believed to be equivalent to the 315-5242
  246. d) Also seen as 315-5476A and ASSP 5c105 and ASSP 5c68a
  247. Quick review of the system16 hardware:
  248. Hang-on hardware:
  249. The first one. Two tilemap planes, one sprite plane, one road
  250. plane. The shadow capability doesn't seem to be used, the
  251. highlight/shadow switch in the 5242-equivalent is global for all
  252. colors.
  253. Space harrier hardware:
  254. Similar to hang-on, with per-color highlight/shadow selection, and
  255. the shadows are used.
  256. System16a / Pre-system16:
  257. Space harrier without the road generator.
  258. System16b:
  259. 4-layer tilemap hardware in two pairs, with selection between each
  260. members on the pairs on a 8-lines basis. Slightly better sprites.
  261. System18
  262. System 16b plus a genesis vdp.
  263. Outrun:
  264. System 16b tilemaps, frame buffered sprites with better zooming
  265. capabilities, and a road generator able to handle two roads
  266. simultaneously.
  267. Super hang-on:
  268. Outrun lite, with System 16b sprites instead of the frame buffered
  269. sprites, and only one of the two roads is actually used.
  270. X-Board:
  271. Outrun with a better fillrate and an even more flexible road
  272. generator.
  273. Y-Board:
  274. New design, with two sprite planes and no tilemaps. The back
  275. sprite plane has a huge fillrate and the capability to have its
  276. frame buffer completely rotated. Also, it has a palette
  277. indirection capability to allows for easier palette rotations.
  278. The front sprite plane is System 16b.
  279. System24:
  280. The odd one out. Medium resolution. Entirely ram-based, no
  281. graphics roms. 4-layer tilemap hardware in two pairs, selection
  282. on a 8-pixels basis. Tile-based sprites(!) organised as a linked
  283. list. The tilemap chip has been reused for model1 and model2,
  284. probably because they had it handy and it handles medium res.
  285. System32:
  286. 5-layer tilemap hardware consisting of 4 independent rom-based
  287. layers with linescroll, lineselection, linezoom and window
  288. clipping capability and one simpler ram-based text plane. Mixed
  289. ram/rom sprite engine with palette indirection, per-color priority
  290. (thankfully not actually used). The sprite list includes jumping
  291. and clipping capabilities, and advanced hot-spot positioning. The
  292. mixer chip adds totally dynamic priorities, alpha-blending of the
  293. tilemaps, per-component color control, and some other funnies we
  294. have not been able to decypher.
  295. ST-V (also know as Titan or the Saturn console):
  296. The ultimate 2D system. Even more advanced tilemaps, with 6-dof
  297. roz support, alpha up to the wazoo and other niceties, known as
  298. the vdp2. Ths sprite engine, vdp1, allows for any 4-point
  299. streching of the sprites, actually giving polygonal 3D
  300. capabilities. Interestingly, the mixer capabilities took a hit,
  301. with no real per-sprite mixer priority, which could be considered
  302. annoying for a 2D system. It still allowed some beauties like
  303. Radiant Silvergun.
  304. ***************************************************************************/
  305. #include "emu.h"
  306. #include "segaic16.h"
  307. #include "video/resnet.h"
  308. /*************************************
  309. *
  310. * Debugging
  311. *
  312. *************************************/
  313. #define PRINT_UNUSUAL_MODES (0)
  314. /*************************************
  315. *
  316. * Globals
  317. *
  318. *************************************/
  319. UINT8 segaic16_display_enable;
  320. UINT16 *segaic16_tileram_0;
  321. UINT16 *segaic16_textram_0;
  322. UINT16 *segaic16_roadram_0;
  323. UINT16 *segaic16_rotateram_0;
  324. UINT16 *segaic16_paletteram;
  325. struct palette_info segaic16_palette;
  326. struct rotate_info segaic16_rotate[SEGAIC16_MAX_ROTATE];
  327. struct road_info segaic16_road[SEGAIC16_MAX_ROADS];
  328. /*************************************
  329. *
  330. * Statics
  331. *
  332. *************************************/
  333. static struct tilemap_info bg_tilemap[SEGAIC16_MAX_TILEMAPS];
  334. /*************************************
  335. *
  336. * Misc functions
  337. *
  338. *************************************/
  339. void segaic16_set_display_enable(running_machine *machine, int enable)
  340. {
  341. enable = (enable != 0);
  342. if (segaic16_display_enable != enable)
  343. {
  344. machine->primary_screen->update_partial(machine->primary_screen->vpos());
  345. segaic16_display_enable = enable;
  346. }
  347. }
  348. /*************************************
  349. *
  350. * Palette computation
  351. *
  352. *************************************/
  353. /*
  354. Color generation details
  355. Each color is made up of 5 bits, connected through one or more resistors like so:
  356. Bit 0 = 1 x 3.9K ohm
  357. Bit 1 = 1 x 2.0K ohm
  358. Bit 2 = 1 x 1.0K ohm
  359. Bit 3 = 2 x 1.0K ohm
  360. Bit 4 = 4 x 1.0K ohm
  361. Another data bit is connected by a tristate buffer to the color output through a
  362. 470 ohm resistor. The buffer allows the resistor to have no effect (tristate),
  363. halve brightness (pull-down) or double brightness (pull-up). The data bit source
  364. is bit 15 of each color RAM entry.
  365. */
  366. void segaic16_palette_init(int entries)
  367. {
  368. static const int resistances_normal[6] = { 3900, 2000, 1000, 1000/2, 1000/4, 0 };
  369. static const int resistances_sh[6] = { 3900, 2000, 1000, 1000/2, 1000/4, 470 };
  370. double weights[2][6];
  371. int i;
  372. struct palette_info *info = &segaic16_palette;
  373. /* compute the number of palette entries */
  374. info->entries = entries;
  375. /* compute weight table for regular palette entries */
  376. compute_resistor_weights(0, 255, -1.0,
  377. 6, resistances_normal, weights[0], 0, 0,
  378. 0, NULL, NULL, 0, 0,
  379. 0, NULL, NULL, 0, 0);
  380. /* compute weight table for shadow/hilight palette entries */
  381. compute_resistor_weights(0, 255, -1.0,
  382. 6, resistances_sh, weights[1], 0, 0,
  383. 0, NULL, NULL, 0, 0,
  384. 0, NULL, NULL, 0, 0);
  385. /* compute R, G, B for each weight */
  386. for (i = 0; i < 32; i++)
  387. {
  388. int i4 = (i >> 4) & 1;
  389. int i3 = (i >> 3) & 1;
  390. int i2 = (i >> 2) & 1;
  391. int i1 = (i >> 1) & 1;
  392. int i0 = (i >> 0) & 1;
  393. info->normal[i] = combine_6_weights(weights[0], i0, i1, i2, i3, i4, 0);
  394. info->shadow[i] = combine_6_weights(weights[1], i0, i1, i2, i3, i4, 0);
  395. info->hilight[i] = combine_6_weights(weights[1], i0, i1, i2, i3, i4, 1);
  396. }
  397. }
  398. /*************************************
  399. *
  400. * Palette accessors
  401. *
  402. *************************************/
  403. WRITE16_HANDLER( segaic16_paletteram_w )
  404. {
  405. UINT16 newval;
  406. int r, g, b;
  407. struct palette_info *info = &segaic16_palette;
  408. /* get the new value */
  409. newval = segaic16_paletteram[offset];
  410. COMBINE_DATA(&newval);
  411. segaic16_paletteram[offset] = newval;
  412. /* byte 0 byte 1 */
  413. /* sBGR BBBB GGGG RRRR */
  414. /* x000 4321 4321 4321 */
  415. r = ((newval >> 12) & 0x01) | ((newval << 1) & 0x1e);
  416. g = ((newval >> 13) & 0x01) | ((newval >> 3) & 0x1e);
  417. b = ((newval >> 14) & 0x01) | ((newval >> 7) & 0x1e);
  418. /* normal colors */
  419. palette_set_color_rgb(space->machine, offset + 0 * info->entries, info->normal[r], info->normal[g], info->normal[b]);
  420. palette_set_color_rgb(space->machine, offset + 1 * info->entries, info->shadow[r], info->shadow[g], info->shadow[b]);
  421. palette_set_color_rgb(space->machine, offset + 2 * info->entries, info->hilight[r], info->hilight[g], info->hilight[b]);
  422. }
  423. /*************************************
  424. *
  425. * Draw a split tilemap in up to
  426. * four pieces
  427. *
  428. *************************************/
  429. 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)
  430. {
  431. int leftmin = -1, leftmax = -1, rightmin = -1, rightmax = -1;
  432. int topmin = -1, topmax = -1, bottommin = -1, bottommax = -1;
  433. rectangle pageclip;
  434. int page;
  435. int width = machine->primary_screen->width();
  436. int height = machine->primary_screen->height();
  437. /* which half/halves of the virtual tilemap do we intersect in the X direction? */
  438. if (xscroll < 64*8 - width)
  439. {
  440. leftmin = 0;
  441. leftmax = width - 1;
  442. rightmin = -1;
  443. }
  444. else if (xscroll < 64*8)
  445. {
  446. leftmin = 0;
  447. leftmax = 64*8 - xscroll - 1;
  448. rightmin = leftmax + 1;
  449. rightmax = width - 1;
  450. }
  451. else if (xscroll < 128*8 - width)
  452. {
  453. rightmin = 0;
  454. rightmax = width - 1;
  455. leftmin = -1;
  456. }
  457. else
  458. {
  459. rightmin = 0;
  460. rightmax = 128*8 - xscroll - 1;
  461. leftmin = rightmax + 1;
  462. leftmax = width - 1;
  463. }
  464. /* which half/halves of the virtual tilemap do we intersect in the Y direction? */
  465. if (yscroll < 32*8 - height)
  466. {
  467. topmin = 0;
  468. topmax = height - 1;
  469. bottommin = -1;
  470. }
  471. else if (yscroll < 32*8)
  472. {
  473. topmin = 0;
  474. topmax = 32*8 - yscroll - 1;
  475. bottommin = topmax + 1;
  476. bottommax = height - 1;
  477. }
  478. else if (yscroll < 64*8 - height)
  479. {
  480. bottommin = 0;
  481. bottommax = height - 1;
  482. topmin = -1;
  483. }
  484. else
  485. {
  486. bottommin = 0;
  487. bottommax = 64*8 - yscroll - 1;
  488. topmin = bottommax + 1;
  489. topmax = height - 1;
  490. }
  491. /* if the tilemap is flipped, we need to flip our sense within each quadrant */
  492. if (info->flip)
  493. {
  494. if (leftmin != -1)
  495. {
  496. int temp = leftmin;
  497. leftmin = width - 1 - leftmax;
  498. leftmax = width - 1 - temp;
  499. }
  500. if (rightmin != -1)
  501. {
  502. int temp = rightmin;
  503. rightmin = width - 1 - rightmax;
  504. rightmax = width - 1 - temp;
  505. }
  506. if (topmin != -1)
  507. {
  508. int temp = topmin;
  509. topmin = height - 1 - topmax;
  510. topmax = height - 1 - temp;
  511. }
  512. if (bottommin != -1)
  513. {
  514. int temp = bottommin;
  515. bottommin = height - 1 - bottommax;
  516. bottommax = height - 1 - temp;
  517. }
  518. }
  519. /* draw the upper-left chunk */
  520. if (leftmin != -1 && topmin != -1)
  521. {
  522. pageclip.min_x = (leftmin < cliprect->min_x) ? cliprect->min_x : leftmin;
  523. pageclip.max_x = (leftmax > cliprect->max_x) ? cliprect->max_x : leftmax;
  524. pageclip.min_y = (topmin < cliprect->min_y) ? cliprect->min_y : topmin;
  525. pageclip.max_y = (topmax > cliprect->max_y) ? cliprect->max_y : topmax;
  526. if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
  527. {
  528. page = (pages >> 0) & 0xf;
  529. tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
  530. tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
  531. tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
  532. }
  533. }
  534. /* draw the upper-right chunk */
  535. if (rightmin != -1 && topmin != -1)
  536. {
  537. pageclip.min_x = (rightmin < cliprect->min_x) ? cliprect->min_x : rightmin;
  538. pageclip.max_x = (rightmax > cliprect->max_x) ? cliprect->max_x : rightmax;
  539. pageclip.min_y = (topmin < cliprect->min_y) ? cliprect->min_y : topmin;
  540. pageclip.max_y = (topmax > cliprect->max_y) ? cliprect->max_y : topmax;
  541. if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
  542. {
  543. page = (pages >> 4) & 0xf;
  544. tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
  545. tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
  546. tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
  547. }
  548. }
  549. /* draw the lower-left chunk */
  550. if (leftmin != -1 && bottommin != -1)
  551. {
  552. pageclip.min_x = (leftmin < cliprect->min_x) ? cliprect->min_x : leftmin;
  553. pageclip.max_x = (leftmax > cliprect->max_x) ? cliprect->max_x : leftmax;
  554. pageclip.min_y = (bottommin < cliprect->min_y) ? cliprect->min_y : bottommin;
  555. pageclip.max_y = (bottommax > cliprect->max_y) ? cliprect->max_y : bottommax;
  556. if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
  557. {
  558. page = (pages >> 8) & 0xf;
  559. tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
  560. tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
  561. tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
  562. }
  563. }
  564. /* draw the lower-right chunk */
  565. if (rightmin != -1 && bottommin != -1)
  566. {
  567. pageclip.min_x = (rightmin < cliprect->min_x) ? cliprect->min_x : rightmin;
  568. pageclip.max_x = (rightmax > cliprect->max_x) ? cliprect->max_x : rightmax;
  569. pageclip.min_y = (bottommin < cliprect->min_y) ? cliprect->min_y : bottommin;
  570. pageclip.max_y = (bottommax > cliprect->max_y) ? cliprect->max_y : bottommax;
  571. if (pageclip.min_x <= pageclip.max_x && pageclip.min_y <= pageclip.max_y)
  572. {
  573. page = (pages >> 12) & 0xf;
  574. tilemap_set_scrollx(info->tilemaps[page], 0, xscroll);
  575. tilemap_set_scrolly(info->tilemaps[page], 0, yscroll);
  576. tilemap_draw(bitmap, &pageclip, info->tilemaps[page], flags, priority);
  577. }
  578. }
  579. }
  580. /*******************************************************************************************
  581. *
  582. * Hang On/System 16A-style tilemaps
  583. *
  584. * 4 total pages (Hang On)
  585. * 8 total pages (System 16A)
  586. * Column/rowscroll enabled via external signals
  587. *
  588. * Tile format:
  589. * Bits Usage
  590. * ??------ -------- Unknown
  591. * --b----- -------- Tile bank select
  592. * ---p---- -------- Tile priority versus sprites
  593. * ----cccc ccc----- Tile color palette
  594. * ----nnnn nnnnnnnn Tile index
  595. *
  596. * Text format:
  597. * Bits Usage
  598. * ????---- -------- Unknown
  599. * ----p--- -------- Priority
  600. * -----ccc -------- Tile color palette
  601. * -------- nnnnnnnn Tile index
  602. *
  603. * Text RAM:
  604. * Offset Bits Usage
  605. * E8C -aaa-bbb -ccc-ddd Background tilemap page select (screen flipped)
  606. * E8E -aaa-bbb -ccc-ddd Foreground tilemap page select (screen flipped)
  607. * E9C -aaa-bbb -ccc-ddd Background tilemap page select
  608. * E9E -aaa-bbb -ccc-ddd Foreground tilemap page select
  609. * F24 -------- vvvvvvvv Foreground tilemap vertical scroll
  610. * F26 -------- vvvvvvvv Background tilemap vertical scroll
  611. * F30-F7D -------- vvvvvvvv Foreground tilemap per-16-pixel-column vertical scroll (every 2 words)
  612. * F32-F7F -------- vvvvvvvv Background tilemap per-16-pixel-column vertical scroll (every 2 words)
  613. * F80-FED -------h hhhhhhhh Foreground tilemap per-8-pixel-row horizontal scroll (every 2 words)
  614. * F82-FEF -------h hhhhhhhh Background tilemap per-8-pixel-row horizontal scroll (every 2 words)
  615. * FF8 -------h hhhhhhhh Foreground tilemap horizontal scroll
  616. * FFA -------h hhhhhhhh Background tilemap horizontal scroll
  617. *
  618. *******************************************************************************************/
  619. static TILE_GET_INFO( segaic16_tilemap_16a_tile_info )
  620. {
  621. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  622. UINT16 data = info->rambase[tile_index];
  623. int code = ((data >> 1) & 0x1000) | (data & 0xfff);
  624. int color = (data >> 5) & 0x7f;
  625. SET_TILE_INFO(0, code, color, 0);
  626. tileinfo->category = (data >> 12) & 1;
  627. }
  628. static TILE_GET_INFO( segaic16_tilemap_16a_text_info )
  629. {
  630. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  631. UINT16 data = info->rambase[tile_index];
  632. int color = (data >> 8) & 0x07;
  633. int code = data & 0xff;
  634. SET_TILE_INFO(0, code, color, 0);
  635. tileinfo->category = (data >> 11) & 1;
  636. }
  637. 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)
  638. {
  639. UINT16 *textram = info->textram;
  640. /* note that the scrolling for these games can only scroll as much as the top-left */
  641. /* page; in order to scroll beyond that they swap pages and reset the scroll value */
  642. UINT16 xscroll = textram[0xff8/2 + which] & 0x1ff;
  643. UINT16 yscroll = textram[0xf24/2 + which] & 0x0ff;
  644. UINT16 pages = textram[(info->flip ? 0xe8e/2 : 0xe9e/2) - which];
  645. int x, y;
  646. /* pages are swapped along the X direction, and there are only 8 of them */
  647. pages = ((pages >> 4) & 0x0707) | ((pages << 4) & 0x7070);
  648. if (info->numpages == 4)
  649. pages &= 0x3333;
  650. /* column AND row scroll */
  651. if (info->colscroll && info->rowscroll)
  652. {
  653. if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column AND row scroll\n");
  654. /* loop over row chunks */
  655. for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
  656. {
  657. int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
  658. rectangle rowcolclip;
  659. /* adjust to clip this row only */
  660. rowcolclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
  661. rowcolclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
  662. /* loop over column chunks */
  663. for (x = cliprect->min_x & ~15; x <= cliprect->max_x; x += 16)
  664. {
  665. UINT16 effxscroll, effyscroll;
  666. /* adjust to clip this column only */
  667. rowcolclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
  668. rowcolclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
  669. /* get the effective scroll values */
  670. effxscroll = textram[0xf80/2 + rowscrollindex * 2 + which] & 0x1ff;
  671. effyscroll = textram[0xf30/2 + (x/16) * 2 + which] & 0x0ff;
  672. /* adjust the xscroll for flipped screen */
  673. if (info->flip)
  674. effxscroll += 17;
  675. /* draw the chunk */
  676. effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
  677. effyscroll = effyscroll & 0x1ff;
  678. segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowcolclip, pages, effxscroll, effyscroll, flags, priority);
  679. }
  680. }
  681. }
  682. else if (info->colscroll)
  683. {
  684. if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column scroll\n");
  685. /* loop over column chunks */
  686. for (x = cliprect->min_x & ~15; x <= cliprect->max_x; x += 16)
  687. {
  688. rectangle colclip = *cliprect;
  689. UINT16 effxscroll, effyscroll;
  690. /* adjust to clip this row only */
  691. colclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
  692. colclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
  693. /* get the effective scroll values */
  694. effxscroll = xscroll;
  695. effyscroll = textram[0xf30/2 + (x/16) * 2 + which] & 0x0ff;
  696. /* adjust the xscroll for flipped screen */
  697. if (info->flip)
  698. effxscroll += 17;
  699. /* draw the chunk */
  700. effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
  701. effyscroll = effyscroll & 0x1ff;
  702. segaic16_draw_virtual_tilemap(machine, info, bitmap, &colclip, pages, effxscroll, effyscroll, flags, priority);
  703. }
  704. }
  705. else if (info->rowscroll)
  706. {
  707. if (PRINT_UNUSUAL_MODES) mame_printf_debug("Row scroll\n");
  708. /* loop over row chunks */
  709. for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
  710. {
  711. int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
  712. rectangle rowclip = *cliprect;
  713. UINT16 effxscroll, effyscroll;
  714. /* adjust to clip this row only */
  715. rowclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
  716. rowclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
  717. /* get the effective scroll values */
  718. effxscroll = textram[0xf80/2 + rowscrollindex * 2 + which] & 0x1ff;
  719. effyscroll = yscroll;
  720. /* adjust the xscroll for flipped screen */
  721. if (info->flip)
  722. effxscroll += 17;
  723. /* draw the chunk */
  724. effxscroll = (0xc8 - effxscroll + info->xoffs) & 0x3ff;
  725. effyscroll = effyscroll & 0x1ff;
  726. segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowclip, pages, effxscroll, effyscroll, flags, priority);
  727. }
  728. }
  729. else
  730. {
  731. /* adjust the xscroll for flipped screen */
  732. if (info->flip)
  733. xscroll += 17;
  734. xscroll = (0xc8 - xscroll + info->xoffs) & 0x3ff;
  735. yscroll = yscroll & 0x1ff;
  736. segaic16_draw_virtual_tilemap(machine, info, bitmap, cliprect, pages, xscroll, yscroll, flags, priority);
  737. }
  738. }
  739. /*******************************************************************************************
  740. *
  741. * System 16B-style tilemaps
  742. *
  743. * 16 total pages
  744. * Column/rowscroll enabled via bits in text layer
  745. * Alternate tilemap support
  746. *
  747. * Tile format:
  748. * Bits Usage
  749. * p------- -------- Tile priority versus sprites
  750. * -??----- -------- Unknown
  751. * ---ccccc cc------ Tile color palette
  752. * ---nnnnn nnnnnnnn Tile index
  753. *
  754. * Text format:
  755. * Bits Usage
  756. * p------- -------- Tile priority versus sprites
  757. * -???---- -------- Unknown
  758. * ----ccc- -------- Tile color palette
  759. * -------n nnnnnnnn Tile index
  760. *
  761. * Alternate tile format:
  762. * Bits Usage
  763. * p------- -------- Tile priority versus sprites
  764. * -??----- -------- Unknown
  765. * ----cccc ccc----- Tile color palette
  766. * ---nnnnn nnnnnnnn Tile index
  767. *
  768. * Alternate text format:
  769. * Bits Usage
  770. * p------- -------- Tile priority versus sprites
  771. * -???---- -------- Unknown
  772. * -----ccc -------- Tile color palette
  773. * -------- nnnnnnnn Tile index
  774. *
  775. * Text RAM:
  776. * Offset Bits Usage
  777. * E80 aaaabbbb ccccdddd Foreground tilemap page select
  778. * E82 aaaabbbb ccccdddd Background tilemap page select
  779. * E84 aaaabbbb ccccdddd Alternate foreground tilemap page select
  780. * E86 aaaabbbb ccccdddd Alternate background tilemap page select
  781. * E90 c------- -------- Foreground tilemap column scroll enable
  782. * -------v vvvvvvvv Foreground tilemap vertical scroll
  783. * E92 c------- -------- Background tilemap column scroll enable
  784. * -------v vvvvvvvv Background tilemap vertical scroll
  785. * E94 -------v vvvvvvvv Alternate foreground tilemap vertical scroll
  786. * E96 -------v vvvvvvvv Alternate background tilemap vertical scroll
  787. * E98 r------- -------- Foreground tilemap row scroll enable
  788. * ------hh hhhhhhhh Foreground tilemap horizontal scroll
  789. * E9A r------- -------- Background tilemap row scroll enable
  790. * ------hh hhhhhhhh Background tilemap horizontal scroll
  791. * E9C ------hh hhhhhhhh Alternate foreground tilemap horizontal scroll
  792. * E9E ------hh hhhhhhhh Alternate background tilemap horizontal scroll
  793. * F16-F3F -------- vvvvvvvv Foreground tilemap per-16-pixel-column vertical scroll
  794. * F56-F7F -------- vvvvvvvv Background tilemap per-16-pixel-column vertical scroll
  795. * F80-FB7 a------- -------- Foreground tilemap per-8-pixel-row alternate tilemap enable
  796. * -------h hhhhhhhh Foreground tilemap per-8-pixel-row horizontal scroll
  797. * FC0-FF7 a------- -------- Background tilemap per-8-pixel-row alternate tilemap enable
  798. * -------h hhhhhhhh Background tilemap per-8-pixel-row horizontal scroll
  799. *
  800. *******************************************************************************************/
  801. static TILE_GET_INFO( segaic16_tilemap_16b_tile_info )
  802. {
  803. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  804. UINT16 data = info->rambase[tile_index];
  805. int color = (data >> 6) & 0x7f;
  806. int code = data & 0x1fff;
  807. code = info->bank[code / info->banksize] * info->banksize + code % info->banksize;
  808. SET_TILE_INFO(0, code, color, 0);
  809. tileinfo->category = (data >> 15) & 1;
  810. }
  811. static TILE_GET_INFO( segaic16_tilemap_16b_text_info )
  812. {
  813. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  814. UINT16 data = info->rambase[tile_index];
  815. int bank = info->bank[0];
  816. int color = (data >> 9) & 0x07;
  817. int code = data & 0x1ff;
  818. SET_TILE_INFO(0, bank * info->banksize + code, color, 0);
  819. tileinfo->category = (data >> 15) & 1;
  820. }
  821. static TILE_GET_INFO( segaic16_tilemap_16b_alt_tile_info )
  822. {
  823. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  824. UINT16 data = info->rambase[tile_index];
  825. int color = (data >> 5) & 0x7f;
  826. int code = data & 0x1fff;
  827. code = info->bank[code / info->banksize] * info->banksize + code % info->banksize;
  828. SET_TILE_INFO(0, code, color, 0);
  829. tileinfo->category = (data >> 15) & 1;
  830. }
  831. static TILE_GET_INFO( segaic16_tilemap_16b_alt_text_info )
  832. {
  833. const struct tilemap_callback_info *info = (const struct tilemap_callback_info *)param;
  834. UINT16 data = info->rambase[tile_index];
  835. int bank = info->bank[0];
  836. int color = (data >> 8) & 0x07;
  837. int code = data & 0xff;
  838. SET_TILE_INFO(0, bank * info->banksize + code, color, 0);
  839. tileinfo->category = (data >> 15) & 1;
  840. }
  841. 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)
  842. {
  843. UINT16 *textram = info->textram;
  844. UINT16 xscroll, yscroll, pages;
  845. int x, y;
  846. /* get global values */
  847. xscroll = info->latched_xscroll[which];
  848. yscroll = info->latched_yscroll[which];
  849. pages = info->latched_pageselect[which];
  850. /* column scroll? */
  851. if (yscroll & 0x8000)
  852. {
  853. if (PRINT_UNUSUAL_MODES) mame_printf_debug("Column AND row scroll\n");
  854. /* loop over row chunks */
  855. for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
  856. {
  857. int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
  858. rectangle rowcolclip;
  859. /* adjust to clip this row only */
  860. rowcolclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
  861. rowcolclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
  862. /* loop over column chunks */
  863. for (x = ((cliprect->min_x + 8) & ~15) - 8; x <= cliprect->max_x; x += 16)
  864. {
  865. UINT16 effxscroll, effyscroll, rowscroll;
  866. UINT16 effpages = pages;
  867. /* adjust to clip this column only */
  868. rowcolclip.min_x = (x < cliprect->min_x) ? cliprect->min_x : x;
  869. rowcolclip.max_x = (x + 15 > cliprect->max_x) ? cliprect->max_x : x + 15;
  870. /* get the effective scroll values */
  871. rowscroll = textram[0xf80/2 + 0x40/2 * which + rowscrollindex];
  872. effxscroll = (xscroll & 0x8000) ? rowscroll : xscroll;
  873. effyscroll = textram[0xf16/2 + 0x40/2 * which + (x+8)/16];
  874. /* are we using an alternate? */
  875. if (rowscroll & 0x8000)
  876. {
  877. effxscroll = info->latched_xscroll[which + 2];
  878. effyscroll = info->latched_yscroll[which + 2];
  879. effpages = info->latched_pageselect[which + 2];
  880. }
  881. /* draw the chunk */
  882. effxscroll = (0xc0 - effxscroll + info->xoffs) & 0x3ff;
  883. effyscroll = effyscroll & 0x1ff;
  884. segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowcolclip, effpages, effxscroll, effyscroll, flags, priority);
  885. }
  886. }
  887. }
  888. else
  889. {
  890. if (PRINT_UNUSUAL_MODES) mame_printf_debug("Row scroll\n");
  891. /* loop over row chunks */
  892. for (y = cliprect->min_y & ~7; y <= cliprect->max_y; y += 8)
  893. {
  894. int rowscrollindex = (info->flip ? (216 - y) : y) / 8;
  895. rectangle rowclip = *cliprect;
  896. UINT16 effxscroll, effyscroll, rowscroll;
  897. UINT16 effpages = pages;
  898. /* adjust to clip this row only */
  899. rowclip.min_y = (y < cliprect->min_y) ? cliprect->min_y : y;
  900. rowclip.max_y = (y + 7 > cliprect->max_y) ? cliprect->max_y : y + 7;
  901. /* get the effective scroll values */
  902. rowscroll = textram[0xf80/2 + 0x40/2 * which + rowscrollindex];
  903. effxscroll = (xscroll & 0x8000) ? rowscroll : xscroll;
  904. effyscroll = yscroll;
  905. /* are we using an alternate? */
  906. if (rowscroll & 0x8000)
  907. {
  908. effxscroll = info->latched_xscroll[which + 2];
  909. effyscroll = info->latched_yscroll[which + 2];
  910. effpages = info->latched_pageselect[which + 2];
  911. }
  912. /* draw the chunk */
  913. effxscroll = (0xc0 - effxscroll + info->xoffs) & 0x3ff;
  914. effyscroll = effyscroll & 0x1ff;
  915. segaic16_draw_virtual_tilemap(machine, info, bitmap, &rowclip, effpages, effxscroll, effyscroll, flags, priority);
  916. }
  917. }
  918. }
  919. static TIMER_CALLBACK( segaic16_tilemap_16b_latch_values )
  920. {
  921. struct tilemap_info *info = &bg_tilemap[param];
  922. UINT16 *textram = info->textram;
  923. int i;
  924. /* latch the scroll and page select values */
  925. for (i = 0; i < 4; i++)
  926. {
  927. info->latched_pageselect[i] = textram[0xe80/2 + i];
  928. info->latched_yscroll[i] = textram[0xe90/2 + i];
  929. info->latched_xscroll[i] = textram[0xe98/2 + i];
  930. }
  931. /* set a timer to do this again next frame */
  932. //timer_set(machine, machine->primary_screen->time_until_pos(261), NULL, param, segaic16_tilemap_16b_latch_values);
  933. timer_adjust_oneshot(info->latch_timer,machine->primary_screen->time_until_pos(261),param);
  934. }
  935. static void segaic16_tilemap_16b_reset(running_machine *machine, struct tilemap_info *info)
  936. {
  937. /* set a timer to latch values on scanline 261 */
  938. //timer_set(machine, machine->primary_screen->time_until_pos(261), NULL, info->index, segaic16_tilemap_16b_latch_values);
  939. timer_adjust_oneshot(info->latch_timer,machine->primary_screen->time_until_pos(261),info->index);
  940. }
  941. /*************************************
  942. *
  943. * General tilemap initialization
  944. *
  945. *************************************/
  946. void segaic16_tilemap_init(running_machine *machine, int which, int type, int colorbase, int xoffs, int numbanks)
  947. {
  948. struct tilemap_info *info = &bg_tilemap[which];
  949. tile_get_info_func get_text_info;
  950. tile_get_info_func get_tile_info;
  951. int pagenum;
  952. int i;
  953. /* reset the tilemap info */
  954. memset(info, 0, sizeof(*info));
  955. info->index = which;
  956. info->type = type;
  957. for (i = 0; i < numbanks; i++)
  958. info->bank[i] = i;
  959. info->banksize = 0x2000 / numbanks;
  960. info->xoffs = xoffs;
  961. /* set up based on which tilemap */
  962. switch (which)
  963. {
  964. case 0:
  965. info->textram = segaic16_textram_0;
  966. info->tileram = segaic16_tileram_0;
  967. break;
  968. default:
  969. fatalerror("Invalid tilemap index specified in segaic16_tilemap_init");
  970. }
  971. /* determine the parameters of the tilemaps */
  972. switch (type)
  973. {
  974. case SEGAIC16_TILEMAP_HANGON:
  975. get_text_info = segaic16_tilemap_16a_text_info;
  976. get_tile_info = segaic16_tilemap_16a_tile_info;
  977. info->numpages = 4;
  978. info->draw_layer = segaic16_tilemap_16a_draw_layer;
  979. info->reset = NULL;
  980. info->latch_timer = NULL;
  981. break;
  982. case SEGAIC16_TILEMAP_16A:
  983. get_text_info = segaic16_tilemap_16a_text_info;
  984. get_tile_info = segaic16_tilemap_16a_tile_info;
  985. info->numpages = 8;
  986. info->draw_layer = segaic16_tilemap_16a_draw_layer;
  987. info->reset = NULL;
  988. info->latch_timer = NULL;
  989. break;
  990. case SEGAIC16_TILEMAP_16B:
  991. get_text_info = segaic16_tilemap_16b_text_info;
  992. get_tile_info = segaic16_tilemap_16b_tile_info;
  993. info->numpages = 16;
  994. info->draw_layer = segaic16_tilemap_16b_draw_layer;
  995. info->reset = segaic16_tilemap_16b_reset;
  996. //DAV FIX
  997. info->latch_timer = timer_alloc(machine,segaic16_tilemap_16b_latch_values,NULL);
  998. break;
  999. case SEGAIC16_TILEMAP_16B_ALT:
  1000. get_text_info = segaic16_tilemap_16b_alt_text_info;
  1001. get_tile_info = segaic16_tilemap_16b_alt_tile_info;
  1002. info->numpages = 16;
  1003. info->draw_layer = segaic16_tilemap_16b_draw_layer;
  1004. info->reset = segaic16_tilemap_16b_reset;
  1005. //DAV FIX
  1006. info->latch_timer = timer_alloc(machine,segaic16_tilemap_16b_latch_values,NULL);
  1007. break;
  1008. default:
  1009. fatalerror("Invalid tilemap type specified in segaic16_tilemap_init");
  1010. }
  1011. /* create the tilemap for the text layer */
  1012. info->textmap = tilemap_create(machine, get_text_info, tilemap_scan_rows, 8,8, 64,28);
  1013. /* configure it */
  1014. info->textmap_info.rambase = info->textram;
  1015. info->textmap_info.bank = info->bank;
  1016. info->textmap_info.banksize = info->banksize;
  1017. tilemap_set_user_data(info->textmap, &info->textmap_info);
  1018. tilemap_set_palette_offset(info->textmap, colorbase);
  1019. tilemap_set_transparent_pen(info->textmap, 0);
  1020. tilemap_set_scrolldx(info->textmap, -192 + xoffs, -170 + xoffs);
  1021. tilemap_set_scrolldy(info->textmap, 0, 38);
  1022. /* create the tilemaps for the tile pages */
  1023. for (pagenum = 0; pagenum < info->numpages; pagenum++)
  1024. {
  1025. /* each page is 64x32 */
  1026. info->tilemaps[pagenum] = tilemap_create(machine, get_tile_info, tilemap_scan_rows, 8,8, 64,32);
  1027. /* configure the tilemap */
  1028. info->tmap_info[pagenum].rambase = info->tileram + pagenum * 64*32;
  1029. info->tmap_info[pagenum].bank = info->bank;
  1030. info->tmap_info[pagenum].banksize = info->banksize;
  1031. tilemap_set_user_data(info->tilemaps[pagenum], &info->tmap_info[pagenum]);
  1032. tilemap_set_palette_offset(info->tilemaps[pagenum], colorbase);
  1033. tilemap_set_transparent_pen(info->tilemaps[pagenum], 0);
  1034. tilemap_set_scrolldx(info->tilemaps[pagenum], 0, 22);
  1035. tilemap_set_scrolldy(info->tilemaps[pagenum], 0, 38);
  1036. }
  1037. }
  1038. /*************************************
  1039. *
  1040. * General tilemap rendering
  1041. *
  1042. *************************************/
  1043. void segaic16_tilemap_draw(running_device *screen, bitmap_t *bitmap, const rectangle *cliprect, int which, int map, int priority, int priority_mark)
  1044. {
  1045. running_machine *machine = screen->machine;
  1046. struct tilemap_info *info = &bg_tilemap[which];
  1047. /* text layer is a special common case */
  1048. if (map == SEGAIC16_TILEMAP_TEXT)
  1049. tilemap_draw(bitmap, cliprect, info->textmap, priority, priority_mark);
  1050. /* other layers are handled differently per-system */
  1051. else
  1052. (*info->draw_layer)(machine, info, bitmap, cliprect, map, priority, priority_mark);
  1053. }
  1054. /*************************************
  1055. *
  1056. * General tilemap reset
  1057. *
  1058. *************************************/
  1059. void segaic16_tilemap_reset(running_machine *machine, int which)
  1060. {
  1061. struct tilemap_info *info = &bg_tilemap[which];
  1062. if (info->reset)
  1063. (*info->reset)(machine, info);
  1064. }
  1065. /*************************************
  1066. *
  1067. * General tilemap banking
  1068. *
  1069. *************************************/
  1070. void segaic16_tilemap_set_bank(running_machine *machine, int which, int banknum, int offset)
  1071. {
  1072. struct tilemap_info *info = &bg_tilemap[which];
  1073. if (info->bank[banknum] != offset)
  1074. {
  1075. screen_device *screen = machine->primary_screen;
  1076. screen->update_partial(screen->vpos());
  1077. info->bank[banknum] = offset;
  1078. tilemap_mark_all_tiles_dirty_all(machine);
  1079. }
  1080. }
  1081. /*************************************
  1082. *
  1083. * General tilemap screen flipping
  1084. *
  1085. *************************************/
  1086. void segaic16_tilemap_set_flip(running_machine *machine, int which, int flip)
  1087. {
  1088. struct tilemap_info *info = &bg_tilemap[which];
  1089. int pagenum;
  1090. flip = (flip != 0);
  1091. if (info->flip != flip)
  1092. {
  1093. screen_device *screen = machine->primary_screen;
  1094. screen->update_partial(screen->vpos());
  1095. info->flip = flip;
  1096. tilemap_set_flip(info->textmap, flip ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
  1097. for (pagenum = 0; pagenum < info->numpages; pagenum++)
  1098. tilemap_set_flip(info->tilemaps[pagenum], flip ? (TILEMAP_FLIPX | TILEMAP_FLIPY) : 0);
  1099. }
  1100. }
  1101. /*************************************
  1102. *
  1103. * General tilemap row scroll enable
  1104. *
  1105. *************************************/
  1106. void segaic16_tilemap_set_rowscroll(running_machine *machine, int which, int enable)
  1107. {
  1108. struct tilemap_info *info = &bg_tilemap[which];
  1109. enable = (enable != 0);
  1110. if (info->rowscroll != enable)
  1111. {
  1112. screen_device *screen = machine->primary_screen;
  1113. screen->update_partial(screen->vpos());
  1114. info->rowscroll = enable;
  1115. }
  1116. }
  1117. /*************************************
  1118. *
  1119. * General tilemap column scroll enable
  1120. *
  1121. *************************************/
  1122. void segaic16_tilemap_set_colscroll(running_machine *machine, int which, int enable)
  1123. {
  1124. struct tilemap_info *info = &bg_tilemap[which];
  1125. enable = (enable != 0);
  1126. if (info->colscroll != enable)
  1127. {
  1128. screen_device *screen = machine->primary_screen;
  1129. screen->update_partial(screen->vpos());
  1130. info->colscroll = enable;
  1131. }
  1132. }
  1133. /*************************************
  1134. *
  1135. * General tilemap write handlers
  1136. *
  1137. *************************************/
  1138. WRITE16_HANDLER( segaic16_tileram_0_w )
  1139. {
  1140. COMBINE_DATA(&segaic16_tileram_0[offset]);
  1141. tilemap_mark_tile_dirty(bg_tilemap[0].tilemaps[offset / (64*32)], offset % (64*32));
  1142. }
  1143. WRITE16_HANDLER( segaic16_textram_0_w )
  1144. {
  1145. /* certain ranges need immediate updates */
  1146. if (offset >= 0xe80/2)
  1147. space->machine->primary_screen->update_partial(space->machine->primary_screen->vpos());
  1148. COMBINE_DATA(&segaic16_textram_0[offset]);
  1149. tilemap_mark_tile_dirty(bg_tilemap[0].textmap, offset);
  1150. }
  1151. /*******************************************************************************************
  1152. *
  1153. * Hang On/Space Harrier-style road chip
  1154. *
  1155. * Road RAM:
  1156. * Offset Bits Usage
  1157. * 000-1FF ----pp-- -------- road priority versus tilemaps and sprites
  1158. * ------s- -------- (Hang On only) Stripe coloring enable (1=enable)
  1159. * ------s- -------- (Space Harrier only) Solid color fill (1=solid, 0=from ROM)
  1160. * -------m -------- mirror enable (1=enable)
  1161. * -------- iiiiiiii index for other tables
  1162. * -------- rrrrrrrr road ROM line select
  1163. * 200-3FF ----hhhh hhhhhhhh horizontal scroll
  1164. * 400-5FF --bbbbbb -------- background color (colorset 0)
  1165. * -------- --bbbbbb background color (colorset 1)
  1166. * 600-7FF -------- s------- stripe color index (colorset 1)
  1167. * -------- -s------ stripe color index (colorset 0)
  1168. * -------- --a----- pixel value 2 color index (colorset 1)
  1169. * -------- ---a---- pixel value 2 color index (colorset 0)
  1170. * -------- ----b--- pixel value 1 color index (colorset 1)
  1171. * -------- -----b-- pixel value 1 color index (colorset 0)
  1172. * -------- ------c- pixel value 0 color index (colorset 1)
  1173. * -------- -------c pixel value 0 color index (colorset 0)
  1174. *
  1175. * Logic:
  1176. * First, the scanline is used to index into the table at 000-1FF
  1177. *
  1178. * The index is taken from the low 8 bits of the table value from 000-1FF
  1179. *
  1180. * The horizontal scroll value is looked up using the index in the table at
  1181. * 200-3FF
  1182. *
  1183. * The background color information is looked up using the index in the table at 400-5FF.
  1184. *
  1185. * The pixel color information is looked up using the index in the table at 600-7FF.
  1186. *
  1187. *******************************************************************************************/
  1188. static void segaic16_road_hangon_decode(running_machine *machine, struct road_info *info)
  1189. {
  1190. int x, y;
  1191. const UINT8 *gfx = memory_region(machine, "gfx3");
  1192. int len = memory_region_length(machine, "gfx3");
  1193. /* allocate memory for the unpacked road data */
  1194. info->gfx = auto_alloc_array(machine, UINT8, 256 * 512);
  1195. /* loop over rows */
  1196. for (y = 0; y < 256; y++)
  1197. {
  1198. const UINT8 *src = gfx + ((y & 0xff) * 0x40) % len;
  1199. UINT8 *dst = info->gfx + y * 512;
  1200. /* loop over columns */
  1201. for (x = 0; x < 512; x++)
  1202. dst[x] = (((src[x/8] >> (~x & 7)) & 1) << 0) | (((src[x/8 + 0x4000] >> (~x & 7)) & 1) << 1);
  1203. }
  1204. }
  1205. static void segaic16_road_hangon_draw(struct road_info *info, bitmap_t *bitmap, const rectangle *cliprect, int priority)
  1206. {
  1207. UINT16 *roadram = info->roadram;
  1208. int x, y;
  1209. /* loop over scanlines */
  1210. for (y = cliprect->min_y; y <= cliprect->max_y; y++)
  1211. {
  1212. UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
  1213. int control = roadram[0x000 + y];
  1214. int hpos = roadram[0x100 + (control & 0xff)];
  1215. int color0 = roadram[0x200 + (control & 0xff)];
  1216. int color1 = roadram[0x300 + (control & 0xff)];
  1217. int ff9j1, ff9j2, ctr9m, ctr9n9p, ctr9n9p_ena, ss8j, plycont;
  1218. UINT8 *src;
  1219. /* the PLYCONT signal controls the road layering */
  1220. plycont = (control >> 10) & 3;
  1221. /* skip layers we aren't supposed to be drawing */
  1222. if ((plycont == 0 && priority != SEGAIC16_ROAD_BACKGROUND) ||
  1223. (plycont != 0 && priority != SEGAIC16_ROAD_FOREGROUND))
  1224. continue;
  1225. /* compute the offset of the road graphics for this line */
  1226. src = info->gfx + (0x000 + (control & 0xff)) * 512;
  1227. /* initialize the 4-bit counter at 9M, which counts bits within each road byte */
  1228. ctr9m = hpos & 7;
  1229. /* initialize the two 4-bit counters at 9P (low) and 9N (high), which count road data bytes */
  1230. ctr9n9p = (hpos >> 3) & 0xff;
  1231. /* initialize the flip-flop at 9J (lower half), which controls the counting direction */
  1232. ff9j1 = (hpos >> 11) & 1;
  1233. /* initialize the flip-flop at 9J (upper half), which controls the background color */
  1234. ff9j2 = 1;
  1235. /* initialize the serial shifter at 8S, which delays several signals after we flip */
  1236. ss8j = 0;
  1237. /* draw this scanline from the beginning */
  1238. for (x = -24; x <= cliprect->max_x; x++)
  1239. {
  1240. int md, color, select;
  1241. /* ---- the following logic all happens constantly ---- */
  1242. /* the enable is controlled by the value in the counter at 9M */
  1243. ctr9n9p_ena = (ctr9m == 7);
  1244. /* if we carried out of the 9P/9N counters, we will forcibly clear the flip-flop at 9J (lower half) */
  1245. if ((ctr9n9p & 0xff) == 0xff)
  1246. ff9j1 = 0;
  1247. /* if the control word bit 8 is clear, we will forcibly set the flip-flop at 9J (lower half) */
  1248. if (!(control & 0x100))
  1249. ff9j1 = 1;
  1250. /* for the Hang On/Super Hang On case only: if the control word bit 9 is clear, we will forcibly */
  1251. /* set the flip-flip at 9J (upper half) */
  1252. if (info->type == SEGAIC16_ROAD_HANGON && !(control & 0x200))
  1253. ff9j2 = 1;
  1254. /* ---- now process the pixel ---- */
  1255. md = 3;
  1256. /* the Space Harrier/Enduro Racer hardware has a tweak that maps the control word bit 9 to the */
  1257. /* /CE line on the road ROM; use this to effectively disable the road data */
  1258. if (info->type != SEGAIC16_ROAD_SHARRIER || !(control & 0x200))
  1259. /* the /OE line on the road ROM is linked to the AND of bits 2 & 3 of the counter at 9N */
  1260. if ((ctr9n9p & 0xc0) == 0xc0)
  1261. {
  1262. /* note that the pixel logic is hidden in a custom at 9S; this is just a guess */
  1263. if (ss8j & 1)
  1264. md = src[((ctr9n9p & 0x3f) << 3) | ctr9m];
  1265. else
  1266. md = src[((ctr9n9p & 0x3f) << 3) | (ctr9m ^ 7)];
  1267. }
  1268. /* "select" is a made-up signal that comes from bit 3 of the serial shifter and is */
  1269. /* used in several places for color selection */
  1270. select = (ss8j >> 3) & 1;
  1271. /* check the flip-flop at 9J (upper half) to determine if we should use the background color; */
  1272. /* the output of this is ANDed with M0 and M1 so it only affects pixels with a value of 3; */
  1273. /* this is done by the AND gates at 9L and 7K */
  1274. if (ff9j2 && md == 3)
  1275. {
  1276. /* in this case, the "select" signal is used to select which background color to use */
  1277. /* since the color0 control word contains two selections */
  1278. color = (color0 >> (select ? 0 : 8)) & 0x3f;
  1279. color |= info->colorbase2;
  1280. }
  1281. /* if we're not using the background color, we select pixel data from an alternate path */
  1282. else
  1283. {
  1284. /* the AND gates at 7L, 9K, and 7K clamp the pixel value to 0 if bit 7 of the color 1 */
  1285. /* signal is 1 and if the pixel value is 3 (both M0 and M1 == 1) */
  1286. if ((color1 & 0x80) && md == 3)
  1287. md = 0;
  1288. /* the pixel value plus the "select" line combine to form a mux into the low 8 bits of color1 */
  1289. color = (color1 >> ((md << 1) | select)) & 1;
  1290. /* this value becomes the low bit of the final color; the "select" line itself and the pixel */
  1291. /* value form the other bits */
  1292. color |= select << 3;
  1293. color |= md << 1;
  1294. color |= info->colorbase1;
  1295. }
  1296. /* write the pixel if we're past the minimum clip */
  1297. if (x >= cliprect->min_x)
  1298. dest[x] = color;
  1299. /* ---- the following logic all happens on the 6M clock ---- */
  1300. /* clock the counter at 9M */
  1301. ctr9m = (ctr9m + 1) & 7;
  1302. /* if enabled, clock on the two cascaded 4-bit counters at 9P and 9N */
  1303. if (ctr9n9p_ena)
  1304. {
  1305. if (ff9j1)
  1306. ctr9n9p++;
  1307. else
  1308. ctr9n9p--;
  1309. }
  1310. /* clock the flip-flop at 9J (upper half) */
  1311. ff9j2 = !(!ff9j1 && (ss8j & 0x80));
  1312. /* clock the serial shift register at 8J */
  1313. ss8j = (ss8j << 1) | ff9j1;
  1314. }
  1315. }
  1316. }
  1317. /*******************************************************************************************
  1318. *
  1319. * Out Run/X-Board-style road chip
  1320. *
  1321. * Road control register:
  1322. * Bits Usage
  1323. * -------- -----d-- (X-board only) Direct scanline mode (1) or indirect mode (0)
  1324. * -------- ------pp Road enable/priorities:
  1325. * 0 = road 0 only visible
  1326. * 1 = both roads visible, road 0 has priority
  1327. * 2 = both roads visible, road 1 has priority
  1328. * 3 = road 1 only visible
  1329. *
  1330. * Road RAM:
  1331. * Offset Bits Usage
  1332. * 000-1FF ----s--- -------- Road 0: Solid fill (1) or ROM fill
  1333. * -------- -ccccccc Road 0: Solid color (if solid fill)
  1334. * -------i iiiiiiii Road 0: Index for other tables (if in indirect mode)
  1335. * -------r rrrrrrr- Road 0: Road ROM line select
  1336. * 200-3FF ----s--- -------- Road 1: Solid fill (1) or ROM fill
  1337. * -------- -ccccccc Road 1: Solid color (if solid fill)
  1338. * -------i iiiiiiii Road 1: Index for other tables (if in indirect mode)
  1339. * -------r rrrrrrr- Road 1: Road ROM line select
  1340. * 400-7FF ----hhhh hhhhhhhh Road 0: horizontal scroll
  1341. * 800-BFF ----hhhh hhhhhhhh Road 1: horizontal scroll
  1342. * C00-FFF ----bbbb -------- Background color index
  1343. * -------- s------- Road 1: stripe color index
  1344. * -------- -a------ Road 1: pixel value 2 color index
  1345. * -------- --b----- Road 1: pixel value 1 color index
  1346. * -------- ---c---- Road 1: pixel value 0 color index
  1347. * -------- ----s--- Road 0: stripe color index
  1348. * -------- -----a-- Road 0: pixel value 2 color index
  1349. * -------- ------b- Road 0: pixel value 1 color index
  1350. * -------- -------c Road 0: pixel value 0 color index
  1351. *
  1352. * Logic:
  1353. * First, the scanline is used to index into the tables at 000-1FF/200-3FF
  1354. * - if solid fill, the background is filled with the specified color index
  1355. * - otherwise, the remaining tables are used
  1356. *
  1357. * If indirect mode is selected, the index is taken from the low 9 bits of the
  1358. * table value from 000-1FF/200-3FF
  1359. * If direct scanline mode is selected, the index is set equal to the scanline
  1360. * for road 0, or the scanline + 256 for road 1
  1361. *
  1362. * The horizontal scroll value is looked up using the index in the tables at
  1363. * 400-7FF/800-BFF
  1364. *
  1365. * The color information is looked up using the index in the table at C00-FFF. Note
  1366. * that the same table is used for both roads.
  1367. *
  1368. *
  1369. * Out Run road priorities are controlled by a PAL that maps as indicated below.
  1370. * This was used to generate the priority_map. It is assumed that X-board is the
  1371. * same, though this logic is locked inside a Sega custom.
  1372. *
  1373. * RRC0 = CENTA & (RDA == 3) & !RRC2
  1374. * | CENTB & (RDB == 3) & RRC2
  1375. * | (RDA == 1) & !RRC2
  1376. * | (RDB == 1) & RRC2
  1377. *
  1378. * RRC1 = CENTA & (RDA == 3) & !RRC2
  1379. * | CENTB & (RDB == 3) & RRC2
  1380. * | (RDA == 2) & !RRC2
  1381. * | (RDB == 2) & RRC2
  1382. *
  1383. * RRC2 = !/HSYNC & IIQ
  1384. * | (CTRL == 3)
  1385. * | !CENTA & (RDA == 3) & !CENTB & (RDB == 3) & (CTRL == 2)
  1386. * | CENTB & (RDB == 3) & (CTRL == 2)
  1387. * | !CENTA & (RDA == 3) & !M2 & (CTRL == 2)
  1388. * | !CENTA & (RDA == 3) & !M3 & (CTRL == 2)
  1389. * | !M0 & (RDB == 0) & (CTRL == 2)
  1390. * | !M1 & (RDB == 0) & (CTRL == 2)
  1391. * | !CENTA & (RDA == 3) & CENTB & (RDB == 3) & (CTRL == 1)
  1392. * | !M0 & CENTB & (RDB == 3) & (CTRL == 1)
  1393. * | !M1 & CENTB & (RDB == 3) & (CTRL == 1)
  1394. * | !CENTA & M0 & (RDB == 0) & (CTRL == 1)
  1395. * | !CENTA & M1 & (RDB == 0) & (CTRL == 1)
  1396. * | !CENTA & (RDA == 3) & (RDB == 1) & (CTRL == 1)
  1397. * | !CENTA & (RDA == 3) & (RDB == 2) & (CTRL == 1)
  1398. *
  1399. * RRC3 = VA11 & VB11
  1400. * | VA11 & (CTRL == 0)
  1401. * | (CTRL == 3) & VB11
  1402. *
  1403. * RRC4 = !CENTA & (RDA == 3) & !CENTB & (RDB == 3)
  1404. * | VA11 & VB11
  1405. * | VA11 & (CTRL == 0)
  1406. * | (CTRL == 3) & VB11
  1407. * | !CENTB & (RDB == 3) & (CTRL == 3)
  1408. * | !CENTA & (RDA == 3) & (CTRL == 0)
  1409. *
  1410. *******************************************************************************************/
  1411. static void segaic16_road_outrun_decode(running_machine *machine, struct road_info *info)
  1412. {
  1413. int x, y;
  1414. const UINT8 *gfx = memory_region(machine, "gfx3");
  1415. int len = memory_region_length(machine, "gfx3");
  1416. /* allocate memory for the unpacked road data */
  1417. info->gfx = auto_alloc_array(machine, UINT8, (256 * 2 + 1) * 512);
  1418. /* loop over rows */
  1419. for (y = 0; y < 256 * 2; y++)
  1420. {
  1421. const UINT8 *src = gfx + ((y & 0xff) * 0x40 + (y >> 8) * 0x8000) % len;
  1422. UINT8 *dst = info->gfx + y * 512;
  1423. /* loop over columns */
  1424. for (x = 0; x < 512; x++)
  1425. {
  1426. dst[x] = (((src[x/8] >> (~x & 7)) & 1) << 0) | (((src[x/8 + 0x4000] >> (~x & 7)) & 1) << 1);
  1427. /* pre-mark road data in the "stripe" area with a high bit */
  1428. if (x >= 256-8 && x < 256 && dst[x] == 3)
  1429. dst[x] |= 4;
  1430. }
  1431. }
  1432. /* set up a dummy road in the last entry */
  1433. memset(info->gfx + 256 * 2 * 512, 3, 512);
  1434. }
  1435. static void segaic16_road_outrun_draw(struct road_info *info, bitmap_t *bitmap, const rectangle *cliprect, int priority)
  1436. {
  1437. UINT16 *roadram = info->buffer;
  1438. int x, y;
  1439. /* loop over scanlines */
  1440. for (y = cliprect->min_y; y <= cliprect->max_y; y++)
  1441. {
  1442. static const UINT8 priority_map[2][8] =
  1443. {
  1444. { 0x80,0x81,0x81,0x87,0,0,0,0x00 },
  1445. { 0x81,0x81,0x81,0x8f,0,0,0,0x80 }
  1446. //
  1447. // Original guesses from X-board priorities:
  1448. // { 0x80,0x81,0x81,0x83,0,0,0,0x00 },
  1449. // { 0x81,0x87,0x87,0x8f,0,0,0,0x00 }
  1450. };
  1451. UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
  1452. int data0 = roadram[0x000 + y];
  1453. int data1 = roadram[0x100 + y];
  1454. /* background case: look for solid fill scanlines */
  1455. if (priority == SEGAIC16_ROAD_BACKGROUND)
  1456. {
  1457. int color = -1;
  1458. /* based on the info->control, we can figure out which sky to draw */
  1459. switch (info->control & 3)
  1460. {
  1461. case 0:
  1462. if (data0 & 0x800)
  1463. color = data0 & 0x7f;
  1464. break;
  1465. case 1:
  1466. if (data0 & 0x800)
  1467. color = data0 & 0x7f;
  1468. else if (data1 & 0x800)
  1469. color = data1 & 0x7f;
  1470. break;
  1471. case 2:
  1472. if (data1 & 0x800)
  1473. color = data1 & 0x7f;
  1474. else if (data0 & 0x800)
  1475. color = data0 & 0x7f;
  1476. break;
  1477. case 3:
  1478. if (data1 & 0x800)
  1479. color = data1 & 0x7f;
  1480. break;
  1481. }
  1482. /* fill the scanline with color */
  1483. if (color != -1)
  1484. {
  1485. color |= info->colorbase3;
  1486. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1487. dest[x] = color;
  1488. }
  1489. }
  1490. /* foreground case: render from ROM */
  1491. else
  1492. {
  1493. int hpos0, hpos1, color0, color1;
  1494. int control = info->control & 3;
  1495. UINT16 color_table[32];
  1496. UINT8 *src0, *src1;
  1497. UINT8 bgcolor;
  1498. /* if both roads are low priority, skip */
  1499. if ((data0 & 0x800) && (data1 & 0x800))
  1500. continue;
  1501. /* get road 0 data */
  1502. src0 = (data0 & 0x800) ? info->gfx + 256 * 2 * 512 : (info->gfx + (0x000 + ((data0 >> 1) & 0xff)) * 512);
  1503. hpos0 = (roadram[0x200 + ((info->control & 4) ? y : (data0 & 0x1ff))]) & 0xfff;
  1504. color0 = roadram[0x600 + ((info->control & 4) ? y : (data0 & 0x1ff))];
  1505. /* get road 1 data */
  1506. src1 = (data1 & 0x800) ? info->gfx + 256 * 2 * 512 : (info->gfx + (0x100 + ((data1 >> 1) & 0xff)) * 512);
  1507. hpos1 = (roadram[0x400 + ((info->control & 4) ? (0x100 + y) : (data1 & 0x1ff))]) & 0xfff;
  1508. color1 = roadram[0x600 + ((info->control & 4) ? (0x100 + y) : (data1 & 0x1ff))];
  1509. /* determine the 5 colors for road 0 */
  1510. color_table[0x00] = info->colorbase1 ^ 0x00 ^ ((color0 >> 0) & 1);
  1511. color_table[0x01] = info->colorbase1 ^ 0x02 ^ ((color0 >> 1) & 1);
  1512. color_table[0x02] = info->colorbase1 ^ 0x04 ^ ((color0 >> 2) & 1);
  1513. bgcolor = (color0 >> 8) & 0xf;
  1514. color_table[0x03] = (data0 & 0x200) ? color_table[0x00] : (info->colorbase2 ^ 0x00 ^ bgcolor);
  1515. color_table[0x07] = info->colorbase1 ^ 0x06 ^ ((color0 >> 3) & 1);
  1516. /* determine the 5 colors for road 1 */
  1517. color_table[0x10] = info->colorbase1 ^ 0x08 ^ ((color1 >> 4) & 1);
  1518. color_table[0x11] = info->colorbase1 ^ 0x0a ^ ((color1 >> 5) & 1);
  1519. color_table[0x12] = info->colorbase1 ^ 0x0c ^ ((color1 >> 6) & 1);
  1520. bgcolor = (color1 >> 8) & 0xf;
  1521. color_table[0x13] = (data1 & 0x200) ? color_table[0x10] : (info->colorbase2 ^ 0x10 ^ bgcolor);
  1522. color_table[0x17] = info->colorbase1 ^ 0x0e ^ ((color1 >> 7) & 1);
  1523. /* draw the road */
  1524. switch (control)
  1525. {
  1526. case 0:
  1527. if (data0 & 0x800)
  1528. continue;
  1529. hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
  1530. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1531. {
  1532. int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
  1533. dest[x] = color_table[0x00 + pix0];
  1534. hpos0 = (hpos0 + 1) & 0xfff;
  1535. }
  1536. break;
  1537. case 1:
  1538. hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
  1539. hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
  1540. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1541. {
  1542. int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
  1543. int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
  1544. if ((priority_map[0][pix0] >> pix1) & 1)
  1545. dest[x] = color_table[0x10 + pix1];
  1546. else
  1547. dest[x] = color_table[0x00 + pix0];
  1548. hpos0 = (hpos0 + 1) & 0xfff;
  1549. hpos1 = (hpos1 + 1) & 0xfff;
  1550. }
  1551. break;
  1552. case 2:
  1553. hpos0 = (hpos0 - (0x5f8 + info->xoffs)) & 0xfff;
  1554. hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
  1555. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1556. {
  1557. int pix0 = (hpos0 < 0x200) ? src0[hpos0] : 3;
  1558. int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
  1559. if ((priority_map[1][pix0] >> pix1) & 1)
  1560. dest[x] = color_table[0x10 + pix1];
  1561. else
  1562. dest[x] = color_table[0x00 + pix0];
  1563. hpos0 = (hpos0 + 1) & 0xfff;
  1564. hpos1 = (hpos1 + 1) & 0xfff;
  1565. }
  1566. break;
  1567. case 3:
  1568. if (data1 & 0x800)
  1569. continue;
  1570. hpos1 = (hpos1 - (0x5f8 + info->xoffs)) & 0xfff;
  1571. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1572. {
  1573. int pix1 = (hpos1 < 0x200) ? src1[hpos1] : 3;
  1574. dest[x] = color_table[0x10 + pix1];
  1575. hpos1 = (hpos1 + 1) & 0xfff;
  1576. }
  1577. break;
  1578. }
  1579. }
  1580. }
  1581. }
  1582. /*************************************
  1583. *
  1584. * General road initialization
  1585. *
  1586. *************************************/
  1587. void segaic16_road_init(running_machine *machine, int which, int type, int colorbase1, int colorbase2, int colorbase3, int xoffs)
  1588. {
  1589. struct road_info *info = &segaic16_road[which];
  1590. /* reset the tilemap info */
  1591. memset(info, 0, sizeof(*info));
  1592. info->index = which;
  1593. info->type = type;
  1594. info->colorbase1 = colorbase1;
  1595. info->colorbase2 = colorbase2;
  1596. info->colorbase3 = colorbase3;
  1597. info->xoffs = xoffs;
  1598. /* set up based on which road generator */
  1599. switch (which)
  1600. {
  1601. case 0:
  1602. info->roadram = segaic16_roadram_0;
  1603. break;
  1604. default:
  1605. fatalerror("Invalid road index specified in segaic16_road_init");
  1606. }
  1607. /* determine the parameters of the road */
  1608. switch (type)
  1609. {
  1610. case SEGAIC16_ROAD_HANGON:
  1611. case SEGAIC16_ROAD_SHARRIER:
  1612. info->draw = segaic16_road_hangon_draw;
  1613. segaic16_road_hangon_decode(machine, info);
  1614. break;
  1615. case SEGAIC16_ROAD_OUTRUN:
  1616. case SEGAIC16_ROAD_XBOARD:
  1617. info->buffer = auto_alloc_array(machine, UINT16, 0x1000/2);
  1618. info->draw = segaic16_road_outrun_draw;
  1619. segaic16_road_outrun_decode(machine, info);
  1620. break;
  1621. default:
  1622. fatalerror("Invalid road system specified in segaic16_road_init");
  1623. }
  1624. }
  1625. /*************************************
  1626. *
  1627. * General road drawing
  1628. *
  1629. *************************************/
  1630. void segaic16_road_draw(int which, bitmap_t *bitmap, const rectangle *cliprect, int priority)
  1631. {
  1632. struct road_info *info = &segaic16_road[which];
  1633. (*info->draw)(info, bitmap, cliprect, priority);
  1634. }
  1635. /*************************************
  1636. *
  1637. * General road control read/write
  1638. *
  1639. *************************************/
  1640. READ16_HANDLER( segaic16_road_control_0_r )
  1641. {
  1642. struct road_info *info = &segaic16_road[0];
  1643. if (info->buffer)
  1644. {
  1645. UINT32 *src = (UINT32 *)info->roadram;
  1646. UINT32 *dst = (UINT32 *)info->buffer;
  1647. int i;
  1648. /* swap the halves of the road RAM */
  1649. for (i = 0; i < 0x1000/4; i++)
  1650. {
  1651. UINT32 temp = *src;
  1652. *src++ = *dst;
  1653. *dst++ = temp;
  1654. }
  1655. }
  1656. return 0xffff;
  1657. }
  1658. WRITE16_HANDLER( segaic16_road_control_0_w )
  1659. {
  1660. struct road_info *info = &segaic16_road[0];
  1661. if (ACCESSING_BITS_0_7)
  1662. {
  1663. info->control = data & ((info->type == SEGAIC16_ROAD_OUTRUN) ? 3 : 7);
  1664. }
  1665. }
  1666. /*************************************
  1667. *
  1668. * General rotation initialization
  1669. *
  1670. *************************************/
  1671. void segaic16_rotate_init(running_machine *machine, int which, int type, int colorbase)
  1672. {
  1673. struct rotate_info *info = &segaic16_rotate[which];
  1674. /* reset the tilemap info */
  1675. memset(info, 0, sizeof(*info));
  1676. info->index = which;
  1677. info->type = type;
  1678. info->colorbase = colorbase;
  1679. /* set up based on which road generator */
  1680. switch (which)
  1681. {
  1682. case 0:
  1683. info->rotateram = segaic16_rotateram_0;
  1684. break;
  1685. default:
  1686. fatalerror("Invalid rotate index specified in segaic16_rotate_init");
  1687. }
  1688. /* determine the parameters of the rotate */
  1689. switch (type)
  1690. {
  1691. case SEGAIC16_ROTATE_YBOARD:
  1692. info->ramsize = 0x800;
  1693. break;
  1694. default:
  1695. fatalerror("Invalid rotate system specified in segaic16_rotate_init");
  1696. }
  1697. /* allocate a buffer for swapping */
  1698. info->buffer = auto_alloc_array(machine, UINT16, info->ramsize/2);
  1699. state_save_register_item(machine, "segaic16_rot", NULL, which, info->colorbase);
  1700. state_save_register_item_pointer(machine, "segaic16_rot", NULL, which, ((UINT8 *) info->buffer), info->ramsize);
  1701. }
  1702. /*************************************
  1703. *
  1704. * General rotation drawing
  1705. *
  1706. *************************************/
  1707. void segaic16_rotate_draw(running_machine *machine, int which, bitmap_t *bitmap, const rectangle *cliprect, bitmap_t *srcbitmap)
  1708. {
  1709. struct rotate_info *info = &segaic16_rotate[which];
  1710. INT32 currx = (info->buffer[0x3f0] << 16) | info->buffer[0x3f1];
  1711. INT32 curry = (info->buffer[0x3f2] << 16) | info->buffer[0x3f3];
  1712. INT32 dyy = (info->buffer[0x3f4] << 16) | info->buffer[0x3f5];
  1713. INT32 dxx = (info->buffer[0x3f6] << 16) | info->buffer[0x3f7];
  1714. INT32 dxy = (info->buffer[0x3f8] << 16) | info->buffer[0x3f9];
  1715. INT32 dyx = (info->buffer[0x3fa] << 16) | info->buffer[0x3fb];
  1716. int x, y;
  1717. /* advance forward based on the clip rect */
  1718. currx += dxx * (cliprect->min_x + 27) + dxy * cliprect->min_y;
  1719. curry += dyx * (cliprect->min_x + 27) + dyy * cliprect->min_y;
  1720. /* loop over screen Y coordinates */
  1721. for (y = cliprect->min_y; y <= cliprect->max_y; y++)
  1722. {
  1723. UINT16 *dest = BITMAP_ADDR16(bitmap, y, 0);
  1724. UINT16 *src = (UINT16 *)srcbitmap->base;
  1725. UINT8 *pri = BITMAP_ADDR8(machine->priority_bitmap, y, 0);
  1726. INT32 tx = currx;
  1727. INT32 ty = curry;
  1728. /* loop over screen X coordinates */
  1729. for (x = cliprect->min_x; x <= cliprect->max_x; x++)
  1730. {
  1731. /* fetch the pixel from the source bitmap */
  1732. int sx = (tx >> 14) & 0x1ff;
  1733. int sy = (ty >> 14) & 0x1ff;
  1734. int pix = src[sy * srcbitmap->rowpixels + sx];
  1735. /* non-zero pixels get written; everything else is the scanline color */
  1736. if (pix != 0xffff)
  1737. {
  1738. *dest++ = (pix & 0x1ff) | ((pix >> 6) & 0x200) | ((pix >> 3) & 0xc00) | 0x1000;
  1739. *pri++ = (pix >> 8) | 1;
  1740. }
  1741. else
  1742. {
  1743. *dest++ = info->colorbase + sy;
  1744. *pri++ = 0xff;
  1745. }
  1746. /* advance the source X/Y pointers */
  1747. tx += dxx;
  1748. ty += dyx;
  1749. }
  1750. /* advance the source X/Y pointers */
  1751. currx += dxy;
  1752. curry += dyy;
  1753. }
  1754. }
  1755. /*************************************
  1756. *
  1757. * General road control read/write
  1758. *
  1759. *************************************/
  1760. READ16_HANDLER( segaic16_rotate_control_0_r )
  1761. {
  1762. struct rotate_info *info = &segaic16_rotate[0];
  1763. if (info->buffer)
  1764. {
  1765. UINT32 *src = (UINT32 *)info->rotateram;
  1766. UINT32 *dst = (UINT32 *)info->buffer;
  1767. int i;
  1768. /* swap the halves of the rotation RAM */
  1769. for (i = 0; i < info->ramsize/4; i++)
  1770. {
  1771. UINT32 temp = *src;
  1772. *src++ = *dst;
  1773. *dst++ = temp;
  1774. }
  1775. }
  1776. return 0xffff;
  1777. }
  1778. DEFINE_LEGACY_DEVICE(SEGA16SP, sega16sp);