00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <QString>
00026
00027 #include "decoder.hh"
00028 #include "../model/nesgamegeniecode.hh"
00029 #include "../model/nesrawcode.hh"
00030 #include "../model/snesgamegeniecode.hh"
00031 #include "../model/snesrawcode.hh"
00032 #include "../model/genesisgamegeniecode.hh"
00033 #include "../model/genesisrawcode.hh"
00034 #include "../model/gbgggamegeniecode.hh"
00035 #include "../model/gbggrawcode.hh"
00036 #include "../exceptions/invalidgamegeniecode.hh"
00037
00038 using namespace emuWorks;
00039
00040 NESRawCode Decoder::decodeNES(GameGenieCode &code) {
00041 QString ggcode = code.getCode();
00042 int length = ggcode.length();
00043
00044 if (!NESGameGenieCode::isValidCode(ggcode)) {
00045 throw InvalidGameGenieCodeException();
00046 }
00047
00048 int bitstring = 0;
00049
00050 for (int i = 0; i < length; i++) {
00051 QChar ch = ggcode[i];
00052
00053 bitstring <<= 4;
00054 bitstring |= code.toHex(ch.toAscii());
00055 }
00056
00057 int value;
00058 int address;
00059 int temp;
00060
00061 if (length == 6) {
00062 bitstring <<= 8;
00063 }
00064
00065
00066 value = ((bitstring >> 28) & 0x8) | ((bitstring >> 24) & 0x7);
00067
00068 if (length == 6) {
00069 temp = (bitstring & 0x800) >> 8;
00070 } else {
00071 temp = bitstring & 0x8;
00072 }
00073
00074 temp |= ((bitstring >> 28) & 0x7);
00075
00076 value <<= 4;
00077 value |= temp;
00078
00079
00080 address = (bitstring & 0x70000) >> 16;
00081
00082
00083 temp = ((bitstring & 0x8000) >> 12) | ((bitstring & 0x700) >> 8);
00084 address <<= 4;
00085 address |= temp;
00086
00087
00088 temp = ((bitstring & 0x8000000) >> 24) | ((bitstring & 0x700000) >> 20);
00089 address <<= 4;
00090 address |= temp;
00091
00092
00093 temp = ((bitstring & 0x80000) >> 16) | ((bitstring & 0x7000) >> 12);
00094 address <<= 4;
00095 address |= temp;
00096
00097 if (length == 6) {
00098 return NESRawCode(address, value);
00099 }
00100
00101 int compare;
00102
00103
00104 compare = ((bitstring & 0x80) >> 4) | (bitstring & 0x7);
00105
00106
00107 temp = ((bitstring & 0x800) >> 8) | ((bitstring & 0x70) >> 4);
00108 compare <<= 4;
00109 compare |= temp;
00110
00111 return NESRawCode(address, value, compare);
00112 }
00113
00114 SNESRawCode Decoder::decodeSNES(GameGenieCode &code) {
00115 QString ggcode = code.getCode();
00116 int length = ggcode.length();
00117
00118 if (!SNESGameGenieCode::isValidCode(ggcode)) {
00119 throw InvalidGameGenieCodeException();
00120 }
00121
00122 int bitstring = 0;
00123
00124 for (int i = 0; i < length; i++) {
00125 if (i == 4) {
00126 continue;
00127 }
00128
00129 QChar ch = ggcode[i];
00130
00131 bitstring <<= 4;
00132 bitstring |= code.toHex(ch.toAscii());
00133 }
00134
00135 int value;
00136 int address;
00137 int temp;
00138
00139
00140 value = (bitstring >> 24) & 0xFF;
00141
00142
00143 address = ((bitstring >> 10) & 0xC) | ((bitstring >> 10) & 0x3);
00144
00145
00146 temp = ((bitstring >> 2) & 0xC) | ((bitstring >> 2) & 0x3);
00147 address <<= 4;
00148 address |= temp;
00149
00150
00151 temp = (bitstring >> 20) & 0xF;
00152 address <<= 4;
00153 address |= temp;
00154
00155
00156 temp = ((bitstring << 2) & 0xC) | ((bitstring >> 14) & 0x3);
00157 address <<= 4;
00158 address |= temp;
00159
00160
00161 temp = (bitstring >> 16) & 0xF;
00162 address <<= 4;
00163 address |= temp;
00164
00165
00166 temp = ((bitstring >> 6) & 0xC) | ((bitstring >> 6) & 0x3);
00167 address <<= 4;
00168 address |= temp;
00169
00170 return SNESRawCode(address, value);
00171 }
00172
00173 GenesisRawCode Decoder::decodeGenesis(GameGenieCode &code) {
00174 QString ggcode = code.getCode();
00175 int length = ggcode.length();
00176
00177 if (!GenesisGameGenieCode::isValidCode(ggcode)) {
00178 throw InvalidGameGenieCodeException();
00179 }
00180
00181 qint64 bitstring = 0;
00182
00183 for (int i = 0; i < length; i++) {
00184 if (i == 4) {
00185 continue;
00186 }
00187
00188 QChar ch = ggcode[i];
00189
00190 bitstring <<= 5;
00191 bitstring |= code.toHex(ch.toAscii());
00192 }
00193
00194 int value;
00195 int address;
00196 int temp;
00197
00198
00199 value = (int)(((bitstring >> 7) & 0xE) | ((bitstring >> 15) & 0x1));
00200
00201
00202 temp = (int)(((bitstring >> 11) & 0xE) | ((bitstring >> 11) & 0x1));
00203 value <<= 4;
00204 value |= temp;
00205
00206
00207 temp = (int)(bitstring >> 32);
00208 value <<= 8;
00209 value |= temp;
00210
00211
00212
00213
00214 address = (int)((bitstring >> 16) & 0xFF);
00215
00216
00217 temp = (int)((bitstring >> 24) & 0xFF);
00218 address <<= 8;
00219 address |= temp;
00220
00221
00222 temp = (int)(bitstring & 0xFF);
00223 address <<= 8;
00224 address |= temp;
00225
00226 return GenesisRawCode(address, value);
00227 }
00228
00229 GBGGRawCode Decoder::decodeGBGG(GameGenieCode &code) {
00230 QString ggcode = code.getCode();
00231 int length = ggcode.length();
00232
00233 if (!GBGGGameGenieCode::isValidCode(ggcode)) {
00234 throw InvalidGameGenieCodeException();
00235 }
00236
00237 qint64 bitstring = 0;
00238
00239 for (int i = 0; i < length; i++) {
00240 if ((i == 3) || (i == 7)) {
00241 continue;
00242 }
00243
00244 QChar ch = ggcode[i];
00245
00246 bitstring <<= 4;
00247 bitstring |= code.toHex(ch.toAscii());
00248 }
00249
00250 int value;
00251 int address;
00252 int temp;
00253
00254 if (length == 7) {
00255 bitstring <<= 12;
00256 }
00257
00258 value = (int)(bitstring >> 28);
00259
00260 temp = (int)((bitstring >> 12) & 0xF);
00261 temp = (~temp & 0xF) << 12;
00262 address = (int)((bitstring >> 16) & 0xFFF) | temp;
00263
00264 if (length == 7) {
00265 return GBGGRawCode(address, value);
00266 }
00267
00268 temp = (int)(((bitstring >> 4) & 0xF0) | (bitstring & 0xF));
00269 temp = (temp >> 2) | ((temp << 6) & 0xFC);
00270
00271 int compare = temp ^ 0xBA;
00272
00273 return GBGGRawCode(address, value, compare);
00274 }
00275