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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
// license: BSD-3-Clause
// copyright-holders: Angelo Salese
/**************************************************************************************************
Multigame cart mappers, with CMOS latching on power/reset
TODO:
- sportg mirroring is unconfirmed (may just rotate starting address instead);
**************************************************************************************************/
#include "emu.h"
#include "multigame.h"
#include "bus/generic/slot.h"
/*
* TecToy Sport Games
* https://segaretro.org/Sport_Games
*
* Sega MPR-19945-MX ROM with a 74HC74N and a 74HC00N attached.
* Games bankswitch also changes with power switch according to manual,
* for simplicity we just use /VRES only.
*
*
*/
DEFINE_DEVICE_TYPE(MEGADRIVE_TECTOY_SPORTS, megadrive_tectoy_sports_device, "megadrive_tectoy_sports", "Megadrive TecToy Sport Games cart")
megadrive_tectoy_sports_device::megadrive_tectoy_sports_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MEGADRIVE_TECTOY_SPORTS, tag, owner, clock)
, device_megadrive_cart_interface( mconfig, *this )
, m_rom(*this, "rom")
{
}
void megadrive_tectoy_sports_device::device_start()
{
memory_region *const romregion(cart_rom_region());
const u32 page_size = 0x10'0000;
device_generic_cart_interface::map_non_power_of_two(
unsigned(romregion->bytes() / page_size),
[this, base = &romregion->as_u8()] (unsigned entry, unsigned page)
{
m_rom->configure_entry(entry, &base[page * page_size]);
});
// m_rom_mirror = 0x30'0000;
// No info about what is the default game on cold boot, assume Super Volley Ball
m_game_sel = 2;
save_item(NAME(m_game_sel));
}
void megadrive_tectoy_sports_device::device_reset()
{
m_game_sel ++;
m_game_sel %= 3;
const std::string game_names[] = { "Super Volley Ball", "World Championship Soccer II", "Super Real Basketball" };
logerror("Game mounted: %s\n", game_names[m_game_sel]);
m_rom->set_entry(m_game_sel);
}
void megadrive_tectoy_sports_device::cart_map(address_map &map)
{
map(0x00'0000, 0x0f'ffff).mirror(0x30'0000).bankr(m_rom);
}
/*
* Codemasters 2-in-1
* https://segaretro.org/2_Games_on_One_Cart:_Fantastic_Dizzy_and_Cosmic_Spacehead
* https://segaretro.org/Double_Hits:_Micro_Machines_/_Psycho_Pinball
*
* "One of the games will begin: for example Cosmic Spacehead", again suggesting that cold boot
* may still have preserved (static) state.
*
*/
DEFINE_DEVICE_TYPE(MEGADRIVE_CM2IN1, megadrive_cm2in1_device, "megadrive_cm2in1", "Megadrive Codemasters 2 games on 1 cart")
megadrive_cm2in1_device::megadrive_cm2in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, MEGADRIVE_CM2IN1, tag, owner, clock)
, device_megadrive_cart_interface( mconfig, *this )
, m_rom(*this, "rom")
{
}
void megadrive_cm2in1_device::device_start()
{
memory_region *const romregion(cart_rom_region());
const u32 page_size = 0x20'0000;
device_generic_cart_interface::map_non_power_of_two(
unsigned(romregion->bytes() / page_size),
[this, base = &romregion->as_u8()] (unsigned entry, unsigned page)
{
m_rom->configure_entry(entry, &base[page * page_size]);
});
// start in a predictable manner
m_game_sel = 1;
save_item(NAME(m_game_sel));
}
void megadrive_cm2in1_device::device_reset()
{
m_game_sel ++;
m_game_sel &= 1;
m_rom->set_entry(m_game_sel);
}
void megadrive_cm2in1_device::cart_map(address_map &map)
{
map(0x00'0000, 0x1f'ffff).mirror(0x20'0000).bankr(m_rom);
}
/*
* 3 in 1 Flashback - World Championship Soccer - Tecmo World Cup 92
* 3 in 1 Road Rash - Ms. Pac-Man - Block Out
*
* Unknown source (pirate but with copyright text on back cover!?)
*
* Uneven bank scheme, the two soccer games lies at $18'0000 and $1c'0000 so we simplify with a
* memory_view. Road Rash cart is half total size/page size, so we need to capture ROM length at
* init time.
*
*/
DEFINE_DEVICE_TYPE(MEGADRIVE_3IN1FWT, megadrive_3in1fwt_device, "megadrive_3in1fwt", "Megadrive Flashback 3-in-1 cart")
megadrive_3in1fwt_device::megadrive_3in1fwt_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: megadrive_rom_device(mconfig, MEGADRIVE_3IN1FWT, tag, owner, clock)
, m_rom_bank(*this, "rom_bank")
, m_rom_view(*this, "rom_view")
{
}
void megadrive_3in1fwt_device::device_start()
{
megadrive_rom_device::device_start();
memory_region *const romregion(cart_rom_region());
m_rom_mask = romregion->bytes() - 1;
const u32 page_size = romregion->bytes() / 8;
device_generic_cart_interface::map_non_power_of_two(
unsigned(romregion->bytes() / page_size),
[this, base = &romregion->as_u8(), pg_mult = page_size] (unsigned entry, unsigned page)
{
m_rom_bank->configure_entry(entry, &base[page * pg_mult]);
});
m_page_mask = page_size - 1;
// start in a predictable manner
m_game_sel = 2;
save_item(NAME(m_game_sel));
}
void megadrive_3in1fwt_device::device_reset()
{
megadrive_rom_device::device_reset();
m_game_sel ++;
m_game_sel %= 3;
m_rom_view.select(m_game_sel);
// unknown order
if (m_game_sel != 0)
{
u8 page_sel = 6 + ((m_game_sel & 1) ^ 1);
logerror("Page selection %02x\n", page_sel);
m_rom_bank->set_entry(page_sel);
}
}
void megadrive_3in1fwt_device::cart_map(address_map &map)
{
map(0x00'0000, m_rom_mask).view(m_rom_view);
m_rom_view[0](0x00'0000, m_rom_mask ).bankr(m_rom);
m_rom_view[1](0x00'0000, m_page_mask).bankr(m_rom_bank);
m_rom_view[2](0x00'0000, m_page_mask).bankr(m_rom_bank);
}
|