Lua: Fix type confusion between signed and unsigned
[lsnes.git] / include / library / memoryspace.hpp
blob70d0dae88d600a661230a3eb1cd3a6bf1f9c3d8d
1 #ifndef _library__memoryspace__hpp__included__
2 #define _library__memoryspace__hpp__included__
4 #include <string>
5 #include <list>
6 #include <vector>
7 #include <cstdint>
8 #include <cstring>
9 #include "threads.hpp"
10 #include "arch-detect.hpp"
13 /**
14 * A whole memory space.
16 class memory_space
18 public:
19 /**
20 * Information about region of memory.
22 struct region
24 /**
25 * Destructor.
27 virtual ~region() throw();
28 /**
29 * Name of the region (mainly for debugging and showing to user).
31 std::string name;
32 /**
33 * Base address of the region.
35 uint64_t base;
36 /**
37 * Size of the region.
39 uint64_t size;
40 /**
41 * Last address in region.
43 uint64_t last_address() const throw() { return base + size - 1; }
44 /**
45 * Endianess of region (-1 => little, 0 => host, 1 => big).
47 int endian;
48 /**
49 * Read-only flag.
51 bool readonly;
52 /**
53 * Special flag.
55 * Signals that this region is not RAM/ROM-like, but is special I/O region where reads and writes might not be
56 * consistent.
58 bool special;
59 /**
60 * Direct mapping for the region. If not NULL, read/write will not be used, instead all operations directly
61 * manipulate this buffer (faster). Must be NULL for special regions.
63 unsigned char* direct_map;
64 /**
65 * Read from region.
67 * Parameter offset: Offset to start the read.
68 * Parameter buffer: Buffer to store the data to.
69 * Parameter tsize: Amount to read.
71 * Note: The default implementation reads from direct_map.
72 * Note: Needs to be overridden if direct_map is NULL.
73 * Note: Must be able to read the whole region at once.
75 virtual void read(uint64_t offset, void* buffer, size_t tsize);
76 /**
77 * Write to region (writes to readonly regions are ignored).
79 * Parameter offset: Offset to start the write.
80 * Parameter buffer: Buffer to read the data from.
81 * Parameter tsize: Amount to write.
82 * Returns: True on success, false on failure.
84 * Note: The default implementation writes to direct_map if available and readwrite. Otherwise fails.
85 * Note: Must be able to write the whole region at once.
87 virtual bool write(uint64_t offset, const void* buffer, size_t tsize);
89 /**
90 * Direct-mapped region.
92 struct region_direct : public region
94 /**
95 * Create new direct-mapped region.
97 * Parameter name: Name of the region.
98 * Parameter base: Base address of the region.
99 * Parameter endian: Endianess of the region.
100 * Parameter memory: Memory backing the region.
101 * Parameter size: Size of the region.
102 * Parameter _readonly: If true, region is readonly.
104 region_direct(const std::string& name, uint64_t base, int endian, unsigned char* memory,
105 size_t size, bool _readonly = false);
107 * Destructor.
109 ~region_direct() throw();
112 * Get system endianess.
114 #ifdef ARCH_IS_I386
115 static int get_system_endian() throw() { return -1; }
116 #else
117 static int get_system_endian() throw() { if(!sysendian) sysendian = _get_system_endian(); return sysendian; }
118 #endif
120 * Do native unaligned reads work?
122 #ifdef ARCH_IS_I386
123 static int can_read_unaligned() throw() { return true; }
124 #else
125 static int can_read_unaligned() throw() { return false; }
126 #endif
128 * Lookup region covering address.
130 * Parameter address: The address to look up.
131 * Returns: The region/offset pair, or NULL/0 if that address is unmapped.
133 std::pair<region*, uint64_t> lookup(uint64_t address);
135 * Lookup region covering linear address.
137 * Parameter linear: The linear address to look up.
138 * Returns: The region/offset pair, or NULL/0 if that address is unmapped.
140 std::pair<region*, uint64_t> lookup_linear(uint64_t linear);
142 * Lookup region with specified index..
144 * Parameter n: The index to look up.
145 * Returns: The region, or NULL if index is invalid.
147 region* lookup_n(size_t n);
149 * Get number of regions.
151 size_t get_region_count() { return u_regions.size(); }
153 * Get linear RAM size.
155 * Returns: The linear RAM size in bytes.
157 uint64_t get_linear_size() { return linear_size; }
159 * Get list of all regions in memory space.
161 std::list<region*> get_regions();
163 * Set list of all regions in memory space.
165 void set_regions(const std::list<region*>& regions);
167 * Read an element (primitive type) from memory.
169 * Parameter address: The address to read.
170 * Returns: The read value.
172 template<typename T> T read(uint64_t address);
174 * Write an element (primitive type) to memory.
176 * Parameter address: The address to write.
177 * Parameter value: The value to write.
178 * Returns: True on success, false on failure.
180 template<typename T> bool write(uint64_t address, T value);
182 * Get physical mapping of region of memory.
184 * Parameter base: The base address.
185 * Parameter size: The size of region.
186 * Returns: Pointer to base on success, NULL on failure (range isn't backed by memory)
188 char* get_physical_mapping(uint64_t base, uint64_t size);
190 * Read a byte range (not across regions).
192 * Parameter address: Base address to start the read from.
193 * Parameter buffer: Buffer to store the data to.
194 * Parameter bsize: Size of buffer.
196 void read_range(uint64_t address, void* buffer, size_t bsize);
198 * Write a byte range (not across regions).
200 * Parameter address: Base address to start the write from.
201 * Parameter buffer: Buffer to read the data from.
202 * Parameter bsize: Size of buffer.
203 * Returns: True on success, false on failure.
205 bool write_range(uint64_t address, const void* buffer, size_t bsize);
207 * Read an element (primitive type) from memory.
209 * Parameter linear: The linear address to read.
210 * Returns: The read value.
212 template<typename T> T read_linear(uint64_t linear);
214 * Write an element (primitive type) to memory.
216 * Parameter linear: The linear address to write.
217 * Parameter value: The value to write.
218 * Returns: True on success, false on failure.
220 template<typename T> bool write_linear(uint64_t linear, T value);
222 * Read a byte range (not across regions).
224 * Parameter linear: Base linear address to start the read from.
225 * Parameter buffer: Buffer to store the data to.
226 * Parameter bsize: Size of buffer.
228 void read_range_linear(uint64_t linear, void* buffer, size_t bsize);
230 * Write a byte range (not across regions).
232 * Parameter linear: Base linear address to start the write from.
233 * Parameter buffer: Buffer to read the data from.
234 * Parameter bsize: Size of buffer.
235 * Returns: True on success, false on failure.
237 bool write_range_linear(uint64_t linear, const void* buffer, size_t bsize);
239 * Read complete linear memory.
241 * Parameter buffer: Buffer to store to (get_linear_size() bytes).
243 void read_all_linear_memory(uint8_t* buffer);
245 * Get textual identifier for mapped address.
247 * Parameter addr: The address to get textual form for.
248 * Returns: The textual address.
250 std::string address_to_textual(uint64_t addr);
251 private:
252 threads::lock mlock;
253 std::vector<region*> u_regions;
254 std::vector<region*> u_lregions;
255 std::vector<uint64_t> linear_bases;
256 uint64_t linear_size;
257 static int _get_system_endian();
258 static int sysendian;
262 * Calculate span of strided request.
264 * Parameter base: The base address.
265 * Parameter size: The size of each row.
266 * Parameter rows: Number of raows.
267 * Parameter stride: The stride.
268 * Returns: (low, high) of access bounds. low > high if no memory is accessed.
270 std::pair<uint64_t, uint64_t> memoryspace_row_bounds(uint64_t base, uint64_t size, uint64_t rows,
271 uint64_t stride);
274 * Does strided request fit in certain bounds?
276 * Parameter base: The base address.
277 * Parameter size: The size of each row.
278 * Parameter rows: Number of raows.
279 * Parameter stride: The stride.
280 * Parameter limit: The size of area.
281 * Returns: True if entiere access stays below limit, false otherwise.
283 bool memoryspace_row_limited(uint64_t base, uint64_t size, uint64_t rows, uint64_t stride, uint64_t limit);
285 #endif