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