1 // license:BSD-3-Clause
2 // copyright-holders:Philip Bennett, Anonymous
3 /******************************************************************************
4
5 Bell-Fruit Cobra I/II and Viper Hardware
6
7 driver by Phil Bennett and Anonymous
8
9 Games supported:
10 * A Question of Sport [2 sets]
11 * Beeline (non-working - missing disk)
12 * Every Second Counts
13 * Inquizitor (Viper hardware, non-working - missing disk)
14 * Quizvaders
15 * Treble Top
16
17 Other games on this hardware:
18 * Brain Box
19 * Quintoon alt. version (Cobra II/Cyclone hardware)
20
21 Notes:
22
23 The hardware is based on a chipset known as 'Flare One', developed
24 by Flare Technology. It consists of a 16-bit DSP (intended for sound
25 synthesis and 3D maths), an 8bpp blitter and a video controller, driven
26 by a Z80.
27
28 Flare One would evolve to become 'Slipstream', used by the unreleased
29 Konix Multisystem console.
30
31 The Flare One chipset is implemented as four Texas Instruments ASICs,
32 each an 84 pin PLCC package:
33
34 CF30204, CF30205, CF30206 (DSP) and CF30207.
35
36 The hardware using this chipset is as follows:
37
38 Viper
39 =====
40
41 A video expansion PCB for Scorpion I?
42 On some PCB revisions there is audio output circuitry connected to the DSP.
43 Viper uses a WD1772 type floppy disk controller.
44
45 Cobra I
46 =======
47
48 A combination of Viper and Scorpion I hardware on a single PCB.
49 Cobra uses an NEC '765 type FDC. Later revisions have no DSP.
50
51 Cobra II (Cyclone)
52 ==================
53
54 A compact video expansion board for Scorpion II.
55 The Z80 is replaced by a Z180 and there is no Flare DSP.
56 The FDC is replaced by a NCR53C80 SCSI controller.
57 Cyclone was never released due to reliability issues.
58
59 Cobra II Jamma
60 ==============
61 Based on Cobra II but with a JAMMA edge connector for easy use in video game cabinets.
62 This is a standalone board which is not paired with any Scorpion boards.
63 Break Ball is the only released game for this platform.
64 The only other known software is for a functional test unit (FTU).
65
66 Note that for Z8S180 boards the CPU has 20 address lines so can select the entire memory map
67 without using the Flare chipset paging option. I believe changing the addresses using chipset_w
68 have no effect on Z8S180 boards.
69
70 To do:
71
72 * Complete blitter emulation
73 * Cobra II support.
74 * Hook up additional inputs, EM meters, lamps etc
75 * The prom range selected for the first 16K of Z80 memory map is not fixed so chipset_w
76 function needs changing to process offset 0. Note that no released software changes this anyway.
77 * Frame interrupt for Z80 boards is wrong. It isn't a frame interrupt but an interrupt which can be
78 triggered on any scan line. For Z80 boards the fact that it's treated as a frame interrupt doesn't
79 matter as no released software changes the position of the interrupt. Emulation for Z8S180 boards
80 is correct as Break Ball uses multiple scan line interrupts.
81
82 Known issues:
83
84 * All games bar qos: NVRAM not saved
85
86 * Viper does not have a colour palette - the Flare chipset drives RGB direct.
87 To fix this I set default values in the palette when the machine is initialised
88 * CPU execution rate is wrong, the hardware adds 1 TCycle to each access which is unaccounted for.
89 * Plane priority is probably wrong but it's only used in Treble Top.
90 * Blitter loop counts and step are wrong - they are 9 bit counts, not 8.
91 * Blitter emulation doesn't support hi-res mode (needed for Inquizitor)
92 * Blitter emulation currently runs until blit is complete then burns the required number of Z80
93 cycles to simulate it holding the bus. On the real hardware the blitter halts the CPU until the
94 operation is complete or an interrupt is issued to CPU. When the interrupt line is asserted the
95 CPU is allowed to run until the interrupt line is released. This allows all interrupts to run at
96 the correct time. The current emulation is OK for Z80 boards and all released software for those
97 boards, however, for Cobra II/JAMMA this causes problems due to the UPD7759 audio chip issuing
98 dma requests which are then processed too late if the Z8S180 cycles are burnt. To get round this
99 the Z8S180 blitter emulation does not burn CPU cycles.
100 The blitter emulation ought to take account of irq/dma requests but I don't know how to do that!
101
102 ******************************************************************************/
103
104 #include "emu.h"
105
106 #include "video/bfm_dm01.h"
107
108 #include "cpu/m6809/m6809.h"
109 #include "cpu/z80/z80.h"
110 #include "cpu/z180/z180.h"
111 #include "machine/6850acia.h"
112 #include "machine/clock.h"
113 #include "machine/i2cmem.h"
114 #include "machine/meters.h"
115 #include "machine/nvram.h"
116 #include "sound/ay8910.h"
117 #include "sound/upd7759.h"
118 #include "sound/ym2413.h"
119 #include "video/ramdac.h"
120
121 #include "emupal.h"
122 #include "screen.h"
123 #include "speaker.h"
124
125 #include "brkball.lh"
126
127
128 /*
129 Defines
130 */
131 #define Z8S180_XTAL 24000000
132 #define Z80_XTAL 5910000 /* Unconfirmed */
133 #define M6809_XTAL 4000000
134
135
136
137 /***************************************************************************
138
139 Split into video\bfcobra.cpp !
140
141 ***************************************************************************/
142
143 union ADDR_REG
144 {
145 #ifdef LSB_FIRST
146 struct { uint16_t loword, hiword ; } as16bit;
147 struct { uint8_t addr0, addr1, addr2; } as8bit;
148 #else
149 struct { uint16_t hiword, loword ; } as16bit;
150 struct { uint8_t addr2, addr1, addr0; } as8bit;
151 #endif
152 uint32_t addr;
153 };
154
155 /* Blitter register flag bits */
156 #define CMD_RUN 0x01
157 #define CMD_COLST 0x02
158 #define CMD_PARRD 0x04 /* Never used? */
159 #define CMD_SRCUP 0x08
160 #define CMD_DSTUP 0x10
161 #define CMD_LT0 0x20
162 #define CMD_LT1 0x40
163 #define CMD_LINEDRAW 0x80
164
165
166 /* All unconfirmed */
167 //#define SRCDST_CMP 0x10
168 //#define SRCDST_WRAP 0x20
169 //#define SRCDST_SIGN 0x40
170 #define SRCDST_A_1 0x80 /* This might be correct for line drawing? */
171
172 /* These appear to be correct */
173 #define MODE_SSIGN 0x80
174 #define MODE_DSIGN 0x40
175 #define MODE_YFRAC 0x20
176 #define MODE_BITTOBYTE 0x04
177 #define MODE_PALREMAP 0x10
178
179 #define CMPFUNC_LT 0x01
180 #define CMPFUNC_EQ 0x02
181 #define CMPFUNC_GT 0x04
182 #define CMPFUNC_BEQ 0x08
183 #define CMPFUNC_LOG0 0x10
184 #define CMPFUNC_LOG1 0x20
185 #define CMPFUNC_LOG2 0x40
186 #define CMPFUNC_LOG3 0x80
187
188 /*
189 Blitter state
190 */
191 struct bf_blitter_t
192 {
193 ADDR_REG program;
194
195 uint8_t control;
196 uint8_t status;
197
198 uint8_t command;
199 ADDR_REG source;
200 ADDR_REG dest;
201 uint8_t modectl;
202 uint8_t compfunc;
203 uint8_t outercnt;
204
205 uint8_t innercnt;
206 uint8_t step;
207 uint8_t pattern;
208 };
209
210 #define LOOPTYPE ( ( blitter.command&0x60 ) >> 5 )
211
212 struct fdc_t
213 {
214 uint8_t MSR;
215
216 int side;
217 int track;
218 int sector;
219 int number;
220 int stop_track;
221 int setup_read;
222
223 int byte_pos;
224 int offset;
225
226 int phase;
227 int next_phase;
228 int cmd_len;
229 int cmd_cnt;
230 int res_len;
231 int res_cnt;
232 uint8_t cmd[10];
233 uint8_t results[8];
234 };
235
236
237 #define BLUE_0 0
238 #define BLUE_1 1
239 #define BLUE_2 2
240 #define BLUE_3 3
241 #define GREEN_0 ( 0 << 2 )
242 #define GREEN_1 ( 1 << 2 )
243 #define GREEN_2 ( 2 << 2 )
244 #define GREEN_3 ( 3 << 2 )
245 #define GREEN_4 ( 4 << 2 )
246 #define GREEN_5 ( 5 << 2 )
247 #define GREEN_6 ( 6 << 2 )
248 #define GREEN_7 ( 7 << 2 )
249 #define RED_0 ( 0 << 5 )
250 #define RED_1 ( 1 << 5 )
251 #define RED_2 ( 2 << 5 )
252 #define RED_3 ( 3 << 5 )
253 #define RED_4 ( 4 << 5 )
254 #define RED_5 ( 5 << 5 )
255 #define RED_6 ( 6 << 5 )
256 #define RED_7 ( 7 << 5 )
257
258 class bfcobra_state : public driver_device
259 {
260 public:
bfcobra_state(const machine_config & mconfig,device_type type,const char * tag)261 bfcobra_state(const machine_config &mconfig, device_type type, const char *tag) :
262 driver_device(mconfig, type, tag),
263 m_maincpu(*this, "maincpu"),
264 m_audiocpu(*this, "audiocpu"),
265 m_acia6850_0(*this, "acia6850_0"),
266 m_acia6850_1(*this, "acia6850_1"),
267 m_acia6850_2(*this, "acia6850_2"),
268 m_upd7759(*this, "upd"),
269 m_palette(*this, "palette"),
270 m_meters(*this, "meters")
271 {
272 }
273
274 void init_bfcobra();
275 void bfcobra(machine_config &config);
276
277 protected:
278 uint8_t chipset_r(offs_t offset);
279 void chipset_w(offs_t offset, uint8_t data);
280 void rombank_w(uint8_t data);
281 uint8_t fdctrl_r();
282 uint8_t fddata_r();
283 void fdctrl_w(uint8_t data);
284 uint8_t int_latch_r();
285 uint8_t meter_r();
286 void meter_w(uint8_t data);
287 uint8_t latch_r();
288 void latch_w(offs_t offset, uint8_t data);
289 uint8_t upd_r();
290 void upd_w(uint8_t data);
291 DECLARE_WRITE_LINE_MEMBER(z80_acia_irq);
292 DECLARE_WRITE_LINE_MEMBER(m6809_data_irq);
293 DECLARE_WRITE_LINE_MEMBER(data_acia_tx_w);
294 DECLARE_WRITE_LINE_MEMBER(write_acia_clock);
295 virtual void machine_reset() override;
296 virtual void video_start() override;
297 uint32_t screen_update_bfcobra(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
298 INTERRUPT_GEN_MEMBER(timer_irq);
299 INTERRUPT_GEN_MEMBER(vblank_gen);
300 void RunBlit();
301 void update_irqs();
302 void reset_fdc();
303 void exec_w_phase(uint8_t data);
304 void init_ram();
305 void command_phase(struct fdc_t &fdc, uint8_t data);
306 inline uint8_t* blitter_get_addr(uint32_t addr);
307 inline void z80_bank(int num, int data);
308
309 void m6809_prog_map(address_map &map);
310 void ramdac_map(address_map &map);
311 void z80_io_map(address_map &map);
312 void z80_prog_map(address_map &map);
313
314 private:
315 uint8_t m_bank_data[4];
316 std::unique_ptr<uint8_t[]> m_work_ram;
317 std::unique_ptr<uint8_t[]> m_video_ram;
318 uint8_t m_h_scroll;
319 uint8_t m_v_scroll;
320 uint8_t m_flip_8;
321 uint8_t m_flip_22;
322 uint8_t m_videomode;
323 uint8_t m_data_r;
324 uint8_t m_data_t;
325 int m_irq_state;
326 int m_acia_irq;
327 int m_vblank_irq;
328 int m_blitter_irq;
329 uint8_t m_z80_int;
330 uint8_t m_z80_inten;
331 uint32_t m_meter_latch;
332 uint32_t m_mux_input;
333 uint32_t m_mux_outputlatch;
334 uint8_t m_col4bit[16];
335 uint8_t m_col3bit[16];
336 uint8_t m_col8bit[256];
337 uint8_t m_col7bit[256];
338 uint8_t m_col6bit[256];
339 struct bf_blitter_t m_blitter;
340 struct fdc_t m_fdc;
341 required_device<cpu_device> m_maincpu;
342 required_device<cpu_device> m_audiocpu;
343 required_device<acia6850_device> m_acia6850_0;
344 required_device<acia6850_device> m_acia6850_1;
345 required_device<acia6850_device> m_acia6850_2;
346 required_device<upd7759_device> m_upd7759;
347 required_device<palette_device> m_palette;
348 required_device<meters_device> m_meters;
349 };
350
351
352 static const uint8_t col4bit_default[16]=
353 {
354 BLUE_0 | GREEN_0 | RED_0,
355 BLUE_1,
356 GREEN_2,
357 BLUE_1 | GREEN_2,
358 RED_2,
359 RED_2 | BLUE_1,
360 RED_2 | GREEN_2,
361 RED_2 | GREEN_2 | BLUE_1,
362 BLUE_2 | GREEN_5 | RED_5,
363 BLUE_3,
364 GREEN_7,
365 BLUE_3 | GREEN_7,
366 RED_7,
367 RED_7 | BLUE_3,
368 RED_7 | GREEN_7,
369 RED_7 | GREEN_7 | BLUE_3
370 };
371
372 static const uint8_t col3bit_default[16]=
373 {
374 0,
375 BLUE_3,
376 GREEN_7,
377 BLUE_3 | GREEN_7,
378 RED_7,
379 RED_7 | BLUE_3,
380 RED_7 | GREEN_7,
381 RED_7 | GREEN_7 | BLUE_3,
382 0,
383 BLUE_3,
384 GREEN_7,
385 BLUE_3 | GREEN_7,
386 RED_7,
387 RED_7 | BLUE_3,
388 RED_7 | GREEN_7,
389 RED_7 | GREEN_7 | BLUE_3
390 };
391
392 static const uint8_t col76index[] = {0, 2, 4, 7};
393
394
video_start()395 void bfcobra_state::video_start()
396 {
397 int i;
398
399 memcpy(m_col4bit, col4bit_default, sizeof(m_col4bit));
400 memcpy(m_col3bit, col3bit_default, sizeof(m_col3bit));
401 for (i = 0; i < 256; ++i)
402 {
403 uint8_t col;
404
405 m_col8bit[i] = i;
406 col = i & 0x7f;
407 col = (col & 0x1f) | (col76index[ ( (col & 0x60) >> 5 ) & 3] << 5);
408 m_col7bit[i] = col;
409
410 col = (col & 3) | (col76index[( (col & 0x0c) >> 2) & 3] << 2 ) |
411 (col76index[( (col & 0x30) >> 4) & 3] << 5 );
412 m_col6bit[i] = col;
413 }
414 }
415
screen_update_bfcobra(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)416 uint32_t bfcobra_state::screen_update_bfcobra(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
417 {
418 /* Select screen has to be programmed into two registers */
419 /* No idea what happens if the registers are different */
420 uint32_t offset;
421 if (m_flip_8 & 0x40 && m_flip_22 & 0x40)
422 offset = 0x10000;
423 else
424 offset = 0;
425
426 uint8_t const *hirescol;
427 uint8_t const *lorescol;
428 if(m_videomode & 0x20)
429 {
430 hirescol = m_col3bit;
431 lorescol = m_col7bit;
432 }
433 else if(m_videomode & 0x40)
434 {
435 hirescol = m_col4bit;
436 lorescol = m_col6bit;
437 }
438 else
439 {
440 hirescol = m_col4bit;
441 lorescol = m_col8bit;
442 }
443
444 for (int y = cliprect.top(); y <= cliprect.bottom(); ++y)
445 {
446 uint16_t y_offset = (y + m_v_scroll) * 256;
447 uint8_t const *const src = &m_video_ram[offset + y_offset];
448 uint32_t *dest = &bitmap.pix(y);
449
450 for (int x = cliprect.left(); x <= cliprect.right() / 2; ++x)
451 {
452 uint8_t const x_offset = x + m_h_scroll;
453 uint8_t const pen = *(src + x_offset);
454
455 if ( ( m_videomode & 0x81 ) == 1 || (m_videomode & 0x80 && pen & 0x80) )
456 {
457 *dest++ = m_palette->pen(hirescol[pen & 0x0f]);
458 *dest++ = m_palette->pen(hirescol[(pen >> 4) & 0x0f]);
459 }
460 else
461 {
462 *dest++ = m_palette->pen(lorescol[pen]);
463 *dest++ = m_palette->pen(lorescol[pen]);
464 }
465 }
466 }
467
468 return 0;
469 }
470
blitter_get_addr(uint32_t addr)471 uint8_t* bfcobra_state::blitter_get_addr(uint32_t addr)
472 {
473 if (addr < 0x10000)
474 {
475 /* Is this region fixed? */
476 return (uint8_t*)(memregion("user1")->base() + addr);
477 }
478 else if(addr < 0x20000)
479 {
480 addr &= 0xffff;
481 addr += (m_bank_data[0] & 1) ? 0x10000 : 0;
482
483 return (uint8_t*)(memregion("user1")->base() + addr + ((m_bank_data[0] >> 1) * 0x20000));
484 }
485 else if (addr >= 0x20000 && addr < 0x40000)
486 {
487 return (uint8_t*)&m_video_ram[addr - 0x20000];
488 }
489 else
490 {
491 return (uint8_t*)&m_work_ram[addr - 0x40000];
492 }
493 }
494
495
496 /*
497 This is based this on the Slipstream technical reference manual.
498 The Flare One blitter is a simpler design with slightly different parameters
499 and will require hardware tests to figure everything out correctly.
500 */
RunBlit()501 void bfcobra_state::RunBlit()
502 {
503 #define BLITPRG_READ(x) blitter.x = *(blitter_get_addr(blitter.program.addr++))
504
505 struct bf_blitter_t &blitter = m_blitter;
506 int cycles_used = 0;
507
508
509 do
510 {
511 uint8_t srcdata = 0;
512 uint8_t dstdata = 0;
513
514 /* Read the blitter command */
515 BLITPRG_READ(source.as8bit.addr0);
516 BLITPRG_READ(source.as8bit.addr1);
517 BLITPRG_READ(source.as8bit.addr2);
518 BLITPRG_READ(dest.as8bit.addr0);
519 BLITPRG_READ(dest.as8bit.addr1);
520 BLITPRG_READ(dest.as8bit.addr2);
521 BLITPRG_READ(modectl);
522 BLITPRG_READ(compfunc);
523 BLITPRG_READ(outercnt);
524 BLITPRG_READ(innercnt);
525 BLITPRG_READ(step);
526 BLITPRG_READ(pattern);
527
528 #if 0
529 /* This debug is now wrong ! */
530 if (DEBUG_BLITTER)
531 {
532 osd_printf_debug("\n%s:Blitter: Running command from 0x%.5x\n\n", device->machine().describe_context(), blitter.program.addr - 12);
533 osd_printf_debug("Command Reg %.2x", blitter.command);
534 osd_printf_debug(" %s %s %s %s %s %s %s\n",
535 blitter.command & CMD_RUN ? "RUN" : " ",
536 blitter.command & CMD_COLST ? "COLST" : " ",
537 blitter.command & CMD_PARRD ? "PARRD" : " ",
538 blitter.command & CMD_SRCUP ? "SRCUP" : " ",
539 blitter.command & CMD_DSTUP ? "DSTUP" : " ");
540
541 osd_printf_debug("Src Address Byte 0 %.2x\n", blitter.source.as8bit.addr0);
542 osd_printf_debug("Src Address Byte 1 %.2x\n", blitter.source.as8bit.addr1);
543 osd_printf_debug("Src Control %.2x\n", blitter.source.as8bit.addr2);
544 osd_printf_debug(" Src Address %.5x\n", blitter.source.addr & 0xfffff);
545 osd_printf_debug("Dest Address Byte 0 %.2x\n", blitter.dest.as8bit.addr0);
546 osd_printf_debug("Dest Address Byte 1 %.2x\n", blitter.dest.as8bit.addr1);
547 osd_printf_debug("Dest Control %.2x\n", blitter.dest.as8bit.addr2);
548 osd_printf_debug(" Dst. Address %.5x\n", blitter.dest.addr & 0xfffff);
549 osd_printf_debug("Mode Control %.2x", blitter.modectl);
550 osd_printf_debug(" %s\n", blitter.modectl & MODE_BITTOBYTE ? "BIT_TO_BYTE" : "");
551
552 osd_printf_debug("Comp. and LFU %.2x\n", blitter.compfunc);
553 osd_printf_debug("Outer Loop Count %.2x (%d)\n", blitter.outercnt, blitter.outercnt);
554 osd_printf_debug("Inner Loop Count %.2x (%d)\n", blitter.innercnt, blitter.innercnt);
555 osd_printf_debug("Step Value %.2x\n", blitter.step);
556 osd_printf_debug("Pattern Byte %.2x\n", blitter.pattern);
557 }
558 #endif
559
560 /* Ignore these writes */
561 if (blitter.dest.addr == 0)
562 return;
563
564 /* Begin outer loop */
565 for (;;)
566 {
567 uint8_t innercnt = blitter.innercnt;
568 dstdata = blitter.pattern;
569
570 if (blitter.command & CMD_LINEDRAW)
571 {
572 do
573 {
574 if (blitter.modectl & MODE_YFRAC)
575 {
576 if (blitter.modectl & MODE_SSIGN )
577 blitter.dest.as8bit.addr0--;
578 else
579 blitter.dest.as8bit.addr0++;
580 }
581 else
582 {
583 if (blitter.modectl & MODE_DSIGN )
584 blitter.dest.as8bit.addr1--;
585 else
586 blitter.dest.as8bit.addr1++;
587 }
588 if( blitter.source.as8bit.addr0 < blitter.step )
589 {
590 blitter.source.as8bit.addr0 -= blitter.step ;
591 blitter.source.as8bit.addr0 += blitter.source.as8bit.addr1;
592
593 if ( blitter.modectl & MODE_YFRAC )
594 {
595 if (blitter.modectl & MODE_DSIGN )
596 blitter.dest.as8bit.addr1--;
597 else
598 blitter.dest.as8bit.addr1++;
599 }
600 else
601 {
602 if (blitter.modectl & MODE_SSIGN )
603 blitter.dest.as8bit.addr0--;
604 else
605 blitter.dest.as8bit.addr0++;
606 }
607 }
608 else
609 {
610 blitter.source.as8bit.addr0 -= blitter.step;
611 }
612
613 *blitter_get_addr( blitter.dest.addr) = blitter.pattern;
614 cycles_used++;
615
616 } while (--innercnt);
617 }
618 else do
619 {
620 uint8_t inhibit = 0;
621
622 /* TODO: Set this correctly */
623 uint8_t result = blitter.pattern;
624
625 if (LOOPTYPE == 3 && innercnt == blitter.innercnt)
626 {
627 srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff));
628 blitter.source.as16bit.loword++;
629 cycles_used++;
630 }
631
632 /* Enable source address read and increment? */
633 if (!(blitter.modectl & (MODE_BITTOBYTE | MODE_PALREMAP)))
634 {
635 if (LOOPTYPE == 0 || LOOPTYPE == 1)
636 {
637 srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff));
638 cycles_used++;
639
640 if (blitter.modectl & MODE_SSIGN)
641 blitter.source.as16bit.loword-- ;
642 else
643 blitter.source.as16bit.loword++;
644
645 result = srcdata;
646 }
647 }
648
649 /* Read destination pixel? */
650 if (LOOPTYPE == 0)
651 {
652 dstdata = *blitter_get_addr( blitter.dest.addr & 0xfffff);
653 cycles_used++;
654 }
655
656 /* Inhibit depending on the bit selected by the inner count */
657
658 /* Switch on comparator type? */
659 if (blitter.modectl & MODE_BITTOBYTE)
660 {
661 inhibit = !(srcdata & (1 << (8 - innercnt)));
662 }
663
664 if (blitter.compfunc & CMPFUNC_BEQ)
665 {
666 if (srcdata == blitter.pattern)
667 {
668 inhibit = 1;
669
670 /* TODO: Resume from inhibit? */
671 if (blitter.command & CMD_COLST)
672 return;
673 }
674 }
675 if (blitter.compfunc & CMPFUNC_LT)
676 {
677 if ((srcdata & 0xc0) > (dstdata & 0xc0))
678 {
679 inhibit = 1;
680
681 /* TODO: Resume from inhibit? */
682 if (blitter.command & CMD_COLST)
683 return;
684 }
685 }
686 if (blitter.compfunc & CMPFUNC_EQ)
687 {
688 if ((srcdata & 0xc0) == (dstdata & 0xc0))
689 {
690 inhibit = 1;
691
692 /* TODO: Resume from inhibit? */
693 if (blitter.command & CMD_COLST)
694 return;
695 }
696 }
697 if (blitter.compfunc & CMPFUNC_GT)
698 {
699 if ((srcdata & 0xc0) < (dstdata & 0xc0))
700 {
701 inhibit = 1;
702
703 /* TODO: Resume from inhibit? */
704 if (blitter.command & CMD_COLST)
705 return;
706 }
707 }
708
709 /* Write the data if not inhibited */
710 if (!inhibit)
711 {
712 if (blitter.modectl == MODE_PALREMAP)
713 {
714 /*
715 In this mode, the source points to a 256 entry lookup table.
716 The existing destination pixel is used as a lookup
717 into the table and the colours is replaced.
718 */
719 uint8_t dest = *blitter_get_addr( blitter.dest.addr);
720 uint8_t newcol = *(blitter_get_addr( (blitter.source.addr + dest) & 0xfffff));
721
722 *blitter_get_addr( blitter.dest.addr) = newcol;
723 cycles_used += 3;
724 }
725 else
726 {
727 uint8_t final_result = 0;
728
729 if (blitter.compfunc & CMPFUNC_LOG3)
730 final_result |= result & dstdata;
731
732 if (blitter.compfunc & CMPFUNC_LOG2)
733 final_result |= result & ~dstdata;
734
735 if (blitter.compfunc & CMPFUNC_LOG1)
736 final_result |= ~result & dstdata;
737
738 if (blitter.compfunc & CMPFUNC_LOG0)
739 final_result |= ~result & ~dstdata;
740
741 *blitter_get_addr( blitter.dest.addr) = final_result;
742 cycles_used++;
743 }
744 }
745
746 /* Update destination address */
747 if (blitter.modectl & MODE_DSIGN)
748 blitter.dest.as16bit.loword--;
749 else
750 blitter.dest.as16bit.loword++;
751
752 } while (--innercnt);
753
754 if (!--blitter.outercnt)
755 {
756 break;
757 }
758 else
759 {
760 if (blitter.command & CMD_DSTUP)
761 blitter.dest.as16bit.loword += blitter.step;
762
763 if (blitter.command & CMD_SRCUP)
764 blitter.source.as16bit.loword += blitter.step;
765
766 if (blitter.command & CMD_PARRD)
767 {
768 BLITPRG_READ(innercnt);
769 BLITPRG_READ(step);
770 BLITPRG_READ(pattern);
771 }
772 }
773 }
774
775 /* Read next command header */
776 BLITPRG_READ(command);
777
778 } while (blitter.command & CMD_RUN);
779
780 /* Burn Z80 cycles while blitter is in operation */
781 m_maincpu->spin_until_time(attotime::from_nsec( (1000000000 / Z80_XTAL)*cycles_used * 2 ) );
782 }
783
784 /***************************************************************************
785
786 Flare One Register Map
787
788 01 Bank control for Z80 region 0x4000-0x7fff (16kB) WR
789 02 Bank control for Z80 region 0x8000-0xbfff (16kB) WR
790 03 Bank control for Z80 region 0xc000-0xffff (16kB) WR
791
792 06 Interrupt status....................................WR
793 07 Interrupt ack.......................................WR
794 Writing here sets the line number that vertical interrupt is generated at.
795 cmd1, bit2 is the 9th bit of the line number
796 ???? Written with 0x21
797 08 cmd1 WR * bit 6 = screen select
798 bit2 = 9th bit of vertical interrupt line number
799 bit6 = 1 = select screen 1 else screen 0
800 09 cmd2 Linked with c001...............................W * bit 0 = 1 = hires
801 bit0=1=hi res else lo res (as long as bit7 is 0)
802 bit5=mask msb of each pixel
803 bit6=mask 2 msbits of each lores pixel
804 bit7=1=variable resolution - resolution is set by bit 7 of each vram byte. bit7=1=2 hires pixels
805 0A ???? Written with 0 and 1...........................W
806 color of border
807
808 0B Horizontal frame buffer scroll .....................W
809 0C Vertical frame buffer scroll .......................W
810
811 0D Colour hold colour..................................W
812 0E Palette value for hi-res magenta....................W
813 0F Palette value for hi-res yellow?....................W
814 14 ....................................................W
815
816 18 Blitter program low byte............................WR
817 19 Blitter program middle byte.........................W
818 1A Blitter program high byte...........................W
819 1B Blitter command?....................................W
820 1C Blitter status?......................................R
821 20 Blitter control register............................W
822
823 22 ???? Linked with C002...............................W
824 Mask of 20
825
826 Joystick: xxx1 11xx R
827 ? (polled on tight loop): x1xx xxxx R
828
829 40: ROM bank select.....................................W
830
831 ***************************************************************************/
832
update_irqs()833 void bfcobra_state::update_irqs()
834 {
835 int newstate = m_blitter_irq || m_vblank_irq || m_acia_irq;
836
837 if (newstate != m_irq_state)
838 {
839 m_irq_state = newstate;
840 m_maincpu->set_input_line(0, m_irq_state ? ASSERT_LINE : CLEAR_LINE);
841 }
842 }
843
chipset_r(offs_t offset)844 uint8_t bfcobra_state::chipset_r(offs_t offset)
845 {
846 uint8_t val = 0xff;
847
848 switch(offset)
849 {
850 case 1:
851 case 2:
852 case 3:
853 {
854 val = m_bank_data[offset];
855 break;
856 }
857 case 6:
858 {
859 /* TODO */
860 val = m_vblank_irq << 4;
861 break;
862 }
863 case 7:
864 {
865 m_vblank_irq = 0;
866 val = 0x1;
867
868 /* TODO */
869 update_irqs();
870 break;
871 }
872 case 0x1C:
873 {
874 /* Blitter status ? */
875 val = 0;
876 break;
877 }
878 case 0x20:
879 {
880 /* Seems correct - used during RLE pic decoding */
881 val = m_blitter.dest.as8bit.addr0;
882 break;
883 }
884 case 0x22:
885 {
886 val = 0x40 | ioport("JOYSTICK")->read();
887 break;
888 }
889 default:
890 {
891 osd_printf_debug("Flare One unknown read: 0x%.2x (PC:0x%.4x)\n", offset, m_maincpu->pcbase());
892 }
893 }
894
895 return val;
896 }
897
chipset_w(offs_t offset,uint8_t data)898 void bfcobra_state::chipset_w(offs_t offset, uint8_t data)
899 {
900 switch (offset)
901 {
902 case 0x01:
903 case 0x02:
904 case 0x03:
905 {
906 if (data > 0x3f)
907 popmessage("%x: Unusual bank access (%x)\n", m_maincpu->pcbase(), data);
908
909 data &= 0x3f;
910 m_bank_data[offset] = data;
911 z80_bank(offset, data);
912 break;
913 }
914
915 case 0x08:
916 {
917 m_flip_8 = data;
918 break;
919 }
920 case 9:
921 m_videomode = data;
922 break;
923
924 case 0x0B:
925 {
926 m_h_scroll = data;
927 break;
928 }
929 case 0x0C:
930 {
931 m_v_scroll = data;
932 break;
933 }
934 case 0x0E:
935 {
936 m_col4bit[5] = data;
937 m_col3bit[5] = data;
938 m_col3bit[5 + 8] = data;
939 break;
940 }
941 case 0x0f:
942 {
943 m_col4bit[6] = data;
944 m_col3bit[6] = data;
945 m_col3bit[6 + 8] = data;
946 break;
947 }
948 case 0x18:
949 {
950 m_blitter.program.as8bit.addr0 = data;
951 break;
952 }
953 case 0x19:
954 {
955 m_blitter.program.as8bit.addr1 = data;
956 break;
957 }
958 case 0x1A:
959 {
960 m_blitter.program.as8bit.addr2 = data;
961 break;
962 }
963 case 0x20:
964 {
965 m_blitter.command = data;
966
967 if (data & CMD_RUN)
968 RunBlit();
969 else
970 osd_printf_debug("Blitter stopped by IO.\n");
971
972 break;
973 }
974 case 0x22:
975 {
976 m_flip_22 = data;
977 break;
978 }
979 default:
980 {
981 osd_printf_debug("Flare One unknown write: 0x%.2x with 0x%.2x (PC:0x%.4x)\n", offset, data, m_maincpu->pcbase());
982 }
983 }
984 }
985
z80_bank(int num,int data)986 void bfcobra_state::z80_bank(int num, int data)
987 {
988 static const char * const bank_names[] = { "bank1", "bank2", "bank3" };
989
990 if (data < 0x08)
991 {
992 uint32_t offset = ((m_bank_data[0] >> 1) * 0x20000) + ((0x4000 * data) ^ ((m_bank_data[0] & 1) ? 0 : 0x10000));
993
994 membank(bank_names[num - 1])->set_base(memregion("user1")->base() + offset);
995 }
996 else if (data < 0x10)
997 {
998 membank(bank_names[num - 1])->set_base(&m_video_ram[(data - 0x08) * 0x4000]);
999 }
1000 else
1001 {
1002 membank(bank_names[num - 1])->set_base(&m_work_ram[(data - 0x10) * 0x4000]);
1003 }
1004 }
1005
rombank_w(uint8_t data)1006 void bfcobra_state::rombank_w(uint8_t data)
1007 {
1008 m_bank_data[0] = data;
1009 z80_bank(1, m_bank_data[1]);
1010 z80_bank(2, m_bank_data[2]);
1011 z80_bank(3, m_bank_data[3]);
1012 }
1013
1014
1015
1016 /***************************************************************************
1017
1018 Split into machine\bfcobra.cpp !
1019
1020 Alternatively chuck it all away and borrow the MESS implementation
1021 because it's a million times better.
1022
1023 ***************************************************************************/
1024
1025
1026 /*
1027 WD37C656C-PL (or equivalent) Floppy Disk Controller
1028 */
1029
1030 enum fdc_phase
1031 {
1032 COMMAND,
1033 EXECUTION_R,
1034 EXECUTION_W,
1035 RESULTS
1036 };
1037
1038 enum command
1039 {
1040 SENSE_DRIVE_STATUS = 0,
1041 READ_A_TRACK = 2,
1042 SPECIFY = 3,
1043 WRITE_DATA = 5,
1044 READ_DATA = 6,
1045 RECALIBRATE = 7,
1046 SENSE_INTERRUPT_STATUS = 8,
1047 WRITE_DELETED_DATA = 9,
1048 READ_ID = 10,
1049 FORMAT_TRACK = 13,
1050 READ_DELETED_DATA = 14,
1051 SEEK = 15,
1052 SCAN_EQUAL = 17,
1053 SCAN_LOW_OR_EQUAL = 25,
1054 SCAN_HIGH_OR_EQUAL = 29
1055 };
1056
reset_fdc()1057 void bfcobra_state::reset_fdc()
1058 {
1059 memset(&m_fdc, 0, sizeof(m_fdc));
1060
1061 m_fdc.MSR = 0x80;
1062 m_fdc.phase = COMMAND;
1063 }
1064
fdctrl_r()1065 uint8_t bfcobra_state::fdctrl_r()
1066 {
1067 uint8_t val = 0;
1068
1069 val = m_fdc.MSR;
1070
1071 return val;
1072 }
1073
fddata_r()1074 uint8_t bfcobra_state::fddata_r()
1075 {
1076 struct fdc_t &fdc = m_fdc;
1077 #define BPS 1024
1078 #define SPT 10
1079 #define BPT 1024*10
1080
1081 uint8_t val = 0;
1082
1083 if (fdc.phase == EXECUTION_R)
1084 {
1085 switch (fdc.cmd[0] & 0x1f)
1086 {
1087 /* Specify */
1088 case READ_DATA:
1089 {
1090 if (fdc.setup_read)
1091 {
1092 fdc.track = fdc.cmd[2];
1093 fdc.side = fdc.cmd[3];
1094 fdc.sector = fdc.cmd[4];
1095 fdc.number = fdc.cmd[5];
1096 fdc.stop_track = fdc.cmd[6];
1097 //int GPL = fdc.cmd[7];
1098 //int DTL = fdc.cmd[8];
1099
1100 fdc.setup_read = 0;
1101 fdc.byte_pos = 0;
1102 }
1103
1104 fdc.offset = (BPT * fdc.track*2) + (fdc.side ? BPT : 0) + (BPS * (fdc.sector-1)) + fdc.byte_pos++;
1105 val = *(memregion("user2")->base() + fdc.offset);
1106
1107 /* Move on to next sector? */
1108 if (fdc.byte_pos == 1024)
1109 {
1110 fdc.byte_pos = 0;
1111
1112 if (fdc.sector == fdc.stop_track || ++fdc.sector == 11)
1113 {
1114 /* End of read operation */
1115 fdc.MSR = 0xd0;
1116 fdc.phase = RESULTS;
1117
1118 fdc.results[0] = 0;
1119 fdc.results[1] = 0;
1120 fdc.results[2] = 0;
1121
1122 fdc.results[3] = 0;
1123 fdc.results[4] = 0;
1124 fdc.results[5] = 0;
1125 fdc.results[6] = 0;
1126 }
1127 }
1128 break;
1129 }
1130 }
1131 }
1132 else if (fdc.phase == RESULTS)
1133 {
1134 val = fdc.results[fdc.res_cnt++];
1135
1136 if (fdc.res_cnt == fdc.res_len)
1137 {
1138 fdc.phase = COMMAND;
1139 fdc.res_cnt = 0;
1140 fdc.MSR &= ~0x40;
1141 }
1142 }
1143
1144 return val;
1145 }
1146
fdctrl_w(uint8_t data)1147 void bfcobra_state::fdctrl_w(uint8_t data)
1148 {
1149 struct fdc_t &fdc = m_fdc;
1150 switch (fdc.phase)
1151 {
1152 case COMMAND:
1153 {
1154 command_phase(fdc, data);
1155 break;
1156 }
1157 case EXECUTION_W:
1158 {
1159 exec_w_phase(data);
1160 break;
1161 }
1162 default:
1163 {
1164 osd_printf_debug("Unknown FDC phase?!");
1165 }
1166 }
1167 }
1168
command_phase(struct fdc_t & fdc,uint8_t data)1169 void bfcobra_state::command_phase(struct fdc_t &fdc, uint8_t data)
1170 {
1171 if (fdc.cmd_cnt == 0)
1172 {
1173 fdc.cmd[0] = data;
1174
1175 fdc.cmd_cnt = 1;
1176
1177 switch (data & 0x1f)
1178 {
1179 /* Specify */
1180 case READ_DATA:
1181 {
1182 // osd_printf_debug("Read data\n");
1183 fdc.cmd_len = 9;
1184 fdc.res_len = 7;
1185 fdc.next_phase = EXECUTION_R;
1186 fdc.setup_read = 1;
1187 break;
1188 }
1189 case SPECIFY:
1190 {
1191 // osd_printf_debug("Specify\n");
1192 fdc.cmd_len = 3;
1193 fdc.res_len = 0;
1194 fdc.next_phase = COMMAND;
1195 break;
1196 }
1197 case RECALIBRATE:
1198 {
1199 // osd_printf_debug("Recalibrate\n");
1200 fdc.cmd_len = 2;
1201 fdc.res_len = 0;
1202 fdc.next_phase = COMMAND;
1203 //fdc.MSR |= 0x40;
1204 break;
1205 }
1206 case SENSE_INTERRUPT_STATUS:
1207 {
1208 // osd_printf_debug("Sense interrupt status\n");
1209 fdc.cmd_len = 1;
1210 fdc.res_len = 2;
1211 fdc.phase = RESULTS;
1212
1213 fdc.results[0] = 0;
1214 fdc.results[1] = 0;
1215
1216 fdc.cmd_cnt = 0;
1217 fdc.MSR |= 0x40;
1218 break;
1219 }
1220 case SEEK:
1221 {
1222 // osd_printf_debug("Seek\n");
1223 fdc.cmd_len = 3;
1224 fdc.res_len = 0;
1225 fdc.next_phase = COMMAND;
1226 break;
1227 }
1228 default:
1229 {
1230 // osd_printf_debug("%x\n",data & 0x1f);
1231 }
1232 }
1233 }
1234 else
1235 {
1236 fdc.cmd[fdc.cmd_cnt++] = data;
1237 //osd_printf_debug(" %x\n",data);
1238 }
1239
1240 if (fdc.cmd_cnt == fdc.cmd_len)
1241 {
1242 fdc.phase = fdc.next_phase;
1243 fdc.cmd_cnt = 0;
1244
1245 if ((fdc.cmd[0] & 0x1f) == READ_DATA)
1246 fdc.MSR = 0xf0;
1247 }
1248 }
1249
1250 #ifdef UNUSED_FUNCTION
exec_r_phase(void)1251 uint8_t bfcobra_state::exec_r_phase(void)
1252 {
1253 return 0;
1254 }
1255 #endif
1256
exec_w_phase(uint8_t data)1257 void bfcobra_state::exec_w_phase(uint8_t data)
1258 {
1259 }
1260
1261 #ifdef UNUSED_FUNCTION
results_phase(void)1262 uint8_t bfcobra_state::results_phase(void)
1263 {
1264 return 0;
1265 }
1266
fd_op_w(uint8_t data)1267 void bfcobra_state::fd_op_w(uint8_t data)
1268 {
1269 }
1270
fd_ctrl_w(uint8_t data)1271 void bfcobra_state::fd_ctrl_w(uint8_t data)
1272 {
1273 }
1274 #endif
1275
machine_reset()1276 void bfcobra_state::machine_reset()
1277 {
1278 unsigned int pal;
1279
1280 for (pal = 0; pal < 256; ++pal)
1281 {
1282 m_palette->set_pen_color(pal, pal3bit((pal>>5)&7), pal3bit((pal>>2)&7), pal2bit(pal&3));
1283 }
1284
1285 m_bank_data[0] = 1;
1286 reset_fdc();
1287
1288 m_irq_state = m_blitter_irq = m_vblank_irq = m_acia_irq = 0;
1289 }
1290
1291 /***************************************************************************
1292
1293 Cobra I/Viper Z80 Memory Map
1294
1295 ***************************************************************************/
1296
z80_prog_map(address_map & map)1297 void bfcobra_state::z80_prog_map(address_map &map)
1298 {
1299 map(0x0000, 0x3fff).bankr("bank4");
1300 map(0x4000, 0x7fff).bankrw("bank1");
1301 map(0x8000, 0xbfff).bankrw("bank2");
1302 map(0xc000, 0xffff).bankrw("bank3");
1303 }
1304
z80_io_map(address_map & map)1305 void bfcobra_state::z80_io_map(address_map &map)
1306 {
1307 map.global_mask(0xff);
1308 map(0x00, 0x23).rw(FUNC(bfcobra_state::chipset_r), FUNC(bfcobra_state::chipset_w));
1309 map(0x24, 0x25).w(m_acia6850_0, FUNC(acia6850_device::write));
1310 map(0x26, 0x27).r(m_acia6850_0, FUNC(acia6850_device::read));
1311 map(0x30, 0x30).r(FUNC(bfcobra_state::fdctrl_r));
1312 map(0x31, 0x31).rw(FUNC(bfcobra_state::fddata_r), FUNC(bfcobra_state::fdctrl_w));
1313 map(0x40, 0x40).w(FUNC(bfcobra_state::rombank_w));
1314 map(0x50, 0x50).w("ramdac", FUNC(ramdac_device::index_w));
1315 map(0x51, 0x51).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w));
1316 map(0x52, 0x52).w("ramdac", FUNC(ramdac_device::mask_w));
1317 map(0x53, 0x53).w("ramdac", FUNC(ramdac_device::index_r_w));
1318 }
1319
1320
ramdac_map(address_map & map)1321 void bfcobra_state::ramdac_map(address_map &map)
1322 {
1323 map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w));
1324 }
1325
1326
1327 /***************************************************************************
1328
1329 Cobra I/Viper 6809 Memory Map
1330
1331 Cobra I has these components:
1332
1333 EF68B50P - For communication with Z80
1334 EF68B50P - For data retrieval
1335 AY38912A
1336 UPD7759C
1337 BFM1090 (CF30056) - 'TEXAS' I/O chip, lamps and misc
1338 BFM1095 (CF30057) - 'TEXAS' I/O chip, handles switches
1339 BFM1071 - 6809 Address decoding and bus control
1340
1341 /IRQ provided by EF68850P at IC38
1342 /FIRQ connected to meter current sensing circuitry
1343
1344 TODO: Calculate watchdog timer period.
1345
1346 ***************************************************************************/
1347
1348 /* TODO */
int_latch_r()1349 uint8_t bfcobra_state::int_latch_r()
1350 {
1351 return 2 | 1;
1352 }
1353
1354 /* TODO */
meter_r()1355 uint8_t bfcobra_state::meter_r()
1356 {
1357 return m_meter_latch;
1358 }
1359
1360 /* TODO: This is borrowed from Scorpion 1 */
meter_w(uint8_t data)1361 void bfcobra_state::meter_w(uint8_t data)
1362 {
1363 int i;
1364 int changed = m_meter_latch ^ data;
1365
1366 m_meter_latch = data;
1367
1368 /*
1369 When a meter is triggered, the current drawn is sensed. If a meter
1370 is connected, the /FIRQ line will be pulsed.
1371 */
1372 for (i = 0; i < 8; i++)
1373 {
1374 if (changed & (1 << i))
1375 {
1376 m_meters->update(i, data & (1 << i) );
1377 m_audiocpu->set_input_line(M6809_FIRQ_LINE, HOLD_LINE);
1378 }
1379 }
1380 }
1381
1382 /* TODO */
latch_r()1383 uint8_t bfcobra_state::latch_r()
1384 {
1385 return m_mux_input;
1386 }
1387
latch_w(offs_t offset,uint8_t data)1388 void bfcobra_state::latch_w(offs_t offset, uint8_t data)
1389 {
1390 /* TODO: This is borrowed from Scorpion 1 */
1391 switch(offset)
1392 {
1393 case 0:
1394 {
1395 int changed = m_mux_outputlatch ^ data;
1396 static const char *const port[] = { "STROBE0", "STROBE1", "STROBE2", "STROBE3", "STROBE4", "STROBE5", "STROBE6", "STROBE7" };
1397
1398 m_mux_outputlatch = data;
1399
1400 /* Clock has changed */
1401 if (changed & 0x08)
1402 {
1403 int input_strobe = data & 0x7;
1404
1405 /* Clock is low */
1406 if (!(data & 0x08))
1407 m_mux_input = ioport(port[input_strobe])->read();
1408 }
1409 break;
1410 }
1411 case 1:
1412 {
1413 // strobe_data_l = data;
1414 break;
1415 }
1416 case 2:
1417 {
1418 // strobe_data_h = data;
1419 break;
1420 }
1421 }
1422 }
1423
upd_r()1424 uint8_t bfcobra_state::upd_r()
1425 {
1426 return 2 | m_upd7759->busy_r();
1427 }
1428
upd_w(uint8_t data)1429 void bfcobra_state::upd_w(uint8_t data)
1430 {
1431 m_upd7759->reset_w(BIT(data, 7));
1432 m_upd7759->port_w(data & 0x3f);
1433 m_upd7759->start_w(!BIT(data, 6));
1434 }
1435
m6809_prog_map(address_map & map)1436 void bfcobra_state::m6809_prog_map(address_map &map)
1437 {
1438 map(0x0000, 0x1fff).ram().share("nvram");
1439 map(0x2000, 0x2000).ram(); // W 'B', 6F
1440 map(0x2200, 0x2200).ram(); // W 'F'
1441 map(0x2600, 0x2600).rw(FUNC(bfcobra_state::meter_r), FUNC(bfcobra_state::meter_w));
1442 map(0x2800, 0x2800).ram(); // W
1443 map(0x2a00, 0x2a02).rw(FUNC(bfcobra_state::latch_r), FUNC(bfcobra_state::latch_w));
1444 map(0x2e00, 0x2e00).r(FUNC(bfcobra_state::int_latch_r));
1445 map(0x3001, 0x3001).w("aysnd", FUNC(ay8910_device::data_w));
1446 map(0x3201, 0x3201).w("aysnd", FUNC(ay8910_device::address_w));
1447 map(0x3404, 0x3405).rw(m_acia6850_1, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
1448 map(0x3406, 0x3407).rw(m_acia6850_2, FUNC(acia6850_device::read), FUNC(acia6850_device::write));
1449 // map(0x3408, 0x3408).noprw();
1450 // map(0x340a, 0x340a).noprw();
1451 // map(0x3600, 0x3600).noprw();
1452 map(0x3801, 0x3801).rw(FUNC(bfcobra_state::upd_r), FUNC(bfcobra_state::upd_w));
1453 map(0x8000, 0xffff).rom();
1454 map(0xf000, 0xf000).nopw(); /* Watchdog */
1455 }
1456
1457 static INPUT_PORTS_START( bfcobra )
1458 PORT_START("STROBE0")
1459 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_NAME("Coin: 10p")
1460 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_NAME("Coin: 20p")
1461 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) PORT_NAME("Coin: 50p")
1462 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN4 ) PORT_NAME("Coin: 1 pound")
1463 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_CODE(KEYCODE_F1)1464 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Green Test?") PORT_CODE(KEYCODE_F1)
1465 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Red Test?")
1466 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
1467
1468 PORT_START("STROBE1")
1469 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Pass") PORT_CODE(KEYCODE_A)
1470 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Continue") PORT_CODE(KEYCODE_S)
1471 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Collect") PORT_CODE(KEYCODE_D)
1472 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Start")
1473 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Bonus") PORT_CODE(KEYCODE_F)
1474 // PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1475 // PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 )
1476 // PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON3 )
1477
1478 PORT_START("STROBE2")
1479 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("<A")
1480 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("<B")
1481 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("<C")
1482 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("A>")
1483 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON9 ) PORT_NAME("B>")
1484 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON10 ) PORT_NAME("C>")
1485 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1486 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1487
1488 PORT_START("STROBE3")
1489 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_INTERLOCK) PORT_NAME("Cash box door") PORT_CODE(KEYCODE_Y) PORT_TOGGLE
1490 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Front Door? (resets)") PORT_CODE(KEYCODE_T) PORT_TOGGLE
1491 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SERVICE ) PORT_NAME("Refill Key") PORT_CODE(KEYCODE_R) PORT_TOGGLE
1492 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1493 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1494 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1495 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1496 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1497
1498 PORT_START("STROBE4")
1499 PORT_BIT( 0xFF, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1500
1501 PORT_START("STROBE5")
1502 PORT_BIT( 0xFF, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1503
1504 PORT_START("STROBE6")
1505 PORT_DIPNAME( 0x01, 0x00, "DIL09" )
1506 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1507 PORT_DIPSETTING( 0x01, DEF_STR( On ) )
1508 PORT_DIPNAME( 0x02, 0x00, "DIL10" )
1509 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1510 PORT_DIPSETTING( 0x02, DEF_STR( On ) )
1511 PORT_DIPNAME( 0x04, 0x00, "DIL11" )
1512 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1513 PORT_DIPSETTING( 0x04, DEF_STR( On ) )
1514 PORT_DIPNAME( 0x08, 0x00, "DIL12" )
1515 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1516 PORT_DIPSETTING( 0x08, DEF_STR( On ) )
1517 PORT_DIPNAME( 0x10, 0x00, "DIL13" )
1518 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1519 PORT_DIPSETTING( 0x10, DEF_STR( On ) )
1520 PORT_DIPNAME( 0x20, 0x00, "DIL14" )
1521 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1522 PORT_DIPSETTING( 0x20, DEF_STR( On ) )
1523 PORT_DIPNAME( 0x40, 0x00, "DIL15" )
1524 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1525 PORT_DIPSETTING( 0x40, DEF_STR( On ) )
1526 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1527
1528 PORT_START("STROBE7")
1529 PORT_DIPNAME( 0x01, 0x00, "DIL02" )
1530 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1531 PORT_DIPSETTING( 0x01, DEF_STR( On ) )
1532 PORT_DIPNAME( 0x02, 0x00, "DIL03" )
1533 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1534 PORT_DIPSETTING( 0x02, DEF_STR( On ) )
1535 PORT_DIPNAME( 0x04, 0x00, "DIL04" )
1536 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1537 PORT_DIPSETTING( 0x04, DEF_STR( On ) )
1538 PORT_DIPNAME( 0x08, 0x00, "DIL05" )
1539 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1540 PORT_DIPSETTING( 0x08, DEF_STR( On ) )
1541 PORT_DIPNAME( 0x10, 0x00, "DIL06" )
1542 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1543 PORT_DIPSETTING( 0x10, DEF_STR( On ) )
1544 PORT_DIPNAME( 0x20, 0x00, "DIL07" )
1545 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1546 PORT_DIPSETTING( 0x20, DEF_STR( On ) )
1547 PORT_DIPNAME( 0x40, 0x00, "DIL08" )
1548 PORT_DIPSETTING( 0x00, DEF_STR( Off ) )
1549 PORT_DIPSETTING( 0x40, DEF_STR( On ) )
1550 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
1551
1552 PORT_START("JOYSTICK")
1553 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
1554 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
1555 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
1556 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
1557 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON1 )
1558 INPUT_PORTS_END
1559
1560 /*
1561 Allocate work RAM and video RAM shared by the Z80 and chipset.
1562 */
1563 void bfcobra_state::init_ram()
1564 {
1565 /* 768kB work RAM */
1566 m_work_ram = make_unique_clear<uint8_t[]>(0xC0000);
1567
1568 /* 128kB video RAM */
1569 m_video_ram = make_unique_clear<uint8_t[]>(0x20000);
1570 }
1571
1572
WRITE_LINE_MEMBER(bfcobra_state::z80_acia_irq)1573 WRITE_LINE_MEMBER(bfcobra_state::z80_acia_irq)
1574 {
1575 m_acia_irq = state;
1576 update_irqs();
1577 }
1578
1579
WRITE_LINE_MEMBER(bfcobra_state::m6809_data_irq)1580 WRITE_LINE_MEMBER(bfcobra_state::m6809_data_irq)
1581 {
1582 m_audiocpu->set_input_line(M6809_IRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
1583 }
1584
1585
WRITE_LINE_MEMBER(bfcobra_state::data_acia_tx_w)1586 WRITE_LINE_MEMBER(bfcobra_state::data_acia_tx_w)
1587 {
1588 m_data_t = state;
1589 }
1590
1591
WRITE_LINE_MEMBER(bfcobra_state::write_acia_clock)1592 WRITE_LINE_MEMBER(bfcobra_state::write_acia_clock)
1593 {
1594 m_acia6850_0->write_txc(state);
1595 m_acia6850_0->write_rxc(state);
1596 m_acia6850_1->write_txc(state);
1597 m_acia6850_1->write_rxc(state);
1598 m_acia6850_2->write_txc(state);
1599 m_acia6850_2->write_rxc(state);
1600 }
1601
1602
1603 /* TODO: Driver vs Machine Init */
init_bfcobra()1604 void bfcobra_state::init_bfcobra()
1605 {
1606 /*
1607 6809 ROM address and data lines are scrambled.
1608 This is the same scrambling as Scorpion 2.
1609 */
1610 static const uint8_t datalookup[] = { 1, 3, 5, 6, 4, 2, 0, 7 };
1611 static const uint8_t addrlookup[] = { 11, 12, 0, 2, 3, 5, 7, 9, 8, 6, 1, 4, 10, 13, 14 };
1612
1613 std::vector<uint8_t> tmp(0x8000);
1614 uint8_t *rom = memregion("audiocpu")->base() + 0x8000;
1615 memcpy(&tmp[0], rom, 0x8000);
1616
1617 for (uint32_t i = 0; i < 0x8000; i++)
1618 {
1619 uint8_t val = tmp[i];
1620
1621 uint8_t data = 0;
1622 for (uint8_t x = 0; x < 8; x ++)
1623 data |= ((val >> x) & 1) << datalookup[x];
1624
1625 uint16_t addr = 0;
1626 for (uint8_t x = 0; x < 15; x ++)
1627 addr |= ((i >> x) & 1) << addrlookup[x];
1628
1629 rom[addr] = data;
1630 }
1631
1632 init_ram();
1633
1634 m_bank_data[0] = 1;
1635 m_bank_data[1] = 0;
1636 m_bank_data[2] = 0;
1637 m_bank_data[3] = 0;
1638
1639 /* Fixed 16kB ROM region */
1640 membank("bank4")->set_base(memregion("user1")->base());
1641
1642 /* TODO: Properly sort out the data ACIA */
1643 m_acia6850_2->write_rxd(1);
1644
1645 /* Finish this */
1646 save_item(NAME(m_data_r));
1647 save_item(NAME(m_data_t));
1648 save_item(NAME(m_h_scroll));
1649 save_item(NAME(m_v_scroll));
1650 save_item(NAME(m_flip_8));
1651 save_item(NAME(m_flip_22));
1652 save_item(NAME(m_z80_int));
1653 save_item(NAME(m_z80_inten));
1654 save_item(NAME(m_bank_data));
1655 save_pointer(NAME(m_work_ram), 0xc0000);
1656 save_pointer(NAME(m_video_ram), 0x20000);
1657 }
1658
1659 /* TODO */
INTERRUPT_GEN_MEMBER(bfcobra_state::timer_irq)1660 INTERRUPT_GEN_MEMBER(bfcobra_state::timer_irq)
1661 {
1662 device.execute().set_input_line(M6809_IRQ_LINE, HOLD_LINE);
1663 }
1664
1665 /* TODO */
INTERRUPT_GEN_MEMBER(bfcobra_state::vblank_gen)1666 INTERRUPT_GEN_MEMBER(bfcobra_state::vblank_gen)
1667 {
1668 m_vblank_irq = 1;
1669 update_irqs();
1670 }
1671
bfcobra(machine_config & config)1672 void bfcobra_state::bfcobra(machine_config &config)
1673 {
1674 Z80(config, m_maincpu, Z80_XTAL);
1675 m_maincpu->set_addrmap(AS_PROGRAM, &bfcobra_state::z80_prog_map);
1676 m_maincpu->set_addrmap(AS_IO, &bfcobra_state::z80_io_map);
1677 m_maincpu->set_vblank_int("screen", FUNC(bfcobra_state::vblank_gen));
1678
1679 MC6809(config, m_audiocpu, M6809_XTAL); // MC6809P
1680 m_audiocpu->set_addrmap(AS_PROGRAM, &bfcobra_state::m6809_prog_map);
1681 m_audiocpu->set_periodic_int(FUNC(bfcobra_state::timer_irq), attotime::from_hz(1000));
1682
1683 NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
1684
1685
1686 /* TODO */
1687 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
1688 screen.set_refresh_hz(50);
1689 screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
1690 screen.set_size(512, 256);
1691 screen.set_visarea_full();
1692 screen.set_screen_update(FUNC(bfcobra_state::screen_update_bfcobra));
1693
1694 PALETTE(config, m_palette).set_entries(256);
1695
1696 ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette)); // MUSIC Semiconductor TR9C1710 RAMDAC or equivalent
1697 ramdac.set_addrmap(0, &bfcobra_state::ramdac_map);
1698 ramdac.set_split_read(1);
1699
1700 SPEAKER(config, "mono").front_center();
1701
1702 AY8910(config, "aysnd", M6809_XTAL / 4).add_route(ALL_OUTPUTS, "mono", 0.20);
1703
1704 UPD7759(config, m_upd7759).add_route(ALL_OUTPUTS, "mono", 0.40);
1705
1706 /* ACIAs */
1707 ACIA6850(config, m_acia6850_0, 0);
1708 m_acia6850_0->txd_handler().set(m_acia6850_1, FUNC(acia6850_device::write_rxd));
1709 m_acia6850_0->irq_handler().set(FUNC(bfcobra_state::z80_acia_irq));
1710
1711 ACIA6850(config, m_acia6850_1, 0);
1712 m_acia6850_1->txd_handler().set(m_acia6850_0, FUNC(acia6850_device::write_rxd));
1713
1714 ACIA6850(config, m_acia6850_2, 0);
1715 m_acia6850_2->txd_handler().set(FUNC(bfcobra_state::data_acia_tx_w));
1716 m_acia6850_2->irq_handler().set(FUNC(bfcobra_state::m6809_data_irq));
1717
1718 clock_device &acia_clock(CLOCK(config, "acia_clock", 31250*16)); // What are the correct ACIA clocks ?
1719 acia_clock.signal_handler().set(FUNC(bfcobra_state::write_acia_clock));
1720
1721 METERS(config, m_meters, 0).set_number(8);
1722 }
1723
1724 /***************************************************************************
1725 Cobra II Jamma.
1726
1727 This has a Z180 and no 6809
1728
1729 ***************************************************************************/
1730 class bfcobjam_state : public driver_device
1731 {
1732 public:
bfcobjam_state(const machine_config & mconfig,device_type type,const char * tag)1733 bfcobjam_state(const machine_config &mconfig, device_type type, const char *tag) :
1734 driver_device(mconfig, type, tag),
1735 m_maincpu(*this, "maincpu"),
1736 m_acia6850_0(*this, "acia6850_0"),
1737 m_screen(*this, "screen"),
1738 m_palette(*this, "palette"),
1739 m_aux_upd7759(*this, "upd"),
1740 m_upd7759_int(*this, "updint"),
1741 m_ym2413(*this, "ymsnd"),
1742 m_i2cmem(*this, "i2cmem"),
1743 m_dm01(*this, "dm01"),
1744 m_work_ram(*this, "work_ram"),
1745 m_video_ram(*this, "video_ram")
1746 {
1747 }
1748
1749 void init_bfcobjam();
1750 void bfcobjam(machine_config &config);
1751 void bfcobjam_with_dmd(machine_config &config);
1752
1753 protected:
1754 virtual void machine_start() override;
1755 virtual void machine_reset() override;
1756 virtual void video_start() override;
1757
1758 private:
1759 uint8_t m_bank_data[4];
1760 uint8_t m_rompage;
1761 uint8_t m_h_scroll;
1762 uint8_t m_v_scroll;
1763 uint8_t m_flip_8;
1764 uint8_t m_flip_22;
1765 uint8_t m_videomode;
1766 uint8_t m_data_r;
1767 uint8_t m_data_t;
1768 uint8_t m_port_0;
1769 int m_irq_state;
1770 int m_acia_irq;
1771 int m_scanline_irq;
1772 int m_blitter_irq;
1773 int m_global_volume;
1774 uint8_t dm_shift_data ;
1775 int dm_shift = 0 ;
1776 int dm_last_data = 0 ;
1777
1778 uint8_t m_z8s180_int;
1779 uint8_t m_z8s180_inten;
1780 uint8_t m_col4bit[16];
1781 uint8_t m_col3bit[16];
1782 uint8_t m_col8bit[256];
1783 uint8_t m_col7bit[256];
1784 uint8_t m_col6bit[256];
1785 struct bf_blitter_t m_blitter;
1786 emu_timer *m_scanline_timer;
1787 uint8_t m_genio ;
1788 required_device<cpu_device> m_maincpu;
1789 required_device<acia6850_device> m_acia6850_0;
1790 required_device<screen_device> m_screen;
1791 required_device<palette_device> m_palette;
1792 optional_device<upd7759_device> m_aux_upd7759;
1793 required_device<upd7759_device> m_upd7759_int;
1794 required_device<ym2413_device> m_ym2413;
1795 required_device<i2c_24c08_device> m_i2cmem;
1796 optional_device<bfm_dm01_device> m_dm01;
1797 required_shared_ptr<uint8_t> m_work_ram;
1798 required_shared_ptr<uint8_t> m_video_ram;
1799
1800 uint8_t chipset_r(offs_t offset);
1801 void chipset_w(offs_t offset, uint8_t data);
1802 void rombank_w(uint8_t data);
1803 void upd7759_w(uint8_t data);
1804 uint8_t aux_upd7759_r();
1805 void aux_upd7759_w(uint8_t data);
1806 void output0_w(uint8_t data);
1807 uint8_t input0_r();
1808 uint8_t input1_r();
1809 DECLARE_WRITE_LINE_MEMBER(z8s180_acia_irq);
1810 DECLARE_WRITE_LINE_MEMBER(data_acia_tx_w);
1811 DECLARE_WRITE_LINE_MEMBER(write_acia_clock);
1812 DECLARE_WRITE_LINE_MEMBER(upd7759_generate_dreq );
1813 uint32_t screen_update_bfcobjam(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
1814 INTERRUPT_GEN_MEMBER(timer_irq);
1815 TIMER_CALLBACK_MEMBER( scanline_callback ) ;
1816 void RunBlit();
1817 void update_irqs();
1818 void genio_w( uint8_t data ) ;
1819 void dotmatrix_w( uint8_t data );
1820 inline uint8_t* blitter_get_addr(uint32_t addr);
1821 inline void z8s180_bank(int num, int data);
1822
1823 void ramdac_map(address_map &map);
1824 void z8s180_io_map(address_map &map);
1825 void z8s180_prog_map(address_map &map);
1826 };
1827
init_bfcobjam()1828 void bfcobjam_state::init_bfcobjam()
1829 {
1830 m_rompage = 0 ;
1831 m_bank_data[0] = 0;
1832 m_bank_data[1] = 0;
1833 m_bank_data[2] = 0;
1834 m_bank_data[3] = 0;
1835
1836 /* Fixed 16kB ROM region */
1837 membank("bank4")->set_base(memregion("user1")->base());
1838 membank("bank1")->set_base(memregion("user1")->base()+0x04000);
1839 membank("bank2")->set_base(memregion("user1")->base()+0x08000);
1840 membank("bank3")->set_base(memregion("user1")->base()+0x0c000);
1841
1842 m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(bfcobjam_state::scanline_callback),this));
1843
1844 /* Finish this */
1845 save_item(NAME(m_data_r));
1846 save_item(NAME(m_data_t));
1847 save_item(NAME(m_h_scroll));
1848 save_item(NAME(m_v_scroll));
1849 save_item(NAME(m_flip_8));
1850 save_item(NAME(m_flip_22));
1851 save_item(NAME(m_z8s180_int));
1852 save_item(NAME(m_z8s180_inten));
1853 save_item(NAME(m_bank_data));
1854 save_item(NAME(m_genio));
1855 save_item(NAME(m_global_volume));
1856
1857 }
1858
1859 /*
1860 This is based this on the Slipstream technical reference manual.
1861 The Flare One blitter is a simpler design with slightly different parameters
1862 and will require hardware tests to figure everything out correctly.
1863 */
RunBlit()1864 void bfcobjam_state::RunBlit()
1865 {
1866 #define BLITPRG_READ(x) blitter.x = *(blitter_get_addr(blitter.program.addr++))
1867
1868 struct bf_blitter_t &blitter = m_blitter;
1869 int cycles_used = 0;
1870
1871
1872 do
1873 {
1874 uint8_t srcdata = 0;
1875 uint8_t dstdata = 0;
1876
1877 /* Read the blitter command */
1878 BLITPRG_READ(source.as8bit.addr0);
1879 BLITPRG_READ(source.as8bit.addr1);
1880 BLITPRG_READ(source.as8bit.addr2);
1881 BLITPRG_READ(dest.as8bit.addr0);
1882 BLITPRG_READ(dest.as8bit.addr1);
1883 BLITPRG_READ(dest.as8bit.addr2);
1884 BLITPRG_READ(modectl);
1885 BLITPRG_READ(compfunc);
1886 BLITPRG_READ(outercnt);
1887 BLITPRG_READ(innercnt);
1888 BLITPRG_READ(step);
1889 BLITPRG_READ(pattern);
1890
1891 #if 0
1892 /* This debug is now wrong ! */
1893 if (DEBUG_BLITTER)
1894 {
1895 osd_printf_debug("\n%s:Blitter: Running command from 0x%.5x\n\n", device->machine().describe_context(), blitter.program.addr - 12);
1896 osd_printf_debug("Command Reg %.2x", blitter.command);
1897 osd_printf_debug(" %s %s %s %s %s %s %s\n",
1898 blitter.command & CMD_RUN ? "RUN" : " ",
1899 blitter.command & CMD_COLST ? "COLST" : " ",
1900 blitter.command & CMD_PARRD ? "PARRD" : " ",
1901 blitter.command & CMD_SRCUP ? "SRCUP" : " ",
1902 blitter.command & CMD_DSTUP ? "DSTUP" : " ");
1903
1904 osd_printf_debug("Src Address Byte 0 %.2x\n", blitter.source.as8bit.addr0);
1905 osd_printf_debug("Src Address Byte 1 %.2x\n", blitter.source.as8bit.addr1);
1906 osd_printf_debug("Src Control %.2x\n", blitter.source.as8bit.addr2);
1907 osd_printf_debug(" Src Address %.5x\n", blitter.source.addr & 0xfffff);
1908 osd_printf_debug("Dest Address Byte 0 %.2x\n", blitter.dest.as8bit.addr0);
1909 osd_printf_debug("Dest Address Byte 1 %.2x\n", blitter.dest.as8bit.addr1);
1910 osd_printf_debug("Dest Control %.2x\n", blitter.dest.as8bit.addr2);
1911 osd_printf_debug(" Dst. Address %.5x\n", blitter.dest.addr & 0xfffff);
1912 osd_printf_debug("Mode Control %.2x", blitter.modectl);
1913 osd_printf_debug(" %s\n", blitter.modectl & MODE_BITTOBYTE ? "BIT_TO_BYTE" : "");
1914
1915 osd_printf_debug("Comp. and LFU %.2x\n", blitter.compfunc);
1916 osd_printf_debug("Outer Loop Count %.2x (%d)\n", blitter.outercnt, blitter.outercnt);
1917 osd_printf_debug("Inner Loop Count %.2x (%d)\n", blitter.innercnt, blitter.innercnt);
1918 osd_printf_debug("Step Value %.2x\n", blitter.step);
1919 osd_printf_debug("Pattern Byte %.2x\n", blitter.pattern);
1920 }
1921 #endif
1922
1923 /* Ignore these writes */
1924 if (blitter.dest.addr == 0)
1925 return;
1926
1927 /* Begin outer loop */
1928 for (;;)
1929 {
1930 uint8_t innercnt = blitter.innercnt;
1931 dstdata = blitter.pattern;
1932
1933 if (blitter.command & CMD_LINEDRAW)
1934 {
1935 do
1936 {
1937 if (blitter.modectl & MODE_YFRAC)
1938 {
1939 if (blitter.modectl & MODE_SSIGN )
1940 blitter.dest.as8bit.addr0--;
1941 else
1942 blitter.dest.as8bit.addr0++;
1943 }
1944 else
1945 {
1946 if (blitter.modectl & MODE_DSIGN )
1947 blitter.dest.as8bit.addr1--;
1948 else
1949 blitter.dest.as8bit.addr1++;
1950 }
1951 if( blitter.source.as8bit.addr0 < blitter.step )
1952 {
1953 blitter.source.as8bit.addr0 -= blitter.step ;
1954 blitter.source.as8bit.addr0 += blitter.source.as8bit.addr1;
1955
1956 if ( blitter.modectl & MODE_YFRAC )
1957 {
1958 if (blitter.modectl & MODE_DSIGN )
1959 blitter.dest.as8bit.addr1--;
1960 else
1961 blitter.dest.as8bit.addr1++;
1962 }
1963 else
1964 {
1965 if (blitter.modectl & MODE_SSIGN )
1966 blitter.dest.as8bit.addr0--;
1967 else
1968 blitter.dest.as8bit.addr0++;
1969 }
1970 }
1971 else
1972 {
1973 blitter.source.as8bit.addr0 -= blitter.step;
1974 }
1975
1976 *blitter_get_addr( blitter.dest.addr) = blitter.pattern;
1977 cycles_used++;
1978
1979 } while (--innercnt);
1980 }
1981 else do
1982 {
1983 uint8_t inhibit = 0;
1984
1985 /* TODO: Set this correctly */
1986 uint8_t result = blitter.pattern;
1987
1988 if (LOOPTYPE == 3 && innercnt == blitter.innercnt)
1989 {
1990 srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff));
1991 blitter.source.as16bit.loword++;
1992 cycles_used++;
1993 }
1994
1995 /* Enable source address read and increment? */
1996 if (!(blitter.modectl & (MODE_BITTOBYTE | MODE_PALREMAP)))
1997 {
1998 if (LOOPTYPE == 0 || LOOPTYPE == 1)
1999 {
2000 srcdata = *(blitter_get_addr( blitter.source.addr & 0xfffff));
2001 cycles_used++;
2002
2003 if (blitter.modectl & MODE_SSIGN)
2004 blitter.source.as16bit.loword-- ;
2005 else
2006 blitter.source.as16bit.loword++;
2007
2008 result = srcdata;
2009 }
2010 }
2011
2012 /* Read destination pixel? */
2013 if (LOOPTYPE == 0)
2014 {
2015 dstdata = *blitter_get_addr( blitter.dest.addr & 0xfffff);
2016 cycles_used++;
2017 }
2018
2019 /* Inhibit depending on the bit selected by the inner count */
2020
2021 /* Switch on comparator type? */
2022 if (blitter.modectl & MODE_BITTOBYTE)
2023 {
2024 inhibit = !(srcdata & (1 << (8 - innercnt)));
2025 }
2026
2027 if (blitter.compfunc & CMPFUNC_BEQ)
2028 {
2029 if (srcdata == blitter.pattern)
2030 {
2031 inhibit = 1;
2032
2033 /* TODO: Resume from inhibit? */
2034 if (blitter.command & CMD_COLST)
2035 return;
2036 }
2037 }
2038 if (blitter.compfunc & CMPFUNC_LT)
2039 {
2040 if ((srcdata & 0xc0) > (dstdata & 0xc0))
2041 {
2042 inhibit = 1;
2043
2044 /* TODO: Resume from inhibit? */
2045 if (blitter.command & CMD_COLST)
2046 return;
2047 }
2048 }
2049 if (blitter.compfunc & CMPFUNC_EQ)
2050 {
2051 if ((srcdata & 0xc0) == (dstdata & 0xc0))
2052 {
2053 inhibit = 1;
2054
2055 /* TODO: Resume from inhibit? */
2056 if (blitter.command & CMD_COLST)
2057 return;
2058 }
2059 }
2060 if (blitter.compfunc & CMPFUNC_GT)
2061 {
2062 if ((srcdata & 0xc0) < (dstdata & 0xc0))
2063 {
2064 inhibit = 1;
2065
2066 /* TODO: Resume from inhibit? */
2067 if (blitter.command & CMD_COLST)
2068 return;
2069 }
2070 }
2071
2072 /* Write the data if not inhibited */
2073 if (!inhibit)
2074 {
2075 if (blitter.modectl == MODE_PALREMAP)
2076 {
2077 /*
2078 In this mode, the source points to a 256 entry lookup table.
2079 The existing destination pixel is used as a lookup
2080 into the table and the colours is replaced.
2081 */
2082 uint8_t dest = *blitter_get_addr( blitter.dest.addr);
2083 uint8_t newcol = *(blitter_get_addr( (blitter.source.addr + dest) & 0xfffff));
2084
2085 *blitter_get_addr( blitter.dest.addr) = newcol;
2086 cycles_used += 3;
2087 }
2088 else
2089 {
2090 uint8_t final_result = 0;
2091
2092 if (blitter.compfunc & CMPFUNC_LOG3)
2093 final_result |= result & dstdata;
2094
2095 if (blitter.compfunc & CMPFUNC_LOG2)
2096 final_result |= result & ~dstdata;
2097
2098 if (blitter.compfunc & CMPFUNC_LOG1)
2099 final_result |= ~result & dstdata;
2100
2101 if (blitter.compfunc & CMPFUNC_LOG0)
2102 final_result |= ~result & ~dstdata;
2103
2104 *blitter_get_addr( blitter.dest.addr) = final_result;
2105 cycles_used++;
2106 }
2107 }
2108
2109 /* Update destination address */
2110 if (blitter.modectl & MODE_DSIGN)
2111 blitter.dest.as16bit.loword--;
2112 else
2113 blitter.dest.as16bit.loword++;
2114
2115 } while (--innercnt);
2116
2117 if (!--blitter.outercnt)
2118 {
2119 break;
2120 }
2121 else
2122 {
2123 if (blitter.command & CMD_DSTUP)
2124 blitter.dest.as16bit.loword += blitter.step;
2125
2126 if (blitter.command & CMD_SRCUP)
2127 blitter.source.as16bit.loword += blitter.step;
2128
2129 if (blitter.command & CMD_PARRD)
2130 {
2131 BLITPRG_READ(innercnt);
2132 BLITPRG_READ(step);
2133 BLITPRG_READ(pattern);
2134 }
2135 }
2136 }
2137
2138 /* Read next command header */
2139 BLITPRG_READ(command);
2140
2141 } while (blitter.command & CMD_RUN);
2142
2143 /* Burn Z180 cycles while blitter is in operation */
2144 /* Don't burn for Z8S180 */
2145 // m_maincpu->spin_until_time(attotime::from_nsec( (1000000000 / Z8S180_XTAL)*cycles_used * 2 ) );
2146 }
2147
blitter_get_addr(uint32_t addr)2148 uint8_t* bfcobjam_state::blitter_get_addr(uint32_t addr)
2149 {
2150 if (addr < 0x10000)
2151 {
2152 /* Is this region fixed? */
2153 return (uint8_t*)(memregion("user1")->base() + addr);
2154 }
2155 else if(addr < 0x20000)
2156 {
2157 addr &= 0xffff;
2158 addr += m_rompage * 0x10000 ;
2159
2160 return (uint8_t*)(memregion("user1")->base() + addr );
2161 }
2162 else if (addr >= 0x20000 && addr < 0x40000)
2163 {
2164 return (uint8_t*)&m_video_ram[addr - 0x20000];
2165 }
2166 else
2167 {
2168 return (uint8_t*)&m_work_ram[addr - 0x40000];
2169 }
2170 }
2171
chipset_r(offs_t offset)2172 uint8_t bfcobjam_state::chipset_r(offs_t offset)
2173 {
2174 uint8_t val = 0xff;
2175
2176 switch(offset)
2177 {
2178 case 0:
2179 case 1:
2180 case 2:
2181 case 3:
2182 {
2183 val = m_bank_data[offset];
2184 break;
2185 }
2186 case 6:
2187 {
2188 /* TODO */
2189 val = m_scanline_irq << 4;
2190 break;
2191 }
2192 case 7:
2193 {
2194 m_scanline_irq = 0;
2195 val = 0x1;
2196
2197 /* TODO */
2198 update_irqs();
2199 break;
2200 }
2201 case 0x1C:
2202 {
2203 /* Blitter status ? */
2204 val = ioport("CJIN3")->read();
2205 break;
2206 }
2207 case 0x20:
2208 {
2209 /* Seems correct - used during RLE pic decoding */
2210 val = m_blitter.dest.as8bit.addr0;
2211 break;
2212 }
2213 case 0x22:
2214 {
2215 val = 0x40 | ioport("CJIN2")->read() | ( m_upd7759_int->busy_r() ? 0x20 : 0 ) ;
2216 break;
2217 }
2218 default:
2219 {
2220 osd_printf_debug("Flare One unknown read: 0x%.2x (PC:0x%.4x)\n", offset, m_maincpu->pcbase());
2221 }
2222 }
2223
2224 return val;
2225 }
2226
chipset_w(offs_t offset,uint8_t data)2227 void bfcobjam_state::chipset_w(offs_t offset, uint8_t data)
2228 {
2229 switch (offset)
2230 {
2231 case 0x00:
2232 case 0x01:
2233 case 0x02:
2234 case 0x03:
2235 {
2236 popmessage("%x: Unusual bank access (%x)\n", m_maincpu->pcbase(), data);
2237
2238 data &= 0x3f;
2239 m_bank_data[offset] = data;
2240 z8s180_bank(offset, data);
2241 break;
2242 }
2243
2244 case 0x07:
2245 m_scanline_timer->adjust(m_screen->time_until_pos(data));
2246 break ;
2247
2248 case 0x08:
2249 {
2250 m_flip_8 = data;
2251 break;
2252 }
2253 case 9:
2254 m_videomode = data;
2255 break;
2256
2257 case 0x0B:
2258 {
2259 m_h_scroll = data;
2260 break;
2261 }
2262 case 0x0C:
2263 {
2264 m_v_scroll = data;
2265 break;
2266 }
2267 case 0x0E:
2268 {
2269 m_col4bit[5] = data;
2270 m_col3bit[5] = data;
2271 m_col3bit[5 + 8] = data;
2272 break;
2273 }
2274 case 0x0f:
2275 {
2276 m_col4bit[6] = data;
2277 m_col3bit[6] = data;
2278 m_col3bit[6 + 8] = data;
2279 break;
2280 }
2281 case 0x18:
2282 {
2283 m_blitter.program.as8bit.addr0 = data;
2284 break;
2285 }
2286 case 0x19:
2287 {
2288 m_blitter.program.as8bit.addr1 = data;
2289 break;
2290 }
2291 case 0x1A:
2292 {
2293 m_blitter.program.as8bit.addr2 = data;
2294 break;
2295 }
2296 case 0x20:
2297 {
2298 m_blitter.command = data;
2299
2300 if (data & CMD_RUN)
2301 RunBlit();
2302 else
2303 osd_printf_debug("Blitter stopped by IO.\n");
2304
2305 break;
2306 }
2307 case 0x22:
2308 {
2309 m_flip_22 = data;
2310 genio_w( data ) ;
2311 break;
2312 }
2313 default:
2314 {
2315 osd_printf_debug("Flare One unknown write: 0x%.2x with 0x%.2x (PC:0x%.4x)\n", offset, data, m_maincpu->pcbase());
2316 }
2317 }
2318 }
2319
screen_update_bfcobjam(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)2320 uint32_t bfcobjam_state::screen_update_bfcobjam(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
2321 {
2322 /* Select screen has to be programmed into two registers */
2323 /* No idea what happens if the registers are different */
2324 uint32_t offset;
2325 if (m_flip_8 & 0x40 && m_flip_22 & 0x40)
2326 offset = 0x10000;
2327 else
2328 offset = 0;
2329
2330 uint8_t const *hirescol;
2331 uint8_t const *lorescol;
2332 if(m_videomode & 0x20)
2333 {
2334 hirescol = m_col3bit;
2335 lorescol = m_col7bit;
2336 }
2337 else if(m_videomode & 0x40)
2338 {
2339 hirescol = m_col4bit;
2340 lorescol = m_col6bit;
2341 }
2342 else
2343 {
2344 hirescol = m_col4bit;
2345 lorescol = m_col8bit;
2346 }
2347
2348 for (int y = cliprect.top(); y <= cliprect.bottom(); ++y)
2349 {
2350 uint16_t const y_offset = (y + m_v_scroll) * 256;
2351 uint8_t const *const src = &m_video_ram[offset + y_offset];
2352 uint32_t *dest = &bitmap.pix(y);
2353
2354 for (int x = cliprect.left(); x <= cliprect.right() / 2; ++x)
2355 {
2356 uint8_t const x_offset = x + m_h_scroll;
2357 uint8_t const pen = *(src + x_offset);
2358
2359 if ( ( m_videomode & 0x81 ) == 1 || (m_videomode & 0x80 && pen & 0x80) )
2360 {
2361 *dest++ = m_palette->pen(hirescol[pen & 0x0f]);
2362 *dest++ = m_palette->pen(hirescol[(pen >> 4) & 0x0f]);
2363 }
2364 else
2365 {
2366 *dest++ = m_palette->pen(lorescol[pen]);
2367 *dest++ = m_palette->pen(lorescol[pen]);
2368 }
2369 }
2370 }
2371
2372 return 0;
2373 }
2374
ramdac_map(address_map & map)2375 void bfcobjam_state::ramdac_map(address_map &map)
2376 {
2377 map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w));
2378 }
2379
2380
z8s180_bank(int num,int data)2381 void bfcobjam_state::z8s180_bank(int num, int data)
2382 {
2383 static const char * const bank_names[] = { "bank4","bank1", "bank2", "bank3" };
2384
2385 if (data < 0x04)
2386 {
2387 membank(bank_names[num])->set_base(memregion("user1")->base() + (data*0x4000));
2388 }
2389 else if (data < 0x08)
2390 {
2391 uint32_t offset ;
2392 offset = m_rompage * 0x10000 ;
2393 offset += (data-4) * 0x4000 ;
2394
2395 membank(bank_names[num])->set_base(memregion("user1")->base() + offset);
2396 }
2397 else if (data < 0x10)
2398 {
2399 membank(bank_names[num])->set_base(&m_video_ram[(data - 0x08) * 0x4000]);
2400 }
2401 else
2402 {
2403 membank(bank_names[num])->set_base(&m_work_ram[(data - 0x10) * 0x4000]);
2404 }
2405 }
2406
update_irqs()2407 void bfcobjam_state::update_irqs()
2408 {
2409 int newstate = m_blitter_irq || m_scanline_irq || m_acia_irq;
2410
2411 if (newstate != m_irq_state)
2412 {
2413 m_irq_state = newstate;
2414 m_maincpu->set_input_line(0, m_irq_state ? ASSERT_LINE : CLEAR_LINE);
2415 }
2416 }
2417
TIMER_CALLBACK_MEMBER(bfcobjam_state::scanline_callback)2418 TIMER_CALLBACK_MEMBER( bfcobjam_state::scanline_callback )
2419 {
2420 m_scanline_timer->adjust(m_screen->time_until_pos(0));
2421 m_scanline_irq = 1;
2422 update_irqs();
2423 }
2424
WRITE_LINE_MEMBER(bfcobjam_state::z8s180_acia_irq)2425 WRITE_LINE_MEMBER(bfcobjam_state::z8s180_acia_irq)
2426 {
2427 m_acia_irq = state;
2428 update_irqs();
2429 }
2430
2431
rombank_w(uint8_t data)2432 void bfcobjam_state::rombank_w(uint8_t data)
2433 {
2434 m_rompage = data ;
2435
2436 membank("bank5")->set_entry(m_rompage & 0x0f);
2437 }
2438
2439 /*
2440 This parallel port is used for bit-bashing the following devices.
2441 1. Dot matrix display
2442 2. I2C 24C08
2443 The bit use is as follows:
2444 b0 =
2445 b1 =
2446 b2 = Dot matrix clock
2447 b3 = Dot matrix data
2448 b4 = Dot matrix reset
2449 b5 = I2C SDA
2450 b6 = I2C SCL
2451 b7 =
2452 */
output0_w(uint8_t data)2453 void bfcobjam_state::output0_w(uint8_t data)
2454 {
2455 uint8_t changed = m_port_0 ^ data ;
2456 m_port_0 = data ;
2457
2458 dotmatrix_w( data ) ;
2459
2460 //cobra handling of scl and sda is wrong but devices handle it ok
2461 //unfortunately mame emulation of i2c 24c08 doesn't :(
2462 //we frig the driving of scl/sda to correct this
2463 changed &= 0x60 ;
2464
2465 if( changed == 0x60 )
2466 {
2467 if( data & 0x40 )
2468 {
2469 m_i2cmem->write_scl(!(BIT(data, 6)));
2470 m_i2cmem->write_sda(!(BIT(data, 5)));
2471 }
2472 else
2473 {
2474 m_i2cmem->write_sda(!(BIT(data, 5)));
2475 m_i2cmem->write_scl(!(BIT(data, 6)));
2476 }
2477 }
2478 else
2479 {
2480 m_i2cmem->write_scl(!(BIT(data, 6)));
2481 m_i2cmem->write_sda(!(BIT(data, 5)));
2482 }
2483 }
2484
dotmatrix_w(uint8_t data)2485 void bfcobjam_state::dotmatrix_w( uint8_t data )
2486 {
2487 if( m_dm01 )
2488 {
2489 data &= 0x1c ;
2490
2491 if( data != dm_last_data )
2492 {
2493 if( data & 0x10 )
2494 {
2495 }
2496 else
2497 {
2498 m_dm01->reset() ;
2499 dm_shift=0;
2500 dm_shift_data=0;
2501 }
2502 if( !(data & 4 ) && ( dm_last_data & 4 ) && data & 0x10 ) // clock is low but was high and out of reset
2503 {
2504 dm_shift_data <<= 1 ;
2505 if( !(data & 0x08 ))
2506 {
2507 dm_shift_data |=1 ;
2508 }
2509 dm_shift++;
2510 if( dm_shift == 8 )
2511 {
2512 dm_shift=0;
2513 m_dm01->writedata( dm_shift_data ) ;
2514 }
2515 }
2516 dm_last_data = data ;
2517 }
2518 }
2519 }
2520
input0_r()2521 uint8_t bfcobjam_state::input0_r()
2522 {
2523 return ioport("CJIN0")->read() | (m_i2cmem->read_sda() ? 0x80 : 0x00);
2524 }
2525
input1_r()2526 uint8_t bfcobjam_state::input1_r()
2527 {
2528 return ioport("CJIN1")->read();
2529 }
2530
aux_upd7759_w(uint8_t data)2531 void bfcobjam_state::aux_upd7759_w(uint8_t data)
2532 {
2533 if( m_aux_upd7759 )
2534 {
2535 m_aux_upd7759->set_rom_bank((data>>2)&3);
2536
2537 m_aux_upd7759->port_w((data>>4)&0xf);
2538
2539 m_aux_upd7759->md_w(1);
2540
2541 m_aux_upd7759->reset_w(BIT(data, 0));
2542
2543 m_aux_upd7759->start_w(!BIT(data, 1));
2544 }
2545 }
2546
aux_upd7759_r()2547 uint8_t bfcobjam_state::aux_upd7759_r()
2548 {
2549 if( m_aux_upd7759 )
2550 {
2551 return m_aux_upd7759->busy_r();
2552 }
2553 else
2554 {
2555 return 0 ;
2556 }
2557 }
2558
genio_w(uint8_t data)2559 void bfcobjam_state::genio_w( uint8_t data )
2560 {
2561 //bit 0 = ??
2562 //bit 1 = upd7759 start
2563 //bit 2 = upd7759 reset
2564 //bit 3 = ??
2565 //bit 4 = digital volume clock
2566 //bit 5 = digital volume up/down
2567 //bit 6 = ??
2568 //bit 7 = ??
2569
2570 uint8_t changed = m_genio ^ data ;
2571
2572 m_genio = data ;
2573
2574 if ( changed & 0x10)
2575 { // digital volume clock line changed
2576 if ( !(data & 0x10) )
2577 { // changed from high to low,
2578 if ( data & 0x20 )
2579 {
2580 if ( m_global_volume < 31 ) m_global_volume++; //0-31 expressed as 1-32
2581 }
2582 else
2583 {
2584 if ( m_global_volume > 0 ) m_global_volume--;
2585 }
2586
2587 {
2588 if (m_ym2413)
2589 {
2590 float percent = (32 - m_global_volume) / 32.0f;
2591
2592 m_ym2413->set_output_gain(ALL_OUTPUTS, percent);
2593 m_upd7759_int->set_output_gain(ALL_OUTPUTS, percent);
2594 if( m_aux_upd7759 )
2595 {
2596 m_aux_upd7759->set_output_gain(ALL_OUTPUTS, percent);
2597 }
2598 }
2599 }
2600 }
2601 }
2602
2603 //bits 1 and 2 are for upd7759
2604 m_upd7759_int->md_w(0);
2605 m_upd7759_int->reset_w(!BIT(data,2));
2606 m_upd7759_int->start_w(BIT(data,1));
2607 }
2608
upd7759_w(uint8_t data)2609 void bfcobjam_state::upd7759_w(uint8_t data)
2610 {
2611 m_upd7759_int->port_w(data);
2612 }
2613
WRITE_LINE_MEMBER(bfcobjam_state::upd7759_generate_dreq)2614 WRITE_LINE_MEMBER( bfcobjam_state::upd7759_generate_dreq )
2615 {
2616 if( state )
2617 {
2618 m_maincpu->set_input_line(Z180_INPUT_LINE_DREQ0, ASSERT_LINE );
2619 }
2620 else
2621 {
2622 m_maincpu->set_input_line(Z180_INPUT_LINE_DREQ0, CLEAR_LINE );
2623 }
2624 }
2625
video_start()2626 void bfcobjam_state::video_start()
2627 {
2628 memcpy(m_col4bit, col4bit_default, sizeof(m_col4bit));
2629 memcpy(m_col3bit, col3bit_default, sizeof(m_col3bit));
2630 for (int i = 0; i < 256; ++i)
2631 {
2632 uint8_t col;
2633
2634 m_col8bit[i] = i;
2635 col = i & 0x7f;
2636 col = (col & 0x1f) | (col76index[ ( (col & 0x60) >> 5 ) & 3] << 5);
2637 m_col7bit[i] = col;
2638
2639 col = (col & 3) | (col76index[( (col & 0x0c) >> 2) & 3] << 2 ) |
2640 (col76index[( (col & 0x30) >> 4) & 3] << 5 );
2641 m_col6bit[i] = col;
2642 }
2643 }
2644
2645 /***************************************************************************
2646
2647 Cobra II Z8S180 Memory Map
2648
2649 ***************************************************************************/
2650
z8s180_prog_map(address_map & map)2651 void bfcobjam_state::z8s180_prog_map(address_map &map)
2652 {
2653 map(0x00000, 0x03fff).bankrw("bank4");
2654 map(0x04000, 0x07fff).bankrw("bank1");
2655 map(0x08000, 0x0bfff).bankrw("bank2");
2656 map(0x0c000, 0x0ffff).bankrw("bank3");
2657 map(0x10000, 0x1ffff).bankrw("bank5");
2658 map(0x20000, 0x3ffff).ram().share(m_video_ram);
2659 map(0x40000, 0xfffff).ram().share(m_work_ram);
2660 }
2661
z8s180_io_map(address_map & map)2662 void bfcobjam_state::z8s180_io_map(address_map &map)
2663 {
2664 map.global_mask(0xff);
2665 map(0x00, 0x23).rw(FUNC(bfcobjam_state::chipset_r), FUNC(bfcobjam_state::chipset_w));
2666 map(0x24, 0x25).w(m_acia6850_0, FUNC(acia6850_device::write));
2667 map(0x26, 0x27).r(m_acia6850_0, FUNC(acia6850_device::read));
2668 map(0x2c, 0x2c).w(FUNC(bfcobjam_state::rombank_w));
2669 map(0x30, 0x30).w(FUNC(bfcobjam_state::upd7759_w));
2670 map(0x50, 0x50).w("ramdac", FUNC(ramdac_device::index_w));
2671 map(0x51, 0x51).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w));
2672 map(0x52, 0x52).w("ramdac", FUNC(ramdac_device::mask_w));
2673 map(0x53, 0x53).w("ramdac", FUNC(ramdac_device::index_r_w));
2674 map(0x80, 0x87).r(FUNC(bfcobjam_state::input1_r));
2675 map(0x88, 0x8f).r(FUNC(bfcobjam_state::input0_r));
2676 map(0x88, 0x8f).w(FUNC(bfcobjam_state::output0_w));
2677 map(0x90, 0x97).r(FUNC(bfcobjam_state::aux_upd7759_r));
2678 map(0x90, 0x97).w(m_ym2413,FUNC(ym2413_device::write));
2679 map(0x98, 0x9f).w(FUNC(bfcobjam_state::aux_upd7759_w));
2680 }
2681
2682
2683 static INPUT_PORTS_START( brkball )
2684 PORT_START("CJIN0")
2685 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 FIRE C")
2686 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
2687 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2688 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2689 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
2690 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
2691 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_COIN1 )
2692
2693 PORT_START("CJIN1")
2694 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START2 )
2695 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP )
2696 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN )
2697 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT )
2698 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )
2699 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Left Flip")
2700 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Right Flip")
2701 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2702
2703 PORT_START("CJIN2")
2704 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P1 Left Flip")
2705 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P1 Right Flip")
2706 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2707 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2708 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_SERVICE1 )
2709 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2710 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2711 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN2 )
2712
2713 PORT_START("CJIN3")
2714 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2715 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2716 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2717 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )
PORT_CODE(KEYCODE_F1)2718 PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_TILT ) PORT_NAME("TEST") PORT_CODE(KEYCODE_F1)
2719 PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2720 PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2721 PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNKNOWN )
2722 INPUT_PORTS_END
2723
2724
2725 void bfcobjam_state::machine_start()
2726 {
2727 membank("bank5")->configure_entries(0, 0x10, memregion("user1")->base(), 0x10000);
2728 membank("bank5")->set_entry(1);
2729 }
2730
machine_reset()2731 void bfcobjam_state::machine_reset()
2732 {
2733 for (unsigned int pal = 0; pal < 256; ++pal)
2734 {
2735 m_palette->set_pen_color(pal, pal3bit((pal>>5)&7), pal3bit((pal>>2)&7), pal2bit(pal&3));
2736 }
2737
2738 m_rompage = 0 ;
2739 m_bank_data[0] = 0;
2740 m_bank_data[1] = 0;
2741 m_bank_data[2] = 0;
2742 m_bank_data[3] = 0;
2743
2744 m_genio = 0 ;
2745 m_global_volume = 0;
2746
2747 m_ym2413->reset();
2748
2749
2750 m_irq_state = m_blitter_irq = m_scanline_irq = m_acia_irq = 0;
2751
2752 m_scanline_timer->adjust(m_screen->time_until_pos(0));
2753
2754 if( m_dm01 )
2755 m_dm01->reset() ;
2756 }
2757
WRITE_LINE_MEMBER(bfcobjam_state::write_acia_clock)2758 WRITE_LINE_MEMBER(bfcobjam_state::write_acia_clock)
2759 {
2760 m_acia6850_0->write_txc(state);
2761 m_acia6850_0->write_rxc(state);
2762 }
2763
bfcobjam(machine_config & config)2764 void bfcobjam_state::bfcobjam(machine_config &config)
2765 {
2766 Z8S180(config, m_maincpu, Z8S180_XTAL);
2767 m_maincpu->set_addrmap(AS_PROGRAM, &bfcobjam_state::z8s180_prog_map);
2768 m_maincpu->set_addrmap(AS_IO, &bfcobjam_state::z8s180_io_map);
2769
2770 /* TODO */
2771 SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
2772 m_screen->set_refresh_hz(50);
2773 m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
2774 m_screen->set_size(512, 256);
2775 m_screen->set_visarea_full();
2776 m_screen->set_screen_update(FUNC(bfcobjam_state::screen_update_bfcobjam));
2777
2778 PALETTE(config, m_palette).set_entries(256);
2779
2780 ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette)); // MUSIC Semiconductor TR9C1710 RAMDAC or equivalent
2781 ramdac.set_addrmap(0, &bfcobjam_state::ramdac_map);
2782 ramdac.set_split_read(1);
2783
2784 SPEAKER(config, "mono").front_center();
2785
2786 UPD7759(config, m_upd7759_int);
2787 m_upd7759_int->add_route(ALL_OUTPUTS, "mono", 0.40);
2788 m_upd7759_int->drq().set(FUNC(bfcobjam_state::upd7759_generate_dreq));
2789
2790 YM2413(config, m_ym2413, XTAL(3'579'545)).add_route(ALL_OUTPUTS, "mono", 1.0);
2791
2792
2793 /* ACIAs */
2794 ACIA6850(config, m_acia6850_0, 0);
2795 m_acia6850_0->irq_handler().set(FUNC(bfcobjam_state::z8s180_acia_irq));
2796
2797 clock_device &acia_clock(CLOCK(config, "acia_clock", 31250*16)); // What are the correct ACIA clocks ?
2798 acia_clock.signal_handler().set(FUNC(bfcobjam_state::write_acia_clock));
2799
2800 I2C_24C08(config, m_i2cmem);
2801 }
2802
bfcobjam_with_dmd(machine_config & config)2803 void bfcobjam_state::bfcobjam_with_dmd(machine_config &config)
2804 {
2805 bfcobjam( config ) ;
2806
2807 UPD7759(config, m_aux_upd7759);
2808 m_aux_upd7759->add_route(ALL_OUTPUTS, "mono", 0.40);
2809
2810 BFM_DM01(config, m_dm01, 0);
2811 }
2812
2813 /***************************************************************************
2814
2815 Game driver(s)
2816
2817 Note: Two different versions of each 6809 ROM exist: standard and protocol
2818 It appears sets can be a combination of disk images, 6809 and Z80 ROMs!
2819
2820 ***************************************************************************/
2821
2822 ROM_START( inquiztr )
2823 ROM_REGION( 0x10000, "audiocpu", 0 )
2824 ROM_LOAD( "inq6809", 0x08000, 0x08000, CRC(ae996600) SHA1(f360399e77b81399d910770fa8106c196f04363c) )
2825
2826 ROM_REGION( 0x20000, "user1", 0 )
2827 ROM_LOAD( "9576002.bin", 0x00000, 0x10000, CRC(5b8c8a04) SHA1(af5328fee79c370f45bff36f534aaf50964b6900) )
2828
2829 ROM_REGION( 0x20000, "altuser1", 0 )
2830 ROM_LOAD( "9576028.bin", 0x10000, 0x10000, CRC(2d85682c) SHA1(baec47bff4b8beef5afbb737dc57b22bf93ebcf8) )
2831
2832 // these look quite different.. (like they belong together) but booting with these gives a checksum error (banking?)
2833 ROM_LOAD( "inqvypp1", 0x00000, 0x010000, CRC(9bac8c6e) SHA1(15e24d60c2f3997e637694f60daa552b22628766) )
2834 ROM_LOAD( "inqvypp2", 0x10000, 0x010000, CRC(f9cd196c) SHA1(0ac31d87462cbee6f41e19aefe740d876910bdf5) )
2835
2836 ROM_REGION( 0x1c2000, "user2", 0 )
2837 ROM_LOAD( "inqdisk.img", 0x000000, 0x1c2000, NO_DUMP )
2838 ROM_END
2839
2840
2841
2842
2843 ROM_START( escounts )
2844 ROM_REGION( 0x10000, "audiocpu", 0 )
2845 ROM_LOAD( "esc12int", 0x08000, 0x08000, CRC(741a1fe6) SHA1(e741d0ae0d2f11036a358120381e4b0df4a560a1) )
2846
2847 ROM_REGION( 0x10000, "altrevs", 0 )
2848 ROM_LOAD( "bfm_esc.bin", 0x08000, 0x08000, CRC(27acb5a5) SHA1(da50d650ab6456d61d0fb7f89247f2040b4bb9a8) )
2849 ROM_LOAD( "escint1b", 0x08000, 0x08000, CRC(fde413c9) SHA1(18724a1b771ba4c72e571c356591c5be32948d7a) )
2850
2851 ROM_REGION( 0x10000, "user1", 0 )
2852 ROM_LOAD( "esccobpa", 0x00000, 0x10000, CRC(d8eadeb7) SHA1(9b94f1454e6a17bf8321b0ef4ddd0ed1a56150f7) )
2853
2854 /* 95-100-207 */
2855 ROM_REGION( 0x190000, "user2", 0 )
2856 ROM_LOAD( "escdisk4.img", 0x000000, 0x190000, CRC(24156e0f) SHA1(e163daa8effadd93ace2bc2ba1af0f4a190abd7f) )
2857 ROM_END
2858
2859 ROM_START( trebltop )
2860 ROM_REGION( 0x10000, "audiocpu", 0 )
2861 ROM_LOAD( "95740078.bin", 0x08000, 0x08000, CRC(aca1980b) SHA1(3d4ed1dc545cc80f56d7daa13028fb10a12a718b) )
2862
2863 ROM_REGION( 0x10000, "altrevs", 0 )
2864 ROM_LOAD( "ttopint", 0x08000, 0x08000, CRC(cc798f90) SHA1(c3f541ebbb3a2c29cc4f00bbd47e289bcff50ecb) )
2865
2866 ROM_REGION( 0x20000, "user1", 0 )
2867 ROM_LOAD( "95760031.bin", 0x00000, 0x10000, CRC(8e75edb8) SHA1(0aaa3834d5ac20f92bdf1f2b8f1eb71854469cbe) )
2868 ROM_LOAD( "95760021.bin", 0x10000, 0x10000, CRC(f42016c0) SHA1(7067d018cb4bdcfba777267fb01cddf44e4216c3) )
2869
2870 ROM_REGION( 0x1c2000, "user2", 0 )
2871 ROM_LOAD( "ttdisk1.img", 0x000000, 0x190000, CRC(b2003228) SHA1(5eb49f05137cdd404f22948d39aa79c1518c06eb) )
2872
2873 ROM_REGION( 0x20000, "upd", 0 )
2874 ROM_LOAD( "95000172.bin", 0x00000, 0x10000, CRC(e85367a5) SHA1(695fd95ddeecdb16602f7b0f075cf5128a2fb808) )
2875 ROM_LOAD( "95000173.bin", 0x10000, 0x10000, CRC(8bda2c5e) SHA1(79aab5a2af7a5add5fe9132dc13bcc3705c6faf3) )
2876 ROM_END
2877
2878 ROM_START( beeline )
2879 ROM_REGION( 0x10000, "audiocpu", 0 )
2880 ROM_LOAD( "bln12int.a", 0x08000, 0x08000, CRC(cb97905e) SHA1(9725156bf64e53a56bc0f90795d4b07db41d059e) )
2881
2882 ROM_REGION( 0x10000, "altrevs", 0 )
2883 ROM_LOAD( "beeint12", 0x8000, 0x008000, CRC(0a77d0be) SHA1(8e55e7b4eb85cc2521d8fdf7ede02131ed80372e) )
2884
2885
2886 ROM_REGION( 0x20000, "user1", 0 )
2887 ROM_LOAD( "blncob.pa", 0x00000, 0x10000, CRC(8abc0017) SHA1(ecf6e7a4021b35295eb9bb9aed1b88fff27ffbd1) )
2888 ROM_LOAD( "blncob.pb", 0x10000, 0x10000, CRC(feb121fe) SHA1(e83bfd6db00a3264e5076f257e261a1cb4605a83) )
2889
2890 ROM_REGION( 0x1c2000, "user2", 0 )
2891 ROM_LOAD( "beedisk.img", 0x000000, 0x1c2000, NO_DUMP )
2892 ROM_END
2893
2894 ROM_START( quizvadr )
2895 ROM_REGION( 0x10000, "audiocpu", 0 )
2896 ROM_LOAD( "q6809.bin", 0x08000, 0x8000, CRC(a74dff10) SHA1(87578694a022dc3d7ade9cc76d387c1ae5fc74d9) )
2897
2898 ROM_REGION( 0x10000, "altrevs", 0 )
2899 ROM_LOAD( "qvadrint", 0x08000, 0x08000, CRC(4c729943) SHA1(ab4e0fb6cfc66540ea1e9e36eebdf85f65c5fd2a) )
2900
2901 ROM_REGION( 0x200000, "user1", 0 )
2902 ROM_LOAD( "5947011r.0", 0x000000, 0x80000, CRC(cac43c97) SHA1(3af529cd0f8ec57dd3596f5bca7b9c74cff171e4) )
2903 ROM_LOAD( "5947011r.1", 0x080000, 0x80000, CRC(120018dc) SHA1(cd153d2b7ed535b04dbcaf189d2fc96fe3c5b466) )
2904 ROM_LOAD( "5947011r.2", 0x100000, 0x80000, CRC(689b3b5a) SHA1(ea32d18acfd380de822efff4f2c95ce9873a33a2) )
2905 ROM_LOAD( "5947011r.3", 0x180000, 0x80000, CRC(c38dafeb) SHA1(d693387a5c3cde34c9d581f81a08a5fbc6f753f2) )
2906
2907 ROM_REGION( 0x20000, "upd", 0 )
2908 ROM_LOAD( "185snd2.bin", 0x00000, 0x10000, CRC(e36eccc2) SHA1(cfd8ca4c71528ea4e229074016240681b6de37cd) )
2909 ROM_LOAD( "184snd1.bin", 0x10000, 0x10000, CRC(aac058e8) SHA1(39e59ad9524130fc3bd8d46e1aa78bc4daf04e39) )
2910 ROM_END
2911
2912 ROM_START( qos )
2913 ROM_REGION( 0x10000, "audiocpu", 0 )
2914 ROM_LOAD( "39360107.bin", 0x08000, 0x8000, CRC(20844655) SHA1(b67c7f7bbabf6d5139b8ad8cbb5f8cc3f28e9cc7) )
2915
2916 ROM_REGION( 0x200000, "user1", 0 )
2917 ROM_LOAD( "95000338.rm0", 0x000000, 0x80000, CRC(96918aae) SHA1(849ce7b8eccc89c45aacc840a73935f95788a141) )
2918 ROM_LOAD( "95000339.rm1", 0x080000, 0x80000, CRC(b4c6dcc0) SHA1(56d8761766dfbd5b0e71f8c3ca575e88f1bc9929) )
2919 ROM_LOAD( "95000340.rm2", 0x100000, 0x80000, CRC(66d121fd) SHA1(ac65cc0ac6b0a41e78a3159c21ee44f765bdb5c8) )
2920 ROM_LOAD( "95000341.rm3", 0x180000, 0x80000, CRC(ef13658d) SHA1(240bc589900214eac79c91a531f254a9ac2f4ef6) )
2921
2922 ROM_REGION( 0x20000, "upd", 0 )
2923 ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) )
2924 ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) )
2925 ROM_END
2926
2927 ROM_START( qosa )
2928 ROM_REGION( 0x10000, "audiocpu", 0 )
2929 ROM_LOAD( "qos_nondata_68f4.bin", 0x08000, 0x8000, CRC(5f40005a) SHA1(180017acf6b432bc135d1090099fdf99f1e3583a) )
2930
2931 ROM_REGION( 0x200000, "user1", 0 )
2932 ROM_LOAD( "95000338.rm0", 0x000000, 0x80000, CRC(96918aae) SHA1(849ce7b8eccc89c45aacc840a73935f95788a141) )
2933 ROM_LOAD( "95000339.rm1", 0x080000, 0x80000, CRC(b4c6dcc0) SHA1(56d8761766dfbd5b0e71f8c3ca575e88f1bc9929) )
2934 ROM_LOAD( "95000340.rm2", 0x100000, 0x80000, CRC(66d121fd) SHA1(ac65cc0ac6b0a41e78a3159c21ee44f765bdb5c8) )
2935 ROM_LOAD( "95000341.rm3", 0x180000, 0x80000, CRC(ef13658d) SHA1(240bc589900214eac79c91a531f254a9ac2f4ef6) )
2936
2937 ROM_REGION( 0x20000, "upd", 0 )
2938 ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) )
2939 ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) )
2940 ROM_END
2941
2942 ROM_START( qosb )
2943 ROM_REGION( 0x10000, "audiocpu", 0 )
2944 ROM_LOAD( "95740599.bin", 0x08000, 0x8000, CRC(bf1e321f) SHA1(51f18620f22ba2a1b110954284ddf00614d51a0e) )
2945
2946 ROM_REGION( 0x200000, "user1", 0 )
2947 ROM_LOAD( "rom0_306.bin", 0x000000, 0x80000, CRC(c26c8f83) SHA1(6949027e1fe241cbb2e1cbbce18e47bcb0d84550) )
2948 ROM_LOAD( "rom1_307.bin", 0x080000, 0x80000, CRC(94611c03) SHA1(81f545ff96ff3d44285315400da94d870c89f896) )
2949 ROM_LOAD( "rom2_308.bin", 0x100000, 0x80000, CRC(f5572726) SHA1(e109265c5571d21213a6f405a13459e7bc6699bc) )
2950 ROM_LOAD( "rom3_309.bin", 0x180000, 0x80000, CRC(1b5edfa8) SHA1(348488debd4aa52f064e351ed0c082274da1db2b) )
2951
2952 ROM_REGION( 0x20000, "upd", 0 )
2953 ROM_LOAD( "snd1_218.ic7", 0x00000, 0x10000, CRC(061f496d) SHA1(653d16454d909c034191813b37d14010da7258c6) )
2954 ROM_LOAD( "snd2_219.ic8", 0x10000, 0x10000, CRC(d7874a47) SHA1(5bbd4040c7c0299e8cc135e6c6cd05370b260e9b) )
2955
2956 /* there is a set close to this with
2957
2958 ROM_LOAD( "qosrom0", 0x0000, 0x080000, CRC(4f150634) SHA1(beb1d3c212b189f3baa08fe454e83f30108be08e) )
2959 qosrom1 = rom1_307.bin qosb A Question of Sport (39-960-089)
2960 ROM_LOAD( "qosrom2", 0x0000, 0x080000, CRC(c39737db) SHA1(ccfdb19dab3af064db44e6022248aef98749bc97) )
2961 ROM_LOAD( "qosrom3", 0x0000, 0x080000, CRC(785b8ff9) SHA1(61b31e0e60c31ecb4b179bfe008a96155d939709) )
2962 ROM_LOAD( "qossnd1", 0x0000, 0x010000, CRC(888a29f8) SHA1(0e5aa9db54e783708ece1e8c7bffb10d994ab384) )
2963
2964 but it simply looks like a bad dump, rom3 is an alt 'rom 2' and the others are mostly the same as qosb
2965 */
2966
2967 ROM_END
2968
2969 /* The dot matrix software "ledv1.bin" is development software and not the release version.
2970 Everything appears to work correctly except there are issues when the machine first starts with the
2971 display showing a strange animation.
2972 */
2973 ROM_START( brkball )
2974 ROM_REGION( 0x200000, "user1", 0 )
2975 ROM_LOAD( "95000352.bin", 0x000000, 0x80000, CRC(8daad60a) SHA1(10ac31b7791c2215d0561972ae63e1405361b908) )
2976 ROM_LOAD( "95000353.bin", 0x080000, 0x80000, CRC(8e7b84ed) SHA1(b5e9ffe08eabe1446aa583fb85548451d944e811) )
2977
2978 ROM_REGION( 0x80000, "upd", 0 )
2979 ROM_LOAD( "sounds.bin", 0x00000, 0x80000, CRC(4e84402d) SHA1(f6056669f005d8790331be5b0f34d9441190b120) )
2980
2981 ROM_REGION( 0x20000, "dm01:matrix", 0 )
2982 ROM_LOAD("ledv1.bin", 0x00000, 0x10000, CRC(ea918cb9) SHA1(9e7047613cf1cb4b9a7fefb8a02d8479a7b09e6a))
2983 ROM_END
2984
2985 GAME( 1989, inquiztr, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Inquizitor", MACHINE_NOT_WORKING )
2986 GAME( 1990, escounts, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Every Second Counts (39-360-053)", MACHINE_IMPERFECT_GRAPHICS )
2987 GAME( 1991, trebltop, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Treble Top (39-360-070)", MACHINE_IMPERFECT_GRAPHICS )
2988 GAME( 1991, beeline, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Beeline (39-360-075)", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_GRAPHICS )
2989 GAME( 1991, quizvadr, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "Quizvaders (39-360-078)", MACHINE_IMPERFECT_GRAPHICS )
2990 GAME( 1992, qos, 0, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 1, 39-960-107)", MACHINE_IMPERFECT_GRAPHICS )
2991 GAME( 1992, qosa, qos, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 2, 39-960-099)", MACHINE_IMPERFECT_GRAPHICS )
2992 GAME( 1992, qosb, qos, bfcobra, bfcobra, bfcobra_state, init_bfcobra, ROT0, "BFM", "A Question of Sport (set 3, 39-960-089)", MACHINE_IMPERFECT_GRAPHICS )
2993 GAMEL(1994, brkball, 0, bfcobjam_with_dmd,brkball, bfcobjam_state,init_bfcobjam,ROT0, "BFM/ATOD", "Break Ball", MACHINE_IMPERFECT_GRAPHICS, layout_brkball )
2994