openMSX
RomGameMaster2.cc
Go to the documentation of this file.
1// GAME MASTER 2
2//
3// This is a 1 megabit ROM cartridge with 8 Kb SRAM. Because of the SRAM,
4// the mappers have special features.
5//
6// Since the size of the mapper is 8Kb, the memory banks are:
7// Bank 1: 4000h - 5FFFh
8// Bank 2: 6000h - 7FFFh
9// Bank 3: 8000h - 9FFFh
10// Bank 4: A000h - BFFFh
11//
12// And the addresses to change banks:
13// Bank 1: <none>
14// Bank 2: 6000h - 6FFFh (6000h used)
15// Bank 3: 8000h - 8FFFh (8000h used)
16// Bank 4: A000h - AFFFh (A000h used)
17// SRAM write: B000h - BFFFh
18//
19// If SRAM is selected in bank 4, you can write to it in the memory area
20// B000h - BFFFh.
21//
22// The value you write to change banks also determines whether you select ROM
23// or SRAM. SRAM can be in any memory bank (except bank 1 which can't be
24// modified) but it can only be written too in bank 4.
25//
26// bit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
27// ----------------------------------------------------------
28// function | R0 | R1 | R2 | R3 | 1=SRAM/0=ROM | S0 | X | X |
29//
30// If bit 4 is reset, bits 0 - 3 select the ROM page as you would expect them
31// to do. Bits 5 - 7 are ignored now. If bit 4 is set, bit 5 selects the SRAM
32// page (first or second 4Kb of the 8Kb). Bits 6 - 7 and bits 0 - 3 are
33// ignored now.
34//
35// Since you can only select 4Kb of the SRAM at once in a memory bank and a
36// memory bank is 8Kb in size, the first and second 4Kb of the memory bank
37// read the same 4Kb of SRAM if SRAM is selected.
38
39#include "RomGameMaster2.hh"
40#include "SRAM.hh"
41#include "serialize.hh"
42#include "xrange.hh"
43#include <memory>
44
45namespace openmsx {
46
48 : Rom4kBBlocks(config, std::move(rom_), 1)
49{
50 sram = std::make_unique<SRAM>(getName() + " SRAM", 0x2000, config);
51 reset(EmuTime::dummy());
52}
53
54void RomGameMaster2::reset(EmuTime::param /*time*/)
55{
56 for (auto i : xrange(4)) {
57 setUnmapped(i);
58 }
59 for (auto i : xrange(4, 12)) {
60 setRom(i, i - 4);
61 }
62 for (auto i : xrange(12, 16)) {
63 setUnmapped(i);
64 }
65 sramOffset = 0;
66 sramEnabled = false;
67}
68
69void RomGameMaster2::writeMem(word address, byte value, EmuTime::param /*time*/)
70{
71 if ((0x6000 <= address) && (address < 0xB000)) {
72 if (!(address & 0x1000)) {
73 byte region = address >> 12; // 0x6, 0x8 or 0xA
74 if (region == 0x0A) {
75 sramEnabled = (value & 0x10) != 0;
76 invalidateDeviceWCache(0xB000, 0x1000); // 'R' is handled below
77 }
78 if (value & 0x10) {
79 // switch SRAM
80 sramOffset = (value & 0x20) ? 0x1000: 0x0000;
81 setBank(region, &(*sram)[sramOffset], value);
82 setBank(region + 1, &(*sram)[sramOffset], value);
83 } else {
84 // switch ROM
85 setRom(region, 2 * (value & 0x0F));
86 setRom(region + 1, 2 * (value & 0x0F) + 1);
87 }
88 }
89 } else if ((0xB000 <= address) && (address < 0xC000)) {
90 // write SRAM
91 if (sramEnabled) {
92 sram->write(sramOffset | (address & 0x0FFF), value);
93 }
94 }
95}
96
98{
99 if ((0x6000 <= address) && (address < 0xB000)) {
100 if (!(address & 0x1000)) {
101 return nullptr;
102 } else {
103 return unmappedWrite.data();
104 }
105 } else if ((0xB000 <= address) && (address < 0xC000) && sramEnabled) {
106 // write SRAM
107 return nullptr;
108 } else {
109 return unmappedWrite.data();
110 }
111}
112
113template<typename Archive>
114void RomGameMaster2::serialize(Archive& ar, unsigned /*version*/)
115{
116 ar.template serializeBase<Rom4kBBlocks>(*this);
117 ar.serialize("sramOffset", sramOffset,
118 "sramEnabled", sramEnabled);
119}
122
123} // namespace openmsx
void invalidateDeviceWCache()
Definition: MSXDevice.hh:212
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:375
static std::array< byte, 0x10000 > unmappedWrite
Definition: MSXDevice.hh:303
std::unique_ptr< SRAM > sram
Definition: RomBlocks.hh:85
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:103
void setBank(byte region, const byte *adr, byte block)
Sets the memory visible for reading in a certain region.
Definition: RomBlocks.cc:77
void setUnmapped(byte region)
Select 'unmapped' memory for this region.
Definition: RomBlocks.cc:91
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void reset(EmuTime::param time) override
This method is called on reset.
RomGameMaster2(const DeviceConfig &config, Rom &&rom)
void writeMem(word address, byte value, EmuTime::param time) override
Write a given byte to a given location at a certain time to this device.
void serialize(Archive &ar, unsigned version)
This file implemented 3 utility functions:
Definition: Autofire.cc:9
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1021
constexpr auto xrange(T e)
Definition: xrange.hh:133