OXYGENHUB
◆ main openmsx / src / memory / Carnivore2.hh
5.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef CARNIVORE2_HH
2
#define CARNIVORE2_HH
3
4
#include "AmdFlash.hh"
5
#include "EEPROM_93C46.hh"
6
#include "MSXMapperIO.hh"
7
#include "Ram.hh"
8
9
#include "AY8910.hh"
10
#include "MSXCPUInterface.hh"
11
#include "MSXDevice.hh"
12
#include "SCC.hh"
13
#include "YM2413.hh"
14
#include "serialize_meta.hh"
15
16
#include "Math.hh"
17
18
#include <array>
19
#include <cstdint>
20
#include <utility>
21
22
namespace openmsx {
23
24
class IDEDevice;
25
26
class Carnivore2 final
27
	: public MSXDevice
28
	, public MSXMapperIOClient
29
	, public GlobalReadClient<Carnivore2, CT_Interval<0x0000>, CT_Interval<0x4000, 0x4010>>
30
{
31
public:
32
	explicit Carnivore2(DeviceConfig& config);
33
	~Carnivore2() override;
34
35
	void powerUp(EmuTime time) override;
36
	void reset(EmuTime time) override;
37
38
	[[nodiscard]] byte readMem(uint16_t address, EmuTime time) override;
39
	[[nodiscard]] byte peekMem(uint16_t address, EmuTime time) const override;
40
	void writeMem(uint16_t address, byte value, EmuTime time) override;
41
	void globalRead(uint16_t address, EmuTime time) override;
42
43
	[[nodiscard]] byte readIO(uint16_t port, EmuTime time) override;
44
	[[nodiscard]] byte peekIO(uint16_t port, EmuTime time) const override;
45
	void writeIO(uint16_t port, byte value, EmuTime time) override;
46
	[[nodiscard]] byte getSelectedSegment(byte page) const override;
47
48
	template<typename Archive>
49
	void serialize(Archive& ar, unsigned version);
50
51
private:
52
	// config regs
53
	[[nodiscard]] unsigned getDirectFlashAddr() const;
54
	[[nodiscard]] byte peekConfigRegister(uint16_t address, EmuTime time) const;
55
	[[nodiscard]] byte readConfigRegister(uint16_t address, EmuTime time);
56
	void writeSndLVL(byte value, EmuTime time);
57
	void writeCfgEEPR(byte value, EmuTime time);
58
	void writePSGCtrl(byte value, EmuTime time);
59
	void writePSGAlt(byte value);
60
	void writePFXN(byte value);
61
	void writeConfigRegister(uint16_t address, byte value, EmuTime time);
62
63
	[[nodiscard]] bool sccEnabled()        const { return configRegs[0x00] & 0x10; }
64
	[[nodiscard]] bool delayedConfig()     const { return configRegs[0x00] & 0x08; }
65
	[[nodiscard]] bool delayedConfig4000() const { return configRegs[0x00] & 0x04; }
66
	[[nodiscard]] bool readBIOSfromRAM()   const { return configRegs[0x00] & 0x02; }
67
68
	[[nodiscard]] bool slotExpanded() const { return configRegs[0x1e] & 0x80; }
69
	[[nodiscard]] bool memMapReadEnabled() const {
70
		return (configRegs[0x1e] & 0x40) && !(port3C & 0x20);
71
	}
72
	[[nodiscard]] bool fmPacPortEnabled2() const { return configRegs[0x1e] & 0x20; }
73
	[[nodiscard]] bool subSlotEnabled(unsigned slot) const {
74
		assert(slot < 4);
75
		return configRegs[0x1e] & (1 << slot);
76
	}
77
	[[nodiscard]] bool writePort3cEnabled() const {
78
		return (configRegs[0x1e] & 0x10) && !(port3C & 0x20);
79
	}
80
81
	enum class SubDevice : uint8_t { MultiMapper, IDE, MemoryMapper, FmPac, Nothing };
82
83
	[[nodiscard]] SubDevice getSubDevice(uint16_t address) const;
84
85
	// multi-mapper
86
	[[nodiscard]] bool isConfigReg(uint16_t address) const;
87
	[[nodiscard]] std::pair<unsigned, byte> decodeMultiMapper(uint16_t address) const;
88
	[[nodiscard]] bool sccAccess(uint16_t address) const;
89
	[[nodiscard]] byte readMultiMapperSlot(uint16_t address, EmuTime time);
90
	[[nodiscard]] byte peekMultiMapperSlot(uint16_t address, EmuTime time) const;
91
	void writeMultiMapperSlot(uint16_t address, byte value, EmuTime time);
92
93
	// IDE
94
	[[nodiscard]] byte readIDESlot(uint16_t address, EmuTime time);
95
	[[nodiscard]] byte peekIDESlot(uint16_t address, EmuTime time) const;
96
	void writeIDESlot(uint16_t address, byte value, EmuTime time);
97
	[[nodiscard]] uint16_t ideReadData(EmuTime time);
98
	void ideWriteData(uint16_t value, EmuTime time);
99
	[[nodiscard]] byte ideReadReg(byte reg, EmuTime time);
100
	void ideWriteReg(byte reg, byte value, EmuTime time);
101
	[[nodiscard]] bool ideRegsEnabled() const { return ideControlReg & 0x01; }
102
	[[nodiscard]] byte ideBank() const { return Math::reverseByte(ideControlReg & 0xe0); }
103
104
	// memory mapper
105
	[[nodiscard]] bool isMemMapControl(uint16_t address) const;
106
	[[nodiscard]] unsigned getMemoryMapperAddress(uint16_t address) const;
107
	[[nodiscard]] bool isMemoryMapperWriteProtected(uint16_t address) const;
108
	[[nodiscard]] byte peekMemoryMapperSlot(uint16_t address) const;
109
	[[nodiscard]] byte readMemoryMapperSlot(uint16_t address) const;
110
	void writeMemoryMapperSlot(uint16_t address, byte value);
111
112
	// fm-pac
113
	[[nodiscard]] byte readFmPacSlot(uint16_t address, EmuTime time);
114
	[[nodiscard]] byte peekFmPacSlot(uint16_t address, EmuTime time) const;
115
	void writeFmPacSlot(uint16_t address, byte value, EmuTime time);
116
	[[nodiscard]] bool fmPacPortEnabled1() const { return fmPacEnable & 0x01; }
117
	[[nodiscard]] bool fmPacSramEnabled() const {
118
		return (fmPac5ffe == 0x4d) && (fmPac5fff == 0x69);
119
	}
120
	// User-defined ID and control port I/O
121
	[[nodiscard]] byte idControlPort() const { return configRegs[0x35]; }
122
123
private:
124
	AmdFlash flash; // 8MB
125
	Ram ram; // 2MB
126
	EEPROM_93C46 eeprom;
127
	std::array<byte, 64> configRegs; // in reality there are less than 64
128
	std::array<byte, 64> shadowConfigRegs; // only regs[0x05..0x1e] have a shadow counterpart
129
	byte subSlotReg;
130
	byte port3C;
131
132
	// multi-mapper
133
	SCC scc;
134
	byte sccMode;
135
	std::array<byte, 4> sccBank; // mostly write-only, except to test for scc-bank
136
137
	// PSG
138
	AY8910 psg;
139
	byte psgLatch;
140
141
	// ide
142
	std::array<std::unique_ptr<IDEDevice>, 2> ideDevices;
143
	byte ideSoftReset;
144
	byte ideSelectedDevice;
145
	byte ideControlReg;
146
	byte ideRead;
147
	byte ideWrite;
148
149
	// memory-mapper
150
	std::array<byte, 4> memMapRegs; // only stores 6 lower bits
151
152
	// fm-pac
153
	YM2413 ym2413;
154
	byte fmPacEnable; // enable
155
	byte fmPacBank; // bank
156
	byte fmPac5ffe;
157
	byte fmPac5fff;
158
159
	// User-defined ID and control port I/O
160
	byte PF0_RV;
161
};
162
SERIALIZE_CLASS_VERSION(Carnivore2, 3);
163
164
} // namespace openmsx
165
166
#endif