1 /***************************************************************************
2
3 Tank Battalion memory map (preliminary)
4
5 driver by Brad Oliver
6
7 $0000-$000f : bullet ram, first entry is player's bullet
8 $0010-$01ff : zero page & stack
9 $0200-$07ff : RAM
10 $0800-$0bff : videoram
11 $0c00-$0c1f : I/O
12
13 Read:
14 $0c00-$0c03 : p1 joystick
15 $0c04
16 $0c07 : stop at grid self-test if bit 7 is low
17 $0c0f : stop at first self-test if bit 7 is low
18
19 $0c18 : Cabinet, 0 = table, 1 = upright
20 $0c19-$0c1a : Coinage, 00 = free play, 01 = 2 coin 1 credit, 10 = 1 coin 2 credits, 11 = 1 coin 1 credit
21 $0c1b-$0c1c : Bonus, 00 = 10000, 01 = 15000, 10 = 20000, 11 = none
22 $0c1d : Tanks, 0 = 3, 1 = 2
23 $0c1e-$0c1f : ??
24
25 Write:
26 $0c00-$0c01 : p1/p2 start leds
27 $0c02 : ?? written to at end of IRQ, either 0 or 1 - coin counter?
28 $0c03 : ?? written to during IRQ if grid test is on
29 $0c08 : ?? written to during IRQ if grid test is on
30 $0c09 : Sound - coin ding
31 $0c0a : NMI enable (active low) ?? game only ??
32 $0c0b : Sound - background noise, 0 - low rumble, 1 - high rumble
33 $0c0c : Sound - player fire
34 $0c0d : Sound - explosion
35 $0c0f : NMI enable (active high) ?? demo only ??
36
37 $0c10 : IRQ ack ??
38 $0c18 : Watchdog ?? Not written to while game screen is up
39
40 $2000-$3fff : ROM
41
42 TODO:
43 . Resistor values on the color prom need to be verified
44
45 Changes:
46 28 Feb 98 LBO
47 . Fixed the coin interrupts
48 . Fixed the color issues, should be 100% if I guessed at the resistor values properly
49 . Fixed the 2nd player cocktail joystick, had the polarity reversed
50 . Hacked the sound sample triggers so they work better
51
52 Known issues:
53 . The 'moving' tank rumble noise seems to keep playing a second too long
54 . Sample support is all a crapshoot. I have no idea how it really works
55
56 ***************************************************************************/
57
58 #include "driver.h"
59 #include "vidhrdw/generic.h"
60 #include "cpu/m6502/m6502.h"
61
62 extern UINT8 *tankbatt_bulletsram;
63 extern size_t tankbatt_bulletsram_size;
64
65 static int tankbatt_nmi_enable; /* No need to init this - the game will set it on reset */
66 static int tankbatt_sound_enable;
67
68 extern WRITE_HANDLER( tankbatt_videoram_w );
69
70 extern PALETTE_INIT( tankbatt );
71 extern VIDEO_START( tankbatt );
72 extern VIDEO_UPDATE( tankbatt );
73
WRITE_HANDLER(tankbatt_led_w)74 WRITE_HANDLER( tankbatt_led_w )
75 {
76 set_led_status(offset,data & 1);
77 }
78
READ_HANDLER(tankbatt_in0_r)79 READ_HANDLER( tankbatt_in0_r )
80 {
81 int val;
82
83 val = readinputport(0);
84 return ((val << (7-offset)) & 0x80);
85 }
86
READ_HANDLER(tankbatt_in1_r)87 READ_HANDLER( tankbatt_in1_r )
88 {
89 int val;
90
91 val = readinputport(1);
92 return ((val << (7-offset)) & 0x80);
93 }
94
READ_HANDLER(tankbatt_dsw_r)95 READ_HANDLER( tankbatt_dsw_r )
96 {
97 int val;
98
99 val = readinputport(2);
100 return ((val << (7-offset)) & 0x80);
101 }
102
WRITE_HANDLER(tankbatt_interrupt_enable_w)103 WRITE_HANDLER( tankbatt_interrupt_enable_w )
104 {
105 tankbatt_nmi_enable = !data;
106 tankbatt_sound_enable = !data;
107 if (data != 0)
108 {
109 cpu_set_irq_line(0, 0, CLEAR_LINE);
110 cpu_set_nmi_line(0, CLEAR_LINE);
111 }
112 /* hack - turn off the engine noise if the normal game nmi's are disabled */
113 if (data) sample_stop (2);
114 /* interrupt_enable_w (offset, !data);*/
115 }
116
WRITE_HANDLER(tankbatt_demo_interrupt_enable_w)117 WRITE_HANDLER( tankbatt_demo_interrupt_enable_w )
118 {
119 tankbatt_nmi_enable = data;
120 if (data != 0)
121 {
122 cpu_set_irq_line(0, 0, CLEAR_LINE);
123 cpu_set_nmi_line(0, CLEAR_LINE);
124 }
125 /* interrupt_enable_w (offset, data);*/
126 }
127
WRITE_HANDLER(tankbatt_sh_expl_w)128 WRITE_HANDLER( tankbatt_sh_expl_w )
129 {
130 if (tankbatt_sound_enable)
131 sample_start (1, 3, 0);
132 }
133
WRITE_HANDLER(tankbatt_sh_engine_w)134 WRITE_HANDLER( tankbatt_sh_engine_w )
135 {
136 if (tankbatt_sound_enable)
137 {
138 if (data)
139 sample_start (2, 2, 1);
140 else
141 sample_start (2, 1, 1);
142 }
143 else sample_stop (2);
144 }
145
WRITE_HANDLER(tankbatt_sh_fire_w)146 WRITE_HANDLER( tankbatt_sh_fire_w )
147 {
148 if (tankbatt_sound_enable)
149 sample_start (0, 0, 0);
150 }
151
MEMORY_READ_START(readmem)152 static MEMORY_READ_START( readmem )
153 { 0x0000, 0x01ff, MRA_RAM },
154 { 0x0c00, 0x0c07, tankbatt_in0_r },
155 { 0x0c08, 0x0c0f, tankbatt_in1_r },
156 { 0x0c18, 0x0c1f, tankbatt_dsw_r },
157 { 0x0200, 0x0bff, MRA_RAM },
158 { 0x6000, 0x7fff, MRA_ROM },
159 { 0xf800, 0xffff, MRA_ROM }, /* for the reset / interrupt vectors */
160 MEMORY_END
161
162 static MEMORY_WRITE_START( writemem )
163 { 0x0010, 0x01ff, MWA_RAM },
164 { 0x0800, 0x0bff, tankbatt_videoram_w, &videoram },
165 { 0x0000, 0x000f, MWA_RAM, &tankbatt_bulletsram, &tankbatt_bulletsram_size },
166 { 0x0c18, 0x0c18, MWA_NOP }, /* watchdog ?? */
167 { 0x0c00, 0x0c01, tankbatt_led_w },
168 { 0x0c0a, 0x0c0a, tankbatt_interrupt_enable_w },
169 { 0x0c0b, 0x0c0b, tankbatt_sh_engine_w },
170 { 0x0c0c, 0x0c0c, tankbatt_sh_fire_w },
171 { 0x0c0d, 0x0c0d, tankbatt_sh_expl_w },
172 { 0x0c0f, 0x0c0f, tankbatt_demo_interrupt_enable_w },
173 { 0x0200, 0x07ff, MWA_RAM },
174 { 0x2000, 0x3fff, MWA_ROM },
175 MEMORY_END
176
177 INTERRUPT_GEN( tankbatt_interrupt )
178 {
179 if ((readinputport (0) & 0x60) == 0) cpu_set_irq_line(0,0,HOLD_LINE);
180 else if (tankbatt_nmi_enable) cpu_set_irq_line(0,IRQ_LINE_NMI,PULSE_LINE);
181 }
182
183 INPUT_PORTS_START( tankbatt )
184 PORT_START /* IN0 */
185 PORT_BIT ( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY )
186 PORT_BIT ( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY )
187 PORT_BIT ( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY )
188 PORT_BIT ( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY )
189 PORT_BIT ( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 )
190 PORT_BIT_IMPULSE( 0x60, IP_ACTIVE_LOW, IPT_COIN1, 2 )
191 PORT_BIT ( 0x80, IP_ACTIVE_LOW, IPT_TILT )
192
193 PORT_START /* IN1 */
194 PORT_BIT ( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP | IPF_4WAY | IPF_COCKTAIL )
195 PORT_BIT ( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT | IPF_4WAY | IPF_COCKTAIL )
196 PORT_BIT ( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN | IPF_4WAY | IPF_COCKTAIL )
197 PORT_BIT ( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT | IPF_4WAY | IPF_COCKTAIL )
198 PORT_BIT ( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_COCKTAIL )
199 PORT_BIT ( 0x20, IP_ACTIVE_LOW, IPT_START1 )
200 PORT_BIT ( 0x40, IP_ACTIVE_LOW, IPT_START2 )
201 PORT_SERVICE( 0x80, IP_ACTIVE_LOW )
202
203 PORT_START /* DSW */
204 PORT_DIPNAME( 0x01, 0x01, DEF_STR( Cabinet ) )
205 PORT_DIPSETTING( 0x01, DEF_STR( Upright ) )
206 PORT_DIPSETTING( 0x00, DEF_STR( Cocktail ) )
207 PORT_DIPNAME( 0x06, 0x06, DEF_STR( Coinage ) )
208 PORT_DIPSETTING( 0x04, DEF_STR( 2C_1C ) )
209 PORT_DIPSETTING( 0x06, DEF_STR( 1C_1C ) )
210 PORT_DIPSETTING( 0x02, DEF_STR( 1C_2C ) )
211 PORT_DIPSETTING( 0x00, DEF_STR( Free_Play ) )
212 PORT_DIPNAME( 0x18, 0x08, DEF_STR( Bonus_Life ) )
213 PORT_DIPSETTING( 0x00, "10000" )
214 PORT_DIPSETTING( 0x10, "15000" )
215 PORT_DIPSETTING( 0x08, "20000" )
216 PORT_DIPSETTING( 0x18, "None" )
217 PORT_DIPNAME( 0x20, 0x00, DEF_STR( Lives ) )
218 PORT_DIPSETTING( 0x20, "2" )
219 PORT_DIPSETTING( 0x00, "3" )
220 PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
221 PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
222 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
223 PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
224 PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
225 PORT_DIPSETTING( 0x00, DEF_STR( On ) )
226 INPUT_PORTS_END
227
228
229 static struct GfxLayout charlayout =
230 {
231 8,8, /* 8*8 characters */
232 256, /* 256 characters */
233 1, /* 1 bit per pixel */
234 { 0 }, /* only one bitplane */
235 { 0, 1, 2, 3, 4, 5, 6, 7 },
236 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
237 8*8 /* every char takes 8 consecutive bytes */
238 };
239
240 static struct GfxLayout bulletlayout =
241 {
242 /* there is no gfx ROM for this one, it is generated by the hardware */
243 3,3, /* 3*3 box */
244 1, /* just one */
245 1, /* 1 bit per pixel */
246 { 8*8 },
247 { 2, 2, 2 }, /* I "know" that this bit of the */
248 { 2, 2, 2 }, /* graphics ROMs is 1 */
249 0 /* no use */
250 };
251
252
253 static struct GfxDecodeInfo gfxdecodeinfo[] =
254 {
255 { REGION_GFX1, 0, &charlayout, 0, 64 },
256 { REGION_GFX1, 0, &bulletlayout, 0, 64 },
257 { -1 } /* end of array */
258 };
259
260
261
262 static const char *tankbatt_sample_names[] =
263 {
264 "*tankbatt",
265 "fire.wav",
266 "engine1.wav",
267 "engine2.wav",
268 "explode1.wav",
269 0 /* end of array */
270 };
271
272 static struct Samplesinterface samples_interface =
273 {
274 3, /* 3 channels */
275 25, /* volume */
276 tankbatt_sample_names
277 };
278
279
280
281 static MACHINE_DRIVER_START( tankbatt )
282
283 /* basic machine hardware */
284 MDRV_CPU_ADD(M6502, 1000000) /* 1 MHz ???? */
285 MDRV_CPU_MEMORY(readmem,writemem)
286 MDRV_CPU_VBLANK_INT(tankbatt_interrupt,1)
287
288 MDRV_FRAMES_PER_SECOND(60)
289 MDRV_VBLANK_DURATION(DEFAULT_60HZ_VBLANK_DURATION)
290
291 /* video hardware */
292 MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
293 MDRV_SCREEN_SIZE(32*8, 32*8)
294 MDRV_VISIBLE_AREA(0*8, 32*8-1, 2*8, 30*8-1)
295 MDRV_GFXDECODE(gfxdecodeinfo)
296 MDRV_PALETTE_LENGTH(65)
297 MDRV_COLORTABLE_LENGTH(128)
298
299 MDRV_PALETTE_INIT(tankbatt)
300 MDRV_VIDEO_START(tankbatt)
301 MDRV_VIDEO_UPDATE(tankbatt)
302
303 /* sound hardware */
304 MDRV_SOUND_ADD(SAMPLES, samples_interface)
305 MACHINE_DRIVER_END
306
307
308
309 /***************************************************************************
310
311 Game driver(s)
312
313 ***************************************************************************/
314
315 ROM_START( tankbatt )
316 ROM_REGION( 0x10000, REGION_CPU1, 0 ) /* 64k for code */
317 ROM_LOAD( "tb1-1.bin", 0x6000, 0x0800, CRC(278a0b8c) SHA1(11ea8fe8401b3cd986616a30a759c0ac1a5ce73b) )
318 ROM_LOAD( "tb1-2.bin", 0x6800, 0x0800, CRC(e0923370) SHA1(8d3dbea877bed9f9c267d8002dc180f6eb1e5a8f) )
319 ROM_LOAD( "tb1-3.bin", 0x7000, 0x0800, CRC(85005ea4) SHA1(91583081803a5ef600fb90bee34be9edd87f157e) )
320 ROM_LOAD( "tb1-4.bin", 0x7800, 0x0800, CRC(3dfb5bcf) SHA1(aa24bf74f4d5dc81baf3843196c837e0b731077b) )
321 ROM_RELOAD( 0xf800, 0x0800 ) /* for the reset and interrupt vectors */
322
323 ROM_REGION( 0x0800, REGION_GFX1, ROMREGION_DISPOSE )
324 ROM_LOAD( "tb1-5.bin", 0x0000, 0x0800, CRC(aabd4fb1) SHA1(5cff659b531d0f1b6faa503f7c06045c3a209a84) )
325
326 ROM_REGION( 0x0100, REGION_PROMS, 0 )
327 ROM_LOAD( "tankbatt.clr", 0x0000, 0x0100, CRC(1150d613) SHA1(33bb50c199198ba5a129b9e3cfd0f8afca4bf95f) )
328 ROM_END
329
330
331
332 GAME( 1980, tankbatt, 0, tankbatt, tankbatt, 0, ROT90, "Namco", "Tank Battalion" )
333