1 /***************************************************************************
2
3 Atari Basketball hardware
4
5 driver by Mike Balfour
6
7 Games supported:
8 * Basketball
9
10 Known issues:
11 * none at this time
12
13 ****************************************************************************
14
15 Note: The original hardware uses the Player 1 and Player 2 Start buttons
16 as the Jump/Shoot buttons. I've taken button 1 and mapped it to the Start
17 buttons to keep people from getting confused.
18
19 If you have any questions about how this driver works, don't hesitate to
20 ask. - Mike Balfour (mab22@po.cwru.edu)
21
22 ***************************************************************************/
23
24 #include "driver.h"
25 #include "vidhrdw/generic.h"
26
27 extern UINT8 *bsktball_motion;
28
29 extern WRITE_HANDLER( bsktball_videoram_w );
30
31 extern VIDEO_START( bsktball );
32 extern VIDEO_UPDATE( bsktball );
33
34 extern WRITE_HANDLER( bsktball_nmion_w );
35 extern INTERRUPT_GEN( bsktball_interrupt );
36 extern WRITE_HANDLER( bsktball_ld1_w );
37 extern WRITE_HANDLER( bsktball_ld2_w );
38 extern READ_HANDLER( bsktball_in0_r );
39 extern WRITE_HANDLER( bsktball_led1_w );
40 extern WRITE_HANDLER( bsktball_led2_w );
41 extern WRITE_HANDLER( bsktball_bounce_w );
42 extern WRITE_HANDLER( bsktball_note_w );
43 extern WRITE_HANDLER( bsktball_noise_reset_w );
44
45 /*************************************
46 *
47 * Palette generation
48 *
49 *************************************/
50
51 static unsigned short colortable_source[] =
52 {
53 /* Playfield */
54 0x01, 0x00, 0x00, 0x00,
55 0x01, 0x03, 0x03, 0x03,
56
57 /* Motion */
58 0x01, 0x00, 0x00, 0x00,
59 0x01, 0x00, 0x01, 0x00,
60 0x01, 0x00, 0x02, 0x00,
61 0x01, 0x00, 0x03, 0x00,
62
63 0x01, 0x01, 0x00, 0x00,
64 0x01, 0x01, 0x01, 0x00,
65 0x01, 0x01, 0x02, 0x00,
66 0x01, 0x01, 0x03, 0x00,
67
68 0x01, 0x02, 0x00, 0x00,
69 0x01, 0x02, 0x01, 0x00,
70 0x01, 0x02, 0x02, 0x00,
71 0x01, 0x02, 0x03, 0x00,
72
73 0x01, 0x03, 0x00, 0x00,
74 0x01, 0x03, 0x01, 0x00,
75 0x01, 0x03, 0x02, 0x00,
76 0x01, 0x03, 0x03, 0x00,
77
78 0x01, 0x00, 0x00, 0x01,
79 0x01, 0x00, 0x01, 0x01,
80 0x01, 0x00, 0x02, 0x01,
81 0x01, 0x00, 0x03, 0x01,
82
83 0x01, 0x01, 0x00, 0x01,
84 0x01, 0x01, 0x01, 0x01,
85 0x01, 0x01, 0x02, 0x01,
86 0x01, 0x01, 0x03, 0x01,
87
88 0x01, 0x02, 0x00, 0x01,
89 0x01, 0x02, 0x01, 0x01,
90 0x01, 0x02, 0x02, 0x01,
91 0x01, 0x02, 0x03, 0x01,
92
93 0x01, 0x03, 0x00, 0x01,
94 0x01, 0x03, 0x01, 0x01,
95 0x01, 0x03, 0x02, 0x01,
96 0x01, 0x03, 0x03, 0x01,
97
98 0x01, 0x00, 0x00, 0x02,
99 0x01, 0x00, 0x01, 0x02,
100 0x01, 0x00, 0x02, 0x02,
101 0x01, 0x00, 0x03, 0x02,
102
103 0x01, 0x01, 0x00, 0x02,
104 0x01, 0x01, 0x01, 0x02,
105 0x01, 0x01, 0x02, 0x02,
106 0x01, 0x01, 0x03, 0x02,
107
108 0x01, 0x02, 0x00, 0x02,
109 0x01, 0x02, 0x01, 0x02,
110 0x01, 0x02, 0x02, 0x02,
111 0x01, 0x02, 0x03, 0x02,
112
113 0x01, 0x03, 0x00, 0x02,
114 0x01, 0x03, 0x01, 0x02,
115 0x01, 0x03, 0x02, 0x02,
116 0x01, 0x03, 0x03, 0x02,
117
118 0x01, 0x00, 0x00, 0x03,
119 0x01, 0x00, 0x01, 0x03,
120 0x01, 0x00, 0x02, 0x03,
121 0x01, 0x00, 0x03, 0x03,
122
123 0x01, 0x01, 0x00, 0x03,
124 0x01, 0x01, 0x01, 0x03,
125 0x01, 0x01, 0x02, 0x03,
126 0x01, 0x01, 0x03, 0x03,
127
128 0x01, 0x02, 0x00, 0x03,
129 0x01, 0x02, 0x01, 0x03,
130 0x01, 0x02, 0x02, 0x03,
131 0x01, 0x02, 0x03, 0x03,
132
133 0x01, 0x03, 0x00, 0x03,
134 0x01, 0x03, 0x01, 0x03,
135 0x01, 0x03, 0x02, 0x03,
136 0x01, 0x03, 0x03, 0x03,
137 };
138
PALETTE_INIT(bsktball)139 static PALETTE_INIT( bsktball )
140 {
141 palette_set_color(0,0x00,0x00,0x00); /* BLACK */
142 palette_set_color(1,0x80,0x80,0x80); /* LIGHT GREY */
143 palette_set_color(2,0x50,0x50,0x50); /* DARK GREY */
144 palette_set_color(3,0xff,0xff,0xff); /* WHITE */
145 memcpy(colortable,colortable_source,sizeof(colortable_source));
146 }
147
148
149
150 /*************************************
151 *
152 * Main CPU memory handlers
153 *
154 *************************************/
155
MEMORY_READ_START(readmem)156 static MEMORY_READ_START( readmem )
157 { 0x0000, 0x01ff, MRA_RAM }, /* Zero Page RAM */
158 { 0x0800, 0x0800, bsktball_in0_r },
159 { 0x0802, 0x0802, input_port_5_r },
160 { 0x0803, 0x0803, input_port_6_r },
161 { 0x1800, 0x1cff, MRA_RAM }, /* video ram */
162 { 0x2000, 0x3fff, MRA_ROM }, /* PROGRAM */
163 { 0xfff0, 0xffff, MRA_ROM }, /* PROM8 for 6502 vectors */
164 MEMORY_END
165
166
167 static MEMORY_WRITE_START( writemem )
168 { 0x0000, 0x01ff, MWA_RAM }, /* WRAM */
169 { 0x1000, 0x1000, MWA_NOP }, /* Timer Reset */
170 { 0x1010, 0x1010, bsktball_bounce_w }, /* Crowd Amp / Bounce */
171 { 0x1022, 0x1023, MWA_NOP }, /* Coin Counter */
172 { 0x1024, 0x1025, bsktball_led1_w }, /* LED 1 */
173 { 0x1026, 0x1027, bsktball_led2_w }, /* LED 2 */
174 { 0x1028, 0x1029, bsktball_ld1_w }, /* LD 1 */
175 { 0x102a, 0x102b, bsktball_ld2_w }, /* LD 2 */
176 { 0x102c, 0x102d, bsktball_noise_reset_w }, /* Noise Reset */
177 { 0x102e, 0x102f, bsktball_nmion_w }, /* NMI On */
178 { 0x1030, 0x1030, bsktball_note_w }, /* Music Ckt Note Dvsr */
179 { 0x1800, 0x1bbf, bsktball_videoram_w, &videoram }, /* DISPLAY */
180 { 0x1bc0, 0x1bff, MWA_RAM, &bsktball_motion },
181 { 0x2000, 0x3fff, MWA_ROM }, /* PROM1-PROM8 */
182 MEMORY_END
183
184
185
186 /*************************************
187 *
188 * Port definitions
189 *
190 *************************************/
191
192 INPUT_PORTS_START( bsktball )
193 PORT_START /* IN0 */
194 PORT_ANALOG( 0xFF, 0x00, IPT_TRACKBALL_X, 100, 10, 0, 0 ) /* Sensitivity, clip, min, max */
195
196 PORT_START /* IN0 */
197 PORT_ANALOG( 0xFF, 0x00, IPT_TRACKBALL_Y, 100, 10, 0, 0 )
198
199 PORT_START /* IN0 */
200 PORT_ANALOG( 0xFF, 0x00, IPT_TRACKBALL_X | IPF_PLAYER2, 100, 10, 0, 0 ) /* Sensitivity, clip, min, max */
201
202 PORT_START /* IN0 */
203 PORT_ANALOG( 0xFF, 0x00, IPT_TRACKBALL_Y | IPF_PLAYER2, 100, 10, 0, 0 )
204
205 PORT_START /* IN0 */
206 PORT_BIT ( 0x01, IP_ACTIVE_LOW, IPT_START1 )
207 PORT_BIT ( 0x02, IP_ACTIVE_LOW, IPT_START2 )
208 PORT_BIT ( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) /* SPARE */
209 PORT_BIT ( 0x08, IP_ACTIVE_LOW, IPT_BUTTON1 | IPF_PLAYER2 ) /* SPARE */
210 /* 0x10 - DR0 = PL2 H DIR */
211 /* 0x20 - DR1 = PL2 V DIR */
212 /* 0x40 - DR2 = PL1 H DIR */
213 /* 0x80 - DR3 = PL1 V DIR */
214
215 PORT_START /* IN2 */
216 PORT_BIT ( 0x01, IP_ACTIVE_HIGH, IPT_VBLANK )
217 PORT_BIT ( 0x02, IP_ACTIVE_LOW, IPT_TILT )
218 PORT_BIT ( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* SPARE */
219 PORT_BIT ( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* TEST STEP */
220 PORT_SERVICE( 0x10, IP_ACTIVE_LOW )
221 PORT_BIT ( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) /* COIN 0 */
222 PORT_BIT ( 0x40, IP_ACTIVE_LOW, IPT_COIN2 ) /* COIN 1 */
223 PORT_BIT ( 0x80, IP_ACTIVE_LOW, IPT_COIN1 ) /* COIN 2 */
224
225 PORT_START /* DSW */
226 PORT_DIPNAME( 0x07, 0x00, "Play Time per Credit" )
227 PORT_DIPSETTING( 0x07, DEF_STR( Free_Play ) )
228 PORT_DIPSETTING( 0x06, "2:30" )
229 PORT_DIPSETTING( 0x05, "2:00" )
230 PORT_DIPSETTING( 0x04, "1:30" )
231 PORT_DIPSETTING( 0x03, "1:15" )
232 PORT_DIPSETTING( 0x02, "0:45" )
233 PORT_DIPSETTING( 0x01, "0:30" )
234 PORT_DIPSETTING( 0x00, "1:00" )
235 PORT_DIPNAME( 0x18, 0x00, DEF_STR( Coinage ) )
236 PORT_DIPSETTING( 0x00, DEF_STR( 1C_1C ) )
237 PORT_DIPSETTING( 0x10, DEF_STR( 1C_4C ) )
238 PORT_DIPSETTING( 0x08, DEF_STR( 1C_5C ) )
239 PORT_DIPSETTING( 0x18, DEF_STR( 1C_6C ) )
240 PORT_DIPNAME( 0x20, 0x00, "Cost" )
241 PORT_DIPSETTING( 0x20, "Two Coin Minimum" )
242 PORT_DIPSETTING( 0x00, "One Coin Minimum" )
243 PORT_DIPNAME( 0xC0, 0x00, "Language" )
244 PORT_DIPSETTING( 0xC0, "German" )
245 PORT_DIPSETTING( 0x80, "French" )
246 PORT_DIPSETTING( 0x40, "Spanish" )
247 PORT_DIPSETTING( 0x00, "English" )
248 INPUT_PORTS_END
249
250
251
252 /*************************************
253 *
254 * Graphics layouts
255 *
256 *************************************/
257
258 static struct GfxLayout charlayout =
259 {
260 8,8,
261 64,
262 2,
263 { 0, 8*0x800 },
264 { 0, 1, 2, 3, 4, 5, 6, 7 },
265 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
266 8*8
267 };
268
269
270 static struct GfxLayout motionlayout =
271 {
272 8,32,
273 64,
274 2,
275 { 0, 8*0x800 },
276 { 0, 1, 2, 3, 4, 5, 6, 7 },
277 { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8,
278 8*8, 9*8, 10*8, 11*8, 12*8, 13*8, 14*8, 15*8,
279 16*8, 17*8, 18*8, 19*8, 20*8, 21*8, 22*8, 23*8,
280 24*8, 25*8, 26*8, 27*8, 28*8, 29*8, 30*8, 31*8 },
281 32*8
282 };
283
284
285 static struct GfxDecodeInfo gfxdecodeinfo[] =
286 {
287 { REGION_GFX1, 0x0600, &charlayout, 0x00, 0x02 },
288 { REGION_GFX1, 0x0000, &motionlayout, 0x08, 0x40 },
289 { -1 }
290 };
291
292
293 /************************************************************************/
294 /* bsktball Sound System Analog emulation */
295 /************************************************************************/
296
297 const struct discrete_lfsr_desc bsktball_lfsr={
298 16, /* Bit Length */
299 0, /* Reset Value */
300 0, /* Use Bit 0 as XOR input 0 */
301 14, /* Use Bit 14 as XOR input 1 */
302 DISC_LFSR_XNOR, /* Feedback stage1 is XNOR */
303 DISC_LFSR_OR, /* Feedback stage2 is just stage 1 output OR with external feed */
304 DISC_LFSR_REPLACE, /* Feedback stage3 replaces the shifted register contents */
305 0x000001, /* Everything is shifted into the first bit only */
306 0, /* Output is already inverted by XNOR */
307 15 /* Output bit */
308 };
309
310 /* Nodes - Inputs */
311 #define BSKTBALL_NOTE_DATA NODE_01
312 #define BSKTBALL_CROWD_DATA NODE_02
313 #define BSKTBALL_NOISE_EN NODE_03
314 #define BSKTBALL_BOUNCE_EN NODE_04
315 /* Nodes - Sounds */
316 #define BSKTBALL_NOISE NODE_10
317 #define BSKTBALL_BOUNCE_SND NODE_11
318 #define BSKTBALL_NOTE_SND NODE_12
319 #define BSKTBALL_CROWD_SND NODE_13
320
321 static DISCRETE_SOUND_START(bsktball_sound_interface)
322 /************************************************/
323 /* bsktball Effects Relataive Gain Table */
324 /* */
325 /* Effect V-ampIn Gain ratio Relative */
326 /* Note 3.8 47/47 1000.0 */
327 /* Bounce 3.8 47/47 1000.0 */
328 /* Crowd 3.8 47/220 213.6 */
329 /************************************************/
330
331 /************************************************/
332 /* Input register mapping for bsktball */
333 /************************************************/
334 /* NODE ADDR MASK GAIN OFFSET INIT */
335 DISCRETE_INPUT (BSKTBALL_NOTE_DATA, 0x00, 0x000f, 0.0)
336 DISCRETE_INPUTX(BSKTBALL_CROWD_DATA, 0x01, 0x000f, 213.6/15, 0, 0.0)
337 DISCRETE_INPUTX(BSKTBALL_BOUNCE_EN, 0x02, 0x000f, 1000.0/2, 0, 0.0)
338 DISCRETE_INPUT (BSKTBALL_NOISE_EN, 0x03, 0x000f, 0.0)
339
340 /************************************************/
341 /* Bounce is a trigger fed directly to the amp */
342 /************************************************/
343 DISCRETE_FILTER2(BSKTBALL_BOUNCE_SND, 1, BSKTBALL_BOUNCE_EN, 10.0, 5, DISC_FILTER_HIGHPASS) /* remove DC*/
344
345 /************************************************/
346 /* Crowd effect is variable amplitude, filtered */
347 /* random noise. */
348 /* LFSR clk = 256H = 15750.0Hz */
349 /************************************************/
350 DISCRETE_LFSR_NOISE(BSKTBALL_NOISE, BSKTBALL_NOISE_EN, BSKTBALL_NOISE_EN, 15750.0, BSKTBALL_CROWD_DATA, 0, 0, &bsktball_lfsr)
351 DISCRETE_FILTER2(BSKTBALL_CROWD_SND, 1, BSKTBALL_NOISE, 330.0, (1.0 / 7.6), DISC_FILTER_BANDPASS)
352
353 /************************************************/
354 /* Note sound is created by a divider circuit. */
355 /* The master clock is the 32H signal, which is */
356 /* 12.096MHz/128. This is then sent to a */
357 /* preloadable 8 bit counter, which loads the */
358 /* value from OUT30 when overflowing from 0xFF */
359 /* to 0x00. Therefore it divides by 2 (OUT30 */
360 /* = FE) to 256 (OUT30 = 00). */
361 /* There is also a final /2 stage. */
362 /* Note that there is no music disable line. */
363 /* When there is no music, the game sets the */
364 /* oscillator to 0Hz. (OUT30 = FF) */
365 /************************************************/
366 DISCRETE_ADDER2(NODE_20, 1, BSKTBALL_NOTE_DATA, 1) /* To get values of 1 - 256 */
367 DISCRETE_DIVIDE(NODE_21, 1, 12096000.0/128/2, NODE_20)
368 DISCRETE_SQUAREWAVE(BSKTBALL_NOTE_SND, BSKTBALL_NOTE_DATA, NODE_21, 1000, 50.0, 0, 0.0) /* NOTE=FF Disables audio */
369
370 DISCRETE_ADDER3(NODE_90, 1, BSKTBALL_BOUNCE_SND, BSKTBALL_NOTE_SND, BSKTBALL_CROWD_SND)
371 DISCRETE_GAIN(NODE_91, NODE_90, 65534.0/(1000.0+1000.0+213.6))
372 DISCRETE_OUTPUT(NODE_91, 100)
373 DISCRETE_SOUND_END
374
375
376 /*************************************
377 *
378 * Machine driver
379 *
380 *************************************/
381
382 static MACHINE_DRIVER_START( bsktball )
383
384 /* basic machine hardware */
385 MDRV_CPU_ADD(M6502,750000)
386 MDRV_CPU_MEMORY(readmem,writemem)
387 MDRV_CPU_VBLANK_INT(bsktball_interrupt,8)
388
389 MDRV_FRAMES_PER_SECOND(60)
390 MDRV_VBLANK_DURATION(DEFAULT_REAL_60HZ_VBLANK_DURATION)
391
392 /* video hardware */
393 MDRV_VIDEO_ATTRIBUTES(VIDEO_TYPE_RASTER)
394 MDRV_SCREEN_SIZE(32*8, 28*8)
395 MDRV_VISIBLE_AREA(0*8, 32*8-1, 0*8, 28*8-1)
396 MDRV_GFXDECODE(gfxdecodeinfo)
397 MDRV_PALETTE_LENGTH(4)
398 MDRV_COLORTABLE_LENGTH(sizeof(colortable_source) / sizeof(colortable_source[0]))
399
400 MDRV_PALETTE_INIT(bsktball)
401 MDRV_VIDEO_START(bsktball)
402 MDRV_VIDEO_UPDATE(bsktball)
403
404 /* sound hardware */
405 MDRV_SOUND_ADD_TAG("discrete", DISCRETE, bsktball_sound_interface)
406 MACHINE_DRIVER_END
407
408
409
410 /*************************************
411 *
412 * ROM definitions
413 *
414 *************************************/
415
416 ROM_START( bsktball )
417 ROM_REGION( 0x10000, REGION_CPU1, 0 ) /* 64k for code */
418 ROM_LOAD( "034765.d1", 0x2000, 0x0800, CRC(798cea39) SHA1(b1b709a74258b01b21d7c2038a3b6abe879944c5) )
419 ROM_LOAD( "034764.c1", 0x2800, 0x0800, CRC(a087109e) SHA1(f5d6dcccc4a54db35be3d8997bc51e73892747fb) )
420 ROM_LOAD( "034766.f1", 0x3000, 0x0800, CRC(a82e9a9f) SHA1(9aca236c5145c04a8aaebb316179482bbdc9ddfc) )
421 ROM_LOAD( "034763.b1", 0x3800, 0x0800, CRC(1fc69359) SHA1(a215ba3bb18ea2c57c443dfc4c4a0a3846bbedfe) )
422 ROM_RELOAD( 0xf800, 0x0800 )
423
424 ROM_REGION( 0x1000, REGION_GFX1, ROMREGION_DISPOSE )
425 ROM_LOAD( "034757.a6", 0x0000, 0x0800, CRC(010e8ad3) SHA1(43ce2c2089ec3011e2d28e8257a35efeed0e71c5) )
426 ROM_LOAD( "034758.b6", 0x0800, 0x0800, CRC(f7bea344) SHA1(df544bff67bb0334f77cef11792199d9c3f5fdf4) )
427 ROM_END
428
429
430
431 /*************************************
432 *
433 * Game drivers
434 *
435 *************************************/
436
437 GAME( 1979, bsktball, 0, bsktball, bsktball, 0, ROT0, "Atari", "Basketball" )
438