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