2018-01-05 03:18:18 +00:00
|
|
|
//
|
|
|
|
// ROMSlotHandler.hpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 03/01/2018.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2018 Thomas Harte. All rights reserved.
|
2018-01-05 03:18:18 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef ROMSlotHandler_hpp
|
|
|
|
#define ROMSlotHandler_hpp
|
|
|
|
|
|
|
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
2018-01-25 02:48:44 +00:00
|
|
|
#include "../../Analyser/Dynamic/ConfidenceCounter.hpp"
|
2018-01-05 03:18:18 +00:00
|
|
|
|
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdint>
|
2019-03-02 23:07:05 +00:00
|
|
|
#include <string>
|
2018-01-05 03:18:18 +00:00
|
|
|
|
|
|
|
/*
|
2018-01-06 20:51:29 +00:00
|
|
|
Design assumptions:
|
|
|
|
|
|
|
|
- to-ROM writes and paging events are 'rare', so virtual call costs aren't worrisome;
|
|
|
|
- ROM type variety is sufficiently slender that most of it can be built into the MSX.
|
|
|
|
|
|
|
|
Part of the motivation is also that the MSX has four logical slots, the ROM, RAM plus two
|
|
|
|
things plugged in. So even if the base class were templated to remove the virtual call,
|
|
|
|
there'd just be a switch on what to call.
|
2018-01-05 03:18:18 +00:00
|
|
|
*/
|
|
|
|
namespace MSX {
|
|
|
|
|
|
|
|
class MemoryMap {
|
|
|
|
public:
|
2018-01-06 20:51:29 +00:00
|
|
|
/*!
|
|
|
|
Maps source data from the ROM's source to the given address range.
|
|
|
|
*/
|
2018-01-05 03:18:18 +00:00
|
|
|
virtual void map(int slot, std::size_t source_address, uint16_t destination_address, std::size_t length) = 0;
|
2018-01-06 20:51:29 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
Unmaps source data from the given address range; the slot handler's read function will be used
|
|
|
|
to respond to queries in that range.
|
|
|
|
*/
|
|
|
|
virtual void unmap(int slot, uint16_t destination_address, std::size_t length) = 0;
|
2018-01-05 03:18:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class ROMSlotHandler {
|
|
|
|
public:
|
2019-01-14 00:19:01 +00:00
|
|
|
virtual ~ROMSlotHandler() {}
|
|
|
|
|
2018-01-06 20:51:29 +00:00
|
|
|
/*! Advances time by @c half_cycles. */
|
2018-01-05 03:18:18 +00:00
|
|
|
virtual void run_for(HalfCycles half_cycles) {}
|
2018-01-06 20:51:29 +00:00
|
|
|
|
|
|
|
/*! Announces an attempt to write @c value to @c address. */
|
2018-02-10 22:11:16 +00:00
|
|
|
virtual void write(uint16_t address, uint8_t value, bool pc_is_outside_bios) = 0;
|
2018-01-06 20:51:29 +00:00
|
|
|
|
|
|
|
/*! Seeks the result of a read at @c address; this is used only if the area is unmapped. */
|
|
|
|
virtual uint8_t read(uint16_t address) { return 0xff; }
|
|
|
|
|
|
|
|
enum class WrappingStrategy {
|
|
|
|
/// Repeat causes all accesses to be modulo the size of the ROM.
|
|
|
|
Repeat,
|
|
|
|
/// Empty causes all out-of-bounds accesses to read a vacant bus.
|
|
|
|
Empty
|
|
|
|
};
|
2018-01-23 02:50:56 +00:00
|
|
|
|
|
|
|
/*! @returns The wrapping strategy to apply to mapping requests from this ROM slot. */
|
2018-01-06 20:51:29 +00:00
|
|
|
virtual WrappingStrategy wrapping_strategy() const {
|
|
|
|
return WrappingStrategy::Repeat;
|
|
|
|
}
|
2018-01-23 02:50:56 +00:00
|
|
|
|
|
|
|
/*! @returns The probability that this handler is correct for the data it owns. */
|
|
|
|
float get_confidence() {
|
2018-01-26 00:02:16 +00:00
|
|
|
return confidence_counter_.get_confidence();
|
2018-01-23 02:50:56 +00:00
|
|
|
}
|
|
|
|
|
2019-03-02 23:07:05 +00:00
|
|
|
virtual std::string debug_type() {
|
|
|
|
return "";
|
2018-02-01 12:53:52 +00:00
|
|
|
}
|
|
|
|
|
2018-01-23 02:50:56 +00:00
|
|
|
protected:
|
2018-01-29 03:22:21 +00:00
|
|
|
Analyser::Dynamic::ConfidenceCounter confidence_counter_;
|
2018-01-05 03:18:18 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* ROMSlotHandler_hpp */
|