1#ifndef MSXCPUINTERFACE_HH
2#define MSXCPUINTERFACE_HH
102 int ps,
int ss,
unsigned base,
unsigned size);
104 int ps,
int ss,
unsigned base,
unsigned size);
129 return readMemSlow(address, time);
131 return visibleDevices[address >> 14]->readMem(address, time);
140 writeMemSlow(address, value, time);
143 visibleDevices[address>>14]->writeMem(address, value, time);
151 return IO_In[port & 0xFF]->readIO(port, time);
159 IO_Out[port & 0xFF]->writeIO(port, value, time);
179 return visibleDevices[start >> 14]->getReadCacheLine(start);
199 return visibleDevices[start >> 14]->getWriteCacheLine(start);
220 void fillRWCache(
unsigned start,
unsigned size,
const byte* rData,
byte* wData,
int ps,
int ss);
221 void fillRCache (
unsigned start,
unsigned size,
const byte* rData,
int ps,
int ss);
222 void fillWCache (
unsigned start,
unsigned size,
byte* wData,
int ps,
int ss);
228 [[nodiscard]]
byte peekMem(
word address, EmuTime::param time)
const;
229 [[nodiscard]]
byte peekSlottedMem(
unsigned address, EmuTime::param time)
const;
232 EmuTime::param time);
237 std::span<
const std::unique_ptr<MSXDevice>> allowed)
const;
238 [[nodiscard]]
inline bool isExpanded(
int ps)
const {
return expanded[ps] != 0; }
248 void setWatchPoint(
const std::shared_ptr<WatchPoint>& watchPoint);
259 [[nodiscard]]
static bool isBreaked() {
return breaked; }
267 return !breakPoints.empty() || !conditions.empty();
272 if (conditions.empty() && (range.first == range.second)) {
291 template<
typename Archive>
292 void serialize(Archive& ar,
unsigned version);
295 byte readMemSlow(
word address, EmuTime::param time);
296 void writeMemSlow(
word address,
byte value, EmuTime::param time);
298 MSXDevice*& getDevicePtr(
byte port,
bool isIn);
300 void register_IO (
int port,
bool isIn,
304 int ps,
int ss,
unsigned base,
unsigned size);
306 int ps,
int ss,
unsigned base,
unsigned size);
308 int ps,
int ss,
unsigned base,
unsigned size);
312 BreakPoints::const_iterator> range);
316 void removeAllWatchPoints();
319 unsigned value = ~0u);
323 [[nodiscard]]
byte read(
unsigned address, EmuTime::param time)
override;
324 void write(
unsigned address,
byte value, EmuTime::param time)
override;
327 struct SlottedMemoryDebug final : SimpleDebuggable {
328 explicit SlottedMemoryDebug(MSXMotherBoard& motherBoard);
329 [[nodiscard]]
byte read(
unsigned address, EmuTime::param time)
override;
330 void write(
unsigned address,
byte value, EmuTime::param time)
override;
331 } slottedMemoryDebug;
333 struct IODebug final : SimpleDebuggable {
334 explicit IODebug(MSXMotherBoard& motherBoard);
335 [[nodiscard]]
byte read(
unsigned address, EmuTime::param time)
override;
336 void write(
unsigned address,
byte value, EmuTime::param time)
override;
339 struct SlotInfo final : InfoTopic {
340 explicit SlotInfo(InfoCommand& machineInfoCommand);
341 void execute(std::span<const TclObject> tokens,
342 TclObject& result)
const override;
343 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
346 struct SubSlottedInfo final : InfoTopic {
347 explicit SubSlottedInfo(InfoCommand& machineInfoCommand);
348 void execute(std::span<const TclObject> tokens,
349 TclObject& result)
const override;
350 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
353 struct ExternalSlotInfo final : InfoTopic {
354 explicit ExternalSlotInfo(InfoCommand& machineInfoCommand);
355 void execute(std::span<const TclObject> tokens,
356 TclObject& result)
const override;
357 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
360 struct IOInfo : InfoTopic {
361 IOInfo(InfoCommand& machineInfoCommand,
const char* name);
362 void helper(std::span<const TclObject> tokens,
363 TclObject& result, std::span<MSXDevice*, 256> devices)
const;
364 [[nodiscard]] std::string help(std::span<const TclObject> tokens)
const override;
368 struct IInfo final : IOInfo {
369 explicit IInfo(InfoCommand& machineInfoCommand)
370 : IOInfo(machineInfoCommand,
"input_port") {}
371 void execute(std::span<const TclObject> tokens,
372 TclObject& result)
const override;
374 struct OInfo final : IOInfo {
375 explicit OInfo(InfoCommand& machineInfoCommand)
376 : IOInfo(machineInfoCommand,
"output_port") {}
377 void execute(std::span<const TclObject> tokens,
378 TclObject& result)
const override;
387 void updateVisible(
byte page);
388 inline void updateVisible(
byte page,
byte ps,
byte ss);
389 void setSubSlot(
byte primSlot,
byte value);
391 std::unique_ptr<DummyDevice> dummyDevice;
394 MSXMotherBoard& motherBoard;
396 std::unique_ptr<VDPIODelay> delayDevice;
398 std::array<byte, CacheLine::NUM> disallowReadCache;
399 std::array<byte, CacheLine::NUM> disallowWriteCache;
400 std::array<std::bitset<CacheLine::SIZE>,
CacheLine::NUM> readWatchSet;
401 std::array<std::bitset<CacheLine::SIZE>,
CacheLine::NUM> writeWatchSet;
403 struct GlobalRwInfo {
406 [[nodiscard]]
constexpr bool operator==(
const GlobalRwInfo&)
const =
default;
408 std::vector<GlobalRwInfo> globalReads;
409 std::vector<GlobalRwInfo> globalWrites;
411 std::array<MSXDevice*, 256> IO_In;
412 std::array<MSXDevice*, 256> IO_Out;
413 std::array<std::array<std::array<MSXDevice*, 4>, 4>, 4> slotLayout;
414 std::array<MSXDevice*, 4> visibleDevices;
415 std::array<byte, 4> subSlotRegister;
416 std::array<byte, 4> primarySlotState;
417 std::array<byte, 4> secondarySlotState;
418 byte initialPrimarySlots;
419 std::array<unsigned, 4> expanded;
421 bool fastForward =
false;
427 static inline bool breaked =
false;
433template<
unsigned BEGIN,
unsigned END = BEGIN + 1>
436 [[nodiscard]]
unsigned begin()
const {
return BEGIN; }
437 [[nodiscard]]
unsigned end()
const {
return END; }
443 for (
auto i = ct_interval.begin(); i != ct_interval.end(); ++i) {
448 auto front_interval,
auto... tail_intervals)
455template<
typename MSXDEVICE,
typename... CT_INTERVALS>
458 void execute(std::invocable<MSXCPUInterface&, MSXDevice&, unsigned>
auto action)
460 auto& dev =
static_cast<MSXDEVICE&
>(*this);
461 auto& cpu = dev.getCPUInterface();
463 [&](
unsigned addr) { action(cpu, dev, addr); },
468template<
typename MSXDEVICE,
typename... CT_INTERVALS>
486template<
typename MSXDEVICE,
typename... CT_INTERVALS>
void tick(CacheLineCounters e) const
Base class for CPU breakpoints.
General debugger condition Like breakpoints, but not tied to a specific address.
void register_IO_Out(byte port, MSXDevice *device)
Devices can register their Out ports.
void setWatchPoint(const std::shared_ptr< WatchPoint > &watchPoint)
void invalidateRWCache(word start, unsigned size, int ps, int ss)
void insertBreakPoint(BreakPoint bp)
std::vector< DebugCondition > Conditions
void register_IO_In(byte port, MSXDevice *device)
Devices can register their In ports.
MSXDevice * getMSXDevice(int ps, int ss, int page)
void fillWCache(unsigned start, unsigned size, byte *wData, int ps, int ss)
void unregister_IO_In(byte port, MSXDevice *device)
DummyDevice & getDummyDevice()
void writeIO(word port, byte value, EmuTime::param time)
This writes a byte to the given IO-port.
bool replace_IO_Out(byte port, MSXDevice *oldDevice, MSXDevice *newDevice)
void changeExpanded(bool newExpanded)
void unregisterMemDevice(MSXDevice &device, int ps, int ss, unsigned base, unsigned size)
void removeCondition(const DebugCondition &cond)
byte peekMem(word address, EmuTime::param time) const
Peek memory location.
byte readIO(word port, EmuTime::param time)
This read a byte from the given IO-port.
void testUnsetExpanded(int ps, std::span< const std::unique_ptr< MSXDevice > > allowed) const
static const Conditions & getConditions()
void writeSlottedMem(unsigned address, byte value, EmuTime::param time)
void setPrimarySlots(byte value)
byte * getWriteCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for writing.
void invalidateRCache(word start, unsigned size, int ps, int ss)
void unregisterGlobalWrite(MSXDevice &device, word address)
void unregisterGlobalRead(MSXDevice &device, word address)
byte peekSlottedMem(unsigned address, EmuTime::param time) const
void removeWatchPoint(std::shared_ptr< WatchPoint > watchPoint)
std::vector< std::shared_ptr< WatchPoint > > WatchPoints
byte readMem(word address, EmuTime::param time)
This reads a byte from the currently selected device.
void fillRWCache(unsigned start, unsigned size, const byte *rData, byte *wData, int ps, int ss)
void reset()
Reset (the slot state)
void setCondition(DebugCondition cond)
void invalidateWCache(word start, unsigned size, int ps, int ss)
void unsetExpanded(int ps)
bool isFastForward() const
const WatchPoints & getWatchPoints() const
byte readIRQVector()
CPU uses this method to read 'extra' data from the data bus used in interrupt routines.
bool checkBreakPoints(unsigned pc)
MSXCPUInterface & operator=(const MSXCPUInterface &)=delete
void serialize(Archive &ar, unsigned version)
void registerGlobalRead(MSXDevice &device, word address)
(Un)register global read.
void writeMem(word address, byte value, EmuTime::param time)
This writes a byte to the currently selected device.
byte readSlottedMem(unsigned address, EmuTime::param time)
void registerMemDevice(MSXDevice &device, int ps, int ss, unsigned base, unsigned size)
Devices can register themself in the MSX slot structure.
static const BreakPoints & getBreakPoints()
void removeBreakPoint(const BreakPoint &bp)
void unregister_IO_Out(byte port, MSXDevice *device)
void registerGlobalWrite(MSXDevice &device, word address)
(Un)register global writes.
std::vector< BreakPoint > BreakPoints
static bool anyBreakPoints()
bool replace_IO_In(byte port, MSXDevice *oldDevice, MSXDevice *newDevice)
These methods replace a previously registered device with a new one.
void setFastForward(bool fastForward_)
const byte * getReadCacheLine(word start) const
Test that the memory in the interval [start, start + CacheLine::SIZE) is cacheable for reading.
MSXCPUInterface(const MSXCPUInterface &)=delete
void fillRCache(unsigned start, unsigned size, const byte *rData, int ps, int ss)
bool isExpanded(int ps) const
An MSXDevice is an emulated hardware component connected to the bus of the emulated MSX.
byte read(unsigned address) override
void write(unsigned address, byte value) override
This file implemented 3 utility functions:
bool operator==(const Event &x, const Event &y)
constexpr bool PROFILE_CACHELINES
std::ostream & operator<<(std::ostream &os, EnumTypeName< CacheLineCounters >)
uint16_t word
16 bit unsigned integer
void foreach_ct_interval(std::invocable< unsigned > auto action, auto ct_interval)
auto equal_range(ForwardRange &&range, const T &value, Compare comp={})
size_t size(std::string_view utf8)
void execute(std::invocable< MSXCPUInterface &, MSXDevice &, unsigned > auto action)