Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

6510_.h

Go to the documentation of this file.
00001 //
00002 // 1997/05/30 13:36:14
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 // ------------------------------------------------------ (S)tatus (R)egister
00016 // MOS-6510 SR: NV-BDIZC
00017 //              76543210
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 // Some handy defines to ease SR access.
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 // for Zero filling object
00052 #else
00053 class C6510
00054 #endif
00055         {
00056   public:
00057         C6510();
00058         ~C6510();
00059         //
00060         bool c64memAlloc();
00061         //
00062         // called by eeconfig.cpp
00063         //
00064         void initInterpreter(int inMemoryMode);
00065         void c64memReset(int clockSpeed, ubyte randomSeed);
00066         void c64memClear();
00067         //
00068         // called by player.cpp
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                 // Explicit paranthesis looks great.
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 // Handling conditional branches.
00115 
00116         inline void branchIfClear(ubyte flag)
00117                 {
00118                 if (flag == 0)
00119                         {
00120                         PC = (uword)(pPC-pPCbase);   // calculate 16-bit PC
00121                         PC += (sbyte)(*pPC);  // add offset, keep it 16-bit (uword)
00122                         pPC = pPCbase+PC;   // calc new pointer-PC
00123                         }
00124                 pPC++;
00125                 }
00126 
00127         inline void branchIfSet(ubyte flag)
00128                 {
00129                 if (flag != 0)
00130                         {
00131                         PC = (uword)(pPC-pPCbase);   // calculate 16-bit PC
00132                         PC += (sbyte)(*pPC);  // add offset, keep it 16-bit (uword)
00133                         pPC = pPCbase+PC;   // calc new pointer-PC
00134                         }
00135                 pPC++;
00136                 }
00137 
00138 // --------------------------------------------------------------------------
00139 // Addressing modes:
00140 // Calculating 8/16-bit effective addresses out of data operands.
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 // Relevant configurable memory banks:
00193 //
00194 //  $A000 to $BFFF = RAM, Basic-ROM
00195 //  $C000 to $CFFF = RAM
00196 //  $D000 to $DFFF = RAM, I/O, Char-ROM 
00197 //  $E000 to $FFFF = RAM, Kernal-ROM
00198 //
00199 // Bank-Select Register $01:
00200 // 
00201 //   Bits
00202 //   210    $A000-$BFFF   $D000-$DFFF   $E000-$FFFF
00203 //  ------------------------------------------------
00204 //   000       RAM           RAM            RAM
00205 //   001       RAM        Char-ROM          RAM
00206 //   010       RAM        Char-ROM      Kernal-ROM
00207 //   011    Basic-ROM     Char-ROM      Kernal-ROM
00208 //   100       RAM           RAM            RAM
00209 //   101       RAM           I/O            RAM
00210 //   110       RAM           I/O        Kernal-ROM
00211 //   111    Basic-ROM        I/O        Kernal-ROM
00212 //
00213 // "Transparent ROM" mode:
00214 //
00215 // Basic-ROM and Kernal-ROM are considered transparent to read/write access.
00216 // Basic-ROM is also considered transparent to branches (JMP, BCC, ...).
00217 // I/O and Kernal-ROM are togglable via bank-select register $01.
00218 
00219 
00220 
00221         inline void evalBankSelect()
00222                 {
00223                 // Determine new memory configuration.
00224                 isBasic = ((*bankSelReg & 3) == 3);
00225                 isIO = ((*bankSelReg & 7) > 4);
00226                 isKernal = ((*bankSelReg & 2) != 0);
00227                 }
00228 
00229 
00230 // Upon JMP/JSR prevent code execution in Basic-ROM/Kernal-ROM.
00231         inline void evalBankJump()
00232                 {
00233                 if (PC < 0xA000)
00234                         {
00235                         ;
00236                         }
00237                 else
00238                         {
00239                         // Get high-nibble of address.
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:  // <-- just to please the compiler
00266                                   {
00267                                   if (isKernal)
00268                                           {
00269                                           RTS_();
00270                                           }
00271                                   break;
00272                                   }
00273                                 }
00274                         }
00275                 }
00276 
00277 
00278   private:
00279 
00280 // Functions to retrieve data.
00281         ubyte readData_bs(uword addr)
00282                 {
00283                 if (addr < 0xA000)
00284                         {
00285                         return c64mem1[addr];
00286                         }
00287                 else
00288                         {
00289                         // Get high-nibble of address.
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                                           // Not SID ?
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                                                   // $D41D/1E/1F, $D43D/, ... SID not mirrored
00330                                                   if (( tempAddr & 0x00ff ) >= 0x001d )
00331                                                           return(c64mem2[addr]); 
00332                                                   // (Mirrored) SID.
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:  // <-- just to please the compiler
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                         // Get high-nibble of address.
00378                         switch (addr >> 12)
00379                                 {
00380                           case 0xd:
00381                                   {
00382                                   if (isIO)
00383                                           {
00384                                           uword tempAddr = (uword)(addr & 0xfc1f);
00385                                           // Not SID ?
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                                                   // $D41D/1E/1F, $D43D/, ... SID not mirrored
00406                                                   if (( tempAddr & 0x00ff ) >= 0x001d )
00407                                                           return(c64mem2[addr]); 
00408                                                   // (Mirrored) SID.
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:  // <-- just to please the compiler
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 // Functions to store data.
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)  // write to Bank-Select Register ?
00461                                 {
00462                                 evalBankSelect();
00463                                 }
00464                         }
00465                 else
00466                         {
00467                         if (isIO)
00468                                 {
00469                                 // Check whether real SID or mirrored SID.
00470                                 uword tempAddr = (uword)(addr & 0xfc1f);
00471                                 // Not SID ?
00472                                 if (( tempAddr & 0xff00 ) != 0xd400 )
00473                                         {
00474                                         c64mem2[addr] = data;
00475                                         }
00476                                 // $D41D/1E/1F, $D43D/3E/3F, ...
00477                                 // Map to real address to support PlaySID
00478                                 // Extended SID Chip Registers.
00479                                 else if (( tempAddr & 0x00ff ) >= 0x001d )
00480                                         {
00481                                         // Mirrored SID.
00482                                         c64mem2[addr] = (sidLastValue = data);
00483                                         }
00484                                 else
00485                                         {
00486                                         // SID.
00487                                         c64mem2[tempAddr] = (sidLastValue = data);
00488                                         // Handle key_ons.
00489                                         sidKeysOn[tempAddr&0x001f] = sidKeysOn[tempAddr&0x001f] || ((data&1)!=0); 
00490                                         // Handle key_offs.
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                 // Check whether real SID or mirrored SID.
00504                 uword tempAddr = (uword)(addr & 0xfc1f);
00505                 // Not SID ?
00506                 if (( tempAddr & 0xff00 ) != 0xd400 )
00507                         {
00508                         c64mem1[addr] = data; 
00509                         }
00510                 // $D41D/1E/1F, $D43D/3E/3F, ...
00511                 // Map to real address to support PlaySID
00512                 // Extended SID Chip Registers.
00513                 else if (( tempAddr & 0x00ff ) >= 0x001d )
00514                         {
00515                         // Mirrored SID.
00516                         c64mem1[addr] = (sidLastValue = data);
00517                         }
00518                 else
00519                         {
00520                         // SID.
00521                         c64mem2[tempAddr] = (sidLastValue = data);
00522                         // Handle key_ons.
00523                         sidKeysOn[tempAddr&0x001f] = sidKeysOn[tempAddr&0x001f] || ((data&1)!=0); 
00524                         // Handle key_offs.
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)  // write to Bank-Select Register ?
00533                         {
00534                         evalBankSelect();
00535                         }
00536                 }
00537 
00538 
00539 // --------------------------------------------------------------------------
00540 // Legal instructions in alphabetical order.
00541 //
00542 // LIFO-Stack:
00543 //
00544 // |xxxxxx|
00545 // |xxxxxx|
00546 // |______|<- SP <= (hi)-return-address
00547 // |______|      <= (lo)
00548 // |______|
00549 //
00550 
00551 
00552         inline void resetSP()
00553                 {
00554                 SP = 0x1ff;          // SP to top of stack
00555                 stackIsOkay = true;
00556                 }
00557 
00558         inline void checkSP()
00559                 {
00560                 stackIsOkay = ((SP>0xff)&&(SP<=0x1ff));  // check boundaries
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_();  // will set pPC
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_();  // will set pPC
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_();  // will set pPC
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                 // equal to RTS_();
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 // Illegal codes/instructions part (1).
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 // Illegal codes/instructions part (2).
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 // Illegal codes/instructions part (3). This implementation is considered to
01481 // be only partially working due to inconsistencies in the available
01482 // documentation.
01483 // Note: In some of the functions emulated, defined instructions are used and
01484 // already increment the PC ! Take care, and do not increment further !
01485 // Double-setting of processor flags can occur, too.
01486 
01487         void ILL_0B() // equal to 2B
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()));  // would be LDA_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 // PC is only used temporarily ! 
01647 // The current program-counter is pPC-pPCbase
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 // Use pointers to allow plain-memory modifications.
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

Generated on Tue Feb 8 04:13:55 2005 for Esidplay by doxygen 1.3.3