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 <memory>
43 
44 namespace openmsx {
45 
47  : Rom4kBBlocks(config, std::move(rom_), 1)
48 {
49  sram = std::make_unique<SRAM>(getName() + " SRAM", 0x2000, config);
50  reset(EmuTime::dummy());
51 }
52 
53 void RomGameMaster2::reset(EmuTime::param /*time*/)
54 {
55  for (int i = 0; i < 4; i++) {
56  setUnmapped(i);
57  }
58  for (int i = 4; i < 12; i++) {
59  setRom(i, i - 4);
60  }
61  for (int i = 12; i < 16; i++) {
62  setUnmapped(i);
63  }
64  sramOffset = 0;
65  sramEnabled = false;
66 }
67 
68 void RomGameMaster2::writeMem(word address, byte value, EmuTime::param /*time*/)
69 {
70  if ((0x6000 <= address) && (address < 0xB000)) {
71  if (!(address & 0x1000)) {
72  byte region = address >> 12; // 0x6, 0x8 or 0xA
73  if (region == 0x0A) {
74  sramEnabled = (value & 0x10) != 0;
75  }
76  if (value & 0x10) {
77  // switch SRAM
78  sramOffset = (value & 0x20) ? 0x1000: 0x0000;
79  setBank(region, &(*sram)[sramOffset], value);
80  setBank(region + 1, &(*sram)[sramOffset], value);
81  } else {
82  // switch ROM
83  setRom(region, 2 * (value & 0x0F));
84  setRom(region + 1, 2 * (value & 0x0F) + 1);
85  }
86  }
87  } else if ((0xB000 <= address) && (address < 0xC000)) {
88  // write SRAM
89  if (sramEnabled) {
90  sram->write(sramOffset | (address & 0x0FFF), value);
91  }
92  }
93 }
94 
96 {
97  if ((0x6000 <= address) && (address < 0xB000)) {
98  if (!(address & 0x1000)) {
99  return nullptr;
100  } else {
101  return unmappedWrite;
102  }
103  } else if ((0xB000 <= address) && (address < 0xC000) && sramEnabled) {
104  // write SRAM
105  return nullptr;
106  } else {
107  return unmappedWrite;
108  }
109 }
110 
111 template<typename Archive>
112 void RomGameMaster2::serialize(Archive& ar, unsigned /*version*/)
113 {
114  ar.template serializeBase<Rom4kBBlocks>(*this);
115  ar.serialize("sramOffset", sramOffset,
116  "sramEnabled", sramEnabled);
117 }
119 REGISTER_MSXDEVICE(RomGameMaster2, "RomGameMaster2");
120 
121 } // namespace openmsx
void setRom(byte region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition: RomBlocks.cc:98
uint8_t byte
8 bit unsigned integer
Definition: openmsx.hh:26
STL namespace.
virtual std::string getName() const
Returns a human-readable name for this device.
Definition: MSXDevice.cc:370
REGISTER_MSXDEVICE(ChakkariCopy, "ChakkariCopy")
void setBank(byte region, const byte *adr, int block)
Sets the memory visible for reading in a certain region.
Definition: RomBlocks.cc:71
void reset(EmuTime::param time) override
This method is called on reset.
byte * getWriteCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing...
RomGameMaster2(const DeviceConfig &config, Rom &&rom)
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
uint16_t word
16 bit unsigned integer
Definition: openmsx.hh:29
static byte unmappedWrite[0x10000]
Definition: MSXDevice.hh:275
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:981
void setUnmapped(byte region)
Select &#39;unmapped&#39; memory for this region.
Definition: RomBlocks.cc:85
std::unique_ptr< SRAM > sram
Definition: RomBlocks.hh:82
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)