1 // license:BSD-3-Clause
2 // copyright-holders:hap
3 // thanks-to:Kevin Horton
4 /******************************************************************************
5
6 Parker Brothers Starting Lineup Talking Baseball
7
8 Hardware notes:
9 - PCB label KPT-349 REV 6C<1>
10 - 80C31 MCU @ 12MHz
11 - 2KB RAM, 128KB ROM, 2 cartridge slots
12 - 12 leds, 2 16-button keypads
13
14 ROM chip has (C) 1987 Tonka (Kenner Parker Toys was acquired by Tonka in 1987, Parker
15 Brothers itself was acquired by Kenner in 1985)
16
17 The speech driver is by Forrest S. Mozer's company.
18
19 The cartridge slots are for extra teams. There are around 8 cartridges, each one
20 included 3 or 4 baseball teams, with exception to the "Hall of Fame" cartridge.
21 Players enter a 3-digit code to select the team.
22
23 TODO:
24 - add cartridge slots
25 - Buttons are unresponsive at initial game setup, you need to hold the yes/no button
26 until it responds. The keypad reading routine is at $1A5D, it gets skipped for several
27 seconds at a time. Once in-game, everything is fine though. BTANB or different cause?
28
29 *******************************************************************************
30
31 Field positions (used when substituting):
32
33 1: Pitcher
34 2: Catcher
35 3: First Base
36 4: Second Base
37 5: Third Base
38 6: Shortstop
39 7: Left Field
40 8: Center Field
41 9: Right Field
42
43 The game includes baseball cards with player stats. At the very least, the roster
44 cards are needed to play the game properly. See below for the default teams.
45
46 American Team:
47 --------------
48
49 Starting lineup batting order:
50
51 1: #23 Rickey Henderson, CF
52 2: #14 Don Mattingly, 1B
53 3: #18 Wade Boggs, 3B
54 4: #22 George Bell, LF
55 5: #24 Dave Winfield, RF
56 6: #16 Cal Ripken, SS
57 7: #11 Terry Kennedy, C
58 8: #15 Willie Randolph, 2B
59 9: #20 Alan Trammell, SS & DH
60 10:#27 Roger Clemens, P
61
62 Substitutes:
63
64 #19: George Brett, 3B
65 #12: Carlton Fisk, C
66 #25: Jack Morris, P
67 #13: Eddie Murray, 1B
68 #21: Kirby Puckett, OF
69 #30: Dan Quisenberry, P
70 #29: Dave Righetti, P
71 #28: Bret Saberhagen, P
72 #17: Lou Whitaker, 2B
73 #26: Robin Yount, SS
74
75 National Team:
76 --------------
77
78 Starting lineup batting order:
79
80 1: #23: Tim Raines, LF
81 2: #16: Ryne Sandberg, 2B
82 3: #22: Darryl Strawberry, RF
83 4: #19: Mike Schmidt, 3B
84 5: #13: Jack Clark, 1B
85 6: #20: Eric Davis, CF
86 7: #11: Gary Carter, C
87 8: #17: Ozzie Smith, SS
88 9: #18: Dale Murphy, OF & DH
89 10:#25: Mike Scott, P
90
91 Substitutes:
92
93 #15: Buddy Bell, 3B
94 #26: Jody Davis, C
95 #24: Andre Dawson, CF
96 #29: Dwight Gooden, P
97 #21: Tony Gwynn, OF
98 #14: Keith Hernandez, 1B
99 #30: Nolan Ryan, P
100 #12: Steve Sax, 2B
101 #28: Fernando Valenzuela, P
102 #27: Todd Worrell, P
103
104 ******************************************************************************/
105
106 #include "emu.h"
107 #include "cpu/mcs51/mcs51.h"
108 #include "video/pwm.h"
109 #include "sound/dac.h"
110 #include "speaker.h"
111
112 // internal artwork
113 #include "talkingbb.lh"
114
115
116 namespace {
117
118 class talkingbb_state : public driver_device
119 {
120 public:
talkingbb_state(const machine_config & mconfig,device_type type,const char * tag)121 talkingbb_state(const machine_config &mconfig, device_type type, const char *tag) :
122 driver_device(mconfig, type, tag),
123 m_maincpu(*this, "maincpu"),
124 m_rom(*this, "maincpu"),
125 m_display(*this, "display"),
126 m_inputs(*this, "IN.%u", 0)
127 { }
128
129 void talkingbb(machine_config &config);
130
131 protected:
132 virtual void machine_start() override;
133
134 private:
135 // devices/pointers
136 required_device<mcs51_cpu_device> m_maincpu;
137 required_region_ptr<u8> m_rom;
138 required_device<pwm_display_device> m_display;
139 required_ioport_array<5> m_inputs;
140
141 void main_map(address_map &map);
142 void main_io(address_map &map);
143
144 u8 m_bank;
145 u8 m_inp_mux;
146
147 // I/O handlers
148 void bank_w(u8 data);
149 u8 bank_r(offs_t offset);
150 void input_w(u8 data);
151 u8 input_r();
152 u8 switch_r();
153 };
154
machine_start()155 void talkingbb_state::machine_start()
156 {
157 // zerofill
158 m_bank = 0;
159 m_inp_mux = 0;
160
161 // register for savestates
162 save_item(NAME(m_bank));
163 save_item(NAME(m_inp_mux));
164 }
165
166
167
168 /******************************************************************************
169 I/O
170 ******************************************************************************/
171
bank_w(u8 data)172 void talkingbb_state::bank_w(u8 data)
173 {
174 // d0-d1: upper rom bank
175 // d2-d4: upper rom enable (bus conflict possible)
176 // d2: internal rom, d3: cart slot 1, d4: cart slot 2
177 m_bank = data;
178 }
179
bank_r(offs_t offset)180 u8 talkingbb_state::bank_r(offs_t offset)
181 {
182 u32 hi = (~m_bank & 3) << 15;
183 u8 data = (m_bank & 4) ? 0xff : m_rom[offset | hi];
184
185 // TODO: cartridge
186
187 return data;
188 }
189
input_w(u8 data)190 void talkingbb_state::input_w(u8 data)
191 {
192 // no effect if P30 is low (never happens though)
193 if (~m_bank & 1)
194 return;
195
196 // d4-d7: led select (also input mux)
197 // d0-d2: led data
198 m_inp_mux = data >> 4;
199 m_display->matrix(m_inp_mux, ~data & 7);
200 }
201
input_r()202 u8 talkingbb_state::input_r()
203 {
204 // open bus if P30 is low (never happens though)
205 if (~m_bank & 1)
206 return 0xff;
207
208 u8 data = 0;
209
210 // multiplexed inputs
211 for (int i = 0; i < 4; i++)
212 if (BIT(m_inp_mux, i))
213 data |= m_inputs[i]->read();
214
215 return ~data;
216 }
217
switch_r()218 u8 talkingbb_state::switch_r()
219 {
220 // d5: mode switch
221 return ~m_inputs[4]->read();
222 }
223
224
225
226 /******************************************************************************
227 Address Maps
228 ******************************************************************************/
229
main_map(address_map & map)230 void talkingbb_state::main_map(address_map &map)
231 {
232 map(0x0000, 0x7fff).rom().region("maincpu", 0x18000);
233 map(0x8000, 0xffff).r(FUNC(talkingbb_state::bank_r));
234 }
235
main_io(address_map & map)236 void talkingbb_state::main_io(address_map &map)
237 {
238 map(0x0000, 0x07ff).mirror(0x7800).ram();
239 map(0x8000, 0x8000).mirror(0x7fff).rw(FUNC(talkingbb_state::input_r), FUNC(talkingbb_state::input_w));
240 }
241
242
243
244 /******************************************************************************
245 Input Ports
246 ******************************************************************************/
247
248 /* keypad layout: **** P1 = Batter **** | **** P2 = Pitcher ****
249 |
250 [PINCH [1 [2] [3 [TIME OUT] | [INFIELD [1 [2 [3 [TIME OUT]
251 HITTER] BUNT] POWER] | IN] FAST] CURVE] CHANGE]
252 |
253 [SCORE] [4] [5 [6] [NO | [SCORE] [4 [5 [6 [NO
254 SQUEEZE] CANCEL] | PTCHOUT] PICKOFF] INTWALK] CANCEL]
255 |
256 [PINCH [7 [8] [9 [YES | [INSTANT [7 [8] [9 [YES
257 RUNNER] STEAL] X-BASE] ENTER] | REPLAY] RELIEF] SUB] ENTER]
258 |
259 [0 | [0
260 SWING] | BALL]
261 */
262
263 static INPUT_PORTS_START( talkingbb )
264 PORT_START("IN.0")
PORT_CODE(KEYCODE_3)265 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3) PORT_CODE(KEYCODE_R) PORT_NAME("P1 3 / Power")
266 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6) PORT_CODE(KEYCODE_F) PORT_NAME("P1 6")
267 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9) PORT_CODE(KEYCODE_V) PORT_NAME("P1 9 / Extra Base")
268 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_MINUS) PORT_NAME("P1 Time Out")
269 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_3_PAD) PORT_CODE(KEYCODE_O) PORT_NAME("P2 3 / Change")
270 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_6_PAD) PORT_CODE(KEYCODE_L) PORT_NAME("P2 6 / Intentional Walk")
271 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_9_PAD) PORT_CODE(KEYCODE_STOP) PORT_NAME("P2 9 / Sub")
272 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("P2 Time Out")
273
274 PORT_START("IN.1")
275 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2) PORT_CODE(KEYCODE_E) PORT_NAME("P1 2")
276 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5) PORT_CODE(KEYCODE_D) PORT_NAME("P1 5 / Squeeze")
277 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8) PORT_CODE(KEYCODE_C) PORT_NAME("P1 8")
278 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_LALT) PORT_NAME("P1 0 / Swing")
279 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_2_PAD) PORT_CODE(KEYCODE_I) PORT_NAME("P2 2 / Curve")
280 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_5_PAD) PORT_CODE(KEYCODE_K) PORT_NAME("P2 5 / Pickoff")
281 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_8_PAD) PORT_CODE(KEYCODE_COMMA) PORT_NAME("P2 8")
282 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_0_PAD) PORT_CODE(KEYCODE_RALT) PORT_NAME("P2 0 / Ball")
283
284 PORT_START("IN.2")
285 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_W) PORT_NAME("P1 1 / Bunt")
286 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4) PORT_CODE(KEYCODE_S) PORT_NAME("P1 4")
287 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7) PORT_CODE(KEYCODE_X) PORT_NAME("P1 7 / Steal")
288 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("P1 No / Cancel")
289 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_1_PAD) PORT_CODE(KEYCODE_U) PORT_NAME("P2 1 / Fast")
290 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_4_PAD) PORT_CODE(KEYCODE_J) PORT_NAME("P2 4 / Pitchout")
291 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_7_PAD) PORT_CODE(KEYCODE_M) PORT_NAME("P2 7 / Relief")
292 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_DEL_PAD) PORT_NAME("P2 No / Cancel")
293
294 PORT_START("IN.3")
295 PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Q) PORT_NAME("P1 Pinch Hitter")
296 PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_A) PORT_NAME("P1 Score")
297 PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Z) PORT_NAME("P1 Pinch Runner")
298 PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("P1 Yes / Enter")
299 PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_Y) PORT_NAME("P2 Infield In")
300 PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_H) PORT_NAME("P2 Score")
301 PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_N) PORT_NAME("P2 Instant Replay")
302 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYPAD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("P2 Yes / Enter")
303
304 PORT_START("IN.4")
305 PORT_CONFNAME( 0x20, 0x00, "Mode" )
306 PORT_CONFSETTING( 0x00, "Player" )
307 PORT_CONFSETTING( 0x20, "Coach" )
308 INPUT_PORTS_END
309
310
311
312 /******************************************************************************
313 Machine Configs
314 ******************************************************************************/
315
316 void talkingbb_state::talkingbb(machine_config &config)
317 {
318 /* basic machine hardware */
319 I80C31(config, m_maincpu, 12_MHz_XTAL);
320 m_maincpu->set_addrmap(AS_PROGRAM, &talkingbb_state::main_map);
321 m_maincpu->set_addrmap(AS_IO, &talkingbb_state::main_io);
322 m_maincpu->port_out_cb<1>().set("dac", FUNC(dac_8bit_r2r_device::write));
323 m_maincpu->port_out_cb<3>().set(FUNC(talkingbb_state::bank_w));
324 m_maincpu->port_in_cb<3>().set(FUNC(talkingbb_state::switch_r));
325
326 /* video hardware */
327 PWM_DISPLAY(config, m_display).set_size(4, 3);
328 config.set_default_layout(layout_talkingbb);
329
330 /* sound hardware */
331 SPEAKER(config, "speaker").front_center();
332 DAC_8BIT_R2R(config, "dac").add_route(ALL_OUTPUTS, "speaker", 0.5);
333 }
334
335
336
337 /******************************************************************************
338 ROM Definitions
339 ******************************************************************************/
340
341 ROM_START( talkingbb )
342 ROM_REGION( 0x20000, "maincpu", 0 )
343 ROM_LOAD("sp17208-002", 0x0000, 0x20000, CRC(e0e56217) SHA1(24a06b5c94a5c750799f61e3eb865e02d6cea68a) ) // GM231000-110
344 ROM_END
345
346 } // anonymous namespace
347
348
349
350 /******************************************************************************
351 Drivers
352 ******************************************************************************/
353
354 // YEAR NAME PARENT CMP MACHINE INPUT CLASS INIT COMPANY, FULLNAME, FLAGS
355 CONS( 1988, talkingbb, 0, 0, talkingbb, talkingbb, talkingbb_state, empty_init, "Parker Brothers", "Starting Lineup Talking Baseball", MACHINE_SUPPORTS_SAVE )
356