1
//============================================================================
3
// MM MM 6666 555555 0000 2222
4
// MMMM MMMM 66 66 55 00 00 22 22
5
// MM MMM MM 66 55 00 00 22
6
// MM M MM 66666 55555 00 00 22222 -- "A 6502 Microprocessor Emulator"
7
// MM MM 66 66 55 00 00 22
8
// MM MM 66 66 55 55 00 00 22
9
// MM MM 6666 5555 0000 222222
11
// Copyright (c) 1995-2008 by Bradford W. Mott and the Stella team
13
// See the file "license" for information on usage and redistribution of
14
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16
// $Id: System.hxx,v 1.19 2008/02/19 12:33:07 stephena Exp $
17
//============================================================================
30
#include "NullDev.hxx"
31
#include "Serializable.hxx"
34
This class represents a system consisting of a 6502 microprocessor
35
and a set of devices. The devices are mapped into an addressing
36
space of 2^n bytes (1 <= n <= 16). The addressing space is broken
37
into 2^m byte pages (1 <= m <= n), where a page is the smallest unit
38
a device can use when installing itself in the system.
40
In general the addressing space will be 8192 (2^13) bytes for a
41
6507 based system and 65536 (2^16) bytes for a 6502 based system.
43
TODO: To allow for dynamic code generation we probably need to
44
add a tag to each page that indicates if it is read only
45
memory. We also need to notify the processor anytime a
46
page access method is changed so that it can clear the
47
dynamic code for that page of memory.
49
@author Bradford W. Mott
50
@version $Id: System.hxx,v 1.19 2008/02/19 12:33:07 stephena Exp $
52
class System : public Serializable
56
Create a new system with an addressing space of 2^n bytes and
59
@param n Log base 2 of the addressing space size
60
@param m Log base 2 of the page size
62
System(uInt16 n, uInt16 m);
71
Reset the system cycle counter, the attached devices, and the
72
attached processor of the system.
77
Attach the specified device and claim ownership of it. The device
78
will be asked to install itself.
80
@param device The device to attach to the system
82
void attach(Device* device);
85
Attach the specified processor and claim ownership of it. The
86
processor will be asked to install itself.
88
@param m6502 The 6502 microprocessor to attach to the system
90
void attach(M6502* m6502);
93
Attach the specified processor and claim ownership of it. The
94
processor will be asked to install itself.
96
@param m6532 The 6532 microprocessor to attach to the system
98
void attach(M6532* m6532);
101
Attach the specified TIA device and claim ownership of it. The device
102
will be asked to install itself.
104
@param tia The TIA device to attach to the system
106
void attach(TIA* tia);
110
Answer the 6502 microprocessor attached to the system. If a
111
processor has not been attached calling this function will fail.
113
@return The attached 6502 microprocessor
121
Answer the 6532 processor attached to the system. If a
122
processor has not been attached calling this function will fail.
124
@return The attached 6532 microprocessor
132
Answer the TIA device attached to the system.
134
@return The attached TIA device
142
Get the null device associated with the system. Every system
143
has a null device associated with it that's used by pages which
144
aren't mapped to "real" devices.
146
@return The null device associated with the system
148
NullDevice& nullDevice()
154
Get the total number of pages available in the system.
156
@return The total number of pages available
158
uInt16 numberOfPages() const
160
return myNumberOfPages;
164
Get the amount to right shift an address by to obtain its page.
166
@return The amount to right shift an address by to get its page
168
uInt16 pageShift() const
174
Get the mask to apply to an address to obtain its page offset.
176
@return The mask to apply to an address to obtain its page offset
178
uInt16 pageMask() const
185
Get the number of system cycles which have passed since the last
186
time cycles were reset or the system was reset.
188
@return The number of system cycles which have passed
190
uInt32 cycles() const
196
Increment the system cycles by the specified number of cycles.
198
@param amount The amount to add to the system cycles counter
200
void incrementCycles(uInt32 amount)
206
Reset the system cycle count to zero. The first thing that
207
happens is that all devices are notified of the reset by invoking
208
their systemCyclesReset method then the system cycle count is
215
Get the current state of the data bus in the system. The current
216
state is the last data that was accessed by the system.
218
@return the data bus state
220
inline uInt8 getDataBusState() const
222
return myDataBusState;
226
Get the byte at the specified address. No masking of the
227
address occurs before it's sent to the device mapped at
230
@return The byte at the specified address
232
uInt8 peek(uInt16 address);
235
Change the byte at the specified address to the given value.
236
No masking of the address occurs before it's sent to the device
237
mapped at the address.
239
@param address The address where the value should be stored
240
@param value The value to be stored at the address
242
void poke(uInt16 address, uInt8 value);
245
Lock/unlock the data bus. When the bus is locked, peek() and
246
poke() don't update the bus state. The bus should be unlocked
247
while the CPU is running (normal emulation, or when the debugger
248
is stepping/advancing). It should be locked while the debugger
249
is active but not running the CPU. This is so the debugger can
250
use System.peek() to examine memory/registers without changing
251
the state of the system.
254
void unlockDataBus();
258
Structure used to specify access methods for a page
263
Pointer to a block of memory or the null pointer. The null pointer
264
indicates that the device's peek method should be invoked for reads
265
to this page, while other values are the base address of an array
266
to directly access for reads to this page.
268
uInt8* directPeekBase;
271
Pointer to a block of memory or the null pointer. The null pointer
272
indicates that the device's poke method should be invoked for writes
273
to this page, while other values are the base address of an array
274
to directly access for pokes to this page.
276
uInt8* directPokeBase;
279
Pointer to the device associated with this page or to the system's
280
null device if the page hasn't been mapped to a device
286
Set the page accessing method for the specified page.
288
@param page The page accessing methods should be set for
289
@param access The accessing methods to be used by the page
291
void setPageAccess(uInt16 page, const PageAccess& access);
294
Get the page accessing method for the specified page.
296
@param page The page to get accessing methods for
297
@return The accessing methods used by the page
299
const PageAccess& getPageAccess(uInt16 page);
302
Save the current state of this system to the given Serializer.
304
@param out The Serializer object to use
305
@return False on any errors, else true
307
bool save(Serializer& out) const;
310
Load the current state of this system from the given Deserializer.
312
@param in The Deserializer object to use
313
@return False on any errors, else true
315
bool load(Deserializer& in);
318
Get a descriptor for the device name (used in error checking).
320
@return The name of the object
322
virtual string name() const { return "System"; }
325
// Mask to apply to an address before accessing memory
326
const uInt16 myAddressMask;
328
// Amount to shift an address by to determine what page it's on
329
const uInt16 myPageShift;
331
// Mask to apply to an address to obtain its page offset
332
const uInt16 myPageMask;
334
// Number of pages in the system
335
const uInt16 myNumberOfPages;
337
// Pointer to a dynamically allocated array of PageAccess structures
338
PageAccess* myPageAccessTable;
340
// Array of all the devices attached to the system
341
Device* myDevices[100];
343
// Number of devices attached to the system
344
uInt32 myNumberOfDevices;
346
// 6502 processor attached to the system or the null pointer
349
// 6532 processor attached to the system or the null pointer
352
// TIA device attached to the system or the null pointer
355
// Number of system cycles executed since the last reset
358
// Null device to use for page which are not installed
359
NullDevice myNullDevice;
361
// The current state of the Data Bus
362
uInt8 myDataBusState;
364
// Whether or not peek() updates the data bus state. This
365
// is true during normal emulation, and false when the
366
// debugger is active.
367
bool myDataBusLocked;
370
// Copy constructor isn't supported by this class so make it private
371
System(const System&);
373
// Assignment operator isn't supported by this class so make it private
374
System& operator = (const System&);