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 CARTRIDGEAR_HXX |
19 | #define CARTRIDGEAR_HXX |
20 | |
21 | class System; |
22 | |
23 | #include "bspf.hxx" |
24 | #include "Cart.hxx" |
25 | #ifdef DEBUGGER_SUPPORT |
26 | #include "CartARWidget.hxx" |
27 | #endif |
28 | |
29 | /** |
30 | FIXME: This scheme needs to be be described in more detail. |
31 | |
32 | This is the cartridge class for Arcadia (aka Starpath) Supercharger |
33 | games. Christopher Salomon provided most of the technical details |
34 | used in creating this class. A good description of the Supercharger |
35 | is provided in the Cuttle Cart's manual. |
36 | |
37 | The Supercharger has four 2K banks. There are three banks of RAM |
38 | and one bank of ROM. All 6K of the RAM can be read and written. |
39 | |
40 | @author Bradford W. Mott |
41 | */ |
42 | class CartridgeAR : public Cartridge |
43 | { |
44 | friend class CartridgeARWidget; |
45 | |
46 | public: |
47 | /** |
48 | Create a new cartridge using the specified image and size |
49 | |
50 | @param image Pointer to the ROM image |
51 | @param size The size of the ROM image |
52 | @param md5 The md5sum of the ROM image |
53 | @param settings A reference to the various settings (read-only) |
54 | */ |
55 | CartridgeAR(const ByteBuffer& image, size_t size, const string& md5, |
56 | const Settings& settings); |
57 | virtual ~CartridgeAR() = default; |
58 | |
59 | public: |
60 | /** |
61 | Reset device to its power-on state |
62 | */ |
63 | void reset() override; |
64 | |
65 | /** |
66 | Install cartridge in the specified system. Invoked by the system |
67 | when the cartridge is attached to it. |
68 | |
69 | @param system The system the device should install itself in |
70 | */ |
71 | void install(System& system) override; |
72 | |
73 | /** |
74 | Install pages for the specified bank in the system. |
75 | |
76 | @param bank The bank that should be installed in the system |
77 | */ |
78 | bool bank(uInt16 bank) override; |
79 | |
80 | /** |
81 | Get the current bank. |
82 | |
83 | @param address The address to use when querying the bank |
84 | */ |
85 | uInt16 getBank(uInt16 address = 0) const override; |
86 | |
87 | /** |
88 | Query the number of banks supported by the cartridge. |
89 | */ |
90 | uInt16 bankCount() const override; |
91 | |
92 | /** |
93 | Patch the cartridge ROM. |
94 | |
95 | @param address The ROM address to patch |
96 | @param value The value to place into the address |
97 | @return Success or failure of the patch operation |
98 | */ |
99 | bool patch(uInt16 address, uInt8 value) override; |
100 | |
101 | /** |
102 | Access the internal ROM image for this cartridge. |
103 | |
104 | @param size Set to the size of the internal ROM image data |
105 | @return A pointer to the internal ROM image data |
106 | */ |
107 | const uInt8* getImage(size_t& size) const override; |
108 | |
109 | /** |
110 | Save the current state of this cart to the given Serializer. |
111 | |
112 | @param out The Serializer object to use |
113 | @return False on any errors, else true |
114 | */ |
115 | bool save(Serializer& out) const override; |
116 | |
117 | /** |
118 | Load the current state of this cart from the given Serializer. |
119 | |
120 | @param in The Serializer object to use |
121 | @return False on any errors, else true |
122 | */ |
123 | bool load(Serializer& in) override; |
124 | |
125 | /** |
126 | Get a descriptor for the device name (used in error checking). |
127 | |
128 | @return The name of the object |
129 | */ |
130 | string name() const override { return "CartridgeAR" ; } |
131 | |
132 | #ifdef DEBUGGER_SUPPORT |
133 | /** |
134 | Get debugger widget responsible for accessing the inner workings |
135 | of the cart. |
136 | */ |
137 | CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont, |
138 | const GUI::Font& nfont, int x, int y, int w, int h) override |
139 | { |
140 | return new CartridgeARWidget(boss, lfont, nfont, x, y, w, h, *this); |
141 | } |
142 | #endif |
143 | |
144 | public: |
145 | /** |
146 | Get the byte at the specified address |
147 | |
148 | @return The byte at the specified address |
149 | */ |
150 | uInt8 peek(uInt16 address) override; |
151 | |
152 | /** |
153 | Change the byte at the specified address to the given value |
154 | |
155 | @param address The address where the value should be stored |
156 | @param value The value to be stored at the address |
157 | @return True if the poke changed the device address space, else false |
158 | */ |
159 | bool poke(uInt16 address, uInt8 value) override; |
160 | |
161 | private: |
162 | /** |
163 | Query the given address type for the associated disassembly flags. |
164 | |
165 | @param address The address to query |
166 | */ |
167 | uInt8 getAccessFlags(uInt16 address) const override; |
168 | /** |
169 | Change the given address to use the given disassembly flags. |
170 | |
171 | @param address The address to modify |
172 | @param flags A bitfield of DisasmType directives for the given address |
173 | */ |
174 | void setAccessFlags(uInt16 address, uInt8 flags) override; |
175 | |
176 | // Handle a change to the bank configuration |
177 | bool bankConfiguration(uInt8 configuration); |
178 | |
179 | // Compute the sum of the array of bytes |
180 | uInt8 checksum(uInt8* s, uInt16 length); |
181 | |
182 | // Load the specified load into SC RAM |
183 | void loadIntoRAM(uInt8 load); |
184 | |
185 | // Sets up a "dummy" BIOS ROM in the ROM bank of the cartridge |
186 | void initializeROM(); |
187 | |
188 | private: |
189 | // Indicates the offset within the image for the corresponding bank |
190 | std::array<uInt32, 2> myImageOffset; |
191 | |
192 | // The 6K of RAM and 2K of ROM contained in the Supercharger |
193 | std::array<uInt8, 8_KB> myImage; |
194 | |
195 | // The 256 byte header for the current 8448 byte load |
196 | std::array<uInt8, 256> ; |
197 | |
198 | // Size of the ROM image |
199 | size_t mySize; |
200 | |
201 | // All of the 8448 byte loads associated with the game |
202 | ByteBuffer myLoadImages; |
203 | |
204 | // Indicates how many 8448 loads there are |
205 | uInt8 myNumberOfLoadImages; |
206 | |
207 | // Indicates if the RAM is write enabled |
208 | bool myWriteEnabled; |
209 | |
210 | // Indicates if the ROM's power is on or off |
211 | bool myPower; |
212 | |
213 | // Data hold register used for writing |
214 | uInt8 myDataHoldRegister; |
215 | |
216 | // Indicates number of distinct accesses when data hold register was set |
217 | uInt32 myNumberOfDistinctAccesses; |
218 | |
219 | // Indicates if a write is pending or not |
220 | bool myWritePending; |
221 | |
222 | // Indicates which bank is currently active |
223 | uInt16 myCurrentBank; |
224 | |
225 | // Fake SC-BIOS code to simulate the Supercharger load bars |
226 | static std::array<uInt8, 294> ourDummyROMCode; |
227 | |
228 | // Default 256-byte header to use if one isn't included in the ROM |
229 | // This data comes from z26 |
230 | static const std::array<uInt8, 256> ; |
231 | |
232 | private: |
233 | // Following constructors and assignment operators not supported |
234 | CartridgeAR() = delete; |
235 | CartridgeAR(const CartridgeAR&) = delete; |
236 | CartridgeAR(CartridgeAR&&) = delete; |
237 | CartridgeAR& operator=(const CartridgeAR&) = delete; |
238 | CartridgeAR& operator=(CartridgeAR&&) = delete; |
239 | }; |
240 | |
241 | #endif |
242 | |