19static constexpr word ENAR = 0x7FFF;
20static constexpr byte REGEN = 0x01;
21static constexpr byte WREN = 0x10;
22static constexpr word OFFR = 0x7FFE;
23static constexpr word CFGR = 0x7FFD;
24static constexpr byte MDIS = 0x01;
25static constexpr byte ECHO = 0x02;
26static constexpr byte ROMDIS = 0x04;
27static constexpr byte K4 = 0x08;
28static constexpr byte SUBOFF = 0x30;
30static constexpr byte FPGA_EN = 0x40;
31static constexpr byte FPGA_WAIT = 0x80;
32static constexpr word FPGA_REG = 0x7FFC;
36 , romBlockDebug(*this)
37 , flash(rom, AmdFlashChip::S29GL064N90TFI04, {}, config)
44 psg.setSoftwareVolume(3.0f, getCurrentTime());
46 scc.setBalance(0, 0.00f);
47 scc.setBalance(1, -0.67f);
48 scc.setBalance(2, 0.67f);
49 scc.setBalance(3, -0.67f);
50 scc.setBalance(4, 0.67f);
53 getCPUInterface().register_IO_Out_range(0x10, 2,
this);
54 powerUp(getCurrentTime());
90void Yamanooto::writeConfigReg(
byte value)
92 if ((value ^ configReg) & ECHO) {
102bool Yamanooto::isSCCAccess(
word address)
const
104 if (configReg & K4)
return false;
106 if (sccMode & 0x20) {
108 return (bankRegs[3] & 0x80) && (0xB800 <= address) && (address < 0xBFFE);
111 return ((bankRegs[2] & 0x3F) == 0x3F) && (0x9800 <= address) && (address < 0xA000);
115unsigned Yamanooto::getFlashAddr(
unsigned addr)
const
117 unsigned page8kB = (addr >> 13) - 2;
119 auto bank = bankRegs[page8kB] & 0x3ff;
120 return (bank << 13) | (addr & 0x1FFF);
123[[nodiscard]]
static word mirror(
word address)
125 if (address < 0x4000 || 0xC000 <= address) {
129 assert((0x4000 <= address) && (address < 0xC000));
133static constexpr std::array<byte, 4 + 1> FPGA_ID = {
135 0x1F, 0x23, 0x00, 0x00,
139 address = mirror(address);
142 if (FPGA_REG <= address && address <= ENAR && (enableReg & REGEN)) {
145 if (!(configReg & FPGA_EN))
return 0xFF;
147 return FPGA_ID[fpgaFsm];
148 case CFGR:
return configReg | FPGA_WAIT;
149 case OFFR:
return offsetReg;
150 case ENAR:
return enableReg;
156 if (isSCCAccess(address)) {
157 return scc.
peekMem(narrow_cast<uint8_t>(address & 0xFF), time);
159 return ((configReg & ROMDIS) == 0) ? flash.
peek(getFlashAddr(address))
166 if (FPGA_REG <= address && address <= ENAR && (enableReg & REGEN)) {
169 address = mirror(address);
172 if (isSCCAccess(address)) {
173 return scc.
readMem(narrow_cast<uint8_t>(address & 0xFF), time);
175 return ((configReg & ROMDIS) == 0) ? flash.
read(getFlashAddr(address))
184 address = mirror(address);
185 if (isSCCAccess(address))
return nullptr;
186 return ((configReg & ROMDIS) == 0) ? flash.
getReadCacheLine(getFlashAddr(address))
193 if (FPGA_REG <= address && address <= ENAR) {
194 if (address == ENAR) {
196 }
else if (enableReg & REGEN) {
199 if (!(configReg & FPGA_EN))
break;
206 case 1:
case 2:
case 3:
217 writeConfigReg(value);
228 address = mirror(address);
229 unsigned page8kB = (address >> 13) - 2;
231 if (enableReg & WREN) {
233 if (!(configReg & ROMDIS)) {
234 flash.
write(getFlashAddr(address), value);
238 auto invalidateCache = [&](
unsigned start,
unsigned size) {
242 auto offset = (offsetReg << 2) | ((configReg & SUBOFF) >> 4);
243 if (configReg & K4) {
245 if (((configReg & MDIS) == 0) && (0x6000 <= address)) {
248 bankRegs[page8kB] = (value + offset) & 0x3FF;
249 invalidateCache(0x4000 + 0x2000 * page8kB, 0x2000);
253 if (isSCCAccess(address)) {
254 scc.
writeMem(narrow_cast<uint8_t>(address & 0xFF), value, time);
258 if (((address & 0x1800) == 0x1000) && ((configReg & MDIS) == 0)) {
261 bankRegs[page8kB] = (value + offset) & 0x3FF;
262 invalidateCache(0x4000 + 0x2000 * page8kB, 0x2000);
266 if ((address & 0xFFFE) == 0xBFFE) {
270 invalidateCache(0x9800, 0x800);
271 invalidateCache(0xB800, 0x800);
298 psgLatch = value & 0x0F;
302template<
typename Archive>
309 "bankRegs", bankRegs,
310 "enableReg", enableReg,
311 "offsetReg", offsetReg,
312 "configReg", configReg,
315 "psgLatch", psgLatch,
323unsigned Yamanooto::Blocks::readExt(
unsigned address)
326 address = mirror(narrow<word>(address));
327 unsigned page8kB = (address >> 13) - 2;
328 return dev.bankRegs[page8kB];
#define REGISTER_MSXDEVICE(CLASS, NAME)
void reset(EmuTime::param time)
void writeRegister(unsigned reg, uint8_t value, EmuTime::param time)
void write(size_t address, uint8_t value)
const uint8_t * getReadCacheLine(size_t address) const
uint8_t read(size_t address)
uint8_t peek(size_t address) const
static DummyAY8910Periphery & instance()
void unregister_IO_Out_range(byte port, unsigned num, MSXDevice *device)
void register_IO_Out_range(byte port, unsigned num, MSXDevice *device)
void invalidateDeviceRCache()
static std::array< byte, 0x10000 > unmappedRead
MSXCPUInterface & getCPUInterface() const
void setMode(Mode newMode)
void powerUp(EmuTime::param time)
uint8_t readMem(uint8_t address, EmuTime::param time)
void reset(EmuTime::param time)
uint8_t peekMem(uint8_t address, EmuTime::param time) const
void writeMem(uint8_t address, uint8_t value, EmuTime::param time)
const byte * getReadCacheLine(word address) const override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
byte readMem(word address, EmuTime::param time) override
Read a byte from a location at a certain time from this device.
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.
void reset(EmuTime::param time) override
This method is called on reset.
byte peekMem(word address, EmuTime::param time) const override
Read a byte from a given memory location.
byte peekIO(word port, EmuTime::param time) const override
Read a byte from a given IO port.
void serialize(Archive &ar, unsigned version)
void powerUp(EmuTime::param time) override
This method is called when MSX is powered up.
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.
byte * getWriteCacheLine(word address) override
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
Yamanooto(const DeviceConfig &config, Rom &&rom)
byte readIO(word port, EmuTime::param time) override
Read a byte from an IO port at a certain time from this device.
This file implemented 3 utility functions:
uint16_t word
16 bit unsigned integer
constexpr void iota(ForwardIt first, ForwardIt last, T value)
#define OUTER(type, member)
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)