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