OXYGENHUB
◆ main openmsx / src / memory / MegaFlashRomSCCPlusSD.hh
5.4 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef MEGAFLASHROMSCCPLUSSD_HH
2
#define MEGAFLASHROMSCCPLUSSD_HH
3
4
#include "AmdFlash.hh"
5
#include "MSXMapperIO.hh"
6
7
#include "AY8910.hh"
8
#include "MSXDevice.hh"
9
#include "SCC.hh"
10
11
#include <array>
12
#include <cstdint>
13
#include <memory>
14
15
namespace openmsx {
16
17
class CheckedRam;
18
class SdCard;
19
20
class MegaFlashRomSCCPlusSD final : public MSXDevice
21
{
22
public:
23
	explicit MegaFlashRomSCCPlusSD(DeviceConfig& config);
24
	~MegaFlashRomSCCPlusSD() override;
25
26
	void powerUp(EmuTime time) override;
27
	void reset(EmuTime time) override;
28
	[[nodiscard]] byte peekMem(uint16_t address, EmuTime time) const override;
29
	[[nodiscard]] byte readMem(uint16_t address, EmuTime time) override;
30
	[[nodiscard]] const byte* getReadCacheLine(uint16_t address) const override;
31
	void writeMem(uint16_t address, byte value, EmuTime time) override;
32
	[[nodiscard]] byte* getWriteCacheLine(uint16_t address) override;
33
34
	void writeIO(uint16_t port, byte value, EmuTime time) override;
35
36
	template<typename Archive>
37
	void serialize(Archive& ar, unsigned version);
38
39
private:
40
	enum SCCEnable : uint8_t { EN_NONE, EN_SCC, EN_SCCPLUS };
41
	[[nodiscard]] SCCEnable getSCCEnable() const;
42
	void updateConfigReg(byte value);
43
44
	[[nodiscard]] byte getSubSlot(unsigned addr) const;
45
46
	/**
47
	 * Writes to flash only if it was not write protected.
48
	 */
49
	void writeToFlash(unsigned addr, byte value, EmuTime time);
50
	AmdFlash flash;
51
	byte subslotReg;
52
53
	// subslot 0
54
	[[nodiscard]] byte readMemSubSlot0(uint16_t address, EmuTime time);
55
	[[nodiscard]] byte peekMemSubSlot0(uint16_t address, EmuTime time) const;
56
	[[nodiscard]] const byte* getReadCacheLineSubSlot0(uint16_t address) const;
57
	[[nodiscard]] byte* getWriteCacheLineSubSlot0(uint16_t address);
58
	void writeMemSubSlot0(uint16_t address, byte value, EmuTime time);
59
60
	// subslot 1
61
	// mega flash rom scc+
62
	[[nodiscard]] byte readMemSubSlot1(uint16_t address, EmuTime time);
63
	[[nodiscard]] byte peekMemSubSlot1(uint16_t address, EmuTime time) const;
64
	[[nodiscard]] const byte* getReadCacheLineSubSlot1(uint16_t address) const;
65
	[[nodiscard]] byte* getWriteCacheLineSubSlot1(uint16_t address);
66
	void writeMemSubSlot1(uint16_t address, byte value, EmuTime time);
67
	[[nodiscard]] unsigned getFlashAddrSubSlot1(unsigned addr) const;
68
69
	SCC scc;
70
	AY8910 psg;
71
72
	byte mapperReg;
73
	[[nodiscard]] bool is64KmapperConfigured()               const { return (mapperReg & 0xC0) == 0x40; }
74
	[[nodiscard]] bool isKonamiSCCmapperConfigured()         const { return (mapperReg & 0xE0) == 0x00; }
75
	[[nodiscard]] bool isWritingKonamiBankRegisterDisabled() const { return (mapperReg & 0x08) != 0; }
76
	[[nodiscard]] bool isMapperRegisterDisabled()            const { return (mapperReg & 0x04) != 0; }
77
	[[nodiscard]] bool areBankRegsAndOffsetRegsDisabled()    const { return (mapperReg & 0x02) != 0; }
78
	[[nodiscard]] bool areKonamiMapperLimitsEnabled()        const { return (mapperReg & 0x01) != 0; }
79
	unsigned offsetReg;
80
81
	byte configReg = 3; // avoid UMR
82
	[[nodiscard]] bool isConfigRegDisabled()           const { return  (configReg & 0x80) != 0; }
83
	[[nodiscard]] bool isMemoryMapperEnabled()         const { return ((configReg & 0x20) == 0) && checkedRam; }
84
	[[nodiscard]] bool isDSKmodeEnabled()              const { return  (configReg & 0x10) != 0; }
85
	[[nodiscard]] bool isPSGalsoMappedToNormalPorts()  const { return  (configReg & 0x08) != 0; }
86
	[[nodiscard]] bool isSlotExpanderEnabled()         const { return  (configReg & 0x04) == 0; }
87
	[[nodiscard]] bool isFlashRomBlockProtectEnabled() const { return  (configReg & 0x02) != 0; }
88
	[[nodiscard]] bool isFlashRomWriteEnabled()        const { return  (configReg & 0x01) != 0; }
89
90
	// Note: the bankRegsSubSlot1 registers are actually only 9 bit.
91
	std::array<uint16_t, 4> bankRegsSubSlot1;
92
	byte psgLatch;
93
	byte sccMode;
94
	std::array<byte, 4> sccBanks;
95
96
	// subslot 2
97
	// 512k memory mapper
98
	[[nodiscard]] byte readMemSubSlot2(uint16_t address);
99
	[[nodiscard]] byte peekMemSubSlot2(uint16_t address) const;
100
	[[nodiscard]] const byte* getReadCacheLineSubSlot2(uint16_t address) const;
101
	[[nodiscard]] byte* getWriteCacheLineSubSlot2(uint16_t address);
102
	void writeMemSubSlot2(uint16_t address, byte value);
103
104
	[[nodiscard]] unsigned calcMemMapperAddress(uint16_t address) const;
105
	[[nodiscard]] unsigned calcAddress(uint16_t address) const;
106
107
	class MapperIO final : public MSXMapperIOClient {
108
	public:
109
		explicit MapperIO(MegaFlashRomSCCPlusSD& mega_)
110
			: MSXMapperIOClient(mega_.getMotherBoard())
111
			, mega(mega_)
112
		{
113
		}
114
115
		[[nodiscard]] byte readIO(uint16_t port, EmuTime time) override;
116
		[[nodiscard]] byte peekIO(uint16_t port, EmuTime time) const override;
117
		void writeIO(uint16_t port, byte value, EmuTime time) override;
118
		[[nodiscard]] byte getSelectedSegment(byte page) const override;
119
120
	private:
121
		MegaFlashRomSCCPlusSD& mega;
122
	};
123
	const std::unique_ptr<CheckedRam> checkedRam; // can be nullptr
124
	const std::unique_ptr<MapperIO> mapperIO; // nullptr iff checkedRam == nullptr
125
	std::array<byte, 4> memMapperRegs;
126
127
	// subslot 3
128
	[[nodiscard]] byte readMemSubSlot3(uint16_t address, EmuTime time);
129
	[[nodiscard]] byte peekMemSubSlot3(uint16_t address, EmuTime time) const;
130
	[[nodiscard]] const byte* getReadCacheLineSubSlot3(uint16_t address) const;
131
	[[nodiscard]] byte* getWriteCacheLineSubSlot3(uint16_t address);
132
	void writeMemSubSlot3(uint16_t address, byte value, EmuTime time);
133
	[[nodiscard]] unsigned getFlashAddrSubSlot3(unsigned addr) const;
134
135
	std::array<byte, 4> bankRegsSubSlot3;
136
137
	byte selectedCard;
138
	std::array<std::unique_ptr<SdCard>, 2> sdCard;
139
};
140
141
} // namespace openmsx
142
143
#endif