1 /***************************************************************************
2
3 Sun Electronics Arabian hardware
4
5 driver by Dan Boris
6
7 Games supported:
8 * Arabian
9
10 Known bugs:
11 * none at this time
12
13 ****************************************************************************
14
15 Memory map
16
17 ****************************************************************************
18
19 ========================================================================
20 CPU #1 (Arabian)
21 ========================================================================
22 0000-7FFF R xxxxxxxx Program ROM
23 8000-BFFF R/W xxxxxxxx Bitmap RAM
24 C000 R ----xxxx Coin inputs
25 C200 R ----xxxx Option switches
26 D000-DFFF R/W xxxxxxxx Custom microprocessor RAM
27 E000 W ----xxxx BSEL Bank select
28 E001 W xxxxxxxx DMA ROM start address low
29 E002 W xxxxxxxx DMA ROM start address high
30 E003 W xxxxxxxx DMA RAM start address low
31 E004 W xxxxxxxx DMA RAM start address high
32 E005 W xxxxxxxx Picture size/DMA start low
33 E006 W xxxxxxxx Picture size/DMA start high
34 ========================================================================
35 C800 W xxxxxxxx Sound chip address
36 CA00 R/W xxxxxxxx Sound chip data
37 ========================================================================
38 Interrupts:
39 NMI not connected
40 IRQ generated by VBLANK
41 ========================================================================
42
43 ========================================================================
44 CPU #1 (Kangaroo)
45 ========================================================================
46 0000-7FFF R xxxxxxxx Program ROM
47 8000-BFFF R/W xxxxxxxx Bitmap RAM
48 C000 R ----xxxx Coin inputs
49 C200 R ----xxxx Option switches
50 D000-DFFF R/W xxxxxxxx Custom microprocessor RAM
51 E000 W ----xxxx BSEL Bank select
52 E001 W xxxxxxxx DMA ROM start address low
53 E002 W xxxxxxxx DMA ROM start address high
54 E003 W xxxxxxxx DMA RAM start address low
55 E004 W xxxxxxxx DMA RAM start address high
56 E005 W xxxxxxxx Picture size/DMA start low
57 E006 W xxxxxxxx Picture size/DMA start high
58 ========================================================================
59 C800 W xxxxxxxx Sound chip address
60 CA00 R/W xxxxxxxx Sound chip data
61 ========================================================================
62 Interrupts:
63 NMI not connected
64 IRQ generated by VBLANK
65 ========================================================================
66
67 ***************************************************************************/
68
69 #include "driver.h"
70 #include "arabian.h"
71 #include "vidhrdw/generic.h"
72
73
74 /* constants */
75 #define MAIN_OSC 12000000
76
77
78 /* local variables */
79 static UINT8 custom_cpu_reset;
80 static UINT8 custom_cpu_busy;
81 static UINT8 *custom_cpu_ram;
82
83
84
85 /*************************************
86 *
87 * Audio chip output ports
88 *
89 *************************************/
90
WRITE_HANDLER(ay8910_porta_w)91 static WRITE_HANDLER( ay8910_porta_w )
92 {
93 /*
94 bit 7 = ENA
95 bit 6 = ENB
96 bit 5 = /ABHF
97 bit 4 = /AGHF
98 bit 3 = /ARHF
99 */
100 arabian_video_control = data;
101 }
102
103
WRITE_HANDLER(ay8910_portb_w)104 static WRITE_HANDLER( ay8910_portb_w )
105 {
106 /*
107 bit 5 = /IREQ to custom CPU
108 bit 4 = /SRES to custom CPU
109 bit 1 = coin 2 counter
110 bit 0 = coin 1 counter
111 */
112
113 /* track the custom CPU reset */
114 custom_cpu_reset = ~data & 0x10;
115
116 /* clock the coin counters */
117 coin_counter_w(1, ~data & 0x02);
118 coin_counter_w(0, ~data & 0x01);
119 }
120
121
122
123 /*************************************
124 *
125 * Custom CPU RAM snooping
126 *
127 *************************************/
128
READ_HANDLER(custom_cpu_r)129 static READ_HANDLER( custom_cpu_r )
130 {
131 /* since we don't have a simulator for the Fujitsu 8841 4-bit microprocessor */
132 /* we have to simulate its behavior; it looks like Arabian reads out of the */
133 /* alternate CPU's RAM space while the CPU is running. If the CPU is not */
134 /* running (i.e., the /SRES line is low), it needs to look like RAM to pass */
135 /* the self-tests */
136
137 /* if the CPU reset line is being held down, just return RAM */
138 if (custom_cpu_reset)
139 return custom_cpu_ram[0x7f0 + offset];
140
141 /* otherwise, assume the custom CPU is live */
142 switch (offset)
143 {
144 /* 4-bit input ports from the custom */
145 case 0:
146 case 1:
147 case 2:
148 case 3:
149 case 4:
150 case 5:
151 return readinputport(2 + offset);
152
153 /* busy flag; this is polled to check the custom CPU's readiness */
154 /* we just toggle it on and off until the main CPU gets the result */
155 /* it wants. There appears to be a number of different ways to make */
156 /* the custom turn this on. */
157 case 6:
158 return custom_cpu_busy ^= 1;
159
160 /* handshake read; the main CPU writes to the previous memory location */
161 /* and waits for the custom to copy that value here */
162 case 8:
163 return custom_cpu_ram[0x7f0 + offset - 1];
164
165 /* error cases */
166 default:
167 logerror("Input Port %04X read. PC=%04X\n", offset+0xd7f0, activecpu_get_pc());
168 return 0;
169 }
170 return 0;
171 }
172
173
update_flip_state(void)174 static void update_flip_state(void)
175 {
176 /* the custom CPU also controls the video flip control line; unfortunately, */
177 /* it appears that the custom is smart enough to flip the screen itself, based */
178 /* on the information stored at $d400 and $d401. The value at $d400 specifies */
179 /* the active player number, and the value at $d401 is a copy of the input */
180 /* port from $c200. Also, the value at $d34b controls the global flip screen */
181 /* state. */
182
183 /* initial state is based on the flip screen flag */
184 arabian_flip_screen = custom_cpu_ram[0x34b];
185
186 /* flip if not player 1 and cocktail mode */
187 if (custom_cpu_ram[0x400] != 0 && !(custom_cpu_ram[0x401] & 0x02))
188 arabian_flip_screen = !arabian_flip_screen;
189 }
190
191
WRITE_HANDLER(custom_flip_w)192 static WRITE_HANDLER( custom_flip_w )
193 {
194 custom_cpu_ram[0x34b + offset] = data;
195 update_flip_state();
196 }
197
198
WRITE_HANDLER(custom_cocktail_w)199 static WRITE_HANDLER( custom_cocktail_w )
200 {
201 custom_cpu_ram[0x400 + offset] = data;
202 update_flip_state();
203 }
204
205
206
207 /*************************************
208 *
209 * Main CPU memory handlers
210 *
211 *************************************/
212
MEMORY_READ_START(readmem)213 static MEMORY_READ_START( readmem )
214 { 0x0000, 0x7fff, MRA_ROM },
215 { 0xc000, 0xc000, input_port_0_r },
216 { 0xc200, 0xc200, input_port_1_r },
217 { 0xd000, 0xd7ef, MRA_RAM },
218 { 0xd7f0, 0xd7ff, custom_cpu_r },
219 MEMORY_END
220
221
222 static MEMORY_WRITE_START( writemem )
223 { 0x0000, 0x7fff, MWA_ROM },
224 { 0x8000, 0xbfff, arabian_videoram_w, &videoram },
225 { 0xd000, 0xd7ff, MWA_RAM, &custom_cpu_ram },
226 { 0xe000, 0xe07f, arabian_blitter_w, &spriteram },
227 MEMORY_END
228
229
230
231 /*************************************
232 *
233 * Main CPU port handlers
234 *
235 *************************************/
236
237 static PORT_WRITE_START( writeport )
238 { 0xc800, 0xc800, AY8910_control_port_0_w },
239 { 0xca00, 0xca00, AY8910_write_port_0_w },
240 PORT_END
241
242
243
244 /*************************************
245 *
246 * Port definitions
247 *
248 *************************************/
249
250 INPUT_PORTS_START( arabian )
251 PORT_START /* IN0 */
252 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 )
253 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN2 )
254 PORT_SERVICE( 0x04, IP_ACTIVE_HIGH )
255 PORT_BIT( 0xf8, IP_ACTIVE_HIGH, IPT_UNKNOWN )
256
257 PORT_START /* DSW1 */
258 PORT_DIPNAME( 0x01, 0x00, DEF_STR( Lives ))
259 PORT_DIPSETTING( 0x00, "3" )
260 PORT_DIPSETTING( 0x01, "5" )
261 PORT_DIPNAME( 0x02, 0x02, DEF_STR( Cabinet ))
262 PORT_DIPSETTING( 0x02, DEF_STR( Upright ))
263 PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ))
264 PORT_DIPNAME( 0x04, 0x04, DEF_STR( Flip_Screen ))
265 PORT_DIPSETTING( 0x04, DEF_STR( Off ))
266 PORT_DIPSETTING( 0x00, DEF_STR( On ))
267 PORT_DIPNAME( 0x08, 0x00, "Carry Bowls to Next Life" )
268 PORT_DIPSETTING( 0x08, DEF_STR( No ))
269 PORT_DIPSETTING( 0x00, DEF_STR( Yes ))
270 PORT_DIPNAME( 0xf0, 0x00, DEF_STR( Coinage ))
271 PORT_DIPSETTING( 0x10, "A 2/1 B 2/1" )
272 PORT_DIPSETTING( 0x20, "A 2/1 B 1/3" )
273 PORT_DIPSETTING( 0x00, "A 1/1 B 1/1" )
274 PORT_DIPSETTING( 0x30, "A 1/1 B 1/2" )
275 PORT_DIPSETTING( 0x40, "A 1/1 B 1/3" )
276 PORT_DIPSETTING( 0x50, "A 1/1 B 1/4" )
277 PORT_DIPSETTING( 0x60, "A 1/1 B 1/5" )
278 PORT_DIPSETTING( 0x70, "A 1/1 B 1/6" )
279 PORT_DIPSETTING( 0x80, "A 1/2 B 1/2" )
280 PORT_DIPSETTING( 0x90, "A 1/2 B 1/4" )
281 PORT_DIPSETTING( 0xa0, "A 1/2 B 1/6" )
282 PORT_DIPSETTING( 0xb0, "A 1/2 B 1/10" )
283 PORT_DIPSETTING( 0xc0, "A 1/2 B 1/11" )
284 PORT_DIPSETTING( 0xd0, "A 1/2 B 1/12" )
285 PORT_DIPSETTING( 0xf0, DEF_STR( Free_Play ))
286 /* 0xe0 gives A 1/2 B 1/6 */
287
288 PORT_START /* COM0 */
289 PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED )
290 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START1 )
291 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_START2 )
292 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_COIN3 ) /* IN3 */
293
294 PORT_START /* COM1 */
295 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT | IPF_8WAY )
296 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT | IPF_8WAY )
297 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP | IPF_8WAY )
298 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN | IPF_8WAY )
299
300 PORT_START /* COM2 */
301 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 )
302 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN9 */
303 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN10 */
304 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN11 */
305
306 PORT_START /* COM3 */
307 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_COCKTAIL )
308 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_COCKTAIL )
309 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP | IPF_8WAY | IPF_COCKTAIL )
310 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_COCKTAIL )
311
312 PORT_START /* COM4 */
313 PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 | IPF_COCKTAIL )
314 PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN17 */
315 PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN18 */
316 PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN ) /* IN19 */
317
318 PORT_START /* COM5 */
319 PORT_DIPNAME( 0x01, 0x00, "Coin Chutes" )
320 PORT_DIPSETTING( 0x01, "1" )
321 PORT_DIPSETTING( 0x00, "2" )
322 PORT_DIPNAME( 0x02, 0x00, DEF_STR( Demo_Sounds ))
323 PORT_DIPSETTING( 0x02, DEF_STR( Off ))
324 PORT_DIPSETTING( 0x00, DEF_STR( On ))
325 PORT_DIPNAME( 0x0c, 0x04, DEF_STR( Bonus_Life ))
326 PORT_DIPSETTING( 0x04, "20000" )
327 PORT_DIPSETTING( 0x08, "40000" )
328 PORT_DIPSETTING( 0x0c, "20000 50000 +100K" )
329 PORT_DIPSETTING( 0x00, "None" )
330 INPUT_PORTS_END
331
332
333
334 /*************************************
335 *
336 * Sound definitions
337 *
338 *************************************/
339
340 static struct AY8910interface ay8910_interface =
341 {
342 1,
343 MAIN_OSC/4/2, /* 1.5 MHz */
344 { 50 },
345 { 0 },
346 { 0 },
347 { ay8910_porta_w },
348 { ay8910_portb_w }
349 };
350
351
352
353 /*************************************
354 *
355 * Machine driver
356 *
357 *************************************/
358
359 static MACHINE_DRIVER_START( arabian )
360
361 /* basic machine hardware */
362 MDRV_CPU_ADD(Z80, MAIN_OSC/4)
MDRV_CPU_FLAGS(CPU_16BIT_PORT)363 MDRV_CPU_FLAGS(CPU_16BIT_PORT)
364 MDRV_CPU_MEMORY(readmem,writemem)
365 MDRV_CPU_PORTS(0,writeport)
366 MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
367
368 MDRV_FRAMES_PER_SECOND(60)
369 MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
370
371 /* video hardware */
372 MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
373 MDRV_SCREEN_SIZE(256, 256)
374 MDRV_VISIBLE_AREA(0, 255, 11, 244)
375 MDRV_PALETTE_LENGTH(64)
376 MDRV_COLORTABLE_LENGTH(256*32)
377
378 MDRV_PALETTE_INIT(arabian)
379 MDRV_VIDEO_START(arabian)
380 MDRV_VIDEO_UPDATE(arabian)
381
382 /* sound hardware */
383 MDRV_SOUND_ADD(AY8910, ay8910_interface)
384 MACHINE_DRIVER_END
385
386
387
388 /*************************************
389 *
390 * ROM definitions
391 *
392 *************************************/
393
394 ROM_START( arabian )
395 ROM_REGION( 0x10000, REGION_CPU1, 0 )
396 ROM_LOAD( "ic1rev2.87", 0x0000, 0x2000, CRC(5e1c98b8) SHA1(1775b7b125dde3502aefcf6221662e82f55b3f2a) )
397 ROM_LOAD( "ic2rev2.88", 0x2000, 0x2000, CRC(092f587e) SHA1(a722a61d35629ff4087c7a5e4c98b3ab51d6322b) )
398 ROM_LOAD( "ic3rev2.89", 0x4000, 0x2000, CRC(15145f23) SHA1(ae250116b57455ed84948cd9a6bdda86b2ac3e16) )
399 ROM_LOAD( "ic4rev2.90", 0x6000, 0x2000, CRC(32b77b44) SHA1(9d7951e723bc65e3d607f89836f1436b99f2585b) )
400
401 ROM_REGION( 0x10000, REGION_GFX1, 0 )
402 ROM_LOAD( "ic84.91", 0x0000, 0x2000, CRC(c4637822) SHA1(0c73d9a4db925421a535784780ad93bb0f091051) )
403 ROM_LOAD( "ic85.92", 0x2000, 0x2000, CRC(f7c6866d) SHA1(34f545c5f7c152cd59f7be0a72105f739852cd6a) )
404 ROM_LOAD( "ic86.93", 0x4000, 0x2000, CRC(71acd48d) SHA1(cd0bffed351b14c9aebbfc1d3d4d232a5b91a68f) )
405 ROM_LOAD( "ic87.94", 0x6000, 0x2000, CRC(82160b9a) SHA1(03511f6ebcf22ba709a80a565e71acf5bdecbabb) )
406 ROM_END
407
408
409 ROM_START( arabiana )
410 ROM_REGION( 0x10000, REGION_CPU1, 0 )
411 ROM_LOAD( "ic1.87", 0x0000, 0x2000, CRC(51e9a6b1) SHA1(a2e6beab5380eed56972f5625be21b01c7e2082a) )
412 ROM_LOAD( "ic2.88", 0x2000, 0x2000, CRC(1cdcc1ab) SHA1(46886d53cc8a1c1d540fd0e1ddf1811fb256c1f3) )
413 ROM_LOAD( "ic3.89", 0x4000, 0x2000, CRC(b7b7faa0) SHA1(719418b7b7c057acb6d3060cf7061ffacf00798c) )
414 ROM_LOAD( "ic4.90", 0x6000, 0x2000, CRC(dbded961) SHA1(ecc09fa95f6dd58c4ac0e095a89ffd3aae681da4) )
415
416 ROM_REGION( 0x10000, REGION_GFX1, 0 )
417 ROM_LOAD( "ic84.91", 0x0000, 0x2000, CRC(c4637822) SHA1(0c73d9a4db925421a535784780ad93bb0f091051) )
418 ROM_LOAD( "ic85.92", 0x2000, 0x2000, CRC(f7c6866d) SHA1(34f545c5f7c152cd59f7be0a72105f739852cd6a) )
419 ROM_LOAD( "ic86.93", 0x4000, 0x2000, CRC(71acd48d) SHA1(cd0bffed351b14c9aebbfc1d3d4d232a5b91a68f) )
420 ROM_LOAD( "ic87.94", 0x6000, 0x2000, CRC(82160b9a) SHA1(03511f6ebcf22ba709a80a565e71acf5bdecbabb) )
421 ROM_END
422
423
424
425 /*************************************
426 *
427 * Driver initialization
428 *
429 *************************************/
430
431 static DRIVER_INIT( arabian )
432 {
433 install_mem_write_handler(0, 0xd34b, 0xd34b, custom_flip_w);
434 install_mem_write_handler(0, 0xd400, 0xd401, custom_cocktail_w);
435 }
436
437
438
439 /*************************************
440 *
441 * Game drivers
442 *
443 *************************************/
444
445 GAME( 1983, arabian, 0, arabian, arabian, arabian, ROT270, "Sun Electronics", "Arabian" )
446 GAME( 1983, arabiana, arabian, arabian, arabian, arabian, ROT270, "[Sun Electronics] (Atari license)", "Arabian (Atari)" )
447