1 // license:BSD-3-Clause
2 // copyright-holders:
3 
4 /*
5     Blood Bros. (Modular System)
6 
7     As with most of the 'Modular System' setups, the hardware is heavily modified from the original
8     and consists of a multi-board stack in a cage, hence different driver.
9 
10     For this game the Modular System cage contains 8 main boards and 1 sub board.
11 
12     MOD-6/1 - MC68000P10, 6 ROMs, RAMs, 22.1184 MHz XTAL.
13     MOD 21/1(?) - 24 MHz XTAL.
14     MOD 1/2 - Sound board (Z80, 2xYM2203C). 2 8-dips banks + small sub board with OKI M5205.
15     MOD 51/1 - Sprite board, has logic + 4 empty ROM sockets. Sprite ROMs are actually on the below board.
16     MODULAR SYSTEM 2 - red sprite ROM board, 16 sprite ROMs populated (maximum 24 ROMs)
17     MOD 4/3 - Tilemap board, has logic + NO ROMs populated, long thin sub-board (CAR-0484/1 SOLD) with no chips, just routing along one edge.
18     MOD 4/3 - Tilemap board, has logic + 4 tilemap ROMs, long thin sub-board (CAR-0484/1 SOLD) with no chips, just routing along one edge.
19     MOD 4/3 - Tilemap board, has logic + 4 tilemap ROMs, long thin sub-board (CAR-0484/1 SOLD) with no chips, just routing along one edge.
20 
21     PCBs pictures and dip listing are available at: http://www.recreativas.org/modular-system-blood-bros-4316-gaelco-sa
22 */
23 
24 
25 #include "emu.h"
26 #include "cpu/m68000/m68000.h"
27 #include "cpu/z80/z80.h"
28 #include "machine/gen_latch.h"
29 #include "sound/2203intf.h"
30 #include "sound/msm5205.h"
31 #include "emupal.h"
32 #include "screen.h"
33 #include "speaker.h"
34 
35 
36 class bloodbro_ms_state : public driver_device
37 {
38 public:
bloodbro_ms_state(const machine_config & mconfig,device_type type,const char * tag)39 	bloodbro_ms_state(const machine_config &mconfig, device_type type, const char *tag) :
40 		driver_device(mconfig, type, tag),
41 		m_maincpu(*this, "maincpu"),
42 		m_palette(*this, "palette"),
43 		m_screen(*this, "screen"),
44 		m_spriteram(*this, "spriteram"),
45 		m_gfxdecode(*this, "gfxdecode")
46 	{ }
47 
48 	void bloodbrom(machine_config &config);
49 	void init_bloodbrom();
50 
51 protected:
52 	virtual void machine_start() override;
53 
54 private:
55 	required_device<cpu_device> m_maincpu;
56 	required_device<palette_device> m_palette;
57 	required_device<screen_device> m_screen;
58 	required_shared_ptr<uint16_t> m_spriteram;
59 	required_device<gfxdecode_device> m_gfxdecode;
60 
61 	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
62 
63 	void bloodbrom_map(address_map &map);
64 
65 	void descramble_16x16tiles(uint8_t* src, int len);
66 };
67 
68 
bloodbrom_map(address_map & map)69 void bloodbro_ms_state::bloodbrom_map(address_map &map)
70 {
71 	map(0x000000, 0x07ffff).rom();
72 
73 
74 	map(0x080000, 0x08ffff).ram(); // original vram is in here, but bootleg copies some of it elsewhere for use
75 
76 	map(0x0a0000, 0x0a0001).nopw();
77 	map(0x0a0008, 0x0a0009).nopw();
78 	map(0x0a000c, 0x0a000d).nopw();
79 
80 	map(0x0c0100, 0x0c0101).nopw();
81 
82 	map(0x0e000e, 0x0e000f).nopw();
83 
84 
85 	map(0x100000, 0x1003ff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
86 	map(0x100400, 0x1007ff).ram().w(m_palette, FUNC(palette_device::write16_ext)).share("palette_ext");
87 	map(0x100800, 0x100fff).ram();
88 	map(0x101000, 0x1017ff).ram().share("spriteram");
89 	map(0x101800, 0x101fff).ram();
90 
91 	map(0x102000, 0x102001).nopw();
92 
93 	map(0x18d000, 0x18dfff).ram();
94 
95 }
96 
97 
machine_start()98 void bloodbro_ms_state::machine_start()
99 {
100 }
101 
102 
screen_update(screen_device & screen,bitmap_ind16 & bitmap,const rectangle & cliprect)103 uint32_t bloodbro_ms_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
104 {
105 	bitmap.fill(0, cliprect);
106 
107 	// TODO, convert to device, share between Modualar System games
108 	const int NUM_SPRITES = 0x200;
109 	const int X_EXTRA_OFFSET = 256;
110 
111 	for (int i = NUM_SPRITES-2; i >= 0; i-=2)
112 	{
113 		gfx_element *gfx = m_gfxdecode->gfx(0);
114 
115 		uint16_t attr0 = m_spriteram[i + 0];
116 		uint16_t attr1 = m_spriteram[i + 1];
117 
118 		uint16_t attr2 = m_spriteram[i + NUM_SPRITES];
119 		//uint16_t attr3 = m_spriteram[i + NUM_SPRITES + 1]; // unused?
120 
121 		int ypos = attr0 & 0x00ff;
122 		int xpos = (attr1 & 0xff00)>>8;
123 		xpos |= (attr2 & 0x8000) ? 0x100 : 0x000;
124 
125 		ypos = (0xff - ypos);
126 
127 		int tile = (attr0 & 0xff00) >> 8;
128 		tile |= (attr1 & 0x003f) << 8;
129 
130 		int flipx = (attr1 & 0x0040);
131 		int flipy = (attr2 & 0x4000);
132 
133 		gfx->transpen(bitmap,cliprect,tile,(attr2&0x0f00)>>8,flipx,flipy,xpos-16-X_EXTRA_OFFSET,ypos-16,15);
134 	}
135 
136 	return 0;
137 }
138 
139 
140 
141 static const gfx_layout tiles16x16x4_layout =
142 {
143 	16,16,
144 	RGN_FRAC(1,1),
145 	4,
146 	{ 0,8,16,24 },
147 	{ 0,1,2,3,4,5,6,7, 512,513,514,515,516,517,518,519 },
148 	{ STEP16(0,32) },
149 	16 * 16 * 4
150 };
151 
152 /*
153 static const gfx_layout tiles8x8x4_layout =
154 {
155     8,8,
156     RGN_FRAC(1,1),
157     4,
158     { 0,8,16,24 },
159     { 0,1,2,3,4,5,6,7 },
160     { STEP8(0,32) },
161     16 * 16
162 };
163 */
164 
165 static GFXDECODE_START( gfx_bloodbro_ms )
166 	GFXDECODE_ENTRY( "sprites", 0, tiles16x16x4_layout, 0x100, 32 )
167 	GFXDECODE_ENTRY( "gfx1", 0, tiles16x16x4_layout, 0x000, 32 )
168 	GFXDECODE_ENTRY( "gfx2", 0, tiles16x16x4_layout, 0x000, 32 )
169 GFXDECODE_END
170 
171 
INPUT_PORTS_START(bloodbrom)172 static INPUT_PORTS_START( bloodbrom )
173 INPUT_PORTS_END
174 
175 void bloodbro_ms_state::bloodbrom(machine_config &config)
176 {
177 	/* basic machine hardware */
178 	M68000(config, m_maincpu, 22.1184_MHz_XTAL / 2); // divisor unknown
179 	m_maincpu->set_addrmap(AS_PROGRAM, &bloodbro_ms_state::bloodbrom_map);
180 	m_maincpu->set_vblank_int("screen", FUNC(bloodbro_ms_state::irq4_line_hold));
181 
182 	Z80(config, "audiocpu", 24_MHz_XTAL / 8).set_disable(); // divisor unknown, no XTAL on the PCB, might also use the 20 MHz one
183 
184 	/* video hardware */
185 	SCREEN(config, m_screen, SCREEN_TYPE_RASTER); // all wrong
186 	m_screen->set_refresh_hz(60);
187 	m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500) /* not accurate */);
188 	m_screen->set_size(256, 256);
189 	m_screen->set_visarea(0, 256-1, 0, 256-32-1);
190 	m_screen->set_screen_update(FUNC(bloodbro_ms_state::screen_update));
191 	m_screen->set_palette("palette");
192 
193 	PALETTE(config, m_palette).set_format(palette_device::xBGR_444, 0x400);
194 
195 	GFXDECODE(config, "gfxdecode", "palette", gfx_bloodbro_ms);
196 
197 	/* sound hardware */
198 	SPEAKER(config, "mono").front_center();
199 
200 	GENERIC_LATCH_8(config, "soundlatch");
201 
202 	YM2203(config, "ym1", 24_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.15); // divisor unknown, no XTAL on the PCB, might also use the 20 MHz one
203 
204 	YM2203(config, "ym2", 24_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.15); // divisor unknown, no XTAL on the PCB, might also use the 20 MHz one
205 
206 	MSM5205(config, "msm", 24_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.15); // divisor unknown, no XTAL on the PCB, might also use the 20 MHz one
207 }
208 
209 // reorganize graphics into something we can decode with a single pass
descramble_16x16tiles(uint8_t * src,int len)210 void bloodbro_ms_state::descramble_16x16tiles(uint8_t* src, int len)
211 {
212 	std::vector<uint8_t> buffer(len);
213 	{
214 		for (int i = 0; i < len; i++)
215 		{
216 			int j = bitswap<20>(i, 19,18,17,16,15,12,11,10,9,8,7,6,5,14,13,4,3,2,1,0);
217 			buffer[j] = src[i];
218 		}
219 
220 		std::copy(buffer.begin(), buffer.end(), &src[0]);
221 	}
222 }
223 
init_bloodbrom()224 void bloodbro_ms_state::init_bloodbrom()
225 {
226 	descramble_16x16tiles(memregion("gfx1")->base(), memregion("gfx1")->bytes());
227 	descramble_16x16tiles(memregion("gfx2")->base(), memregion("gfx2")->bytes());
228 }
229 
230 
231 
232 
233 ROM_START( bloodbrom )
234 	ROM_REGION( 0x100000, "maincpu", 0 ) // on MOD 6/1 board
235 	ROM_LOAD16_BYTE( "6-1_bb606.ic8",   0x00001, 0x10000, CRC(3c069061) SHA1(537a10376ad24537367fb221817789bdc31787fa) )
236 	ROM_LOAD16_BYTE( "6-1_bb603.ic17",  0x00000, 0x10000, CRC(10f4c8e9) SHA1(e5c078395b70b73d21c100c6b60cff89e4668473) )
237 	ROM_LOAD16_BYTE( "6-1_bb605.ic11",  0x20001, 0x10000, CRC(2dc3fb8c) SHA1(44e8e4136979464101385531f97cce27abe1de34) )
238 	ROM_LOAD16_BYTE( "6-1_bb602.ic20",  0x20000, 0x10000, CRC(8e507cce) SHA1(93bef8838cf8f73eb158dfe276f53c29f364fd45) )
239 	ROM_LOAD16_BYTE( "6-1_bb604.ic25",  0x40001, 0x10000, CRC(cc069a40) SHA1(314b27cde5427b285272840f41da097326b39ee9) )
240 	ROM_LOAD16_BYTE( "6-1_bb601.ic26",  0x40000, 0x10000, CRC(d06bf68d) SHA1(7df7a99805aa7dd2ad91fb3d641e369c058cc6ae) )
241 
242 	ROM_REGION( 0x10000, "audiocpu", 0 ) // on MOD 1/2 board
243 	ROM_LOAD( "1-2_bb101.ic12",  0x00000, 0x10000, CRC(3e184e74) SHA1(031cd37fe6d09daf8c9e88562da99fde03f52109) )
244 
245 	// dumper's note: ROMs [bb4b1, bb4b2, bb4b3, bb4b4] and [bb4a1, bb4a2, bb4a3, bb4a4] have a strange setup
246 	// with pins 32, 31 and 31 soldered together and pin 2 connected between all four chips,
247 	// while the sockets are for 28 pin chips (with 27C512 silkscreened on the PCB behind the chips)
248 	ROM_REGION( 0x80000, "gfx1", 0 ) // on one of the MOD 4/3 boards
249 	ROM_LOAD32_BYTE( "4-3-a_bb4a1.ic17",  0x00003, 0x20000, CRC(499c91db) SHA1(bd7142a311a4f3e606f8a31aafc0b504f3d5a2e4) )
250 	ROM_LOAD32_BYTE( "4-3-a_bb4a2.ic16",  0x00002, 0x20000, CRC(e8f87153) SHA1(f4147c971d1c66e7c6133c6318357ced7e30e217) )
251 	ROM_LOAD32_BYTE( "4-3-a_bb4a3.ic15",  0x00001, 0x20000, CRC(13b888f2) SHA1(7a53f78f22a09fe4db45c36bf3912ad379deca64) )
252 	ROM_LOAD32_BYTE( "4-3-a_bb4a4.ic14",  0x00000, 0x20000, CRC(19bc0508) SHA1(01c4eb570dc7ba9401085012d23bdb865df78029) )
253 
254 	ROM_REGION( 0x80000, "gfx2", 0 ) // on another MOD 4/3 board
255 	ROM_LOAD32_BYTE( "4-3-b_bb4b1.ic17",  0x00003, 0x20000, CRC(aa86ae59) SHA1(c15a78eaaca36bebd3261cb2c4a2c232b967a135) )
256 	ROM_LOAD32_BYTE( "4-3-b_bb4b2.ic16",  0x00002, 0x20000, CRC(f25dd182) SHA1(eff29970c7b898744b08a151f9e17b68ce77e78d) )
257 	ROM_LOAD32_BYTE( "4-3-b_bb4b3.ic15",  0x00001, 0x20000, CRC(3efcb6aa) SHA1(0a162285d08e171e946147e0725db879643ae113) )
258 	ROM_LOAD32_BYTE( "4-3-b_bb4b4.ic14",  0x00000, 0x20000, CRC(6b5254fa) SHA1(1e9e3096e5f29554fb8f8cb0df0e5157f940f8c9) )
259 
260 	// ROMs for frontmost tile layer (text) are missing?
261 	ROM_REGION( 0x80000, "gfx3", 0 ) // on another MOD 4/3 board
262 	ROM_LOAD32_BYTE( "text.ic17",  0x00003, 0x20000, NO_DUMP )
263 	ROM_LOAD32_BYTE( "text.ic16",  0x00002, 0x20000, NO_DUMP )
264 	ROM_LOAD32_BYTE( "text.ic15",  0x00001, 0x20000, NO_DUMP )
265 	ROM_LOAD32_BYTE( "text.ic14",  0x00000, 0x20000, NO_DUMP )
266 
267 	ROM_REGION( 0x100000, "sprites", ROMREGION_INVERT ) // on MOD 51/1 board
268 	ROM_LOAD32_BYTE( "51-1-b_bb503.ic3",   0x00003, 0x10000, CRC(9d2a382d) SHA1(734b495ace73f07c622f64b305dafe43099395c1) )
269 	ROM_LOAD32_BYTE( "51-1-b_bb512.ic12",  0x00002, 0x10000, CRC(83bbb220) SHA1(8f43354c7cea89938d1115d7a0f27ede8f7d3e96) )
270 	ROM_LOAD32_BYTE( "51-1-b_bb518.ic18",  0x00001, 0x10000, CRC(efcf5b1d) SHA1(515b27f8e6df7ac7ed172cbd1ac64b14791de99f) )
271 	ROM_LOAD32_BYTE( "51-1-b_bb524.ic24",  0x00000, 0x10000, CRC(c4ccf38d) SHA1(be93ce6ed87c79fbd13838c0fe80526ce7e7e870) )
272 	ROM_LOAD32_BYTE( "51-1-b_bb504.ic4",   0x40003, 0x10000, CRC(1fc7f229) SHA1(37120c85a170f31bc4fbf287b1ba80bc319522ec) )
273 	ROM_LOAD32_BYTE( "51-1-b_bb513.ic13",  0x40002, 0x10000, CRC(3767456b) SHA1(3680807282079862cdfb5ec055e7d771e708545b) )
274 	ROM_LOAD32_BYTE( "51-1-b_bb519.ic19",  0x40001, 0x10000, CRC(77670244) SHA1(27a5572d86ae6e9a5ef076572a4b3a04a22c86e9) )
275 	ROM_LOAD32_BYTE( "51-1-b_bb525.ic25",  0x40000, 0x10000, CRC(25b4e119) SHA1(7e7d95aefee2b8d4dddf105c16d347ec65cd76a5) )
276 	ROM_LOAD32_BYTE( "51-1-b_bb505.ic5",   0x80003, 0x10000, CRC(3ec650ce) SHA1(28091f535fcd580f2d3a941251a9c4f662fcf2e4) )
277 	ROM_LOAD32_BYTE( "51-1-b_bb514.ic14",  0x80002, 0x10000, CRC(a29a2f44) SHA1(4e039d9a9b225179e84590d450eca3bed05bd3b8) )
278 	ROM_LOAD32_BYTE( "51-1-b_bb520.ic20",  0x80001, 0x10000, CRC(d7f3b09a) SHA1(339206a7c3389d4eac63e8314ba7fdda9de73be7) )
279 	ROM_LOAD32_BYTE( "51-1-b_bb526.ic26",  0x80000, 0x10000, CRC(1c2d70b0) SHA1(703f1acbcdaa7ff539f58829890d25b51a2e269e) )
280 	ROM_LOAD32_BYTE( "51-1-b_bb506.ic6",   0xc0003, 0x10000, CRC(10dba663) SHA1(ea0e4115ebb1c9f894c044a1eb11f135fcf5aba8) )
281 	ROM_LOAD32_BYTE( "51-1-b_bb515.ic15",  0xc0002, 0x10000, CRC(30110411) SHA1(fe9f418070c224d3a9acf6913bd4597b55afcc94) )
282 	ROM_LOAD32_BYTE( "51-1-b_bb521.ic21",  0xc0001, 0x10000, CRC(fb8cff4c) SHA1(5fa0b52140959e029911a28928b3efad4aa9f1db) )
283 	ROM_LOAD32_BYTE( "51-1-b_bb527.ic27",  0xc0000, 0x10000, CRC(a73cd7a5) SHA1(9106565d1c8a8e0efa8f5035106f3cdac2189107) )
284 
285 	ROM_REGION( 0x0400, "proms", 0 )    // PROMs (function unknown)
286 	ROM_LOAD( "1-2_110_tbp18s030.ic20",  0x000, 0x020, CRC(e26e680a) SHA1(9bbe30e98e952a6113c64e1171330153ddf22ce7) )
287 	ROM_LOAD( "2_211_82s129.ic4",        0x100, 0x100, CRC(4f8c3e63) SHA1(0aa68fa1de6ca945027366a06752e834bbbc8d09) )
288 	ROM_LOAD( "2_202_82s129.ic12",       0x200, 0x100, CRC(e434128a) SHA1(ef0f6d8daef8b25211095577a182cdf120a272c1) )
289 	ROM_LOAD( "51-1_p0502_82s129n.ic10", 0x300, 0x100, CRC(15085e44) SHA1(646e7100fcb112594023cf02be036bd3d42cc13c) )
290 
291 	ROM_REGION( 0x1000, "plds", ROMREGION_ERASEFF )
292 	ROM_LOAD( "6-1_606_gal16v8-20hb1.ic13",    0x000, 0x117, NO_DUMP ) // Protected
293 	ROM_LOAD( "6-1_646_gal16v8-20hb1.ic7",     0x000, 0x117, NO_DUMP ) // Protected
294 	ROM_LOAD( "4-3_403_gal16v8-25hb1.ic29",    0x000, 0x117, NO_DUMP ) // Protected
295 	ROM_LOAD( "4-3-a_p0403_pal16r8acn.ic29",   0x000, 0x104, CRC(506156cc) SHA1(5560671fc2c9872ed28620491af5dc486909fc6e) )
296 	ROM_LOAD( "4-3-b_403_gal16v8-25hb1.ic19",  0x000, 0x117, NO_DUMP ) // Protected
297 	ROM_LOAD( "51-1_503_gal16v8-25lp.ic48",    0x000, 0x117, NO_DUMP ) // Protected
298 	ROM_LOAD( "51-1-b_5146_gal16v8-20hb1.ic9", 0x000, 0x117, NO_DUMP ) // Protected
299 	ROM_LOAD( "51-1-b_5246_gal16v8-20hb1.ic8", 0x000, 0x117, NO_DUMP ) // Protected
300 ROM_END
301 
302 
303 
304 
305 GAME( 199?, bloodbrom,  bloodbro,  bloodbrom,  bloodbrom,  bloodbro_ms_state, init_bloodbrom, ROT0, "bootleg (Gaelco / Ervisa)", "Blood Bros. (Modular System)", MACHINE_IS_SKELETON )
306