1 // license:BSD-3-Clause
2 // copyright-holders:Tomasz Slanina
3 /*
4 BMC Bowling (c) 1994.05 BMC, Ltd
5 
6 - TS 2004.10.22
7 
8   Game is almost playable, especially with NVRAM_HACK (undefine it
9   to get real nvram  access, but sometimes it's impossible to get back to
10   title screen ).
11 
12  Controls:
13 
14  press START(1) OR BUTTON1 to start game , also START(1) or BUTTON1 to bowl / start
15         ( 5 to insert coin(s) , B to bet , D to pay out (?)  etc...)
16 
17  press ANALIZER(0) durning boot to enter test menu, then :
18             STOP1+STOP2 - sound test menu
19         BIG(G) - cycle options ,
20         DOUBLE(H) - play
21             STOP1(X),STOP2(C) - change
22             TAKE(A) - color test
23             START(1) - exit
24         BET(B)+START(1) - other tests
25         START(1) - next test
26 
27  press START(1)+HP(S) during boot to see stats
28 
29  press CONFIRM(N) during boot, to enter    settings
30         BET(B) - change page
31         STOP1(X)/STOP3(V) - modify
32         START(1)/SMALL(F) - move
33         KEY DOWN(D) - default ?
34 
35 TODO:
36 
37  - scroll (writes to $91800 and VIA port A - not used in game (only in test mode))
38  - VIA 6522(ports)
39  - Crt
40  - interrupts
41  - missing gfx elements
42 
43 ---
44 
45 Chips:
46 MC68000P10
47 Goldstar GM68B45S (same as Hitachi HD6845 CTR Controller)*
48 Winbond WF19054 (same as AY3-8910)
49 MK28 (appears to be a AD-65, AKA OKI6295) next to rom 10
50 Synertek SY6522 VIA
51 9325-AG (Elliptical Filter)
52 KDA0476BCN-66 (RAMDAC)
53 part # scratched 64 pin PLCC next to 7EX & 8 EX
54 
55 Ram:
56 Goldstar GM76C28A (2Kx8 SRAM) x3
57 HM62256LP-12 x6
58 
59 OSC:
60 GREAT1 21.47727
61 13.3M
62 3.579545
63 
64 DIPS:
65 Place for 4 8 switch dips
66 dips 1 & 3 are all connected via resistors
67 dips 2 & 4 are standard 8 switch dips
68 
69 EPROM        Label         Use
70 ----------------------------------------
71 ST M27C1001  bmc_8ex.bin - 68K code 0x00
72 ST M27C1001  bmc_7ex.bin - 68K code 0x01
73 ST M27C512   bmc_3.bin\
74 ST M27C512   bmc_4.bin | Graphics
75 ST M27C512   bmc_5.bin |
76 ST M27C512   bmc_6.bin/
77 HM27C101AG   bmc_10.bin - Sound samples
78 
79 BrianT
80 
81 Top board:
82           --- Edge Connection ---
83 GS9403      7EX    8EX   Part #      Misc HD74LS374p
84                          Scratched   HM62256   HM62256
85                          PLC
86   OKI                                ST T74L6245BI
87                   PEEl 18CV8P
88           10
89 
90 
91 
92 Main board:
93           --- Edge Connection ---              JAMMA Connection
94   68K     GM76C28A         3   5   GMC76C28A
95           GM76C28A         4   6   GM68B45S   BATTERY
96 
97 21.47727MHz                                 WF19054
98                                                       DIP1
99 13.3Mhz                                               DIP2
100   SY6522            HM62256 x4  3.579545MHz 9325-AG   DIP3
101                                    KDA0476BCN-66      DIP4
102 */
103 
104 #include "emu.h"
105 #include "cpu/m68000/m68000.h"
106 #include "machine/6522via.h"
107 #include "machine/nvram.h"
108 #include "sound/ay8910.h"
109 #include "sound/okim6295.h"
110 #include "sound/ym2413.h"
111 #include "video/ramdac.h"
112 #include "emupal.h"
113 #include "screen.h"
114 #include "speaker.h"
115 
116 #define NVRAM_HACK
117 
118 
119 class bmcbowl_state : public driver_device
120 {
121 public:
bmcbowl_state(const machine_config & mconfig,device_type type,const char * tag)122 	bmcbowl_state(const machine_config &mconfig, device_type type, const char *tag) :
123 		driver_device(mconfig, type, tag),
124 		m_maincpu(*this, "maincpu"),
125 		m_stats_ram(*this, "nvram", 16),
126 		m_vid1(*this, "vid1"),
127 		m_vid2(*this, "vid2"),
128 		m_palette(*this, "palette"),
129 		m_input(*this, "IN%u", 1)
130 	{ }
131 
132 	void bmcbowl(machine_config &config);
133 
134 private:
135 	virtual void machine_start() override;
136 	virtual void machine_reset() override;
137 
138 	uint8_t random_read();
139 	uint16_t protection_r();
140 	void scroll_w(uint16_t data);
141 	void via_a_out(uint8_t data);
142 	void via_b_out(uint8_t data);
143 	DECLARE_WRITE_LINE_MEMBER(via_ca2_out);
144 	uint8_t dips1_r();
145 	void input_mux_w(uint8_t data);
146 	void int_ack_w(uint8_t data);
147 	uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
148 	void init_stats(const uint8_t *table, int table_len, int address);
149 	void main_mem(address_map &map);
150 	void ramdac_map(address_map &map);
151 
152 	required_device<cpu_device> m_maincpu;
153 	optional_shared_ptr<uint8_t> m_stats_ram;
154 	required_shared_ptr<uint16_t> m_vid1;
155 	required_shared_ptr<uint16_t> m_vid2;
156 	required_device<palette_device> m_palette;
157 
158 	required_ioport_array<2> m_input;
159 	uint8_t m_selected_input;
160 };
161 
162 
screen_update(screen_device & screen,bitmap_rgb32 & bitmap,const rectangle & cliprect)163 uint32_t bmcbowl_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
164 {
165 /*
166       280x230,4 bitmap layers, 8bpp,
167         missing scroll and priorities   (maybe fixed ones)
168 */
169 
170 	bitmap.fill(rgb_t::black(), cliprect);
171 
172 	int z=0;
173 	for (int y=0; y<230; y++)
174 	{
175 		for (int x=0; x<280; x+=2)
176 		{
177 			int pixdat;
178 
179 			pixdat = m_vid2[0x8000+z];
180 
181 			if(pixdat&0xff)
182 				bitmap.pix(y, x+1) = m_palette->pen(pixdat&0xff);
183 			if(pixdat>>8)
184 				bitmap.pix(y, x) = m_palette->pen(pixdat>>8);
185 
186 			pixdat = m_vid2[z];
187 
188 			if(pixdat&0xff)
189 				bitmap.pix(y, x+1) = m_palette->pen(pixdat&0xff);
190 			if(pixdat>>8)
191 				bitmap.pix(y, x) = m_palette->pen(pixdat>>8);
192 
193 			pixdat = m_vid1[0x8000+z];
194 
195 			if(pixdat&0xff)
196 				bitmap.pix(y, x+1) = m_palette->pen(pixdat&0xff);
197 			if(pixdat>>8)
198 				bitmap.pix(y, x) = m_palette->pen(pixdat>>8);
199 
200 			pixdat = m_vid1[z];
201 
202 			if(pixdat&0xff)
203 				bitmap.pix(y, x+1) = m_palette->pen(pixdat&0xff);
204 			if(pixdat>>8)
205 				bitmap.pix(y, x) = m_palette->pen(pixdat>>8);
206 
207 			z++;
208 		}
209 	}
210 	return 0;
211 }
212 
random_read()213 uint8_t bmcbowl_state::random_read()
214 {
215 	return machine().rand();
216 }
217 
protection_r()218 uint16_t bmcbowl_state::protection_r()
219 {
220 	switch(m_maincpu->pcbase())
221 	{
222 		case 0xca68:
223 			switch(m_maincpu->state_int(M68K_D2))
224 			{
225 				case 0:          return 0x37<<8;
226 				case 0x1013: return 0;
227 				default:         return 0x46<<8;
228 			}
229 	}
230 	logerror("Protection read @ %X\n",m_maincpu->pcbase());
231 	return machine().rand();
232 }
233 
scroll_w(uint16_t data)234 void bmcbowl_state::scroll_w(uint16_t data)
235 {
236 	//TODO - scroll
237 }
238 
via_a_out(uint8_t data)239 void bmcbowl_state::via_a_out(uint8_t data)
240 {
241 	// related to video hw ? BG scroll ?
242 }
243 
via_b_out(uint8_t data)244 void bmcbowl_state::via_b_out(uint8_t data)
245 {
246 	//used
247 }
248 
WRITE_LINE_MEMBER(bmcbowl_state::via_ca2_out)249 WRITE_LINE_MEMBER(bmcbowl_state::via_ca2_out)
250 {
251 	//used
252 }
253 
254 
255 // 'working' NVRAM
256 
257 #ifdef NVRAM_HACK
258 static const uint8_t bmc_nv1[]=
259 {
260 	0x00,0x00,0x55,0x55,0x00,0x00,0x55,0x55,0x00,0x00,0x55,0x55,0x00,0x00,0x55,0x55,0x13,0x88,0x46,0xDD,0x0F,0xA0,
261 	0x5A,0xF5,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x6E,0x55,
262 	0x55,0x55,0x3B,0x00,0x00,0x00,0x06,0x55,0x55,0x55,0x53,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,
263 	0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x6E,0x55,0x55,0x55,0x3B,0x00,0x00,0x00,0x06,0x55,0x55,0x55,0x53,0x00,
264 	0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,
265 	0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x55,0x55,0x55,0x55,0xFF,0x00,0x0A,0x00,0x0A,
266 	0x00,0x32,0x00,0x02,0x28,0x32,0x5C,0x0A,0x03,0x03,0xD6,0x66,0xFF,0xFF,0xFF,0xFF,0x5D,0xED,0xFF,0xFF,0xFF,0xFF,
267 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
268 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
269 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
270 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
271 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x25,0xD5,0x25,0x1C,0x00,0x00,0x00,0x00,
272 	0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,
273 	0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
274 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,
275 	0x00,0x00,0x00,0x96,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
276 	0x00,0x00,0xDC,0x00,0xFF,0xFF,0xFF,0xFF
277 };
278 
279 static const uint8_t bmc_nv2[]=
280 {
281 	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
282 	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x03,0x00,0x09,0x00,0x00,0x2B,0xF1,
283 	0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
284 };
285 
286 static const uint8_t bmc_nv3[]=
287 {
288 	0xFA,0xFF,0x01,0x02,0x04,0x0A,0x1E,0xC8,0x02,0x01,0xFF,0xFF,0xFF,0xFF,0xFF
289 };
290 
291 
init_stats(const uint8_t * table,int table_len,int address)292 void bmcbowl_state::init_stats(const uint8_t *table, int table_len, int address)
293 {
294 	for (int i = 0; i < table_len; i++)
295 		m_stats_ram[address+2*i]=table[i];
296 }
297 #endif
298 
int_ack_w(uint8_t data)299 void bmcbowl_state::int_ack_w(uint8_t data)
300 {
301 	m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE);
302 }
303 
machine_start()304 void bmcbowl_state::machine_start()
305 {
306 	save_item(NAME(m_selected_input));
307 }
308 
machine_reset()309 void bmcbowl_state::machine_reset()
310 {
311 #ifdef NVRAM_HACK
312 	for (int i = 0; i < m_stats_ram.bytes(); i++)
313 		m_stats_ram[i] = 0xff;
314 
315 	init_stats(bmc_nv1,ARRAY_LENGTH(bmc_nv1),0);
316 	init_stats(bmc_nv2,ARRAY_LENGTH(bmc_nv2),0x3b0);
317 	init_stats(bmc_nv3,ARRAY_LENGTH(bmc_nv3),0xfe2);
318 #endif
319 }
320 
main_mem(address_map & map)321 void bmcbowl_state::main_mem(address_map &map)
322 {
323 	map(0x000000, 0x01ffff).rom();
324 
325 	map(0x090001, 0x090001).w("ramdac", FUNC(ramdac_device::index_w));
326 	map(0x090003, 0x090003).w("ramdac", FUNC(ramdac_device::pal_w));
327 	map(0x090005, 0x090005).w("ramdac", FUNC(ramdac_device::mask_w));
328 
329 	map(0x090800, 0x090803).nopw();
330 	map(0x091000, 0x091001).nopw();
331 	map(0x091800, 0x091801).w(FUNC(bmcbowl_state::scroll_w));
332 
333 	map(0x092000, 0x09201f).m("via6522_0", FUNC(via6522_device::map)).umask16(0x00ff);
334 
335 	map(0x093000, 0x093003).w("ymsnd", FUNC(ym2413_device::write)).umask16(0x00ff);
336 	map(0x092800, 0x092803).w("aysnd", FUNC(ay8910_device::data_address_w)).umask16(0xff00);
337 	map(0x092802, 0x092802).r("aysnd", FUNC(ay8910_device::data_r));
338 	map(0x093802, 0x093803).portr("IN0");
339 	map(0x095000, 0x095fff).ram().share("nvram"); /* 8 bit */
340 	map(0x097000, 0x097001).nopr();
341 	map(0x140000, 0x1bffff).rom();
342 	map(0x1c0000, 0x1effff).ram().share("vid1");
343 	map(0x1f0000, 0x1fffff).ram();
344 	map(0x200000, 0x21ffff).ram().share("vid2");
345 
346 	map(0x28c000, 0x28c000).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
347 
348 	/* protection device*/
349 	map(0x30c000, 0x30c001).nopw();
350 	map(0x30c040, 0x30c041).nopw();
351 	map(0x30c080, 0x30c081).nopw();
352 	map(0x30c0c0, 0x30c0c1).nopw();
353 	map(0x30c100, 0x30c101).r(FUNC(bmcbowl_state::protection_r));
354 	map(0x30c140, 0x30c141).nopw();
355 	map(0x30ca01, 0x30ca01).rw(FUNC(bmcbowl_state::random_read), FUNC(bmcbowl_state::int_ack_w));
356 }
357 
358 
359 static INPUT_PORTS_START( bmcbowl )
360 	PORT_START("IN0")   /* DSW 1 */
361 	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Note")
362 	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Analizer")
363 
PORT_CODE(KEYCODE_M)364 	PORT_BIT(0x0002, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Pay") PORT_CODE(KEYCODE_M)
365 	PORT_BIT(0x0004, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Stop") PORT_CODE(KEYCODE_Z)
366 	PORT_BIT(0x0010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Stop 1") PORT_CODE(KEYCODE_X)
367 	PORT_BIT(0x0008, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Stop 2") PORT_CODE(KEYCODE_C)
368 	PORT_BIT(0x0020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Stop 3") PORT_CODE(KEYCODE_V)
369 	PORT_BIT(0x0100, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Bet") PORT_CODE(KEYCODE_B)
370 	PORT_BIT(0x0400, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Confirm") PORT_CODE(KEYCODE_N)
371 
372 
373 	PORT_BIT(0x0040, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Start")
374 	PORT_BIT(0x0080, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Take") PORT_CODE(KEYCODE_A)
375 	PORT_BIT(0x0200, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("HP") PORT_CODE(KEYCODE_S)
376 	PORT_BIT(0x0800, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Key Down") PORT_CODE(KEYCODE_D)
377 	PORT_BIT(0x2000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Small") PORT_CODE(KEYCODE_F)
378 	PORT_BIT(0x4000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Big") PORT_CODE(KEYCODE_G)
379 	PORT_BIT(0x8000, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Double") PORT_CODE(KEYCODE_H)
380 
381 	PORT_START("IN1")   /* DSW 2 */
382 	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Coinage ) )
383 	PORT_DIPSETTING(    0x20, "1 COIN 10 CREDITS" )
384 	PORT_DIPSETTING(    0x00, "2 COINS 10 CREDITS" )
385 
386 	PORT_DIPNAME( 0x01, 0x00, "DSW2 8" )
387 	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
388 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
389 	PORT_DIPNAME( 0x02, 0x00, "DSW2 7" )
390 	PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
391 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
392 	PORT_DIPNAME( 0x04, 0x00, "DSW2 6" )
393 	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
394 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
395 	PORT_DIPNAME( 0x08, 0x00, "DSW2 5" )
396 	PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
397 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
398 	PORT_DIPNAME( 0x10, 0x00, "DSW2 4" )
399 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
400 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
401 
402 	PORT_DIPNAME( 0x40, 0x00, "DSW2 2" )
403 	PORT_DIPSETTING(    0x040, DEF_STR( Off ) )
404 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
405 	PORT_DIPNAME( 0x80, 0x00, "DSW2 1" )
406 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
407 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
408 
409 	PORT_START("IN2")   /* DSW 4 */
410 	PORT_DIPNAME( 0x01, 0x00, "DSW4 8" )
411 	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
412 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
413 	PORT_DIPNAME( 0x02, 0x00, "DSW4 7" )
414 	PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
415 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
416 	PORT_DIPNAME( 0x04, 0x00, "DSW4 6" )
417 	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
418 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
419 	PORT_DIPNAME( 0x08, 0x00, "DSW4 5" )
420 	PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
421 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
422 	PORT_DIPNAME( 0x10, 0x00, "DSW4 4" )
423 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
424 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
425 	PORT_DIPNAME( 0x20, 0x00, "DSW4 3" )
426 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
427 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
428 	PORT_DIPNAME( 0x40, 0x00, "DSW4 2" )
429 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
430 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
431 	PORT_DIPNAME( 0x80, 0x00, "DSW4 1" )
432 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
433 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
434 
435 	PORT_START("IN3")
436 	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_IMPULSE(1)
437 	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
438 	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen")
439 
440 INPUT_PORTS_END
441 
442 uint8_t bmcbowl_state::dips1_r()
443 {
444 	switch(m_selected_input)
445 	{
446 		case 0x00: return m_input[0]->read();
447 		case 0x40: return m_input[1]->read();
448 	}
449 	logerror("%s: unknown input - %X\n", machine().describe_context(), m_selected_input);
450 	return 0xff;
451 }
452 
453 
input_mux_w(uint8_t data)454 void bmcbowl_state::input_mux_w(uint8_t data)
455 {
456 	m_selected_input = data;
457 }
458 
ramdac_map(address_map & map)459 void bmcbowl_state::ramdac_map(address_map &map)
460 {
461 	map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb666_w));
462 }
463 
bmcbowl(machine_config & config)464 void bmcbowl_state::bmcbowl(machine_config &config)
465 {
466 	M68000(config, m_maincpu, XTAL(21'477'272) / 2);
467 	m_maincpu->set_addrmap(AS_PROGRAM, &bmcbowl_state::main_mem);
468 
469 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
470 	screen.set_refresh_hz(60);
471 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
472 	screen.set_size(35*8, 30*8);
473 	screen.set_visarea(0*8, 35*8-1, 0*8, 29*8-1);
474 	screen.set_screen_update(FUNC(bmcbowl_state::screen_update));
475 	screen.screen_vblank().set_inputline(m_maincpu, M68K_IRQ_2, ASSERT_LINE); // probably not the source of this interrupt
476 	screen.screen_vblank().append("via6522_0", FUNC(via6522_device::write_cb1));
477 
478 	PALETTE(config, m_palette).set_entries(256);
479 	ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette));
480 	ramdac.set_addrmap(0, &bmcbowl_state::ramdac_map);
481 
482 	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
483 
484 	SPEAKER(config, "lspeaker").front_left();
485 	SPEAKER(config, "rspeaker").front_right();
486 
487 	ym2413_device &ymsnd(YM2413(config, "ymsnd", XTAL(3'579'545)));  // guessed chip type, clock not verified
488 	ymsnd.add_route(ALL_OUTPUTS, "lspeaker", 0.50);
489 	ymsnd.add_route(ALL_OUTPUTS, "rspeaker", 0.50);
490 
491 	ay8910_device &aysnd(AY8910(config, "aysnd", XTAL(3'579'545) / 2));
492 	aysnd.port_a_read_callback().set(FUNC(bmcbowl_state::dips1_r));
493 	aysnd.port_b_write_callback().set(FUNC(bmcbowl_state::input_mux_w));
494 	aysnd.add_route(ALL_OUTPUTS, "lspeaker", 0.50);
495 	aysnd.add_route(ALL_OUTPUTS, "rspeaker", 0.50);
496 
497 	okim6295_device &oki(OKIM6295(config, "oki", 1122000, okim6295_device::PIN7_HIGH)); // clock frequency & pin 7 not verified
498 	oki.add_route(ALL_OUTPUTS, "lspeaker", 0.50);
499 	oki.add_route(ALL_OUTPUTS, "rspeaker", 0.50);
500 
501 	/* via */
502 	via6522_device &via(VIA6522(config, "via6522_0", XTAL(3'579'545) / 4)); // clock not verified (controls music tempo)
503 	via.readpb_handler().set_ioport("IN3");
504 	via.writepa_handler().set(FUNC(bmcbowl_state::via_a_out));
505 	via.writepb_handler().set(FUNC(bmcbowl_state::via_b_out));
506 	via.ca2_handler().set(FUNC(bmcbowl_state::via_ca2_out));
507 	via.irq_handler().set_inputline(m_maincpu, M68K_IRQ_4);
508 }
509 
510 ROM_START( bmcbowl )
511 	ROM_REGION( 0x200000, "maincpu", 0 ) /* 68000 Code */
512 	ROM_LOAD16_BYTE( "bmc_8ex.bin", 0x000000, 0x10000, CRC(8b1aa5db) SHA1(879df950bedf2c163ba89d983ca4a0691b01c46e) )
513 	ROM_LOAD16_BYTE( "bmc_7ex.bin", 0x000001, 0x10000, CRC(7726d47a) SHA1(8438c3345847c2913c640a29145ec8502f6b01e7) )
514 
515 	ROM_LOAD16_BYTE( "bmc_4.bin", 0x140000, 0x10000, CRC(f43880d6) SHA1(9e73a29baa84d417ff88026896d852567a38e714) )
516 	ROM_RELOAD(0x160000,0x10000)
517 	ROM_LOAD16_BYTE( "bmc_3.bin", 0x140001, 0x10000, CRC(d1af9410) SHA1(e66b3ddd9d9e3c567fdb140c4c8972c766f2b975) )
518 	ROM_RELOAD(0x160001,0x10000)
519 
520 	ROM_LOAD16_BYTE( "bmc_6.bin", 0x180000, 0x20000, CRC(7b9e0d77) SHA1(1ec1c92c6d4c512f7292b77e9663518085684ba9) )
521 	ROM_LOAD16_BYTE( "bmc_5.bin", 0x180001, 0x20000, CRC(708b6f8b) SHA1(4a910126d87c11fed99f44b61d51849067eddc02) )
522 
523 	ROM_REGION( 0x040000, "oki", 0 ) /* Samples */
524 	ROM_LOAD( "bmc_10.bin", 0x00000, 0x20000,  CRC(f840c17f) SHA1(82891a85c8dc60f727b5a8c8e8ab09e8e4bd8af4) )
525 
526 ROM_END
527 
528 GAME( 1994, bmcbowl, 0, bmcbowl, bmcbowl, bmcbowl_state, empty_init, ROT0, "BMC", "Konkyuu no Hoshi", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE)
529