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 CARTRIDGEFA2_HXX
19#define CARTRIDGEFA2_HXX
20
21class System;
22
23#include "bspf.hxx"
24#include "Cart.hxx"
25#ifdef DEBUGGER_SUPPORT
26 #include "CartFA2Widget.hxx"
27#endif
28
29/**
30 This is an extended version of the CBS RAM Plus bankswitching scheme
31 supported by the Harmony cartridge.
32
33 There are six (or seven) 4K banks, accessible by read/write to $1FF5 -
34 $1FFA (or $1FFB), and 256 bytes of RAM.
35
36 The 256 bytes of RAM can be loaded/saved to Harmony cart flash by
37 accessing $1FF4 (see ramReadWrite() for more information), which is
38 emulated by storing in a file.
39 RAM read port is $1100 - $11FF, write port is $1000 - $10FF.
40
41 For 29K versions of the scheme, the first 1K is ARM code (implements
42 actual bankswitching on the Harmony cart), which is completely ignored
43 by the emulator. Also supported is a 32K variant. In any event, only
44 data at 1K - 29K of the ROM is used.
45
46 @author Chris D. Walton
47*/
48class CartridgeFA2 : public Cartridge
49{
50 friend class CartridgeFA2Widget;
51
52 public:
53 /**
54 Create a new cartridge using the specified image
55
56 @param image Pointer to the ROM image
57 @param size The size of the ROM image
58 @param md5 The md5sum of the ROM image
59 @param settings A reference to the settings object
60 */
61 CartridgeFA2(const ByteBuffer& image, size_t size, const string& md5,
62 const Settings& settings);
63 virtual ~CartridgeFA2() = default;
64
65 public:
66 /**
67 Reset device to its power-on state
68 */
69 void reset() override;
70
71 /**
72 Install cartridge in the specified system. Invoked by the system
73 when the cartridge is attached to it.
74
75 @param system The system the device should install itself in
76 */
77 void install(System& system) override;
78
79 /**
80 Install pages for the specified bank in the system.
81
82 @param bank The bank that should be installed in the system
83 */
84 bool bank(uInt16 bank) override;
85
86 /**
87 Get the current bank.
88
89 @param address The address to use when querying the bank
90 */
91 uInt16 getBank(uInt16 address = 0) const override;
92
93 /**
94 Query the number of banks supported by the cartridge.
95 */
96 uInt16 bankCount() const override;
97
98 /**
99 Patch the cartridge ROM.
100
101 @param address The ROM address to patch
102 @param value The value to place into the address
103 @return Success or failure of the patch operation
104 */
105 bool patch(uInt16 address, uInt8 value) override;
106
107 /**
108 Access the internal ROM image for this cartridge.
109
110 @param size Set to the size of the internal ROM image data
111 @return A pointer to the internal ROM image data
112 */
113 const uInt8* getImage(size_t& size) const override;
114
115 /**
116 Save the current state of this cart to the given Serializer.
117
118 @param out The Serializer object to use
119 @return False on any errors, else true
120 */
121 bool save(Serializer& out) const override;
122
123 /**
124 Load the current state of this cart from the given Serializer.
125
126 @param in The Serializer object to use
127 @return False on any errors, else true
128 */
129 bool load(Serializer& in) override;
130
131 /**
132 Get a descriptor for the device name (used in error checking).
133
134 @return The name of the object
135 */
136 string name() const override { return "CartridgeFA2"; }
137
138 /**
139 Informs the cartridge about the name of the nvram file it will use.
140
141 @param nvramdir The full path of the nvram directory
142 @param romfile The name of the cart from ROM properties
143 */
144 void setNVRamFile(const string& nvramdir, const string& romfile) override;
145
146 #ifdef DEBUGGER_SUPPORT
147 /**
148 Get debugger widget responsible for accessing the inner workings
149 of the cart.
150 */
151 CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
152 const GUI::Font& nfont, int x, int y, int w, int h) override
153 {
154 return new CartridgeFA2Widget(boss, lfont, nfont, x, y, w, h, *this);
155 }
156 #endif
157
158 public:
159 /**
160 Get the byte at the specified address.
161
162 @return The byte at the specified address
163 */
164 uInt8 peek(uInt16 address) override;
165
166 /**
167 Change the byte at the specified address to the given value
168
169 @param address The address where the value should be stored
170 @param value The value to be stored at the address
171 @return True if the poke changed the device address space, else false
172 */
173 bool poke(uInt16 address, uInt8 value) override;
174
175 private:
176 /**
177 Either load or save internal RAM to Harmony flash (represented by
178 a file in emulation).
179
180 @return The value at $FF4 with bit 6 set or cleared (depending on
181 whether the RAM access was busy or successful)
182 */
183 uInt8 ramReadWrite();
184
185 /**
186 Modify Harmony flash directly (represented by a file in emulation),
187 ignoring any timing emulation. This is for use strictly in the
188 debugger, so you can have low-level access to the Flash media.
189
190 @param operation 0 for erase, 1 for read, 2 for write
191 */
192 void flash(uInt8 operation);
193
194 private:
195 // The 24K/28K ROM image of the cartridge
196 std::array<uInt8, 28_KB> myImage;
197
198 // Actual usable size of the ROM image
199 size_t mySize;
200
201 // The 256 bytes of RAM on the cartridge
202 std::array<uInt8, 256> myRAM;
203
204 // The time after which the first request of a load/save operation
205 // will actually be completed
206 // Due to flash RAM constraints, a read/write isn't instantaneous,
207 // so we need to emulate the delay as well
208 uInt64 myRamAccessTimeout;
209
210 // Full pathname of the file to use when emulating load/save
211 // of internal RAM to Harmony cart flash
212 string myFlashFile;
213
214 // Indicates the offset into the ROM image (aligns to current bank)
215 uInt16 myBankOffset;
216
217 private:
218 // Following constructors and assignment operators not supported
219 CartridgeFA2() = delete;
220 CartridgeFA2(const CartridgeFA2&) = delete;
221 CartridgeFA2(CartridgeFA2&&) = delete;
222 CartridgeFA2& operator=(const CartridgeFA2&) = delete;
223 CartridgeFA2& operator=(CartridgeFA2&&) = delete;
224};
225
226#endif
227