1 // license:BSD-3-Clause
2 // copyright-holders:Angelo Salese, David Haywood
3 /*******************************************************************************************
4 
5     Popo Bear (c) 2000 BMC
6 
7     driver by Angelo Salese, David Haywood
8 
9     TODO:
10     - auto-animation speed is erratic (way too fast);
11     - BGM seems quite off, YM2413 core bug?
12     - IRQ generation;
13       - all possible related to some timers?
14 
15 
16     - I/Os;
17     - Port 0x620000 is quite a mystery, some silly protection?
18 
19 ============================================================================================
20 Popo Bear - BMC-A00211
21 (c) 2000 - Bao Ma Technology Co., LTD
22 
23 |-----------------------------------------|
24 | DIP2 DIP4  UM3567(YM2413)               |J
25 | DIP1 DIP3                               |A
26 |           TA-A-901                      |M
27 | EN-A-701  EN-A-801  U6295(OKI)          |M
28 | EN-A-501  EN-A-601                      |A
29 | EN-A-301  EN-A-401                      |
30 |                                         |C
31 |                   AIA90610              |O
32 |                   BMC-68pin  AIA90423   |N
33 |                   plcc (68k) BMC-160pin |N
34 |                                         |E
35 |                                    OSC  |C
36 |                                 42.000  |T
37 |-----------------------------------------|
38 
39 1 - BMC AIA90423 - 160-Pin ASIC, FGPA, Video?
40 1 - BMC AIA90610 - 68 Pin CPU (Likely 16 MHz, 68-lead plastic LCC 68000)
41 1 - UM3567 (YM2413) Sound
42 1 - U6295 (OKI6295) Sound
43 1 - 42.000MHz XTAL
44 4 - 8 Position DIP switches
45 
46 JAMMA CONNECTOR
47 Component Side   A   B   Solder Side
48            GND   1   1   GND
49            GND   2   2   GND
50            +5v   3   3   +5v
51            +5v   4   4   +5v
52                  5   5
53           +12v   6   6   +12v
54                  7   7
55     Coin Meter   8   8
56                  9   9
57        Speaker  10   10  GND
58                 11   11
59            Red  12   12  Green
60           Blue  13   13  Syn
61            GND  14   14
62           Test  15   15
63          Coin1  16   16  Coin2
64       1P Start  17   17  2P Start
65          1P Up  18   18  2P Up
66        1P Down  19   19  2P Down
67        1P Left  20   20  2P Left
68       1P Right  21   21  2P Right
69           1P A  22   22  2P A
70           1P B  23   23  2P B
71           1P C  24   24  2P C
72                 25   25
73                 26   26
74            GND  27   27  GND
75            GND  28   28  GND
76 *******************************************************************************************/
77 
78 
79 
80 #include "emu.h"
81 #include "cpu/m68000/m68000.h"
82 #include "machine/timer.h"
83 #include "sound/okim6295.h"
84 #include "sound/ym2413.h"
85 #include "emupal.h"
86 #include "screen.h"
87 #include "speaker.h"
88 #include "tilemap.h"
89 
90 class popobear_state : public driver_device
91 {
92 public:
popobear_state(const machine_config & mconfig,device_type type,const char * tag)93 	popobear_state(const machine_config &mconfig, device_type type, const char *tag) :
94 		driver_device(mconfig, type, tag),
95 		m_maincpu(*this,"maincpu"),
96 		m_gfxdecode(*this, "gfxdecode"),
97 		m_palette(*this, "palette"),
98 		m_spr(*this, "spr"),
99 		m_vram(*this, "vram"),
100 		m_vregs(*this, "vregs")
101 	{
102 		m_tilemap_base[0] = 0xf0000;
103 		m_tilemap_base[1] = 0xf4000;
104 		m_tilemap_base[2] = 0xf8000;
105 		m_tilemap_base[3] = 0xfc000;
106 	}
107 
108 	void popobear(machine_config &config);
109 
110 private:
111 	required_device<cpu_device> m_maincpu;
112 	required_device<gfxdecode_device> m_gfxdecode;
113 	required_device<palette_device> m_palette;
114 
115 	required_shared_ptr<uint16_t> m_spr;
116 	required_shared_ptr<uint16_t> m_vram;
117 	required_shared_ptr<uint16_t> m_vregs;
118 
119 	std::vector<uint16_t> m_vram_rearranged;
120 	int m_tilemap_base[4];
121 	tilemap_t    *m_bg_tilemap[4];
122 
123 	TILE_GET_INFO_MEMBER(get_bg0_tile_info);
124 	TILE_GET_INFO_MEMBER(get_bg1_tile_info);
125 	TILE_GET_INFO_MEMBER(get_bg2_tile_info);
126 	TILE_GET_INFO_MEMBER(get_bg3_tile_info);
127 
128 	uint8_t _620000_r();
129 	void irq_ack_w(uint8_t data);
130 	void vram_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0);
131 
132 	virtual void video_start() override;
133 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
134 	void draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect);
135 
136 	TIMER_DEVICE_CALLBACK_MEMBER(irq);
137 
138 	void postload();
139 	void popobear_mem(address_map &map);
140 };
141 
142 
vram_w(offs_t offset,uint16_t data,uint16_t mem_mask)143 void popobear_state::vram_w(offs_t offset, uint16_t data, uint16_t mem_mask)
144 {
145 	COMBINE_DATA(&m_vram[offset]);
146 
147 	// the graphic data for the tiles is in a strange order, rearrange it so that we can use it as tiles..
148 	int swapped_offset = bitswap<32>(offset, /* unused bits */ 31,30,29,28,27,26,25,24,23,22,21,20,19, /* end unused bits */
149 
150 	18,17,16,15,14,13,12,
151 
152 	8,7,6,5,4,3,2,
153 
154 	11,10,9, /* y tile address bits */
155 
156 	1,0 /* x tile address bits */);
157 
158 
159 
160 	COMBINE_DATA(&m_vram_rearranged[swapped_offset]);
161 	m_gfxdecode->gfx(0)->mark_dirty((swapped_offset)/32);
162 
163 	// unfortunately tilemaps and tilegfx share the same ram so we're always dirty if we write to RAM
164 	m_bg_tilemap[0]->mark_all_dirty();
165 	m_bg_tilemap[1]->mark_all_dirty();
166 	m_bg_tilemap[2]->mark_all_dirty();
167 	m_bg_tilemap[3]->mark_all_dirty();
168 }
169 
170 static const gfx_layout char_layout =
171 {
172 	8,8,
173 	RGN_FRAC(1,1),
174 	8,
175 	{ 0,1,2,3,4,5,6,7 },
176 	{ STEP8(0, 8) },
177 	{ STEP8(0, 64) },
178 	8*64
179 };
180 
181 GFXDECODE_START(gfx_popobear)
182 	GFXDECODE_RAM( "vram", 0, char_layout, 0, 1 )
183 GFXDECODE_END
184 
TILE_GET_INFO_MEMBER(popobear_state::get_bg0_tile_info)185 TILE_GET_INFO_MEMBER(popobear_state::get_bg0_tile_info)
186 {
187 	int base = m_tilemap_base[0];
188 	int tileno = m_vram[base/2 + tile_index];
189 	int flipyx = (tileno>>14);
190 	tileinfo.set(0, tileno&0x3fff, 0, TILE_FLIPYX(flipyx));
191 }
192 
TILE_GET_INFO_MEMBER(popobear_state::get_bg1_tile_info)193 TILE_GET_INFO_MEMBER(popobear_state::get_bg1_tile_info)
194 {
195 	int base = m_tilemap_base[1];
196 	int tileno = m_vram[base/2 + tile_index];
197 	int flipyx = (tileno>>14);
198 	tileinfo.set(0, tileno&0x3fff, 0, TILE_FLIPYX(flipyx));
199 }
200 
TILE_GET_INFO_MEMBER(popobear_state::get_bg2_tile_info)201 TILE_GET_INFO_MEMBER(popobear_state::get_bg2_tile_info)
202 {
203 	int base = m_tilemap_base[2];
204 	int tileno = m_vram[base/2 + tile_index];
205 	int flipyx = (tileno>>14);
206 	tileinfo.set(0, tileno&0x3fff, 0, TILE_FLIPYX(flipyx));
207 }
208 
TILE_GET_INFO_MEMBER(popobear_state::get_bg3_tile_info)209 TILE_GET_INFO_MEMBER(popobear_state::get_bg3_tile_info)
210 {
211 	int base = m_tilemap_base[3];
212 	int tileno = m_vram[base/2 + tile_index];
213 	int flipyx = (tileno>>14);
214 	tileinfo.set(0, tileno&0x3fff, 0, TILE_FLIPYX(flipyx));
215 }
216 
217 
postload()218 void popobear_state::postload()
219 {
220 	m_gfxdecode->gfx(0)->mark_all_dirty();
221 }
222 
video_start()223 void popobear_state::video_start()
224 {
225 	m_vram_rearranged.resize(0x100000 / 2);
226 
227 	m_gfxdecode->gfx(0)->set_source(reinterpret_cast<uint8_t *>(&m_vram_rearranged[0]));
228 
229 	m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(popobear_state::get_bg0_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
230 	m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(popobear_state::get_bg1_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
231 	m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(popobear_state::get_bg2_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
232 	m_bg_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(popobear_state::get_bg3_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 128, 64);
233 
234 	m_bg_tilemap[0]->set_transparent_pen(0);
235 	m_bg_tilemap[1]->set_transparent_pen(0);
236 	m_bg_tilemap[2]->set_transparent_pen(0);
237 	m_bg_tilemap[3]->set_transparent_pen(0);
238 
239 	save_item(NAME(m_vram_rearranged));
240 	machine().save().register_postload(save_prepost_delegate(FUNC(popobear_state::postload), this));
241 }
242 
243 
244 
245 
draw_sprites(bitmap_ind16 & bitmap,const rectangle & cliprect)246 void popobear_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
247 {
248 	uint8_t* vram = reinterpret_cast<uint8_t *>(m_spr.target());
249 	int i;
250 
251 	/*
252 	???? ---- ---- ---- unused?
253 	---- xxxx ---- ---- priority (against other sprites! used to keep the line of characters following you in order)
254 	---- ---- x--- ---- Y direction
255 	---- ---- -x-- ---- X direction
256 	---- ---- --xx ---- size (height & width)
257 	---- ---- ---- xx-- color bank
258 	---- ---- ---- --x- NOT set on the enemy character / characters in your line
259 	---- ---- ---- ---x set on opposite to above?
260 	*/
261 
262 	for (int drawpri = 0xf;drawpri>=0x0;drawpri--)
263 	{
264 		/* 0x106 = 8 x 8 */
265 		/* 0x*29 = 32 x 32 */
266 		for(i = 0x800-8;i >= 0; i-=8)
267 		{
268 			uint16_t *sprdata = &m_spr[(0x7f800 + i) / 2];
269 
270 			int param = sprdata[0];
271 			int pri = (param & 0x0f00)>>8;
272 
273 			// we do this because it's sprite<->sprite priority,
274 			if (pri!=drawpri)
275 				continue;
276 
277 			int y = sprdata[1];
278 			int x = sprdata[2];
279 			int spr_num = sprdata[3];
280 
281 			int width = 8 << ((param & 0x30)>>4);
282 			int height = width; // sprites are always square?
283 
284 			int color_bank = ((param & 0xc)>>2);
285 			int x_dir = param & 0x40;
286 			int y_dir = param & 0x80;
287 
288 			if (x&0x8000) x-= 0x10000;
289 			if (y&0x8000) y-= 0x10000;
290 
291 			if (param&0xf000) color_bank = (machine().rand() & 0x3);
292 
293 
294 
295 			int add_it = 0;
296 
297 			// this isn't understood, not enough evidence.
298 			switch (param & 3)
299 			{
300 				case 0x0: // not used?
301 				color_bank = (machine().rand() & 0x3);
302 				add_it = color_bank*0x40;
303 				break;
304 
305 				case 0x1: // butterflies in intro, enemy characters, line of characters, stage start text
306 				//color_bank = (machine().rand() & 0x3);
307 				add_it = color_bank*0x40;
308 				break;
309 
310 				case 0x2: // characters in intro, main player, powerups, timer, large dancing chars between levels (0x3f?)
311 				//color_bank = (machine().rand() & 0x3);
312 				add_it = color_bank*0x40;
313 				break;
314 
315 				case 0x3: // letters on GAME OVER need this..
316 				add_it = color_bank*0x40;
317 				add_it += 0x20;
318 				break;
319 			}
320 
321 			if(param == 0)
322 				continue;
323 
324 
325 			spr_num <<= 3;
326 
327 			for(int yi=0;yi<height;yi++)
328 			{
329 				int y_draw = (y_dir) ? y+((height-1) - yi) : y+yi;
330 
331 				for(int xi=0;xi<width;xi++)
332 				{
333 					uint8_t pix = vram[BYTE_XOR_BE(spr_num)];
334 					int x_draw = (x_dir) ? x+((width-1) - xi) : x+xi;
335 
336 					if(cliprect.contains(x_draw, y_draw))
337 					{
338 						// this is a bit strange, pix data is basically 8-bit
339 						// but we have to treat 0x00, 0x40, 0x80, 0xc0 */
340 						// see scores when you colect an item, must be at least steps of 0x40 or one of the female panda gfx between levels breaks.. might depend on lower bits?
341 						// granularity also means colour bank is applied *0x40
342 						// and we have 2 more possible colour bank bits
343 						// colours on game over screen are still wrong without the weird param kludge above
344 						if (pix&0x3f)
345 						{
346 							bitmap.pix(y_draw, x_draw) = m_palette->pen(((pix+(add_it))&0xff)+0x100);
347 						}
348 					}
349 
350 					spr_num++;
351 				}
352 			}
353 		}
354 	}
355 }
356 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)357 uint32_t popobear_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
358 {
359 	bitmap.fill(0, cliprect);
360 	int line;
361 	rectangle clip;
362 	int scrollbase;
363 	int scrollbase2;
364 
365 	const rectangle &visarea = screen.visible_area();
366 	clip = visarea;
367 
368 	//popmessage("%04x",m_vregs[0/2]);
369 	uint16_t* vreg = m_vregs;
370 
371 //  popmessage("%04x %04x %04x %04x %04x %04x %04x - %04x - %04x %04x",vreg[0x00],vreg[0x01],vreg[0x02],vreg[0x03],vreg[0x04],vreg[0x05],vreg[0x06], vreg[0x0b],vreg[0x0e],vreg[0x0f]);
372 
373 	// vreg[0x00] also looks like it could be some enable registers
374 	// 0x82ff - BMC logo
375 	// 0x8aff - some attract scenes (no sprites)
376 	// 0x8bff - game attract scense etc. (sprites)
377 
378 	// vreg[0x01] is always
379 	// 0xfefb
380 
381 
382 
383 	// these are more than just enable, they get written with 0x0d and 0x1f (and 0x00 when a layer is off)
384 	// seems to be related to the linescroll mode at least? maybe sizes?
385 	int enable0 = (m_vregs[0x0c] & 0xff00)>>8;
386 	int enable1 = (m_vregs[0x0c] & 0x00ff)>>0;
387 	int enable2 = (m_vregs[0x0d] & 0xff00)>>8;
388 	int enable3 = (m_vregs[0x0d] & 0x00ff)>>0;
389 
390 	if ((enable0 != 0x00) && (enable0 != 0x0d) && (enable0 != 0x1f)) printf("unknown enable0 value %02x\n", enable0);
391 	if ((enable1 != 0x00) && (enable1 != 0x0d) && (enable1 != 0x1f)) printf("unknown enable1 value %02x\n", enable1);
392 	if ((enable2 != 0x00) && (enable2 != 0x0d)) printf("unknown enable2 value %02x\n", enable2);
393 	if ((enable3 != 0x00) && (enable3 != 0x0d)) printf("unknown enable3 value %02x\n", enable3);
394 
395 
396 	// the lower 2 tilemaps use regular scrolling
397 	m_bg_tilemap[2]->set_scrollx(0, vreg[0x07]);
398 	m_bg_tilemap[2]->set_scrolly(0, vreg[0x08]);
399 
400 	m_bg_tilemap[3]->set_scrollx(0, vreg[0x09]);
401 	m_bg_tilemap[3]->set_scrolly(0, vreg[0x0a]);
402 
403 	if (enable3) m_bg_tilemap[3]->draw(screen, bitmap, cliprect, 0, 0);
404 	if (enable2) m_bg_tilemap[2]->draw(screen, bitmap, cliprect, 0, 0);
405 
406 	// the upper 2 tilemaps have a lineselect / linescroll logic
407 
408 	if (enable1 == 0x1f)
409 	{
410 		scrollbase = 0xdf600;
411 		scrollbase2 = 0xdf800;
412 
413 		for (line = 0; line < 240;line++)
414 		{
415 			uint16_t val = m_vram[scrollbase/2 + line];
416 			uint16_t upper = (m_vram[scrollbase2/2 + line]&0xff00)>>8;
417 
418 			clip.sety(line, line);
419 
420 			m_bg_tilemap[1]->set_scrollx(0,(val&0x00ff) | (upper << 8));
421 			m_bg_tilemap[1]->set_scrolly(0,((val&0xff00)>>8)-line);
422 
423 			m_bg_tilemap[1]->draw(screen, bitmap, clip, 0, 0);
424 		}
425 	}
426 	else if (enable1 != 0x00)
427 	{
428 		m_bg_tilemap[1]->set_scrollx(0, 0);
429 		m_bg_tilemap[1]->set_scrolly(0, 0);
430 		m_bg_tilemap[1]->draw(screen, bitmap, cliprect, 0, 0);
431 	}
432 
433 	if (enable0 == 0x1f)
434 	{
435 		scrollbase = 0xdf400;
436 		scrollbase2 = 0xdf800;
437 
438 		for (line = 0; line < 240;line++)
439 		{
440 			uint16_t val = m_vram[scrollbase/2 + line];
441 			uint16_t upper = (m_vram[scrollbase2/2 + line]&0x00ff)>>0;
442 
443 			clip.sety(line, line);
444 
445 			m_bg_tilemap[0]->set_scrollx(0,(val&0x00ff) | (upper << 8));
446 			m_bg_tilemap[0]->set_scrolly(0,((val&0xff00)>>8)-line);
447 
448 			m_bg_tilemap[0]->draw(screen, bitmap, clip, 0, 0);
449 		}
450 	}
451 	else if (enable0 != 0x00)
452 	{
453 		m_bg_tilemap[0]->set_scrollx(0, 0);
454 		m_bg_tilemap[0]->set_scrolly(0, 0);
455 		m_bg_tilemap[0]->draw(screen, bitmap, cliprect, 0, 0);
456 	}
457 
458 	draw_sprites(bitmap,cliprect);
459 
460 	return 0;
461 }
462 
463 /* ??? */
_620000_r()464 uint8_t popobear_state::_620000_r()
465 {
466 	return 9;
467 }
468 
irq_ack_w(uint8_t data)469 void popobear_state::irq_ack_w(uint8_t data)
470 {
471 	for(int i=0;i<8;i++)
472 	{
473 		if(data & 1 << i)
474 			m_maincpu->set_input_line(i, CLEAR_LINE);
475 	}
476 }
477 
popobear_mem(address_map & map)478 void popobear_state::popobear_mem(address_map &map)
479 {
480 	map.unmap_value_high();
481 	map(0x000000, 0x03ffff).rom();
482 	map(0x210000, 0x21ffff).ram();
483 	map(0x280000, 0x2fffff).ram().share("spr"); // unknown boundaries, 0x2ff800 contains a sprite list, lower area = sprite gfx
484 	map(0x300000, 0x3fffff).ram().w(FUNC(popobear_state::vram_w)).share("vram"); // tile definitions + tilemaps
485 
486 
487 	/* Most if not all of these are vregs */
488 	map(0x480000, 0x48001f).ram().share("vregs");
489 	map(0x480020, 0x480023).ram();
490 	map(0x480028, 0x48002d).ram();
491 //  map(0x480020, 0x480021).noprw(); //.rw(FUNC(popobear_state::480020_r) FUNC(popobear_state::480020_w));
492 //  map(0x480028, 0x480029).noprw(); //.w(FUNC(popobear_state::480028_w));
493 //  map(0x48002c, 0x48002d).noprw(); //.w(FUNC(popobear_state::48002c_w));
494 	map(0x480031, 0x480031).w(FUNC(popobear_state::irq_ack_w));
495 	map(0x480034, 0x480035).ram(); // coin counter or coin lockout
496 	map(0x48003a, 0x48003b).ram(); //.rw(FUNC(popobear_state::48003a_r) FUNC(popobear_state::48003a_w));
497 
498 	map(0x480400, 0x4807ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
499 
500 	map(0x500000, 0x500001).portr("IN0");
501 	map(0x520000, 0x520001).portr("IN1");
502 	map(0x540001, 0x540001).rw("oki", FUNC(okim6295_device::read), FUNC(okim6295_device::write));
503 	map(0x550000, 0x550003).w("ymsnd", FUNC(ym2413_device::write)).umask16(0x00ff);
504 
505 	map(0x600000, 0x600001).nopw();
506 	map(0x620000, 0x620000).r(FUNC(popobear_state::_620000_r));
507 	map(0x620000, 0x620001).nopw();
508 	map(0x800000, 0xbfffff).rom();
509 }
510 
511 static INPUT_PORTS_START( popobear )
512 
513 	PORT_START("DSW1")
DEF_STR(Demo_Sounds)514 	PORT_DIPNAME( 0x01, 0x01, DEF_STR( Demo_Sounds ) )
515 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
516 	PORT_DIPSETTING(    0x01, DEF_STR( On ) )
517 	PORT_DIPNAME( 0x0e, 0x00, "Coin_A" )
518 	PORT_DIPSETTING(    0x0c, DEF_STR( 3C_1C ) )
519 	PORT_DIPSETTING(    0x0a, DEF_STR( 2C_1C ) )
520 	PORT_DIPSETTING(    0x00, DEF_STR( 1C_1C ) )
521 	PORT_DIPSETTING(    0x02, DEF_STR( 1C_2C ) )
522 	PORT_DIPSETTING(    0x04, DEF_STR( 1C_3C ) )
523 	PORT_DIPSETTING(    0x06, DEF_STR( 1C_4C ) )
524 	PORT_DIPSETTING(    0x08, DEF_STR( 1C_5C ) )
525 	PORT_DIPSETTING(    0x0e, "Freeplay" )
526 	PORT_DIPNAME( 0x30, 0x00, DEF_STR( Lives ) )
527 	PORT_DIPSETTING(    0x10, "2" )
528 	PORT_DIPSETTING(    0x00, "3" )
529 	PORT_DIPSETTING(    0x20, "4" )
530 	PORT_DIPSETTING(    0x30, "5" )
531 	PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Difficulty ) )
532 	PORT_DIPSETTING(    0x80, DEF_STR( Very_Easy ) )
533 	PORT_DIPSETTING(    0x40, DEF_STR( Easy ) )
534 	PORT_DIPSETTING(    0x00, DEF_STR( Normal ) )
535 	PORT_DIPSETTING(    0xc0, DEF_STR( Hard ) )
536 
537 	PORT_START("DSW2")
538 	PORT_DIPNAME( 0x01, 0x00, "Arrow" )
539 	PORT_DIPSETTING(    0x01, DEF_STR( No ) )
540 	PORT_DIPSETTING(    0x00, DEF_STR( Yes ) )
541 	PORT_DIPNAME( 0x02, 0x00, "DSW2:2" )
542 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
543 	PORT_DIPSETTING(    0x02, DEF_STR( On ) )
544 	PORT_DIPNAME( 0x04, 0x00, "DSW2:3" )
545 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
546 	PORT_DIPSETTING(    0x04, DEF_STR( On ) )
547 	PORT_DIPNAME( 0x08, 0x00, "DSW2:4" )
548 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
549 	PORT_DIPSETTING(    0x08, DEF_STR( On ) )
550 	PORT_DIPNAME( 0x10, 0x00, "DSW2:5" )
551 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
552 	PORT_DIPSETTING(    0x10, DEF_STR( On ) )
553 	PORT_DIPNAME( 0x20, 0x00, "DSW2:6" )
554 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
555 	PORT_DIPSETTING(    0x20, DEF_STR( On ) )
556 	PORT_DIPNAME( 0x40, 0x00, "DSW2:7" )
557 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
558 	PORT_DIPSETTING(    0x40, DEF_STR( On ) )
559 	PORT_DIPNAME( 0x80, 0x00, "DSW2:8" )
560 	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
561 	PORT_DIPSETTING(    0x80, DEF_STR( On ) )
562 
563 	PORT_START("IN0")
564 	PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2)
565 	PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2)
566 	PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2)
567 	PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2)
568 	PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
569 	PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
570 	PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
571 	PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_UNUSED )
572 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1)
573 	PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1)
574 	PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1)
575 	PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1)
576 	PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
577 	PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
578 	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
579 	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNUSED )
580 
581 	PORT_START("IN1")
582 	PORT_DIPNAME( 0x01, 0x01, "DSWA" )
583 	PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
584 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
585 	PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
586 	PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
587 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
588 	PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
589 	PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
590 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
591 	PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
592 	PORT_DIPSETTING(    0x08, DEF_STR( Off ) )
593 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
594 	PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
595 	PORT_DIPSETTING(    0x10, DEF_STR( Off ) )
596 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
597 	PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
598 	PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
599 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
600 	PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
601 	PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
602 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
603 	PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
604 	PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
605 	PORT_DIPSETTING(    0x00, DEF_STR( On ) )
606 	PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(2)
607 	PORT_DIPNAME( 0x0200, 0x0200, DEF_STR( Unknown ) )
608 	PORT_DIPSETTING(    0x0200, DEF_STR( Off ) )
609 	PORT_DIPSETTING(    0x0000, DEF_STR( On ) )
610 	PORT_DIPNAME( 0x0400, 0x0400, DEF_STR( Unknown ) )
611 	PORT_DIPSETTING(    0x0400, DEF_STR( Off ) )
612 	PORT_DIPSETTING(    0x0000, DEF_STR( On ) )
613 	PORT_DIPNAME( 0x0800, 0x0800, DEF_STR( Unknown ) )
614 	PORT_DIPSETTING(    0x0800, DEF_STR( Off ) )
615 	PORT_DIPSETTING(    0x0000, DEF_STR( On ) )
616 	PORT_DIPNAME( 0x1000, 0x1000, DEF_STR( Unknown ) )
617 	PORT_DIPSETTING(    0x1000, DEF_STR( Off ) )
618 	PORT_DIPSETTING(    0x0000, DEF_STR( On ) )
619 	PORT_DIPNAME( 0x2000, 0x2000, DEF_STR( Unknown ) )
620 	PORT_DIPSETTING(    0x2000, DEF_STR( Off ) )
621 	PORT_DIPSETTING(    0x0000, DEF_STR( On ) )
622 	PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_START2 )
623 	PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_START1 )
624 INPUT_PORTS_END
625 
626 
627 TIMER_DEVICE_CALLBACK_MEMBER(popobear_state::irq)
628 {
629 	int scanline = param;
630 
631 	/* Order is trusted (5 as vblank-out makes the title screen logo spinning to behave wrongly) */
632 	if(scanline == 240)
633 		m_maincpu->set_input_line(3, ASSERT_LINE);
634 
635 	if(scanline == 0)
636 		m_maincpu->set_input_line(5, ASSERT_LINE);
637 
638 	/* TODO: actually a timer irq, tied with YM2413 sound chip (controls BGM tempo) */
639 	/* the YM2413 doesn't have interrupts? */
640 	if(scanline == 64 || scanline == 192)
641 		m_maincpu->set_input_line(2, ASSERT_LINE);
642 }
643 
popobear(machine_config & config)644 void popobear_state::popobear(machine_config &config)
645 {
646 	M68000(config, m_maincpu, XTAL(42'000'000)/4);  // XTAL CORRECT, DIVISOR GUESSED
647 	m_maincpu->set_addrmap(AS_PROGRAM, &popobear_state::popobear_mem);
648 	// levels 2,3,5 look interesting
649 	//->set_vblank_int("screen", popobear_state, irq5_line_assert)
650 	//->set_periodic_int(FUNC(popobear_state, irq2_line_assert, 120)
651 	TIMER(config, "scantimer").configure_scanline(FUNC(popobear_state::irq), "screen", 0, 1);
652 
653 	screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
654 	screen.set_refresh_hz(60);
655 	screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
656 	screen.set_screen_update(FUNC(popobear_state::screen_update));
657 	screen.set_palette(m_palette);
658 	screen.set_size(128*8, 32*8);
659 	screen.set_visarea(0, 479, 0, 239);
660 
661 	PALETTE(config, m_palette).set_format(palette_device::xBGR_555, 256*2);
662 
663 	SPEAKER(config, "mono").front_center();
664 
665 	GFXDECODE(config, m_gfxdecode, m_palette, gfx_popobear);
666 
667 	YM2413(config, "ymsnd", XTAL(42'000'000)/16).add_route(ALL_OUTPUTS, "mono", 1.0);  // XTAL CORRECT, DIVISOR GUESSED
668 
669 	OKIM6295(config, "oki", XTAL(42'000'000)/32, okim6295_device::PIN7_LOW).add_route(ALL_OUTPUTS, "mono", 1.0);  // XTAL CORRECT, DIVISOR GUESSED
670 }
671 
672 
673 ROM_START( popobear )
674 	ROM_REGION( 0x1000000, "maincpu", 0 ) /* 68000 Code + gfx data */
675 	ROM_LOAD16_BYTE( "popobear_en-a-301_1.6.u3", 0x000001, 0x020000, CRC(b934adf6) SHA1(93431c7a19af812b549aad35cc1176a81805ffab) )
676 	ROM_LOAD16_BYTE( "popobear_en-a-401_1.6.u4", 0x000000, 0x020000, CRC(0568af9c) SHA1(920531dbc4bbde2d1db062bd5c48b97dd50b7185) )
677 	ROM_LOAD16_BYTE( "popobear_en-a-501.u5",     0x800001, 0x100000, CRC(185901a9) SHA1(7ff82b5751645df53435eaa66edce589684cc5c7) )
678 	ROM_LOAD16_BYTE( "popobear_en-a-601.u6",     0x800000, 0x100000, CRC(84fa9f3f) SHA1(34dd7873f88b0dae5fb81fe84e82d2b6b49f7332) )
679 	ROM_LOAD16_BYTE( "popobear_en-a-701.u7",     0xa00001, 0x100000, CRC(45eba6d0) SHA1(0278602ed57ac45040619d590e6cc85e2cfeed31) )
680 	ROM_LOAD16_BYTE( "popobear_en-a-801.u8",     0xa00000, 0x100000, CRC(2760f2e6) SHA1(58af59f486c9df930f7c124f89154f8f389a5bd7) )
681 
682 	ROM_REGION( 0x040000, "oki", 0 ) /* Samples */
683 	ROM_LOAD( "popobear_ta-a-901.u9", 0x00000, 0x40000,  CRC(f1e94926) SHA1(f4d6f5b5811d90d0069f6efbb44d725ff0d07e1c) )
684 ROM_END
685 
686 GAME( 2000, popobear,    0, popobear,    popobear, popobear_state, empty_init, ROT0,  "BMC", "PoPo Bear",  MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )
687