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 CARTRIDGE_BUS_HXX
19#define CARTRIDGE_BUS_HXX
20
21class System;
22class Thumbulator;
23#ifdef DEBUGGER_SUPPORT
24 #include "CartBUSWidget.hxx"
25#endif
26
27#include "bspf.hxx"
28#include "Cart.hxx"
29
30/**
31 Cartridge class used for BUS.
32
33 THIS BANKSWITCHING SCHEME IS EXPERIMENTAL, AND MAY BE REMOVED
34 IN A FUTURE RELEASE.
35
36 There are seven 4K program banks, a 4K Display Data RAM,
37 1K C Varaible and Stack, and the BUS chip.
38 BUS chip access is mapped to $1000 - $103F.
39
40 @authors: Darrell Spice Jr, Chris Walton, Fred Quimby,
41 Stephen Anthony, Bradford W. Mott
42*/
43class CartridgeBUS : public Cartridge
44{
45 friend class CartridgeBUSWidget;
46 friend class CartridgeRamBUSWidget;
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 CartridgeBUS(const ByteBuffer& image, size_t size, const string& md5,
58 const Settings& settings);
59 virtual ~CartridgeBUS() = default;
60
61 public:
62 /**
63 Reset device to its power-on state
64 */
65 void reset() override;
66
67 /**
68 Notification method invoked by the system when the console type
69 has changed. We need this to inform the Thumbulator that the
70 timing has changed.
71
72 @param timing Enum representing the new console type
73 */
74 void consoleChanged(ConsoleTiming timing) override;
75
76 /**
77 Install cartridge in the specified system. Invoked by the system
78 when the cartridge is attached to it.
79
80 @param system The system the device should install itself in
81 */
82 void install(System& system) override;
83
84 /**
85 Install pages for the specified bank in the system.
86
87 @param bank The bank that should be installed in the system
88 */
89 bool bank(uInt16 bank) override;
90
91 /**
92 Get the current bank.
93
94 @param address The address to use when querying the bank
95 */
96 uInt16 getBank(uInt16 address = 0) const override;
97
98 /**
99 Query the number of banks supported by the cartridge.
100 */
101 uInt16 bankCount() const override;
102
103 /**
104 Patch the cartridge ROM.
105
106 @param address The ROM address to patch
107 @param value The value to place into the address
108 @return Success or failure of the patch operation
109 */
110 bool patch(uInt16 address, uInt8 value) override;
111
112 /**
113 Access the internal ROM image for this cartridge.
114
115 @param size Set to the size of the internal ROM image data
116 @return A pointer to the internal ROM image data
117 */
118 const uInt8* getImage(size_t& size) const override;
119
120 /**
121 Save the current state of this cart to the given Serializer.
122
123 @param out The Serializer object to use
124 @return False on any errors, else true
125 */
126 bool save(Serializer& out) const override;
127
128 /**
129 Load the current state of this cart from the given Serializer.
130
131 @param in The Serializer object to use
132 @return False on any errors, else true
133 */
134 bool load(Serializer& in) override;
135
136 /**
137 Get a descriptor for the device name (used in error checking).
138
139 @return The name of the object
140 */
141 string name() const override { return "CartridgeBUS"; }
142
143 uInt8 busOverdrive(uInt16 address);
144
145 /**
146 Used for Thumbulator to pass values back to the cartridge
147 */
148 uInt32 thumbCallback(uInt8 function, uInt32 value1, uInt32 value2) override;
149
150
151 #ifdef DEBUGGER_SUPPORT
152 /**
153 Get debugger widget responsible for accessing the inner workings
154 of the cart.
155 */
156 CartDebugWidget* debugWidget(GuiObject* boss, const GUI::Font& lfont,
157 const GUI::Font& nfont, int x, int y, int w, int h) override
158 {
159 return new CartridgeBUSWidget(boss, lfont, nfont, x, y, w, h, *this);
160 }
161 #endif
162
163 public:
164 /**
165 Get the byte at the specified address.
166
167 @return The byte at the specified address
168 */
169 uInt8 peek(uInt16 address) override;
170
171 /**
172 Change the byte at the specified address to the given value
173
174 @param address The address where the value should be stored
175 @param value The value to be stored at the address
176 @return True if the poke changed the device address space, else false
177 */
178 bool poke(uInt16 address, uInt8 value) override;
179
180 private:
181 /**
182 Sets the initial state of the DPC pointers and RAM
183 */
184 void setInitialState();
185
186 /**
187 Updates any data fetchers in music mode based on the number of
188 CPU cycles which have passed since the last update.
189 */
190 void updateMusicModeDataFetchers();
191
192 /**
193 Call Special Functions
194 */
195 void callFunction(uInt8 value);
196
197 uInt32 getDatastreamPointer(uInt8 index) const;
198 void setDatastreamPointer(uInt8 index, uInt32 value);
199
200 uInt32 getDatastreamIncrement(uInt8 index) const;
201 void setDatastreamIncrement(uInt8 index, uInt32 value);
202
203 uInt32 getAddressMap(uInt8 index) const;
204 void setAddressMap(uInt8 index, uInt32 value);
205
206 uInt8 readFromDatastream(uInt8 index);
207
208 uInt32 getWaveform(uInt8 index) const;
209 uInt32 getWaveformSize(uInt8 index) const;
210 uInt32 getSample();
211
212 private:
213 // The 32K ROM image of the cartridge
214 std::array<uInt8, 32_KB> myImage;
215
216 // Pointer to the 28K program ROM image of the cartridge
217 uInt8* myProgramImage;
218
219 // Pointer to the 4K display ROM image of the cartridge
220 uInt8* myDisplayImage;
221
222 // Pointer to the 2K BUS driver image in RAM
223 uInt8* myBusDriverImage;
224
225 // The BUS 8k RAM image, used as:
226 // $0000 - 2K BUS driver
227 // $0800 - 4K Display Data
228 // $1800 - 2K C Variable & Stack
229 std::array<uInt8, 8_KB> myBUSRAM;
230
231 // Pointer to the Thumb ARM emulator object
232 unique_ptr<Thumbulator> myThumbEmulator;
233
234 // Indicates the offset into the ROM image (aligns to current bank)
235 uInt16 myBankOffset;
236
237 // Address to override the bus for
238 uInt16 myBusOverdriveAddress;
239
240 // set to address of ZP if last byte peeked was $84 (STY ZP)
241 uInt16 mySTYZeroPageAddress;
242
243 // set to address of the JMP operand if last byte peeked was 4C
244 // *and* the next two bytes in ROM are 00 00
245 uInt16 myJMPoperandAddress;
246
247 // System cycle count from when the last update to music data fetchers occurred
248 uInt64 myAudioCycles;
249
250 // ARM cycle count from when the last callFunction() occurred
251 uInt64 myARMCycles;
252
253 // The music mode counters
254 std::array<uInt32, 3> myMusicCounters;
255
256 // The music frequency
257 std::array<uInt32, 3> myMusicFrequencies;
258
259 // The music waveform sizes
260 std::array<uInt8, 3> myMusicWaveformSize;
261
262 // Fractional DPC music OSC clocks unused during the last update
263 double myFractionalClocks;
264
265 // Controls mode, lower nybble sets Fast Fetch, upper nybble sets audio
266 // -0 = Bus Stuffing ON
267 // -F = Bus Stuffing OFF
268 // 0- = Packed Digital Sample
269 // F- = 3 Voice Music
270 uInt8 myMode;
271
272 uInt8 myFastJumpActive;
273
274 private:
275 // Following constructors and assignment operators not supported
276 CartridgeBUS() = delete;
277 CartridgeBUS(const CartridgeBUS&) = delete;
278 CartridgeBUS(CartridgeBUS&&) = delete;
279 CartridgeBUS& operator=(const CartridgeBUS&) = delete;
280 CartridgeBUS& operator=(CartridgeBUS&&) = delete;
281};
282
283#endif
284