00001
00002
00003
00004
00005 #ifndef __6510_H
00006 #define __6510_H
00007
00008
00009 #include "mytypes.h"
00010 #include "myendian.h"
00011 #include "epocglue.h"
00012
00013
00014
00015
00016
00017
00018
00019
00020 struct statusRegister
00021 {
00022 unsigned Carry : 1;
00023 unsigned Zero : 1;
00024 unsigned Interrupt : 1;
00025 unsigned Decimal : 1;
00026 unsigned Break : 1;
00027 unsigned NotUsed : 1;
00028 unsigned oVerflow : 1;
00029 unsigned Negative : 1;
00030 };
00031
00032
00033
00034
00035
00036 #define CF SR.Carry
00037 #define ZF SR.Zero
00038 #define IF SR.Interrupt
00039 #define DF SR.Decimal
00040 #define BF SR.Break
00041 #define NU SR.NotUsed
00042 #define VF SR.oVerflow
00043 #define NF SR.Negative
00044
00045
00050 #if defined (__SYMBIAN32__)
00051 class C6510 : public CBase
00052 #else
00053 class C6510
00054 #endif
00055 {
00056 public:
00057 C6510();
00058 ~C6510();
00059
00060 bool c64memAlloc();
00061
00062
00063
00064 void initInterpreter(int inMemoryMode);
00065 void c64memReset(int clockSpeed, ubyte randomSeed);
00066 void c64memClear();
00067
00068
00069
00070 bool interpreter(uword p, ubyte ramrom, ubyte a, ubyte x, ubyte y);
00071 ubyte c64memRamRom( uword address );
00072
00073
00074 private:
00075
00076 inline void affectNZ(ubyte reg)
00077 {
00078 ZF = (reg == 0);
00079 NF = ((reg & 0x80) != 0);
00080 }
00081
00082 inline void clearSR()
00083 {
00084
00085 CF = (ZF = (IF = (DF = (BF = (NU = (VF = (NF = 0)))))));
00086 }
00087
00088 inline ubyte codeSR()
00089 {
00090 register ubyte tempSR = CF;
00091 tempSR |= (ZF<<1);
00092 tempSR |= (IF<<2);
00093 tempSR |= (DF<<3);
00094 tempSR |= (BF<<4);
00095 tempSR |= (NU<<5);
00096 tempSR |= (VF<<6);
00097 tempSR |= (NF<<7);
00098 return tempSR;
00099 }
00100
00101 inline void decodeSR(ubyte stackByte)
00102 {
00103 CF = (stackByte & 1);
00104 ZF = ((stackByte & 2) !=0 );
00105 IF = ((stackByte & 4) !=0 );
00106 DF = ((stackByte & 8) !=0 );
00107 BF = ((stackByte & 16) !=0 );
00108 NU = ((stackByte & 32) !=0 );
00109 VF = ((stackByte & 64) !=0 );
00110 NF = ((stackByte & 128) !=0 );
00111 }
00112
00113
00114
00115
00116 inline void branchIfClear(ubyte flag)
00117 {
00118 if (flag == 0)
00119 {
00120 PC = (uword)(pPC-pPCbase);
00121 PC += (sbyte)(*pPC);
00122 pPC = pPCbase+PC;
00123 }
00124 pPC++;
00125 }
00126
00127 inline void branchIfSet(ubyte flag)
00128 {
00129 if (flag != 0)
00130 {
00131 PC = (uword)(pPC-pPCbase);
00132 PC += (sbyte)(*pPC);
00133 pPC = pPCbase+PC;
00134 }
00135 pPC++;
00136 }
00137
00138
00139
00140
00141
00142 public:
00143 inline uword abso()
00144 {
00145 return readLEword(pPC);
00146 }
00147 private:
00148
00149 inline uword absx()
00150 {
00151 return (uword)(readLEword(pPC)+XR);
00152 }
00153
00154 inline uword absy()
00155 {
00156 return (uword)(readLEword(pPC)+YR);
00157 }
00158
00159 inline ubyte imm()
00160 {
00161 return *pPC;
00162 }
00163
00164 inline uword indx()
00165 {
00166 return readEndian(c64mem1[(*pPC+1+XR)&0xFF],c64mem1[(*pPC+XR)&0xFF]);
00167 }
00168
00169 inline uword indy()
00170 {
00171 return (uword)(YR+readEndian(c64mem1[(*pPC+1)&0xFF],c64mem1[*pPC]));
00172 }
00173
00174 inline ubyte zp()
00175 {
00176 return *pPC;
00177 }
00178
00179 inline ubyte zpx()
00180 {
00181 return (ubyte)(*pPC+XR);
00182 }
00183
00184 inline ubyte zpy()
00185 {
00186 return (ubyte)(*pPC+YR);
00187 }
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 inline void evalBankSelect()
00222 {
00223
00224 isBasic = ((*bankSelReg & 3) == 3);
00225 isIO = ((*bankSelReg & 7) > 4);
00226 isKernal = ((*bankSelReg & 2) != 0);
00227 }
00228
00229
00230
00231 inline void evalBankJump()
00232 {
00233 if (PC < 0xA000)
00234 {
00235 ;
00236 }
00237 else
00238 {
00239
00240 switch (PC >> 12)
00241 {
00242 case 0xa:
00243 case 0xb:
00244 {
00245 if (isBasic)
00246 {
00247 RTS_();
00248 }
00249 break;
00250 }
00251 case 0xc:
00252 {
00253 break;
00254 }
00255 case 0xd:
00256 {
00257 if (isIO)
00258 {
00259 RTS_();
00260 }
00261 break;
00262 }
00263 case 0xe:
00264 case 0xf:
00265 default:
00266 {
00267 if (isKernal)
00268 {
00269 RTS_();
00270 }
00271 break;
00272 }
00273 }
00274 }
00275 }
00276
00277
00278 private:
00279
00280
00281 ubyte readData_bs(uword addr)
00282 {
00283 if (addr < 0xA000)
00284 {
00285 return c64mem1[addr];
00286 }
00287 else
00288 {
00289
00290 switch (addr >> 12)
00291 {
00292 case 0xa:
00293 case 0xb:
00294 {
00295 if (isBasic)
00296 return c64mem2[addr];
00297 else
00298 return c64mem1[addr];
00299 }
00300 case 0xc:
00301 {
00302 return c64mem1[addr];
00303 }
00304 case 0xd:
00305 {
00306 if (isIO)
00307 {
00308 uword tempAddr = (uword)(addr & 0xfc1f);
00309
00310 if (( tempAddr & 0xff00 ) != 0xd400 )
00311 {
00312 switch (addr)
00313 {
00314 case 0xd011:
00315 case 0xd012:
00316 case 0xdc04:
00317 case 0xdc05:
00318 {
00319 return (ubyte)(fakeReadTimer = (ubyte)(c64mem2[addr]+fakeReadTimer*13+1));
00320 }
00321 default:
00322 {
00323 return c64mem2[addr];
00324 }
00325 }
00326 }
00327 else
00328 {
00329
00330 if (( tempAddr & 0x00ff ) >= 0x001d )
00331 return(c64mem2[addr]);
00332
00333 else
00334 {
00335 switch (tempAddr)
00336 {
00337 case 0xd41b:
00338 {
00339 return optr3readWave;
00340 }
00341 case 0xd41c:
00342 {
00343 return optr3readEnve;
00344 }
00345 default:
00346 {
00347 return sidLastValue;
00348 }
00349 }
00350 }
00351 }
00352 }
00353 else
00354 return c64mem1[addr];
00355 }
00356 case 0xe:
00357 case 0xf:
00358 default:
00359 {
00360 if (isKernal)
00361 return c64mem2[addr];
00362 else
00363 return c64mem1[addr];
00364 }
00365 }
00366 }
00367 }
00368
00369 ubyte readData_transp(uword addr)
00370 {
00371 if (addr < 0xD000)
00372 {
00373 return c64mem1[addr];
00374 }
00375 else
00376 {
00377
00378 switch (addr >> 12)
00379 {
00380 case 0xd:
00381 {
00382 if (isIO)
00383 {
00384 uword tempAddr = (uword)(addr & 0xfc1f);
00385
00386 if (( tempAddr & 0xff00 ) != 0xd400 )
00387 {
00388 switch (addr)
00389 {
00390 case 0xd011:
00391 case 0xd012:
00392 case 0xdc04:
00393 case 0xdc05:
00394 {
00395 return (ubyte)(fakeReadTimer = (ubyte)(c64mem2[addr]+fakeReadTimer*13+1));
00396 }
00397 default:
00398 {
00399 return c64mem2[addr];
00400 }
00401 }
00402 }
00403 else
00404 {
00405
00406 if (( tempAddr & 0x00ff ) >= 0x001d )
00407 return(c64mem2[addr]);
00408
00409 else
00410 {
00411 switch (tempAddr)
00412 {
00413 case 0xd41b:
00414 {
00415 return optr3readWave;
00416 }
00417 case 0xd41c:
00418 {
00419 return optr3readEnve;
00420 }
00421 default:
00422 {
00423 return sidLastValue;
00424 }
00425 }
00426 }
00427 }
00428 }
00429 else
00430 return c64mem1[addr];
00431 }
00432 case 0xe:
00433 case 0xf:
00434 default:
00435 {
00436 return c64mem1[addr];
00437 }
00438 }
00439 }
00440 }
00441
00442 ubyte readData_plain(uword addr)
00443 {
00444 return c64mem1[addr];
00445 }
00446
00447 inline ubyte readData_zp(uword addr)
00448 {
00449 return c64mem1[addr];
00450 }
00451
00452
00453
00454
00455 void writeData_bs(uword addr, ubyte data)
00456 {
00457 if ((addr < 0xd000) || (addr >= 0xe000))
00458 {
00459 c64mem1[addr] = data;
00460 if (addr == 0x01)
00461 {
00462 evalBankSelect();
00463 }
00464 }
00465 else
00466 {
00467 if (isIO)
00468 {
00469
00470 uword tempAddr = (uword)(addr & 0xfc1f);
00471
00472 if (( tempAddr & 0xff00 ) != 0xd400 )
00473 {
00474 c64mem2[addr] = data;
00475 }
00476
00477
00478
00479 else if (( tempAddr & 0x00ff ) >= 0x001d )
00480 {
00481
00482 c64mem2[addr] = (sidLastValue = data);
00483 }
00484 else
00485 {
00486
00487 c64mem2[tempAddr] = (sidLastValue = data);
00488
00489 sidKeysOn[tempAddr&0x001f] = sidKeysOn[tempAddr&0x001f] || ((data&1)!=0);
00490
00491 sidKeysOff[tempAddr&0x001f] = sidKeysOff[tempAddr&0x001f] || ((data&1)==0);
00492 }
00493 }
00494 else
00495 {
00496 c64mem1[addr] = data;
00497 }
00498 }
00499 }
00500
00501 void writeData_plain(uword addr, ubyte data)
00502 {
00503
00504 uword tempAddr = (uword)(addr & 0xfc1f);
00505
00506 if (( tempAddr & 0xff00 ) != 0xd400 )
00507 {
00508 c64mem1[addr] = data;
00509 }
00510
00511
00512
00513 else if (( tempAddr & 0x00ff ) >= 0x001d )
00514 {
00515
00516 c64mem1[addr] = (sidLastValue = data);
00517 }
00518 else
00519 {
00520
00521 c64mem2[tempAddr] = (sidLastValue = data);
00522
00523 sidKeysOn[tempAddr&0x001f] = sidKeysOn[tempAddr&0x001f] || ((data&1)!=0);
00524
00525 sidKeysOff[tempAddr&0x001f] = sidKeysOff[tempAddr&0x001f] || ((data&1)==0);
00526 }
00527 }
00528
00529 inline void writeData_zp(uword addr, ubyte data)
00530 {
00531 c64mem1[addr] = data;
00532 if (addr == 0x01)
00533 {
00534 evalBankSelect();
00535 }
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552 inline void resetSP()
00553 {
00554 SP = 0x1ff;
00555 stackIsOkay = true;
00556 }
00557
00558 inline void checkSP()
00559 {
00560 stackIsOkay = ((SP>0xff)&&(SP<=0x1ff));
00561 }
00562
00563
00564
00565 inline void ADC_m(ubyte x)
00566 {
00567 if ( DF == 1 )
00568 {
00569 uword AC2 = (uword)(AC +x +CF);
00570 ZF = ( AC2 == 0 );
00571 if ((( AC & 15 ) + ( x & 15 ) + CF ) > 9 )
00572 {
00573 AC2 += 6;
00574 }
00575 VF = ((( AC ^ x ^ AC2 ) & 0x80 ) != 0 ) ^ CF;
00576 NF = (( AC2 & 128 ) != 0 );
00577 if ( AC2 > 0x99 )
00578 {
00579 AC2 += 96;
00580 }
00581 CF = ( AC2 > 0x99 );
00582 AC = (ubyte)( AC2 & 255 );
00583 }
00584 else
00585 {
00586 uword AC2 = (uword)(AC +x +CF);
00587 CF = ( AC2 > 255 );
00588 VF = ((( AC ^ x ^ AC2 ) & 0x80 ) != 0 ) ^ CF;
00589 affectNZ( AC = (ubyte)( AC2 & 255 ));
00590 }
00591 }
00592 void ADC_imm() { ADC_m(imm()); pPC++; }
00593 void ADC_abso() { ADC_m( (this->*readData)(abso()) ); pPC += 2; }
00594 void ADC_absx() { ADC_m( (this->*readData)(absx()) ); pPC += 2; }
00595 void ADC_absy() { ADC_m( (this->*readData)(absy()) ); pPC += 2; }
00596 void ADC_indx() { ADC_m( (this->*readData)(indx()) ); pPC++; }
00597 void ADC_indy() { ADC_m( (this->*readData)(indy()) ); pPC++; }
00598 void ADC_zp() { ADC_m( readData_zp(zp()) ); pPC++; }
00599 void ADC_zpx() { ADC_m( readData_zp(zpx()) ); pPC++; }
00600
00601
00602 inline void AND_m(ubyte x)
00603 {
00604 affectNZ( AC &= x );
00605 }
00606 void AND_imm() { AND_m(imm()); pPC++; }
00607 void AND_abso() { AND_m( (this->*readData)(abso()) ); pPC += 2; }
00608 void AND_absx() { AND_m( (this->*readData)(absx()) ); pPC += 2; }
00609 void AND_absy() { AND_m( (this->*readData)(absy()) ); pPC += 2; }
00610 void AND_indx() { AND_m( (this->*readData)(indx()) ); pPC++; }
00611 void AND_indy() { AND_m( (this->*readData)(indy()) ); pPC++; }
00612 void AND_zp() { AND_m( readData_zp(zp()) ); pPC++; }
00613 void AND_zpx() { AND_m( readData_zp(zpx()) ); pPC++; }
00614
00615
00616 inline ubyte ASL_m(ubyte x)
00617 {
00618 CF = (( x & 128 ) != 0 );
00619 affectNZ( x <<= 1);
00620 return x;
00621 }
00622 void ASL_AC()
00623 {
00624 AC = ASL_m(AC);
00625 }
00626 void ASL_abso()
00627 {
00628 uword tempAddr = abso();
00629 pPC += 2;
00630 (this->*writeData)( tempAddr, ASL_m( (this->*readData)(tempAddr)) );
00631 }
00632 void ASL_absx()
00633 {
00634 uword tempAddr = absx();
00635 pPC += 2;
00636 (this->*writeData)( tempAddr, ASL_m( (this->*readData)(tempAddr)) );
00637 }
00638 void ASL_zp()
00639 {
00640 uword tempAddr = zp();
00641 pPC++;
00642 writeData_zp( tempAddr, ASL_m( readData_zp(tempAddr)) );
00643 }
00644 void ASL_zpx()
00645 {
00646 uword tempAddr = zpx();
00647 pPC++;
00648 writeData_zp( tempAddr, ASL_m( readData_zp(tempAddr)) );
00649 }
00650
00651
00652 void BCC_() { branchIfClear(CF); }
00653
00654 void BCS_() { branchIfSet(CF); }
00655
00656 void BEQ_() { branchIfSet(ZF); }
00657
00658
00659 inline void BIT_m(ubyte x)
00660 {
00661 ZF = (( AC & x ) == 0 );
00662 VF = (( x & 64 ) != 0 );
00663 NF = (( x & 128 ) != 0 );
00664 }
00665 void BIT_abso() { BIT_m( (this->*readData)(abso()) ); pPC += 2; }
00666 void BIT_zp() { BIT_m( readData_zp(zp()) ); pPC++; }
00667
00668
00669 void BMI_() { branchIfSet(NF); }
00670
00671 void BNE_() { branchIfClear(ZF); }
00672
00673 void BPL_() { branchIfClear(NF); }
00674
00675
00676 void BRK_()
00677 {
00678 BF = (IF = 1);
00679 #if !defined(NO_RTS_UPON_BRK)
00680 RTS_();
00681 #endif
00682 }
00683
00684
00685 void BVC_() { branchIfClear(VF); }
00686
00687 void BVS_() { branchIfSet(VF); }
00688
00689
00690 void CLC_() { CF = 0; }
00691
00692 void CLD_() { DF = 0; }
00693
00694 void CLI_() { IF = 0; }
00695
00696 void CLV_() { VF = 0; }
00697
00698
00699 inline void CMP_m(ubyte x)
00700 {
00701 ZF = ( AC == x );
00702 CF = ( AC >= x );
00703 NF = ( (sbyte)( AC - x ) < 0 );
00704 }
00705 void CMP_abso() { CMP_m( (this->*readData)(abso()) ); pPC += 2; }
00706 void CMP_absx() { CMP_m( (this->*readData)(absx()) ); pPC += 2; }
00707 void CMP_absy() { CMP_m( (this->*readData)(absy()) ); pPC += 2; }
00708 void CMP_imm() { CMP_m(imm()); pPC++; }
00709 void CMP_indx() { CMP_m( (this->*readData)(indx()) ); pPC++; }
00710 void CMP_indy() { CMP_m( (this->*readData)(indy()) ); pPC++; }
00711 void CMP_zp() { CMP_m( readData_zp(zp()) ); pPC++; }
00712 void CMP_zpx() { CMP_m( readData_zp(zpx()) ); pPC++; }
00713
00714
00715 inline void CPX_m(ubyte x)
00716 {
00717 ZF = ( XR == x );
00718 CF = ( XR >= x );
00719 NF = ( (sbyte)( XR - x ) < 0 );
00720 }
00721 void CPX_abso() { CPX_m( (this->*readData)(abso()) ); pPC += 2; }
00722 void CPX_imm() { CPX_m(imm()); pPC++; }
00723 void CPX_zp() { CPX_m( readData_zp(zp()) ); pPC++; }
00724
00725
00726 inline void CPY_m(ubyte x)
00727 {
00728 ZF = ( YR == x );
00729 CF = ( YR >= x );
00730 NF = ( (sbyte)( YR - x ) < 0 );
00731 }
00732 void CPY_abso() { CPY_m( (this->*readData)(abso()) ); pPC += 2; }
00733 void CPY_imm() { CPY_m(imm()); pPC++; }
00734 void CPY_zp() { CPY_m( readData_zp(zp()) ); pPC++; }
00735
00736
00737 inline void DEC_m(uword addr)
00738 {
00739 ubyte x = (this->*readData)(addr);
00740 affectNZ(--x);
00741 (this->*writeData)(addr, x);
00742 }
00743 inline void DEC_m_zp(uword addr)
00744 {
00745 ubyte x = readData_zp(addr);
00746 affectNZ(--x);
00747 writeData_zp(addr, x);
00748 }
00749 void DEC_abso() { DEC_m( abso() ); pPC += 2; }
00750 void DEC_absx() { DEC_m( absx() ); pPC += 2; }
00751 void DEC_zp() { DEC_m_zp( zp() ); pPC++; }
00752 void DEC_zpx() { DEC_m_zp( zpx() ); pPC++; }
00753
00754
00755 void DEX_() { affectNZ(--XR); }
00756
00757 void DEY_() { affectNZ(--YR); }
00758
00759
00760 inline void EOR_m(ubyte x)
00761 {
00762 AC ^= x;
00763 affectNZ(AC);
00764 }
00765 void EOR_abso() { EOR_m( (this->*readData)(abso()) ); pPC += 2; }
00766 void EOR_absx() { EOR_m( (this->*readData)(absx()) ); pPC += 2; }
00767 void EOR_absy() { EOR_m( (this->*readData)(absy()) ); pPC += 2; }
00768 void EOR_imm() { EOR_m(imm()); pPC++; }
00769 void EOR_indx() { EOR_m( (this->*readData)(indx()) ); pPC++; }
00770 void EOR_indy() { EOR_m( (this->*readData)(indy()) ); pPC++; }
00771 void EOR_zp() { EOR_m( readData_zp(zp()) ); pPC++; }
00772 void EOR_zpx() { EOR_m( readData_zp(zpx()) ); pPC++; }
00773
00774
00775 inline void INC_m(uword addr)
00776 {
00777 ubyte x = (this->*readData)(addr);
00778 affectNZ(++x);
00779 (this->*writeData)(addr, x);
00780 }
00781 inline void INC_m_zp(uword addr)
00782 {
00783 ubyte x = readData_zp(addr);
00784 affectNZ(++x);
00785 writeData_zp(addr, x);
00786 }
00787 void INC_abso() { INC_m( abso() ); pPC += 2; }
00788 void INC_absx() { INC_m( absx() ); pPC += 2; }
00789 void INC_zp() { INC_m_zp( zp() ); pPC++; }
00790 void INC_zpx() { INC_m_zp( zpx() ); pPC++; }
00791
00792
00793 void INX_() { affectNZ(++XR); }
00794
00795 void INY_() { affectNZ(++YR); }
00796
00797
00798
00799 void JMP_()
00800 {
00801 PC = abso();
00802 pPC = pPCbase+PC;
00803 evalBankJump();
00804 }
00805
00806 void JMP_transp()
00807 {
00808 PC = abso();
00809 if ( (PC>=0xd000) && isKernal )
00810 {
00811 RTS_();
00812 }
00813 else
00814 {
00815 pPC = pPCbase+PC;
00816 }
00817 }
00818
00819 void JMP_plain()
00820 {
00821 PC = abso();
00822 pPC = pPCbase+PC;
00823 }
00824
00825
00826 void JMP_vec()
00827 {
00828 uword tempAddrLo = abso();
00829 uword tempAddrHi = (uword)((tempAddrLo&0xFF00) | ((tempAddrLo+1)&0x00FF));
00830 PC = readEndian((this->*readData)(tempAddrHi),(this->*readData)(tempAddrLo));
00831 pPC = pPCbase+PC;
00832 evalBankJump();
00833 }
00834
00835 void JMP_vec_transp()
00836 {
00837 uword tempAddrLo = abso();
00838 uword tempAddrHi = (uword)((tempAddrLo&0xFF00) | ((tempAddrLo+1)&0x00FF));
00839 PC = readEndian((this->*readData)(tempAddrHi),(this->*readData)(tempAddrLo));
00840 if ( (PC>=0xd000) && isKernal )
00841 {
00842 RTS_();
00843 }
00844 else
00845 {
00846 pPC = pPCbase+PC;
00847 }
00848 }
00849
00850 void JMP_vec_plain()
00851 {
00852 uword tempAddrLo = abso();
00853 uword tempAddrHi = (uword)((tempAddrLo&0xFF00) | ((tempAddrLo+1)&0x00FF));
00854 PC = readEndian((this->*readData)(tempAddrHi),(this->*readData)(tempAddrLo));
00855 pPC = pPCbase+PC;
00856 }
00857
00858
00859 inline void JSR_main()
00860 {
00861 uword tempPC = abso();
00862 pPC += 2;
00863 PC = (uword)(pPC-pPCbase);
00864 PC--;
00865 SP--;
00866 writeLEword(c64mem1+SP,PC);
00867 SP--;
00868 checkSP();
00869 PC = tempPC;
00870 }
00871
00872 void JSR_()
00873 {
00874 JSR_main();
00875 pPC = pPCbase+PC;
00876 evalBankJump();
00877 }
00878
00879 void JSR_transp()
00880 {
00881 JSR_main();
00882 if ( (PC>=0xd000) && isKernal )
00883 {
00884 RTS_();
00885 }
00886 else
00887 {
00888 pPC = pPCbase+PC;
00889 }
00890 }
00891
00892 void JSR_plain()
00893 {
00894 JSR_main();
00895 pPC = pPCbase+PC;
00896 }
00897
00898
00899 void LDA_abso() { affectNZ( AC = (this->*readData)(abso()) ); pPC += 2; }
00900 void LDA_absx() { affectNZ( AC = (this->*readData)( absx() )); pPC += 2; }
00901 void LDA_absy() { affectNZ( AC = (this->*readData)( absy() ) ); pPC += 2; }
00902 void LDA_imm() { affectNZ( AC = imm() ); pPC++; }
00903 void LDA_indx() { affectNZ( AC = (this->*readData)( indx() ) ); pPC++; }
00904 void LDA_indy() { affectNZ( AC = (this->*readData)( indy() ) ); pPC++; }
00905 void LDA_zp() { affectNZ( AC = readData_zp( zp() ) ); pPC++; }
00906 void LDA_zpx() { affectNZ( AC = readData_zp( zpx() ) ); pPC++; }
00907
00908
00909 void LDX_abso() { affectNZ(XR=(this->*readData)(abso())); pPC += 2; }
00910 void LDX_absy() { affectNZ(XR=(this->*readData)(absy())); pPC += 2; }
00911 void LDX_imm() { affectNZ(XR=imm()); pPC++; }
00912 void LDX_zp() { affectNZ(XR=readData_zp(zp())); pPC++; }
00913 void LDX_zpy() { affectNZ(XR=readData_zp(zpy())); pPC++; }
00914
00915
00916 void LDY_abso() { affectNZ(YR=(this->*readData)(abso())); pPC += 2; }
00917 void LDY_absx() { affectNZ(YR=(this->*readData)(absx())); pPC += 2; }
00918 void LDY_imm() { affectNZ(YR=imm()); pPC++; }
00919 void LDY_zp() { affectNZ(YR=readData_zp(zp())); pPC++; }
00920 void LDY_zpx() { affectNZ(YR=readData_zp(zpx())); pPC++; }
00921
00922
00923 inline ubyte LSR_m(ubyte x)
00924 {
00925 CF = x & 1;
00926 x >>= 1;
00927 NF = 0;
00928 ZF = (x == 0);
00929 return x;
00930 }
00931 void LSR_AC()
00932 {
00933 AC = LSR_m(AC);
00934 }
00935 void LSR_abso()
00936 {
00937 uword tempAddr = abso();
00938 pPC += 2;
00939 (this->*writeData)( tempAddr, (LSR_m( (this->*readData)(tempAddr))) );
00940 }
00941 void LSR_absx()
00942 {
00943 uword tempAddr = absx();
00944 pPC += 2;
00945 (this->*writeData)( tempAddr, (LSR_m( (this->*readData)(tempAddr))) );
00946 }
00947 void LSR_zp()
00948 {
00949 uword tempAddr = zp();
00950 pPC++;
00951 writeData_zp( tempAddr, (LSR_m( readData_zp(tempAddr))) );
00952 }
00953 void LSR_zpx()
00954 {
00955 uword tempAddr = zpx();
00956 pPC++;
00957 writeData_zp( tempAddr, (LSR_m( readData_zp(tempAddr))) );
00958 }
00959
00960
00961 inline void ORA_m(ubyte x)
00962 {
00963 affectNZ( AC |= x );
00964 }
00965 void ORA_abso() { ORA_m( (this->*readData)(abso()) ); pPC += 2; }
00966 void ORA_absx() { ORA_m( (this->*readData)(absx()) ); pPC += 2; }
00967 void ORA_absy() { ORA_m( (this->*readData)(absy()) ); pPC += 2; }
00968 void ORA_imm() { ORA_m(imm()); pPC++; }
00969 void ORA_indx() { ORA_m( (this->*readData)(indx()) ); pPC++; }
00970 void ORA_indy() { ORA_m( (this->*readData)(indy()) ); pPC++; }
00971 void ORA_zp() { ORA_m( readData_zp(zp()) ); pPC++; }
00972 void ORA_zpx() { ORA_m( readData_zp(zpx()) ); pPC++; }
00973
00974
00975 void NOP_() { }
00976
00977 void PHA_() { c64mem1[SP--] = AC; }
00978
00979
00980 void PHP_()
00981 {
00982 c64mem1[SP--] = codeSR();
00983 }
00984
00985
00986 void PLA_()
00987 {
00988 affectNZ(AC=c64mem1[++SP]);
00989 }
00990
00991
00992 void PLP_()
00993 {
00994 decodeSR(c64mem1[++SP]);
00995 }
00996
00997 inline ubyte ROL_m(ubyte x)
00998 {
00999 ubyte y = (ubyte)(( x << 1 ) + CF);
01000 CF = (( x & 0x80 ) != 0 );
01001 affectNZ(y);
01002 return y;
01003 }
01004 void ROL_AC() { AC=ROL_m(AC); }
01005 void ROL_abso()
01006 {
01007 uword tempAddr = abso();
01008 pPC += 2;
01009 (this->*writeData)( tempAddr, ROL_m( (this->*readData)(tempAddr)) );
01010 }
01011 void ROL_absx()
01012 {
01013 uword tempAddr = absx();
01014 pPC += 2;
01015 (this->*writeData)( tempAddr, ROL_m( (this->*readData)(tempAddr)) );
01016 }
01017 void ROL_zp()
01018 {
01019 uword tempAddr = zp();
01020 pPC++;
01021 writeData_zp( tempAddr, ROL_m( readData_zp(tempAddr)) );
01022 }
01023 void ROL_zpx()
01024 {
01025 uword tempAddr = zpx();
01026 pPC++;
01027 writeData_zp( tempAddr, ROL_m( readData_zp(tempAddr)) );
01028 }
01029
01030 inline ubyte ROR_m(ubyte x)
01031 {
01032 ubyte y = (ubyte)(( x >> 1 ) | ( CF << 7 ));
01033 CF = ( x & 1 );
01034 affectNZ(y);
01035 return y;
01036 }
01037 void ROR_AC()
01038 {
01039 AC = ROR_m(AC);
01040 }
01041 void ROR_abso()
01042 {
01043 uword tempAddr = abso();
01044 pPC += 2;
01045 (this->*writeData)( tempAddr, ROR_m( (this->*readData)(tempAddr)) );
01046 }
01047 void ROR_absx()
01048 {
01049 uword tempAddr = absx();
01050 pPC += 2;
01051 (this->*writeData)( tempAddr, ROR_m( (this->*readData)(tempAddr)) );
01052 }
01053 void ROR_zp()
01054 {
01055 uword tempAddr = zp();
01056 pPC++;
01057 writeData_zp( tempAddr, ROR_m( readData_zp(tempAddr)) );
01058 }
01059 void ROR_zpx()
01060 {
01061 uword tempAddr = zpx();
01062 pPC++;
01063 writeData_zp( tempAddr, ROR_m( readData_zp(tempAddr)) );
01064 }
01065
01066
01067 void RTI_()
01068 {
01069
01070 SP++;
01071 PC = (uword)(readEndian( c64mem1[SP +1], c64mem1[SP] ) +1);
01072 pPC = pPCbase+PC;
01073 SP++;
01074 checkSP();
01075 }
01076
01077
01078 inline void RTS_()
01079 {
01080 SP++;
01081 PC = (uword)(readEndian( c64mem1[SP +1], c64mem1[SP] ) +1);
01082 pPC = pPCbase+PC;
01083 SP++;
01084 checkSP();
01085 }
01086
01087
01088 inline void SBC_m(ubyte s)
01089 {
01090 s = (ubyte)((~s) & 255);
01091 if ( DF == 1 )
01092 {
01093 uword AC2 = (uword)(AC +s +CF);
01094 ZF = ( AC2 == 0 );
01095 if ((( AC & 15 ) + ( s & 15 ) + CF ) > 9 )
01096 {
01097 AC2 += 6;
01098 }
01099 VF = ((( AC ^ s ^ AC2 ) & 0x80 ) != 0 ) ^ CF;
01100 NF = (( AC2 & 128 ) != 0 );
01101 if ( AC2 > 0x99 )
01102 {
01103 AC2 += 96;
01104 }
01105 CF = ( AC2 > 0x99 );
01106 AC = (ubyte)( AC2 & 255 );
01107 }
01108 else
01109 {
01110 uword AC2 = (uword)(AC + s + CF);
01111 CF = ( AC2 > 255 );
01112 VF = ((( AC ^ s ^ AC2 ) & 0x80 ) != 0 ) ^ CF;
01113 affectNZ( AC = (ubyte)( AC2 & 255 ));
01114 }
01115 }
01116 void SBC_abso() { SBC_m( (this->*readData)(abso()) ); pPC += 2; }
01117 void SBC_absx() { SBC_m( (this->*readData)(absx()) ); pPC += 2; }
01118 void SBC_absy() { SBC_m( (this->*readData)(absy()) ); pPC += 2; }
01119 void SBC_imm() { SBC_m(imm()); pPC++; }
01120 void SBC_indx() { SBC_m( (this->*readData)( indx()) ); pPC++; }
01121 void SBC_indy() { SBC_m( (this->*readData)(indy()) ); pPC++; }
01122 void SBC_zp() { SBC_m( readData_zp(zp()) ); pPC++; }
01123 void SBC_zpx() { SBC_m( readData_zp(zpx()) ); pPC++; }
01124
01125
01126 void SEC_() { CF=1; }
01127
01128 void SED_() { DF=1; }
01129
01130 void SEI_() { IF=1; }
01131
01132
01133 void STA_abso() { (this->*writeData)( abso(), AC ); pPC += 2; }
01134 void STA_absx() { (this->*writeData)( absx(), AC ); pPC += 2; }
01135 void STA_absy() { (this->*writeData)( absy(), AC ); pPC += 2; }
01136 void STA_indx() { (this->*writeData)( indx(), AC ); pPC++; }
01137 void STA_indy() { (this->*writeData)( indy(), AC ); pPC++; }
01138 void STA_zp() { writeData_zp( zp(), AC ); pPC++; }
01139 void STA_zpx() { writeData_zp( zpx(), AC ); pPC++; }
01140
01141
01142 void STX_abso() { (this->*writeData)( abso(), XR ); pPC += 2; }
01143 void STX_zp() { writeData_zp( zp(), XR ); pPC++; }
01144 void STX_zpy() { writeData_zp( zpy(), XR ); pPC++; }
01145
01146
01147 void STY_abso() { (this->*writeData)( abso(), YR ); pPC += 2; }
01148 void STY_zp() { writeData_zp( zp(), YR ); pPC++; }
01149 void STY_zpx() { writeData_zp( zpx(), YR ); pPC++; }
01150
01151
01152 void TAX_() { affectNZ(XR=AC); }
01153
01154 void TAY_() { affectNZ(YR=AC); }
01155
01156
01157 void TSX_()
01158 {
01159 XR = (ubyte)(SP & 255);
01160 affectNZ(XR);
01161 }
01162
01163 void TXA_() { affectNZ(AC=XR); }
01164
01165 void TXS_() { SP = XR | 0x100; checkSP(); }
01166
01167 void TYA_() { affectNZ(AC=YR); }
01168
01169
01170
01171
01172
01173 void ILL_TILT() { }
01174
01175 void ILL_1NOP() { }
01176
01177 void ILL_2NOP() { pPC++; }
01178
01179 void ILL_3NOP() { pPC += 2; }
01180
01181
01182
01183
01184
01185 inline void ASLORA_m(uword addr)
01186 {
01187 ubyte x = ASL_m((this->*readData)(addr));
01188 (this->*writeData)(addr,x);
01189 ORA_m(x);
01190 }
01191 inline void ASLORA_m_zp(uword addr)
01192 {
01193 ubyte x = ASL_m(readData_zp(addr));
01194 writeData_zp(addr,x);
01195 ORA_m(x);
01196 }
01197 void ASLORA_abso()
01198 {
01199 ASLORA_m(abso());
01200 pPC += 2;
01201 }
01202 void ASLORA_absx()
01203 {
01204 ASLORA_m(absx());
01205 pPC += 2;
01206 }
01207 void ASLORA_absy()
01208 {
01209 ASLORA_m(absy());
01210 pPC += 2;
01211 }
01212 void ASLORA_indx()
01213 {
01214 ASLORA_m(indx());
01215 pPC++;
01216 }
01217 void ASLORA_indy()
01218 {
01219 ASLORA_m(indy());
01220 pPC++;
01221 }
01222 void ASLORA_zp()
01223 {
01224 ASLORA_m_zp(zp());
01225 pPC++;
01226 }
01227 void ASLORA_zpx()
01228 {
01229 ASLORA_m_zp(zpx());
01230 pPC++;
01231 }
01232
01233
01234 inline void ROLAND_m(uword addr)
01235 {
01236 ubyte x = ROL_m((this->*readData)(addr));
01237 (this->*writeData)(addr, x);
01238 AND_m(x);
01239 }
01240 inline void ROLAND_m_zp(uword addr)
01241 {
01242 ubyte x = ROL_m(readData_zp(addr));
01243 writeData_zp(addr, x);
01244 AND_m(x);
01245 }
01246 void ROLAND_abso()
01247 {
01248 ROLAND_m(abso());
01249 pPC += 2;
01250 }
01251 void ROLAND_absx()
01252 {
01253 ROLAND_m(absx());
01254 pPC += 2;
01255 }
01256 void ROLAND_absy()
01257 {
01258 ROLAND_m(absy());
01259 pPC += 2;
01260 }
01261 void ROLAND_indx()
01262 {
01263 ROLAND_m(indx());
01264 pPC++;
01265 }
01266 void ROLAND_indy()
01267 {
01268 ROLAND_m(indy());
01269 pPC++;
01270 }
01271 void ROLAND_zp()
01272 {
01273 ROLAND_m_zp(zp());
01274 pPC++;
01275 }
01276 void ROLAND_zpx()
01277 {
01278 ROLAND_m_zp(zpx());
01279 pPC++;
01280 }
01281
01282
01283 inline void LSREOR_m(uword addr)
01284 {
01285 ubyte x = LSR_m((this->*readData)(addr));
01286 (this->*writeData)(addr, x);
01287 EOR_m(x);
01288 }
01289 inline void LSREOR_m_zp(uword addr)
01290 {
01291 ubyte x = LSR_m(readData_zp(addr));
01292 writeData_zp(addr,x);
01293 EOR_m(x);
01294 }
01295 void LSREOR_abso()
01296 {
01297 LSREOR_m(abso());
01298 pPC += 2;
01299 }
01300 void LSREOR_absx()
01301 {
01302 LSREOR_m(absx());
01303 pPC += 2;
01304 }
01305 void LSREOR_absy()
01306 {
01307 LSREOR_m(absy());
01308 pPC += 2;
01309 }
01310 void LSREOR_indx()
01311 {
01312 LSREOR_m(indx());
01313 pPC++;
01314 }
01315 void LSREOR_indy()
01316 {
01317 LSREOR_m(indy());
01318 pPC++;
01319 }
01320 void LSREOR_zp()
01321 {
01322 LSREOR_m_zp(zp());
01323 pPC++;
01324 }
01325 void LSREOR_zpx()
01326 {
01327 LSREOR_m_zp(zpx());
01328 pPC++;
01329 }
01330
01331
01332 inline void RORADC_m(uword addr)
01333 {
01334 ubyte x = ROR_m((this->*readData)(addr));
01335 (this->*writeData)(addr,x);
01336 ADC_m(x);
01337 }
01338 inline void RORADC_m_zp(uword addr)
01339 {
01340 ubyte x = ROR_m(readData_zp(addr));
01341 writeData_zp(addr,x);
01342 ADC_m(x);
01343 }
01344 void RORADC_abso()
01345 {
01346 RORADC_m(abso());
01347 pPC += 2;
01348 }
01349 void RORADC_absx()
01350 {
01351 RORADC_m(absx());
01352 pPC += 2;
01353 }
01354 void RORADC_absy()
01355 {
01356 RORADC_m(absy());
01357 pPC += 2;
01358 }
01359 void RORADC_indx()
01360 {
01361 RORADC_m(indx());
01362 pPC++;
01363 }
01364 void RORADC_indy()
01365 {
01366 RORADC_m(indy());
01367 pPC++;
01368 }
01369 void RORADC_zp()
01370 {
01371 RORADC_m_zp(zp());
01372 pPC++;
01373 }
01374 void RORADC_zpx()
01375 {
01376 RORADC_m_zp(zpx());
01377 pPC++;
01378 }
01379
01380
01381 inline void DECCMP_m(uword addr)
01382 {
01383 ubyte x = (this->*readData)(addr);
01384 (this->*writeData)(addr,(--x));
01385 CMP_m(x);
01386 }
01387 inline void DECCMP_m_zp(uword addr)
01388 {
01389 ubyte x = readData_zp(addr);
01390 writeData_zp(addr,(--x));
01391 CMP_m(x);
01392 }
01393 void DECCMP_abso()
01394 {
01395 DECCMP_m(abso());
01396 pPC += 2;
01397 }
01398 void DECCMP_absx()
01399 {
01400 DECCMP_m(absx());
01401 pPC += 2;
01402 }
01403 void DECCMP_absy()
01404 {
01405 DECCMP_m(absy());
01406 pPC += 2;
01407 }
01408 void DECCMP_indx()
01409 {
01410 DECCMP_m(indx());
01411 pPC++;
01412 }
01413 void DECCMP_indy()
01414 {
01415 DECCMP_m(indy());
01416 pPC++;
01417 }
01418 void DECCMP_zp()
01419 {
01420 DECCMP_m_zp(zp());
01421 pPC++;
01422 }
01423 void DECCMP_zpx()
01424 {
01425 DECCMP_m_zp(zpx());
01426 pPC++;
01427 }
01428
01429
01430 inline void INCSBC_m(uword addr)
01431 {
01432 ubyte x = (this->*readData)(addr);
01433 (this->*writeData)(addr,(++x));
01434 SBC_m(x);
01435 }
01436 inline void INCSBC_m_zp(uword addr)
01437 {
01438 ubyte x = readData_zp(addr);
01439 writeData_zp(addr,(++x));
01440 SBC_m(x);
01441 }
01442 void INCSBC_abso()
01443 {
01444 INCSBC_m(abso());
01445 pPC += 2;
01446 }
01447 void INCSBC_absx()
01448 {
01449 INCSBC_m(absx());
01450 pPC += 2;
01451 }
01452 void INCSBC_absy()
01453 {
01454 INCSBC_m(absy());
01455 pPC += 2;
01456 }
01457 void INCSBC_indx()
01458 {
01459 INCSBC_m(indx());
01460 pPC++;
01461 }
01462 void INCSBC_indy()
01463 {
01464 INCSBC_m(indy());
01465 pPC++;
01466 }
01467 void INCSBC_zp()
01468 {
01469 INCSBC_m_zp(zp());
01470 pPC++;
01471 }
01472 void INCSBC_zpx()
01473 {
01474 INCSBC_m_zp(zpx());
01475 pPC++;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487 void ILL_0B()
01488 {
01489 AND_imm();
01490 CF = NF;
01491 }
01492
01493 void ILL_4B()
01494 {
01495 AND_imm();
01496 LSR_AC();
01497 }
01498
01499 void ILL_6B()
01500 {
01501 if (DF == 0)
01502 {
01503 AND_imm();
01504 ROR_AC();
01505 CF = (AC & 1);
01506 VF = (AC >> 5) ^ (AC >> 6);
01507 }
01508 }
01509
01510 void ILL_83()
01511 {
01512 (this->*writeData)(indx(),AC & XR);
01513 pPC++;
01514 }
01515
01516 void ILL_87()
01517 {
01518 writeData_zp(zp(),AC & XR);
01519 pPC++;
01520 }
01521
01522 void ILL_8B()
01523 {
01524 TXA_();
01525 AND_imm();
01526 }
01527
01528 void ILL_8F()
01529 {
01530 (this->*writeData)(abso(),AC & XR);
01531 pPC += 2;
01532 }
01533
01534 void ILL_93()
01535 {
01536 (this->*writeData)(indy(), AC & XR & (1+((this->*readData)((*pPC)+1) & 0xFF)));
01537 pPC++;
01538 }
01539
01540 void ILL_97()
01541 {
01542 writeData_zp(zpx(),AC & XR);
01543 pPC++;
01544 }
01545
01546 void ILL_9B()
01547 {
01548 SP = (uword)(0x100 | (AC & XR));
01549 (this->*writeData)(absy(),(SP & ((*pPC+1)+1)));
01550 pPC += 2;
01551 checkSP();
01552 }
01553
01554 void ILL_9C()
01555 {
01556 (this->*writeData)(absx(),(YR & ((*pPC+1)+1)));
01557 pPC += 2;
01558 }
01559
01560 void ILL_9E()
01561 {
01562 (this->*writeData)(absy(),(XR & ((*pPC+1)+1)));
01563 pPC += 2;
01564 }
01565
01566 void ILL_9F()
01567 {
01568 (this->*writeData)(absy(),(AC & XR & ((*pPC+1)+1)));
01569 pPC += 2;
01570 }
01571
01572 void ILL_A3()
01573 {
01574 LDA_indx();
01575 TAX_();
01576 }
01577
01578 void ILL_A7()
01579 {
01580 LDA_zp();
01581 TAX_();
01582 }
01583
01584 void ILL_AF()
01585 {
01586 LDA_abso();
01587 TAX_();
01588 }
01589
01590 void ILL_B3()
01591 {
01592 LDA_indy();
01593 TAX_();
01594 }
01595
01596 void ILL_B7()
01597 {
01598 affectNZ(AC = readData_zp(zpy()));
01599 TAX_();
01600 pPC++;
01601 }
01602
01603 void ILL_BB()
01604 {
01605 XR = (ubyte)(SP & absy());
01606 pPC += 2;
01607 TXS_();
01608 TXA_();
01609 }
01610
01611 void ILL_BF()
01612 {
01613 LDA_absy();
01614 TAX_();
01615 }
01616
01617 void ILL_CB()
01618 {
01619 uword tmp = (uword)(XR & AC);
01620 tmp -= imm();
01621 CF = (tmp > 255);
01622 affectNZ(XR=(tmp&255));
01623 }
01624
01625 void ILL_EB()
01626 {
01627 SBC_imm();
01628 }
01629
01630
01634
01635 public:
01636 ubyte* c64mem1;
01637 ubyte* c64mem2;
01638 bool sidKeysOff[32];
01639 bool sidKeysOn[32];
01640 ubyte sidLastValue;
01641 ubyte optr3readWave;
01642 ubyte optr3readEnve;
01643 public:
01644 ubyte AC, XR, YR;
01645 uword PC, SP;
01646
01647
01648 ubyte* pPCbase;
01649 ubyte* pPCend;
01650 ubyte* pPC;
01651 ubyte c64ramBuf[65536+256];
01652 ubyte c64romBuf[65536+256];
01653
01654 statusRegister SR;
01655
01656 bool isBasic;
01657 bool isIO;
01658 bool isKernal;
01659 ubyte* bankSelReg;
01660 ubyte fakeReadTimer;
01661
01662 public:
01663
01664
01665 ubyte (C6510::*readData)(uword);
01666 void (C6510::*writeData)(uword, ubyte);
01667 bool stackIsOkay;
01668
01669 int memoryMode;
01670
01671 typedef void (C6510::*C6510ptr2func)();
01672 C6510ptr2func instrList[256];
01673
01674 ubyte iFakeRndSeed;
01675
01676 public:
01677 inline ubyte my_read_data(uword w)
01678 {
01679 return (this->*readData)(w);
01680 }
01681 };
01682
01683
01684 #endif