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