1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef CARTRIDGEE0_HXX
19#define CARTRIDGEE0_HXX
20
21class System;
22
23#include "bspf.hxx"
24#include "Cart.hxx"
25#ifdef DEBUGGER_SUPPORT
26 #include "CartE0Widget.hxx"
27#endif
28
29/**
30 This is the cartridge class for Parker Brothers' 8K games. In
31 this bankswitching scheme the 2600's 4K cartridge address space
32 is broken into four 1K segments. The desired 1K slice of the
33 ROM is selected by accessing $1FE0 to $1FE7 for the first 1K.
34 $1FE8 to $1FEF selects the slice for the second 1K, and $1FF0 to
35 $1FF7 selects the slice for the third 1K. The last 1K segment
36 always points to the last 1K of the ROM image.
37
38 Because of the complexity of this scheme, the cart reports having
39 only one actual bank, in which pieces of it can be swapped out in
40 many different ways.
41
42 @author Bradford W. Mott
43*/
44class CartridgeE0 : public Cartridge
45{
46 friend class CartridgeE0Widget;
47
48 public:
49 /**
50 Create a new cartridge using the specified image
51
52 @param image Pointer to the ROM image
53 @param size The size of the ROM image
54 @param md5 The md5sum of the ROM image
55 @param settings A reference to the various settings (read-only)
56 */
57 CartridgeE0(const ByteBuffer& image, size_t size, const string& md5,
58 const Settings& settings);
59 virtual ~CartridgeE0() = default;
60
61 public:
62 /**
63 Reset device to its power-on state
64 */
65 void reset() override;
66
67 /**
68 Install cartridge in the specified system. Invoked by the system
69 when the cartridge is attached to it.
70
71 @param system The system the device should install itself in
72 */
73 void install(System& system) override;
74
75
76 /**
77 Get the current bank.
78
79 @param address The address to use when querying the bank
80 */
81 uInt16 getBank(uInt16 address = 0) const override;
82
83 /**
84 Query the number of banks supported by the cartridge.
85 */
86 uInt16 bankCount() const override;
87
88 /**
89 Patch the cartridge ROM.
90
91 @param address The ROM address to patch
92 @param value The value to place into the address
93 @return Success or failure of the patch operation
94 */
95 bool patch(uInt16 address, uInt8 value) override;
96
97 /**
98 Access the internal ROM image for this cartridge.
99
100 @param size Set to the size of the internal ROM image data
101 @return A pointer to the internal ROM image data
102 */
103 const uInt8* getImage(size_t& size) const override;
104
105 /**
106 Save the current state of this cart to the given Serializer.
107
108 @param out The Serializer object to use
109 @return False on any errors, else true
110 */
111 bool save(Serializer& out) const override;
112
113 /**
114 Load the current state of this cart from the given Serializer.
115
116 @param in The Serializer object to use
117 @return False on any errors, else true
118 */
119 bool load(Serializer& in) override;
120
121 /**
122 Get a descriptor for the device name (used in error checking).
123
124 @return The name of the object
125 */
126 string name() const override { return "CartridgeE0"; }
127
128 #ifdef DEBUGGER_SUPPORT
129 /**
130 Get debugger widget responsible for accessing the inner workings
131 of the cart.
132 */
133 CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
134 const GUI::Font& nfont, int x, int y, int w, int h) override
135 {
136 return new CartridgeE0Widget(boss, lfont, nfont, x, y, w, h, *this);
137 }
138 #endif
139
140 public:
141 /**
142 Get the byte at the specified address.
143
144 @return The byte at the specified address
145 */
146 uInt8 peek(uInt16 address) override;
147
148 /**
149 Change the byte at the specified address to the given value
150
151 @param address The address where the value should be stored
152 @param value The value to be stored at the address
153 @return True if the poke changed the device address space, else false
154 */
155 bool poke(uInt16 address, uInt8 value) override;
156
157 private:
158 /**
159 Install the specified slice for segment zero
160
161 @param slice The slice to map into the segment
162 */
163 void segmentZero(uInt16 slice);
164
165 /**
166 Install the specified slice for segment one
167
168 @param slice The slice to map into the segment
169 */
170 void segmentOne(uInt16 slice);
171
172 /**
173 Install the specified slice for segment two
174
175 @param slice The slice to map into the segment
176 */
177 void segmentTwo(uInt16 slice);
178
179 private:
180 // The 8K ROM image of the cartridge
181 std::array<uInt8, 8_KB> myImage;
182
183 // Indicates the slice mapped into each of the four segments
184 std::array<uInt16, 4> myCurrentSlice;
185
186 private:
187 // Following constructors and assignment operators not supported
188 CartridgeE0() = delete;
189 CartridgeE0(const CartridgeE0&) = delete;
190 CartridgeE0(CartridgeE0&&) = delete;
191 CartridgeE0& operator=(const CartridgeE0&) = delete;
192 CartridgeE0& operator=(CartridgeE0&&) = delete;
193};
194
195#endif
196