openMSX
RomNational.cc
Go to the documentation of this file.
1#include "RomNational.hh"
2#include "CacheLine.hh"
3#include "SRAM.hh"
4#include "one_of.hh"
5#include "serialize.hh"
6#include "xrange.hh"
7#include <memory>
8
9namespace openmsx {
10
12 : Rom16kBBlocks(config, std::move(rom_))
13{
14 sram = std::make_unique<SRAM>(getName() + " SRAM", 0x1000, config);
15 reset(EmuTime::dummy());
16}
17
18void RomNational::reset(EmuTime::param /*time*/)
19{
20 control = 0;
21 for (auto region : xrange(4)) {
22 setRom(region, 0);
23 bankSelect[region] = 0;
24 invalidateDeviceRCache((region * 0x4000) + (0x3FF0 & CacheLine::HIGH),
26 }
27 sramAddr = 0; // TODO check this
28}
29
30byte RomNational::peekMem(word address, EmuTime::param time) const
31{
32 if ((control & 0x04) && ((address & 0x7FF9) == 0x7FF0)) {
33 // TODO check mirrored
34 // 7FF0 7FF2 7FF4 7FF6 bank select read back
35 int bank = (address & 6) / 2;
36 return bankSelect[bank];
37 }
38 if ((control & 0x02) && ((address & 0x3FFF) == 0x3FFD)) {
39 // SRAM read
40 return (*sram)[sramAddr & 0x0FFF];
41 }
42 return Rom16kBBlocks::peekMem(address, time);
43}
44
45byte RomNational::readMem(word address, EmuTime::param time)
46{
47 byte result = RomNational::peekMem(address, time);
48 if ((control & 0x02) && ((address & 0x3FFF) == 0x3FFD)) {
49 ++sramAddr;
50 }
51 return result;
52}
53
54const byte* RomNational::getReadCacheLine(word address) const
55{
56 if ((0x3FF0 & CacheLine::HIGH) == (address & 0x3FFF)) {
57 return nullptr;
58 } else {
59 return Rom16kBBlocks::getReadCacheLine(address);
60 }
61}
62
63void RomNational::writeMem(word address, byte value, EmuTime::param /*time*/)
64{
65 // TODO bank switch address mirrored?
66 if (address == 0x6000) {
67 bankSelect[1] = value;
68 setRom(1, value); // !!
70 } else if (address == 0x6400) {
71 bankSelect[0] = value;
72 setRom(0, value); // !!
74 } else if (address == 0x7000) {
75 bankSelect[2] = value;
76 setRom(2, value);
78 } else if (address == 0x7400) {
79 bankSelect[3] = value;
80 setRom(3, value);
82 } else if (address == 0x7FF9) {
83 // write control byte
84 control = value;
85 } else if (control & 0x02) {
86 address &= 0x3FFF;
87 if (address == 0x3FFA) {
88 // SRAM address bits 23-16
89 sramAddr = (sramAddr & 0x00FFFF) | value << 16;
90 } else if (address == 0x3FFB) {
91 // SRAM address bits 15-8
92 sramAddr = (sramAddr & 0xFF00FF) | value << 8;
93 } else if (address == 0x3FFC) {
94 // SRAM address bits 7-0
95 sramAddr = (sramAddr & 0xFFFF00) | value;
96 } else if (address == 0x3FFD) {
97 sram->write((sramAddr++ & 0x0FFF), value);
98 }
99 }
100}
101
103{
104 if (address == one_of(0x6000 & CacheLine::HIGH,
105 0x6400 & CacheLine::HIGH,
106 0x7000 & CacheLine::HIGH,
107 0x7400 & CacheLine::HIGH,
108 0x7FF9 & CacheLine::HIGH)) {
109 return nullptr;
110 } else if ((address & 0x3FFF) == (0x3FFA & CacheLine::HIGH)) {
111 return nullptr;
112 } else {
113 return unmappedWrite.data();
114 }
115}
116
117template<typename Archive>
118void RomNational::serialize(Archive& ar, unsigned /*version*/)
119{
120 ar.template serializeBase<Rom16kBBlocks>(*this);
121 ar.serialize("control", control,
122 "sramAddr", sramAddr,
123 "bankSelect", bankSelect);
124}
127
128} // namespace openmsx
#define REGISTER_MSXDEVICE(CLASS, NAME)
Definition MSXDevice.hh:356
void invalidateDeviceRCache()
Definition MSXDevice.hh:215
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:307
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
Definition RomBlocks.cc:60
std::unique_ptr< SRAM > sram
Definition RomBlocks.hh:85
void setRom(unsigned region, unsigned block)
Selects a block of the ROM image for reading in a certain region.
Definition RomBlocks.cc:104
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
Definition RomBlocks.cc:72
RomNational(const DeviceConfig &config, Rom &&rom)
void reset(EmuTime::param time) override
This method is called on reset.
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.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
void serialize(Archive &ar, unsigned version)
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
constexpr unsigned HIGH
Definition CacheLine.hh:10
constexpr unsigned SIZE
Definition CacheLine.hh:7
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
STL namespace.
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
constexpr auto xrange(T e)
Definition xrange.hh:132