1 // license:BSD-3-Clause
2 // copyright-holders:Luca Elia, Hau
3 /***************************************************************************
4
5 Hyper Duel
6 (c)1993 Technosoft
7 TEC442-A(Japan)
8
9 TMP68000N-10 x2
10 YM2151,YM3012
11 OKI M6295
12 OSC: 4.0000MHz, 20.0000MHz, 26.6660MHz
13 Imagetek Inc 14220 071
14
15
16 Magical Error wo Sagase
17 (c)1994 Technosoft / Jaleco
18 TEC5000(Japan)
19
20 TMP68000N-10 x2
21 YM2413
22 OKI M6295
23 OSC: 3.579545MHz, 4.0000MHz, 20.0000MHz, 26.6660MHz
24 Imagetek Inc 14220 071
25
26 --
27 Written by Hau
28 03/29/2009
29 based on driver from drivers/metro.cpp by Luca Elia
30 spthx to kikur,Cha,teioh,kokkyu,teruchu,aya,sgo
31 ---
32
33 Magical Error
34 different sized sound / shared region (or the mem map needs more alterations?)
35 fix comms so it boots, it's a bit of a hack for hyperduel at the moment ;-)
36
37 ***************************************************************************/
38
39 #include "emu.h"
40
41 #include "cpu/m68000/m68000.h"
42 #include "machine/timer.h"
43 #include "sound/okim6295.h"
44 #include "sound/ym2151.h"
45 #include "sound/ym2413.h"
46 #include "video/imagetek_i4100.h"
47
48 #include "screen.h"
49 #include "speaker.h"
50
51
52 #define RASTER_LINES 262
53 #define FIRST_VISIBLE_LINE 0
54 #define LAST_VISIBLE_LINE 223
55
56 class hyprduel_state : public driver_device
57 {
58 public:
hyprduel_state(const machine_config & mconfig,device_type type,const char * tag)59 hyprduel_state(const machine_config &mconfig, device_type type, const char *tag)
60 : driver_device(mconfig, type, tag)
61 , m_irq_enable(*this, "irq_enable")
62 , m_sharedram(*this, "sharedram%u", 1)
63 , m_maincpu(*this, "maincpu")
64 , m_subcpu(*this, "sub")
65 , m_vdp(*this, "vdp")
66 { }
67
68 void magerror(machine_config &config);
69 void hyprduel(machine_config &config);
70
71 void init_magerror();
72 void init_hyprduel();
73
74 private:
75 uint8_t irq_cause_r();
76 void irq_cause_w(uint8_t data);
77 void subcpu_control_w(uint16_t data);
78 uint16_t hyprduel_cpusync_trigger1_r(offs_t offset);
79 void hyprduel_cpusync_trigger1_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
80 uint16_t hyprduel_cpusync_trigger2_r(offs_t offset);
81 void hyprduel_cpusync_trigger2_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
82 DECLARE_MACHINE_START(hyprduel);
83 DECLARE_MACHINE_START(magerror);
84 TIMER_CALLBACK_MEMBER(vblank_end_callback);
85 DECLARE_WRITE_LINE_MEMBER(vdp_blit_end_w);
86 TIMER_DEVICE_CALLBACK_MEMBER(interrupt);
87
88 void i4220_config(machine_config &config);
89
90 void hyprduel_map(address_map &map);
91 void hyprduel_map2(address_map &map);
92 void magerror_map(address_map &map);
93 void magerror_map2(address_map &map);
94
95 virtual void machine_reset() override;
96
97 /* memory pointers */
98 required_shared_ptr<uint16_t> m_irq_enable;
99 required_shared_ptr_array<uint16_t, 3> m_sharedram;
100
101 /* misc */
102 emu_timer *m_vblank_end_timer;
103 int m_blitter_bit;
104 int m_requested_int;
105 int m_subcpu_resetline;
106 int m_cpu_trigger;
107 int m_int_num;
108
109 /* devices */
110 required_device<cpu_device> m_maincpu;
111 required_device<cpu_device> m_subcpu;
112 required_device<imagetek_i4220_device> m_vdp;
113
114 void update_irq_state( );
115 };
116
117
118 /***************************************************************************
119 Interrupts
120 ***************************************************************************/
121
update_irq_state()122 void hyprduel_state::update_irq_state( )
123 {
124 int irq = m_requested_int & ~*m_irq_enable;
125
126 m_maincpu->set_input_line(3, (irq & m_int_num) ? ASSERT_LINE : CLEAR_LINE);
127 }
128
TIMER_CALLBACK_MEMBER(hyprduel_state::vblank_end_callback)129 TIMER_CALLBACK_MEMBER(hyprduel_state::vblank_end_callback)
130 {
131 m_requested_int &= ~param;
132 }
133
TIMER_DEVICE_CALLBACK_MEMBER(hyprduel_state::interrupt)134 TIMER_DEVICE_CALLBACK_MEMBER(hyprduel_state::interrupt)
135 {
136 int line = param;
137
138 if (line == 0) /* TODO: fix this! */
139 {
140 m_requested_int |= 0x01; /* vblank */
141 m_requested_int |= 0x20;
142 m_maincpu->set_input_line(2, HOLD_LINE);
143 /* the duration is a guess */
144 m_vblank_end_timer->adjust(attotime::from_usec(2500), 0x20);
145 }
146 else
147 m_requested_int |= 0x12; /* hsync */
148
149 update_irq_state();
150 }
151
irq_cause_r()152 uint8_t hyprduel_state::irq_cause_r()
153 {
154 return m_requested_int;
155 }
156
irq_cause_w(uint8_t data)157 void hyprduel_state::irq_cause_w(uint8_t data)
158 {
159 if (data == m_int_num)
160 m_requested_int &= ~(m_int_num & ~*m_irq_enable);
161 else
162 m_requested_int &= ~(data & *m_irq_enable);
163
164 update_irq_state();
165 }
166
167
subcpu_control_w(uint16_t data)168 void hyprduel_state::subcpu_control_w(uint16_t data)
169 {
170 switch (data)
171 {
172 case 0x0d:
173 case 0x0f:
174 case 0x01:
175 if (!m_subcpu_resetline)
176 {
177 m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
178 m_subcpu_resetline = 1;
179 }
180 break;
181
182 case 0x00:
183 if (m_subcpu_resetline)
184 {
185 m_subcpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
186 m_subcpu_resetline = 0;
187 }
188 m_maincpu->spin_until_interrupt();
189 break;
190
191 case 0x0c:
192 case 0x80:
193 m_subcpu->set_input_line(2, HOLD_LINE);
194 break;
195 }
196 }
197
198
hyprduel_cpusync_trigger1_r(offs_t offset)199 uint16_t hyprduel_state::hyprduel_cpusync_trigger1_r(offs_t offset)
200 {
201 if (m_cpu_trigger == 1001)
202 {
203 machine().scheduler().trigger(1001);
204 m_cpu_trigger = 0;
205 }
206
207 return m_sharedram[0][0x000408 / 2 + offset];
208 }
209
hyprduel_cpusync_trigger1_w(offs_t offset,uint16_t data,uint16_t mem_mask)210 void hyprduel_state::hyprduel_cpusync_trigger1_w(offs_t offset, uint16_t data, uint16_t mem_mask)
211 {
212 COMBINE_DATA(&m_sharedram[0][0x00040e / 2 + offset]);
213
214 if (((m_sharedram[0][0x00040e / 2] << 16) + m_sharedram[0][0x000410 / 2]) != 0x00)
215 {
216 if (!m_cpu_trigger && !m_subcpu_resetline)
217 {
218 m_maincpu->spin_until_trigger(1001);
219 m_cpu_trigger = 1001;
220 }
221 }
222 }
223
224
hyprduel_cpusync_trigger2_r(offs_t offset)225 uint16_t hyprduel_state::hyprduel_cpusync_trigger2_r(offs_t offset)
226 {
227 if (m_cpu_trigger == 1002)
228 {
229 machine().scheduler().trigger(1002);
230 m_cpu_trigger = 0;
231 }
232
233 return m_sharedram[2][(0xfff34c - 0xfe4000) / 2 + offset];
234 }
235
hyprduel_cpusync_trigger2_w(offs_t offset,uint16_t data,uint16_t mem_mask)236 void hyprduel_state::hyprduel_cpusync_trigger2_w(offs_t offset, uint16_t data, uint16_t mem_mask)
237 {
238 COMBINE_DATA(&m_sharedram[0][0x000408 / 2 + offset]);
239
240 if (ACCESSING_BITS_8_15)
241 {
242 if (!m_cpu_trigger && !m_subcpu_resetline)
243 {
244 m_maincpu->spin_until_trigger(1002);
245 m_cpu_trigger = 1002;
246 }
247 }
248 }
249
WRITE_LINE_MEMBER(hyprduel_state::vdp_blit_end_w)250 WRITE_LINE_MEMBER(hyprduel_state::vdp_blit_end_w)
251 {
252 m_requested_int |= 1 << m_blitter_bit;
253 update_irq_state();
254 }
255
256 /***************************************************************************
257 Memory Maps
258 ***************************************************************************/
259
hyprduel_map(address_map & map)260 void hyprduel_state::hyprduel_map(address_map &map)
261 {
262 map(0x000000, 0x07ffff).rom();
263 map(0x400000, 0x47ffff).m(m_vdp, FUNC(imagetek_i4220_device::v2_map));
264 map(0x4788a3, 0x4788a3).rw(FUNC(hyprduel_state::irq_cause_r), FUNC(hyprduel_state::irq_cause_w)); /* IRQ Cause,Acknowledge */
265 map(0x4788a4, 0x4788a5).ram().share("irq_enable"); /* IRQ Enable */
266 map(0x800000, 0x800001).w(FUNC(hyprduel_state::subcpu_control_w));
267 map(0xc00000, 0xc07fff).ram().share("sharedram1");
268 map(0xe00000, 0xe00001).portr("SERVICE").nopw();
269 map(0xe00002, 0xe00003).portr("DSW");
270 map(0xe00004, 0xe00005).portr("P1_P2");
271 map(0xe00006, 0xe00007).portr("SYSTEM");
272 map(0xfe0000, 0xfe3fff).ram().share("sharedram2");
273 map(0xfe4000, 0xffffff).ram().share("sharedram3");
274 }
275
hyprduel_map2(address_map & map)276 void hyprduel_state::hyprduel_map2(address_map &map)
277 {
278 map(0x000000, 0x003fff).ram().share("sharedram1"); /* shadow ($c00000 - $c03fff : vector) */
279 map(0x004000, 0x007fff).readonly().nopw().share("sharedram3"); /* shadow ($fe4000 - $fe7fff : read only) */
280 map(0x400000, 0x400003).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write)).umask16(0x00ff);
281 map(0x400005, 0x400005).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
282 map(0x800000, 0x800001).noprw();
283 map(0xc00000, 0xc07fff).ram().share("sharedram1");
284 map(0xfe0000, 0xfe3fff).ram().share("sharedram2");
285 map(0xfe4000, 0xffffff).ram().share("sharedram3");
286 }
287
288
289 /* Magical Error - video is at 8x now */
290
magerror_map(address_map & map)291 void hyprduel_state::magerror_map(address_map &map)
292 {
293 map(0x000000, 0x07ffff).rom();
294 map(0x400000, 0x400001).w(FUNC(hyprduel_state::subcpu_control_w));
295 map(0x800000, 0x87ffff).m(m_vdp, FUNC(imagetek_i4220_device::v2_map));
296 map(0x8788a3, 0x8788a3).rw(FUNC(hyprduel_state::irq_cause_r), FUNC(hyprduel_state::irq_cause_w)); /* IRQ Cause, Acknowledge */
297 map(0x8788a4, 0x8788a5).ram().share("irq_enable"); /* IRQ Enable */
298 map(0xc00000, 0xc1ffff).ram().share("sharedram1");
299 map(0xe00000, 0xe00001).portr("SERVICE").nopw();
300 map(0xe00002, 0xe00003).portr("DSW");
301 map(0xe00004, 0xe00005).portr("P1_P2");
302 map(0xe00006, 0xe00007).portr("SYSTEM");
303 map(0xfe0000, 0xfe3fff).ram().share("sharedram2");
304 map(0xfe4000, 0xffffff).ram().share("sharedram3");
305 }
306
magerror_map2(address_map & map)307 void hyprduel_state::magerror_map2(address_map &map)
308 {
309 map(0x000000, 0x003fff).ram().share("sharedram1"); /* shadow ($c00000 - $c03fff : vector) */
310 map(0x004000, 0x007fff).readonly().nopw().share("sharedram3"); /* shadow ($fe4000 - $fe7fff : read only) */
311 map(0x400000, 0x400003).noprw();
312 map(0x800000, 0x800003).nopr().w("ymsnd", FUNC(ym2413_device::write)).umask16(0x00ff);
313 map(0x800005, 0x800005).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
314 map(0xc00000, 0xc1ffff).ram().share("sharedram1");
315 map(0xfe0000, 0xfe3fff).ram().share("sharedram2");
316 map(0xfe4000, 0xffffff).ram().share("sharedram3");
317 }
318
319 /***************************************************************************
320 Input Ports
321 ***************************************************************************/
322
323 static INPUT_PORTS_START( hyprduel )
324 PORT_START("SERVICE")
325 PORT_SERVICE_NO_TOGGLE( 0x8000, IP_ACTIVE_LOW )
326 PORT_DIPNAME( 0x4000, 0x0000, "Show Warning" )
DEF_STR(Off)327 PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
328 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
329 PORT_BIT( 0x3fff, IP_ACTIVE_LOW, IPT_UNKNOWN )
330
331 PORT_START("DSW")
332 PORT_DIPNAME( 0x0007, 0x0007, DEF_STR( Coin_A ) )
333 PORT_DIPSETTING( 0x0001, DEF_STR( 4C_1C ) )
334 PORT_DIPSETTING( 0x0002, DEF_STR( 3C_1C ) )
335 PORT_DIPSETTING( 0x0003, DEF_STR( 2C_1C ) )
336 PORT_DIPSETTING( 0x0007, DEF_STR( 1C_1C ) )
337 PORT_DIPSETTING( 0x0006, DEF_STR( 1C_2C ) )
338 PORT_DIPSETTING( 0x0005, DEF_STR( 1C_3C ) )
339 PORT_DIPSETTING( 0x0004, DEF_STR( 1C_4C ) )
340 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
341 PORT_DIPNAME( 0x0038, 0x0038, DEF_STR( Coin_B ) )
342 PORT_DIPSETTING( 0x0008, DEF_STR( 4C_1C ) )
343 PORT_DIPSETTING( 0x0010, DEF_STR( 3C_1C ) )
344 PORT_DIPSETTING( 0x0018, DEF_STR( 2C_1C ) )
345 PORT_DIPSETTING( 0x0038, DEF_STR( 1C_1C ) )
346 PORT_DIPSETTING( 0x0030, DEF_STR( 1C_2C ) )
347 PORT_DIPSETTING( 0x0028, DEF_STR( 1C_3C ) )
348 PORT_DIPSETTING( 0x0020, DEF_STR( 1C_4C ) )
349 PORT_DIPSETTING( 0x0000, DEF_STR( Free_Play ) )
350 PORT_DIPNAME( 0x0040, 0x0000, DEF_STR( Demo_Sounds ) )
351 PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
352 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
353 PORT_DIPNAME( 0x0080, 0x0080, "Start Up Mode" )
354 PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
355 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
356 PORT_DIPNAME( 0x0100, 0x0100, DEF_STR( Flip_Screen ) )
357 PORT_DIPSETTING( 0x0100, DEF_STR( Off ) )
358 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
359 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_UNKNOWN )
360 PORT_DIPNAME( 0x0c00, 0x0c00, DEF_STR( Difficulty ) )
361 PORT_DIPSETTING( 0x0800, DEF_STR( Easy ) )
362 PORT_DIPSETTING( 0x0c00, DEF_STR( Normal ) )
363 PORT_DIPSETTING( 0x0400, DEF_STR( Hard ) )
364 PORT_DIPSETTING( 0x0000, DEF_STR( Very_Hard ) )
365 PORT_DIPNAME( 0x3000, 0x3000, DEF_STR( Lives ) )
366 PORT_DIPSETTING( 0x2000, "2" )
367 PORT_DIPSETTING( 0x3000, "3" )
368 PORT_DIPSETTING( 0x1000, "4" )
369 PORT_DIPSETTING( 0x0000, "5" )
370 PORT_BIT( 0xc000, IP_ACTIVE_LOW, IPT_UNKNOWN )
371
372 PORT_START("P1_P2")
373 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
374 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
375 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
376 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
377 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
378 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
379 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
380 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_PLAYER(1)
381 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
382 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
383 PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
384 PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
385 PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
386 PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
387 PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
388 PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_PLAYER(2)
389
390 PORT_START("SYSTEM")
391 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
392 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(2)
393 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_SERVICE1 )
394 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_SERVICE2 )
395 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_START1 )
396 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_START2 )
397 PORT_BIT( 0xffc0, IP_ACTIVE_LOW, IPT_UNKNOWN )
398 INPUT_PORTS_END
399
400 static INPUT_PORTS_START( magerror )
401 PORT_INCLUDE( hyprduel )
402
403 PORT_MODIFY("DSW")
404 PORT_DIPNAME( 0x0080, 0x0080, "Start Up Mode" )
405 PORT_DIPSETTING( 0x0080, "Game Mode" )
406 PORT_DIPSETTING( 0x0000, "Test Mode" )
407 INPUT_PORTS_END
408
409 /***************************************************************************
410 Machine Drivers
411 ***************************************************************************/
412
413 void hyprduel_state::machine_reset()
414 {
415 /* start with cpu2 halted */
416 m_subcpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
417 m_subcpu_resetline = 1;
418 m_cpu_trigger = 0;
419
420 m_requested_int = 0x00;
421 m_blitter_bit = 2;
422 *m_irq_enable = 0xff;
423 }
424
MACHINE_START_MEMBER(hyprduel_state,hyprduel)425 MACHINE_START_MEMBER(hyprduel_state,hyprduel)
426 {
427 save_item(NAME(m_blitter_bit));
428 save_item(NAME(m_requested_int));
429 save_item(NAME(m_subcpu_resetline));
430 save_item(NAME(m_cpu_trigger));
431
432 m_vblank_end_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hyprduel_state::vblank_end_callback), this));
433 }
434
i4220_config(machine_config & config)435 void hyprduel_state::i4220_config(machine_config &config)
436 {
437 I4220(config, m_vdp, XTAL(26'666'000));
438 m_vdp->blit_irq_cb().set(FUNC(hyprduel_state::vdp_blit_end_w));
439 m_vdp->set_spriteram_buffered(true); // sprites are 1 frame delayed
440
441 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
442 screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
443 screen.set_refresh_hz(60); // Unknown/Unverified
444 screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
445 screen.set_size(320, 224);
446 screen.set_visarea(0, 320-1, FIRST_VISIBLE_LINE, LAST_VISIBLE_LINE);
447 screen.set_screen_update("vdp", FUNC(imagetek_i4100_device::screen_update));
448 screen.screen_vblank().set("vdp", FUNC(imagetek_i4100_device::screen_eof));
449 }
450
hyprduel(machine_config & config)451 void hyprduel_state::hyprduel(machine_config &config)
452 {
453 /* basic machine hardware */
454 M68000(config, m_maincpu, 20000000/2); /* 10MHz */
455 m_maincpu->set_addrmap(AS_PROGRAM, &hyprduel_state::hyprduel_map);
456
457 TIMER(config, "scantimer").configure_scanline(FUNC(hyprduel_state::interrupt), "screen", 0, 1);
458
459 M68000(config, m_subcpu, 20000000/2); /* 10MHz */
460 m_subcpu->set_addrmap(AS_PROGRAM, &hyprduel_state::hyprduel_map2);
461
462 MCFG_MACHINE_START_OVERRIDE(hyprduel_state,hyprduel)
463
464 /* video hardware */
465 i4220_config(config);
466
467 /* sound hardware */
468 SPEAKER(config, "mono").front_center();
469
470 ym2151_device &ymsnd(YM2151(config, "ymsnd", 4000000));
471 ymsnd.irq_handler().set_inputline(m_subcpu, 1);
472 ymsnd.add_route(ALL_OUTPUTS, "mono", 0.80);
473
474 OKIM6295(config, "oki", 4000000/16/16*132, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 0.57); // clock frequency & pin 7 not verified
475 }
476
477
magerror(machine_config & config)478 void hyprduel_state::magerror(machine_config &config)
479 {
480 /* basic machine hardware */
481 M68000(config, m_maincpu, 20000000/2); /* 10MHz */
482 m_maincpu->set_addrmap(AS_PROGRAM, &hyprduel_state::magerror_map);
483
484 TIMER(config, "scantimer").configure_scanline(FUNC(hyprduel_state::interrupt), "screen", 0, 1);
485
486 M68000(config, m_subcpu, 20000000/2); /* 10MHz */
487 m_subcpu->set_addrmap(AS_PROGRAM, &hyprduel_state::magerror_map2);
488 m_subcpu->set_periodic_int(FUNC(hyprduel_state::irq1_line_hold), attotime::from_hz(968)); /* tempo? */
489
490 MCFG_MACHINE_START_OVERRIDE(hyprduel_state,hyprduel)
491
492 /* video hardware */
493 i4220_config(config);
494
495 /* sound hardware */
496 SPEAKER(config, "mono").front_center();
497
498 YM2413(config, "ymsnd", 3579545).add_route(ALL_OUTPUTS, "mono", 1.00);
499
500 OKIM6295(config, "oki", 4000000/16/16*132, okim6295_device::PIN7_HIGH).add_route(ALL_OUTPUTS, "mono", 0.57); // clock frequency & pin 7 not verified
501 }
502
503 /***************************************************************************
504 ROMs Loading
505 ***************************************************************************/
506
507 ROM_START( hyprduel )
508 ROM_REGION( 0x80000, "maincpu", 0 )
CRC(c7402722)509 ROM_LOAD16_BYTE( "24.u24", 0x000000, 0x40000, CRC(c7402722) SHA1(e385676cdcee65a3ddf07791d82a1fe83ba1b3e2) ) /* Also silk screened as position 10 */
510 ROM_LOAD16_BYTE( "23.u23", 0x000001, 0x40000, CRC(d8297c2b) SHA1(2e23c5b1784d0a465c0c0dc3ca28505689a8b16c) ) /* Also silk screened as position 9 */
511
512 ROM_REGION( 0x400000, "vdp", 0 ) /* Gfx + Prg + Data (Addressable by CPU & Blitter) */
513 ROMX_LOAD( "ts_hyper-1.u74", 0x000000, 0x100000, CRC(4b3b2d3c) SHA1(5e9e8ec853f71aeff3910b93dadbaeae2b61717b) , ROM_GROUPWORD | ROM_SKIP(6) )
514 ROMX_LOAD( "ts_hyper-2.u75", 0x000002, 0x100000, CRC(dc230116) SHA1(a3c447657d8499764f52c81382961f425c56037b) , ROM_GROUPWORD | ROM_SKIP(6) )
515 ROMX_LOAD( "ts_hyper-3.u76", 0x000004, 0x100000, CRC(2d770dd0) SHA1(27f9e7f67e96210d3710ab4f940c5d7ae13f8bbf) , ROM_GROUPWORD | ROM_SKIP(6) )
516 ROMX_LOAD( "ts_hyper-4.u77", 0x000006, 0x100000, CRC(f88c6d33) SHA1(277b56df40a17d7dd9f1071b0d498635a5b783cd) , ROM_GROUPWORD | ROM_SKIP(6) )
517
518 ROM_REGION( 0x40000, "oki", 0 ) /* Samples */
519 ROM_LOAD( "97.u97", 0x00000, 0x40000, CRC(bf3f8574) SHA1(9e743f05e53256c886d43e1f0c43d7417134b9b3) ) /* Also silk screened as position 11 */
520 ROM_END
521
522 ROM_START( hyprduel2 )
523 ROM_REGION( 0x80000, "maincpu", 0 )
524 ROM_LOAD16_BYTE( "24a.u24", 0x000000, 0x40000, CRC(2458f91d) SHA1(c75c7bccc84738e29b35667793491a1213aea1da) ) /* Also silk screened as position 10 */
525 ROM_LOAD16_BYTE( "23a.u23", 0x000001, 0x40000, CRC(98aedfca) SHA1(42028e57ac79473cde683be2100b953ff3b2b345) ) /* Also silk screened as position 9 */
526
527 ROM_REGION( 0x400000, "vdp", 0 ) /* Gfx + Prg + Data (Addressable by CPU & Blitter) */
528 ROMX_LOAD( "ts_hyper-1.u74", 0x000000, 0x100000, CRC(4b3b2d3c) SHA1(5e9e8ec853f71aeff3910b93dadbaeae2b61717b) , ROM_GROUPWORD | ROM_SKIP(6) )
529 ROMX_LOAD( "ts_hyper-2.u75", 0x000002, 0x100000, CRC(dc230116) SHA1(a3c447657d8499764f52c81382961f425c56037b) , ROM_GROUPWORD | ROM_SKIP(6) )
530 ROMX_LOAD( "ts_hyper-3.u76", 0x000004, 0x100000, CRC(2d770dd0) SHA1(27f9e7f67e96210d3710ab4f940c5d7ae13f8bbf) , ROM_GROUPWORD | ROM_SKIP(6) )
531 ROMX_LOAD( "ts_hyper-4.u77", 0x000006, 0x100000, CRC(f88c6d33) SHA1(277b56df40a17d7dd9f1071b0d498635a5b783cd) , ROM_GROUPWORD | ROM_SKIP(6) )
532
533 ROM_REGION( 0x40000, "oki", 0 ) /* Samples */
534 ROM_LOAD( "97.u97", 0x00000, 0x40000, CRC(bf3f8574) SHA1(9e743f05e53256c886d43e1f0c43d7417134b9b3) ) /* Also silk screened as position 11 */
535 ROM_END
536
537 ROM_START( magerror )
538 ROM_REGION( 0x80000, "maincpu", 0 )
539 ROM_LOAD16_BYTE( "24.u24", 0x000000, 0x40000, CRC(5e78027f) SHA1(053374942bc545a92cc6f6ab6784c4626e4ec9e1) ) /* Also silk screened as position 10 */
540 ROM_LOAD16_BYTE( "23.u23", 0x000001, 0x40000, CRC(7271ec70) SHA1(bd7666390b70821f90ba976a3afe3194fb119478) ) /* Also silk screened as position 9 */
541
542 ROM_REGION( 0x400000, "vdp", 0 ) /* Gfx + Prg + Data (Addressable by CPU & Blitter) */
543 ROMX_LOAD( "mr93046-02.u74", 0x000000, 0x100000, CRC(f7ba06fb) SHA1(e1407b0d03863f434b68183c01e8547612e5c5fd) , ROM_GROUPWORD | ROM_SKIP(6) )
544 ROMX_LOAD( "mr93046-04.u75", 0x000002, 0x100000, CRC(8c114d15) SHA1(4eb1f82e7992deb126633287cb4fd2a6d215346c) , ROM_GROUPWORD | ROM_SKIP(6) )
545 ROMX_LOAD( "mr93046-01.u76", 0x000004, 0x100000, CRC(6cc3b928) SHA1(f19d0add314867bfb7dcefe8e7a2d50a84530df7) , ROM_GROUPWORD | ROM_SKIP(6) )
546 ROMX_LOAD( "mr93046-03.u77", 0x000006, 0x100000, CRC(6b1eb0ea) SHA1(6167a61562ef28147a7917c692f181f3fc2d5be6) , ROM_GROUPWORD | ROM_SKIP(6) )
547
548 ROM_REGION( 0x40000, "oki", 0 ) /* Samples */
549 ROM_LOAD( "97.u97", 0x00000, 0x40000, CRC(2e62bca8) SHA1(191fff11186dbbc1d9d9f3ba1b6e17c38a7d2d1d) ) /* Also silk screened as position 11 */
550 ROM_END
551
552
553 void hyprduel_state::init_hyprduel()
554 {
555 m_int_num = 0x02;
556
557 /* cpu synchronization (severe timings) */
558 m_maincpu->space(AS_PROGRAM).install_write_handler(0xc0040e, 0xc00411, write16s_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger1_w)));
559 m_subcpu->space(AS_PROGRAM).install_read_handler(0xc00408, 0xc00409, read16sm_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger1_r)));
560 m_maincpu->space(AS_PROGRAM).install_write_handler(0xc00408, 0xc00409, write16s_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger2_w)));
561 m_subcpu->space(AS_PROGRAM).install_read_handler(0xfff34c, 0xfff34d, read16sm_delegate(*this, FUNC(hyprduel_state::hyprduel_cpusync_trigger2_r)));
562 }
563
init_magerror()564 void hyprduel_state::init_magerror()
565 {
566 m_int_num = 0x01;
567 }
568
569
570 GAME( 1993, hyprduel, 0, hyprduel, hyprduel, hyprduel_state, init_hyprduel, ROT0, "Technosoft", "Hyper Duel (Japan set 1)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
571 GAME( 1993, hyprduel2, hyprduel, hyprduel, hyprduel, hyprduel_state, init_hyprduel, ROT0, "Technosoft", "Hyper Duel (Japan set 2)", MACHINE_NO_COCKTAIL | MACHINE_SUPPORTS_SAVE )
572 GAME( 1994, magerror, 0, magerror, magerror, hyprduel_state, init_magerror, ROT0, "Technosoft / Jaleco", "Magical Error wo Sagase", MACHINE_SUPPORTS_SAVE )
573