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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "6510_.h"
00043 #include "emucfg.h"
00044
00045 #ifdef __SYMBIAN32__
00046 #include <e32base.h>
00047 #else
00048 #include <stdlib.h>
00049 #endif
00050
00051
00052
00053
00054
00055
00056
00057 C6510::C6510()
00061 :stackIsOkay(true)
00062 ,memoryMode(MPU_TRANSPARENT_ROM)
00063 ,iFakeRndSeed(0)
00064 {
00065 CTOR(C6510);
00066
00067
00068
00069
00070
00071 readData = &C6510::readData_bs;
00072 writeData = &C6510::writeData_bs;
00073
00074
00075
00076
00077
00078
00079
00080 int i=0;
00081
00082 instrList[i++] = &C6510::BRK_;
00083 instrList[i++] = &C6510::ORA_indx;
00084 instrList[i++] = &C6510::ILL_TILT;
00085 instrList[i++] = &C6510::ASLORA_indx;
00086 instrList[i++] = &C6510::ILL_2NOP;
00087 instrList[i++] = &C6510::ORA_zp;
00088 instrList[i++] = &C6510::ASL_zp;
00089 instrList[i++] = &C6510::ASLORA_zp;
00090 instrList[i++] = &C6510::PHP_;
00091 instrList[i++] = &C6510::ORA_imm;
00092 instrList[i++] = &C6510::ASL_AC;
00093 instrList[i++] = &C6510::ILL_0B;
00094 instrList[i++] = &C6510::ILL_3NOP;
00095 instrList[i++] = &C6510::ORA_abso;
00096 instrList[i++] = &C6510::ASL_abso;
00097 instrList[i++] = &C6510::ASLORA_abso;
00098 instrList[i++] = &C6510::BPL_;
00099 instrList[i++] = &C6510::ORA_indy;
00100 instrList[i++] = &C6510::ILL_TILT;
00101 instrList[i++] = &C6510::ASLORA_indy;
00102 instrList[i++] = &C6510::ILL_2NOP;
00103 instrList[i++] = &C6510::ORA_zpx;
00104 instrList[i++] = &C6510::ASL_zpx;
00105 instrList[i++] = &C6510::ASLORA_zpx;
00106 instrList[i++] = &C6510::CLC_;
00107 instrList[i++] = &C6510::ORA_absy;
00108 instrList[i++] = &C6510::ILL_1NOP;
00109 instrList[i++] = &C6510::ASLORA_absy;
00110 instrList[i++] = &C6510::ILL_3NOP;
00111 instrList[i++] = &C6510::ORA_absx;
00112 instrList[i++] = &C6510::ASL_absx;
00113 instrList[i++] = &C6510::ASLORA_absx;
00114 instrList[i++] = &C6510::JSR_;
00115 instrList[i++] = &C6510::AND_indx;
00116 instrList[i++] = &C6510::ILL_TILT;
00117 instrList[i++] = &C6510::ROLAND_indx;
00118 instrList[i++] = &C6510::BIT_zp;
00119 instrList[i++] = &C6510::AND_zp;
00120 instrList[i++] = &C6510::ROL_zp;
00121 instrList[i++] = &C6510::ROLAND_zp;
00122 instrList[i++] = &C6510::PLP_;
00123 instrList[i++] = &C6510::AND_imm;
00124 instrList[i++] = &C6510::ROL_AC;
00125 instrList[i++] = &C6510::ILL_0B;
00126 instrList[i++] = &C6510::BIT_abso;
00127 instrList[i++] = &C6510::AND_abso;
00128 instrList[i++] = &C6510::ROL_abso;
00129 instrList[i++] = &C6510::ROLAND_abso;
00130 instrList[i++] = &C6510::BMI_;
00131 instrList[i++] = &C6510::AND_indy;
00132 instrList[i++] = &C6510::ILL_TILT;
00133 instrList[i++] = &C6510::ROLAND_indy;
00134 instrList[i++] = &C6510::ILL_2NOP;
00135 instrList[i++] = &C6510::AND_zpx;
00136 instrList[i++] = &C6510::ROL_zpx;
00137 instrList[i++] = &C6510::ROLAND_zpx;
00138 instrList[i++] = &C6510::SEC_;
00139 instrList[i++] = &C6510::AND_absy;
00140 instrList[i++] = &C6510::ILL_1NOP;
00141 instrList[i++] = &C6510::ROLAND_absy;
00142 instrList[i++] = &C6510::ILL_3NOP;
00143 instrList[i++] = &C6510::AND_absx;
00144 instrList[i++] = &C6510::ROL_absx;
00145 instrList[i++] = &C6510::ROLAND_absx,
00146
00147 instrList[i++] = &C6510::RTI_;
00148 instrList[i++] = &C6510::EOR_indx;
00149 instrList[i++] = &C6510::ILL_TILT;
00150 instrList[i++] = &C6510::LSREOR_indx;
00151 instrList[i++] = &C6510::ILL_2NOP;
00152 instrList[i++] = &C6510::EOR_zp;
00153 instrList[i++] = &C6510::LSR_zp;
00154 instrList[i++] = &C6510::LSREOR_zp;
00155 instrList[i++] = &C6510::PHA_;
00156 instrList[i++] = &C6510::EOR_imm;
00157 instrList[i++] = &C6510::LSR_AC;
00158 instrList[i++] = &C6510::ILL_4B;
00159 instrList[i++] = &C6510::JMP_;
00160 instrList[i++] = &C6510::EOR_abso;
00161 instrList[i++] = &C6510::LSR_abso;
00162 instrList[i++] = &C6510::LSREOR_abso;
00163 instrList[i++] = &C6510::BVC_;
00164 instrList[i++] = &C6510::EOR_indy;
00165 instrList[i++] = &C6510::ILL_TILT;
00166 instrList[i++] = &C6510::LSREOR_indy;
00167 instrList[i++] = &C6510::ILL_2NOP;
00168 instrList[i++] = &C6510::EOR_zpx;
00169 instrList[i++] = &C6510::LSR_zpx;
00170 instrList[i++] = &C6510::LSREOR_zpx;
00171 instrList[i++] = &C6510::CLI_;
00172 instrList[i++] = &C6510::EOR_absy;
00173 instrList[i++] = &C6510::ILL_1NOP;
00174 instrList[i++] = &C6510::LSREOR_absy;
00175 instrList[i++] = &C6510::ILL_3NOP;
00176 instrList[i++] = &C6510::EOR_absx;
00177 instrList[i++] = &C6510::LSR_absx;
00178 instrList[i++] = &C6510::LSREOR_absx;
00179 instrList[i++] = &C6510::RTS_;
00180 instrList[i++] = &C6510::ADC_indx;
00181 instrList[i++] = &C6510::ILL_TILT;
00182 instrList[i++] = &C6510::RORADC_indx;
00183 instrList[i++] = &C6510::ILL_2NOP;
00184 instrList[i++] = &C6510::ADC_zp;
00185 instrList[i++] = &C6510::ROR_zp;
00186 instrList[i++] = &C6510::RORADC_zp;
00187 instrList[i++] = &C6510::PLA_;
00188 instrList[i++] = &C6510::ADC_imm;
00189 instrList[i++] = &C6510::ROR_AC;
00190 instrList[i++] = &C6510::ILL_6B;
00191 instrList[i++] = &C6510::JMP_vec;
00192 instrList[i++] = &C6510::ADC_abso;
00193 instrList[i++] = &C6510::ROR_abso;
00194 instrList[i++] = &C6510::RORADC_abso;
00195 instrList[i++] = &C6510::BVS_;
00196 instrList[i++] = &C6510::ADC_indy;
00197 instrList[i++] = &C6510::ILL_TILT;
00198 instrList[i++] = &C6510::RORADC_indy;
00199 instrList[i++] = &C6510::ILL_2NOP;
00200 instrList[i++] = &C6510::ADC_zpx;
00201 instrList[i++] = &C6510::ROR_zpx;
00202 instrList[i++] = &C6510::RORADC_zpx;
00203 instrList[i++] = &C6510::SEI_;
00204 instrList[i++] = &C6510::ADC_absy;
00205 instrList[i++] = &C6510::ILL_1NOP;
00206 instrList[i++] = &C6510::RORADC_absy;
00207 instrList[i++] = &C6510::ILL_3NOP;
00208 instrList[i++] = &C6510::ADC_absx;
00209 instrList[i++] = &C6510::ROR_absx;
00210 instrList[i++] = &C6510::RORADC_absx;
00211
00212 instrList[i++] = &C6510::ILL_2NOP;
00213 instrList[i++] = &C6510::STA_indx;
00214 instrList[i++] = &C6510::ILL_2NOP;
00215 instrList[i++] = &C6510::ILL_83;
00216 instrList[i++] = &C6510::STY_zp;
00217 instrList[i++] = &C6510::STA_zp;
00218 instrList[i++] = &C6510::STX_zp;
00219 instrList[i++] = &C6510::ILL_87;
00220 instrList[i++] = &C6510::DEY_;
00221 instrList[i++] = &C6510::ILL_2NOP;
00222 instrList[i++] = &C6510::TXA_;
00223 instrList[i++] = &C6510::ILL_8B;
00224 instrList[i++] = &C6510::STY_abso;
00225 instrList[i++] = &C6510::STA_abso;
00226 instrList[i++] = &C6510::STX_abso;
00227 instrList[i++] = &C6510::ILL_8F;
00228 instrList[i++] = &C6510::BCC_;
00229 instrList[i++] = &C6510::STA_indy;
00230 instrList[i++] = &C6510::ILL_TILT;
00231 instrList[i++] = &C6510::ILL_93;
00232 instrList[i++] = &C6510::STY_zpx;
00233 instrList[i++] = &C6510::STA_zpx;
00234 instrList[i++] = &C6510::STX_zpy;
00235 instrList[i++] = &C6510::ILL_97;
00236 instrList[i++] = &C6510::TYA_;
00237 instrList[i++] = &C6510::STA_absy;
00238 instrList[i++] = &C6510::TXS_;
00239 instrList[i++] = &C6510::ILL_9B;
00240 instrList[i++] = &C6510::ILL_9C;
00241 instrList[i++] = &C6510::STA_absx;
00242 instrList[i++] = &C6510::ILL_9E;
00243 instrList[i++] = &C6510::ILL_9F;
00244 instrList[i++] = &C6510::LDY_imm;
00245 instrList[i++] = &C6510::LDA_indx;
00246 instrList[i++] = &C6510::LDX_imm;
00247 instrList[i++] = &C6510::ILL_A3;
00248 instrList[i++] = &C6510::LDY_zp;
00249 instrList[i++] = &C6510::LDA_zp;
00250 instrList[i++] = &C6510::LDX_zp;
00251 instrList[i++] = &C6510::ILL_A7;
00252 instrList[i++] = &C6510::TAY_;
00253 instrList[i++] = &C6510::LDA_imm;
00254 instrList[i++] = &C6510::TAX_;
00255 instrList[i++] = &C6510::ILL_1NOP;
00256 instrList[i++] = &C6510::LDY_abso;
00257 instrList[i++] = &C6510::LDA_abso;
00258 instrList[i++] = &C6510::LDX_abso;
00259 instrList[i++] = &C6510::ILL_AF;
00260 instrList[i++] = &C6510::BCS_;
00261 instrList[i++] = &C6510::LDA_indy;
00262 instrList[i++] = &C6510::ILL_TILT;
00263 instrList[i++] = &C6510::ILL_B3;
00264 instrList[i++] = &C6510::LDY_zpx;
00265 instrList[i++] = &C6510::LDA_zpx;
00266 instrList[i++] = &C6510::LDX_zpy;
00267 instrList[i++] = &C6510::ILL_B7;
00268 instrList[i++] = &C6510::CLV_;
00269 instrList[i++] = &C6510::LDA_absy;
00270 instrList[i++] = &C6510::TSX_;
00271 instrList[i++] = &C6510::ILL_BB;
00272 instrList[i++] = &C6510::LDY_absx;
00273 instrList[i++] = &C6510::LDA_absx;
00274 instrList[i++] = &C6510::LDX_absy;
00275 instrList[i++] = &C6510::ILL_BF;
00276
00277 instrList[i++] = &C6510::CPY_imm;
00278 instrList[i++] = &C6510::CMP_indx;
00279 instrList[i++] = &C6510::ILL_2NOP;
00280 instrList[i++] = &C6510::DECCMP_indx;
00281 instrList[i++] = &C6510::CPY_zp;
00282 instrList[i++] = &C6510::CMP_zp;
00283 instrList[i++] = &C6510::DEC_zp;
00284 instrList[i++] = &C6510::DECCMP_zp;
00285 instrList[i++] = &C6510::INY_;
00286 instrList[i++] = &C6510::CMP_imm;
00287 instrList[i++] = &C6510::DEX_;
00288 instrList[i++] = &C6510::ILL_CB;
00289 instrList[i++] = &C6510::CPY_abso;
00290 instrList[i++] = &C6510::CMP_abso;
00291 instrList[i++] = &C6510::DEC_abso;
00292 instrList[i++] = &C6510::DECCMP_abso;
00293 instrList[i++] = &C6510::BNE_;
00294 instrList[i++] = &C6510::CMP_indy;
00295 instrList[i++] = &C6510::ILL_TILT;
00296 instrList[i++] = &C6510::DECCMP_indy;
00297 instrList[i++] = &C6510::ILL_2NOP;
00298 instrList[i++] = &C6510::CMP_zpx;
00299 instrList[i++] = &C6510::DEC_zpx;
00300 instrList[i++] = &C6510::DECCMP_zpx;
00301 instrList[i++] = &C6510::CLD_;
00302 instrList[i++] = &C6510::CMP_absy;
00303 instrList[i++] = &C6510::ILL_1NOP;
00304 instrList[i++] = &C6510::DECCMP_absy;
00305 instrList[i++] = &C6510::ILL_3NOP;
00306 instrList[i++] = &C6510::CMP_absx;
00307 instrList[i++] = &C6510::DEC_absx;
00308 instrList[i++] = &C6510::DECCMP_absx;
00309 instrList[i++] = &C6510::CPX_imm;
00310 instrList[i++] = &C6510::SBC_indx;
00311 instrList[i++] = &C6510::ILL_2NOP;
00312 instrList[i++] = &C6510::INCSBC_indx;
00313 instrList[i++] = &C6510::CPX_zp;
00314 instrList[i++] = &C6510::SBC_zp;
00315 instrList[i++] = &C6510::INC_zp;
00316 instrList[i++] = &C6510::INCSBC_zp;
00317 instrList[i++] = &C6510::INX_;
00318 instrList[i++] = &C6510::SBC_imm;
00319 instrList[i++] = &C6510::NOP_;
00320 instrList[i++] = &C6510::ILL_EB;
00321 instrList[i++] = &C6510::CPX_abso;
00322 instrList[i++] = &C6510::SBC_abso;
00323 instrList[i++] = &C6510::INC_abso;
00324 instrList[i++] = &C6510::INCSBC_abso;
00325 instrList[i++] = &C6510::BEQ_;
00326 instrList[i++] = &C6510::SBC_indy;
00327 instrList[i++] = &C6510::ILL_TILT;
00328 instrList[i++] = &C6510::INCSBC_indy;
00329 instrList[i++] = &C6510::ILL_2NOP;
00330 instrList[i++] = &C6510::SBC_zpx;
00331 instrList[i++] = &C6510::INC_zpx;
00332 instrList[i++] = &C6510::INCSBC_zpx;
00333 instrList[i++] = &C6510::SED_;
00334 instrList[i++] = &C6510::SBC_absy;
00335 instrList[i++] = &C6510::ILL_1NOP;
00336 instrList[i++] = &C6510::INCSBC_absy;
00337 instrList[i++] = &C6510::ILL_3NOP;
00338 instrList[i++] = &C6510::SBC_absx;
00339 instrList[i++] = &C6510::INC_absx;
00340 instrList[i++] = &C6510::INCSBC_absx;
00341
00342 if(i!=256)
00343 {
00344
00345 #if defined(__SYMBIAN32__)
00346 User::Leave(-1);
00347 #else
00348 exit(-1);
00349 #endif
00350 }
00351
00352
00353 }
00354
00355
00356 C6510::~C6510()
00360 {
00361 DTOR(C6510);
00362 }
00363
00364
00365
00366
00367 bool C6510::c64memAlloc()
00368 {
00370
00371 c64mem1 = c64ramBuf;
00372 c64mem2 = c64romBuf;
00373 return true;
00374 }
00375
00376
00377 void C6510::initInterpreter(int inMemoryMode)
00378 {
00379 memoryMode = inMemoryMode;
00380 if (memoryMode == MPU_TRANSPARENT_ROM)
00381 {
00382 readData = &C6510::readData_transp;
00383 writeData = &C6510::writeData_bs;
00384 instrList[0x20] = &C6510::JSR_transp;
00385 instrList[0x4C] = &C6510::JMP_transp;
00386 instrList[0x6C] = &C6510::JMP_vec_transp;
00387
00388
00389 c64mem1 = c64ramBuf;
00390 c64mem2 = c64romBuf;
00391 }
00392 else if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00393 {
00394 readData = &C6510::readData_plain;
00395 writeData = &C6510::writeData_plain;
00396 instrList[0x20] = &C6510::JSR_plain;
00397 instrList[0x4C] = &C6510::JMP_plain;
00398 instrList[0x6C] = &C6510::JMP_vec_plain;
00399
00400
00401 c64mem2 = (c64mem1 = c64ramBuf);
00402 }
00403 else
00404 {
00405 readData = &C6510::readData_bs;
00406 writeData = &C6510::writeData_bs;
00407 instrList[0x20] = &C6510::JSR_;
00408 instrList[0x4C] = &C6510::JMP_;
00409 instrList[0x6C] = &C6510::JMP_vec;
00410
00411
00412 c64mem1 = c64ramBuf;
00413 c64mem2 = c64romBuf;
00414 }
00415 bankSelReg = c64ramBuf+1;
00416
00417 pPCbase = c64ramBuf;
00418 pPCend = c64ramBuf+65536;
00419 }
00420
00421
00422 void C6510::c64memReset(int clockSpeed, ubyte randomSeed)
00423 {
00424 iFakeRndSeed = (ubyte)(iFakeRndSeed*13+randomSeed);
00425 fakeReadTimer = iFakeRndSeed;
00426
00427 if ((c64mem1 != 0) && (c64mem2 != 0))
00428 {
00429 c64mem1[0] = 0x2F;
00430
00431 c64mem1[1] = 0x07;
00432 evalBankSelect();
00433
00434
00435 if (clockSpeed == SIDTUNE_CLOCK_NTSC)
00436 {
00437 c64mem1[0x02a6] = 0;
00438 c64mem2[0xdc04] = 0x95;
00439 c64mem2[0xdc05] = 0x42;
00440 }
00441 else
00442 {
00443 c64mem1[0x02a6] = 1;
00444 c64mem2[0xdc04] = 0x25;
00445 c64mem2[0xdc05] = 0x40;
00446 }
00447
00448
00449 c64mem2[0xd019] = 0xff;
00450
00451
00452
00453 c64mem1[0x0314] = 0x31;
00454 c64mem1[0x0315] = 0xea;
00455
00456 c64mem1[0x0316] = 0x66;
00457 c64mem1[0x0317] = 0xfe;
00458
00459 c64mem1[0x0318] = 0x47;
00460 c64mem1[0x0319] = 0xfe;
00461
00462
00463 if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00464 {
00465 c64mem1[0xff48] = 0x6c;
00466 c64mem1[0xff49] = 0x14;
00467 c64mem1[0xff4a] = 0x03;
00468 c64mem1[0xfffa] = 0xf8;
00469 c64mem1[0xfffb] = 0xff;
00470 c64mem1[0xfffe] = 0x48;
00471 c64mem1[0xffff] = 0xff;
00472 }
00473 else
00474 {
00475
00476 c64mem1[0xfffa] = 0x43;
00477 c64mem1[0xfffb] = 0xfe;
00478
00479 c64mem1[0xfffc] = 0xe2;
00480 c64mem1[0xfffd] = 0xfc;
00481
00482 c64mem1[0xfffe] = 0x48;
00483 c64mem1[0xffff] = 0xff;
00484 }
00485
00486
00487 for ( int i = 0; i < 0x1d; i++ )
00488 {
00489 c64mem2[0xd400 +i] = 0;
00490 }
00491
00492 c64mem2[0xd418] = (sidLastValue = 0x0f);
00493 }
00494 }
00495
00496
00497 void C6510::c64memClear()
00498 {
00499
00500 #if defined(__SYMBIAN32__)
00501
00502
00503
00504
00505
00506 Mem::FillZ((TAny*)c64mem1, 0x10000);
00507 if (memoryMode != MPU_PLAYSID_ENVIRONMENT)
00508 {
00509 Mem::FillZ((TAny*)c64mem2, 0x10000);
00510 }
00511 sidLastValue = 0;
00512
00513 if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00514 {
00515 Mem::Fill((TAny*)&c64mem1[0xE000], (0x10000-0xE000), 0x40);
00516 }
00517 else
00518 {
00519
00520 Mem::Fill((TAny*)&c64mem2[0xA000], (0xC000-0xA000), 0x60);
00521
00522
00523 Mem::Fill((TAny*)&c64mem2[0xE000], (0x10000-0xE000), 0x40);
00524
00525 }
00526 #else
00527 for ( udword i = 0; i < 0x10000; i++ )
00528 {
00529 c64mem1[i] = 0;
00530 if (memoryMode != MPU_PLAYSID_ENVIRONMENT)
00531 {
00532 c64mem2[i] = 0;
00533 }
00534 sidLastValue = 0;
00535 }
00536 if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00537 {
00538
00539 for ( udword j = 0xE000; j < 0x10000; j++ )
00540 {
00541 c64mem1[j] = 0x40;
00542 }
00543 }
00544 else
00545 {
00546
00547 for ( udword j1 = 0xA000; j1 < 0xC000; j1++ )
00548 {
00549 c64mem2[j1] = 0x60;
00550 }
00551
00552 for ( udword j2 = 0xE000; j2 < 0x10000; j2++ )
00553 {
00554 c64mem2[j2] = 0x40;
00555 }
00556 }
00557 #endif
00558 }
00559
00560
00561 bool C6510::interpreter(uword p, ubyte ramrom, ubyte a, ubyte x, ubyte y)
00562 {
00563 if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00564 {
00565 AC = a;
00566 XR = 0;
00567 YR = 0;
00568 }
00569 else
00570 {
00571 *bankSelReg = ramrom;
00572 evalBankSelect();
00573 AC = a;
00574 XR = x;
00575 YR = y;
00576 }
00577
00578
00579 pPC = pPCbase+p;
00580
00581 resetSP();
00582 clearSR();
00583 sidKeysOff[4] = (sidKeysOff[4+7] = (sidKeysOff[4+14] = false));
00584 sidKeysOn[4] = (sidKeysOn[4+7] = (sidKeysOn[4+14] = false));
00585
00586 do
00587 {
00588
00589
00590
00591
00592
00593 const ubyte instr = *(pPC++);
00594 (this->*instrList[instr])();
00595 }
00596 while (stackIsOkay&&(pPC<pPCend));
00597
00598 return true;
00599 }
00600
00601
00602
00603
00604 ubyte C6510::c64memRamRom( uword address )
00605 {
00606 if (memoryMode == MPU_PLAYSID_ENVIRONMENT)
00607 {
00608 return 4;
00609 }
00610 else
00611 {
00612 if ( address < 0xa000 )
00613 {
00614 return 7;
00615 }
00616 else if ( address < 0xd000 )
00617 {
00618 return 6;
00619 }
00620 else if ( address >= 0xe000 )
00621 {
00622 return 5;
00623 }
00624 else
00625 {
00626 return 4;
00627 }
00628 }
00629 }