2016-08-27 22:17:40 +00:00
|
|
|
//
|
2016-08-27 22:26:51 +00:00
|
|
|
// Cartridge.hpp
|
2016-08-27 22:17:40 +00:00
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 27/08/2016.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2016 Thomas Harte. All rights reserved.
|
2016-08-27 22:17:40 +00:00
|
|
|
//
|
|
|
|
|
2024-01-17 04:34:46 +00:00
|
|
|
#pragma once
|
2016-08-27 22:17:40 +00:00
|
|
|
|
2016-08-28 16:20:40 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
|
2023-05-10 21:02:18 +00:00
|
|
|
namespace Storage::Cartridge {
|
2016-08-27 22:17:40 +00:00
|
|
|
|
2016-08-28 16:20:40 +00:00
|
|
|
/*!
|
|
|
|
Provides a base class for cartridges; the bus provided to cartridges and therefore
|
|
|
|
the interface they support is extremely machine-dependent so unlike disks and tapes,
|
|
|
|
no model is imposed; this class seeks merely to be a base class for fully-descriptive
|
|
|
|
summaries of the contents of emulator files that themselves describe cartridges.
|
|
|
|
|
|
|
|
Consumers will almost certainly seek to dynamic_cast to something more appropriate,
|
|
|
|
however some cartridge container formats have no exposition beyond the ROM dump,
|
|
|
|
making the base class 100% descriptive.
|
|
|
|
*/
|
|
|
|
class Cartridge {
|
|
|
|
public:
|
|
|
|
struct Segment {
|
2018-01-17 03:27:41 +00:00
|
|
|
Segment(size_t start_address, size_t end_address, std::vector<uint8_t> &&data) :
|
|
|
|
start_address(start_address), end_address(end_address), data(data) {}
|
2016-08-28 16:20:40 +00:00
|
|
|
|
2018-01-17 03:27:41 +00:00
|
|
|
Segment(size_t start_address, size_t end_address, const std::vector<uint8_t> &data) :
|
|
|
|
start_address(start_address), end_address(end_address), data(data) {}
|
|
|
|
|
|
|
|
Segment(size_t start_address, std::vector<uint8_t> &&data) :
|
|
|
|
Segment(start_address, start_address + data.size(), data) {}
|
|
|
|
|
|
|
|
Segment(size_t start_address, const std::vector<uint8_t> &data) :
|
2017-12-02 21:01:30 +00:00
|
|
|
Segment(start_address, start_address + data.size(), data) {}
|
2018-01-17 03:27:41 +00:00
|
|
|
|
|
|
|
Segment(Segment &&segment) :
|
|
|
|
start_address(segment.start_address),
|
|
|
|
end_address(segment.end_address),
|
|
|
|
data(std::move(segment.data)) {}
|
|
|
|
|
|
|
|
Segment(const Segment &segment) :
|
|
|
|
start_address(segment.start_address),
|
|
|
|
end_address(segment.end_address),
|
|
|
|
data(segment.data) {}
|
2017-12-02 21:01:30 +00:00
|
|
|
|
2016-08-28 16:20:40 +00:00
|
|
|
/// Indicates that an address is unknown.
|
2017-12-02 21:01:30 +00:00
|
|
|
static const size_t UnknownAddress;
|
2016-08-28 16:20:40 +00:00
|
|
|
|
|
|
|
/// The initial CPU-exposed starting address for this segment; may be @c UnknownAddress.
|
2017-12-02 21:01:30 +00:00
|
|
|
size_t start_address;
|
2016-08-28 16:20:40 +00:00
|
|
|
/*!
|
|
|
|
The initial CPU-exposed ending address for this segment; may be @c UnknownAddress. Not necessarily equal
|
|
|
|
to start_address + data_length due to potential paging.
|
|
|
|
*/
|
2017-12-02 21:01:30 +00:00
|
|
|
size_t end_address;
|
2016-08-28 16:20:40 +00:00
|
|
|
|
|
|
|
/*!
|
|
|
|
The data contents for this segment. If @c start_address and @c end_address are suppled then
|
|
|
|
the first end_address - start_address bytes will be those initially visible. The size will
|
|
|
|
not necessarily be the same as @c end_address - @c start_address due to potential paging.
|
|
|
|
*/
|
|
|
|
std::vector<uint8_t> data;
|
|
|
|
};
|
|
|
|
|
2017-12-02 21:01:30 +00:00
|
|
|
const std::vector<Segment> &get_segments() const {
|
|
|
|
return segments_;
|
|
|
|
}
|
2017-08-27 19:19:30 +00:00
|
|
|
virtual ~Cartridge() {}
|
2016-08-28 16:20:40 +00:00
|
|
|
|
2017-12-02 21:01:30 +00:00
|
|
|
Cartridge() {}
|
|
|
|
Cartridge(const std::vector<Segment> &segments) : segments_(segments) {}
|
|
|
|
|
2016-08-28 16:20:40 +00:00
|
|
|
protected:
|
2017-12-02 21:01:30 +00:00
|
|
|
std::vector<Segment> segments_;
|
2016-08-28 16:20:40 +00:00
|
|
|
};
|
2016-08-27 22:17:40 +00:00
|
|
|
|
|
|
|
}
|