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
21class 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*/
42class 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> myHeader;
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> ourDefaultHeader;
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