1 /* Aquarium (c)1996 Excellent Systems */
2
3 /* the hardware is similar to gcpinbal.c, probably should merge it at some point */
4
5 /*
6
7 AQUARIUM
8 EXCELLENT SYSTEMS
9 ES-9206
10 3
11 14.318MHz 7
12 ES 9207
13 8
14 ES 9303
15 ES 9208 2
16
17 AQUARF1 68000-16 6
18
19 SW1
20 YM2151 M6295 4 32MHz 1
21 Z80-6 5 SW2Q
22
23 */
24
25 /* To Do (top are higher priorities)
26
27 Controls + Dipswitches *done* - stephh
28 Fix Sound (z80, ym2151 + m6295) (program banking, oki illegal samples etc.)
29 Fix Priority Problems
30 Merge with gcpinbal.c (and clean up gcpinbal.c)
31
32
33 Stephh's notes (based on the game M68000 code and some tests) :
34
35 - The current set is a Japan set (0x0a5c.w = 0x0000), so there must exist
36 a non-Japan set which is AFAIK not dumped at the moment.
37 I have however no clue about what should be the value in the non-Japan set.
38 - Use AQUARIUS_HACK to be able to change the game to English language
39 via the FAKE Dip Switch.
40 Change the Dip Switch then reset the game to make the changes effective.
41 - I haven't found a way to enter sort of "test mode", even if there seems
42 to be code (or at least data) for it.
43
44
45 */
46
47
48 #include "driver.h"
49 #include "vidhrdw/generic.h"
50
51 #define AQUARIUS_HACK 0
52
53 data16_t *aquarium_scroll, *aquarium_priority;
54 data16_t *aquarium_txt_videoram;
55 data16_t *aquarium_mid_videoram;
56 data16_t *aquarium_bak_videoram;
57
58 WRITE16_HANDLER( aquarium_txt_videoram_w );
59 WRITE16_HANDLER( aquarium_mid_videoram_w );
60 WRITE16_HANDLER( aquarium_bak_videoram_w );
61
62 VIDEO_START(aquarium);
63 VIDEO_UPDATE(aquarium);
64
65 #if AQUARIUS_HACK
MACHINE_INIT(aquarium)66 static MACHINE_INIT( aquarium )
67 {
68 data16_t *RAM = (data16_t *)memory_region(REGION_CPU1);
69 int data = readinputport(3);
70
71 /* Language : 0x0000 = Japanese - Other value = English */
72
73 RAM[0x000a5c/2] = data;
74
75 }
76 #endif
77
READ16_HANDLER(aquarium_coins_r)78 READ16_HANDLER( aquarium_coins_r )
79 {
80 static int toggle = 0x0000;
81 toggle ^= 0x8000; /* sound status */
82 return (input_port_2_word_r(0,mem_mask) & 0x7fff) | toggle; /* IN1 */
83 }
84
WRITE16_HANDLER(aquarium_sound_w)85 WRITE16_HANDLER( aquarium_sound_w )
86 {
87 // usrintf_showmessage("sound write %04x",data);
88
89 soundlatch_w(1,data&0xff);
90 cpu_set_irq_line( 1, IRQ_LINE_NMI, PULSE_LINE );
91 }
92
WRITE_HANDLER(aquarium_z80_bank_w)93 static WRITE_HANDLER( aquarium_z80_bank_w )
94 {
95 int soundbank = ((data & 0x7) + 1) * 0x8000;
96 data8_t *Z80 = (data8_t *)memory_region(REGION_CPU2);
97
98 cpu_setbank(1, &Z80[soundbank + 0x10000]);
99 }
100
MEMORY_READ16_START(readmem)101 static MEMORY_READ16_START( readmem )
102 { 0x000000, 0x07ffff, MRA16_ROM },
103 { 0xc00000, 0xc03fff, MRA16_RAM },
104 { 0xc80000, 0xc81fff, MRA16_RAM }, /* sprite ram */
105 { 0xd00000, 0xd00fff, MRA16_RAM },
106 { 0xd80080, 0xd80081, input_port_0_word_r },
107 { 0xd80082, 0xd80083, MRA16_NOP }, /* stored but not read back ? check code at 0x01f440 */
108 { 0xd80084, 0xd80085, input_port_1_word_r },
109 { 0xd80086, 0xd80087, aquarium_coins_r },
110 { 0xff0000, 0xffffff, MRA16_RAM }, /* RAM */
111 MEMORY_END
112
113 static MEMORY_WRITE16_START( writemem )
114 { 0x000000, 0x07ffff, MWA16_ROM },
115 { 0xc00000, 0xc00fff, aquarium_mid_videoram_w, &aquarium_mid_videoram },
116 { 0xc01000, 0xc01fff, aquarium_bak_videoram_w, &aquarium_bak_videoram },
117 { 0xc02000, 0xc03fff, aquarium_txt_videoram_w, &aquarium_txt_videoram },
118 { 0xc80000, 0xc81fff, MWA16_RAM, &spriteram16, &spriteram_size },
119 { 0xd00000, 0xd00fff, paletteram16_RRRRGGGGBBBBRGBx_word_w, &paletteram16 },
120 { 0xd80014, 0xd8001f, MWA16_RAM, &aquarium_scroll },
121 { 0xd80068, 0xd80069, MWA16_RAM, &aquarium_priority }, /* maybe not on this game? */
122 { 0xd80088, 0xd80089, MWA16_NOP }, /* ?? */
123 { 0xd8008a, 0xd8008b, aquarium_sound_w },
124 { 0xff0000, 0xffffff, MWA16_RAM },
125 MEMORY_END
126
127 static MEMORY_READ_START( snd_readmem )
128 { 0x0000, 0x3fff, MRA_ROM },
129 { 0x7800, 0x7fff, MRA_RAM },
130 { 0x8000, 0xffff, MRA_BANK1 },
131 MEMORY_END
132
133 static MEMORY_WRITE_START( snd_writemem )
134 { 0x0000, 0x3fff, MWA_ROM },
135 { 0x7800, 0x7fff, MWA_RAM },
136 MEMORY_END
137
138 static PORT_READ_START( snd_readport )
139 { 0x01, 0x01, YM2151_status_port_0_r },
140 { 0x02, 0x02, OKIM6295_status_0_r },
141 { 0x04, 0x04, soundlatch_r },
142 PORT_END
143
144 static PORT_WRITE_START( snd_writeport )
145 { 0x00, 0x00, YM2151_register_port_0_w },
146 { 0x01, 0x01, YM2151_data_port_0_w },
147 { 0x02, 0x02, OKIM6295_data_0_w },
148 { 0x06, 0x06, IOWP_NOP }, /* zero is always written here, command ack? */
149 { 0x08, 0x08, aquarium_z80_bank_w },
150 PORT_END
151
152 INPUT_PORTS_START( aquarium )
153 PORT_START /* DSW */
154 PORT_DIPNAME( 0x0003, 0x0003, DEF_STR( Difficulty ) )
155 PORT_DIPSETTING( 0x0002, "Easy" )
156 PORT_DIPSETTING( 0x0003, "Normal" )
157 PORT_DIPSETTING( 0x0001, "Hard" )
158 PORT_DIPSETTING( 0x0000, "Hardest" )
159 PORT_DIPNAME( 0x000c, 0x000c, "Winning Rounds (Player VS CPU)" )
160 PORT_DIPSETTING( 0x000c, "1/1" )
161 PORT_DIPSETTING( 0x0008, "2/3" )
162 PORT_DIPSETTING( 0x0004, "3/5" )
163 // PORT_DIPSETTING( 0x0000, "1/1" )
164 PORT_DIPNAME( 0x0030, 0x0030, "Winning Rounds (Player VS Player)" )
165 PORT_DIPSETTING( 0x0030, "1/1" )
166 PORT_DIPSETTING( 0x0020, "2/3" )
167 PORT_DIPSETTING( 0x0010, "3/5" )
168 // PORT_DIPSETTING( 0x0000, "1/1" )
169 PORT_DIPNAME( 0x0040, 0x0040, DEF_STR( Unused ) )
170 PORT_DIPSETTING( 0x0040, DEF_STR( Off ) )
171 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
172 PORT_DIPNAME( 0x0080, 0x0080, DEF_STR( Unused ) )
173 PORT_DIPSETTING( 0x0080, DEF_STR( Off ) )
174 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
175 PORT_DIPNAME( 0x0700, 0x0700, DEF_STR( Coinage ) )
176 PORT_DIPSETTING( 0x0000, DEF_STR( 5C_1C ) )
177 PORT_DIPSETTING( 0x0100, DEF_STR( 4C_1C ) )
178 PORT_DIPSETTING( 0x0200, DEF_STR( 3C_1C ) )
179 PORT_DIPSETTING( 0x0300, DEF_STR( 2C_1C ) )
180 PORT_DIPSETTING( 0x0700, DEF_STR( 1C_1C ) )
181 PORT_DIPSETTING( 0x0600, DEF_STR( 1C_2C ) )
182 PORT_DIPSETTING( 0x0500, DEF_STR( 1C_3C ) )
183 PORT_DIPSETTING( 0x0400, DEF_STR( 1C_4C ) )
184 PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unused ) )
185 PORT_DIPSETTING( 0x0800, DEF_STR( Off ) )
186 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
187 PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Flip_Screen ) ) // to be confirmed - code at 0x01f82c
188 PORT_DIPSETTING( 0x1000, DEF_STR( Off ) )
189 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
190 PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Demo_Sounds ) ) // to be confirmed - code at 0x0037de
191 PORT_DIPSETTING( 0x0000, DEF_STR( Off ) )
192 PORT_DIPSETTING( 0x2000, DEF_STR( On ) )
193 PORT_DIPNAME( 0x4000, 0x4000, DEF_STR( Unused ) )
194 PORT_DIPSETTING( 0x4000, DEF_STR( Off ) )
195 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
196 PORT_DIPNAME( 0x8000, 0x8000, DEF_STR( Unused ) )
197 PORT_DIPSETTING( 0x8000, DEF_STR( Off ) )
198 PORT_DIPSETTING( 0x0000, DEF_STR( On ) )
199
200 PORT_START /* IN0 */
201 PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER2 )
202 PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER2 )
203 PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER2 )
204 PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER2 )
205 PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 )
206 PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER2 )
207 PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_UNKNOWN )
208 PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_START2 )
209 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_PLAYER1 )
210 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_PLAYER1 )
211 PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_PLAYER1 )
212 PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_PLAYER1 )
213 PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER1 )
214 PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_PLAYER1 )
215 PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
216 PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START1 )
217
218 PORT_START /* IN1 */
219 PORT_BIT( 0x00ff, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* untested */
220 PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_COIN2 )
221 PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_COIN1 )
222 PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_UNKNOWN )
223 PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_SERVICE1 )
224 PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_UNKNOWN )
225 PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN )
226 PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNKNOWN )
227 PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* sound status */
228
229 #if AQUARIUS_HACK
230 PORT_START /* FAKE DSW to support language */
231 PORT_DIPNAME( 0xffff, 0x0001, "Language" )
232 PORT_DIPSETTING( 0x0000, "Japanese" )
233 PORT_DIPSETTING( 0x0001, "English" ) // This is a guess of what should be the value
234 #endif
235 INPUT_PORTS_END
236
237 static struct GfxLayout char5bpplayout =
238 {
239 16,16, /* 16*16 characters */
240 RGN_FRAC(1,2),
241 5, /* 4 bits per pixel */
242 { RGN_FRAC(1,2), 0, 1, 2, 3 },
243 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4, 2*4+32, 3*4+32, 0*4+32, 1*4+32, 6*4+32, 7*4+32, 4*4+32, 5*4+32 },
244 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
245 128*8 /* every sprite takes 128 consecutive bytes */
246 };
247
248 static struct GfxLayout char_8x8_layout =
249 {
250 8,8, /* 8*8 characters */
251 RGN_FRAC(1,1),
252 4, /* 4 bits per pixel */
253 { 0, 1, 2, 3 },
254 { 2*4, 3*4, 0*4, 1*4, 6*4, 7*4, 4*4, 5*4 },
255 { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 },
256 32*8 /* every sprite takes 32 consecutive bytes */
257 };
258
259 static struct GfxLayout tilelayout =
260 {
261 16,16, /* 16*16 sprites */
262 RGN_FRAC(1,1),
263 4, /* 4 bits per pixel */
264 { 48, 16, 32, 0 },
265 { 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7 },
266 { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 8*64, 9*64, 10*64, 11*64, 12*64, 13*64, 14*64, 15*64 },
267 128*8 /* every sprite takes 128 consecutive bytes */
268 };
269
DRIVER_INIT(aquarium)270 static DRIVER_INIT( aquarium )
271 {
272 /* The BG tiles are 5bpp, this rearranges the data from
273 the roms containing the 1bpp data so we can decode it
274 correctly */
275
276 data8_t *DAT2 = memory_region(REGION_GFX1)+0x080000;
277 data8_t *DAT = memory_region(REGION_USER1);
278 int len = 0x0200000;
279
280 for (len = 0 ; len < 0x020000 ; len ++ )
281 {
282 DAT2[len*4+1] = (DAT[len] & 0x80) << 0;
283 DAT2[len*4+1] |= (DAT[len] & 0x40) >> 3;
284 DAT2[len*4+0] = (DAT[len] & 0x20) << 2;
285 DAT2[len*4+0] |= (DAT[len] & 0x10) >> 1;
286 DAT2[len*4+3] = (DAT[len] & 0x08) << 4;
287 DAT2[len*4+3] |= (DAT[len] & 0x04) << 1;
288 DAT2[len*4+2] = (DAT[len] & 0x02) << 6;
289 DAT2[len*4+2] |= (DAT[len] & 0x01) << 3;
290 }
291
292 DAT2 = memory_region(REGION_GFX4)+0x080000;
293 DAT = memory_region(REGION_USER2);
294
295 for (len = 0 ; len < 0x020000 ; len ++ )
296 {
297 DAT2[len*4+1] = (DAT[len] & 0x80) << 0;
298 DAT2[len*4+1] |= (DAT[len] & 0x40) >> 3;
299 DAT2[len*4+0] = (DAT[len] & 0x20) << 2;
300 DAT2[len*4+0] |= (DAT[len] & 0x10) >> 1;
301 DAT2[len*4+3] = (DAT[len] & 0x08) << 4;
302 DAT2[len*4+3] |= (DAT[len] & 0x04) << 1;
303 DAT2[len*4+2] = (DAT[len] & 0x02) << 6;
304 DAT2[len*4+2] |= (DAT[len] & 0x01) << 3;
305 }
306
307 /* reset the sound bank */
308 aquarium_z80_bank_w(0, 0);
309 }
310
311
312 struct GfxDecodeInfo gfxdecodeinfo[] =
313 {
314 { REGION_GFX3, 0, &tilelayout, 0x300, 32 },
315 { REGION_GFX1, 0, &char5bpplayout, 0x400, 32 },
316 { REGION_GFX2, 0, &char_8x8_layout, 0x200, 32 },
317 { REGION_GFX4, 0, &char5bpplayout, 0x400, 32 },
318 { -1 } /* end of array */
319 };
320
irq_handler(int irq)321 static void irq_handler(int irq)
322 {
323 cpu_set_irq_line( 1, 0 , irq ? ASSERT_LINE : CLEAR_LINE );
324 }
325
326 static struct YM2151interface ym2151_interface =
327 {
328 1, /* 1 chip */
329 3579545, /* Guess */
330 { YM3012_VOL(45,MIXER_PAN_LEFT,45,MIXER_PAN_RIGHT) },
331 { irq_handler }
332 };
333
334 static struct OKIM6295interface okim6295_interface =
335 {
336 1, /* 1 chip */
337 { 8500 }, /* frequency (Hz) */
338 { REGION_SOUND1 }, /* memory region */
339 { 47 }
340 };
341
342 static MACHINE_DRIVER_START( aquarium )
343
344 /* basic machine hardware */
345 MDRV_CPU_ADD(M68000, 32000000/2)
346 MDRV_CPU_MEMORY(readmem,writemem)
347 MDRV_CPU_VBLANK_INT(irq1_line_hold,1)
348
349 MDRV_CPU_ADD(Z80, 6000000)
350 MDRV_CPU_FLAGS(CPU_AUDIO_CPU)
351 MDRV_CPU_MEMORY(snd_readmem,snd_writemem)
352 MDRV_CPU_PORTS(snd_readport,snd_writeport)
353
354 MDRV_FRAMES_PER_SECOND(60)
355 MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
356
357 #if AQUARIUS_HACK
358 MDRV_MACHINE_INIT(aquarium)
359 #endif
360
361 /* video hardware */
362 MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
363 MDRV_SCREEN_SIZE(64*8, 64*8)
364 MDRV_VISIBLE_AREA(2*8, 42*8-1, 2*8, 34*8-1)
365 MDRV_GFXDECODE(gfxdecodeinfo)
366 MDRV_PALETTE_LENGTH(0x1000/2)
367
368 MDRV_VIDEO_START(aquarium)
369 MDRV_VIDEO_UPDATE(aquarium)
370
371 /* sound hardware */
372 MDRV_SOUND_ATTRIBUTES(SOUND_SUPPORTS_STEREO)
373 MDRV_SOUND_ADD(YM2151, ym2151_interface)
374 MDRV_SOUND_ADD(OKIM6295, okim6295_interface)
375 MACHINE_DRIVER_END
376
377 ROM_START( aquarium )
378 ROM_REGION( 0x080000, REGION_CPU1, 0 ) /* 68000 code */
379 ROM_LOAD16_WORD_SWAP( "aquar3", 0x000000, 0x080000, CRC(344509a1) SHA1(9deb610732dee5066b3225cd7b1929b767579235) )
380
381 ROM_REGION( 0x50000, REGION_CPU2, 0 ) /* z80 (sound) code */
382 ROM_LOAD( "aquar5", 0x000000, 0x40000, CRC(fa555be1) SHA1(07236f2b2ba67e92984b9ddf4a8154221d535245) )
383 ROM_RELOAD( 0x010000, 0x40000 )
384
385 ROM_REGION( 0x100000, REGION_GFX1, ROMREGION_DISPOSE ) /* BG Tiles */
386 ROM_LOAD( "aquar1", 0x000000, 0x080000, CRC(575df6ac) SHA1(071394273e512666fe124facdd8591a767ad0819) ) // 4bpp
387 /* data is expanded here from USER1 */
388 ROM_REGION( 0x100000, REGION_USER1, ROMREGION_DISPOSE ) /* BG Tiles */
389 ROM_LOAD( "aquar6", 0x000000, 0x020000, CRC(9065b146) SHA1(befc218bbcd63453ea7eb8f976796d36f2b2d552) ) // 1bpp
390
391 ROM_REGION( 0x100000, REGION_GFX4, ROMREGION_DISPOSE ) /* BG Tiles */
392 ROM_LOAD( "aquar8", 0x000000, 0x080000, CRC(915520c4) SHA1(308207cb20f1ed6df365710c808644a6e4f07614) ) // 4bpp
393 /* data is expanded here from USER2 */
394 ROM_REGION( 0x100000, REGION_USER2, ROMREGION_DISPOSE ) /* BG Tiles */
395 ROM_LOAD( "aquar7", 0x000000, 0x020000, CRC(b96b2b82) SHA1(2b719d0c185d1eca4cd9ea66bed7842b74062288) ) // 1bpp
396
397 ROM_REGION( 0x060000, REGION_GFX2, ROMREGION_DISPOSE ) /* FG Tiles */
398 ROM_LOAD( "aquar2", 0x000000, 0x020000, CRC(aa071b05) SHA1(517415bfd8e4dd51c6eb03a25c706f8613d34a09) )
399
400 ROM_REGION( 0x200000, REGION_GFX3, ROMREGION_DISPOSE ) /* Sprites? */
401 ROM_LOAD( "aquarf1", 0x000000, 0x0100000, CRC(14758b3c) SHA1(b372ccb42acb55a3dd15352a9d4ed576878a6731) )
402
403 ROM_REGION( 0x100000, REGION_SOUND1, 0 ) /* Samples */
404 ROM_LOAD( "aquar4", 0x000000, 0x80000, CRC(9a4af531) SHA1(bb201b7a6c9fd5924a0d79090257efffd8d4aba1) )
405 ROM_END
406
407 #if !AQUARIUS_HACK
408 GAMEX( 1996, aquarium, 0, aquarium, aquarium, aquarium, ROT0, "Excellent System", "Aquarium (Japan)", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NO_COCKTAIL )
409 #else
410 GAMEX( 1996, aquarium, 0, aquarium, aquarium, aquarium, ROT0, "Excellent System", "Aquarium", GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS | GAME_NO_COCKTAIL )
411 #endif
412