-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathCart.hxx
185 lines (145 loc) · 5.65 KB
/
Cart.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//============================================================================
//
// K K RRRR OOO K K CCCC OOO M M
// K K R R O O K K C O O MM MM
// KKK RRRR O O KKK C O O M M M "Krokodile Cart software"
// K K R R O O K K C O O M M
// K K R R OOO K K CCCC OOO M M
//
// Copyright (c) 2009-2020 by Stephen Anthony <sa666666@gmail.com>
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef CART_HXX
#define CART_HXX
// 2048 sectors of 256 bytes each
#define MAXCARTSIZE 2048*256
#include <vector>
#include "bspf.hxx"
#include "BSType.hxx"
#include "SerialPort.hxx"
/**
*
* @author stephena
*/
class Cart
{
public:
/**
Create a new Cart object, which can be used to create single
cartridge or one consisting of many ROMs (aka multi-cart).
*/
Cart() = default;
public:
/**
Loads cartridge data from the given filename, creating a cart.
The bankswitch type is autodetected if type is "".
The filename should exist and be readable.
*/
bool create(const string& filename, const string& type = "");
/**
Creates a single ROM file comprised of the given files.
This will be a 'multi-cart' ROM, consisting of each of the separate
ROMs, all with the same bankswitching scheme.
*/
bool createMultiFile(const StringList& menuNames, const StringList& fileNames,
BSType type, bool ntsc, const string& romfile = "");
//////////////////////////////////////////////////////////////////
// The following two methods act as an iterator through all the
// sectors making up the current Cart.
//////////////////////////////////////////////////////////////////
/**
Initializes the sector iterator to the beginning of the list,
in preparation for multiple calls to writeNextSector() or
verifyNextSector().
NOTE: After calling initSectors(), DO NOT mix calls to
writeNextSector() and verifyNextSector().
@return The number of sectors that need to be accessed
*/
uInt16 initSectors(bool downloadMode);
/**
Write the next sector in the iterator to the serial port,
returning the actual sector number that was written.
NOTE: After calling initSectors(), DO NOT mix calls to
writeNextSector() and verifyNextSector().
@return The sector number written; an exception is thrown
on any errors
*/
uInt16 writeNextSector(SerialPort& port);
/**
Read and verify the next sector in the iterator from the serial port,
returning the actual sector number that was verified.
NOTE: After calling initSectors(), DO NOT mix calls to
writeNextSector() and verifyNextSector().
@return The sector number verified; an exception is thrown
on any errors
*/
uInt16 verifyNextSector(SerialPort& port);
/**
Finalizes the sector iterator after all sectors have been downloaded.
@return True if all sectors were written, else false.
*/
bool finalizeSectors();
/**
Return the current position of the sector iterator.
@return The current sector number
*/
uInt16 currentSector() const { return myCurrentSector; }
/** Accessor and mutator for bankswitch type. */
BSType getBSType() const { return myType; }
void setBSType(BSType type) { myType = type; }
/** Accessor and mutator for incremental download. */
bool getIncremental() const { return myIncremental; }
void setIncremental(bool enable) { myIncremental = enable; }
/** Set number of write retries before bailing out. */
void setRetry(int retry) { myRetry = retry; }
/** Get the current cart size. */
uInt32 getSize() const { return myCartSize; }
/** Was the ROM loaded correctly? */
bool isValid() const { return myIsValid; }
/** Get the most recent logged message. */
const string& message() const { return myLogMessage; }
static void setLastRomFilePath(const string& rom) { ourLastCart = rom; }
private:
/**
Read data from given file and place it in the given buffer.
@return The number of bytes read (0 indicates error).
*/
uInt32 readFile(const string& filename, uInt8* buffer, uInt32 maxSize, bool showmessage = true) const;
/**
Write data from the given buffer to the given file.
@return The number of bytes written (0 indicates error).
*/
uInt32 writeFile(const string& filename, uInt8* buffer, uInt32 size, bool showmessage = true) const;
/**
Write the given sector to the serial port.
*/
void padImage(uInt8* buffer, uInt32 bufsize, uInt32 requiredsize) const;
/**
Write the given sector to the serial port.
*/
bool downloadSector(uInt32 sector, SerialPort& port) const;
/**
Read and verify the given sector from the serial port.
*/
bool verifySector(uInt32 sector, SerialPort& port) const;
/**
Fill the buffer with the data read ...
*/
void menuEntry(uInt8* buffer, const string& name) const;
private:
uInt8 myCart[MAXCARTSIZE];
uInt32 myCartSize{0};
uInt32 myRetry{0};
BSType myType{BS_NONE};
bool myIncremental{false};
// The following keep track of progress of sector writes
uInt16 myCurrentSector{0};
uInt16 myNumSectors{0};
bool myModifiedSectors[MAXCARTSIZE/256];
bool myIsValid{false};
string myLogMessage;
static string ourLastCart;
};
#endif