1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett
3 /***************************************************************************
4 
5     Tatsumi TX-1/Buggy Boy video hardware
6 
7 ****************************************************************************/
8 
9 #include "emu.h"
10 #include "includes/tx1.h"
11 
12 #include "video/resnet.h"
13 #include "cpu/i86/i86.h"
14 
15 
16 #define OBJ_FRAC    16
17 
18 /*************************************
19  *
20  *  HD46505S-2 CRT Controller
21  *
22  *************************************/
23 
24 #define CURSOR_YPOS 239
25 #define CURSOR_XPOS 168
26 #define PRINT_CRTC_DATA 0
27 
28 /*
29     6845 cursor output is connected to the main CPU interrupt pin.
30     The CRTC is programmed to provide a rudimentary VBLANK interrupt.
31 
32     TODO: Calc TX-1 values...
33 */
34 
35 /*
36     TODO: Check interrupt timing from CRT config. Probably different between games.
37 */
TIMER_CALLBACK_MEMBER(tx1_state::interrupt_callback)38 TIMER_CALLBACK_MEMBER(tx1_state::interrupt_callback)
39 {
40 	m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xff); // I8086
41 	m_interrupt_timer->adjust(m_screen->time_until_pos(CURSOR_YPOS, CURSOR_XPOS));
42 }
43 
44 
tx1_crtc_r()45 uint16_t tx1_state::tx1_crtc_r()
46 {
47 	return 0xffff;
48 }
49 
tx1_crtc_w(offs_t offset,uint16_t data)50 void tx1_state::tx1_crtc_w(offs_t offset, uint16_t data)
51 {
52 if (PRINT_CRTC_DATA)
53 {
54 	data &= 0xff;
55 	if (offset == 0)
56 	{
57 		switch (data)
58 		{
59 			case 0x00: osd_printf_debug("Horizontal Total         "); break;
60 			case 0x01: osd_printf_debug("Horizontal displayed     "); break;
61 			case 0x02: osd_printf_debug("Horizontal sync position "); break;
62 			case 0x03: osd_printf_debug("Horizontal sync width    "); break;
63 			case 0x04: osd_printf_debug("Vertical total           "); break;
64 			case 0x05: osd_printf_debug("Vertical total adjust    "); break;
65 			case 0x06: osd_printf_debug("Vertical displayed       "); break;
66 			case 0x07: osd_printf_debug("Vertical sync position   "); break;
67 			case 0x08: osd_printf_debug("Interlace mode           "); break;
68 			case 0x09: osd_printf_debug("Max. scan line address   "); break;
69 			case 0x0a: osd_printf_debug("Cursror start            "); break;
70 			case 0x0b: osd_printf_debug("Cursor end               "); break;
71 			case 0x0c: osd_printf_debug("Start address (h)        "); break;
72 			case 0x0d: osd_printf_debug("Start address (l)        "); break;
73 			case 0x0e: osd_printf_debug("Cursor (h)               "); break;
74 			case 0x0f: osd_printf_debug("Cursor (l)               "); break;
75 			case 0x10: osd_printf_debug("Light pen (h))           "); break;
76 			case 0x11: osd_printf_debug("Light pen (l)            "); break;
77 		}
78 	}
79 	else if (offset == 1)
80 	{
81 		osd_printf_debug("0x%.2x, (%d)\n",data, data);
82 	}
83 }
84 }
85 
86 
87 /***************************************************************************
88 
89   TX-1
90 
91 ***************************************************************************/
92 
93 enum
94 {
95 	TX1_RDFLAG_RVA8 = 0,
96 	TX1_RDFLAG_RVA9,
97 	TX1_RDFLAG_RVA7,
98 	TX1_RDFLAG_TNLF,
99 	TX1_RDFLAG_STLF,
100 	TX1_RDFLAG_SCCHGF
101 };
102 
103 
104 
105 /***************************************************************************
106 
107   Palette initialisation
108 
109   bit 3 -- 220 ohm resistor  -- RED/GREEN/BLUE
110         -- 470 ohm resistor  -- RED/GREEN/BLUE
111         -- 1.0kohm resistor  -- RED/GREEN/BLUE
112   bit 0 -- 2.2kohm resistor  -- RED/GREEN/BLUE
113 
114 ***************************************************************************/
115 
tx1_palette(palette_device & palette) const116 void tx1_state::tx1_palette(palette_device &palette) const
117 {
118 	static const res_net_info tx1_net_info =
119 	{
120 		RES_NET_VCC_5V | RES_NET_VIN_TTL_OUT,
121 		{
122 			{ RES_NET_AMP_NONE, 0, 0, 4, { 2200, 1000, 470, 220 } },
123 			{ RES_NET_AMP_NONE, 0, 0, 4, { 2200, 1000, 470, 220 } },
124 			{ RES_NET_AMP_NONE, 0, 0, 4, { 2200, 1000, 470, 220 } }
125 		}
126 	};
127 
128 	uint8_t const *const color_prom = &m_proms[0];
129 	for (int i = 0; i < 256; ++i)
130 	{
131 		int const r = compute_res_net(color_prom[i + 0x300] & 0xf, 0, tx1_net_info);
132 		int const g = compute_res_net(color_prom[i + 0x400] & 0xf, 1, tx1_net_info);
133 		int const b = compute_res_net(color_prom[i + 0x500] & 0xf, 2, tx1_net_info);
134 
135 		palette.set_pen_color(i, rgb_t(r, g, b));
136 	}
137 }
138 
139 
140 /*************************************
141  *
142  *  Video Control Registers
143  *
144  *************************************/
145 
tx1_bankcs_w(offs_t offset,uint16_t data)146 void tx1_state::tx1_bankcs_w(offs_t offset, uint16_t data)
147 {
148 	vregs_t &tx1_vregs = m_vregs;
149 
150 	// AAB2 = /BASET0
151 	// AAB3 = /BASET
152 	// AAB4 = /BSET
153 	// AAB5 = /HASET
154 	// AAB6 = /HSET
155 
156 	offset <<= 1;
157 
158 	if (offset & 0x04)
159 	{
160 		tx1_vregs.ba_inc &= ~0x0000ffff;
161 		tx1_vregs.ba_inc |= data;
162 
163 		if (!(offset & 2))
164 			tx1_vregs.ba_val &= ~0x000ffff;
165 	}
166 	if (offset & 0x08)
167 	{
168 		data &= 0xff;
169 		tx1_vregs.ba_inc &= ~0xffff0000;
170 		tx1_vregs.ba_inc |= data << 16;
171 
172 		// TODO: Schems say D15.
173 		tx1_vregs.bank_mode = BIT(data, 1);
174 
175 		if (!(offset & 2))
176 			tx1_vregs.ba_val &= ~0xffff0000;
177 	}
178 	if ( !(offset & 0x10) )
179 	{
180 		/* Ignore data */
181 		if (offset & 2)
182 			tx1_vregs.ba_val = (tx1_vregs.ba_inc + tx1_vregs.ba_val) & 0x00ffffff;
183 	}
184 	if (offset & 0x20)
185 	{
186 		tx1_vregs.h_inc = data;
187 
188 		if ( !(offset & 2) )
189 			tx1_vregs.h_val = 0;
190 	}
191 	if (!(offset & 0x40))
192 	{
193 		/* TODO: Looks safe to remove this */
194 //      if ( offset & 2 )
195 			tx1_vregs.h_val += tx1_vregs.h_inc;
196 	}
197 }
198 
tx1_slincs_w(offs_t offset,uint16_t data)199 void tx1_state::tx1_slincs_w(offs_t offset, uint16_t data)
200 {
201 	if (offset == 1)
202 		m_vregs.slin_inc = data;
203 	else
204 		m_vregs.slin_inc = m_vregs.slin_val = 0;
205 }
206 
tx1_slock_w(uint16_t data)207 void tx1_state::tx1_slock_w(uint16_t data)
208 {
209 	m_vregs.slock = data & 1;
210 }
211 
tx1_scolst_w(uint16_t data)212 void tx1_state::tx1_scolst_w(uint16_t data)
213 {
214 	m_vregs.scol = data & 0x0707;
215 }
216 
tx1_flgcs_w(uint16_t data)217 void tx1_state::tx1_flgcs_w(uint16_t data)
218 {
219 	m_vregs.flags = data & 0xff;
220 }
221 
222 
223 /*************************************
224  *
225  *  Characters
226  *
227  *************************************/
228 
tx1_draw_char(uint8_t * bitmap)229 void tx1_state::tx1_draw_char(uint8_t *bitmap)
230 {
231 	uint16_t *tx1_vram = m_vram;
232 	int32_t x, y;
233 	uint32_t scroll_x;
234 
235 	/* 2bpp characters */
236 	const uint8_t *const chars = &m_char_tiles[0];
237 	const uint8_t *const gfx2 = &m_char_tiles[0x4000];
238 
239 	/* X scroll value is the last word in char RAM */
240 	scroll_x = tx1_vram[0xfff] & 0x3ff;
241 
242 	for (y = 0; y < 240; ++y)
243 	{
244 		uint32_t d0 = 0, d1 = 0;
245 		uint32_t colour = 0;
246 		uint32_t y_offs;
247 		uint32_t x_offs;
248 		uint32_t y_gran;
249 
250 		/* No y-scrolling? */
251 		y_offs = y;
252 
253 		if ((y_offs >= 64) && (y_offs < 128))
254 			x_offs = m_vregs.slock ? scroll_x : 0;
255 		else
256 			x_offs = 0;
257 
258 		y_gran = y_offs & 7;
259 
260 		if (x_offs & 7)
261 		{
262 			uint32_t tilenum;
263 			uint16_t ram_val = tx1_vram[((y_offs << 4) & 0xf80) + ((x_offs >> 3) & 0x7f)];
264 
265 			tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5);
266 			colour = (ram_val & 0xfc00) >> 8;
267 			d0 = *(gfx2 + (tilenum << 3) + y_gran);
268 			d1 = *(chars + (tilenum << 3) + y_gran);
269 		}
270 
271 		for (x = 0; x < 256 * 3; ++x)
272 		{
273 			uint32_t x_gran = x_offs & 7;
274 
275 			if (!x_gran)
276 			{
277 				uint32_t tilenum;
278 				uint16_t ram_val = tx1_vram[((y_offs << 4) & 0xf80) + ((x_offs >> 3) & 0x7f)];
279 
280 				tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5);
281 				colour = (ram_val & 0xfc00) >> 8;
282 				d0 = *(gfx2 + (tilenum << 3) + y_gran);
283 				d1 = *(chars + (tilenum << 3) + y_gran);
284 			}
285 
286 			*bitmap++ = colour |
287 						(((d1 >> (7 ^ x_gran)) & 1) << 1) |
288 						((d0 >> (7 ^ x_gran)) & 1);
289 
290 			x_offs = (x_offs + 1) & 0x3ff;
291 		}
292 	}
293 }
294 
295 
296 /*************************************
297  *
298  *  Road
299  *
300  *************************************/
301 
302 #define TX1_GET_ROADPIX(NUM) \
303 { \
304 	uint32_t addr = (rva6_0 << 5) | (road##NUM##_hcnt & 0x1f); \
305 	uint8_t promaddr1, promaddr2, promaddr3; \
306 	promaddr1 = rom_a[addr]; \
307 	promaddr2 = rom_b[addr]; \
308 	promaddr3 = rom_c[addr]; \
309 	pix[NUM][0][0] = prom_a[promaddr1]; pix[NUM][0][1] = prom_b[promaddr1]; pix[NUM][0][2] = prom_c[promaddr1]; \
310 	pix[NUM][1][0] = prom_a[promaddr2]; pix[NUM][1][1] = prom_b[promaddr2]; pix[NUM][1][2] = prom_c[promaddr2]; \
311 	pix[NUM][2][0] = prom_a[promaddr3]; pix[NUM][2][1] = prom_b[promaddr3]; pix[NUM][2][2] = prom_c[promaddr3]; \
312 	pix[NUM][3][0] = prom_a[0];         pix[NUM][3][1] = prom_b[0];         pix[NUM][3][2] = prom_c[0]; \
313 }
314 
tx1_draw_road_pixel(int screen,uint8_t * bmpaddr,uint8_t apix[3],uint8_t bpix[3],uint32_t pixnuma,uint32_t pixnumb,uint8_t stl,uint8_t sld,uint8_t selb,uint8_t bnk,uint8_t rorev,uint8_t eb,uint8_t r,uint8_t delr)315 void tx1_state::tx1_draw_road_pixel(int screen, uint8_t *bmpaddr,
316 									uint8_t apix[3], uint8_t bpix[3], uint32_t pixnuma, uint32_t pixnumb,
317 									uint8_t stl, uint8_t sld, uint8_t selb,
318 									uint8_t bnk, uint8_t rorev, uint8_t eb, uint8_t r, uint8_t delr)
319 {
320 	vregs_t &tx1_vregs = m_vregs;
321 	uint8_t a0 = BIT(apix[0], pixnuma);
322 	uint8_t a1 = BIT(apix[1], pixnuma);
323 	uint8_t a2 = BIT(apix[2], pixnuma);
324 
325 	uint8_t b0 = BIT(bpix[0], pixnumb);
326 	uint8_t b1 = BIT(bpix[1], pixnumb);
327 	uint8_t b2 = BIT(bpix[2], pixnumb);
328 
329 	uint8_t d3;
330 	uint8_t d2;
331 	uint8_t d1;
332 	uint8_t d0;
333 	uint8_t sel;
334 	uint8_t c6 = BIT(sld, 6);
335 	uint8_t c5 = BIT(sld, 5);
336 	uint8_t c4 = BIT(sld, 4);
337 	uint8_t c3 = BIT(sld, 2);
338 
339 	uint32_t addr_offset = screen * 256;
340 
341 	sel = !bnk && ( (a2 && !b0) || (!a0 && b2) || !a1 || !a2 || !b1 || !b2 );
342 
343 	d3 =
344 		(a2 && a1 && a0 && b2 && b1 && b0 && !rorev)
345 		|| (a1 && b1 && !b0 && stl && !bnk && !c6)
346 		|| (a1 && !a0 && b1 && stl && !bnk && !c6)
347 		|| (a1 && !b2 && b1 && stl && !bnk && !c6)
348 		|| (a2 && b2 && !b1 && stl && !bnk && !c4)
349 		|| (a2 && !a1 && b2 && stl && !bnk && !c4)
350 		|| (!a2 && a1 && b2 && stl && !bnk && !c6)
351 		|| (a2 && !b2 && b1 && stl && !bnk && !c6)
352 		|| (!a2 && !a1 && stl && !bnk && !c5)
353 		|| (!b2 && !b1 && stl && !bnk && !c5)
354 		|| (!b0 && !stl && !bnk && !c3)
355 		|| (!b1 && !stl && !bnk && !c3)
356 		|| (!a0 && !stl && !bnk && !c3)
357 		|| (!a1 && !stl && !bnk && !c3)
358 		|| (!a2 && !stl && !bnk && !c3)
359 		|| (!b2 && !stl && !bnk && !c3)
360 		|| (bnk && !rorev);
361 
362 	if (eb == 0)
363 	{
364 		if (sel == 1)
365 		{
366 			d2 = stl && (!a2 || !b2);
367 			d1 = !stl || (!a2 && !a1) || (!b1 && !b2) || (a2 && !b1) || (b2 && !a1);
368 			d0 = !stl
369 				|| (!a2 && !a0 && b1)
370 				|| (a1 && !b2 && !b0)
371 				|| (!a2 && !a1 && !a0)
372 				|| (!b2 && !b1 && !b0)
373 				|| (a2 && a1 && !b0)
374 				|| (!a0 && b2 && b1)
375 				|| (a2 && !b1 && !b0)
376 				|| (!a1 && !a0 && b2)
377 				|| (!a2 && !a0 && b2)
378 				|| (a2 && !b2 && !b0);
379 		}
380 		else
381 		{
382 			d2 = BIT(tx1_vregs.scol, selb ? 2 : 10);
383 			d1 = BIT(tx1_vregs.scol, selb ? 1 : 9);
384 			d0 = BIT(tx1_vregs.scol, selb ? 0 : 8);
385 		}
386 	}
387 	else
388 		d2 = d1 = d0 = 0;
389 
390 	*(bmpaddr + addr_offset) = (bnk << 6) | (r << 5) | (!(sel && delr) << 4 ) | (d3 << 3) | (d2 << 2) | (d1 << 1) | d0;
391 }
392 
393 /* This could do with a tidy up and more comments... */
tx1_draw_road(uint8_t * bitmap)394 void tx1_state::tx1_draw_road(uint8_t *bitmap)
395 {
396 	uint16_t *tx1_rcram = m_rcram;
397 	vregs_t &tx1_vregs = m_vregs;
398 	int32_t   y;
399 	uint32_t  rva9_8;
400 	uint32_t  rva7;
401 	uint32_t  tnlf;
402 	uint32_t  stlf;
403 	uint32_t  scchgf;
404 
405 	uint32_t  vc = 0;
406 
407 	uint16_t  road0_hcnt;
408 	uint8_t   road0_pcnt;
409 	uint16_t  road1_hcnt;
410 	uint8_t   road1_pcnt;
411 	uint8_t   pix[2][4][3];
412 
413 	/* Road slice map ROMs */
414 	const uint8_t *const rom_a = &m_road_rom[0];
415 	const uint8_t *const rom_b = &m_road_rom[0x2000];
416 	const uint8_t *const rom_c = &m_road_rom[0x4000];
417 
418 	/* Pixel data */
419 	const uint8_t *const prom_a = &m_proms[0x1100];
420 	const uint8_t *const prom_b = &m_proms[0x1300];
421 	const uint8_t *const prom_c = &m_proms[0x1500];
422 	const uint8_t *const vprom  = &m_proms[0x1700];
423 
424 	rva9_8  = (tx1_vregs.flags & 3) << 8;
425 	rva7    = !BIT(tx1_vregs.flags, TX1_RDFLAG_RVA7) << 7;
426 	tnlf    = BIT(tx1_vregs.flags, TX1_RDFLAG_TNLF);
427 	scchgf  = BIT(tx1_vregs.flags, TX1_RDFLAG_SCCHGF);
428 	stlf    = BIT(tx1_vregs.flags, TX1_RDFLAG_STLF);
429 
430 	for (y = 0; y < 240; ++y)
431 	{
432 		uint32_t  x;
433 		uint8_t   sld;
434 		uint8_t   rva6_0;
435 		uint16_t  rcrdb15_0;
436 		uint16_t  rva_addr;
437 		uint32_t  bank_cnt;
438 
439 		uint16_t  vat;
440 		uint16_t  vp0;
441 		uint16_t  vp1;
442 		uint16_t  vp2;
443 		uint16_t  vp3;
444 		uint16_t  vp4;
445 
446 		uint32_t  va8, va9, va10, va11, va12, va13, va14, va15;
447 		uint32_t  v0, v1, v2;
448 
449 		uint8_t   hc1_u, hc1_l;
450 		uint8_t   hc0_u, hc0_l;
451 
452 		uint32_t  bnkls, bnkcs, bnkrs;
453 		uint32_t  rl, rc, rr;
454 
455 		uint32_t  stl;
456 		uint32_t  selb;
457 		uint32_t  ebls, ebcs, ebrs;
458 
459 		uint8_t *bmpaddr = bitmap + (y * 768);
460 
461 		uint32_t rltmp, rctmp, rrtmp;
462 		uint32_t eltmp, ectmp, ertmp;
463 
464 		uint32_t tmpm;
465 		uint32_t tmpn;
466 		uint32_t tmpc;
467 		uint32_t tmpd;
468 
469 		uint8_t scrcnt0;
470 		uint8_t scrcnt1;
471 
472 		uint8_t rorevls = 0;
473 		uint8_t rorevcs = 0;
474 		uint8_t rorevrs = 0;
475 
476 		int febl[2] = { 0, 0 };
477 		int febr[2] = { 0, 0 };
478 		int febc[2] = { 0, 0 };
479 
480 		/* Road vertical address */
481 		if (BIT(tx1_vregs.h_val, 15))
482 			rva6_0 = 0x7f;
483 		else
484 			rva6_0 = (~tx1_vregs.h_val >> 7) & 0x7f;
485 
486 		rva_addr = rva9_8 | rva6_0;
487 
488 		/* Get the stripe data also */
489 		sld = vprom[rva6_0] + tx1_vregs.slin_val;
490 
491 		/* Load the left road h-counter */
492 		rcrdb15_0 = tx1_rcram[(0x80 + rva_addr) ^ 0x7ff];
493 		road0_pcnt = rcrdb15_0 & 0x7;
494 		road0_hcnt = (rcrdb15_0 >> 3) & 0x7f;
495 		road0_hcnt |= rcrdb15_0 & 0xfc00 ? 0x80 : 0;
496 		road0_hcnt |= (rcrdb15_0 & 0xfc00) == 0xfc00 ? 0x100 : 0x000;
497 
498 		/* Load the second road h-counter */
499 		rcrdb15_0 = tx1_rcram[(rva7 + rva_addr) ^ 0x7ff];
500 		road1_pcnt = rcrdb15_0 & 0x7;
501 		road1_hcnt = (rcrdb15_0 >> 3) & 0x7f;
502 		road1_hcnt |= rcrdb15_0 & 0xfc00 ? 0x80 : 0;
503 		road1_hcnt |= (rcrdb15_0 & 0xfc00) == 0xfc00 ? 0x100 : 0x000;
504 		road1_hcnt |= (rcrdb15_0 & 0x800);
505 
506 		scrcnt0 = (road0_hcnt >> 5) & 0xf;
507 		scrcnt1 = (road1_hcnt >> 5) & 0xf;
508 
509 		if (road0_pcnt & 7)
510 		{
511 			TX1_GET_ROADPIX(0);
512 
513 			febl[0] = (scrcnt0 + 0) & 0xc;
514 			febc[0] = (scrcnt0 + 1) & 0xc;
515 			febr[0] = (scrcnt0 + 2) & 0xc;
516 		}
517 
518 		if (road1_pcnt & 7)
519 		{
520 			uint32_t y4 = (road1_hcnt >> 4) & 1;
521 			uint32_t temp = (road1_hcnt >> 5) & 0xf;
522 			uint32_t x, u;
523 			uint32_t fl11 = BIT(road1_hcnt, 15);
524 
525 			TX1_GET_ROADPIX(1);
526 
527 			x = (temp & 0xc);
528 			u = !(((temp & 1) && y4) || (temp & 2));
529 			rorevls = ((fl11 && !x) || (fl11 && x && u));
530 			febl[1] = x;
531 
532 			temp += 1;
533 			x = (temp & 0xc);
534 			u = !(((temp & 1) && y4) || (temp & 2));
535 			rorevcs = ((fl11 && !x) || (fl11 && x && u));
536 			febc[1] = x;
537 
538 			temp += 1;
539 			x = (temp & 0xc);
540 			u = !(((temp & 1) && y4) || (temp & 2));
541 			rorevrs = ((fl11 && !x) || (fl11 && x && u));
542 			febr[1] = x;
543 		}
544 
545 		/* Load the bank counter with accumulator bits 14-5 */
546 		bank_cnt = (tx1_vregs.ba_val >> 5) & 0x3ff;
547 
548 		/* Load vertical position data */
549 		vat = tx1_rcram[(rva9_8 + 7) ^ 0x7f8];
550 		vp0 = tx1_rcram[(rva9_8 + 6) ^ 0x7f8];
551 		vp1 = tx1_rcram[(rva9_8 + 5) ^ 0x7f8];
552 		vp2 = tx1_rcram[(rva9_8 + 4) ^ 0x7f8];
553 		vp3 = tx1_rcram[(rva9_8 + 3) ^ 0x7f8];
554 		vp4 = tx1_rcram[(rva9_8 + 2) ^ 0x7f8];
555 
556 		/*  */
557 		if (y-1 == vp0) vc++;
558 		if (y-1 == vp1) vc++;
559 		if (y-1 == vp2) vc++;
560 		if (y-1 == vp3) vc++;
561 		if (y-1 == vp4) vc++;
562 
563 		/* */
564 		va8 = BIT(vat, 8);
565 		va9 = BIT(vat, 9);
566 		va10 = BIT(vat, 10);
567 		va11 = BIT(vat, 11);
568 		va12 = BIT(vat, 12);
569 		va13 = BIT(vat, 13);
570 		va14 = BIT(vat, 14);
571 		va15 = BIT(vat, 15);
572 
573 		v0 = BIT(vc, 0);
574 		v1 = BIT(vc, 1);
575 		v2 = BIT(vc, 2);
576 
577 		/* Load the horizontal tunnel position counters */
578 		hc1_u = tx1_rcram[(rva9_8 + 1) ^ 0x7f8] >> 8;
579 		hc1_l = tx1_rcram[(rva9_8 + 1) ^ 0x7f8] & 0xff;
580 		hc0_u = tx1_rcram[(rva9_8 + 0) ^ 0x7f8] >> 8;
581 		hc0_l = tx1_rcram[(rva9_8 + 0) ^ 0x7f8] & 0xff;
582 
583 		stl = !stlf || v0 || (!v2 && !scchgf) || scchgf;
584 		selb = (!v2 && !scchgf) || v2;
585 
586 		rltmp =
587 		(v2 && !v0 && !va10)
588 		|| (!v2 && v0 && !va10)
589 		|| (v2 && !v0 && !va11)
590 		|| (v2 && !v1 && !v0)
591 		|| (!v2 && v0 && !va11)
592 		|| (!v2 && v1 && !v0)
593 		|| (!v2 && !v1 && v0);
594 
595 		rctmp =
596 		(v2 && !v0 && va9 && va8)
597 		|| (!v2 && v0 && va9 && va8)
598 		|| (v2 && !v0 && !va11)
599 		|| (v2 && !v1 && !v0)
600 		|| (!v2 &&  v0 && !va11)
601 		|| (!v2 &&  v1 && !v0)
602 		|| (!v2 && !v1 &&  v0);
603 
604 		rrtmp =
605 		(v2 && !v0 && !va11 && !va10)
606 		|| (!v2 && v0 && !va11 && !va10)
607 		|| (v2 && !v0 && va9)
608 		|| (!v2 && v0 && va9)
609 		|| (v2 && !v1 && !v0)
610 		|| (!v2 && v1 && !v0)
611 		|| (!v2 && !v1 && v0);
612 
613 		ectmp =
614 		(v2 && !v0 && va13 && va12)
615 		|| (!v2 && v1 && va13 && va12)
616 		|| (!v2 && !v1 && v0)
617 		|| (v2 && !v0 && !va15)
618 		|| (!v2 && v1 && !va15);
619 
620 		eltmp =
621 		(v2 && !v0 && !va14)
622 		|| (!v2 && v1 && !va14)
623 		|| (!v2 && !v1 && v0)
624 		|| (v2 && !v0 && !va15)
625 		|| (!v2 && v1 && !va15);
626 
627 		ertmp =
628 		(v2 && !v0 && !va15 && !va14)
629 		|| (!v2 && v1 && !va15 && !va14)
630 		|| (v2 && !v0 && va13)
631 		|| (!v2 && v1 && va13)
632 		|| (!v2 && !v1 && v0);
633 
634 		tmpn = (v2 && !v0) || (!v2 && v0);
635 		tmpm = (v2 && !v0) || (!v2 && v1);
636 		tmpc = (!v1 && !v0) || (v2);
637 		tmpd = v1 && v0 && va11;
638 
639 		for (x = 0; x < 256; x++)
640 		{
641 			uint32_t pixnum0 = (road0_pcnt & 7) ^ 7;
642 			uint32_t pixnum1 = (road1_pcnt & 7) ^ 7;
643 
644 			uint32_t cyu, cyl;
645 			uint32_t delrl, delrc, delrr;
646 
647 			/* */
648 			scrcnt0 = (road0_hcnt >> 5) & 0xf;
649 			scrcnt1 = (road1_hcnt >> 5) & 0xf;
650 
651 			/* Get new pixel data? */
652 			if (!(road0_pcnt & 7))
653 			{
654 				TX1_GET_ROADPIX(0);
655 
656 				/* Road 0 enables */
657 				febl[0] = (scrcnt0 + 0) & 0xc;
658 				febc[0] = (scrcnt0 + 1) & 0xc;
659 				febr[0] = (scrcnt0 + 2) & 0xc;
660 			}
661 
662 			if (!(road1_pcnt & 7))
663 			{
664 				uint32_t y4 = (road1_hcnt >> 4) & 1;
665 				uint32_t temp = (road1_hcnt >> 5) & 0xf;
666 				uint32_t x, u;
667 				uint32_t fl11 = BIT(road1_hcnt, 15);
668 
669 				TX1_GET_ROADPIX(1);
670 
671 				x = (temp & 0xc);
672 				u = !(((temp & 1) && y4) || (temp & 2));
673 				rorevls = ((fl11 && !x) || (fl11 && x && u));
674 				febl[1] = x;
675 
676 				temp += 1;
677 				x = (temp & 0xc);
678 				u = !(((temp & 1) && y4) || (temp & 2));
679 				rorevcs = ((fl11 && !x) || (fl11 && x && u));
680 				febc[1] = x;
681 
682 				temp += 1;
683 				x = (temp & 0xc);
684 				u = !(((temp & 1) && y4) || (temp & 2));
685 				rorevrs = ((fl11 && !x) || (fl11 && x && u));
686 				febr[1] = x;
687 			}
688 
689 			/* Road camber/banking */
690 			if (BIT(tx1_vregs.ba_val, 23))
691 			{
692 				bnkls = 1;
693 				bnkcs = 1;
694 				bnkrs = 1;
695 			}
696 			else if (tx1_vregs.ba_val & 0x007f8000)
697 			{
698 				bnkls = 0;
699 				bnkcs = 0;
700 				bnkrs = 0;
701 			}
702 			else
703 			{
704 				bnkls = bank_cnt < 0x400;
705 				bnkcs = bank_cnt < 0x300;
706 				bnkrs = bank_cnt < 0x200;
707 			}
708 
709 			if (tx1_vregs.bank_mode)
710 			{
711 				bnkls ^= 1;
712 				bnkcs ^= 1;
713 				bnkrs ^= 1;
714 			}
715 
716 			cyu = hc1_u == 0xff;
717 			cyl = hc1_l == 0xff;
718 
719 			rl = tnlf && ( rltmp || (tmpn && (!cyl || (va8 && va9 && cyu))) );
720 			rc = tnlf && ( rctmp || (tmpn && ((!va10 && !cyl) || (va9 && cyu))) );
721 			rr = tnlf && ( rrtmp || (tmpn && ((!va11 && !cyl) || (va8 && cyu))) );
722 
723 			/* Evaluates to 0 for tunnels */
724 			delrl = !tnlf || tmpc || ((tmpd && va10) && ((!va8 && cyl) || (!va9 && cyl) || (!cyu && !cyl)));
725 
726 			delrr =
727 				!tnlf
728 				|| tmpc
729 				|| (v1 && v0 && va10 && !va9 && !va8 && cyl)
730 				|| (v1 && v0 && va10 && !va9 && cyl && !cyu)
731 				|| (tmpd && !va9 && !cyu)
732 				|| (tmpd && !va9 && !va8);
733 
734 			delrc = !tnlf || tmpc || (tmpd && ((!va8 && cyl && !cyu) || (!va8 && va10 && !cyu) || (!va9 && cyl) || (va10 && !va9)));
735 
736 			cyu = hc0_u == 0xff;
737 			cyl = hc0_l == 0xff;
738 
739 			ebls = tnlf && ( eltmp || (tmpm && (!cyl || (va12 && va13 && cyu))));
740 			ebcs = tnlf && ( ectmp || (tmpm && ((!va14 && !cyl) || (va13 && cyu))));
741 			ebrs = tnlf && ( ertmp || (tmpm && ((!va15 && !cyl) || (va12 && cyu))));
742 
743 			/* Carry for horizontal position counters */
744 			cyu = hc0_u == 0xff;
745 			cyl = hc0_l == 0xff;
746 
747 			if (!(bnkls && !rl))
748 			{
749 				int a, b;
750 
751 				if (!febl[0])
752 					a = (scrcnt0) & 3;
753 				else
754 					a = 3;
755 
756 				if (!febl[1])
757 					b = (scrcnt1) & 3;
758 				else
759 					b = 3;
760 
761 				tx1_draw_road_pixel(0, bmpaddr,
762 							&pix[0][a][0], &pix[1][b][0],
763 							pixnum0, pixnum1,
764 							stl, sld, selb, bnkls, rorevls, ebls, rl, delrl);
765 			}
766 			else
767 				*(bmpaddr) = (bnkls << 6) | (rl << 5);
768 
769 			if (!(bnkcs && !rc))
770 			{
771 				int a, b;
772 
773 				if (!febc[0])
774 					a = (scrcnt0 + 1) & 3;
775 				else
776 					a = 3;
777 
778 				if (!febc[1])
779 					b = (scrcnt1 + 1) & 3;
780 				else
781 					b = 3;
782 
783 				tx1_draw_road_pixel(1, bmpaddr,
784 							&pix[0][a][0], &pix[1][b][0],
785 							pixnum0, pixnum1,
786 							stl, sld, selb, bnkcs, rorevcs, ebcs, rc, delrc);
787 			}
788 			else
789 				*(bmpaddr + 256) = (bnkcs << 6) | (rc << 5);
790 
791 			if (!(bnkrs && !rr))
792 			{
793 				int a, b;
794 
795 				if (!febr[0])
796 					a = (scrcnt0 + 2) & 3;
797 				else
798 					a = 3;
799 
800 				if (!febr[1])
801 					b = (scrcnt1 + 2) & 3;
802 				else
803 					b = 3;
804 
805 				tx1_draw_road_pixel(2, bmpaddr,
806 							&pix[0][a][0], &pix[1][b][0],
807 							pixnum0, pixnum1,
808 							stl, sld, selb, bnkrs, rorevrs, ebrs, rr, delrr);
809 			}
810 			else
811 				*(bmpaddr + 512) = (bnkrs << 6) | (rr << 5);
812 
813 			++bmpaddr;
814 
815 			/* Update road counters */
816 			if (!(++road0_pcnt & 7))
817 				++road0_hcnt;
818 
819 			if (!(++road1_pcnt & 7))
820 				++road1_hcnt;
821 
822 			/* Increment horizontal counters (stop at 0xff) */
823 			if (hc0_u != 0xff) ++hc0_u;
824 			if (hc0_l != 0xff) ++hc0_l;
825 			if (hc1_u != 0xff) ++hc1_u;
826 			if (hc1_l != 0xff) ++hc1_l;
827 
828 			/* Update bank counter */
829 			bank_cnt = (bank_cnt + 1) & 0x7ff;
830 		}
831 
832 		tx1_vregs.h_val += tx1_vregs.h_inc;
833 
834 		/* Finally, increment the bank accumulator */
835 		tx1_vregs.ba_val = (tx1_vregs.ba_val + tx1_vregs.ba_inc) & 0x00ffffff;
836 	}
837 
838 }
839 
840 /*************************************
841  *
842  *  Objects
843  *
844  *************************************/
845 
tx1_draw_objects(uint8_t * bitmap)846 void tx1_state::tx1_draw_objects(uint8_t *bitmap)
847 {
848 	uint16_t *tx1_objram = m_objram;
849 
850 	uint32_t offs;
851 
852 	/* The many lookup table ROMs */
853 	const uint8_t *const ic48 = &m_obj_luts[0];
854 	const uint8_t *const ic281 = &m_obj_luts[0x2000];
855 
856 	const uint8_t *const ic190 = &m_proms[0xc00];
857 	const uint8_t *const ic162 = &m_proms[0xe00];
858 	const uint8_t *const ic25  = &m_proms[0x1000];
859 
860 	const uint8_t *const ic106 = &m_obj_map[0];
861 	const uint8_t *const ic73  = &m_obj_map[0x4000];
862 
863 	const uint8_t *const pixdata_rgn = &m_obj_tiles[0];
864 
865 	for (offs = 0x0; offs <= 0x300; offs += 8)
866 	{
867 		uint32_t  x;
868 		uint32_t  y;
869 		uint32_t  gxflip;
870 
871 		uint32_t  x_scale;
872 		uint32_t  x_step;
873 		uint16_t  y_scale;
874 		uint16_t  y_step;
875 
876 		uint8_t   pctmp0_7;
877 		uint8_t   code;
878 
879 		/* Check for end of object list */
880 		if ((tx1_objram[offs] & 0xff00) == 0xff00)
881 			break;
882 
883 		/* X scale */
884 		x_scale = tx1_objram[offs + 2] & 0xff;
885 
886 		/* TODO: Confirm against hardware? */
887 		if (x_scale == 0)
888 			continue;
889 
890 		/* 16-bit y-scale accumulator */
891 		y_scale = tx1_objram[offs + 1];
892 		y_step  = tx1_objram[offs + 3];
893 
894 		/* Object number */
895 		code = tx1_objram[offs] & 0xff;
896 
897 		/* Attributes */
898 		pctmp0_7 = tx1_objram[offs + 2] >> 8;
899 
900 		/* Global x-flip */
901 		gxflip = (pctmp0_7 & 0x80) >> 7;
902 
903 		/* Add 1 to account for line buffering */
904 		y = (tx1_objram[offs] >> 8) + 1;
905 
906 		for (; y < 240; ++y)
907 		{
908 			uint32_t  rom_addr2   = 0;
909 			uint8_t   ic106_data  = 0;
910 			uint8_t   ic73_data;
911 
912 			/* Are we drawing on this line? */
913 
914 			/* TODO: See big lampposts. */
915 			if (y_scale & 0x8000)
916 				break;
917 
918 			{
919 				uint32_t  psa0_11;
920 				uint32_t  ic48_addr;
921 				uint32_t  ic48_data;
922 				uint32_t  rom_addr;
923 				uint32_t  x_acc;
924 				uint32_t  newtile = 1;
925 				uint32_t  dataend = 0;
926 				uint8_t   data1 = 0;
927 				uint8_t   data2 = 0;
928 				uint32_t  xflip = 0;
929 				uint32_t  opcd0_7 = 0;
930 				uint32_t  lasttile = 0;
931 
932 				/* Use the object code to lookup the tile sequence data in ROM */
933 				ic48_addr = code << 4;
934 				ic48_addr |= ((y_scale >> 11) & 0xf);
935 				ic48_data = ic48[ic48_addr];
936 
937 				/* Reached the bottom of the object? (/PASS2E) */
938 				if (ic48_data == 0xff)
939 					break;
940 
941 				/* Combine ROM and PROM data */
942 				psa0_11 = ((ic25[code] << 8) | ic48_data) & 0xfff;
943 
944 				/* psa8_11 */
945 				rom_addr = (psa0_11 & ~0xff) << 2;
946 
947 				/* Prepare the x-scaling */
948 				x_step = (128 << OBJ_FRAC) / x_scale;
949 				x_acc = (psa0_11 & 0xff) << (OBJ_FRAC + 5);
950 
951 #define TX1_MASK    0xfff
952 
953 				x = tx1_objram[offs + 4] & TX1_MASK;
954 
955 				for (;;)
956 				{
957 					if (newtile)
958 					{
959 						uint32_t  psbb0_12;
960 						uint32_t  pscb0_14;
961 						uint32_t  pscb11;
962 						uint8_t   *romptr;
963 						uint32_t  ic281_addr;
964 						uint32_t  grom_addr;
965 						uint32_t  lut_data;
966 						uint32_t  low_addr = ((x_acc >> (OBJ_FRAC + 3)) & TX1_MASK);
967 
968 						if (gxflip)
969 						{
970 							uint32_t xor_mask;
971 
972 							if (BIT(psa0_11, 11) && BIT(psa0_11, 10))
973 								xor_mask = 0xf;
974 							else if (BIT(psa0_11, 11) || BIT(psa0_11, 10) || BIT(psa0_11, 9))
975 								xor_mask = 0x7;
976 							else
977 								xor_mask = 0x3;
978 
979 							rom_addr2 = rom_addr + (xor_mask ^ low_addr);
980 						}
981 						else
982 							rom_addr2 = rom_addr + low_addr;
983 
984 						ic106_data = ic106[rom_addr2 & 0x3fff];
985 
986 						if ((ic106_data & 0x40) && dataend)
987 							lasttile = 1;
988 
989 						dataend |= ic106_data & 0x40;
990 
991 						/* Retrieve data for an 8x8 tile */
992 						ic73_data = ic73[rom_addr2 & 0x3fff];
993 
994 						/* This is the data from the LUT pair */
995 						lut_data = (ic106_data << 8) | ic73_data;
996 						psbb0_12 = lut_data & 0x1fff;
997 
998 						pscb0_14 = (psbb0_12 & 0xc3f);
999 
1000 						/* Bits 9_6 are from PCTMP11-8 or PSBB9-6 */
1001 						if (BIT(psbb0_12, 12))
1002 							pscb0_14 |= psbb0_12 & 0x3c0;
1003 						else
1004 							pscb0_14 |= (pctmp0_7 & 0xf) << 6;
1005 
1006 						if (BIT(lut_data, 13))
1007 							pscb0_14 |= BIT(psbb0_12, 10) << 12;
1008 						else
1009 							pscb0_14 |= ((pctmp0_7 & 0x70) << 8);
1010 
1011 						/* Bit 12 is bit 10 duplicated. */
1012 						pscb0_14 &= ~(1 << 12);
1013 						pscb0_14 |= BIT(psbb0_12, 10) << 12;
1014 
1015 						pscb11 = BIT(pscb0_14, 11);
1016 
1017 						/* TODO: Remove this - it's constant. */
1018 						romptr = (uint8_t*)(pixdata_rgn + pscb11 * (0x4000 * 2));
1019 
1020 						grom_addr = ((pscb0_14 << 3) | ((y_scale >> 8) & 7)) & 0x3fff;
1021 
1022 						/* Get raw 8x8 2bpp pixel row data */
1023 						data1 = *(grom_addr + romptr);
1024 						data2 = *(grom_addr + romptr + 0x4000);
1025 
1026 						/* Determine flip state (global XOR local) */
1027 						xflip = gxflip ^ !BIT(lut_data, 15);
1028 
1029 						ic281_addr = pscb0_14 & 0x3ff;
1030 						ic281_addr |= ((pscb0_14 & 0x7000) >> 2);
1031 						ic281_addr |= pscb11 << 13;
1032 
1033 						opcd0_7 = ic281[ic281_addr];
1034 
1035 						newtile = 0;
1036 					}
1037 
1038 					/* Draw a pixel? */
1039 					if (x < 768)
1040 					{
1041 						uint8_t   pix;
1042 						uint8_t   bit;
1043 
1044 						bit = (x_acc >> OBJ_FRAC) & 7;
1045 
1046 						if (xflip)
1047 							bit ^= 7;
1048 
1049 						pix = (((data1 >> bit) & 1) << 1) | ((data2 >> bit) & 1);
1050 
1051 						/* Draw pixel, if not transparent */
1052 						if ( !(!(opcd0_7 & 0x80) && !pix) )
1053 						{
1054 							uint8_t color;
1055 							uint32_t prom_addr;
1056 
1057 							prom_addr = ((opcd0_7 << 2) | pix) & 0x1ff;
1058 
1059 							/* Inverted on schematic */
1060 							if (x & 1)
1061 								color = ~ic190[prom_addr] & 0x3f;
1062 							else
1063 								color = ~ic162[prom_addr] & 0x3f;
1064 
1065 							*(bitmap + 768*y + x) = 0x40 | color;
1066 						}
1067 					}
1068 
1069 					/* Check if we've stepped into a new 8x8 tile */
1070 
1071 					if ((((x_acc + x_step) >> (OBJ_FRAC + 3)) & TX1_MASK) != ((x_acc >> (OBJ_FRAC + 3)) & TX1_MASK))
1072 					{
1073 						if (lasttile)
1074 							break;
1075 
1076 						newtile = 1;
1077 					}
1078 
1079 					x = (x + 1) & TX1_MASK;
1080 					x_acc += x_step;
1081 				}
1082 			}
1083 			y_scale += y_step;
1084 		}
1085 	}
1086 }
1087 
1088 
1089 /*************************************
1090  *
1091  *  Core Functions
1092  *
1093  *************************************/
1094 
VIDEO_START_MEMBER(tx1_state,tx1)1095 VIDEO_START_MEMBER(tx1_state,tx1)
1096 {
1097 	/* Allocate a large bitmap that covers the three screens */
1098 	m_bitmap = std::make_unique<bitmap_ind16>(768, 256);
1099 
1100 	/* Allocate some bitmaps */
1101 	m_chr_bmp = std::make_unique<uint8_t[]>(256 * 3 * 240);
1102 	m_obj_bmp = std::make_unique<uint8_t[]>(256 * 3 * 240);
1103 	m_rod_bmp = std::make_unique<uint8_t[]>(256 * 3 * 240);
1104 
1105 	/* Set a timer to run the interrupts */
1106 	m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx1_state::interrupt_callback),this));
1107 
1108 	/* /CUDISP CRTC interrupt */
1109 	m_interrupt_timer->adjust(m_screen->time_until_pos(CURSOR_YPOS, CURSOR_XPOS));
1110 }
1111 
WRITE_LINE_MEMBER(tx1_state::screen_vblank_tx1)1112 WRITE_LINE_MEMBER(tx1_state::screen_vblank_tx1)
1113 {
1114 	// rising edge
1115 	if (state)
1116 	{
1117 		/* /VSYNC: Update TZ113 */
1118 		m_vregs.slin_val += m_vregs.slin_inc;
1119 
1120 		m_needs_update = true;
1121 	}
1122 }
1123 
tx1_combine_layers(bitmap_ind16 & bitmap,int screen)1124 void tx1_state::tx1_combine_layers(bitmap_ind16 &bitmap, int screen)
1125 {
1126 	uint8_t const *const chr_pal = &m_proms[0x900];
1127 
1128 	int x_offset = screen * 256;
1129 
1130 	for (int y = 0; y < 240; ++y)
1131 	{
1132 		uint16_t *bmp_addr = &bitmap.pix(y);
1133 
1134 		uint32_t bmp_offset = y * 768 + x_offset;
1135 
1136 		uint8_t *chr_addr = m_chr_bmp.get() + bmp_offset;
1137 		uint8_t *rod_addr = m_rod_bmp.get() + bmp_offset;
1138 		uint8_t *obj_addr = m_obj_bmp.get() + bmp_offset;
1139 
1140 		for (int x = 0; x < 256; ++x)
1141 		{
1142 			uint8_t out_val;
1143 			uint32_t char_val = chr_addr[x];
1144 			uint32_t c7 = BIT(char_val, 7);
1145 			uint32_t c1 = BIT(char_val, 1);
1146 			uint32_t c0 = BIT(char_val, 0);
1147 
1148 			uint32_t road_val = rod_addr[x];
1149 			uint32_t r6 = BIT(road_val, 6);
1150 			uint32_t r5 = BIT(road_val, 5);
1151 
1152 			uint32_t obj_val = obj_addr[x];
1153 			uint32_t obj6 = BIT(obj_val, 6);
1154 
1155 			uint32_t term1 = !(c7 && c1);
1156 			uint32_t term2 = !(c7 && c0);
1157 			uint32_t term3 = r5 || !r6;
1158 			uint32_t p12 = !(term1 && term2 && term3);
1159 			uint32_t p6 = !(obj6 && term1 && term2);
1160 			uint32_t sel =  p12 | (p6 << 1);
1161 
1162 			uint32_t psel =  (!(p6 && p12) << 1) | p6;
1163 
1164 			if      (sel == 3)  out_val = ((char_val & 0xc0) >> 2) | (chr_pal[char_val] & 0xf);
1165 			else if (sel == 2)  out_val = road_val & 0x3f;
1166 			else                out_val = obj_val & 0x3f;
1167 
1168 			*bmp_addr++ = (psel << 6) | out_val;
1169 		}
1170 	}
1171 }
1172 
1173 
tx1_update_layers()1174 void tx1_state::tx1_update_layers()
1175 {
1176 	memset(m_obj_bmp.get(), 0, 768*240);
1177 
1178 	tx1_draw_char(m_chr_bmp.get());
1179 	tx1_draw_road(m_rod_bmp.get());
1180 	tx1_draw_objects(m_obj_bmp.get());
1181 
1182 	m_needs_update = false;
1183 }
1184 
screen_update_tx1_left(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1185 uint32_t tx1_state::screen_update_tx1_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1186 {
1187 	if (m_needs_update)
1188 		tx1_update_layers();
1189 
1190 	tx1_combine_layers(bitmap, 0);
1191 	return 0;
1192 }
1193 
screen_update_tx1_middle(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1194 uint32_t tx1_state::screen_update_tx1_middle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1195 {
1196 	if (m_needs_update)
1197 		tx1_update_layers();
1198 
1199 	tx1_combine_layers(bitmap, 1);
1200 	return 0;
1201 }
1202 
screen_update_tx1_right(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)1203 uint32_t tx1_state::screen_update_tx1_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1204 {
1205 	if (m_needs_update)
1206 		tx1_update_layers();
1207 
1208 	tx1_combine_layers(bitmap, 2);
1209 	return 0;
1210 }
1211 
1212 
1213 /***************************************************************************
1214 
1215   Buggy Boy
1216 
1217 ***************************************************************************/
1218 
1219 /* Road register bits */
1220 #define BB_RDFLAG_WAVE1     7
1221 #define BB_RDFLAG_WAVE0     6
1222 #define BB_RDFLAG_TNLMD1    5
1223 #define BB_RDFLAG_TNLMD0    4
1224 #define BB_RDFLAG_TNLF      3
1225 #define BB_RDFLAG_LINF      2
1226 #define BB_RDFLAG_RVA7      1
1227 #define BB_RDFLAG_WANGL     0
1228 
1229 /***************************************************************************
1230 
1231   Convert the color PROMs into a more useable format.
1232 
1233   IC39, BB12 = Blue
1234   IC40, BB11 = Green
1235   IC41, BB10 = Red
1236 
1237   IC42, BB13 = Brightness
1238 
1239   bit 3 -- 220 ohm resistor  -- RED/GREEN/BLUE
1240         -- 470 ohm resistor  -- RED/GREEN/BLUE
1241         -- 1.0kohm resistor  -- RED/GREEN/BLUE
1242   bit 0 -- 2.2kohm resistor  -- RED/GREEN/BLUE
1243 
1244   bit 0 -- 4.7kohm resistor  -- BLUE
1245   bit 1 -- 4.7kohm resistor  -- GREEN
1246   bit 2 -- 4.7kohm resistor  -- RED
1247 
1248 ***************************************************************************/
1249 
buggyboy_palette(palette_device & palette) const1250 void tx1_state::buggyboy_palette(palette_device &palette) const
1251 {
1252 	uint8_t const *const color_prom = &m_proms[0];
1253 
1254 	for (int i = 0; i < 0x100; i++)
1255 	{
1256 		int bit0, bit1, bit2, bit3, bit4;
1257 
1258 		bit0 = BIT(color_prom[i + 0x000], 0);
1259 		bit1 = BIT(color_prom[i + 0x000], 1);
1260 		bit2 = BIT(color_prom[i + 0x000], 2);
1261 		bit3 = BIT(color_prom[i + 0x000], 3);
1262 		bit4 = BIT(color_prom[i + 0x300], 2);
1263 		int const r = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3;
1264 
1265 		bit0 = BIT(color_prom[i + 0x100], 0);
1266 		bit1 = BIT(color_prom[i + 0x100], 1);
1267 		bit2 = BIT(color_prom[i + 0x100], 2);
1268 		bit3 = BIT(color_prom[i + 0x100], 3);
1269 		bit4 = BIT(color_prom[i + 0x300], 1);
1270 		int const g = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3;
1271 
1272 		bit0 = BIT(color_prom[i + 0x200], 0);
1273 		bit1 = BIT(color_prom[i + 0x200], 1);
1274 		bit2 = BIT(color_prom[i + 0x200], 2);
1275 		bit3 = BIT(color_prom[i + 0x200], 3);
1276 		bit4 = BIT(color_prom[i + 0x300], 0);
1277 		int const b = 0x06 * bit4 + 0x0d * bit0 + 0x1e * bit1 + 0x41 * bit2 + 0x8a * bit3;
1278 
1279 		palette.set_pen_color(i, rgb_t(r, g, b));
1280 	}
1281 }
1282 
1283 
1284 /*************************************
1285  *
1286  *  Characters
1287  *
1288  *************************************/
1289 
buggyboy_draw_char(uint8_t * bitmap,bool wide)1290 void tx1_state::buggyboy_draw_char(uint8_t *bitmap, bool wide)
1291 {
1292 	uint16_t *buggyboy_vram = m_vram;
1293 	int32_t x, y;
1294 	uint32_t scroll_x, scroll_y;
1295 	uint32_t total_width;
1296 	uint32_t x_mask;
1297 
1298 	/* 2bpp characters */
1299 	const uint8_t *const chars = &m_char_tiles[0];
1300 	const uint8_t *const gfx2 = &m_char_tiles[0x4000];
1301 
1302 	/* X/Y scroll values are the last word in char RAM */
1303 	if (wide)
1304 	{
1305 		scroll_y = (buggyboy_vram[0xfff] >> 10) & 0x3f;
1306 		scroll_x = buggyboy_vram[0xfff] & 0x3ff;
1307 		total_width = 768;
1308 		x_mask = 0x3ff;
1309 	}
1310 	else
1311 	{
1312 		scroll_y = (buggyboy_vram[0x7ff] >> 10) & 0x3f;
1313 		scroll_x = buggyboy_vram[0x7ff] & 0x1ff;
1314 		total_width = 256;
1315 		x_mask = 0x1ff;
1316 	}
1317 
1318 	for (y = 0; y < 240; ++y)
1319 	{
1320 		uint32_t d0 = 0, d1 = 0;
1321 		uint32_t colour = 0;
1322 		uint32_t y_offs;
1323 		uint32_t x_offs;
1324 		uint32_t y_gran;
1325 
1326 		/* There's no y-scrolling between scanlines 0 and 63 */
1327 		if (y < 64)
1328 			y_offs = y;
1329 		else
1330 		{
1331 			y_offs = (y + (scroll_y | 0xc0) + 1) & 0xff;
1332 
1333 			/* Clamp */
1334 			if (y_offs < 64)
1335 				y_offs |= 0xc0;
1336 		}
1337 
1338 		if ((y_offs >= 64) && (y_offs < 128))
1339 			x_offs = scroll_x;
1340 		else
1341 			x_offs = 0;
1342 
1343 
1344 		y_gran = y_offs & 7;
1345 
1346 		if (x_offs & 7)
1347 		{
1348 			uint32_t tilenum;
1349 			uint16_t ram_val;
1350 
1351 			if (wide)
1352 				ram_val = buggyboy_vram[((y_offs << 4) & 0xf80) + ((x_offs >> 3) & 0x7f)];
1353 			else
1354 				ram_val = buggyboy_vram[((y_offs << 3) & 0x7c0) + ((x_offs >> 3) & 0x3f)];
1355 
1356 			tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5);
1357 			colour = (ram_val & 0xfc00) >> 8;
1358 			d0 = *(gfx2 + (tilenum << 3) + y_gran);
1359 			d1 = *(chars + (tilenum << 3) + y_gran);
1360 		}
1361 
1362 		for (x = 0; x < total_width; ++x)
1363 		{
1364 			uint32_t x_gran = x_offs & 7;
1365 
1366 			if (!x_gran)
1367 			{
1368 				uint32_t tilenum;
1369 				uint16_t ram_val;
1370 
1371 				if (wide)
1372 					ram_val = buggyboy_vram[((y_offs << 4) & 0xf80) + ((x_offs >> 3) & 0x7f)];
1373 				else
1374 					ram_val = buggyboy_vram[((y_offs << 3) & 0x7c0) + ((x_offs >> 3) & 0x3f)];
1375 
1376 				tilenum = (ram_val & 0x03ff) | ((ram_val & 0x8000) >> 5);
1377 				colour = (ram_val & 0xfc00) >> 8;
1378 				d0 = *(gfx2 + (tilenum << 3) + y_gran);
1379 				d1 = *(chars + (tilenum << 3) + y_gran);
1380 			}
1381 
1382 			*bitmap++ = colour |
1383 						(((d1 >> (7 ^ x_gran)) & 1) << 1) |
1384 						((d0 >> (7 ^ x_gran)) & 1);
1385 
1386 			x_offs = (x_offs + 1) & x_mask;
1387 		}
1388 	}
1389 }
1390 
1391 
1392 /***************************************************************************
1393 
1394   Buggy Boy Road Hardware
1395 
1396   A hacked up version of TX-1 but without the second road.
1397 
1398   There are two lists in road/common RAM (double buffered) starting at 0x800
1399   and 0xa00:
1400 
1401   0x1800 - 0x18ff:    Road line horizontal position word (128 entries).
1402   0x19e0 - 0x19ef:    Vertical positions (starting line, water, tunnels etc)
1403   0x19f0 - 0x19ff:    Horizontal positions (walls and tunnels)
1404 
1405   Three TZ1113 accumulators are used to vary:
1406   * Road camber (update per pixel)
1407   * Road vertical scale/position (update per scanline)
1408   * Road 'speed' (update per frame)
1409 
1410   Road flags register (0x24E0):
1411   7 : Water sparkle control 1
1412   6 : Water sparkle control 0 ('WAVE0,1')
1413   5 : Tunnel mode 1
1414   4 : Tunnel mode 0 ('TNLMD0,1')
1415   3 : Tunnel flag ('TNLF')
1416   2 : Starting Line flag ('LINF')
1417   1 : Road list select
1418   0 : Wall angle enable ('WANGL')
1419 
1420   Buggy Boy Jr. Road PAL equations:
1421 
1422   http://philwip.mameworld.info/buggyboy/PAL14H4.149.htm
1423   http://philwip.mameworld.info/buggyboy/PAL14L4.151.htm
1424   http://philwip.mameworld.info/buggyboy/PAL16H2.3.htm
1425   http://philwip.mameworld.info/buggyboy/PAL16L8.4.htm
1426   http://philwip.mameworld.info/buggyboy/PAL16L8.150.htm
1427 
1428 ***************************************************************************/
1429 
buggyboy_get_roadpix(int screen,int ls161,uint8_t rva0_6,uint8_t sld,uint32_t * _rorev,uint8_t * rc0,uint8_t * rc1,uint8_t * rc2,uint8_t * rc3)1430 void tx1_state::buggyboy_get_roadpix(int screen, int ls161, uint8_t rva0_6, uint8_t sld, uint32_t *_rorev,
1431 									uint8_t *rc0, uint8_t *rc1, uint8_t *rc2, uint8_t *rc3)
1432 {
1433 	/* Counter Q10-7 are added to 384 */
1434 	uint16_t ls283_159 = (ls161 & 0x780) + 128 + (256 * screen);
1435 	uint32_t ls283_159_co = ls283_159 & 0x800;
1436 	uint32_t rom_flip = ls283_159 & 0x200 ? 0 : 1;
1437 	uint32_t rom_en = !(ls283_159 & 0x400) && !(ls283_159_co ^ (ls161 & 0x800));
1438 	uint8_t d0 = 0;
1439 	uint8_t d1 = 0;
1440 
1441 	/* ROM/PROM lookup tables */
1442 	const uint8_t *const rom   = &m_road_rom[0];
1443 	const uint8_t *const prom0 = &m_road_rom[0x4000];
1444 	const uint8_t *const prom1 = &m_road_rom[0x4200];
1445 	const uint8_t *const prom2 = &m_road_rom[0x4400];
1446 
1447 	/* Latch road reverse bit */
1448 	*_rorev = !( (rom_en && rom_flip) || (!rom_en && (ls161 & 0x4000)) );
1449 
1450 	/* TODO: ROM data is 0xff if not enabled. */
1451 	if (rom_en)
1452 	{
1453 		uint8_t  rom_data;
1454 		uint16_t prom_addr;
1455 
1456 		/* 6 bit road horizontal address */
1457 		uint16_t rha = (ls283_159 & 0x180) | (ls161 & 0x78);
1458 
1459 		if (rom_flip)
1460 			rha ^= 0x1f8;
1461 
1462 		/* Get road chunk first */
1463 		rom_data = rom[(1 << 13) | (rha << 4) | rva0_6];
1464 		prom_addr = (rom_flip ? 0x80 : 0) | (rom_data & 0x7f);
1465 
1466 		*rc0 = prom0[prom_addr];
1467 		*rc1 = prom1[prom_addr];
1468 		*rc2 = prom2[prom_addr];
1469 
1470 		/* Now get the dirt chunk */
1471 		rom_data = rom[(rha << 4) | rva0_6];
1472 		prom_addr = 0x100 | rom_data;
1473 
1474 		d0 = prom0[prom_addr];
1475 		d1 = prom1[prom_addr];
1476 	}
1477 	else
1478 	{
1479 		/*
1480 		    TODO: When ROM is not enabled, data = 0xff
1481 		    But does anybody care?
1482 		*/
1483 		*rc0 = *rc1 = *rc2 = *rc3 = 0;
1484 	}
1485 
1486 	/* The data is mixed by two TZ0314 PALs */
1487 	if (BIT(sld, 4))
1488 	{
1489 		if (BIT(sld, 5))
1490 			d1 = ~d1;
1491 
1492 		*rc3 = d0 & d1;
1493 
1494 		if (rom_flip)
1495 			*rc3 = bitswap<8>(*rc3, 0, 1, 2, 3, 4, 5, 6, 7);
1496 	}
1497 	else
1498 		*rc3 = 0;
1499 }
1500 
1501 #define LOAD_HPOS_COUNTER(NUM)                                                  \
1502 	ram_val = buggyboy_rcram[(rva_offs + 0x1f8 + (2*NUM)) >> 1];                \
1503 	rcrs10 = ram_val & 0xfc00 ? 0x0400 : 0x0000;                                \
1504 	hp = vregs.wa8 + ((BIT(ram_val, 15) << 11) | rcrs10 | (ram_val & 0x03ff));  \
1505 	hp##NUM = hp & 0xff;                                                        \
1506 	hp >>= 8;                                                                   \
1507 	hps##NUM##0 = (BIT(hp, 0) || BIT(hp, 2)) && !BIT(hp, 3);                    \
1508 	hps##NUM##1 = (BIT(hp, 1) || BIT(hp, 2)) && !BIT(hp, 3);                    \
1509 	hps##NUM##2 = BIT(hp, 2);
1510 #define UPDATE_HPOS(NUM)                \
1511 	if (hp##NUM##_en)                   \
1512 	{                                   \
1513 		if ((hp##NUM & 0xff) == 0xff)   \
1514 			hp##NUM##_cy = 1;           \
1515 		else                            \
1516 			hp##NUM = hp##NUM + 1;      \
1517 	}
buggyboy_draw_road(uint8_t * bitmap)1518 void tx1_state::buggyboy_draw_road(uint8_t *bitmap)
1519 {
1520 	uint16_t *buggyboy_rcram = m_rcram;
1521 	vregs_t &vregs = m_vregs;
1522 	int32_t x;
1523 	uint32_t y;
1524 	uint16_t rva_offs;
1525 	uint32_t tnlmd0;
1526 	uint32_t tnlmd1;
1527 	uint32_t linf;
1528 	uint32_t tnlf;
1529 	uint32_t wangl;
1530 	uint32_t tcmd;
1531 	uint32_t wave0;
1532 	uint32_t wave1;
1533 	uint32_t rva20_6;
1534 
1535 	/* ROM/PROM lookup tables */
1536 	const uint8_t *const rcols = &m_proms[0x1500];
1537 	const uint8_t *const vprom = &m_road_rom[0x4600];
1538 
1539 	/* Extract constant values */
1540 	tcmd     = ((vregs.scol & 0xc000) >> 12) | ((vregs.scol & 0x00c0) >> 6);
1541 	tnlmd0   = BIT(vregs.flags, BB_RDFLAG_TNLMD0);
1542 	tnlmd1   = BIT(vregs.flags, BB_RDFLAG_TNLMD1);
1543 	linf     = BIT(vregs.flags, BB_RDFLAG_LINF);
1544 	tnlf     = BIT(vregs.flags, BB_RDFLAG_TNLF);
1545 	wangl    = BIT(vregs.flags, BB_RDFLAG_WANGL);
1546 	wave0    = BIT(vregs.flags, BB_RDFLAG_WAVE0);
1547 	wave1    = BIT(vregs.flags, BB_RDFLAG_WAVE1);
1548 	rva_offs = BIT(vregs.flags, BB_RDFLAG_RVA7) ? 0x800 : 0xc00;
1549 
1550 	for (y = 0; y < 240; ++y)
1551 	{
1552 		uint8_t   rva0_6;
1553 		uint8_t   ram_addr;
1554 		uint16_t  rcrdb0_15;
1555 		uint16_t  rcrs10;
1556 		uint16_t  ls161_156_a;
1557 		uint16_t  ls161;
1558 		uint8_t   sld;
1559 		uint32_t  rva8;
1560 		uint32_t  rm0, rm1;
1561 		uint32_t  rcmd;
1562 		uint32_t  bnkls = 1;
1563 		uint32_t  bnkcs = 1;
1564 		uint32_t  bnkrs = 1;
1565 
1566 //      uint32_t  x_offs;
1567 		uint8_t sf;
1568 
1569 		/* Vertical positions shift register */
1570 		uint32_t  ram_val;
1571 		uint32_t  hp;
1572 		uint32_t  vp1, vp2, vp3, vp4, vp5, vp6, vp7;
1573 
1574 		/* Horizontal positions */
1575 		uint32_t  hp0, hp1, hp2, hp3;
1576 		uint8_t   hps00, hps01, hps02;
1577 		uint8_t   hps10, hps11, hps12;
1578 		uint8_t   hps20, hps21, hps22;
1579 		uint8_t   hps30, hps31, hps32;
1580 
1581 		/* Road pixel data planes */
1582 		uint8_t   rc0[3] = {0, 0, 0};
1583 		uint8_t   rc1[3] = {0, 0, 0};
1584 		uint8_t   rc2[3] = {0, 0, 0};
1585 		uint8_t   rc3[3] = {0, 0, 0};
1586 
1587 		/* Horizontal position counter carry out */
1588 		uint8_t   hp0_cy = 0, hp1_cy = 0, hp2_cy = 0, hp3_cy = 0;
1589 
1590 		uint8_t   *bmpaddr = bitmap + (y * 256 * 3);
1591 
1592 		uint32_t  bank_cnt;
1593 		uint32_t  _rorevls = 0;
1594 		uint32_t  _rorevcs = 0;
1595 		uint32_t  _rorevrs = 0;
1596 
1597 		uint32_t  ic96_o17;
1598 		uint32_t  ic96_term1;
1599 		uint32_t  ic97_o12;
1600 		uint32_t  ic97_o13;
1601 		uint32_t  ic79_p19;
1602 
1603 		rva8 = (vregs.h_val & 0x8000) || !(vregs.shift & 0x80);
1604 
1605 		/* Get RVA0_6 from TZ113 accumulator chain @ 122/123 */
1606 		rva0_6 = (vregs.h_val >> 7) & 0x7f;
1607 
1608 		/* For /WAVE bit logic later */
1609 		rva20_6 = ((rva0_6 >> 3) & 0xe) | ((rva0_6 & 2) >> 1);
1610 
1611 		/* RVA is inverted! */
1612 		ram_addr = (~rva0_6 & 0x7f) << 1;
1613 
1614 		/* Get the road RAM data for this line */
1615 		rcrdb0_15 = buggyboy_rcram[(rva_offs + ram_addr) >> 1];
1616 
1617 		/* If 15-10 == 000000, then 0 */
1618 		rcrs10 = rcrdb0_15 & 0xfc00 ? 0x0400 : 0x0000;
1619 
1620 		/* If 15-10 == 111111, then 1 */
1621 		ls161_156_a = (rcrdb0_15 & 0xfc00) == 0xfc00 ? 0x800 : 0x0000;
1622 
1623 		/* LS161 15-bit counter chain - loaded with RAM data (bar bits 10-13) */
1624 		ls161 =  ((rcrdb0_15 & 0x8000) >> 1) | ls161_156_a | rcrs10 | (rcrdb0_15 & 0x03ff);
1625 
1626 		/* SLD */
1627 		sld = (vprom[rva0_6] + vregs.slin_val) & 0x38;
1628 
1629 		/* Determine the x-offset */
1630 //      x_offs = ls161 & 7;
1631 
1632 		/* Fill vertical position shift register with bits for this line */
1633 		/* TODO; cheated slightly to shift stuff up one pixel*/
1634 		vp1 = buggyboy_rcram[(rva_offs + 0x1e2) >> 1] >= y ? 0 : 1;
1635 		vp2 = buggyboy_rcram[(rva_offs + 0x1e4) >> 1] >= y ? 0 : 1;
1636 		vp3 = buggyboy_rcram[(rva_offs + 0x1e6) >> 1] >= y ? 0 : 1;
1637 		vp4 = buggyboy_rcram[(rva_offs + 0x1e8) >> 1] >= y ? 0 : 1;
1638 		vp5 = buggyboy_rcram[(rva_offs + 0x1ea) >> 1] >= y ? 0 : 1;
1639 		vp6 = buggyboy_rcram[(rva_offs + 0x1ec) >> 1] >= y ? 0 : 1;
1640 		vp7 = buggyboy_rcram[(rva_offs + 0x1ee) >> 1] >= y ? 0 : 1;
1641 
1642 		/* Stuff */
1643 		rm0 = vp7 ? BIT(vregs.scol, 4) : BIT(vregs.scol, 12);
1644 		rm1 = vp7 ? BIT(vregs.scol, 5) : BIT(vregs.scol, 13);
1645 
1646 		/* Wall/tunnel control */
1647 		rcmd = (vp7 ? vregs.scol : vregs.scol >> 8) & 0xf;
1648 
1649 		/* Load 'em up */
1650 		LOAD_HPOS_COUNTER(0);
1651 		LOAD_HPOS_COUNTER(1);
1652 		LOAD_HPOS_COUNTER(2);
1653 		LOAD_HPOS_COUNTER(3);
1654 
1655 		/* Load the bank counter with accumulator bits 14-5 */
1656 		bank_cnt = (vregs.ba_val >> 5) & 0x3ff;
1657 
1658 		/* Have we crossed a road gfx strip boundary? */
1659 		if (ls161 & 7)
1660 		{
1661 			buggyboy_get_roadpix(0, ls161, rva0_6, sld, &_rorevls, &rc0[0], &rc1[0], &rc2[0], &rc3[0]);
1662 			buggyboy_get_roadpix(1, ls161, rva0_6, sld, &_rorevcs, &rc0[1], &rc1[1], &rc2[1], &rc3[1]);
1663 			buggyboy_get_roadpix(2, ls161, rva0_6, sld, &_rorevrs, &rc0[2], &rc1[2], &rc2[2], &rc3[2]);
1664 		}
1665 
1666 		/* We can evaluate some of the pixel logic outside of the x-loop */
1667 		ic96_term1 = !tnlf || (vp5 && vp6) || (!vp3 && vp6) || (!vp4 && vp5) || (!vp3 && !vp4);
1668 		ic96_o17 = (vp3 && vp4) || tnlmd0 || tnlmd1 || !vp1 || !tnlf;
1669 
1670 		ic97_o12 = (!vp1 && !vp2 && !vp6) || (!vp1 && !vp2 && vp7) || (vp4 && !vp6) || (vp4 && vp7);
1671 		ic97_o13 = (!vp1 && !vp2 && !vp5) || (!vp1 && !vp2 && vp7) || (vp3 && !vp5) || (vp3 && vp7);
1672 
1673 		ic79_p19 = !(!(vp5 || vp6) || vp7) && !(tnlmd0 || tnlmd1);
1674 
1675 		for (x = 0; x < 256; ++x)
1676 		{
1677 			uint32_t  pix;
1678 			uint32_t  hp0_en, hp1_en, hp2_en, hp3_en;
1679 
1680 			uint32_t  ic97_o17;
1681 			uint32_t  ic97_o18;
1682 			uint32_t  ic97_o19;
1683 
1684 			uint32_t  ic96_o14;
1685 			uint32_t  ic96_o15;
1686 			uint32_t  ic96_o16;
1687 
1688 			uint32_t  ic79_o15;
1689 			uint32_t  ic79_o16;
1690 			uint32_t  ic79_o17;
1691 
1692 			uint32_t  ic82_o17;
1693 			uint32_t  ic82_o16;
1694 			uint32_t  ic82_o15;
1695 			uint32_t  ic82_o14;
1696 
1697 			uint32_t  ic80_o17;
1698 			uint32_t  ic80_o16;
1699 			uint32_t  ic80_o15;
1700 			uint32_t  ic80_o14;
1701 
1702 			uint32_t  ic78_o17;
1703 			uint32_t  ic78_o16;
1704 			uint32_t  ic78_o15;
1705 			uint32_t  ic78_o14;
1706 
1707 			uint32_t  ic48_o12, ic50_o12, ic52_o12;
1708 			uint32_t  ic48_o16, ic50_o16, ic52_o16;
1709 			uint32_t  ic48_o17, ic50_o17, ic52_o17;
1710 			uint32_t  ic48_o18, ic50_o18, ic52_o18;
1711 			uint32_t  ic48_o19, ic50_o19, ic52_o19;
1712 
1713 			uint32_t  tmp;
1714 
1715 			uint8_t   px0[3];
1716 			uint8_t   px1[3];
1717 			uint8_t   px2[3];
1718 			uint8_t   px3[3];
1719 
1720 			uint32_t lfsr = vregs.wave_lfsr;
1721 			uint32_t wave =
1722 						(wave0 ^ BIT(lfsr, 0))
1723 						&& (wave1 ^ BIT(lfsr, 3))
1724 						&& BIT(lfsr, 5)
1725 						&& !BIT(lfsr, 15)
1726 						&& BIT(lfsr, 11)
1727 						&& BIT(lfsr, 13)
1728 						&& (rva20_6 < ((lfsr >> 8) & 0xf));
1729 
1730 
1731 			/* Strip pixel number */
1732 			pix = (ls161 & 7) ^ 7;
1733 
1734 			/* Horizontal position counter enables - also used as PAL inputs */
1735 			hp0_en = !(hp0_cy || hps02);
1736 			hp1_en = !(hp1_cy || hps12);
1737 			hp2_en = !(hp2_cy || hps22);
1738 			hp3_en = !(hp3_cy || hps32);
1739 
1740 			/* Load in a new road gfx strip? */
1741 			if (!(ls161 & 7))
1742 			{
1743 				buggyboy_get_roadpix(0, ls161, rva0_6, sld, &_rorevls, &rc0[0], &rc1[0], &rc2[0], &rc3[0]);
1744 				buggyboy_get_roadpix(1, ls161, rva0_6, sld, &_rorevcs, &rc0[1], &rc1[1], &rc2[1], &rc3[1]);
1745 				buggyboy_get_roadpix(2, ls161, rva0_6, sld, &_rorevrs, &rc0[2], &rc1[2], &rc2[2], &rc3[2]);
1746 			}
1747 
1748 			/* Road camber/banking */
1749 			if (BIT(vregs.ba_val, 23))
1750 			{
1751 				bnkls = 1; bnkcs = 1; bnkrs = 1;
1752 			}
1753 			else if (vregs.ba_val & 0x007f8000)
1754 			{
1755 				bnkls = 0; bnkcs = 0; bnkrs = 0;
1756 			}
1757 			else
1758 			{
1759 				bnkls = bank_cnt < 0x400;
1760 				bnkcs = bank_cnt < 0x300;
1761 				bnkrs = bank_cnt < 0x200;
1762 			}
1763 
1764 			if (vregs.bank_mode)
1765 			{
1766 				bnkls ^= 1; bnkcs ^= 1; bnkrs ^= 1;
1767 			}
1768 
1769 			px0[0] = BIT(rc0[0], pix);
1770 			px1[0] = BIT(rc1[0], pix);
1771 			px2[0] = BIT(rc2[0], pix);
1772 			px3[0] = BIT(rc3[0], pix);
1773 
1774 			px0[1] = BIT(rc0[1], pix);
1775 			px1[1] = BIT(rc1[1], pix);
1776 			px2[1] = BIT(rc2[1], pix);
1777 			px3[1] = BIT(rc3[1], pix);
1778 
1779 			px0[2] = BIT(rc0[2], pix);
1780 			px1[2] = BIT(rc1[2], pix);
1781 			px2[2] = BIT(rc2[2], pix);
1782 			px3[2] = BIT(rc3[2], pix);
1783 
1784 			/*
1785 			    Now evaluate the pixel logic for each of the three screens
1786 
1787 			    TODO: A lot of this could be macrofied to avoid repetition.
1788 			    Shuffling the equations around would squeeze out some extra speed.
1789 			*/
1790 
1791 			/* Left */
1792 			ic96_o14 =
1793 			ic96_term1
1794 			|| (!hp1_en && hps10 && vp4 && !hps20 && !hps21)
1795 			|| (!hp1_en && hps10 && vp4 && hp2_en && !hps21)
1796 			|| (!hp1_en && hps10 && vp4 && vp6)
1797 			|| (hps11 && vp4 && !hps20 && !hps21)
1798 			|| (hps11 && vp4 && hp2_en && !hps21)
1799 			|| (vp5 && !hps20 && !hps21)
1800 			|| (!vp3 && !hps20 && !hps21)
1801 			|| (vp5 && hp2_en && !hps21)
1802 			|| (!vp3 && hp2_en && !hps21)
1803 			|| (!hp1_en && hps10 && !vp4)
1804 			|| (hps11 && vp4 && vp6)
1805 			|| (hps11 && !vp4);
1806 
1807 			/* Centre */
1808 			ic96_o15 =
1809 			ic96_term1
1810 			|| (hps10 && hps11 && vp4 && hp2_en && !hps20)
1811 			||(!hp1_en && hps11 && vp4 && hp2_en && !hps20)
1812 			|| (hps10 && hps11 && vp6)
1813 			|| (!hp1_en && hps11 && vp6)
1814 			|| (hps10 && hps11 && vp4 && !hps21)
1815 			|| (!hp1_en && hps11 && vp4 && !hps21)
1816 			|| (vp5 && hp2_en && !hps20)
1817 			|| (!vp3 && hp2_en && !hps20)
1818 			|| (hps10 && hps11 && !vp4)
1819 			|| (!hp1_en && hps11 && !vp4)
1820 			|| (vp5 && !hps21)
1821 			|| (!vp3 && !hps21);
1822 
1823 			/* Right */
1824 			ic96_o16 =
1825 			ic96_term1
1826 			|| (!hp1_en && hps10 && hps11 && vp6)
1827 			|| (!hp1_en && hps10 && hps11 && !vp4)
1828 			|| (!hp1_en && hps10 && hps11 && !hps20)
1829 			|| (!hp1_en && hps10 && hps11 && hp2_en)
1830 			|| (!hp1_en && hps10 && hps11 && !hps21)
1831 			|| (vp5 && !hps20)
1832 			|| (!vp3 && !hps20)
1833 			|| (vp5 && hp2_en)
1834 			|| (!vp3 && hp2_en)
1835 			|| (vp5 && !hps21)
1836 			|| (!vp3 && !hps21);
1837 
1838 			tmp = (!vp1 && !vp2) || (vp2 && vp7);
1839 			ic97_o17 = tmp || (!hp0_en && hps00 && vp2 && !hps30 && !hps31) || (!hp0_en && hps00 && vp2 && hp3_en && !hps31) || (hps01 && vp2 && !hps30 && !hps31) || (hps01 && vp2 && hp3_en && !hps31);
1840 			ic97_o18 = tmp || (hps00 && hps01 && vp2 && hp3_en && !hps30) || (!hp0_en && hps01 && vp2 && hp3_en && !hps30) || (hps00 && hps01 && vp2 && !hps31) || (!hp0_en && hps01 && vp2 && !hps31);
1841 			ic97_o19 = tmp || (!hp0_en && hps00 && hps01 && vp2 && !hps30) || (!hp0_en && hps00 && hps01 && vp2 && hp3_en) || (!hp0_en && hps00 && hps01 && vp2 && !hps31);
1842 
1843 
1844 			/* Left */
1845 			{
1846 			uint32_t P4, P6, P7, P18, P19;
1847 
1848 			P4 = !(ic96_o16 && ic96_o17 && ic97_o19);
1849 			P6 = BIT(sld, 3);
1850 			P7 = (!vp5 && !vp6) || vp7 || !linf;
1851 			P19 = wangl && bnkls;
1852 
1853 			ic78_o17 = (_rorevls && !tnlmd1 && tnlmd0) || (!_rorevls && tnlmd1 && !tnlmd0) || (_rorevls && ic97_o12) || (!_rorevls && ic97_o13);
1854 			P18 = ic78_o17;
1855 			ic78_o16 = P7 || (px1[0] && !px0[0] && tnlmd1 && !tnlmd0) || (px2[0] && tnlmd1 && tnlmd0);
1856 			ic78_o15 = !tnlf || (!P4 && px0[0] && P19) || (!P4 && px1[0] && P19) || (!P4 && P18) || (!P4 && px2[0]);
1857 			ic78_o14 = !P6 || tnlmd0 || tnlmd1 || P7;
1858 			}
1859 
1860 			/* Centre */
1861 			{
1862 			uint32_t P4, P6, P7, P18, P19;
1863 
1864 			P4 = !(ic96_o15 && ic96_o17 && ic97_o18);
1865 			P6 = BIT(sld, 3);
1866 			P7 = (!vp5 && !vp6) || vp7 || !linf;
1867 			P19 = wangl && bnkcs;
1868 
1869 			ic80_o17 = (_rorevcs && !tnlmd1 && tnlmd0) || (!_rorevcs && tnlmd1 && !tnlmd0) || (_rorevcs && ic97_o12) || (!_rorevcs && ic97_o13);
1870 			P18 = ic80_o17;
1871 			ic80_o16 = P7 || (px1[1] && !px0[1] && tnlmd1 && !tnlmd0) || (px2[1] && tnlmd1 && tnlmd0);
1872 			ic80_o15 = !tnlf || (!P4 && px0[1] && P19) || (!P4 && px1[1] && P19) || (!P4 && P18) || (!P4 && px2[1]);
1873 			ic80_o14 = !P6 || tnlmd0 || tnlmd1 || P7;
1874 			}
1875 
1876 			/* Right */
1877 			{
1878 			uint32_t P4, P6, P7, P18, P19;
1879 
1880 			P4 = !(ic96_o14 && ic96_o17 && ic97_o17);
1881 			P6 = BIT(sld, 3);
1882 			P7 = (!vp5 && !vp6) || vp7 || !linf;
1883 			P19 = wangl && bnkrs;
1884 
1885 			ic82_o17 = (_rorevrs && !tnlmd1 && tnlmd0) || (!_rorevrs && tnlmd1 && !tnlmd0) || (_rorevrs && ic97_o12) || (!_rorevrs && ic97_o13);
1886 			P18 = ic82_o17;
1887 			ic82_o16 = P7 || (px1[2] && !px0[2] && tnlmd1 && !tnlmd0) || (px2[2] && tnlmd1 && tnlmd0);
1888 			ic82_o15 = !tnlf || (!P4 && px0[2] && P19) || (!P4 && px1[2] && P19) || (!P4 && P18) || (!P4 && px2[2]);
1889 			ic82_o14 = !P6 || tnlmd0 || tnlmd1 || P7;
1890 			}
1891 
1892 
1893 			ic79_o17 = (!px2[0] && _rorevls && ic78_o15) || (tnlf && !ic97_o19) || (tnlf && ic79_p19 && px2[0] && ic78_o15);
1894 			ic79_o16 = (!px2[1] && _rorevcs && ic80_o15) || (tnlf && !ic97_o18) || (tnlf && ic79_p19 && px2[1] && ic80_o15);
1895 			ic79_o15 = (!px2[2] && _rorevrs && ic82_o15) || (tnlf && !ic97_o17) || (tnlf && ic79_p19 && px2[2] && ic82_o15);
1896 
1897 
1898 			/* Left */
1899 			{
1900 			uint32_t P5,P7, P8;
1901 			uint32_t rcsd0_3;
1902 			uint32_t cprom_addr;
1903 
1904 			P5 = BIT(tcmd, 3) ? ((!vp5 && !vp6) || vp7 || !linf) : ic78_o16;
1905 			P7 = BIT(sld, 5);
1906 			P8 = BIT(sld, 4);
1907 
1908 			ic48_o19 = (px2[0] && !rva8) || !bnkls || !P5 || !ic78_o15;
1909 
1910 			if (ic48_o19)
1911 			{
1912 				ic48_o12 =
1913 				ic78_o14 &&
1914 				(
1915 					(px2[0] && px1[0] && px0[0] && rm1 && !rm0)
1916 					|| (!px2[0] && px1[0] && px0[0] && !P8 && rm0)
1917 					|| (px2[0] && px0[0] && !P7 && !rm1 && !rm0)
1918 					|| (px2[0] && !px1[0] && px0[0] && !P7 && !rm1)
1919 					|| (px2[0] && px1[0] && px0[0] && !P7 && !P8)
1920 					|| (px2[0] && px1[0] && px0[0] && !P8 && rm1)
1921 					|| (!px2[0] && !px3[0] && !rm0)
1922 					|| (!px1[0] && !px3[0] && rm1)
1923 					|| (!px2[0] && !px1[0] && !px3[0])
1924 					|| (rva8)
1925 					|| (!px0[0] && !px3[0])
1926 					|| (!ic78_o15)
1927 					|| (!P5)
1928 				);
1929 
1930 				ic48_o16 = (px2[0] && P5 && rm1) || (P5 && rva8 && ic78_o15) || (!px0[0] && P5) || !ic78_o15;
1931 				ic48_o17 = (px0[0] && P5 && !rm0 && ic78_o15) || (!px1[0] && P5 && ic78_o15) || (P5 && rva8 && ic78_o15);
1932 				ic48_o18 = (!px2[0] && P5 && ic78_o15) || (P5 && rva8 && ic78_o15);
1933 
1934 				if (vp6 || ic78_o16)
1935 				{
1936 					if (!(ic78_o15 && P5))
1937 						cprom_addr = (tcmd & 0x7) | (ic78_o16 << 3);
1938 					else
1939 						cprom_addr = rcmd;
1940 
1941 					cprom_addr = (~cprom_addr & 0xf) << 4;
1942 				}
1943 				else
1944 					cprom_addr = 0xf0;
1945 
1946 				cprom_addr |= (ic79_o17 << 3) |
1947 								(ic48_o18 << 2) |
1948 								(ic48_o17 << 1) |
1949 								ic48_o16;
1950 
1951 				rcsd0_3 = rcols[cprom_addr] & 0xf;
1952 				*(bmpaddr + 0) = 0x40 | (!wave << 5) | (ic48_o12 << 4) | rcsd0_3;
1953 			}
1954 			else
1955 				*(bmpaddr + 0) = 0;
1956 			}
1957 
1958 			/* Centre */
1959 			{
1960 			uint32_t rcsd0_3;
1961 			uint32_t cprom_addr;
1962 			uint32_t P5, P7, P8;
1963 
1964 			P5 = BIT(tcmd, 3) ? ((!vp5 && !vp6) || vp7 || !linf) : ic80_o16;
1965 			P7 = BIT(sld, 5);
1966 			P8 = BIT(sld, 4);
1967 
1968 			ic50_o19 = (px2[1] && !rva8) || !bnkcs || !P5 || !ic80_o15;
1969 
1970 			if (ic50_o19)
1971 			{
1972 				if (ic80_o14)
1973 					ic50_o12 =
1974 					(px2[1] && px1[1] && px0[1] && rm1 && !rm0)
1975 					|| (!px2[1] && px1[1] && px0[1] && !P8 && rm0)
1976 					|| (px2[1] && px0[1] && !P7 && !rm1 && !rm0)
1977 					|| (px2[1] && !px1[1] && px0[1] && !P7 && !rm1)
1978 					|| (px2[1] && px1[1] && px0[1] && !P7 && !P8)
1979 					|| (px2[1] && px1[1] && px0[1] && !P8 && rm1)
1980 					|| (!px2[1] && !px3[1] && !rm0)
1981 					|| (!px1[1] && !px3[1] && rm1)
1982 					|| (!px2[1] && !px1[1] && !px3[1])
1983 					|| (rva8)
1984 					|| (!px0[1] && !px3[1])
1985 					|| (!ic80_o15)
1986 					|| (!P5);
1987 				else
1988 					ic50_o12 = 0;
1989 
1990 
1991 				ic50_o16 = (P5 && px2[1] && rm1) || (P5 && rva8 && ic80_o15) || (P5 && !px0[1]) || !ic80_o15;
1992 				ic50_o17 = (P5 && px0[1] && !rm0 && ic80_o15) || (P5 && !px1[1] && ic80_o15) || (P5 && rva8 && ic80_o15);
1993 				ic50_o18 = (P5 && !px2[1] && ic80_o15) || (P5 && rva8 && ic80_o15);
1994 
1995 				if (vp6 || ic80_o16)
1996 				{
1997 					if (!(ic80_o15 && P5))
1998 						cprom_addr = (tcmd & 0x7) | (ic80_o16 << 3);
1999 					else
2000 						cprom_addr = rcmd;
2001 
2002 					cprom_addr = ((~cprom_addr) & 0xf) << 4;
2003 				}
2004 				else
2005 					cprom_addr = 0xf0;
2006 
2007 				cprom_addr |= (ic79_o16 << 3) |
2008 								(ic50_o18 << 2) |
2009 								(ic50_o17 << 1) |
2010 								ic50_o16;
2011 
2012 				rcsd0_3 = rcols[cprom_addr] & 0xf;
2013 				*(bmpaddr + 256) = 0x40 | (!wave << 5) | (ic50_o12 << 4) | rcsd0_3;
2014 			}
2015 			else
2016 				*(bmpaddr + 256) = 0;
2017 			}
2018 
2019 			/* Right */
2020 			{
2021 			uint32_t rcsd0_3;
2022 			uint32_t cprom_addr;
2023 			uint32_t P5, P7, P8;
2024 
2025 			P5 = BIT(tcmd, 3) ? ((!vp5 && !vp6) || vp7 || !linf) : ic82_o16;
2026 			P7 = BIT(sld, 5);
2027 			P8 = BIT(sld, 4);
2028 
2029 			ic52_o19 = (px2[2] && !rva8) || !bnkrs || !P5 || !ic82_o15;
2030 
2031 			if (ic52_o19)
2032 			{
2033 				ic52_o12 =
2034 				ic82_o14 &&
2035 				(
2036 					(px2[2] && px1[2] && px0[2] && rm1 && !rm0)
2037 					|| (!px2[2] && px1[2] && px0[2] && !P8 && rm0)
2038 					|| (px2[2] && px0[2] && !P7 && !rm1 && !rm0)
2039 					|| (px2[2] && !px1[2] && px0[2] && !P7 && !rm1)
2040 					|| (px2[2] && px1[2] && px0[2] && !P7 && !P8)
2041 					|| (px2[2] && px1[2] && px0[2] && !P8 && rm1)
2042 					|| (!px2[2] && !px3[2] && !rm0)
2043 					|| (!px1[2] && !px3[2] && rm1)
2044 					|| (!px2[2] && !px1[2] && !px3[2])
2045 					|| (rva8)
2046 					|| (!px0[2] && !px3[2])
2047 					|| (!ic82_o15)
2048 					|| (!P5)
2049 				);
2050 
2051 				ic52_o16 = (px2[2] && P5 && rm1) || (P5 && rva8 && ic82_o15) || (!px0[2] && P5) || !ic82_o15;
2052 				ic52_o17 = (px0[2] && P5 && !rm0 && ic82_o15) || (!px1[2] && P5 && ic82_o15) || (P5 && rva8 && ic82_o15);
2053 				ic52_o18 = (P5 && ic82_o15 && !px2[2]) || (P5 && ic82_o15 && rva8);
2054 
2055 				if (vp6 || ic82_o16)
2056 				{
2057 					if (!(ic82_o15 && P5))
2058 						cprom_addr = (tcmd & 0x7) | (ic82_o16 << 3);
2059 					else
2060 						cprom_addr = rcmd;
2061 
2062 					cprom_addr = (~cprom_addr & 0xf) << 4;
2063 				}
2064 				else
2065 					cprom_addr = 0xf0;
2066 
2067 				cprom_addr |= (ic79_o15 << 3) |
2068 								(ic52_o18 << 2) |
2069 								(ic52_o17 << 1) |
2070 								ic52_o16;
2071 
2072 				rcsd0_3 = rcols[cprom_addr] & 0xf;
2073 
2074 				*(bmpaddr + 512) = 0x40 | (!wave << 5) | (ic52_o12 ? 0x10 : 0) | rcsd0_3;
2075 			}
2076 			else
2077 				*(bmpaddr + 512) = 0;
2078 			}
2079 
2080 			/* Now update counters and whatnot */
2081 			++bmpaddr;
2082 
2083 			UPDATE_HPOS(0);
2084 			UPDATE_HPOS(1);
2085 			UPDATE_HPOS(2);
2086 			UPDATE_HPOS(3);
2087 
2088 			/* Update the wave LFSR */
2089 			vregs.wave_lfsr = (vregs.wave_lfsr << 1) | (BIT(vregs.wave_lfsr, 6) ^ !BIT(vregs.wave_lfsr, 15));
2090 
2091 			/* Increment the bank counter */
2092 			bank_cnt = (bank_cnt + 1) & 0x7ff;
2093 
2094 			/* X pos */
2095 			ls161 = (ls161 + 1) & 0x7fff;
2096 		}
2097 
2098 		/* WANGL active? Update the 8-bit counter */
2099 		if (wangl)
2100 		{
2101 			if (BIT(vregs.flags, BB_RDFLAG_TNLMD0))
2102 				--vregs.wa8;
2103 			else
2104 				++vregs.wa8;
2105 		}
2106 
2107 		/* No carry out - just increment */
2108 		if (vregs.wa4 != 0xf)
2109 			++vregs.wa4;
2110 		else
2111 		{
2112 			/* Carry out; increment again on /TMG2S rise */
2113 			if (wangl)
2114 			{
2115 				if (BIT(vregs.flags, BB_RDFLAG_TNLMD0))
2116 					--vregs.wa8;
2117 				else
2118 					++vregs.wa8;
2119 			}
2120 			vregs.wa4 = 1;
2121 		}
2122 
2123 		/* Update accumulator */
2124 		vregs.h_val += vregs.h_inc;
2125 
2126 		/* Seems correct */
2127 		sf = vregs.shift;
2128 
2129 		if ((vregs.shift & 0x80) == 0)
2130 		{
2131 			vregs.shift <<= 1;
2132 
2133 			if ((sf & 0x08) == 0)
2134 				vregs.shift |= BIT(vregs.h_val, 15);
2135 		}
2136 
2137 		if ((sf & 0x08) && !(vregs.shift & 0x08))
2138 			vregs.h_inc = vregs.gas;
2139 
2140 		/* Finally, increment the banking accumulator */
2141 		vregs.ba_val = (vregs.ba_val + vregs.ba_inc) & 0x00ffffff;
2142 	}
2143 }
2144 
buggybjr_draw_road(uint8_t * bitmap)2145 void tx1_state::buggybjr_draw_road(uint8_t *bitmap)
2146 {
2147 	uint16_t *buggyboy_rcram = m_rcram;
2148 	vregs_t &vregs = m_vregs;
2149 	int32_t x;
2150 	uint32_t y;
2151 	uint16_t rva_offs;
2152 	uint32_t tnlmd0;
2153 	uint32_t tnlmd1;
2154 	uint32_t linf;
2155 	uint32_t tnlf;
2156 	uint32_t wangl;
2157 	uint32_t tcmd;
2158 	uint32_t wave0;
2159 	uint32_t wave1;
2160 	uint32_t rva20_6;
2161 
2162 	/* ROM/PROM lookup tables */
2163 	const uint8_t *const rcols = &m_proms[0x1500];
2164 	const uint8_t *const vprom = &m_road_rom[0x4600];
2165 
2166 	/* Extract constant values */
2167 	tcmd     = ((vregs.scol & 0xc000) >> 12) | ((vregs.scol & 0x00c0) >> 6);
2168 	tnlmd0   = BIT(vregs.flags, BB_RDFLAG_TNLMD0);
2169 	tnlmd1   = BIT(vregs.flags, BB_RDFLAG_TNLMD1);
2170 	linf     = BIT(vregs.flags, BB_RDFLAG_LINF);
2171 	tnlf     = BIT(vregs.flags, BB_RDFLAG_TNLF);
2172 	wangl    = BIT(vregs.flags, BB_RDFLAG_WANGL);
2173 	wave0    = BIT(vregs.flags, BB_RDFLAG_WAVE0);
2174 	wave1    = BIT(vregs.flags, BB_RDFLAG_WAVE1);
2175 	rva_offs = BIT(vregs.flags, BB_RDFLAG_RVA7) ? 0x800 : 0xc00;
2176 
2177 	for (y = 0; y < 240; ++y)
2178 	{
2179 		uint8_t   rva0_6;
2180 		uint8_t   ram_addr;
2181 		uint16_t  rcrdb0_15;
2182 		uint16_t  rcrs10;
2183 		uint16_t  ls161_156_a;
2184 		uint16_t  ls161;
2185 		uint8_t   sld;
2186 		uint32_t  rva8;
2187 		uint32_t  rm0, rm1;
2188 		uint32_t  rcmd;
2189 		uint32_t  bnkcs = 1;
2190 
2191 //      uint32_t  x_offs;
2192 		uint8_t   sf;
2193 
2194 		/* Vertical positions shift register */
2195 		uint32_t  ram_val;
2196 		uint32_t  hp;
2197 		uint32_t  vp1, vp2, vp3, vp4, vp5, vp6, vp7;
2198 
2199 		/* PAL outputs */
2200 		uint32_t  ic4_o12;
2201 		uint32_t  ic4_o13;
2202 		uint32_t  ic149_o15;
2203 		uint32_t  ic151_o14;
2204 
2205 		/* Horizontal positions */
2206 		uint32_t  hp0, hp1, hp2, hp3;
2207 		uint8_t   hps00, hps01, hps02;
2208 		uint8_t   hps10, hps11, hps12;
2209 		uint8_t   hps20, hps21, hps22;
2210 		uint8_t   hps30, hps31, hps32;
2211 
2212 		/* Road pixel data planes */
2213 		uint8_t   rc0 = 0, rc1 = 0, rc2 = 0, rc3 = 0;
2214 
2215 		/* Horizontal position counter carry out */
2216 		uint8_t   hp0_cy = 0, hp1_cy = 0, hp2_cy = 0, hp3_cy = 0;
2217 
2218 		uint8_t   *bmpaddr = bitmap + (y * 256);
2219 
2220 		uint32_t  bank_cnt;
2221 		uint32_t  _rorevcs = 0;
2222 
2223 		rva8 = (vregs.h_val & 0x8000) || !(vregs.shift & 0x80);
2224 
2225 		/* Get RVA0_6 from TZ113 accumulator chain @ 122/123 */
2226 		rva0_6 = (vregs.h_val >> 7) & 0x7f;
2227 
2228 		/* For /WAVE bit logic later */
2229 		rva20_6 = ((rva0_6 >> 3) & 0xe) | ((rva0_6 & 2) >> 1);
2230 
2231 		/* RVA is inverted! */
2232 		ram_addr = (~rva0_6 & 0x7f) << 1;
2233 
2234 		/* Get the road RAM data for this line */
2235 		rcrdb0_15 = buggyboy_rcram[(rva_offs + ram_addr) >> 1];
2236 
2237 		/* If 15-10 == 000000, then 0 */
2238 		rcrs10 = rcrdb0_15 & 0xfc00 ? 0x0400 : 0x0000;
2239 
2240 		/* If 15-10 == 111111, then 1 */
2241 		ls161_156_a = (rcrdb0_15 & 0xfc00) == 0xfc00 ? 0x800 : 0x0000;
2242 
2243 		/* LS161 15-bit counter chain - loaded with RAM data (bar bits 10-13) */
2244 		ls161 =  ((rcrdb0_15 & 0x8000) >> 1) | ls161_156_a | rcrs10 | (rcrdb0_15 & 0x03ff);
2245 
2246 		/* SLD */
2247 		sld = (vprom[rva0_6] + vregs.slin_val) & 0x38;
2248 
2249 		/* Determine the x-offset */
2250 //      x_offs = ls161 & 7;
2251 
2252 		/* Fill vertical position shift register with bits for this line */
2253 		/* TODO; cheated slightly to shift stuff up one pixel*/
2254 		vp1 = buggyboy_rcram[(rva_offs + 0x1e2) >> 1] >= y ? 0 : 1;
2255 		vp2 = buggyboy_rcram[(rva_offs + 0x1e4) >> 1] >= y ? 0 : 1;
2256 		vp3 = buggyboy_rcram[(rva_offs + 0x1e6) >> 1] >= y ? 0 : 1;
2257 		vp4 = buggyboy_rcram[(rva_offs + 0x1e8) >> 1] >= y ? 0 : 1;
2258 		vp5 = buggyboy_rcram[(rva_offs + 0x1ea) >> 1] >= y ? 0 : 1;
2259 		vp6 = buggyboy_rcram[(rva_offs + 0x1ec) >> 1] >= y ? 0 : 1;
2260 		vp7 = buggyboy_rcram[(rva_offs + 0x1ee) >> 1] >= y ? 0 : 1;
2261 
2262 		/* Stuff */
2263 		rm0 = vp7 ? BIT(vregs.scol, 4) : BIT(vregs.scol, 12);
2264 		rm1 = vp7 ? BIT(vregs.scol, 5) : BIT(vregs.scol, 13);
2265 
2266 		/* Wall/tunnel control */
2267 		rcmd = (vp7 ? vregs.scol : vregs.scol >> 8) & 0xf;
2268 
2269 		/* Load 'em up */
2270 		LOAD_HPOS_COUNTER(0);
2271 		LOAD_HPOS_COUNTER(1);
2272 		LOAD_HPOS_COUNTER(2);
2273 		LOAD_HPOS_COUNTER(3);
2274 
2275 		/* Some PAL equations that we can evaluate outside of the x-loop */
2276 		ic4_o12 = (!vp1 && !vp2 && !vp6) || (!vp1 && !vp2 && vp7) || (vp4 && !vp6) || (vp4 && vp7);
2277 		ic4_o13 = (!vp1 && !vp2 && !vp5) || (!vp1 && !vp2 && vp7) || (vp3 && !vp5) || (vp3 && vp7);
2278 		ic149_o15 = (!vp5 && !vp6) || vp7 || !linf;
2279 		ic151_o14 = !BIT(sld, 3) || tnlmd0 || tnlmd1 || ic149_o15;
2280 
2281 		/* Load the bank counter with accumulator bits 14-5 */
2282 		bank_cnt = (vregs.ba_val >> 5) & 0x3ff;
2283 
2284 		/* Have we crossed a road gfx strip boundary? */
2285 		if (ls161 & 7)
2286 			buggyboy_get_roadpix(1, ls161, rva0_6, sld, &_rorevcs, &rc0, &rc1, &rc2, &rc3);
2287 
2288 		for (x = 0; x < 256; ++x)
2289 		{
2290 			uint32_t  pix;
2291 			uint32_t  hp0_en, hp1_en, hp2_en, hp3_en;
2292 			uint32_t  ic149_o16;
2293 			uint32_t  ic4_o18;
2294 			uint32_t  ic3_o15;
2295 			uint32_t  ic150_o12 = 0;
2296 			uint32_t  ic150_o16;
2297 			uint32_t  ic150_o17;
2298 			uint32_t  ic150_o18;
2299 			uint32_t  ic150_o19;
2300 			uint32_t  ic151_o15;
2301 			uint32_t  ic151_o16;
2302 			uint32_t  ic151_o17;
2303 			uint32_t  rcsd0_3 = 0;
2304 			uint32_t  sld5 = BIT(sld, 5);
2305 			uint32_t  sld4 = BIT(sld, 4);
2306 			uint32_t  mux;
2307 			uint32_t  cprom_addr;
2308 			uint8_t   px0, px1, px2, px3;
2309 
2310 			/* Strip pixel number */
2311 			pix = (ls161 & 7) ^ 7;
2312 
2313 			/* Horizontal position counter enables - also used as PAL inputs */
2314 			hp0_en = !(hp0_cy || hps02);
2315 			hp1_en = !(hp1_cy || hps12);
2316 			hp2_en = !(hp2_cy || hps22);
2317 			hp3_en = !(hp3_cy || hps32);
2318 
2319 			/* Load in a new road gfx strip? */
2320 			if (!(ls161 & 7))
2321 				buggyboy_get_roadpix(1, ls161, rva0_6, sld, &_rorevcs, &rc0, &rc1, &rc2, &rc3);
2322 
2323 			/* Road camber */
2324 			if (vregs.bank_mode == 0)
2325 			{
2326 				if (BIT(vregs.ba_val, 23))
2327 					bnkcs = 1;
2328 				else if (vregs.ba_val & 0x007f8000)
2329 					bnkcs = 0;
2330 				else
2331 					bnkcs = bank_cnt < 0x300;
2332 			}
2333 			else
2334 			{
2335 				if (BIT(vregs.ba_val, 23))
2336 					bnkcs = 0;
2337 				else if (vregs.ba_val & 0x007f8000)
2338 					bnkcs = 1;
2339 				else
2340 					bnkcs = bank_cnt >= 0x300;
2341 			}
2342 
2343 			px0 = BIT(rc0, pix);
2344 			px1 = BIT(rc1, pix);
2345 			px2 = BIT(rc2, pix);
2346 			px3 = BIT(rc3, pix);
2347 
2348 			/* Now go through and evaluate all the pixel logic */
2349 			if (vp2)
2350 				ic4_o18 = (hps00 && hps01 && hp3_en && !hps30)      ||
2351 							(!hp0_en && hps01 && hp3_en && !hps30)  ||
2352 							(hps00 && hps01 && !hps31)              ||
2353 							(!hp0_en && hps01 && !hps31)                ||
2354 							vp7;
2355 			else
2356 				ic4_o18 = !vp1;
2357 
2358 
2359 			if (tnlf)
2360 				ic3_o15 = (vp4 && !vp6 && !hp2_en && hps21)     ||
2361 							(vp4 && !vp6 && hps20 && hps21)     ||
2362 							(vp1 && !vp4 && !tnlmd1 && !tnlmd0) ||
2363 							(vp1 && !vp3 && !tnlmd1 && !tnlmd0) ||
2364 							(hp1_en && !hps10 && vp3 && !vp5)       ||
2365 							(!hps11 && vp3 && !vp5);
2366 			else
2367 				ic3_o15 = !ic4_o18;
2368 
2369 			ic151_o17 = (_rorevcs && !tnlmd1 && tnlmd0)     ||
2370 						(!_rorevcs && tnlmd1 && !tnlmd0)    ||
2371 						(_rorevcs && ic4_o12)               ||
2372 						(!_rorevcs && ic4_o13);
2373 
2374 			if (!ic3_o15)
2375 				ic151_o15 = (px0 && (bnkcs && wangl))   ||
2376 							(px1 && (bnkcs && wangl))   ||
2377 							ic151_o17                   ||
2378 							px2                         ||
2379 							!tnlf;
2380 			else
2381 				ic151_o15 = !tnlf;
2382 
2383 			ic151_o16 = (px1 && !px0 && tnlmd1 && !tnlmd0)  ||
2384 						(px2 && tnlmd1 && tnlmd0)           ||
2385 						ic149_o15;
2386 
2387 			mux = BIT(tcmd, 3) ? ic149_o15 : ic151_o16;
2388 
2389 			ic150_o19 = (px2 && !rva8)  ||
2390 						!bnkcs          ||
2391 						!mux            ||
2392 						!ic151_o15;
2393 
2394 			/* Don't calculate the pixel colour if not visible */
2395 			if (ic150_o19)
2396 			{
2397 				ic149_o16 = (_rorevcs && !px2 && ic151_o15)                                 ||
2398 							(tnlf && vp5 && !vp7 && px2 && !tnlmd0 && !tnlmd1 && ic151_o15) ||
2399 							(tnlf && vp6 && !vp7 && px2 && !tnlmd0 && !tnlmd1 && ic151_o15) ||
2400 							(tnlf && !ic4_o18);
2401 
2402 				ic150_o16 = (px2 && mux && rm1)         ||
2403 							(mux && rva8 && ic151_o15)  ||
2404 							(!px0 && mux)               ||
2405 							!ic151_o15;
2406 
2407 				{
2408 					uint32_t a = mux && ic151_o15;
2409 
2410 					ic150_o17 = (a && !rm0 && px0)  ||
2411 								(a && !px1)         ||
2412 								(rva8 && a);
2413 
2414 					ic150_o18 = (a && !px2) ||
2415 								(rva8 && a);
2416 				}
2417 
2418 				if (ic151_o14)
2419 					ic150_o12 = rva8 || !mux || !ic151_o15              ||
2420 								(px2 && px1 && px0 && rm1 && !rm0)      ||
2421 								(!px2 && px1 && px0 && !sld4 && rm0)    ||
2422 								(px2 && px0 && !sld5 && !rm1 && !rm0)   ||
2423 								(px2 && !px1 && px0 && !sld5 && !rm1)   ||
2424 								(px2 && px1 && px0 && !sld5 && !sld4)   ||
2425 								(px2 && px1 && px0 && !sld4 && rm1)     ||
2426 								(!px2 && !px3 && !rm0)                  ||
2427 								(!px1 && !px3 && rm1)                   ||
2428 								(!px2 && !px1 && !px3)                  ||
2429 								(!px0 && !px3);
2430 				else
2431 					ic150_o12 = 0;
2432 
2433 				if (vp6 || ic151_o16)
2434 				{
2435 					uint32_t ic150_i5 = BIT(tcmd, 3) ? ic149_o15 : ic151_o16;
2436 
2437 					if (!(ic151_o15 && ic150_i5))
2438 						cprom_addr = (tcmd & 0x7) | (ic151_o16 ? 0x08 : 0);
2439 					else
2440 						cprom_addr = rcmd;
2441 
2442 					/* Inverted! */
2443 					cprom_addr = ((~cprom_addr) & 0xf) << 4;
2444 				}
2445 				else
2446 					cprom_addr = 0xf0;
2447 
2448 				cprom_addr |= (ic149_o16 ? 0x8 : 0) |
2449 								(ic150_o18 ? 0x4 : 0) |
2450 								(ic150_o17 ? 0x2 : 0) |
2451 								(ic150_o16 ? 0x1 : 0);
2452 
2453 				/* Lower four bits of colour output come from PROM BB7 @ 188 */
2454 				rcsd0_3 = rcols[cprom_addr] & 0xf;
2455 
2456 				{
2457 					uint32_t lfsr = vregs.wave_lfsr;
2458 					uint32_t wave =
2459 								(wave0 ^ BIT(lfsr, 0))  &&
2460 								(wave1 ^ BIT(lfsr, 3))  &&
2461 								BIT(lfsr, 5)            &&
2462 								!BIT(lfsr, 15)          &&
2463 								BIT(lfsr, 11)           &&
2464 								BIT(lfsr, 13)           &&
2465 								(rva20_6 < ((lfsr >> 8) & 0xf));
2466 
2467 					*bmpaddr++ = 0x40 | (wave ? 0 : 0x20) | (ic150_o12 ? 0x10 : 0) | rcsd0_3;
2468 				}
2469 			}
2470 			else
2471 				*bmpaddr++ = 0;
2472 
2473 			/* Update the various horizontal counters */
2474 			UPDATE_HPOS(0);
2475 			UPDATE_HPOS(1);
2476 			UPDATE_HPOS(2);
2477 			UPDATE_HPOS(3);
2478 
2479 			/* Update the LFSR */
2480 			vregs.wave_lfsr = (vregs.wave_lfsr << 1) | (BIT(vregs.wave_lfsr, 6) ^ !BIT(vregs.wave_lfsr, 15));
2481 
2482 			/* Increment the bank counter */
2483 			bank_cnt = (bank_cnt + 1) & 0x7ff;
2484 
2485 			/* X pos */
2486 			ls161 = (ls161 + 1) & 0x7fff;
2487 		}
2488 
2489 		/* WANGL active? Then update the 8-bit counter */
2490 		if (wangl)
2491 		{
2492 			if (BIT(vregs.flags, BB_RDFLAG_TNLMD0))
2493 				--vregs.wa8;
2494 			else
2495 				++vregs.wa8;
2496 		}
2497 
2498 		/* No carry out - just increment */
2499 		if (vregs.wa4 != 0xf)
2500 			++vregs.wa4;
2501 		else
2502 		{
2503 			/* Carry out; increment again on /TMG2S rise */
2504 			if (wangl)
2505 			{
2506 				if (BIT(vregs.flags, BB_RDFLAG_TNLMD0))
2507 					--vregs.wa8;
2508 				else
2509 					++vregs.wa8;
2510 			}
2511 			vregs.wa4 = 1;
2512 		}
2513 
2514 		/* Update accumulator */
2515 		vregs.h_val += vregs.h_inc;
2516 
2517 		/* Seems correct */
2518 		sf = vregs.shift;
2519 
2520 		if ((vregs.shift & 0x80) == 0)
2521 		{
2522 			vregs.shift <<= 1;
2523 
2524 			if ((sf & 0x08) == 0)
2525 				vregs.shift |= BIT(vregs.h_val, 15);
2526 		}
2527 
2528 		if ((sf & 0x08) && !(vregs.shift & 0x08))
2529 			vregs.h_inc = vregs.gas;
2530 
2531 		/* Finally, increment the banking accumulator */
2532 		vregs.ba_val = (vregs.ba_val + vregs.ba_inc) & 0x00ffffff;
2533 	}
2534 }
2535 
2536 
2537 /***************************************************************************
2538 
2539     Buggy Boy Object Drawing
2540 
2541     X-scaling isn't quite right but you wouldn't notice...
2542 
2543     -------- xxxxxxxx       Object number
2544     xxxxxxxx --------       Y position
2545 
2546     xxxxxxxx xxxxxxxx       Y scale value
2547 
2548     -------- xxxxxxxx       X scale
2549                              00 = Invisible?
2550                              80 = 1:1
2551                              FF = Double size
2552     xxxxxxxx --------       Attributes
2553 
2554     xxxxxxxx xxxxxxxx       Y scale delta
2555 
2556     ------xx xxxxxxxx       X position
2557 
2558 **************************************************************************/
2559 
buggyboy_draw_objs(uint8_t * bitmap,bool wide)2560 void tx1_state::buggyboy_draw_objs(uint8_t *bitmap, bool wide)
2561 {
2562 	uint16_t *buggyboy_objram = m_objram;
2563 
2564 	uint32_t offs;
2565 
2566 	uint32_t x_mask;
2567 	uint32_t x_stride;
2568 
2569 	/* The many lookup table ROMs */
2570 	const uint8_t *const bug13  = &m_obj_luts[0];
2571 	const uint8_t *const bug18s = &m_obj_luts[0x2000];
2572 	const uint8_t *const bb8    = &m_proms[0x1600];
2573 
2574 	const uint8_t *const bug16s = &m_obj_map[0];
2575 	const uint8_t *const bug17s = &m_obj_map[0x8000];
2576 
2577 	const uint8_t *const bb9o = &m_proms[0x500];
2578 	const uint8_t *const bb9e = &m_proms[0xd00];
2579 
2580 	const uint8_t *const pixdata_rgn = &m_obj_tiles[0];
2581 
2582 	if (wide)
2583 	{
2584 		x_mask = 0x7ff;
2585 		x_stride = 768;
2586 	}
2587 	else
2588 	{
2589 		x_mask = 0x3ff;
2590 		x_stride = 256;
2591 	}
2592 
2593 	for (offs = 0; offs <= 0x300; offs += 8)
2594 	{
2595 		uint32_t  x;
2596 		uint32_t  y;
2597 		uint32_t  gxflip;
2598 
2599 		uint32_t  x_scale;
2600 		uint32_t  x_step;
2601 		uint16_t  y_scale;
2602 		uint16_t  y_step;
2603 
2604 		uint8_t   pctmp0_7;
2605 		uint8_t   code;
2606 
2607 		/* Check for end of object list */
2608 		if ((buggyboy_objram[offs] & 0xff00) == 0xff00)
2609 			break;
2610 
2611 		/* X scale */
2612 		x_scale = buggyboy_objram[offs + 2] & 0xff;
2613 
2614 		/* TODO: Confirm against hardware? */
2615 		if (x_scale == 0)
2616 			continue;
2617 
2618 		/* 16-bit y-scale accumulator */
2619 		y_scale = buggyboy_objram[offs + 1];
2620 		y_step  = buggyboy_objram[offs + 3];
2621 
2622 		/* Object number */
2623 		code = buggyboy_objram[offs] & 0xff;
2624 
2625 		/* Attributes */
2626 		pctmp0_7 = buggyboy_objram[offs + 2] >> 8;
2627 
2628 		/* Global x-flip */
2629 		gxflip = (pctmp0_7 & 0x80) >> 7;
2630 
2631 		/* Add 1 to account for line buffering */
2632 		y = (buggyboy_objram[offs] >> 8) + 1;
2633 
2634 		for (; y < 240; ++y)
2635 		{
2636 			uint32_t  rom_addr2   = 0;
2637 			uint8_t   bug17s_data = 0;
2638 			uint8_t   bug16s_data;
2639 
2640 			/* Are we drawing on this line? */
2641 
2642 			// TODO: See big lampposts.
2643 			if (y_scale & 0x8000)
2644 				break;
2645 
2646 			{
2647 				uint32_t  psa0_12;
2648 				uint32_t  bug13_addr;
2649 				uint32_t  bug13_data;
2650 				uint32_t  rom_addr;
2651 				uint32_t  x_acc;
2652 				uint32_t  newtile = 1;
2653 				uint32_t  dataend = 0;
2654 				uint8_t   data1 = 0;
2655 				uint8_t   data2 = 0;
2656 				uint32_t  xflip = 0;
2657 				uint32_t  opcd10_11;
2658 				uint32_t  opcd8_9;
2659 				uint32_t  opcd0_11 = 0;
2660 				uint32_t  lasttile = 0;
2661 
2662 				/* Use the object code to lookup the tile sequence data */
2663 				bug13_addr = code << 4;
2664 				bug13_addr |= ((y_scale >> 11) & 0xf);
2665 				bug13_data = bug13[bug13_addr];
2666 
2667 				/* Reached the bottom of the object */
2668 				if (bug13_data == 0xff)
2669 					break;
2670 
2671 				psa0_12  = (((code & 0x80) << 5) | ((code & 0x40) << 6)) & 0x1000;
2672 				psa0_12 |= ((bb8[code] << 8) | bug13_data) & 0x1fff;
2673 
2674 				/* Static part of the BUG17S/BUG16S ROM address */
2675 				rom_addr = (psa0_12 & ~0xff) << 2;
2676 
2677 				/* Prepare the x-scaling */
2678 				x_step = (128 << OBJ_FRAC) / x_scale;
2679 				x_acc = (psa0_12 & 0xff) << (OBJ_FRAC + 5);
2680 
2681 				/* TODO Add note */
2682 				x = buggyboy_objram[offs + 4] & x_mask;
2683 
2684 				for (;;)
2685 				{
2686 					/* Get data and attributes for an 8x8 tile */
2687 					if (newtile)
2688 					{
2689 						uint32_t  pscb0_11;
2690 						uint32_t  psbb0_15;
2691 						uint32_t  psbb6_7;
2692 						uint32_t  rombank;
2693 						uint8_t   *romptr;
2694 						uint32_t  bug18s_data;
2695 						uint32_t  low_addr = ((x_acc >> (OBJ_FRAC + 3)) & x_mask);
2696 
2697 						/*
2698 						    Objects are grouped by width (either 16, 8 or 4 tiles) in
2699 						    the LUT ROMs. The ROM address lines therefore indicate
2700 						    width and are used to determine the correct scan order
2701 						    when x-flip is set.
2702 						*/
2703 						if (gxflip)
2704 						{
2705 							uint32_t  xor_mask;
2706 
2707 							if (BIT(psa0_12, 11) || !BIT(psa0_12, 12))
2708 								xor_mask = 0xf;
2709 							else if (!BIT(psa0_12, 9))
2710 								xor_mask = 0x7;
2711 							else
2712 								xor_mask = 0x3;
2713 
2714 							rom_addr2 = rom_addr + (low_addr ^ xor_mask);
2715 						}
2716 						else
2717 							rom_addr2 = rom_addr + low_addr;
2718 
2719 						bug17s_data = bug17s[rom_addr2 & 0x7fff];
2720 
2721 						if ((bug17s_data & 0x40) && dataend)
2722 							lasttile = 1;
2723 
2724 						dataend |= (bug17s_data & 0x40);
2725 
2726 						/* Retrieve data for an 8x8 tile */
2727 						bug16s_data = bug16s[rom_addr2 & 0x7fff];
2728 						psbb0_15 = (bug17s_data << 8) | bug16s_data;
2729 						psbb6_7 = (BIT(psbb0_15, 12) ? psbb0_15 : (pctmp0_7 << 6)) & 0xc0;
2730 
2731 						/* Form the tile ROM address */
2732 						pscb0_11 = ((((psbb0_15 & ~0xc0) | psbb6_7) << 3) | ((y_scale >> 8) & 7)) & 0x7fff;
2733 
2734 						/* Choose from one of three banks */
2735 						rombank = ((BIT(pctmp0_7, 4) << 1) | BIT(psbb0_15, 13)) & 3;
2736 
2737 						romptr = (uint8_t*)(pixdata_rgn + rombank * (0x8000 * 2));
2738 
2739 						/* Get raw 8x8 pixel row data */
2740 						data1 = *(pscb0_11 + romptr);
2741 						data2 = *(pscb0_11 + romptr + 0x8000);
2742 
2743 						/* Determine flip state (global XOR local) */
2744 						xflip = gxflip ^ !BIT(psbb0_15, 15);
2745 
2746 						bug18s_data = bug18s[ (BIT(pctmp0_7, 4)  << 13) |
2747 												(BIT(psbb0_15, 13) << 12)   |
2748 												(psbb0_15 & ~0xf0c0)        |
2749 												psbb6_7 ];
2750 
2751 						/* Get the colour data. Note that bits 11 and 10 are inverted */
2752 						opcd10_11 = ((pctmp0_7 << 8) & 0xc00) ^ 0xc00;
2753 						opcd8_9 = ((pctmp0_7 & 0x60) << 3);
2754 						opcd0_11 = (opcd10_11 | opcd8_9 | bug18s_data) & 0xfff;
2755 
2756 						newtile = 0;
2757 					}
2758 
2759 					/* Draw a pixel? */
2760 					if (x < x_stride)
2761 					{
2762 						uint8_t   pix;
2763 						uint8_t   bit;
2764 
2765 						bit = (x_acc >> OBJ_FRAC) & 7;
2766 
2767 						if (xflip)
2768 							bit ^= 7;
2769 
2770 						pix = (((data1 >> bit) & 1) << 1) | ((data2 >> bit) & 1);
2771 
2772 						/* Write the pixel if not transparent */
2773 						if (!(!(opcd0_11 & 0x80) && !pix))
2774 						{
2775 							uint8_t color;
2776 							uint32_t bb9_addr;
2777 
2778 							bb9_addr = ((opcd0_11 << 1) & 0x600) | ((opcd0_11 & 0x7f) << 2) | pix;
2779 							color = ((opcd0_11 >> 6) & 0x30);
2780 
2781 							/* Inverted on schematic */
2782 							if (x & 1)
2783 								color = ~(color | bb9o[bb9_addr]) & 0x3f;
2784 							else
2785 								color = ~(color | bb9e[bb9_addr]) & 0x3f;
2786 
2787 							*(bitmap + x_stride*y + x) = 0x40 | color;
2788 						}
2789 					}
2790 
2791 					/* Check if we've stepped into a new 8x8 tile */
2792 					if ((((x_acc + x_step) >> (OBJ_FRAC + 3)) & x_mask) != ((x_acc >> (OBJ_FRAC + 3)) & x_mask))
2793 					{
2794 						if (lasttile)
2795 							break;
2796 
2797 						newtile = 1;
2798 					}
2799 
2800 					x = (x + 1) & x_mask;
2801 					x_acc += x_step;
2802 				}
2803 			}// if (yscale)
2804 			y_scale += y_step;
2805 		} /* for (y) */
2806 	}/* for (offs) */
2807 }
2808 
2809 
2810 /*************************************
2811  *
2812  *  Video Control Registers
2813  *
2814  *************************************/
2815 
2816 /*
2817     2400-24FF is road control (R/W)
2818 
2819     /GAS = 24XX:
2820     /BASET0 = 2400-F, 2410-F
2821     /BASET1 = 2420-F, 2430-F
2822     /BSET   = 2440-F, 2450-F
2823     /HASET  = 2460-F, 2470-F
2824     /HSET   = 2480-F, 2490-F
2825     /WASET  = 24A0-F, 24B0-F
2826     /FLAGS  = 24E0-F, 24F0-F
2827 */
buggyboy_gas_w(offs_t offset,uint16_t data)2828 void tx1_state::buggyboy_gas_w(offs_t offset, uint16_t data)
2829 {
2830 	vregs_t &vregs = m_vregs;
2831 	offset <<= 1;
2832 
2833 	switch (offset & 0xe0)
2834 	{
2835 		case 0x00:
2836 		{
2837 			vregs.ba_inc &= ~0x0000ffff;
2838 			vregs.ba_inc |= data;
2839 
2840 			if (!(offset & 2))
2841 				vregs.ba_val &= ~0x0000ffff;
2842 
2843 			break;
2844 		}
2845 		case 0x20:
2846 		{
2847 			data &= 0xff;
2848 			vregs.ba_inc &= ~0xffff0000;
2849 			vregs.ba_inc |= data << 16;
2850 
2851 			vregs.bank_mode = data & 1;
2852 
2853 			if (!(offset & 2))
2854 				vregs.ba_val &= ~0xffff0000;
2855 
2856 			break;
2857 		}
2858 		case 0x40:
2859 		{
2860 			/* Ignore data? */
2861 			if (offset & 2)
2862 				vregs.ba_val = (vregs.ba_inc + vregs.ba_val) & 0x00ffffff;
2863 
2864 			break;
2865 		}
2866 		case 0x60:
2867 		{
2868 			vregs.h_inc = data;
2869 			vregs.shift = 0;
2870 
2871 			if (!(offset & 2))
2872 				vregs.h_val = 0;
2873 
2874 			break;
2875 		}
2876 		case 0x80:
2877 		{
2878 			/* Ignore data? */
2879 			if (offset & 2)
2880 				vregs.h_val += vregs.h_inc;
2881 			break;
2882 		}
2883 		case 0xa0:
2884 		{
2885 			vregs.wa8 = data >> 8;
2886 			vregs.wa4 = 0;
2887 			break;
2888 		}
2889 		case 0xe0:
2890 		{
2891 			m_mathcpu->set_input_line(INPUT_LINE_TEST, CLEAR_LINE);
2892 			vregs.flags = data;
2893 			break;
2894 		}
2895 	}
2896 
2897 	/* Value is latched by LS373 76/77 */
2898 	vregs.gas = data;
2899 }
2900 
buggyboy_sky_w(uint16_t data)2901 void tx1_state::buggyboy_sky_w(uint16_t data)
2902 {
2903 	m_vregs.sky = data;
2904 }
2905 
buggyboy_scolst_w(uint16_t data)2906 void tx1_state::buggyboy_scolst_w(uint16_t data)
2907 {
2908 	m_vregs.scol = data;
2909 }
2910 
2911 
2912 /*************************************
2913  *
2914  *  Core Functions
2915  *
2916  *************************************/
2917 
bb_combine_layers(bitmap_ind16 & bitmap,int screen)2918 void tx1_state::bb_combine_layers(bitmap_ind16 &bitmap, int screen)
2919 {
2920 	uint8_t const *const chr_pal = &m_proms[0x400];
2921 	uint32_t bmp_stride;
2922 	uint32_t x_offset;
2923 
2924 	if (screen < 0)
2925 	{
2926 		bmp_stride = 256;
2927 		x_offset = 0;
2928 	}
2929 	else
2930 	{
2931 		bmp_stride = 768;
2932 		x_offset = 256 * screen;
2933 	}
2934 
2935 	for (uint32_t y = 0; y < 240; ++y)
2936 	{
2937 		uint32_t bmp_offset = y * bmp_stride + x_offset;
2938 
2939 		uint8_t *chr_addr = m_chr_bmp.get() + bmp_offset;
2940 		uint8_t *rod_addr = m_rod_bmp.get() + bmp_offset;
2941 		uint8_t *obj_addr = m_obj_bmp.get() + bmp_offset;
2942 
2943 		uint32_t sky_en = BIT(m_vregs.sky, 7);
2944 		uint32_t sky_val = (((m_vregs.sky & 0x7f) + y) >> 2) & 0x3f;
2945 
2946 		uint16_t *bmp_addr = &bitmap.pix(y);
2947 
2948 		for (uint32_t x = 0; x < 256; ++x)
2949 		{
2950 			uint32_t out_val;
2951 
2952 			uint32_t char_val = *chr_addr++;
2953 			uint32_t char_6_7 = (char_val & 0xc0) >> 2;
2954 
2955 			uint32_t obj_val = *obj_addr++;
2956 			uint32_t obj6 = BIT(obj_val, 6);
2957 
2958 			uint32_t rod_val = *rod_addr++;
2959 			uint32_t rod6 = BIT(rod_val, 6);
2960 
2961 			uint32_t chr = !(BIT(char_val, 7) && (char_val & 3) );
2962 
2963 			uint32_t sel =
2964 			(
2965 				( BIT(obj_val, 6) && chr) ||
2966 				( sky_en && !(char_val & 3) && (!obj6 && !rod6) )
2967 			) ? 0 : 1;
2968 
2969 			sel |= (!(obj6 || rod6) || !chr) ? 2 : 0;
2970 
2971 			/* Select the layer */
2972 			if      (sel == 0)  out_val = obj_val & 0x3f;
2973 			else if (sel == 1)  out_val = rod_val & 0x3f;
2974 			else if (sel == 2)  out_val = sky_val;
2975 			else                out_val = char_6_7 + chr_pal[char_val];
2976 
2977 			*bmp_addr++ = (sel << 6) + out_val;
2978 		}
2979 	}
2980 }
2981 
VIDEO_START_MEMBER(tx1_state,buggyboy)2982 VIDEO_START_MEMBER(tx1_state,buggyboy)
2983 {
2984 	/* Allocate some bitmaps */
2985 	m_chr_bmp = std::make_unique<uint8_t[]>(3 * 256 * 240);
2986 	m_obj_bmp = std::make_unique<uint8_t[]>(3 * 256 * 240);
2987 	m_rod_bmp = std::make_unique<uint8_t[]>(3 * 256 * 240);
2988 
2989 	/* Set a timer to run the interrupts */
2990 	m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx1_state::interrupt_callback),this));
2991 
2992 	/* /CUDISP CRTC interrupt */
2993 	m_interrupt_timer->adjust(m_screen->time_until_pos(CURSOR_YPOS, CURSOR_XPOS));
2994 }
2995 
VIDEO_START_MEMBER(tx1_state,buggybjr)2996 VIDEO_START_MEMBER(tx1_state,buggybjr)
2997 {
2998 	/* Allocate some bitmaps */
2999 	m_chr_bmp = std::make_unique<uint8_t[]>(256 * 240);
3000 	m_obj_bmp = std::make_unique<uint8_t[]>(256 * 240);
3001 	m_rod_bmp = std::make_unique<uint8_t[]>(256 * 240);
3002 
3003 	/* Set a timer to run the interrupts */
3004 	m_interrupt_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tx1_state::interrupt_callback),this));
3005 
3006 	/* /CUDISP CRTC interrupt */
3007 	m_interrupt_timer->adjust(m_screen->time_until_pos(CURSOR_YPOS, CURSOR_XPOS));
3008 }
3009 
WRITE_LINE_MEMBER(tx1_state::screen_vblank_buggyboy)3010 WRITE_LINE_MEMBER(tx1_state::screen_vblank_buggyboy)
3011 {
3012 	// rising edge
3013 	if (state)
3014 	{
3015 		/* /VSYNC: Update TZ113 @ 219 */
3016 		m_vregs.slin_val += m_vregs.slin_inc;
3017 
3018 		/* /VSYNC: Clear wave LFSR */
3019 		m_vregs.wave_lfsr = 0;
3020 
3021 		m_needs_update = true;
3022 	}
3023 }
3024 
3025 
bb_update_layers()3026 void tx1_state::bb_update_layers()
3027 {
3028 	memset(m_obj_bmp.get(), 0, 768*240);
3029 	memset(m_rod_bmp.get(), 0, 768*240);
3030 
3031 	buggyboy_draw_char(m_chr_bmp.get(), 1);
3032 	buggyboy_draw_road(m_rod_bmp.get());
3033 	buggyboy_draw_objs(m_obj_bmp.get(), 1);
3034 
3035 	m_needs_update = false;
3036 }
3037 
screen_update_buggyboy_left(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)3038 uint32_t tx1_state::screen_update_buggyboy_left(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3039 {
3040 	if (m_needs_update)
3041 		bb_update_layers();
3042 
3043 	bb_combine_layers(bitmap, 0);
3044 	return 0;
3045 }
3046 
screen_update_buggyboy_middle(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)3047 uint32_t tx1_state::screen_update_buggyboy_middle(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3048 {
3049 	if (m_needs_update)
3050 		bb_update_layers();
3051 
3052 	bb_combine_layers(bitmap, 1);
3053 	return 0;
3054 }
3055 
screen_update_buggyboy_right(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)3056 uint32_t tx1_state::screen_update_buggyboy_right(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3057 {
3058 	if (m_needs_update)
3059 		bb_update_layers();
3060 
3061 	bb_combine_layers(bitmap, 2);
3062 	return 0;
3063 }
3064 
screen_update_buggybjr(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)3065 uint32_t tx1_state::screen_update_buggybjr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
3066 {
3067 	memset(m_obj_bmp.get(), 0, 256*240);
3068 
3069 	buggyboy_draw_char(m_chr_bmp.get(), 0);
3070 	buggybjr_draw_road(m_rod_bmp.get());
3071 	buggyboy_draw_objs(m_obj_bmp.get(), 0);
3072 
3073 	bb_combine_layers(bitmap, -1);
3074 	return 0;
3075 }
3076