1 // license:BSD-3-Clause
2 // copyright-holders:Jason Eckhardt, Andrew Gardner, Philip Bennett
3 /*
4 Virtual Combat hardware games.
5
6 Driver by Jason Eckhardt, Andrew Gardner and Phil Bennett.
7
8 ----
9
10 There are two known games on this hardware. Both are developed by
11 Kyle Hodgetts.
12
13 Virtual Combat (c) VR8 Inc. 1993
14 http://arcade.sonzogni.com/VRCombat/
15
16 Shadow Fighters (German) (c) Dutech 1993
17
18 ----
19
20 There are two boards to this hardware. The upper, which contains the
21 graphics ROMs and the i860, and the lower which contains the main
22 and sound CPUs. Virtual Combat sports two upper boards which
23 output a different rasterization of the scene for each stereo eye.
24
25 UPPER: (Virtual Combat has an identical MIDDLE board also).
26 Intel I860 XR processor
27 MB8298-25P-SK RAMS x12 (silkscreen said 62256)
28 Analog device ADV476KN50E (silkscreen said BT476)
29 20 MHZ Oscillator
30 8-way DIP switch
31 574200D x4
32 PAL palce24v10 x2 (next to the i860)
33 Bt476 RAMDAC
34
35 LOWER:
36 Motorola MC68000P12 x2
37 12 MHz Oscillator x2
38 Harris ADC0804LCN x2
39 4 MB8298-25P-SK RAMS (in groups of 2 off by themselves)
40 1 CXK58257SP-10L at each end of the SNDCPU ROMS and the CPU ROMS (4 chips total)
41 Motorola MC6845P CRT controller
42 2x 27C010A containing sound code
43 Xx 27C040 containing sound data (VOC files)
44 Dallas DS1220Y - closest to pin 64 of CPU - read as a 2716 - (silkscreened "6116")
45 Xx 27c040 containing program code, etc.
46
47 ----
48
49 NOTES : Shadow Fighters appears to have been dumped from an earlier
50 revision of the hardware. There are no IC labels, and
51 lots of factory rework has been done to the bottom board.
52 Because the board was so early for Shadow Fighters, there were
53 no IC locations silkscreened on the PCB. The locations
54 from Virtual Combat have been used.
55 The Shadow Fighters bottom board has an extra 20 mhz xtal on it.
56 The data stored in "samples" is simply a series of
57 Creative Media VOC files concatenated to each other.
58 The sound program ("sound") is about 640 bytes long.
59 The hardware is said to run at medium resolution.
60 The SRAM module dump can likely be thrown away for both games.
61 The PAL that's dumped for Shadow Fighters looks pretty bad.
62
63 TODO : This is a partially working driver. Most of the memory maps for
64 all four CPUs are complete. An Intel i860XR CPU core has now
65 been incorporated into MAME.
66
67 -------- Notes/questions ----------
68 - Most of the memory maps and input ports are complete now.
69 For "main", the only I/O locations that seem to be left
70 mysterious are:
71 0x60001C: Only read; might be a latch of some sort. It is
72 read each time M0's interrupt service routine syncs
73 with the i860's to have them update the frame buffer.
74 Might this be a HW blank bit so things look clean when
75 the i860's do their updates?
76 The two other times I see it read are just before
77 and after one of the palette setups is done.
78 0x600018: ? No info yet.
79 0x704000: (VC only) Likely analog axis for VR headset
80 0x703000: (VC only) Likely analog axis for VR headset
81
82 ----------------------------------------------
83 */
84
85 #include "emu.h"
86 #include "cpu/i860/i860.h"
87 #include "cpu/m68000/m68000.h"
88 #include "machine/nvram.h"
89 #include "sound/dac.h"
90 #include "video/mc6845.h"
91 #include "video/tlc34076.h"
92 #include "rendlay.h"
93 #include "screen.h"
94 #include "speaker.h"
95
96 #define VERBOSE 0
97 #include "logmacro.h"
98
99
100 class vcombat_state : public driver_device
101 {
102 public:
vcombat_state(const machine_config & mconfig,device_type type,const char * tag)103 vcombat_state(const machine_config &mconfig, device_type type, const char *tag)
104 : driver_device(mconfig, type, tag),
105 m_tlc34076(*this, "tlc34076"),
106 m_framebuffer_ctrl(*this, "fb_control"),
107 m_maincpu(*this, "maincpu"),
108 m_soundcpu(*this, "soundcpu"),
109 m_vid(*this, "vid_%u", 0U),
110 m_dac(*this, "dac"),
111 m_crtc(*this, "crtc") { }
112
113 void init_shadfgtr();
114 void init_vcombat();
115
116 void shadfgtr(machine_config &config);
117 void vcombat(machine_config &config);
118
119 protected:
120 virtual void machine_reset() override;
121
122 private:
123 required_device<tlc34076_device> m_tlc34076;
124 required_shared_ptr<uint16_t> m_framebuffer_ctrl;
125 required_device<cpu_device> m_maincpu;
126 required_device<cpu_device> m_soundcpu;
127 optional_device_array<i860_cpu_device, 2> m_vid;
128 required_device<dac_word_interface> m_dac;
129 optional_device<mc6845_device> m_crtc;
130
131 std::unique_ptr<uint16_t[]> m_m68k_framebuffer[2];
132 std::unique_ptr<uint16_t[]> m_i860_framebuffer[2][2];
133 int m_crtc_select;
134
135 void main_video_write(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
136 uint16_t control_1_r();
137 uint16_t control_2_r();
138 uint16_t control_3_r();
139 void wiggle_i860_common(int which, uint16_t data);
140 void wiggle_i860p0_pins_w(uint16_t data);
141 void wiggle_i860p1_pins_w(uint16_t data);
142 uint16_t main_irqiack_r();
143 uint16_t sound_resetmain_r();
144 void v0_fb_w(offs_t offset, uint64_t data, uint64_t mem_mask = ~0);
145 void v1_fb_w(offs_t offset, uint64_t data, uint64_t mem_mask = ~0);
146 void crtc_w(uint16_t data);
147 void vcombat_dac_w(uint16_t data);
148 DECLARE_WRITE_LINE_MEMBER(sound_update);
149
150 uint32_t update_screen(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int index);
151 uint32_t screen_update_vcombat_main(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
152 uint32_t screen_update_vcombat_aux(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
153
154 void main_map(address_map &map);
155 void sound_map(address_map &map);
156 void vid_0_map(address_map &map);
157 void vid_1_map(address_map &map);
158 };
159
update_screen(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect,int index)160 uint32_t vcombat_state::update_screen(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int index)
161 {
162 int y;
163 const pen_t *const pens = m_tlc34076->pens();
164
165 uint16_t *m68k_buf = m_m68k_framebuffer[(*m_framebuffer_ctrl & 0x20) ? 1 : 0].get();
166 uint16_t *i860_buf = m_i860_framebuffer[index][0].get();
167
168 /* TODO: It looks like the leftmost chunk of the ground should really be on the right side? */
169 /* But the i860 draws the background correctly, so it may be an original game issue. */
170 /* There's also some garbage in the upper-left corner. Might be related to this 'wraparound'. */
171 /* Or maybe it's related to the 68k's alpha? It might come from the 68k side of the house. */
172
173 for (y = cliprect.min_y; y <= cliprect.max_y; ++y)
174 {
175 int src_addr = 256/2 * y;
176 const uint16_t *m68k_src = &m68k_buf[src_addr];
177 const uint16_t *i860_src = &i860_buf[src_addr];
178 uint32_t *dst = &bitmap.pix(y, cliprect.min_x);
179
180 for (int x = cliprect.min_x; x <= cliprect.max_x; x += 2)
181 {
182 uint16_t m68k_pix = *m68k_src++;
183 uint16_t i860_pix = *i860_src++;
184
185 /* Draw two pixels */
186 for (int i = 0; i < 2; ++i)
187 {
188 /* Vcombat's screen renders 'flopped' - very likely because VR headset displays may reflect off mirrors.
189 Shadfgtr isn't flopped, so it's not a constant feature of the hardware. */
190
191 /* Combine the two layers */
192 if ((m68k_pix & 0xff) == 0)
193 *dst++ = pens[i860_pix & 0xff];
194 else
195 *dst++ = pens[m68k_pix & 0xff];
196
197 m68k_pix >>= 8;
198 i860_pix >>= 8;
199 }
200 }
201 }
202
203 return 0;
204 }
205
screen_update_vcombat_main(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)206 uint32_t vcombat_state::screen_update_vcombat_main(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 0); }
screen_update_vcombat_aux(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)207 uint32_t vcombat_state::screen_update_vcombat_aux(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect){ return update_screen(screen, bitmap, cliprect, 1); }
208
209
main_video_write(offs_t offset,uint16_t data,uint16_t mem_mask)210 void vcombat_state::main_video_write(offs_t offset, uint16_t data, uint16_t mem_mask)
211 {
212 int fb = (*m_framebuffer_ctrl & 0x20) ? 0 : 1;
213 uint16_t old_data = m_m68k_framebuffer[fb][offset];
214
215 /* Transparency mode? */
216 if (*m_framebuffer_ctrl & 0x40)
217 {
218 if (data == 0x0000)
219 return;
220
221 if ((data & 0x00ff) == 0)
222 data = (data & 0xff00) | (old_data & 0x00ff);
223 if ((data & 0xff00) == 0)
224 data = (data & 0x00ff) | (old_data & 0xff00);
225
226 COMBINE_DATA(&m_m68k_framebuffer[fb][offset]);
227 }
228 else
229 {
230 COMBINE_DATA(&m_m68k_framebuffer[fb][offset]);
231 }
232 }
233
control_1_r()234 uint16_t vcombat_state::control_1_r()
235 {
236 return (ioport("IN0")->read() << 8);
237 }
238
control_2_r()239 uint16_t vcombat_state::control_2_r()
240 {
241 return (ioport("IN1")->read() << 8);
242 }
243
control_3_r()244 uint16_t vcombat_state::control_3_r()
245 {
246 return (ioport("IN2")->read() << 8);
247 }
248
wiggle_i860_common(int which,uint16_t data)249 void vcombat_state::wiggle_i860_common(int which, uint16_t data)
250 {
251 int bus_hold = (data & 0x03) == 0x03;
252 int reset = data & 0x10;
253 if (!m_vid[which].found())
254 return;
255
256 i860_cpu_device &device = *m_vid[which];
257 if (bus_hold)
258 {
259 LOG("M0 asserting bus HOLD to i860 #%d\n", which);
260 device.i860_set_pin(DEC_PIN_BUS_HOLD, 1);
261 }
262 else
263 {
264 LOG("M0 clearing bus HOLD to i860 #%d\n", which);
265 device.i860_set_pin(DEC_PIN_BUS_HOLD, 0);
266 }
267
268 if (reset)
269 {
270 LOG("M0 asserting RESET to i860 #%d\n", which);
271 device.i860_set_pin(DEC_PIN_RESET, 1);
272 }
273 else
274 device.i860_set_pin(DEC_PIN_RESET, 0);
275 }
276
wiggle_i860p0_pins_w(uint16_t data)277 void vcombat_state::wiggle_i860p0_pins_w(uint16_t data)
278 {
279 wiggle_i860_common(0, data);
280 }
281
wiggle_i860p1_pins_w(uint16_t data)282 void vcombat_state::wiggle_i860p1_pins_w(uint16_t data)
283 {
284 wiggle_i860_common(1, data);
285 }
286
main_irqiack_r()287 uint16_t vcombat_state::main_irqiack_r()
288 {
289 //LOG("M0: irq iack\n");
290 m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE);
291 //m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
292 return 0;
293 }
294
sound_resetmain_r()295 uint16_t vcombat_state::sound_resetmain_r()
296 {
297 //LOG("M1: reset line to M0\n");
298 //m_maincpu->pulse_input_line(INPUT_LINE_RESET, attotime::zero);
299 return 0;
300 }
301
v0_fb_w(offs_t offset,uint64_t data,uint64_t mem_mask)302 void vcombat_state::v0_fb_w(offs_t offset, uint64_t data, uint64_t mem_mask)
303 {
304 /* The frame buffer seems to sit on a 32-bit data bus, while the
305 i860 uses a 64-bit data bus. Adjust accordingly. */
306 char *p = (char *)(m_i860_framebuffer[0][0].get());
307 int m = mem_mask;
308 int o = (offset << 2);
309 if (m & 0xff000000) {
310 p[o+3] = (data >> 24) & 0xff;
311 }
312 if (m & 0x00ff0000) {
313 p[o+2] = (data >> 16) & 0xff;
314 }
315 if (m & 0x0000ff00) {
316 p[o+1] = (data >> 8) & 0xff;
317 }
318 if (m & 0x000000ff) {
319 p[o+0] = (data >> 0) & 0xff;
320 }
321 }
322
323 /* This is just temporary so we can see what each i860 is doing to the
324 framebuffer. */
v1_fb_w(offs_t offset,uint64_t data,uint64_t mem_mask)325 void vcombat_state::v1_fb_w(offs_t offset, uint64_t data, uint64_t mem_mask)
326 {
327 /* The frame buffer seems to sit on a 32-bit data bus, while the
328 i860 uses a 64-bit data bus. Adjust accordingly. */
329 char *p = (char *)(m_i860_framebuffer[1][0].get());
330 int m = mem_mask;
331 int o = (offset << 2);
332 if (m & 0xff000000) {
333 p[o+3] = (data >> 24) & 0xff;
334 }
335 if (m & 0x00ff0000) {
336 p[o+2] = (data >> 16) & 0xff;
337 }
338 if (m & 0x0000ff00) {
339 p[o+1] = (data >> 8) & 0xff;
340 }
341 if (m & 0x000000ff) {
342 p[o+0] = (data >> 0) & 0xff;
343 }
344 }
345
crtc_w(uint16_t data)346 void vcombat_state::crtc_w(uint16_t data)
347 {
348 if (m_crtc == nullptr)
349 return;
350
351 if (m_crtc_select == 0)
352 m_crtc->address_w(data >> 8);
353 else
354 m_crtc->register_w(data >> 8);
355
356 m_crtc_select ^= 1;
357 }
358
vcombat_dac_w(uint16_t data)359 void vcombat_state::vcombat_dac_w(uint16_t data)
360 {
361 m_dac->write(data >> 5);
362 if (data & 0x801f)
363 LOG("dac overflow %04x\n", data & 0x801f);
364 }
365
main_map(address_map & map)366 void vcombat_state::main_map(address_map &map)
367 {
368 map(0x000000, 0x0fffff).rom();
369 map(0x200000, 0x20ffff).ram();
370 map(0x300000, 0x30ffff).w(FUNC(vcombat_state::main_video_write));
371
372 map(0x400000, 0x43ffff).ram().share("vid_0_ram"); /* First i860 shared RAM */
373 map(0x440000, 0x440003).ram().share("share6"); /* M0->P0 i860 #1 com 1 */
374 map(0x480000, 0x480003).ram().share("share7"); /* M0<-P0 i860 #1 com 2 */
375 map(0x4c0000, 0x4c0003).w(FUNC(vcombat_state::wiggle_i860p0_pins_w)); /* i860 #1 stop/start/reset */
376
377 map(0x500000, 0x53ffff).ram().share("vid_1_ram"); /* Second i860 shared RAM */
378 map(0x540000, 0x540003).ram().share("share8"); /* M0->P1 i860 #2 com 1 */
379 map(0x580000, 0x580003).ram().share("share9"); /* M0<-P1 i860 #2 com 2 */
380 map(0x5c0000, 0x5c0003).w(FUNC(vcombat_state::wiggle_i860p1_pins_w)); /* i860 #2 stop/start/reset */
381
382 map(0x600000, 0x600001).r(FUNC(vcombat_state::control_1_r)); /* IN0 port */
383 map(0x600004, 0x600005).ram().share("share5"); /* M0<-M1 */
384 map(0x600008, 0x600009).r(FUNC(vcombat_state::control_2_r)); /* IN1 port */
385 map(0x60001c, 0x60001d).noprw();
386
387 map(0x60000c, 0x60000d).w(FUNC(vcombat_state::crtc_w));
388 map(0x600010, 0x600011).ram().share("fb_control");
389 map(0x700000, 0x7007ff).ram().share("nvram");
390 map(0x701000, 0x701001).r(FUNC(vcombat_state::main_irqiack_r));
391 map(0x702000, 0x702001).r(FUNC(vcombat_state::control_3_r));
392 map(0x705000, 0x705001).ram().share("share4"); /* M1->M0 */
393
394 //map(0x703000, 0x703001) /* Headset rotation axis? */
395 //map(0x704000, 0x704001) /* Headset rotation axis? */
396
397 map(0x706000, 0x70601f).rw(m_tlc34076, FUNC(tlc34076_device::read), FUNC(tlc34076_device::write)).umask16(0x00ff);
398 }
399
400
401 /* The first i860 - middle board */
vid_0_map(address_map & map)402 void vcombat_state::vid_0_map(address_map &map)
403 {
404 map(0x00000000, 0x0001ffff).ram().w(FUNC(vcombat_state::v0_fb_w)); /* Shared framebuffer - half of the bits lost to 32-bit bus */
405 map(0x20000000, 0x20000007).ram().share("share6"); /* M0<-P0 com 1 (0x440000 in 68k-land) */
406 map(0x40000000, 0x401fffff).rom().region("gfx", 0);
407 map(0x80000000, 0x80000007).ram().share("share7"); /* M0->P0 com 2 (0x480000 in 68k-land) */
408 map(0xc0000000, 0xc0000fff).noprw(); /* Dummy D$ flush page. */
409 map(0xfffc0000, 0xffffffff).ram().share("vid_0_ram"); /* Shared RAM with main */
410 }
411
412
413 /* The second i860 - top board */
vid_1_map(address_map & map)414 void vcombat_state::vid_1_map(address_map &map)
415 {
416 map(0x00000000, 0x0001ffff).ram().w(FUNC(vcombat_state::v1_fb_w)); /* Half of the bits lost to 32-bit bus */
417 map(0x20000000, 0x20000007).ram().share("share8"); /* M0->P1 com 1 (0x540000 in 68k-land) */
418 map(0x40000000, 0x401fffff).rom().region("gfx", 0);
419 map(0x80000000, 0x80000007).ram().share("share9"); /* M0<-P1 com 2 (0x580000 in 68k-land) */
420 map(0xc0000000, 0xc0000fff).noprw(); /* Dummy D$ flush page. */
421 map(0xfffc0000, 0xffffffff).ram().share("vid_1_ram"); /* Shared RAM with main */
422 }
423
424
425 /* Sound CPU */
sound_map(address_map & map)426 void vcombat_state::sound_map(address_map &map)
427 {
428 map(0x000000, 0x03ffff).rom();
429 map(0x080000, 0x08ffff).ram();
430 map(0x0c0000, 0x0c0001).w(FUNC(vcombat_state::vcombat_dac_w));
431 map(0x140000, 0x140001).r(FUNC(vcombat_state::sound_resetmain_r)); /* Ping M0's reset line */
432 map(0x180000, 0x180001).ram().share("share4"); /* M1<-M0 */
433 map(0x1c0000, 0x1c0001).ram().share("share5"); /* M1->M0 */
434 map(0x200000, 0x37ffff).rom().region("samples", 0);
435 }
436
437
machine_reset()438 void vcombat_state::machine_reset()
439 {
440 for (auto &i860 : m_vid)
441 if (i860.found())
442 i860->i860_set_pin(DEC_PIN_BUS_HOLD, 1);
443
444 m_crtc_select = 0;
445 }
446
447
init_vcombat()448 void vcombat_state::init_vcombat()
449 {
450 uint8_t *ROM = memregion("maincpu")->base();
451
452 /* Allocate the 68000 framebuffers */
453 m_m68k_framebuffer[0] = std::make_unique<uint16_t[]>(0x8000);
454 m_m68k_framebuffer[1] = std::make_unique<uint16_t[]>(0x8000);
455
456 /* First i860 */
457 m_i860_framebuffer[0][0] = std::make_unique<uint16_t[]>(0x8000);
458 m_i860_framebuffer[0][1] = std::make_unique<uint16_t[]>(0x8000);
459
460 /* Second i860 */
461 m_i860_framebuffer[1][0] = std::make_unique<uint16_t[]>(0x8000);
462 m_i860_framebuffer[1][1] = std::make_unique<uint16_t[]>(0x8000);
463
464 /* pc==4016 : jump 4038 ... There's something strange about how it waits at 402e (interrupts all masked out)
465 I think what is happening here is that M0 snags the first time
466 it hits this point based on a counter test just above this
467 instruction. That counter gets updated just past this instruction.
468 However, the only way this can be passed is if the M0 CPU is
469 reset (the IPL=7, but irq 7 is a nop). I am almost sure that M1
470 reads a latch, which resets M0 (probably to ensure M0 and M1 are
471 both alive) and gets passed this snag. I tried to hook up a reset
472 which should work, but asserting the reset line on the m68k doesn't
473 seem to do anything. Maybe the 68k emulator doesn't respond to
474 that, or I didn't do it correctly. But I think that is what needs
475 to be done. But it isn't crucial for emulation. Shadow does not
476 have this snag. */
477 ROM[0x4017] = 0x66;
478 }
479
init_shadfgtr()480 void vcombat_state::init_shadfgtr()
481 {
482 /* Allocate th 68000 frame buffers */
483 m_m68k_framebuffer[0] = std::make_unique<uint16_t[]>(0x8000);
484 m_m68k_framebuffer[1] = std::make_unique<uint16_t[]>(0x8000);
485
486 /* Only one i860 */
487 m_i860_framebuffer[0][0] = std::make_unique<uint16_t[]>(0x8000);
488 m_i860_framebuffer[0][1] = std::make_unique<uint16_t[]>(0x8000);
489 m_i860_framebuffer[1][0] = nullptr;
490 m_i860_framebuffer[1][1] = nullptr;
491 }
492
493
494 static INPUT_PORTS_START( vcombat )
495 PORT_START("IN0")
496 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
497 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* Left button */
498 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) /* Right button */
499 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
500 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
501 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
502 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
503 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
504
505 PORT_START("IN1")
506 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
507 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
508 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
509 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
510 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
511 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE )
512 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
513 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
514 INPUT_PORTS_END
515
516
INPUT_PORTS_START(shadfgtr)517 static INPUT_PORTS_START( shadfgtr )
518 /* Check me */
519 PORT_START("IN0")
520 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
521 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
522 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
523 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
524 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_PLAYER(2)
525 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY PORT_PLAYER(2)
526 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY PORT_PLAYER(2)
527 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY PORT_PLAYER(2)
528
529 PORT_START("IN1")
530 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
531 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
532 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
533 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 )
534 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START2 )
535 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SERVICE )
536 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
537 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
538
539 /* Check me */
540 PORT_START("IN2")
541 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_4WAY
542 PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_4WAY
543 PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_4WAY
544 PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_4WAY
545 PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
546 PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 )
547 PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON3 )
548 PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON4 )
549 INPUT_PORTS_END
550
551
552 WRITE_LINE_MEMBER(vcombat_state::sound_update)
553 {
554 /* Seems reasonable */
555 m_soundcpu->set_input_line(M68K_IRQ_1, state ? ASSERT_LINE : CLEAR_LINE);
556 }
557
vcombat(machine_config & config)558 void vcombat_state::vcombat(machine_config &config)
559 {
560 M68000(config, m_maincpu, XTAL(12'000'000));
561 m_maincpu->set_addrmap(AS_PROGRAM, &vcombat_state::main_map);
562 m_maincpu->set_vblank_int("screen", FUNC(vcombat_state::irq1_line_assert));
563
564 /* The middle board i860 */
565 I860(config, m_vid[0], XTAL(20'000'000));
566 m_vid[0]->set_addrmap(AS_PROGRAM, &vcombat_state::vid_0_map);
567
568 /* The top board i860 */
569 I860(config, m_vid[1], XTAL(20'000'000));
570 m_vid[1]->set_addrmap(AS_PROGRAM, &vcombat_state::vid_1_map);
571
572 /* Sound CPU */
573 M68000(config, m_soundcpu, XTAL(12'000'000));
574 m_soundcpu->set_addrmap(AS_PROGRAM, &vcombat_state::sound_map);
575 m_soundcpu->set_periodic_int(FUNC(vcombat_state::irq1_line_hold), attotime::from_hz(15000)); /* Remove this if MC6845 is enabled */
576
577 NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
578
579 /* Temporary hack for experimenting with timing. */
580 #if 0
581 //config.set_maximum_quantum(attotime::from_hz(1200));
582 config.m_perfect_cpu_quantum = subtag("maincpu");
583 #endif
584
585 TLC34076(config, m_tlc34076, tlc34076_device::TLC34076_6_BIT);
586
587 /* Disabled for now as it can't handle multiple screens */
588 // MC6845(config, m_crtc, 6000000 / 16);
589 // m_crtc->set_screen("screen");
590 config.set_default_layout(layout_dualhsxs);
591
592 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
593 screen.set_raw(XTAL(12'000'000) / 2, 400, 0, 256, 291, 0, 208);
594 screen.set_screen_update(FUNC(vcombat_state::screen_update_vcombat_main));
595
596 screen_device &aux(SCREEN(config, "aux", SCREEN_TYPE_RASTER));
597 aux.set_raw(XTAL(12'000'000) / 2, 400, 0, 256, 291, 0, 208);
598 aux.set_screen_update(FUNC(vcombat_state::screen_update_vcombat_aux));
599
600 SPEAKER(config, "speaker").front_center();
601 DAC_10BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC
602 }
603
604
shadfgtr(machine_config & config)605 void vcombat_state::shadfgtr(machine_config &config)
606 {
607 M68000(config, m_maincpu, XTAL(12'000'000));
608 m_maincpu->set_addrmap(AS_PROGRAM, &vcombat_state::main_map);
609 m_maincpu->set_vblank_int("screen", FUNC(vcombat_state::irq1_line_assert));
610
611 /* The middle board i860 */
612 I860(config, m_vid[0], XTAL(20'000'000));
613 m_vid[0]->set_addrmap(AS_PROGRAM, &vcombat_state::vid_0_map);
614
615 /* Sound CPU */
616 M68000(config, m_soundcpu, XTAL(12'000'000));
617 m_soundcpu->set_addrmap(AS_PROGRAM, &vcombat_state::sound_map);
618
619 NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_0);
620
621 TLC34076(config, m_tlc34076, tlc34076_device::TLC34076_6_BIT);
622
623 MC6845(config, m_crtc, XTAL(20'000'000) / 4 / 16);
624 m_crtc->set_screen("screen");
625 m_crtc->set_show_border_area(false);
626 m_crtc->set_char_width(16);
627 m_crtc->out_hsync_callback().set(FUNC(vcombat_state::sound_update));
628
629 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
630 screen.set_raw(XTAL(20'000'000) / 4, 320, 0, 256, 277, 0, 224);
631 screen.set_screen_update(FUNC(vcombat_state::screen_update_vcombat_main));
632
633 SPEAKER(config, "speaker").front_center();
634 DAC_10BIT_R2R(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 1.0); // unknown DAC
635 }
636
637
638 ROM_START( vcombat )
639 ROM_REGION( 0x100000, "maincpu", 0 )
640 ROM_LOAD16_BYTE( "ep8v2.b49", 0x00000, 0x80000, CRC(98d5a45d) SHA1(099e314f11c93ad6e642ceaa311e2a5b6fd7193c) )
641 ROM_LOAD16_BYTE( "ep7v2.b51", 0x00001, 0x80000, CRC(06185bcb) SHA1(855b11ae7644d6c7c1c935b2f5aec484071ca870) )
642
643 ROM_REGION( 0x40000, "soundcpu", 0 )
644 ROM_LOAD16_BYTE( "ep1v2.b42", 0x00000, 0x20000, CRC(560b2e6c) SHA1(e35c0466a1e14beab080e3155f873e9c2a1c028b) )
645 ROM_LOAD16_BYTE( "ep6v2.b33", 0x00001, 0x20000, CRC(37928a5d) SHA1(7850be26dbd356cdeef2a0d87738de16420f6291) )
646
647 ROM_REGION16_BE( 0x180000, "samples", 0 )
648 ROM_LOAD16_BYTE( "ep2v2.b41", 0x000000, 0x80000, CRC(7dad3458) SHA1(deae5ebef0346250d3f9744933423253a336bb67) )
649 ROM_LOAD16_BYTE( "ep4v2.b37", 0x000001, 0x80000, CRC(b0be2e91) SHA1(66f3a9f5abeb4b95ac806e4bb165f938dca38b2d) )
650 ROM_LOAD16_BYTE( "ep3v2.b40", 0x100000, 0x40000, CRC(8c491526) SHA1(95c6bcbe0adcfffb12fd2b86c9f4ca26aa188bbf) )
651 ROM_LOAD16_BYTE( "ep5v2.b36", 0x100001, 0x40000, CRC(7592b2eb) SHA1(92a540726306d7adbf207fe86a4c4fa66958f90b) )
652
653 ROM_REGION( 0x800, "user1", 0 ) /* The SRAM module */
654 ROM_LOAD( "ds1220y.b53", 0x000, 0x800, CRC(b21cfe5f) SHA1(898ace3cd0913ea4b0dc84320219777773ef856f) )
655
656 /* These roms are identical on both of the upper boards */
657 ROM_REGION64_LE( 0x200000, "gfx", 0 )
658 ROM_LOAD64_WORD( "9.u55", 0x000000, 0x80000, CRC(a276e18b) SHA1(6d60e519196a4858b82241504592413df498e12f) )
659 ROM_LOAD64_WORD( "10.u57", 0x000002, 0x80000, CRC(8921f20e) SHA1(6e9ca2eaad3e1108ba0e1d7792fd5d0305bec201) )
660 ROM_LOAD64_WORD( "11.u54", 0x000004, 0x80000, CRC(a83094ce) SHA1(c3512375fecdb5e7eb02a4aa140ae4efe0233cb8) )
661 ROM_LOAD64_WORD( "12.u56", 0x000006, 0x80000, CRC(0cdffd4f) SHA1(65ace78711b3ef6e0ff9a7ad7343b5558e652f6c) )
662
663 ROM_REGION( 0x400, "plds", 0 )
664 ROM_LOAD( "pal1_w2.u51", 0x000, 0x1f1, CRC(af497420) SHA1(03aa82189d91ae194dd5a6e7b9dbdb7cd473ddb6) )
665 ROM_LOAD( "pal2_w2.u52", 0x200, 0x1f1, CRC(4a6df05d) SHA1(236b951e5daf927c050d0f35558c171a020156ab) )
666 ROM_END
667
668 ROM_START( shadfgtr )
669 ROM_REGION( 0x100000, "maincpu", 0 )
670 ROM_LOAD16_BYTE( "shadfgtr.b49", 0x00000, 0x80000, CRC(2d9d31a1) SHA1(45854915bcb9db2e4076a7f26a0a349077cd10bc) )
671 ROM_LOAD16_BYTE( "shadfgtr.b51", 0x00001, 0x80000, CRC(03d0f075) SHA1(06013a4363305a23d7e8ba8fe2fa961cd540391d) )
672
673 ROM_REGION( 0x40000, "soundcpu", 0 )
674 ROM_LOAD16_BYTE( "shadfgtr.b42", 0x00000, 0x20000, CRC(f8605dcd) SHA1(1b29f47856ccc757bc96674682ae48f87e6b0e54) )
675 ROM_LOAD16_BYTE( "shadfgtr.b33", 0x00001, 0x20000, CRC(291d59ac) SHA1(cc4904c2ac8ef6a12033c10893246a438ac44014) )
676
677 ROM_REGION16_BE( 0x180000, "samples", 0 )
678 ROM_LOAD16_BYTE( "shadfgtr.b41", 0x00000, 0x80000, CRC(9e4b4df3) SHA1(8101197275e9f728acdeef85737eecbdec132b27) )
679 ROM_LOAD16_BYTE( "shadfgtr.b37", 0x00001, 0x80000, CRC(98446ba2) SHA1(1c8cc0d9c5de54d9e53699a5ab281579d15edc96) )
680
681 ROM_REGION( 0x800, "user1", 0 ) /* The SRAM module */
682 ROM_LOAD( "shadfgtr.b53", 0x000, 0x800, CRC(e766a3ab) SHA1(e7696ec08d5c86f64d768480f43edbd19ded162d) )
683
684 ROM_REGION64_LE( 0x200000, "gfx", 0 )
685 ROM_LOAD64_WORD( "shadfgtr.u55", 0x000000, 0x80000, CRC(e807631d) SHA1(9027ff7dc60b808434dac292c08f0630d3d52186) )
686 ROM_LOAD64_WORD( "shadfgtr.u57", 0x000002, 0x80000, CRC(60d701d7) SHA1(936473b5e3b2e9e9e3b50cf977fc5a670a097850) )
687 ROM_LOAD64_WORD( "shadfgtr.u54", 0x000004, 0x80000, CRC(c45d68d6) SHA1(a133e4f13d3af18bccf0d060a659d64ac699b159) )
688 ROM_LOAD64_WORD( "shadfgtr.u56", 0x000006, 0x80000, CRC(fb76db5a) SHA1(fa546f465df113c13037abed1162bfa6f9b1dc9b) )
689
690 ROM_REGION( 0x200, "plds", 0 )
691 ROM_LOAD( "shadfgtr.u51", 0x000, 0x1f1, CRC(bab58337) SHA1(c4a79c8e53aeadb7f64d49d214b607b5b36f144e) )
692 /* The second upper-board PAL couldn't be read */
693 ROM_END
694
695 // YEAR NAME PARENT MACHINE INPUT STATE INIT MONITOR COMPANY FULLNAME FLAGS
696 GAME( 1993, vcombat, 0, vcombat, vcombat, vcombat_state, init_vcombat, ORIENTATION_FLIP_X, "VR8 Inc.", "Virtual Combat", MACHINE_NOT_WORKING )
697 GAME( 1993, shadfgtr, 0, shadfgtr, shadfgtr, vcombat_state, init_shadfgtr, ROT0, "Dutech Inc.", "Shadow Fighters", MACHINE_NOT_WORKING )
698