1 /****************************************************************************
2 
3 Formation Z / Aeroboto
4 
5 Driver by Carlos A. Lozano
6 
7 
8 TODO:
9 - star field
10   Uki's report:
11   - The color of stars:
12     at 1st title screen = neutral tints of blue and aqua (1 color only)
13     at 2nd title screen and attract mode (purple surface) = light & dark aqua
14     This color will not be affected by scroll. Leftmost 8pixels are light, next
15     16 pixels are dark, the next 16 pixels are light, and so on.
16 
17 Revisions:
18 - Updated starfield according to Uki's report. (AT)
19 
20 *note: Holding any key at boot puts the game in MCU test. Press F3 to quit.
21 
22 ****************************************************************************/
23 
24 #include "driver.h"
25 #include "vidhrdw/generic.h"
26 
27 
28 extern data8_t *aeroboto_videoram;
29 extern data8_t *aeroboto_hscroll, *aeroboto_vscroll, *aeroboto_tilecolor;
30 extern data8_t *aeroboto_starx, *aeroboto_stary, *aeroboto_bgcolor;
31 
32 VIDEO_START( aeroboto );
33 VIDEO_UPDATE( aeroboto );
34 
35 READ_HANDLER( aeroboto_in0_r );
36 WRITE_HANDLER( aeroboto_3000_w );
37 WRITE_HANDLER( aeroboto_videoram_w );
38 WRITE_HANDLER( aeroboto_tilecolor_w );
39 
40 static data8_t *aeroboto_mainram;
41 static int disable_irq = 0;
42 
43 
READ_HANDLER(aeroboto_201_r)44 static READ_HANDLER( aeroboto_201_r )
45 {
46 	/* if you keep a button pressed during boot, the game will expect this */
47 	/* serie of values to be returned from 3004, and display "PASS 201" if it is */
48 	int res[4] = { 0xff,0x9f,0x1b,0x03};
49 	static int count;
50 	log_cb(RETRO_LOG_DEBUG, LOGPRE "PC %04x: read 3004\n",activecpu_get_pc());
51 	return res[(count++)&3];
52 }
53 
54 
INTERRUPT_GEN(aeroboto_interrupt)55 static INTERRUPT_GEN( aeroboto_interrupt )
56 {
57 	if (!disable_irq)
58 		cpu_set_irq_line(0, 0, HOLD_LINE);
59 	else
60 		disable_irq--;
61 }
62 
READ_HANDLER(aeroboto_2973_r)63 static READ_HANDLER( aeroboto_2973_r )
64 {
65 	aeroboto_mainram[0x02be] = 0;
66 	return(0xff);
67 }
68 
WRITE_HANDLER(aeroboto_1a2_w)69 static WRITE_HANDLER ( aeroboto_1a2_w )
70 {
71 	aeroboto_mainram[0x01a2] = data;
72 	if (data) disable_irq = 1;
73 }
74 
MEMORY_READ_START(readmem)75 static MEMORY_READ_START( readmem )
76 	{ 0x0000, 0x07ff, MRA_RAM }, /* main RAM*/
77 	{ 0x0800, 0x08ff, MRA_RAM }, /* tile color buffer; copied to 0x2000*/
78 	{ 0x1000, 0x17ff, MRA_RAM }, /* tile RAM*/
79 	{ 0x1800, 0x183f, MRA_RAM }, /* horizontal scroll regs*/
80 	{ 0x2000, 0x20ff, MRA_RAM }, /* tile color RAM*/
81 	{ 0x2800, 0x28ff, MRA_RAM }, /* sprite RAM*/
82 	{ 0x2973, 0x2973, aeroboto_2973_r }, /* protection read*/
83 	{ 0x3000, 0x3000, aeroboto_in0_r },
84 	{ 0x3001, 0x3001, input_port_2_r },
85 	{ 0x3002, 0x3002, input_port_3_r },
86 	{ 0x3004, 0x3004, aeroboto_201_r }, /* protection read*/
87 	{ 0x3800, 0x3800, MRA_NOP }, /* watchdog or IRQ ack*/
88 	{ 0x4000, 0xffff, MRA_ROM }, /* main ROM*/
89 MEMORY_END
90 
91 static MEMORY_WRITE_START( writemem )
92 	{ 0x01a2, 0x01a2, aeroboto_1a2_w }, /* affects IRQ line (more protection?)*/
93 	{ 0x0000, 0x07ff, MWA_RAM, &aeroboto_mainram },
94 	{ 0x0800, 0x08ff, MWA_RAM },
95 	{ 0x0900, 0x09ff, MWA_RAM }, /* a backup of default tile colors*/
96 	{ 0x1000, 0x17ff, aeroboto_videoram_w, &aeroboto_videoram },
97 	{ 0x1800, 0x183f, MWA_RAM, &aeroboto_hscroll },
98 	{ 0x2000, 0x20ff, aeroboto_tilecolor_w, &aeroboto_tilecolor },
99 	{ 0x1840, 0x27ff, MWA_NOP }, /* cleared during custom LSI test*/
100 	{ 0x2800, 0x28ff, MWA_RAM, &spriteram, &spriteram_size },
101 	{ 0x2900, 0x2fff, MWA_NOP }, /* cleared along with sprite RAM*/
102 	{ 0x3000, 0x3000, aeroboto_3000_w },
103 	{ 0x3001, 0x3001, soundlatch_w },
104 	{ 0x3002, 0x3002, soundlatch2_w },
105 	{ 0x3003, 0x3003, MWA_RAM, &aeroboto_vscroll },
106 	{ 0x3004, 0x3004, MWA_RAM, &aeroboto_starx },
107 	{ 0x3005, 0x3005, MWA_RAM, &aeroboto_stary }, /* usable but probably wrong*/
108 	{ 0x3006, 0x3006, MWA_RAM, &aeroboto_bgcolor },
109 	{ 0x4000, 0xffff, MWA_ROM },
110 MEMORY_END
111 
112 static MEMORY_READ_START( readmem_sound )
113 	{ 0x0000, 0x0fff, MRA_RAM },
114 	{ 0x9002, 0x9002, AY8910_read_port_0_r },
115 	{ 0xa002, 0xa002, AY8910_read_port_1_r },
116 	{ 0xf000, 0xffff, MRA_ROM },
117 MEMORY_END
118 
119 static MEMORY_WRITE_START( writemem_sound )
120 	{ 0x0000, 0x0fff, MWA_RAM },
121 	{ 0x9000, 0x9000, AY8910_control_port_0_w },
122 	{ 0x9001, 0x9001, AY8910_write_port_0_w },
123 	{ 0xa000, 0xa000, AY8910_control_port_1_w },
124 	{ 0xa001, 0xa001, AY8910_write_port_1_w },
125 	{ 0xf000, 0xffff, MWA_ROM },
126 MEMORY_END
127 
128 
129 
130 INPUT_PORTS_START( formatz )
131 	PORT_START      /* IN0 */
132 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY )
133 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY )
134 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY )
135 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY )
136 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 )
137 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 )
138 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_START1 )
139 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START2 )
140 
141 	PORT_START      /* IN1 */
142 	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_8WAY | IPF_COCKTAIL )
143 	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_8WAY | IPF_COCKTAIL )
144 	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_8WAY | IPF_COCKTAIL )
145 	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_8WAY | IPF_COCKTAIL )
146 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON2 | IPF_COCKTAIL )
147 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )
148 	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
149 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
150 
151 	PORT_START
152 	PORT_DIPNAME( 0x03, 0x00, DEF_STR( Lives ) )
153 	PORT_DIPSETTING(    0x00, "3" )
154 	PORT_DIPSETTING(    0x01, "4" )
155 	PORT_DIPSETTING(    0x02, "5" )
156 	PORT_BITX( 0,       0x03, IPT_DIPSWITCH_SETTING | IPF_CHEAT, "Infinite", IP_KEY_NONE, IP_JOY_NONE )
157 	PORT_DIPNAME( 0x0c, 0x0c, DEF_STR( Bonus_Life ) )
158 	PORT_DIPSETTING(    0x0c, "30000" )
159 	PORT_DIPSETTING(    0x08, "40000" )
160 	PORT_DIPSETTING(    0x04, "70000" )
161 	PORT_DIPSETTING(    0x00, "100000" )
162 	PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) )
163 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
164 	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
165 	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Demo_Sounds ) )
166 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
167 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
168 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Cabinet ) )
169 	PORT_DIPSETTING(    0x40, DEF_STR( Upright ) )
170 	PORT_DIPSETTING(    0x00, DEF_STR( Cocktail ) )
171 	/* The last dip switch is directly connected to the video hardware and
172 	   flips the screen. The program instead sees the coin input, which must
173 	   stay low for exactly 2 frames to be consistently recognized. */
174 	PORT_BIT_IMPULSE( 0x80, IP_ACTIVE_LOW, IPT_COIN1, 2 )
175 
176 	PORT_START
177 	PORT_DIPNAME( 0x07, 0x00, DEF_STR( Coinage ) )
178 	PORT_DIPSETTING(    0x07, DEF_STR( 5C_1C ) )
179 	PORT_DIPSETTING(    0x05, DEF_STR( 4C_1C ) )
180 	PORT_DIPSETTING(    0x03, DEF_STR( 3C_1C ) )
181 	PORT_DIPSETTING(    0x01, DEF_STR( 2C_1C ) )
182 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
183 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
184 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_3C ) )
185 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_4C ) )
186 	PORT_DIPNAME( 0x18, 0x08, DEF_STR( Difficulty ) )
187 	PORT_DIPSETTING(    0x00, "0(Easy)" )
188 	PORT_DIPSETTING(    0x08, "1(Medium)" )
189 	PORT_DIPSETTING(    0x10, "2(Hard)" )
190 	PORT_DIPSETTING(    0x18, "3(Hardest)" )
191 	PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) )
192 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
193 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
194 	PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) )
195 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
196 	PORT_DIPSETTING(    0x40, DEF_STR( On ) )
197 	PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) )
198 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
199 	PORT_DIPSETTING(    0x80, DEF_STR( On ) )
200 INPUT_PORTS_END
201 
202 
203 
204 static struct GfxLayout charlayout =
205 {
206 	8,8,
207 	RGN_FRAC(1,2),
208 	2,
209 	{ 4, 0 },
210 	{ 0, 1, 2, 3, RGN_FRAC(1,2)+0, RGN_FRAC(1,2)+1, RGN_FRAC(1,2)+2, RGN_FRAC(1,2)+3 },
211 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
212 	8*8
213 };
214 /*
215 // exact star layout unknown... could be anything
216 static struct GfxLayout starlayout =
217 {
218 	8,8,
219 	RGN_FRAC(1,1),
220 	1,
221 	{ 0 },
222 	{ 0, 1, 2, 3, 4, 5, 6, 7 },
223 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
224 	8*8
225 };
226 */
227 static struct GfxLayout spritelayout =
228 {
229 	8,16,
230 	RGN_FRAC(1,3),
231 	3,
232 	{ RGN_FRAC(2,3), RGN_FRAC(1,3), RGN_FRAC(0,3) },
233 	{ 0, 1, 2, 3, 4, 5, 6, 7 },
234 	{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
235 	  8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8 },
236 	16*8
237 };
238 
239 static struct GfxDecodeInfo gfxdecodeinfo[] =
240 {
241 	{ REGION_GFX1, 0, &charlayout,     0,  64 },     /* chars */
242 /*	{ REGION_GFX2, 0, &starlayout,     0, 128 },      // sky /*/
243 	{ REGION_GFX3, 0, &spritelayout,   0,   8 },
244 	{ -1 } /* end of array */
245 };
246 
247 
248 
249 static struct AY8910interface ay8910_interface =
250 {
251 	2,      /* 2 chips */
252 	1500000,	/* 1.5 MHz ? (hand tuned) */
253 	{ 25, 25 },
254 	{ soundlatch_r, 0 },    /* ? */
255 	{ soundlatch2_r, 0 },   /* ? */
256 	{ 0, 0 },
257 	{ 0, 0 }
258 };
259 
260 static MACHINE_DRIVER_START( formatz )
261 
262 	/* basic machine hardware */
263 	MDRV_CPU_ADD(M6809, 1250000) /* 1.25MHz*/
264 	MDRV_CPU_MEMORY(readmem,writemem)
265 	MDRV_CPU_VBLANK_INT(aeroboto_interrupt,1)
266 
267 	MDRV_CPU_ADD(M6809, 640000)
268 	MDRV_CPU_FLAGS(CPU_AUDIO_CPU)
269 	MDRV_CPU_MEMORY(readmem_sound,writemem_sound)
270 	MDRV_CPU_VBLANK_INT(irq0_line_hold,1)
271 
272 	MDRV_FRAMES_PER_SECOND(60)
273 	MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
274 
275 	/* video hardware */
276 	MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
277 	MDRV_GFXDECODE(gfxdecodeinfo)
278 
279 	MDRV_SCREEN_SIZE(32*8, 32*8)
280 	MDRV_VISIBLE_AREA(0*8, 31*8-1, 2*8, 30*8-1)
281 	MDRV_PALETTE_LENGTH(256)
282 
283 	MDRV_PALETTE_INIT(RRRR_GGGG_BBBB)
284 	MDRV_VIDEO_START(aeroboto)
285 	MDRV_VIDEO_UPDATE(aeroboto)
286 
287 	/* sound hardware */
288 	MDRV_SOUND_ADD(AY8910, ay8910_interface)
289 MACHINE_DRIVER_END
290 
291 
292 
293 /***************************************************************************
294 
295   Game driver(s)
296 
297 ***************************************************************************/
298 
299 ROM_START( formatz )
300 	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for main CPU */
301 	ROM_LOAD( "format_z.8",   0x4000, 0x4000, CRC(81a2416c) SHA1(d43c6bcc079847cb4c8e77fdc4d9d5bb9c2cc41a) )
302 	ROM_LOAD( "format_z.7",   0x8000, 0x4000, CRC(986e6052) SHA1(4d39eda38fa17695f8217b0032a750cbe71c5674) )
303 	ROM_LOAD( "format_z.6",   0xc000, 0x4000, CRC(baa0d745) SHA1(72b6cf31c9bbf9b5c55ef3f4ca5877ce576beda9) )
304 
305 	ROM_REGION( 0x10000, REGION_CPU2, 0 )     /* 64k for sound CPU */
306 	ROM_LOAD( "format_z.9",   0xf000, 0x1000, CRC(6b9215ad) SHA1(3ab416d070bf6b9a8be3e19d4dbc3a399d9ab5cb) )
307 
308 	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
309 	ROM_LOAD( "format_z.5",   0x0000, 0x2000, CRC(ba50be57) SHA1(aa37b644e8c1944b4c0ba81164d5a52be8ab491f) )  /* characters */
310 
311 	ROM_REGION( 0x2000, REGION_GFX2, 0 ) /* starfield data*/
312 	ROM_LOAD( "format_z.4",   0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) )  /* characters */
313 
314 	ROM_REGION( 0x3000, REGION_GFX3, ROMREGION_DISPOSE )
315 	ROM_LOAD( "format_z.1",   0x0000, 0x1000, CRC(5739afd2) SHA1(3a645bc8a5ac69f1dc878a589c580f2bf033d3cb) )  /* sprites */
316 	ROM_LOAD( "format_z.2",   0x1000, 0x1000, CRC(3a821391) SHA1(476507ba5e5d64ca3729244590beadb9b3a6a018) )  /* sprites */
317 	ROM_LOAD( "format_z.3",   0x2000, 0x1000, CRC(7d1aec79) SHA1(bb19d6c91a14df26706226cfe22853bb8383c63d) )  /* sprites */
318 
319 	ROM_REGION( 0x0300, REGION_PROMS, 0 )
320 	ROM_LOAD( "10c",          0x0000, 0x0100, CRC(b756dd6d) SHA1(ea79f87f84ded2f0a66458af24cbc792e5ff77e3) )
321 	ROM_LOAD( "10b",          0x0100, 0x0100, CRC(00df8809) SHA1(f4539c052a5ce8a63662db070c3f52139afef23d) )
322 	ROM_LOAD( "10a",          0x0200, 0x0100, CRC(e8733c8f) SHA1(105b44c9108ee173a417f8c79ec8381f824dd675) )
323 ROM_END
324 
325 ROM_START( aeroboto )
326 	ROM_REGION( 0x10000, REGION_CPU1, 0 )     /* 64k for main CPU */
327 	ROM_LOAD( "aeroboto.8",   0x4000, 0x4000, CRC(4d3fc049) SHA1(6efb8c58c025a69ac2dce99049128861f7ede690) )
328 	ROM_LOAD( "aeroboto.7",   0x8000, 0x4000, CRC(522f51c1) SHA1(4ea47d0b8b65e711c99701c055dbaf70a003d441) )
329 	ROM_LOAD( "aeroboto.6",   0xc000, 0x4000, CRC(1a295ffb) SHA1(990b3f2f883717c180089b6ba5ae381ed9272341) )
330 
331 	ROM_REGION( 0x10000, REGION_CPU2, 0 )     /* 64k for sound CPU */
332 	ROM_LOAD( "format_z.9",   0xf000, 0x1000, CRC(6b9215ad) SHA1(3ab416d070bf6b9a8be3e19d4dbc3a399d9ab5cb) )
333 
334 	ROM_REGION( 0x2000, REGION_GFX1, ROMREGION_DISPOSE )
335 	ROM_LOAD( "aeroboto.5",   0x0000, 0x2000, CRC(32fc00f9) SHA1(fd912fe2ab0101057c15c846f0cc4259cd94b035) )  /* characters */
336 
337 	ROM_REGION( 0x2000, REGION_GFX2, 0 ) /* starfield data*/
338 	ROM_LOAD( "format_z.4",   0x0000, 0x2000, CRC(910375a0) SHA1(1044e0f45ce34c15986d9ab520c0e7d08fd46dde) )  /* characters */
339 
340 	ROM_REGION( 0x3000, REGION_GFX3, ROMREGION_DISPOSE )
341 	ROM_LOAD( "aeroboto.1",   0x0000, 0x1000, CRC(7820eeaf) SHA1(dedd15295bb02f417d0f51a29df686b66b94dee1) )  /* sprites */
342 	ROM_LOAD( "aeroboto.2",   0x1000, 0x1000, CRC(c7f81a3c) SHA1(21476a4146d5c57e2b15125c304fc61d82edf4af) )  /* sprites */
343 	ROM_LOAD( "aeroboto.3",   0x2000, 0x1000, CRC(5203ad04) SHA1(d16eb370de9033793a502e23c82a3119cd633aa9) )  /* sprites */
344 
345 	ROM_REGION( 0x0300, REGION_PROMS, 0 )
346 	ROM_LOAD( "10c",          0x0000, 0x0100, CRC(b756dd6d) SHA1(ea79f87f84ded2f0a66458af24cbc792e5ff77e3) )
347 	ROM_LOAD( "10b",          0x0100, 0x0100, CRC(00df8809) SHA1(f4539c052a5ce8a63662db070c3f52139afef23d) )
348 	ROM_LOAD( "10a",          0x0200, 0x0100, CRC(e8733c8f) SHA1(105b44c9108ee173a417f8c79ec8381f824dd675) )
349 ROM_END
350 
351 
352 
353 GAMEX( 1984, formatz,  0,       formatz, formatz, 0, ROT0, "Jaleco", "Formation Z", GAME_IMPERFECT_GRAPHICS )
354 GAMEX( 1984, aeroboto, formatz, formatz, formatz, 0, ROT0, "[Jaleco] (Williams license)", "Aeroboto", GAME_IMPERFECT_GRAPHICS )
355