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

CPU_emulcycle.i

Go to the documentation of this file.
00001 /*
00002  *  CPU_emulcycle.i - SC 6510/6502 emulation core (body of
00003  *                    EmulateCycle() function, the same for
00004  *                    both 6510 and 6502)
00005  *
00006  *  Frodo (C) 1994-1997 Christian Bauer
00007  */
00008 
00009 
00010 /*
00011  *  Stack macros
00012  */
00013 
00014 // Pop processor flags from the stack
00015 #define pop_flags() \
00016         read_to(sp | 0x100, data); \
00017         n_flag = data; \
00018         v_flag = data & 0x40; \
00019         d_flag = data & 0x08; \
00020         i_flag = data & 0x04; \
00021         z_flag = !(data & 0x02); \
00022         c_flag = data & 0x01;
00023 
00024 // Push processor flags onto the stack
00025 #define push_flags(b_flag) \
00026         data = 0x20 | (n_flag & 0x80); \
00027         if (v_flag) data |= 0x40; \
00028         if (b_flag) data |= 0x10; \
00029         if (d_flag) data |= 0x08; \
00030         if (i_flag) data |= 0x04; \
00031         if (!z_flag) data |= 0x02; \
00032         if (c_flag) data |= 0x01; \
00033         write_byte(sp-- | 0x100, data);
00034 
00035 
00036 /*
00037  *  Other macros
00038  */
00039 
00040 // Branch (cycle 1)
00041 #define Branch(flag) \
00042                 read_to(pc++, data);  \
00043                 if (flag) { \
00044                         ar = pc + (int8)data; \
00045                         if ((ar >> 8) != (pc >> 8)) { \
00046                                 if (data & 0x80) \
00047                                         state = O_BRANCH_BP; \
00048                                 else \
00049                                         state = O_BRANCH_FP; \
00050                         } else \
00051                                 state = O_BRANCH_NP; \
00052                 } else \
00053                         state = 0; \
00054                 break;
00055 
00056 // Set N and Z flags according to byte
00057 #define set_nz(x) (z_flag = n_flag = (x))
00058 
00059 // Address fetch of RMW instruction done, now read and write operand
00060 #define DoRMW state = RMW_DO_IT; break;
00061 
00062 // Operand fetch done, now execute opcode
00063 #define Execute state = OpTab[op]; break;
00064 
00065 // Last cycle of opcode
00066 #define Last state = 0; break;
00067 
00068 
00069 /*
00070  *  EmulCycle() function
00071  */
00072 
00073         switch (state) {
00074 
00075 
00076                 // Opcode fetch (cycle 0)
00077                 case 0:
00078                         read_to(pc++, op);
00079                         state = ModeTab[op];
00080                         break;
00081 
00082 
00083                 // IRQ
00084                 case 0x0008:
00085                         read_idle(pc);
00086                         state = 0x0009;
00087                         break;
00088                 case 0x0009:
00089                         read_idle(pc);
00090                         state = 0x000a;
00091                         break;
00092                 case 0x000a:
00093                         write_byte(sp-- | 0x100, pc >> 8);
00094                         state = 0x000b;
00095                         break;
00096                 case 0x000b:
00097                         write_byte(sp-- | 0x100, pc);
00098                         state = 0x000c;
00099                         break;
00100                 case 0x000c:
00101                         push_flags(false);
00102                         i_flag = true;
00103                         state = 0x000d;
00104                         break;
00105                 case 0x000d:
00106                         read_to(0xfffe, pc);
00107                         state = 0x000e;
00108                         break;
00109                 case 0x000e:
00110                         read_to(0xffff, data);
00111                         pc |= data << 8;
00112                         Last;
00113 
00114 
00115                 // NMI
00116                 case 0x0010:
00117                         read_idle(pc);
00118                         state = 0x0011;
00119                         break;
00120                 case 0x0011:
00121                         read_idle(pc);
00122                         state = 0x0012;
00123                         break;
00124                 case 0x0012:
00125                         write_byte(sp-- | 0x100, pc >> 8);
00126                         state = 0x0013;
00127                         break;
00128                 case 0x0013:
00129                         write_byte(sp-- | 0x100, pc);
00130                         state = 0x0014;
00131                         break;
00132                 case 0x0014:
00133                         push_flags(false);
00134                         i_flag = true;
00135                         state = 0x0015;
00136                         break;
00137                 case 0x0015:
00138                         read_to(0xfffa, pc);
00139                         state = 0x0016;
00140                         break;
00141                 case 0x0016:
00142                         read_to(0xfffb, data);
00143                         pc |= data << 8;
00144                         Last;
00145 
00146 
00147                 // Addressing modes: Fetch effective address, no extra cycles (-> ar)
00148                 case A_ZERO:
00149                         read_to(pc++, ar);
00150                         Execute;
00151 
00152                 case A_ZEROX:
00153                         read_to(pc++, ar);
00154                         state = A_ZEROX1;
00155                         break;
00156                 case A_ZEROX1:
00157                         read_idle(ar);
00158                         ar = (ar + x) & 0xff;
00159                         Execute;
00160 
00161                 case A_ZEROY:
00162                         read_to(pc++, ar);
00163                         state = A_ZEROY1;
00164                         break;
00165                 case A_ZEROY1:
00166                         read_idle(ar);
00167                         ar = (ar + y) & 0xff;
00168                         Execute;
00169 
00170                 case A_ABS:
00171                         read_to(pc++, ar);
00172                         state = A_ABS1;
00173                         break;
00174                 case A_ABS1:
00175                         read_to(pc++, data);
00176                         ar = ar | (data << 8);
00177                         Execute;
00178 
00179                 case A_ABSX:
00180                         read_to(pc++, ar);
00181                         state = A_ABSX1;
00182                         break;
00183                 case A_ABSX1:
00184                         read_to(pc++, ar2);     // Note: Some undocumented opcodes rely on the value of ar2
00185                         if (ar+x < 0x100)
00186                                 state = A_ABSX2;
00187                         else
00188                                 state = A_ABSX3;
00189                         ar = (ar + x) & 0xff | (ar2 << 8);
00190                         break;
00191                 case A_ABSX2:   // No page crossed
00192                         read_idle(ar);
00193                         Execute;
00194                 case A_ABSX3:   // Page crossed
00195                         read_idle(ar);
00196                         ar += 0x100;
00197                         Execute;
00198 
00199                 case A_ABSY:
00200                         read_to(pc++, ar);
00201                         state = A_ABSY1;
00202                         break;
00203                 case A_ABSY1:
00204                         read_to(pc++, ar2);     // Note: Some undocumented opcodes rely on the value of ar2
00205                         if (ar+y < 0x100)
00206                                 state = A_ABSY2;
00207                         else
00208                                 state = A_ABSY3;
00209                         ar = (ar + y) & 0xff | (ar2 << 8);
00210                         break;
00211                 case A_ABSY2:   // No page crossed
00212                         read_idle(ar);
00213                         Execute;
00214                 case A_ABSY3:   // Page crossed
00215                         read_idle(ar);
00216                         ar += 0x100;
00217                         Execute;
00218 
00219                 case A_INDX:
00220                         read_to(pc++, ar2);
00221                         state = A_INDX1;
00222                         break;
00223                 case A_INDX1:
00224                         read_idle(ar2);
00225                         ar2 = (ar2 + x) & 0xff;
00226                         state = A_INDX2;
00227                         break;
00228                 case A_INDX2:
00229                         read_to(ar2, ar);
00230                         state = A_INDX3;
00231                         break;
00232                 case A_INDX3:
00233                         read_to((ar2 + 1) & 0xff, data);
00234                         ar = ar | (data << 8);
00235                         Execute;
00236 
00237                 case A_INDY:
00238                         read_to(pc++, ar2);
00239                         state = A_INDY1;
00240                         break;
00241                 case A_INDY1:
00242                         read_to(ar2, ar);
00243                         state = A_INDY2;
00244                         break;
00245                 case A_INDY2:
00246                         read_to((ar2 + 1) & 0xff, ar2); // Note: Some undocumented opcodes rely on the value of ar2
00247                         if (ar+y < 0x100)
00248                                 state = A_INDY3;
00249                         else
00250                                 state = A_INDY4;
00251                         ar = (ar + y) & 0xff | (ar2 << 8);
00252                         break;
00253                 case A_INDY3:   // No page crossed
00254                         read_idle(ar);
00255                         Execute;
00256                 case A_INDY4:   // Page crossed
00257                         read_idle(ar);
00258                         ar += 0x100;
00259                         Execute;
00260 
00261 
00262                 // Addressing modes: Fetch effective address, extra cycle on page crossing (-> ar)
00263                 case AE_ABSX:
00264                         read_to(pc++, ar);
00265                         state = AE_ABSX1;
00266                         break;
00267                 case AE_ABSX1:
00268                         read_to(pc++, data);
00269                         if (ar+x < 0x100) {
00270                                 ar = (ar + x) & 0xff | (data << 8);
00271                                 Execute;
00272                         } else {
00273                                 ar = (ar + x) & 0xff | (data << 8);
00274                                 state = AE_ABSX2;
00275                         }
00276                         break;
00277                 case AE_ABSX2:  // Page crossed
00278                         read_idle(ar);
00279                         ar += 0x100;
00280                         Execute;
00281 
00282                 case AE_ABSY:
00283                         read_to(pc++, ar);
00284                         state = AE_ABSY1;
00285                         break;
00286                 case AE_ABSY1:
00287                         read_to(pc++, data);
00288                         if (ar+y < 0x100) {
00289                                 ar = (ar + y) & 0xff | (data << 8);
00290                                 Execute;
00291                         } else {
00292                                 ar = (ar + y) & 0xff | (data << 8);
00293                                 state = AE_ABSY2;
00294                         }
00295                         break;
00296                 case AE_ABSY2:  // Page crossed
00297                         read_idle(ar);
00298                         ar += 0x100;
00299                         Execute;
00300 
00301                 case AE_INDY:
00302                         read_to(pc++, ar2);
00303                         state = AE_INDY1;
00304                         break;
00305                 case AE_INDY1:
00306                         read_to(ar2, ar);
00307                         state = AE_INDY2;
00308                         break;
00309                 case AE_INDY2:
00310                         read_to((ar2 + 1) & 0xff, data);
00311                         if (ar+y < 0x100) {
00312                                 ar = (ar + y) & 0xff | (data << 8);
00313                                 Execute;
00314                         } else {
00315                                 ar = (ar + y) & 0xff | (data << 8);
00316                                 state = AE_INDY3;
00317                         }
00318                         break;
00319                 case AE_INDY3:  // Page crossed
00320                         read_idle(ar);
00321                         ar += 0x100;
00322                         Execute;
00323 
00324 
00325                 // Addressing modes: Read operand, write it back, no extra cycles (-> ar, rdbuf)
00326                 case M_ZERO:
00327                         read_to(pc++, ar);
00328                         DoRMW;
00329 
00330                 case M_ZEROX:
00331                         read_to(pc++, ar);
00332                         state = M_ZEROX1;
00333                         break;
00334                 case M_ZEROX1:
00335                         read_idle(ar);
00336                         ar = (ar + x) & 0xff;
00337                         DoRMW;
00338 
00339                 case M_ZEROY:
00340                         read_to(pc++, ar);
00341                         state = M_ZEROY1;
00342                         break;
00343                 case M_ZEROY1:
00344                         read_idle(ar);
00345                         ar = (ar + y) & 0xff;
00346                         DoRMW;
00347 
00348                 case M_ABS:
00349                         read_to(pc++, ar);
00350                         state = M_ABS1;
00351                         break;
00352                 case M_ABS1:
00353                         read_to(pc++, data);
00354                         ar = ar | (data << 8);
00355                         DoRMW;
00356 
00357                 case M_ABSX:
00358                         read_to(pc++, ar);
00359                         state = M_ABSX1;
00360                         break;
00361                 case M_ABSX1:
00362                         read_to(pc++, data);
00363                         if (ar+x < 0x100)
00364                                 state = M_ABSX2;
00365                         else
00366                                 state = M_ABSX3;
00367                         ar = (ar + x) & 0xff | (data << 8);
00368                         break;
00369                 case M_ABSX2:   // No page crossed
00370                         read_idle(ar);
00371                         DoRMW;
00372                 case M_ABSX3:   // Page crossed
00373                         read_idle(ar);
00374                         ar += 0x100;
00375                         DoRMW;
00376 
00377                 case M_ABSY:
00378                         read_to(pc++, ar);
00379                         state = M_ABSY1;
00380                         break;
00381                 case M_ABSY1:
00382                         read_to(pc++, data);
00383                         if (ar+y < 0x100)
00384                                 state = M_ABSY2;
00385                         else
00386                                 state = M_ABSY3;
00387                         ar = (ar + y) & 0xff | (data << 8);
00388                         break;
00389                 case M_ABSY2:   // No page crossed
00390                         read_idle(ar);
00391                         DoRMW;
00392                 case M_ABSY3:   // Page crossed
00393                         read_idle(ar);
00394                         ar += 0x100;
00395                         DoRMW;
00396 
00397                 case M_INDX:
00398                         read_to(pc++, ar2);
00399                         state = M_INDX1;
00400                         break;
00401                 case M_INDX1:
00402                         read_idle(ar2);
00403                         ar2 = (ar2 + x) & 0xff;
00404                         state = M_INDX2;
00405                         break;
00406                 case M_INDX2:
00407                         read_to(ar2, ar);
00408                         state = M_INDX3;
00409                         break;
00410                 case M_INDX3:
00411                         read_to((ar2 + 1) & 0xff, data);
00412                         ar = ar | (data << 8);
00413                         DoRMW;
00414 
00415                 case M_INDY:
00416                         read_to(pc++, ar2);
00417                         state = M_INDY1;
00418                         break;
00419                 case M_INDY1:
00420                         read_to(ar2, ar);
00421                         state = M_INDY2;
00422                         break;
00423                 case M_INDY2:
00424                         read_to((ar2 + 1) & 0xff, data);
00425                         if (ar+y < 0x100)
00426                                 state = M_INDY3;
00427                         else
00428                                 state = M_INDY4;
00429                         ar = (ar + y) & 0xff | (data << 8);
00430                         break;
00431                 case M_INDY3:   // No page crossed
00432                         read_idle(ar);
00433                         DoRMW;
00434                 case M_INDY4:   // Page crossed
00435                         read_idle(ar);
00436                         ar += 0x100;
00437                         DoRMW;
00438 
00439                 case RMW_DO_IT:
00440                         read_to(ar, rdbuf);
00441                         state = RMW_DO_IT1;
00442                         break;
00443                 case RMW_DO_IT1:
00444                         write_byte(ar, rdbuf);
00445                         Execute;
00446 
00447 
00448                 // Load group
00449                 case O_LDA:
00450                         read_to(ar, data);
00451                         set_nz(a = data);
00452                         Last;
00453                 case O_LDA_I:
00454                         read_to(pc++, data);
00455                         set_nz(a = data);
00456                         Last;
00457 
00458                 case O_LDX:
00459                         read_to(ar, data);
00460                         set_nz(x = data);
00461                         Last;
00462                 case O_LDX_I:
00463                         read_to(pc++, data);
00464                         set_nz(x = data);
00465                         Last;
00466 
00467                 case O_LDY:
00468                         read_to(ar, data);
00469                         set_nz(y = data);
00470                         Last;
00471                 case O_LDY_I:
00472                         read_to(pc++, data);
00473                         set_nz(y = data);
00474                         Last;
00475 
00476 
00477                 // Store group
00478                 case O_STA:
00479                         write_byte(ar, a);
00480                         Last;
00481 
00482                 case O_STX:
00483                         write_byte(ar, x);
00484                         Last;
00485 
00486                 case O_STY:
00487                         write_byte(ar, y);
00488                         Last;
00489 
00490 
00491                 // Transfer group
00492                 case O_TAX:
00493                         read_idle(pc);
00494                         set_nz(x = a);
00495                         Last;
00496 
00497                 case O_TXA:
00498                         read_idle(pc);
00499                         set_nz(a = x);
00500                         Last;
00501 
00502                 case O_TAY:
00503                         read_idle(pc);
00504                         set_nz(y = a);
00505                         Last;
00506 
00507                 case O_TYA:
00508                         read_idle(pc);
00509                         set_nz(a = y);
00510                         Last;
00511 
00512                 case O_TSX:
00513                         read_idle(pc);
00514                         set_nz(x = sp);
00515                         Last;
00516 
00517                 case O_TXS:
00518                         read_idle(pc);
00519                         sp = x;
00520                         Last;
00521 
00522 
00523                 // Arithmetic group
00524                 case O_ADC:
00525                         read_to(ar, data);
00526                         do_adc(data);
00527                         Last;
00528                 case O_ADC_I:
00529                         read_to(pc++, data);
00530                         do_adc(data);
00531                         Last;
00532 
00533                 case O_SBC:
00534                         read_to(ar, data);
00535                         do_sbc(data);
00536                         Last;
00537                 case O_SBC_I:
00538                         read_to(pc++, data);
00539                         do_sbc(data);
00540                         Last;
00541 
00542 
00543                 // Increment/decrement group
00544                 case O_INX:
00545                         read_idle(pc);
00546                         set_nz(++x);
00547                         Last;
00548 
00549                 case O_DEX:
00550                         read_idle(pc);
00551                         set_nz(--x);
00552                         Last;
00553 
00554                 case O_INY:
00555                         read_idle(pc);
00556                         set_nz(++y);
00557                         Last;
00558 
00559                 case O_DEY:
00560                         read_idle(pc);
00561                         set_nz(--y);
00562                         Last;
00563 
00564                 case O_INC:
00565                         write_byte(ar, set_nz(rdbuf + 1));
00566                         Last;
00567 
00568                 case O_DEC:
00569                         write_byte(ar, set_nz(rdbuf - 1));
00570                         Last;
00571 
00572 
00573                 // Logic group
00574                 case O_AND:
00575                         read_to(ar, data);
00576                         set_nz(a &= data);
00577                         Last;
00578                 case O_AND_I:
00579                         read_to(pc++, data);
00580                         set_nz(a &= data);
00581                         Last;
00582 
00583                 case O_ORA:
00584                         read_to(ar, data);
00585                         set_nz(a |= data);
00586                         Last;
00587                 case O_ORA_I:
00588                         read_to(pc++, data);
00589                         set_nz(a |= data);
00590                         Last;
00591 
00592                 case O_EOR:
00593                         read_to(ar, data);
00594                         set_nz(a ^= data);
00595                         Last;
00596                 case O_EOR_I:
00597                         read_to(pc++, data);
00598                         set_nz(a ^= data);
00599                         Last;
00600 
00601                 // Compare group
00602                 case O_CMP:
00603                         read_to(ar, data);
00604                         set_nz(ar = a - data);
00605                         c_flag = ar < 0x100;
00606                         Last;
00607                 case O_CMP_I:
00608                         read_to(pc++, data);
00609                         set_nz(ar = a - data);
00610                         c_flag = ar < 0x100;
00611                         Last;
00612 
00613                 case O_CPX:
00614                         read_to(ar, data);
00615                         set_nz(ar = x - data);
00616                         c_flag = ar < 0x100;
00617                         Last;
00618                 case O_CPX_I:
00619                         read_to(pc++, data);
00620                         set_nz(ar = x - data);
00621                         c_flag = ar < 0x100;
00622                         Last;
00623 
00624                 case O_CPY:
00625                         read_to(ar, data);
00626                         set_nz(ar = y - data);
00627                         c_flag = ar < 0x100;
00628                         Last;
00629                 case O_CPY_I:
00630                         read_to(pc++, data);
00631                         set_nz(ar = y - data);
00632                         c_flag = ar < 0x100;
00633                         Last;
00634 
00635 
00636                 // Bit-test group
00637                 case O_BIT:
00638                         read_to(ar, data);
00639                         z_flag = a & data;
00640                         n_flag = data;
00641                         v_flag = data & 0x40;
00642                         Last;
00643 
00644 
00645                 // Shift/rotate group
00646                 case O_ASL:
00647                         c_flag = rdbuf & 0x80;
00648                         write_byte(ar, set_nz(rdbuf << 1));
00649                         Last;
00650                 case O_ASL_A:
00651                         read_idle(pc);
00652                         c_flag = a & 0x80;
00653                         set_nz(a <<= 1);
00654                         Last;
00655 
00656                 case O_LSR:
00657                         c_flag = rdbuf & 0x01;
00658                         write_byte(ar, set_nz(rdbuf >> 1));
00659                         Last;
00660                 case O_LSR_A:
00661                         read_idle(pc);
00662                         c_flag = a & 0x01;
00663                         set_nz(a >>= 1);
00664                         Last;
00665 
00666                 case O_ROL:
00667                         write_byte(ar, set_nz(c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1));
00668                         c_flag = rdbuf & 0x80;
00669                         Last;
00670                 case O_ROL_A:
00671                         read_idle(pc);
00672                         data = a & 0x80;
00673                         set_nz(a = c_flag ? (a << 1) | 0x01 : a << 1);
00674                         c_flag = data;
00675                         Last;
00676 
00677                 case O_ROR:
00678                         write_byte(ar, set_nz(c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1));
00679                         c_flag = rdbuf & 0x01;
00680                         Last;
00681                 case O_ROR_A:
00682                         read_idle(pc);
00683                         data = a & 0x01;
00684                         set_nz(a = (c_flag ? (a >> 1) | 0x80 : a >> 1));
00685                         c_flag = data;
00686                         Last;
00687 
00688 
00689                 // Stack group
00690                 case O_PHA:
00691                         read_idle(pc);
00692                         state = O_PHA1;
00693                         break;
00694                 case O_PHA1:
00695                         write_byte(sp-- | 0x100, a);
00696                         Last;
00697 
00698                 case O_PLA:
00699                         read_idle(pc);
00700                         state = O_PLA1;
00701                         break;
00702                 case O_PLA1:
00703                         read_idle(sp++ | 0x100);
00704                         state = O_PLA2;
00705                         break;
00706                 case O_PLA2:
00707                         read_to(sp | 0x100, data);
00708                         set_nz(a = data);
00709                         Last;
00710 
00711                 case O_PHP:
00712                         read_idle(pc);
00713                         state = O_PHP1;
00714                         break;
00715                 case O_PHP1:
00716                         push_flags(true);
00717                         Last;
00718 
00719                 case O_PLP:
00720                         read_idle(pc);
00721                         state = O_PLP1;
00722                         break;
00723                 case O_PLP1:
00724                         read_idle(sp++ | 0x100);
00725                         state = O_PLP2;
00726                         break;
00727                 case O_PLP2:
00728                         pop_flags();
00729                         Last;
00730 
00731 
00732                 // Jump/branch group
00733                 case O_JMP:
00734                         read_to(pc++, ar);
00735                         state = O_JMP1;
00736                         break;
00737                 case O_JMP1:
00738                         read_to(pc, data);
00739                         pc = (data << 8) | ar;
00740                         Last;
00741 
00742                 case O_JMP_I:
00743                         read_to(ar, pc);
00744                         state = O_JMP_I1;
00745                         break;
00746                 case O_JMP_I1:
00747                         read_to((ar + 1) & 0xff | ar & 0xff00, data);
00748                         pc |= data << 8;
00749                         Last;
00750 
00751                 case O_JSR:
00752                         read_to(pc++, ar);
00753                         state = O_JSR1;
00754                         break;
00755                 case O_JSR1:
00756                         read_idle(sp | 0x100);
00757                         state = O_JSR2;
00758                         break;
00759                 case O_JSR2:
00760                         write_byte(sp-- | 0x100, pc >> 8);
00761                         state = O_JSR3;
00762                         break;
00763                 case O_JSR3:
00764                         write_byte(sp-- | 0x100, pc);
00765                         state = O_JSR4;
00766                         break;
00767                 case O_JSR4:
00768                         read_to(pc++, data);
00769                         pc = ar | (data << 8);
00770                         Last;
00771 
00772                 case O_RTS:
00773                         read_idle(pc);
00774                         state = O_RTS1;
00775                         break;
00776                 case O_RTS1:
00777                         read_idle(sp++ | 0x100);
00778                         state = O_RTS2;
00779                         break;
00780                 case O_RTS2:
00781                         read_to(sp++ | 0x100, pc);
00782                         state = O_RTS3;
00783                         break;
00784                 case O_RTS3:
00785                         read_to(sp | 0x100, data);
00786                         pc |= data << 8;
00787                         state = O_RTS4;
00788                         break;
00789                 case O_RTS4:
00790                         read_idle(pc++);
00791                         Last;
00792 
00793                 case O_RTI:
00794                         read_idle(pc);
00795                         state = O_RTI1;
00796                         break;
00797                 case O_RTI1:
00798                         read_idle(sp++ | 0x100);
00799                         state = O_RTI2;
00800                         break;
00801                 case O_RTI2:
00802                         pop_flags();
00803                         sp++;
00804                         state = O_RTI3;
00805                         break;
00806                 case O_RTI3:
00807                         read_to(sp++ | 0x100, pc);
00808                         state = O_RTI4;
00809                         break;
00810                 case O_RTI4:
00811                         read_to(sp | 0x100, data);
00812                         pc |= data << 8;
00813                         Last;
00814 
00815                 case O_BRK:
00816                         read_idle(pc++);
00817                         state = O_BRK1;
00818                         break;
00819                 case O_BRK1:
00820                         write_byte(sp-- | 0x100, pc >> 8);
00821                         state = O_BRK2;
00822                         break;
00823                 case O_BRK2:
00824                         write_byte(sp-- | 0x100, pc);
00825                         state = O_BRK3;
00826                         break;
00827                 case O_BRK3:
00828                         push_flags(true);
00829                         i_flag = true;
00830 #ifndef IS_CPU_1541
00831                         if (interrupt.intr[INT_NMI]) {                  // BRK interrupted by NMI?
00832                                 interrupt.intr[INT_NMI] = false;        // Simulate an edge-triggered input
00833                                 state = 0x0015;                                         // Jump to NMI sequence
00834                                 break;
00835                         }
00836 #endif
00837                         state = O_BRK4;
00838                         break;
00839                 case O_BRK4:
00840 #ifndef IS_CPU_1541
00841                         first_nmi_cycle++;              // Delay NMI
00842 #endif
00843                         read_to(0xfffe, pc);
00844                         state = O_BRK5;
00845                         break;
00846                 case O_BRK5:
00847                         read_to(0xffff, data);
00848                         pc |= data << 8;
00849                         Last;
00850 
00851                 case O_BCS:
00852                         Branch(c_flag);
00853 
00854                 case O_BCC:
00855                         Branch(!c_flag);
00856 
00857                 case O_BEQ:
00858                         Branch(!z_flag);
00859 
00860                 case O_BNE:
00861                         Branch(z_flag);
00862 
00863                 case O_BVS:
00864 #ifndef IS_CPU_1541
00865                         Branch(v_flag);
00866 #else
00867                         Branch((via2_pcr & 0x0e) == 0x0e ? 1 : v_flag); // GCR byte ready flag
00868 #endif
00869 
00870                 case O_BVC:
00871 #ifndef IS_CPU_1541
00872                         Branch(!v_flag);
00873 #else
00874                         Branch(!((via2_pcr & 0x0e) == 0x0e) ? 0 : v_flag);      // GCR byte ready flag
00875 #endif
00876 
00877                 case O_BMI:
00878                         Branch(n_flag & 0x80);
00879 
00880                 case O_BPL:
00881                         Branch(!(n_flag & 0x80));
00882 
00883                 case O_BRANCH_NP:       // No page crossed
00884                         first_irq_cycle++;      // Delay IRQ
00885 #ifndef IS_CPU_1541
00886                         first_nmi_cycle++;      // Delay NMI
00887 #endif
00888                         read_idle(pc);
00889                         pc = ar;
00890                         Last;
00891                 case O_BRANCH_BP:       // Page crossed, branch backwards
00892                         read_idle(pc);
00893                         pc = ar;
00894                         state = O_BRANCH_BP1;
00895                         break;
00896                 case O_BRANCH_BP1:
00897                         read_idle(pc + 0x100);
00898                         Last;
00899                 case O_BRANCH_FP:       // Page crossed, branch forwards
00900                         read_idle(pc);
00901                         pc = ar;
00902                         state = O_BRANCH_FP1;
00903                         break;
00904                 case O_BRANCH_FP1:
00905                         read_idle(pc - 0x100);
00906                         Last;
00907 
00908 
00909                 // Flag group
00910                 case O_SEC:
00911                         read_idle(pc);
00912                         c_flag = true;
00913                         Last;
00914 
00915                 case O_CLC:
00916                         read_idle(pc);
00917                         c_flag = false;
00918                         Last;
00919 
00920                 case O_SED:
00921                         read_idle(pc);
00922                         d_flag = true;
00923                         Last;
00924 
00925                 case O_CLD:
00926                         read_idle(pc);
00927                         d_flag = false;
00928                         Last;
00929 
00930                 case O_SEI:
00931                         read_idle(pc);
00932                         i_flag = true;
00933                         Last;
00934 
00935                 case O_CLI:
00936                         read_idle(pc);
00937                         i_flag = false;
00938                         Last;
00939 
00940                 case O_CLV:
00941                         read_idle(pc);
00942                         v_flag = false;
00943                         Last;
00944 
00945 
00946                 // NOP group
00947                 case O_NOP:
00948                         read_idle(pc);
00949                         Last;
00950 
00951 
00952 /*
00953  * Undocumented opcodes start here
00954  */
00955 
00956                 // NOP group
00957                 case O_NOP_I:
00958                         read_idle(pc++);
00959                         Last;
00960 
00961                 case O_NOP_A:
00962                         read_idle(ar);
00963                         Last;
00964 
00965 
00966                 // Load A/X group
00967                 case O_LAX:
00968                         read_to(ar, data);
00969                         set_nz(a = x = data);
00970                         Last;
00971 
00972 
00973                 // Store A/X group
00974                 case O_SAX:
00975                         write_byte(ar, a & x);
00976                         Last;
00977 
00978 
00979                 // ASL/ORA group
00980                 case O_SLO:
00981                         c_flag = rdbuf & 0x80;
00982                         rdbuf <<= 1;
00983                         write_byte(ar, rdbuf);
00984                         set_nz(a |= rdbuf);
00985                         Last;
00986 
00987 
00988                 // ROL/AND group
00989                 case O_RLA:
00990                         tmp = rdbuf & 0x80;
00991                         rdbuf = c_flag ? (rdbuf << 1) | 0x01 : rdbuf << 1;
00992                         c_flag = tmp;
00993                         write_byte(ar, rdbuf);
00994                         set_nz(a &= rdbuf);
00995                         Last;
00996 
00997 
00998                 // LSR/EOR group
00999                 case O_SRE:
01000                         c_flag = rdbuf & 0x01;
01001                         rdbuf >>= 1;
01002                         write_byte(ar, rdbuf);
01003                         set_nz(a ^= rdbuf);
01004                         Last;
01005 
01006 
01007                 // ROR/ADC group
01008                 case O_RRA:
01009                         tmp = rdbuf & 0x01;
01010                         rdbuf = c_flag ? (rdbuf >> 1) | 0x80 : rdbuf >> 1;
01011                         c_flag = tmp;
01012                         write_byte(ar, rdbuf);
01013                         do_adc(rdbuf);
01014                         Last;
01015 
01016 
01017                 // DEC/CMP group
01018                 case O_DCP:
01019                         write_byte(ar, --rdbuf);
01020                         set_nz(ar = a - rdbuf);
01021                         c_flag = ar < 0x100;
01022                         Last;
01023 
01024 
01025                 // INC/SBC group
01026                 case O_ISB:
01027                         write_byte(ar, ++rdbuf);
01028                         do_sbc(rdbuf);
01029                         Last;
01030 
01031 
01032                 // Complex functions
01033                 case O_ANC_I:
01034                         read_to(pc++, data);
01035                         set_nz(a &= data);
01036                         c_flag = n_flag & 0x80;
01037                         Last;
01038 
01039                 case O_ASR_I:
01040                         read_to(pc++, data);
01041                         a &= data;
01042                         c_flag = a & 0x01;
01043                         set_nz(a >>= 1);
01044                         Last;
01045 
01046                 case O_ARR_I:
01047                         read_to(pc++, data);
01048                         data &= a;
01049                         a = (c_flag ? (data >> 1) | 0x80 : data >> 1);
01050                         if (!d_flag) {
01051                                 set_nz(a);
01052                                 c_flag = a & 0x40;
01053                                 v_flag = (a & 0x40) ^ ((a & 0x20) << 1);
01054                         } else {
01055                                 n_flag = c_flag ? 0x80 : 0;
01056                                 z_flag = a;
01057                                 v_flag = (data ^ a) & 0x40;
01058                                 if ((data & 0x0f) + (data & 0x01) > 5)
01059                                         a = a & 0xf0 | (a + 6) & 0x0f;
01060                                 if (c_flag = ((data + (data & 0x10)) & 0x1f0) > 0x50)
01061                                         a += 0x60;
01062                         }
01063                         Last;
01064 
01065                 case O_ANE_I:
01066                         read_to(pc++, data);
01067                         set_nz(a = (a | 0xee) & x & data);
01068                         Last;
01069 
01070                 case O_LXA_I:
01071                         read_to(pc++, data);
01072                         set_nz(a = x = (a | 0xee) & data);
01073                         Last;
01074 
01075                 case O_SBX_I:
01076                         read_to(pc++, data);
01077                         set_nz(x = ar = (x & a) - data);
01078                         c_flag = ar < 0x100;
01079                         Last;
01080 
01081                 case O_LAS:
01082                         read_to(ar, data);
01083                         set_nz(a = x = sp = data & sp);
01084                         Last;
01085 
01086                 case O_SHS:             // ar2 contains the high byte of the operand address
01087                         write_byte(ar, (ar2+1) & (sp = a & x));
01088                         Last;
01089 
01090                 case O_SHY:             // ar2 contains the high byte of the operand address
01091                         write_byte(ar, y & (ar2+1));
01092                         Last;
01093 
01094                 case O_SHX:             // ar2 contains the high byte of the operand address
01095                         write_byte(ar, x & (ar2+1));
01096                         Last;
01097 
01098                 case O_SHA:             // ar2 contains the high byte of the operand address
01099                         write_byte(ar, a & x & (ar2+1));
01100                         Last;

Generated on Tue Feb 8 04:07:36 2005 for E32frodo by doxygen 1.3.3