openMSX
MSXWatchIODevice.cc
Go to the documentation of this file.
1#include "MSXWatchIODevice.hh"
2
3#include "Interpreter.hh"
4#include "MSXCPUInterface.hh"
5#include "MSXMotherBoard.hh"
6#include "Reactor.hh"
8#include "TclObject.hh"
9
10#include "narrow.hh"
11
12#include <cassert>
13#include <memory>
14
15namespace openmsx {
16
17// class WatchIO
18
20 WatchPoint::Type type_,
21 unsigned beginAddr_, unsigned endAddr_,
22 TclObject command_, TclObject condition_,
23 bool once_, unsigned newId /*= -1*/)
24 : WatchPoint(std::move(command_), std::move(condition_), type_, beginAddr_, endAddr_, once_, newId)
25 , motherboard(motherboard_)
26{
27 for (unsigned i = narrow_cast<byte>(beginAddr_); i <= narrow_cast<byte>(endAddr_); ++i) {
28 ios.push_back(std::make_unique<MSXWatchIODevice>(
29 *motherboard.getMachineConfig(), *this));
30 }
31}
32
34{
35 auto begin = narrow_cast<byte>(getBeginAddress());
36 return *ios[port - begin];
37}
38
39void WatchIO::doReadCallback(unsigned port)
40{
41 auto& cpuInterface = motherboard.getCPUInterface();
42 if (cpuInterface.isFastForward()) return;
43
44 auto& cliComm = motherboard.getReactor().getGlobalCliComm();
45 auto& interp = motherboard.getReactor().getInterpreter();
46 interp.setVariable(TclObject("wp_last_address"), TclObject(int(port)));
47
48 // keep this object alive by holding a shared_ptr to it, for the case
49 // this watchpoint deletes itself in checkAndExecute()
50 auto keepAlive = shared_from_this();
51 auto scopedBlock = motherboard.getStateChangeDistributor().tempBlockNewEventsDuringReplay();
52 if (bool remove = checkAndExecute(cliComm, interp); remove) {
53 cpuInterface.removeWatchPoint(keepAlive);
54 }
55
56 interp.unsetVariable("wp_last_address");
57}
58
59void WatchIO::doWriteCallback(unsigned port, unsigned value)
60{
61 auto& cpuInterface = motherboard.getCPUInterface();
62 if (cpuInterface.isFastForward()) return;
63
64 auto& cliComm = motherboard.getReactor().getGlobalCliComm();
65 auto& interp = motherboard.getReactor().getInterpreter();
66 interp.setVariable(TclObject("wp_last_address"), TclObject(int(port)));
67 interp.setVariable(TclObject("wp_last_value"), TclObject(int(value)));
68
69 // see comment in doReadCallback() above
70 auto keepAlive = shared_from_this();
71 auto scopedBlock = motherboard.getStateChangeDistributor().tempBlockNewEventsDuringReplay();
72 if (bool remove = checkAndExecute(cliComm, interp); remove) {
73 cpuInterface.removeWatchPoint(keepAlive);
74 }
75
76 interp.unsetVariable("wp_last_address");
77 interp.unsetVariable("wp_last_value");
78}
79
80
81// class MSXWatchIODevice
82
84 const HardwareConfig& hwConf, WatchIO& watchIO_)
85 : MSXMultiDevice(hwConf)
86 , watchIO(watchIO_)
87{
88}
89
90const std::string& MSXWatchIODevice::getName() const
91{
92 assert(device);
93 return device->getName();
94}
95
96byte MSXWatchIODevice::peekIO(word port, EmuTime::param time) const
97{
98 assert(device);
99 return device->peekIO(port, time);
100}
101
102byte MSXWatchIODevice::readIO(word port, EmuTime::param time)
103{
104 assert(device);
105
106 // first trigger watchpoint, then read from device
107 watchIO.doReadCallback(port);
108 return device->readIO(port, time);
109}
110
111void MSXWatchIODevice::writeIO(word port, byte value, EmuTime::param time)
112{
113 assert(device);
114
115 // first write to device, then trigger watchpoint
116 device->writeIO(port, value, time);
117 watchIO.doWriteCallback(port, value);
118}
119
120} // namespace openmsx
bool checkAndExecute(GlobalCliComm &cliComm, Interpreter &interp)
void setVariable(const TclObject &name, const TclObject &value)
virtual void writeIO(word port, byte value, EmuTime::param time)
Write a byte to a given IO port at a certain time to this device.
Definition MSXDevice.cc:408
virtual byte peekIO(word port, EmuTime::param time) const
Read a byte from a given IO port.
Definition MSXDevice.cc:413
virtual const std::string & getName() const
Returns a human-readable name for this device.
Definition MSXDevice.cc:375
virtual byte readIO(word port, EmuTime::param time)
Read a byte from an IO port at a certain time from this device.
Definition MSXDevice.cc:402
const HardwareConfig * getMachineConfig() const
MSXCPUInterface & getCPUInterface()
StateChangeDistributor & getStateChangeDistributor()
MSXWatchIODevice(const HardwareConfig &hwConf, WatchIO &watchIO)
GlobalCliComm & getGlobalCliComm()
Definition Reactor.hh:90
Interpreter & getInterpreter()
Definition Reactor.cc:328
MSXWatchIODevice & getDevice(byte port)
WatchIO(MSXMotherBoard &motherboard, WatchPoint::Type type, unsigned beginAddr, unsigned endAddr, TclObject command, TclObject condition, bool once, unsigned newId=-1)
Base class for CPU breakpoints.
Definition WatchPoint.hh:14
unsigned getBeginAddress() const
Definition WatchPoint.hh:34
This file implemented 3 utility functions:
Definition Autofire.cc:11
uint16_t word
16 bit unsigned integer
Definition openmsx.hh:29
auto remove(ForwardRange &&range, const T &value)
Definition ranges.hh:291
STL namespace.
constexpr auto begin(const zstring_view &x)