RomGameMaster2.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  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. #include "RomGameMaster2.hh"
  39. #include "SRAM.hh"
  40. #include "serialize.hh"
  41. #include <memory>
  42. namespace openmsx {
  43. RomGameMaster2::RomGameMaster2(const DeviceConfig& config, Rom&& rom_)
  44. : Rom4kBBlocks(config, std::move(rom_), 1)
  45. {
  46. sram = std::make_unique<SRAM>(getName() + " SRAM", 0x2000, config);
  47. reset(EmuTime::dummy());
  48. }
  49. void RomGameMaster2::reset(EmuTime::param /*time*/)
  50. {
  51. for (int i = 0; i < 4; i++) {
  52. setUnmapped(i);
  53. }
  54. for (int i = 4; i < 12; i++) {
  55. setRom(i, i - 4);
  56. }
  57. for (int i = 12; i < 16; i++) {
  58. setUnmapped(i);
  59. }
  60. sramOffset = 0;
  61. sramEnabled = false;
  62. }
  63. void RomGameMaster2::writeMem(word address, byte value, EmuTime::param /*time*/)
  64. {
  65. if ((0x6000 <= address) && (address < 0xB000)) {
  66. if (!(address & 0x1000)) {
  67. byte region = address >> 12; // 0x6, 0x8 or 0xA
  68. if (region == 0x0A) {
  69. sramEnabled = (value & 0x10) != 0;
  70. invalidateDeviceWCache(0xB000, 0x1000); // 'R' is handled below
  71. }
  72. if (value & 0x10) {
  73. // switch SRAM
  74. sramOffset = (value & 0x20) ? 0x1000: 0x0000;
  75. setBank(region, &(*sram)[sramOffset], value);
  76. setBank(region + 1, &(*sram)[sramOffset], value);
  77. } else {
  78. // switch ROM
  79. setRom(region, 2 * (value & 0x0F));
  80. setRom(region + 1, 2 * (value & 0x0F) + 1);
  81. }
  82. }
  83. } else if ((0xB000 <= address) && (address < 0xC000)) {
  84. // write SRAM
  85. if (sramEnabled) {
  86. sram->write(sramOffset | (address & 0x0FFF), value);
  87. }
  88. }
  89. }
  90. byte* RomGameMaster2::getWriteCacheLine(word address) const
  91. {
  92. if ((0x6000 <= address) && (address < 0xB000)) {
  93. if (!(address & 0x1000)) {
  94. return nullptr;
  95. } else {
  96. return unmappedWrite;
  97. }
  98. } else if ((0xB000 <= address) && (address < 0xC000) && sramEnabled) {
  99. // write SRAM
  100. return nullptr;
  101. } else {
  102. return unmappedWrite;
  103. }
  104. }
  105. template<typename Archive>
  106. void RomGameMaster2::serialize(Archive& ar, unsigned /*version*/)
  107. {
  108. ar.template serializeBase<Rom4kBBlocks>(*this);
  109. ar.serialize("sramOffset", sramOffset,
  110. "sramEnabled", sramEnabled);
  111. }
  112. INSTANTIATE_SERIALIZE_METHODS(RomGameMaster2);
  113. REGISTER_MSXDEVICE(RomGameMaster2, "RomGameMaster2");
  114. } // namespace openmsx