1 // license:BSD-3-Clause
2 // copyright-holders:Aaron Giles
3 /***************************************************************************
4 
5     Sega 315-5195 memory mapper
6 
7 ***************************************************************************/
8 
9 #include "emu.h"
10 #include "315_5195.h"
11 
12 #include <algorithm>
13 
14 //**************************************************************************
15 //  DEBUGGING
16 //**************************************************************************
17 
18 #define VERBOSE         (0)
19 
20 #include "logmacro.h"
21 
22 
23 
24 //**************************************************************************
25 //  CONSTANTS
26 //**************************************************************************
27 
28 // device type definition
29 DEFINE_DEVICE_TYPE(SEGA_315_5195_MEM_MAPPER, sega_315_5195_mapper_device, "sega_315_5195", "Sega 315-5195 Memory Mapper")
30 
31 
32 
33 //**************************************************************************
34 //  315-5195 MEMORY MAPPER
35 //**************************************************************************
36 
37 //-------------------------------------------------
38 //  sega_315_5195_mapper_device - constructor
39 //-------------------------------------------------
40 
sega_315_5195_mapper_device(const machine_config & mconfig,const char * tag,device_t * owner,u32 clock)41 sega_315_5195_mapper_device::sega_315_5195_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
42 	: device_t(mconfig, SEGA_315_5195_MEM_MAPPER, tag, owner, clock)
43 	, m_cpu(*this, finder_base::DUMMY_TAG)
44 	, m_cpuregion(*this, finder_base::DUMMY_TAG)
45 	, m_mapper(*this)
46 	, m_pbf_callback(*this)
47 	, m_mcu_int_callback(*this)
48 	, m_space(nullptr)
49 	, m_decrypted_space(nullptr)
50 	, m_curregion(0)
51 	, m_to_sound(0)
52 	, m_from_sound(0)
53 	, m_open_bus_recurse(false)
54 {
55 }
56 
57 
58 //-------------------------------------------------
59 //  open_bus_r - return value from reading an
60 //  unmapped address
61 //-------------------------------------------------
62 
open_bus_r()63 u16 sega_315_5195_mapper_device::open_bus_r()
64 {
65 	// Unmapped memory returns the last word on the data bus, which is almost always the opcode
66 	// of the next instruction due to prefetch; however, since we may be encrypted, we actually
67 	// need to return the encrypted opcode, not the last decrypted data.
68 
69 	// Believe it or not, this is actually important for Cotton, which has the following evil
70 	// code: btst #0,$7038f7, which tests the low bit of an unmapped address, which thus should
71 	// return the prefetched value.
72 
73 	// prevent recursion
74 	if (!machine().side_effects_disabled())
75 	{
76 		if (m_open_bus_recurse)
77 			return 0xffff;
78 
79 		// read original encrypted memory at that address
80 		m_open_bus_recurse = true;
81 		const u16 result = m_space->read_word(m_cpu->pc());
82 		m_open_bus_recurse = false;
83 		return result;
84 	}
85 	return 0xffff;
86 }
87 
88 
89 //-------------------------------------------------
90 //  write - handle a write to the memory mapper
91 //-------------------------------------------------
92 
write(offs_t offset,u8 data)93 void sega_315_5195_mapper_device::write(offs_t offset, u8 data)
94 {
95 	// wraps every 32 bytes
96 	offset &= 0x1f;
97 
98 	LOG("(Write %02X = %02X)\n", offset, data);
99 
100 	// remember the previous value and swap in the new one
101 	const u8 oldval = m_regs[offset];
102 	m_regs[offset] = data;
103 
104 	// switch off the offset
105 	switch (offset)
106 	{
107 		case 0x02:
108 			// misc commands
109 			//   00 - resume execution after 03
110 			//   03 - maybe controls halt and reset lines together?
111 			if ((oldval ^ m_regs[offset]) & 3)
112 			{
113 				// fd1094_machine_init calls device_reset on the CPU, so we must do this afterwards
114 				m_cpu->set_input_line(INPUT_LINE_RESET, (m_regs[offset] & 3) == 3 ? ASSERT_LINE : CLEAR_LINE);
115 			}
116 			break;
117 
118 		case 0x03:
119 			// write through to the sound chip
120 			machine().scheduler().synchronize(timer_expired_delegate(FUNC(sega_315_5195_mapper_device::write_to_sound), this), data);
121 			break;
122 
123 		case 0x04:
124 			// controls IRQ lines to 68000, negative logic -- write $B to signal IRQ4
125 			if ((m_regs[offset] & 7) != 7)
126 				for (int irqnum = 0; irqnum < 8; irqnum++)
127 					m_cpu->set_input_line(irqnum, (irqnum == (~m_regs[offset] & 7)) ? HOLD_LINE : CLEAR_LINE);
128 			break;
129 
130 		case 0x05:
131 			// read/write control
132 			//   01 - write data latched in 00,01 to 2 * (address in 0A,0B,0C)
133 			//   02 - read data into latches 00,01 from 2 * (address in 07,08,09)
134 			if (data == 0x01)
135 			{
136 				const offs_t addr = (m_regs[0x0a] << 17) | (m_regs[0x0b] << 9) | (m_regs[0x0c] << 1);
137 				m_space->write_word(addr, (m_regs[0x00] << 8) | m_regs[0x01]);
138 			}
139 			else if (data == 0x02)
140 			{
141 				const offs_t addr = (m_regs[0x07] << 17) | (m_regs[0x08] << 9) | (m_regs[0x09] << 1);
142 				const u16 result = m_space->read_word(addr);
143 				m_regs[0x00] = result >> 8;
144 				m_regs[0x01] = result;
145 			}
146 			break;
147 
148 		case 0x07:  case 0x08:  case 0x09:
149 			// writes here latch a 68000 address for writing
150 			break;
151 
152 		case 0x0a:  case 0x0b:  case 0x0c:
153 			// writes here latch a 68000 address for reading
154 			break;
155 
156 		case 0x10:  case 0x11:
157 		case 0x12:  case 0x13:
158 		case 0x14:  case 0x15:
159 		case 0x16:  case 0x17:
160 		case 0x18:  case 0x19:
161 		case 0x1a:  case 0x1b:
162 		case 0x1c:  case 0x1d:
163 		case 0x1e:  case 0x1f:
164 			if (oldval != data)
165 				update_mapping();
166 			break;
167 
168 		default:
169 			logerror("Unknown memory_mapper_w to address %02X = %02X\n", offset, data);
170 			break;
171 	}
172 }
173 
174 
175 //-------------------------------------------------
176 //  read - handle a read from the memory mapper
177 //-------------------------------------------------
178 
read(address_space & space,offs_t offset)179 u8 sega_315_5195_mapper_device::read(address_space &space, offs_t offset)
180 {
181 	// wraps every 32 bytes
182 	offset &= 0x1f;
183 
184 	// switch off the offset
185 	switch (offset)
186 	{
187 		case 0x00:
188 		case 0x01:
189 			// data latches - return the values latched
190 			return m_regs[offset];
191 
192 		case 0x02:
193 			// various input bits from the 68000
194 			//   01 - ????
195 			//   02 - ????
196 			//   04 - ????
197 			//   08 - ????
198 			//   40 - set if busy processing a read/write request
199 			// Together, 01+02 == 00 if the 68000 is halted
200 			// Together, 01+02+04+08 == 0F if the 68000 is executing
201 			return (m_regs[0x02] & 3) == 3 ? 0x00 : 0x0f;
202 
203 		case 0x03:
204 			// this returns data that the sound CPU writes
205 			if (!m_mcu_int_callback.isnull() && !machine().side_effects_disabled())
206 				m_mcu_int_callback(CLEAR_LINE);
207 			return m_from_sound;
208 
209 		default:
210 			logerror("Unknown memory_mapper_r from address %02X\n", offset);
211 			break;
212 	}
213 	return (space.data_width() == 8) ? 0xff : open_bus_r();
214 }
215 
216 
217 //-------------------------------------------------
218 //  map_as_rom - map a region as ROM data
219 //-------------------------------------------------
220 
map_as_rom(u32 offset,u32 length,offs_t mirror,const char * bank_name,const char * decrypted_bank_name,offs_t rgnoffset,write16_delegate whandler)221 void sega_315_5195_mapper_device::map_as_rom(u32 offset, u32 length, offs_t mirror, const char *bank_name, const char *decrypted_bank_name, offs_t rgnoffset, write16_delegate whandler)
222 {
223 	// determine parameters
224 	region_info info;
225 	compute_region(info, m_curregion, length, mirror, offset);
226 	LOG("Map %06X-%06X (%06X) as ROM+%06X(%s) with handler=%s\n", info.start, info.end, info.mirror, rgnoffset, bank_name,
227 		whandler.isnull() ? "none" : whandler.name());
228 
229 	// don't map if the start is past the end of the ROM region
230 	const offs_t romsize = m_cpuregion->bytes();
231 	if (rgnoffset < romsize)
232 	{
233 		// clamp the end to the ROM size
234 		offs_t romend = info.end;
235 		if (rgnoffset + romend + 1 - info.start >= romsize)
236 			romend = romsize - 1 - rgnoffset + info.start;
237 
238 		// map now
239 		m_space->install_read_bank(info.start, romend, info.mirror, bank_name);
240 		if (m_decrypted_space)
241 			m_decrypted_space->install_read_bank(info.start, romend, info.mirror, decrypted_bank_name);
242 
243 		// configure the bank
244 		memory_bank *bank = owner()->membank(bank_name);
245 		memory_bank *decrypted_bank = owner()->membank(decrypted_bank_name);
246 		u8 *memptr = m_cpuregion->base() + rgnoffset;
247 		bank->set_base(memptr);
248 
249 		// remember this bank, and decrypt if necessary
250 		m_banks[m_curregion].set(bank, decrypted_bank, info.start, romend, rgnoffset, memptr);
251 	}
252 
253 	// either install a write handler if provided or unmap the region
254 	//
255 	// shdancer relies on this behaviour to prevent a write to ROM from
256 	// falling through to the memory-mapping registers and crashing the
257 	// game during stage 2-4 (see PC:$18a98). Protection maybe?
258 	if (!whandler.isnull())
259 		m_space->install_write_handler(info.start, info.end, 0, info.mirror, 0, whandler);
260 	else
261 		m_space->unmap_write(info.start, info.end | info.mirror);
262 }
263 
264 
265 //-------------------------------------------------
266 //  map_as_ram - map a region as RAM, with an
267 //  optional write handler
268 //-------------------------------------------------
269 
map_as_ram(u32 offset,u32 length,offs_t mirror,const char * bank_share_name,write16_delegate whandler)270 void sega_315_5195_mapper_device::map_as_ram(u32 offset, u32 length, offs_t mirror, const char *bank_share_name, write16_delegate whandler)
271 {
272 	// determine parameters
273 	region_info info;
274 	compute_region(info, m_curregion, length, mirror, offset);
275 	LOG("Map %06X-%06X (%06X) as RAM(%s) with handler=%s\n", info.start, info.end, info.mirror, bank_share_name,
276 		whandler.isnull() ? "none" : whandler.name());
277 
278 	// map now
279 	m_space->install_read_bank(info.start, info.end, info.mirror, bank_share_name);
280 
281 	// either install a write handler or a write bank, as appropriate
282 	if (!whandler.isnull())
283 		m_space->install_write_handler(info.start, info.end, 0, info.mirror, 0, whandler);
284 	else
285 		m_space->install_write_bank(info.start, info.end, info.mirror, bank_share_name);
286 
287 	// configure the bank
288 	memory_bank *bank = owner()->membank(bank_share_name);
289 	bank->set_base(owner()->memshare(bank_share_name)->ptr());
290 
291 	// clear this rom bank reference
292 	m_banks[m_curregion].clear();
293 }
294 
295 
296 //-------------------------------------------------
297 //  map_as_handler - map a region as a pair of
298 //  read write handlers
299 //-------------------------------------------------
300 
map_as_handler(u32 offset,u32 length,offs_t mirror,read16_delegate rhandler,write16_delegate whandler)301 void sega_315_5195_mapper_device::map_as_handler(u32 offset, u32 length, offs_t mirror, read16_delegate rhandler, write16_delegate whandler)
302 {
303 	// determine parameters
304 	region_info info;
305 	compute_region(info, m_curregion, length, mirror, offset);
306 	LOG("Map %06X-%06X (%06X) as handler read=%s write=%s\n", info.start, info.end, info.mirror,
307 		rhandler.isnull() ? "none" : rhandler.name(),
308 		whandler.isnull() ? "none" : whandler.name());
309 
310 	// install read/write handlers
311 	if (!rhandler.isnull())
312 		m_space->install_read_handler(info.start, info.end, 0, info.mirror, 0, rhandler);
313 	if (!whandler.isnull())
314 		m_space->install_write_handler(info.start, info.end, 0, info.mirror, 0, whandler);
315 
316 	// clear this rom bank reference
317 	m_banks[m_curregion].clear();
318 }
319 
320 
321 //-------------------------------------------------
322 //  configure_explicit - explicitly configure the
323 //  memory map
324 //-------------------------------------------------
325 
configure_explicit(const u8 * map_data)326 void sega_315_5195_mapper_device::configure_explicit(const u8 *map_data)
327 {
328 	memcpy(&m_regs[0x10], map_data, 0x10);
329 	update_mapping();
330 }
331 
332 
333 //-------------------------------------------------
334 //  fd1094_state_change - handle notifications
335 //  of state changes
336 //-------------------------------------------------
337 
fd1094_state_change(u8 state)338 void sega_315_5195_mapper_device::fd1094_state_change(u8 state)
339 {
340 	// iterate over regions and set the decrypted address of any ROM banks
341 	for (auto & elem : m_banks)
342 		elem.update();
343 }
344 
345 
346 //-------------------------------------------------
347 //  write_to_sound - write data for the sound CPU
348 //-------------------------------------------------
349 
TIMER_CALLBACK_MEMBER(sega_315_5195_mapper_device::write_to_sound)350 TIMER_CALLBACK_MEMBER(sega_315_5195_mapper_device::write_to_sound)
351 {
352 	m_to_sound = param;
353 	if (!m_pbf_callback.isnull())
354 		m_pbf_callback(ASSERT_LINE);
355 }
356 
357 
358 //-------------------------------------------------
359 //  write_from_sound - handle writes from the
360 //  sound CPU
361 //-------------------------------------------------
362 
TIMER_CALLBACK_MEMBER(sega_315_5195_mapper_device::write_from_sound)363 TIMER_CALLBACK_MEMBER(sega_315_5195_mapper_device::write_from_sound)
364 {
365 	m_from_sound = param;
366 	if (!m_mcu_int_callback.isnull())
367 		m_mcu_int_callback(ASSERT_LINE);
368 }
369 
370 
371 //-------------------------------------------------
372 //  pread - sound CPU read handler
373 //-------------------------------------------------
374 
pread()375 u8 sega_315_5195_mapper_device::pread()
376 {
377 	if (!m_pbf_callback.isnull() && !machine().side_effects_disabled())
378 		m_pbf_callback(CLEAR_LINE);
379 	return m_to_sound;
380 }
381 
382 
383 //-------------------------------------------------
384 //  pwrite - sound CPU write handler
385 //-------------------------------------------------
386 
pwrite(u8 data)387 void sega_315_5195_mapper_device::pwrite(u8 data)
388 {
389 	machine().scheduler().synchronize(timer_expired_delegate(FUNC(sega_315_5195_mapper_device::write_from_sound), this), data);
390 }
391 
392 
393 //-------------------------------------------------
394 //  device_start - device-specific startup
395 //-------------------------------------------------
396 
device_start()397 void sega_315_5195_mapper_device::device_start()
398 {
399 	// bind our handlers
400 	m_mapper.resolve();
401 	m_pbf_callback.resolve();
402 	m_mcu_int_callback.resolve();
403 
404 	// if we are mapping an FD1089, tell all the banks
405 	fd1089_base_device *fd1089 = dynamic_cast<fd1089_base_device *>(m_cpu.target());
406 	if (fd1089 != nullptr)
407 		for (auto & elem : m_banks)
408 			elem.set_decrypt(fd1089);
409 
410 	// if we are mapping an FD1094, register for state change notifications and tell all the banks
411 	fd1094_device *fd1094 = dynamic_cast<fd1094_device *>(m_cpu.target());
412 	if (fd1094 != nullptr)
413 	{
414 		fd1094->notify_state_change(fd1094_device::state_change_delegate(&sega_315_5195_mapper_device::fd1094_state_change, this));
415 		for (auto & elem : m_banks)
416 			elem.set_decrypt(fd1094);
417 	}
418 
419 	// find the address space that is to be mapped
420 	m_space = &m_cpu->space(AS_PROGRAM);
421 	if (m_space == nullptr)
422 		throw emu_fatalerror("Unable to find program address space on device '%s'", m_cpu.finder_tag());
423 
424 	m_decrypted_space = m_cpu->has_space(AS_OPCODES) ? &m_cpu->space(AS_OPCODES) : nullptr;
425 
426 	// register for saves
427 	save_item(NAME(m_regs));
428 	save_item(NAME(m_to_sound));
429 	save_item(NAME(m_from_sound));
430 }
431 
432 
433 //-------------------------------------------------
434 //  device_reset - device-specific reset
435 //-------------------------------------------------
436 
device_reset()437 void sega_315_5195_mapper_device::device_reset()
438 {
439 	// hold the CPU in reset
440 	m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
441 
442 	// clear registers and recompute the memory mapping
443 	std::fill(std::begin(m_regs), std::end(m_regs), 0);
444 	update_mapping();
445 
446 	// release the CPU
447 	m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
448 
449 	m_to_sound = 0;
450 	m_from_sound = 0;
451 	if (!m_pbf_callback.isnull())
452 		m_pbf_callback(CLEAR_LINE);
453 	if (!m_mcu_int_callback.isnull())
454 		m_mcu_int_callback(CLEAR_LINE);
455 }
456 
457 
458 //-------------------------------------------------
459 //  compute_region - determine region parameters
460 //  based on current configuration registers and
461 //  actual underlying bus connections
462 //-------------------------------------------------
463 
compute_region(region_info & info,u8 index,u32 length,u32 mirror,u32 offset)464 void sega_315_5195_mapper_device::compute_region(region_info &info, u8 index, u32 length, u32 mirror, u32 offset)
465 {
466 	static const offs_t region_size_map[4] = { 0x00ffff, 0x01ffff, 0x07ffff, 0x1fffff };
467 	info.size_mask = region_size_map[m_regs[0x10 + 2 * index] & 3];
468 	info.base = (m_regs[0x11 + 2 * index] << 16) & ~info.size_mask;
469 	info.mirror = mirror & info.size_mask;
470 	info.start = info.base + (offset & info.size_mask);
471 	info.end = info.start + std::min(length - 1, info.size_mask);
472 }
473 
474 
475 //-------------------------------------------------
476 //  update_mapping - remap the entire CPU address
477 //  space based on updated mappings
478 //-------------------------------------------------
479 
update_mapping()480 void sega_315_5195_mapper_device::update_mapping()
481 {
482 	LOG("---- Remapping:\n");
483 
484 	// first reset everything back to the beginning
485 	m_space->unmap_readwrite(0x000000, 0xffffff);
486 	m_space->install_read_handler(0x000000, 0xffffff, read8m_delegate(*this, FUNC(sega_315_5195_mapper_device::read)), 0x00ff);
487 	m_space->install_write_handler(0x000000, 0xffffff, write8sm_delegate(*this, FUNC(sega_315_5195_mapper_device::write)), 0x00ff);
488 
489 	// loop over the regions
490 	for (int index = 7; index >= 0; index--)
491 	{
492 		// note the current region and call the mapper to find out what to do
493 		m_curregion = index;
494 		m_mapper(*this, index);
495 	}
496 }
497 
498 
499 //**************************************************************************
500 //  DECRYPT BANK HELPER CLASS
501 //**************************************************************************
502 
503 //-------------------------------------------------
504 //  decrypt_bank - constructor
505 //-------------------------------------------------
506 
decrypt_bank()507 sega_315_5195_mapper_device::decrypt_bank::decrypt_bank()
508 	: m_bank(nullptr)
509 	, m_decrypted_bank(nullptr)
510 	, m_start(0)
511 	, m_end(0)
512 	, m_rgnoffs(~0)
513 	, m_srcptr(nullptr)
514 	, m_fd1089(nullptr)
515 {
516 	// invalidate all states
517 	reset();
518 }
519 
520 
521 //-------------------------------------------------
522 //  ~decrypt_bank - destructor
523 //-------------------------------------------------
524 
~decrypt_bank()525 sega_315_5195_mapper_device::decrypt_bank::~decrypt_bank()
526 {
527 }
528 
529 
530 //-------------------------------------------------
531 //  set_decrypt - configure the decryption target
532 //  CPU
533 //-------------------------------------------------
534 
set_decrypt(fd1089_base_device * fd1089)535 void sega_315_5195_mapper_device::decrypt_bank::set_decrypt(fd1089_base_device *fd1089)
536 {
537 	// set the fd1089 pointer
538 	m_fd1089 = fd1089;
539 
540 	// clear out all fd1094 stuff
541 	m_fd1094_cache.reset();
542 }
543 
set_decrypt(fd1094_device * fd1094)544 void sega_315_5195_mapper_device::decrypt_bank::set_decrypt(fd1094_device *fd1094)
545 {
546 	// set the fd1094 pointer and allocate a decryption cache
547 	m_fd1094_cache = std::make_unique<fd1094_decryption_cache>(*fd1094);
548 
549 	// clear out all fd1089 stuff
550 	m_fd1089 = nullptr;
551 	m_fd1089_decrypted.clear();
552 }
553 
554 
555 //-------------------------------------------------
556 //  set - set the parameters of this bank after
557 //  a change
558 //-------------------------------------------------
559 
set(memory_bank * bank,memory_bank * decrypted_bank,offs_t start,offs_t end,offs_t rgnoffs,u8 * src)560 void sega_315_5195_mapper_device::decrypt_bank::set(memory_bank *bank, memory_bank *decrypted_bank, offs_t start, offs_t end, offs_t rgnoffs, u8 *src)
561 {
562 	// ignore if not encrypted
563 	if (m_fd1089 == nullptr && m_fd1094_cache == nullptr)
564 		return;
565 
566 	// ignore if nothing is changing
567 	if (bank == m_bank && start == m_start && end == m_end && rgnoffs == m_rgnoffs && src == m_srcptr)
568 		return;
569 
570 	// if the start, end, or src change, throw away any cached data
571 	reset();
572 
573 	// update to the current state
574 	m_bank = bank;
575 	m_decrypted_bank = decrypted_bank;
576 	m_start = start;
577 	m_end = end;
578 	m_rgnoffs = rgnoffs;
579 	m_srcptr = src;
580 
581 	// configure the fd1094 cache
582 	if (m_fd1094_cache != nullptr)
583 		m_fd1094_cache->configure(m_start, m_end + 1 - m_start, m_rgnoffs);
584 
585 	// force an update of what we have
586 	update();
587 }
588 
589 
590 //-------------------------------------------------
591 //  update - update the decrypted memory base
592 //  if this rom bank has been assigned
593 //-------------------------------------------------
594 
update()595 void sega_315_5195_mapper_device::decrypt_bank::update()
596 {
597 	// if this isn't a valid state, don't try to do anything
598 	if (m_bank == nullptr || m_srcptr == nullptr)
599 		return;
600 
601 	// fd1089 case
602 	if (m_fd1089 != nullptr)
603 	{
604 		m_fd1089_decrypted.resize((m_end + 1 - m_start) / 2);
605 		m_fd1089->decrypt(m_start, m_end + 1 - m_start, m_rgnoffs, &m_fd1089_decrypted[0], reinterpret_cast<u16 *>(m_srcptr));
606 		m_decrypted_bank->set_base(&m_fd1089_decrypted[0]);
607 	}
608 
609 	// fd1094 case
610 	if (m_fd1094_cache != nullptr)
611 		m_decrypted_bank->set_base(m_fd1094_cache->decrypted_opcodes(m_fd1094_cache->fd1094().state()));
612 }
613