1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/***********************************************************************************************************
Sonic & Knuckles pass-thorugh cart emulation
TODO: This could potentially make use of memory views. Investigate.
***********************************************************************************************************/
#include "emu.h"
#include "sk.h"
#include "rom.h"
#include "md_carts.h"
//-------------------------------------------------
// md_rom_device - constructor
//-------------------------------------------------
DEFINE_DEVICE_TYPE(MD_ROM_SK, md_rom_sk_device, "md_rom_sk", "MD Sonic & Knuckles")
md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
, device_md_cart_interface(mconfig, *this)
, m_exp(*this, "subslot")
, m_map_upper(false)
{
}
md_rom_sk_device::md_rom_sk_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: md_rom_sk_device(mconfig, MD_ROM_SK, tag, owner, clock)
{
}
void md_rom_sk_device::device_start()
{
save_item(NAME(m_map_upper));
}
void md_rom_sk_device::device_reset()
{
m_map_upper = false;
}
/*-------------------------------------------------
mapper specific handlers
-------------------------------------------------*/
uint16_t md_rom_sk_device::read(offs_t offset)
{
if (m_map_upper)
{
if (offset >= 0x300000/2)
return m_rom[MD_ADDR(offset)]; // Sonic 2 patch ROM
else if (m_exp->m_cart != nullptr && m_exp->m_cart->get_rom_base() != nullptr && offset >= 0x200000/2)
return m_exp->m_cart->read(offset); // Sonic 3 ROM pass-through or FRAM
}
if (m_exp->m_cart != nullptr && m_exp->m_cart->get_rom_base() != nullptr && offset >= 0x200000/2)
return m_exp->m_cart->read(offset - 0x200000/2);
if (offset < 0x400000/2)
return m_rom[MD_ADDR(offset)];
else
return 0xffff;
}
void md_rom_sk_device::write(offs_t offset, uint16_t data, uint16_t mem_mask)
{
if (m_exp->m_cart == nullptr || m_exp->m_cart->get_rom_base() == nullptr)
return;
if (m_map_upper)
m_exp->m_cart->write(offset, data, mem_mask);
else if (offset >= 0x200000/2)
m_exp->m_cart->write(offset - 0x200000/2, data, mem_mask);
}
uint16_t md_rom_sk_device::read_a13(offs_t offset)
{
if (m_exp->m_cart != nullptr && m_exp->m_cart->get_rom_base() != nullptr)
return m_exp->m_cart->read_a13(offset);
return 0xffff;
}
void md_rom_sk_device::write_a13(offs_t offset, uint16_t data)
{
if (m_exp->m_cart != nullptr && m_exp->m_cart->get_rom_base() != nullptr)
m_exp->m_cart->write_a13(offset, data);
if (offset == 0xf0/2)
m_map_upper = BIT(data, 0);
}
static void sk_sub_cart(device_slot_interface &device)
{
// Inherit all cartridge types; cartridges <= 2 megabytes in size are mirrored into the upper 2 megabytes by the Sonic & Knuckles cartridge.
md_cart(device);
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void md_rom_sk_device::device_add_mconfig(machine_config &config)
{
MD_CART_SLOT(config, m_exp, sk_sub_cart, nullptr);
m_exp->set_must_be_loaded(false);
}
|