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