| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 121 |
[[nodiscard]] byte idControlPort() const { return configRegs[0x35]; } |
| 122 |
|
| 123 |
private: |
| 124 |
AmdFlash flash; |
| 125 |
Ram ram; |
| 126 |
EEPROM_93C46 eeprom; |
| 127 |
std::array<byte, 64> configRegs; |
| 128 |
std::array<byte, 64> shadowConfigRegs; |
| 129 |
byte subSlotReg; |
| 130 |
byte port3C; |
| 131 |
|
| 132 |
|
| 133 |
SCC scc; |
| 134 |
byte sccMode; |
| 135 |
std::array<byte, 4> sccBank; |
| 136 |
|
| 137 |
|
| 138 |
AY8910 psg; |
| 139 |
byte psgLatch; |
| 140 |
|
| 141 |
|
| 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 |
|
| 150 |
std::array<byte, 4> memMapRegs; |
| 151 |
|
| 152 |
|
| 153 |
YM2413 ym2413; |
| 154 |
byte fmPacEnable; |
| 155 |
byte fmPacBank; |
| 156 |
byte fmPac5ffe; |
| 157 |
byte fmPac5fff; |
| 158 |
|
| 159 |
|
| 160 |
byte PF0_RV; |
| 161 |
}; |
| 162 |
SERIALIZE_CLASS_VERSION(Carnivore2, 3); |
| 163 |
|
| 164 |
} |
| 165 |
|
| 166 |
#endif |