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