Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
emu6502.cpp
00001 // emu6502.c - Emu6502 - MOS6502 Emulator 00002 // 00003 //////////////////////////////////////////////////////////////////////////////// 00004 // 00005 // c-simple-emu-cbm (C Portable Version) 00006 // C64/6502 Emulator for Terminal Console 00007 // 00008 // MIT License 00009 // 00010 // Copyright(c) 2020 by David R. Van Wagner 00011 // davevw.com 00012 // 00013 // Permission is hereby granted, free of charge, to any person obtaining a copy 00014 // of this software and associated documentation files (the "Software"), to deal 00015 // in the Software without restriction, including without limitation the rights 00016 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00017 // copies of the Software, and to permit persons to whom the Software is 00018 // furnished to do so, subject to the following conditions: 00019 // 00020 // The above copyright notice and this permission notice shall be included in all 00021 // copies or substantial portions of the Software. 00022 // 00023 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00024 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00025 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00026 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00027 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00028 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00029 // SOFTWARE. 00030 // 00031 //////////////////////////////////////////////////////////////////////////////// 00032 00033 //#define snprintf sprintf_s 00034 00035 #include <mbed.h> 00036 #include "emu6502.h" 00037 00038 // global references 00039 extern Serial pc; 00040 00041 // globals 00042 byte A = 0; 00043 byte X = 0; 00044 byte Y = 0; 00045 byte S = 0xFF; 00046 bool N = false; 00047 bool V = false; 00048 bool B = false; 00049 bool D = false; 00050 bool I = false; 00051 bool Z = false; 00052 bool C = false; 00053 ushort PC = 0; 00054 bool trace = false; 00055 bool step = false; 00056 00057 #define USE_IRQ 0 00058 00059 extern void ResetRun(bool (*ExecutePatch)(void)) 00060 { 00061 ushort addr = (ushort)((GetMemory(0xFFFC) | (GetMemory(0xFFFD) << 8))); // JMP(RESET) 00062 Execute(addr, ExecutePatch); 00063 } 00064 00065 #ifndef WIN32 00066 static void strcpy_s(char* dest, size_t size, const char* src) 00067 { 00068 strncpy(dest, src, size); 00069 } 00070 00071 static void strcat_s(char* dest, size_t size, const char* src) 00072 { 00073 strncat(dest, src, size); 00074 } 00075 #endif 00076 00077 static void PHP() 00078 { 00079 int flags = (N ? 0x80 : 0) 00080 | (V ? 0x40 : 0) 00081 | (B ? 0x10 : 0) 00082 | (D ? 0x08 : 0) 00083 | (I ? 0x04 : 0) 00084 | (Z ? 0x02 : 0) 00085 | (C ? 0x01 : 0); 00086 Push(flags); 00087 } 00088 00089 extern byte LO(ushort value) 00090 { 00091 return (byte)value; 00092 } 00093 00094 extern byte HI(ushort value) 00095 { 00096 return (byte)(value >> 8); 00097 } 00098 00099 static byte Subtract(byte reg, byte value, bool *p_overflow) 00100 { 00101 bool old_reg_neg = (reg & 0x80) != 0; 00102 bool value_neg = (value & 0x80) != 0; 00103 int result = reg - value - (C ? 0 : 1); 00104 N = (result & 0x80) != 0; 00105 C = (result >= 0); 00106 Z = (result == 0); 00107 bool result_neg = (result & 0x80) != 0; 00108 *p_overflow = (old_reg_neg && !value_neg && !result_neg) // neg - pos = pos 00109 || (!old_reg_neg && value_neg && result_neg); // pos - neg = neg 00110 return (byte)result; 00111 } 00112 00113 static byte SubtractWithoutOverflow(byte reg, byte value) 00114 { 00115 C = true; // init for CMP, etc. 00116 bool unused; 00117 return Subtract(reg, value, &unused); 00118 } 00119 00120 static void CMP(byte value) 00121 { 00122 SubtractWithoutOverflow(A, value); 00123 } 00124 00125 static void CPX(byte value) 00126 { 00127 SubtractWithoutOverflow(X, value); 00128 } 00129 00130 static void CPY(byte value) 00131 { 00132 SubtractWithoutOverflow(Y, value); 00133 } 00134 00135 static void SetReg(byte *p_reg, int value) 00136 { 00137 *p_reg = (byte)value; 00138 Z = (*p_reg == 0); 00139 N = ((*p_reg & 0x80) != 0); 00140 } 00141 00142 static void SetA(int value) 00143 { 00144 SetReg(&A, value); 00145 } 00146 00147 static void SetX(int value) 00148 { 00149 SetReg(&X, value); 00150 } 00151 00152 static void SetY(int value) 00153 { 00154 SetReg(&Y, value); 00155 } 00156 00157 static void SBC(byte value) 00158 { 00159 if (D) 00160 { 00161 int A_dec = (A & 0xF) + ((A >> 4) * 10); 00162 int value_dec = (value & 0xF) + ((value >> 4) * 10); 00163 int result_dec = A_dec - value_dec - (C ? 0 : 1); 00164 C = (result_dec >= 0); 00165 if (!C) 00166 result_dec = -result_dec; // absolute value 00167 int result = (result_dec % 10) | (((result_dec / 10) % 10) << 4); 00168 SetA(result); 00169 N = false; // undefined? 00170 V = false; // undefined? 00171 } 00172 else 00173 { 00174 byte result = Subtract(A, value, &V); 00175 SetA(result); 00176 } 00177 } 00178 00179 static void ADC_OP(byte value) 00180 { 00181 int result; 00182 if (D) 00183 { 00184 int A_dec = (A & 0xF) + ((A >> 4) * 10); 00185 int value_dec = (value & 0xF) + ((value >> 4) * 10); 00186 int result_dec = A_dec + value_dec + (C ? 1 : 0); 00187 C = (result_dec > 99); 00188 result = (result_dec % 10) | (((result_dec / 10) % 10) << 4); 00189 SetA(result); 00190 Z = (result_dec == 0); // BCD quirk -- 100 doesn't set Z 00191 V = false; 00192 } 00193 else 00194 { 00195 bool A_old_neg = (A & 0x80) != 0; 00196 bool value_neg = (value & 0x80) != 0; 00197 result = A + value + (C ? 1 : 0); 00198 C = (result & 0x100) != 0; 00199 SetA(result); 00200 bool result_neg = (result & 0x80) != 0; 00201 V = (!A_old_neg && !value_neg && result_neg) // pos + pos = neg: overflow 00202 || (A_old_neg && value_neg && !result_neg); // neg + neg = pos: overflow 00203 } 00204 } 00205 00206 static void ORA(int value) 00207 { 00208 SetA(A | value); 00209 } 00210 00211 static void EOR(int value) 00212 { 00213 SetA(A ^ value); 00214 } 00215 00216 static void AND(int value) 00217 { 00218 SetA(A & value); 00219 } 00220 00221 static void BIT_OP(byte value) 00222 { 00223 Z = (A & value) == 0; 00224 N = (value & 0x80) != 0; 00225 V = (value & 0x40) != 0; 00226 } 00227 00228 static byte ASL(int value) 00229 { 00230 C = (value & 0x80) != 0; 00231 value = (byte)(value << 1); 00232 Z = (value == 0); 00233 N = (value & 0x80) != 0; 00234 return (byte)value; 00235 } 00236 00237 static byte LSR(int value) 00238 { 00239 C = (value & 0x01) != 0; 00240 value = (byte)(value >> 1); 00241 Z = (value == 0); 00242 N = false; 00243 return (byte)value; 00244 } 00245 00246 static byte ROL(int value) 00247 { 00248 bool newC = (value & 0x80) != 0; 00249 value = (byte)((value << 1) | (C ? 1 : 0)); 00250 C = newC; 00251 Z = (value == 0); 00252 N = (value & 0x80) != 0; 00253 return (byte)value; 00254 } 00255 00256 static byte ROR(int value) 00257 { 00258 bool newC = (value & 0x01) != 0; 00259 N = C; 00260 value = (byte)((value >> 1) | (C ? 0x80 : 0)); 00261 C = newC; 00262 Z = (value == 0); 00263 return (byte)value; 00264 } 00265 00266 extern void Push(int value) 00267 { 00268 SetMemory((ushort)(0x100 + (S--)), (byte)value); 00269 } 00270 00271 extern byte Pop(void) 00272 { 00273 return GetMemory((ushort)(0x100 + (++S))); 00274 } 00275 00276 static void PLP() 00277 { 00278 int flags = Pop(); 00279 N = (flags & 0x80) != 0; 00280 V = (flags & 0x40) != 0; 00281 B = (flags & 0x10) != 0; 00282 D = (flags & 0x08) != 0; 00283 I = (flags & 0x04) != 0; 00284 Z = (flags & 0x02) != 0; 00285 C = (flags & 0x01) != 0; 00286 } 00287 00288 static void PHA() 00289 { 00290 Push(A); 00291 } 00292 00293 static void PLA() 00294 { 00295 SetA(Pop()); 00296 } 00297 00298 static void CLC() 00299 { 00300 C = false; 00301 } 00302 00303 static void CLD() 00304 { 00305 D = false; 00306 } 00307 00308 static void CLI() 00309 { 00310 I = false; 00311 } 00312 00313 static void CLV() 00314 { 00315 V = false; 00316 } 00317 00318 static void SEC() 00319 { 00320 C = true; 00321 } 00322 00323 static void SED() 00324 { 00325 D = true; 00326 } 00327 00328 static void SEI() 00329 { 00330 I = true; 00331 } 00332 00333 static byte INC(byte value) 00334 { 00335 ++value; 00336 Z = (value == 0); 00337 N = (value & 0x80) != 0; 00338 return (byte)value; 00339 } 00340 00341 static void INX() 00342 { 00343 X = INC(X); 00344 } 00345 00346 static void INY() 00347 { 00348 Y = INC(Y); 00349 } 00350 00351 static byte DEC(byte value) 00352 { 00353 --value; 00354 Z = (value == 0); 00355 N = (value & 0x80) != 0; 00356 return (byte)value; 00357 } 00358 00359 static void DEX() 00360 { 00361 X = DEC(X); 00362 } 00363 00364 static void DEY() 00365 { 00366 Y = DEC(Y); 00367 } 00368 00369 static void NOP() 00370 { 00371 } 00372 00373 static void TXA() 00374 { 00375 SetReg(&A, X); 00376 } 00377 00378 static void TAX() 00379 { 00380 SetReg(&X, A); 00381 } 00382 00383 static void TYA() 00384 { 00385 SetReg(&A, Y); 00386 } 00387 00388 static void TAY() 00389 { 00390 SetReg(&Y, A); 00391 } 00392 00393 static void TXS() 00394 { 00395 S = X; 00396 } 00397 00398 static void TSX() 00399 { 00400 SetReg(&X, S); 00401 } 00402 00403 static ushort GetBR(ushort addr, bool *p_conditional, byte *p_bytes) 00404 { 00405 *p_conditional = true; 00406 *p_bytes = 2; 00407 sbyte offset = (sbyte)GetMemory((ushort)(addr + 1)); 00408 ushort addr2 = (ushort)(addr + 2 + offset); 00409 return addr2; 00410 } 00411 00412 static void BR(bool branch, ushort *p_addr, bool *p_conditional, byte *p_bytes) 00413 { 00414 ushort addr2 = GetBR(*p_addr, p_conditional, p_bytes); 00415 if (branch) 00416 { 00417 *p_addr = addr2; 00418 *p_bytes = 0; // don't advance addr 00419 } 00420 } 00421 00422 static void BPL(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00423 { 00424 BR(!N, p_addr, p_conditional, p_bytes); 00425 } 00426 00427 static void BMI(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00428 { 00429 BR(N, p_addr, p_conditional, p_bytes); 00430 } 00431 00432 static void BCC(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00433 { 00434 BR(!C, p_addr, p_conditional, p_bytes); 00435 } 00436 00437 static void BCS(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00438 { 00439 BR(C, p_addr, p_conditional, p_bytes); 00440 } 00441 00442 static void BVC(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00443 { 00444 BR(!V, p_addr, p_conditional, p_bytes); 00445 } 00446 00447 static void BVS(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00448 { 00449 BR(V, p_addr, p_conditional, p_bytes); 00450 } 00451 00452 static void BNE(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00453 { 00454 BR(!Z, p_addr, p_conditional, p_bytes); 00455 } 00456 00457 static void BEQ(ushort *p_addr, bool *p_conditional, byte *p_bytes) 00458 { 00459 BR(Z, p_addr, p_conditional, p_bytes); 00460 } 00461 00462 static void JSR(ushort *p_addr, byte *p_bytes) 00463 { 00464 *p_bytes = 3; // for next calculation 00465 ushort addr2 = (ushort)(*p_addr + *p_bytes - 1); 00466 ushort addr3 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); 00467 Push(HI(addr2)); 00468 Push(LO(addr2)); 00469 *p_addr = addr3; 00470 *p_bytes = 0; // addr already changed 00471 } 00472 00473 static void RTS(ushort *p_addr, byte *p_bytes) 00474 { 00475 byte lo = Pop(); 00476 byte hi = Pop(); 00477 *p_bytes = 1; // make sure caller increases addr by one 00478 *p_addr = (ushort)((hi << 8) | lo); 00479 } 00480 00481 static void RTI(ushort *p_addr, byte *p_bytes) 00482 { 00483 PLP(); 00484 byte lo = Pop(); 00485 byte hi = Pop(); 00486 *p_bytes = 0; // make sure caller does not increase addr by one 00487 *p_addr = (ushort)((hi << 8) | lo); 00488 } 00489 00490 static void BRK(byte *p_bytes) 00491 { 00492 ++PC; 00493 Push(HI(PC)); 00494 Push(LO(PC)); 00495 PHP(); 00496 B = true; 00497 PC = (ushort)(GetMemory(0xFFFE) + (GetMemory(0xFFFF) << 8)); // JMP(IRQ) 00498 *p_bytes = 0; 00499 } 00500 00501 static void JMP(ushort *p_addr, byte *p_bytes) 00502 { 00503 *p_bytes = 0; // caller should not advance address 00504 ushort addr2 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); 00505 *p_addr = addr2; 00506 } 00507 00508 static void JMPIND(ushort *p_addr, byte *p_bytes) 00509 { 00510 *p_bytes = 0; // caller should not advance address 00511 ushort addr2 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); 00512 ushort addr3; 00513 if ((addr2 & 0xFF) == 0xFF) // JMP($XXFF) won't go over page boundary 00514 addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 - 0xFF)) << 8)); // 6502 "bug" - will use XXFF and XX00 as source of address 00515 else 00516 addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)); 00517 *p_addr = addr3; 00518 } 00519 00520 // "A:FF X:FF Y:FF S:FF P:XX-XXXXX" 00521 static void GetDisplayState(char *state, int state_size) 00522 { 00523 snprintf(state, state_size, "A:%02X X:%02X Y:%02X S:%02X P:%c%c-%c%c%c%c%c", 00524 A, 00525 X, 00526 Y, 00527 S, 00528 N ? 'N' : ' ', 00529 V ? 'V' : ' ', 00530 B ? 'B' : ' ', 00531 D ? 'D' : ' ', 00532 I ? 'I' : ' ', 00533 Z ? 'Z' : ' ', 00534 C ? 'C' : ' ' 00535 ); 00536 } 00537 00538 static byte GetIndX(ushort addr, byte *p_bytes) 00539 { 00540 *p_bytes = 2; 00541 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) + X); 00542 return GetMemory((ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8))); 00543 } 00544 00545 static void SetIndX(byte value, ushort addr, byte *p_bytes) 00546 { 00547 *p_bytes = 2; 00548 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) + X); 00549 ushort addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)); 00550 SetMemory(addr3, value); 00551 } 00552 00553 static byte GetIndY(ushort addr, byte *p_bytes) 00554 { 00555 *p_bytes = 2; 00556 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1))); 00557 ushort addr3 = (ushort)((GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)) + Y); 00558 return GetMemory(addr3); 00559 } 00560 00561 static void SetIndY(byte value, ushort addr, byte *p_bytes) 00562 { 00563 *p_bytes = 2; 00564 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1))); 00565 ushort addr3 = (ushort)((GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)) + Y); 00566 SetMemory(addr3, value); 00567 } 00568 00569 static byte GetZP(ushort addr, byte *p_bytes) 00570 { 00571 *p_bytes = 2; 00572 ushort addr2 = GetMemory((ushort)(addr + 1)); 00573 return GetMemory(addr2); 00574 } 00575 00576 static void SetZP(byte value, ushort addr, byte *p_bytes) 00577 { 00578 *p_bytes = 2; 00579 ushort addr2 = GetMemory((ushort)(addr + 1)); 00580 SetMemory(addr2, value); 00581 } 00582 00583 static byte GetZPX(ushort addr, byte *p_bytes) 00584 { 00585 *p_bytes = 2; 00586 ushort addr2 = GetMemory((ushort)(addr + 1)); 00587 return GetMemory((byte)(addr2 + X)); 00588 } 00589 00590 static void SetZPX(byte value, ushort addr, byte *p_bytes) 00591 { 00592 *p_bytes = 2; 00593 ushort addr2 = GetMemory((ushort)(addr + 1)); 00594 SetMemory((byte)(addr2 + X), value); 00595 } 00596 00597 static byte GetZPY(ushort addr, byte *p_bytes) 00598 { 00599 *p_bytes = 2; 00600 ushort addr2 = GetMemory((ushort)(addr + 1)); 00601 return GetMemory((byte)(addr2 + Y)); 00602 } 00603 00604 static void SetZPY(byte value, ushort addr, byte *p_bytes) 00605 { 00606 *p_bytes = 2; 00607 ushort addr2 = GetMemory((ushort)(addr + 1)); 00608 SetMemory((byte)(addr2 + Y), value); 00609 } 00610 00611 static byte GetABS(ushort addr, byte *p_bytes) 00612 { 00613 *p_bytes = 3; 00614 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00615 return GetMemory(addr2); 00616 } 00617 00618 static void SetABS(byte value, ushort addr, byte *p_bytes) 00619 { 00620 *p_bytes = 3; 00621 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00622 SetMemory(addr2, value); 00623 } 00624 00625 static byte GetABSX(ushort addr, byte *p_bytes) 00626 { 00627 *p_bytes = 3; 00628 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00629 return GetMemory((ushort)(addr2 + X)); 00630 } 00631 00632 static void SetABSX(byte value, ushort addr, byte *p_bytes) 00633 { 00634 *p_bytes = 3; 00635 ushort addr2 = (ushort)((GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)) + X); 00636 SetMemory(addr2, value); 00637 } 00638 00639 static byte GetABSY(ushort addr, byte *p_bytes) 00640 { 00641 *p_bytes = 3; 00642 ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00643 return GetMemory((ushort)(addr2 + Y)); 00644 } 00645 00646 static void SetABSY(byte value, ushort addr, byte *p_bytes) 00647 { 00648 *p_bytes = 3; 00649 ushort addr2 = (ushort)((GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)) + Y); 00650 SetMemory(addr2, value); 00651 } 00652 00653 static byte GetIM(ushort addr, byte *p_bytes) 00654 { 00655 *p_bytes = 2; 00656 return GetMemory((ushort)(addr + 1)); 00657 } 00658 00659 extern void Execute(ushort addr, bool (*ExecutePatch)(void)) 00660 { 00661 bool conditional; 00662 byte bytes; 00663 00664 #if (USE_IRQ == 1) 00665 // IRQ support 00666 Timer timer; 00667 const double interrupt_time = 1.0 / 60.0 ; // 60 times per second 00668 timer.start(); 00669 double timer_then = timer.read(); 00670 #endif 00671 00672 PC = addr; 00673 00674 while (true) 00675 { 00676 while (true) 00677 { 00678 #if (USE_IRQ == 1) 00679 if (!I && (timer.read()-timer_then) >= interrupt_time) // IRQ 00680 { 00681 timer_then = timer.read(); // reset timer 00682 Push(HI(PC)); 00683 Push(LO(PC)); 00684 PHP(); 00685 I = true; 00686 PC = (GetMemory(0xfffe) | (GetMemory(0xffff) << 8)); 00687 } 00688 else 00689 #endif 00690 { 00691 bytes = 1; 00692 bool breakpoint = false; 00693 //if (Breakpoints.Contains(PC)) 00694 // breakpoint = true; 00695 if (trace || breakpoint || step) 00696 { 00697 ushort addr2; 00698 char line[27]; 00699 char dis[13]; 00700 DisassembleLong(PC, &conditional, &bytes, &addr2, dis, sizeof(dis), line, sizeof(line)); 00701 char state[33]; 00702 GetDisplayState(state, sizeof(state)); 00703 char full_line[80]; 00704 snprintf(full_line, sizeof(full_line), "%-30s%s\n", line, state); 00705 #ifdef WIN32 00706 OutputDebugStringA(full_line); 00707 #else 00708 pc.printf("%s", full_line); 00709 #endif 00710 if (step) 00711 step = step; // user can put debug breakpoint here to allow stepping 00712 if (breakpoint) 00713 breakpoint = breakpoint; // user can put debug breakpoint here to allow break 00714 } 00715 if (ExecutePatch != 0 && !ExecutePatch()) // allow execute to be overriden at a specific address 00716 break; 00717 } 00718 } 00719 00720 switch (GetMemory(PC)) 00721 { 00722 case 0x00: BRK(&bytes); break; 00723 case 0x01: ORA(GetIndX(PC, &bytes)); break; 00724 case 0x05: ORA(GetZP(PC, &bytes)); break; 00725 case 0x06: SetZP(ASL(GetZP(PC, &bytes)), PC, &bytes); break; 00726 case 0x08: PHP(); break; 00727 case 0x09: ORA(GetIM(PC, &bytes)); break; 00728 case 0x0A: SetA(ASL(A)); break; 00729 case 0x0D: ORA(GetABS(PC, &bytes)); break; 00730 case 0x0E: SetABS(ASL(GetABS(PC, &bytes)), PC, &bytes); break; 00731 00732 case 0x10: BPL(&PC, &conditional, &bytes); break; 00733 case 0x11: ORA(GetIndY(PC, &bytes)); break; 00734 case 0x15: ORA(GetZPX(PC, &bytes)); break; 00735 case 0x16: SetZPX(ASL(GetZPX(PC, &bytes)), PC, &bytes); break; 00736 case 0x18: CLC(); break; 00737 case 0x19: ORA(GetABSY(PC, &bytes)); break; 00738 case 0x1D: ORA(GetABSX(PC, &bytes)); break; 00739 case 0x1E: SetABSX(ASL(GetABSX(PC, &bytes)), PC, &bytes); break; 00740 00741 case 0x20: JSR(&PC, &bytes); break; 00742 case 0x21: AND(GetIndX(PC, &bytes)); break; 00743 case 0x24: BIT_OP(GetZP(PC, &bytes)); break; 00744 case 0x25: AND(GetZP(PC, &bytes)); break; 00745 case 0x26: SetZP(ROL(GetZP(PC, &bytes)), PC, &bytes); break; 00746 case 0x28: PLP(); break; 00747 case 0x29: AND(GetIM(PC, &bytes)); break; 00748 case 0x2A: SetA(ROL(A)); break; 00749 case 0x2C: BIT_OP(GetABS(PC, &bytes)); break; 00750 case 0x2D: AND(GetABS(PC, &bytes)); break; 00751 case 0x2E: ROL(GetABS(PC, &bytes)); break; 00752 00753 case 0x30: BMI(&PC, &conditional, &bytes); break; 00754 case 0x31: AND(GetIndY(PC, &bytes)); break; 00755 case 0x35: AND(GetZPX(PC, &bytes)); break; 00756 case 0x36: SetZPX(ROL(GetZPX(PC, &bytes)), PC, &bytes); break; 00757 case 0x38: SEC(); break; 00758 case 0x39: AND(GetABSY(PC, &bytes)); break; 00759 case 0x3D: AND(GetABSX(PC, &bytes)); break; 00760 case 0x3E: SetABSX(ROL(GetABSX(PC, &bytes)), PC, &bytes); break; 00761 00762 case 0x40: RTI(&PC, &bytes); break; 00763 case 0x41: EOR(GetIndX(PC, &bytes)); break; 00764 case 0x45: EOR(GetZP(PC, &bytes)); break; 00765 case 0x46: SetZP(LSR(GetZP(PC, &bytes)), PC, &bytes); break; 00766 case 0x48: PHA(); break; 00767 case 0x49: EOR(GetIM(PC, &bytes)); break; 00768 case 0x4A: SetA(LSR(A)); break; 00769 case 0x4C: JMP(&PC, &bytes); break; 00770 case 0x4D: EOR(GetABS(PC, &bytes)); break; 00771 case 0x4E: LSR(GetABS(PC, &bytes)); break; 00772 00773 case 0x50: BVC(&PC, &conditional, &bytes); break; 00774 case 0x51: EOR(GetIndY(PC, &bytes)); break; 00775 case 0x55: EOR(GetZPX(PC, &bytes)); break; 00776 case 0x56: SetZPX(LSR(GetZPX(PC, &bytes)), PC, &bytes); break; 00777 case 0x58: CLI(); break; 00778 case 0x59: EOR(GetABSY(PC, &bytes)); break; 00779 case 0x5D: EOR(GetABSX(PC, &bytes)); break; 00780 case 0x5E: SetABSX(LSR(GetABSX(PC, &bytes)), PC, &bytes); break; 00781 00782 case 0x60: RTS(&PC, &bytes); break; 00783 case 0x61: ADC_OP(GetIndX(PC, &bytes)); break; 00784 case 0x65: ADC_OP(GetZP(PC, &bytes)); break; 00785 case 0x66: SetZP(ROR(GetZP(PC, &bytes)), PC, &bytes); break; 00786 case 0x68: PLA(); break; 00787 case 0x69: ADC_OP(GetIM(PC, &bytes)); break; 00788 case 0x6A: SetA(ROR(A)); break; 00789 case 0x6C: JMPIND(&PC, &bytes); break; 00790 case 0x6D: ADC_OP(GetABS(PC, &bytes)); break; 00791 case 0x6E: SetABS(ROR(GetABS(PC, &bytes)), PC, &bytes); break; 00792 00793 case 0x70: BVS(&PC, &conditional, &bytes); break; 00794 case 0x71: ADC_OP(GetIndY(PC, &bytes)); break; 00795 case 0x75: ADC_OP(GetZPX(PC, &bytes)); break; 00796 case 0x76: SetZPX(ROR(GetZPX(PC, &bytes)), PC, &bytes); break; 00797 case 0x78: SEI(); break; 00798 case 0x79: ADC_OP(GetABSY(PC, &bytes)); break; 00799 case 0x7D: ADC_OP(GetABSX(PC, &bytes)); break; 00800 case 0x7E: SetABSX(ROR(GetABSX(PC, &bytes)), PC, &bytes); break; 00801 00802 case 0x81: SetIndX(A, PC, &bytes); break; 00803 case 0x84: SetZP(Y, PC, &bytes); break; 00804 case 0x85: SetZP(A, PC, &bytes); break; 00805 case 0x86: SetZP(X, PC, &bytes); break; 00806 case 0x88: DEY(); break; 00807 case 0x8A: TXA(); break; 00808 case 0x8C: SetABS(Y, PC, &bytes); break; 00809 case 0x8D: SetABS(A, PC, &bytes); break; 00810 case 0x8E: SetABS(X, PC, &bytes); break; 00811 00812 case 0x90: BCC(&PC, &conditional, &bytes); break; 00813 case 0x91: SetIndY(A, PC, &bytes); break; 00814 case 0x94: SetZPX(Y, PC, &bytes); break; 00815 case 0x95: SetZPX(A, PC, &bytes); break; 00816 case 0x96: SetZPY(X, PC, &bytes); break; 00817 case 0x98: TYA(); break; 00818 case 0x99: SetABSY(A, PC, &bytes); break; 00819 case 0x9A: TXS(); break; 00820 case 0x9D: SetABSX(A, PC, &bytes); break; 00821 00822 case 0xA0: SetY(GetIM(PC, &bytes)); break; 00823 case 0xA1: SetA(GetIndX(PC, &bytes)); break; 00824 case 0xA2: SetX(GetIM(PC, &bytes)); break; 00825 case 0xA4: SetY(GetZP(PC, &bytes)); break; 00826 case 0xA5: SetA(GetZP(PC, &bytes)); break; 00827 case 0xA6: SetX(GetZP(PC, &bytes)); break; 00828 case 0xA8: TAY(); break; 00829 case 0xA9: SetA(GetIM(PC, &bytes)); break; 00830 case 0xAA: TAX(); break; 00831 case 0xAC: SetY(GetABS(PC, &bytes)); break; 00832 case 0xAD: SetA(GetABS(PC, &bytes)); break; 00833 case 0xAE: SetX(GetABS(PC, &bytes)); break; 00834 00835 case 0xB0: BCS(&PC, &conditional, &bytes); break; 00836 case 0xB1: SetA(GetIndY(PC, &bytes)); break; 00837 case 0xB4: SetY(GetZPX(PC, &bytes)); break; 00838 case 0xB5: SetA(GetZPX(PC, &bytes)); break; 00839 case 0xB6: SetX(GetZPY(PC, &bytes)); break; 00840 case 0xB8: CLV(); break; 00841 case 0xB9: SetA(GetABSY(PC, &bytes)); break; 00842 case 0xBA: TSX(); break; 00843 case 0xBC: SetY(GetABSX(PC, &bytes)); break; 00844 case 0xBD: SetA(GetABSX(PC, &bytes)); break; 00845 case 0xBE: SetX(GetABSY(PC, &bytes)); break; 00846 00847 case 0xC0: CPY(GetIM(PC, &bytes)); break; 00848 case 0xC1: CMP(GetIndX(PC, &bytes)); break; 00849 case 0xC4: CPY(GetZP(PC, &bytes)); break; 00850 case 0xC5: CMP(GetZP(PC, &bytes)); break; 00851 case 0xC6: SetZP(DEC(GetZP(PC, &bytes)), PC, &bytes); break; 00852 case 0xC8: INY(); break; 00853 case 0xC9: CMP(GetIM(PC, &bytes)); break; 00854 case 0xCA: DEX(); break; 00855 case 0xCC: CPY(GetABS(PC, &bytes)); break; 00856 case 0xCD: CMP(GetABS(PC, &bytes)); break; 00857 case 0xCE: SetABS(DEC(GetABS(PC, &bytes)), PC, &bytes); break; 00858 00859 case 0xD0: BNE(&PC, &conditional, &bytes); break; 00860 case 0xD1: CMP(GetIndY(PC, &bytes)); break; 00861 case 0xD5: CMP(GetZPX(PC, &bytes)); break; 00862 case 0xD6: SetZPX(DEC(GetZPX(PC, &bytes)), PC, &bytes); break; 00863 case 0xD8: CLD(); break; 00864 case 0xD9: CMP(GetABSY(PC, &bytes)); break; 00865 case 0xDD: CMP(GetABSX(PC, &bytes)); break; 00866 case 0xDE: SetABSX(DEC(GetABSX(PC, &bytes)), PC, &bytes); break; 00867 00868 case 0xE0: CPX(GetIM(PC, &bytes)); break; 00869 case 0xE1: SBC(GetIndX(PC, &bytes)); break; 00870 case 0xE4: CPX(GetZP(PC, &bytes)); break; 00871 case 0xE5: SBC(GetZP(PC, &bytes)); break; 00872 case 0xE6: SetZP(INC(GetZP(PC, &bytes)), PC, &bytes); break; 00873 case 0xE8: INX(); break; 00874 case 0xE9: SBC(GetIM(PC, &bytes)); break; 00875 case 0xEA: NOP(); break; 00876 case 0xEC: CPX(GetABS(PC, &bytes)); break; 00877 case 0xED: SBC(GetABS(PC, &bytes)); break; 00878 case 0xEE: SetABS(INC(GetABS(PC, &bytes)), PC, &bytes); break; 00879 00880 case 0xF0: BEQ(&PC, &conditional, &bytes); break; 00881 case 0xF1: SBC(GetIndY(PC, &bytes)); break; 00882 case 0xF5: SBC(GetZPX(PC, &bytes)); break; 00883 case 0xF6: SetZPX(INC(GetZPX(PC, &bytes)), PC, &bytes); break; 00884 case 0xF8: SED(); break; 00885 case 0xF9: SBC(GetABSY(PC, &bytes)); break; 00886 case 0xFD: SBC(GetABSX(PC, &bytes)); break; 00887 case 0xFE: SetABSX(INC(GetABSX(PC, &bytes)), PC, &bytes); break; 00888 00889 default: 00890 { 00891 printf("Invalid opcode %02X at %04X", GetMemory(PC), PC); 00892 exit(1); 00893 } 00894 } 00895 00896 PC += bytes; 00897 } 00898 } 00899 00900 // Examples: 00901 // FFFF FF FF FF JMP ($FFFF) 00902 // FFFF FF FF FF LDA $FFFF,X 00903 extern void DisassembleLong(ushort addr, bool *p_conditional, byte *p_bytes, ushort *p_addr2, char *dis, int dis_size, char *line, int line_size) 00904 { 00905 DisassembleShort(addr, p_conditional, p_bytes, p_addr2, dis, dis_size); 00906 snprintf(line, line_size, "%04X ", addr); 00907 for (int i = 0; i < 3; ++i) 00908 { 00909 if (i < *p_bytes) 00910 snprintf(line+strlen(line), line_size-strlen(line), "%02X ", GetMemory((ushort)(addr + i))); 00911 else 00912 strcat_s(line, line_size, " "); 00913 } 00914 strcat_s(line, line_size, dis); 00915 } 00916 00917 static void Ind(char *dis, int dis_size, char* opcode, ushort addr, ushort *p_addr2, byte *p_bytes) 00918 { 00919 *p_bytes = 3; 00920 ushort addr1 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00921 *p_addr2 = (ushort)(GetMemory(addr1) | (GetMemory((ushort)(addr1 + 1)) << 8)); 00922 snprintf(dis, dis_size, "%s ($%0X4)", opcode, addr1); 00923 } 00924 00925 static void IndX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00926 { 00927 *p_bytes = 2; 00928 snprintf(dis, dis_size, "%s ($%02X,X)", opcode, GetMemory((ushort)(addr + 1))); 00929 } 00930 00931 static void IndY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00932 { 00933 *p_bytes = 2; 00934 snprintf(dis, dis_size, "%s ($%02X),Y", opcode, GetMemory((ushort)(addr + 1))); 00935 } 00936 00937 static void ZP(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00938 { 00939 *p_bytes = 2; 00940 snprintf(dis, dis_size, "%s $%02X", opcode, GetMemory((ushort)(addr + 1))); 00941 } 00942 00943 static void ZPX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00944 { 00945 *p_bytes = 2; 00946 snprintf(dis, dis_size, "%s $%02X,X", opcode, GetMemory((ushort)(addr + 1))); 00947 } 00948 00949 static void ZPY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00950 { 00951 *p_bytes = 2; 00952 snprintf(dis, dis_size, "%s $%02X,Y", opcode, GetMemory((ushort)(addr + 1))); 00953 } 00954 00955 static void ABS(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00956 { 00957 *p_bytes = 3; 00958 snprintf(dis, dis_size, "%s $%04X", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00959 } 00960 00961 static void ABSAddr(char *dis, int dis_size, char* opcode, ushort addr, ushort *p_addr2, byte *p_bytes) 00962 { 00963 *p_bytes = 3; 00964 *p_addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00965 snprintf(dis, dis_size, "%s $%04X", opcode, *p_addr2); 00966 } 00967 00968 static void ABSX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00969 { 00970 *p_bytes = 3; 00971 snprintf(dis, dis_size, "%s $%04X,X", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00972 } 00973 00974 static void ABSY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00975 { 00976 *p_bytes = 3; 00977 snprintf(dis, dis_size, "%s $%04X,Y", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); 00978 } 00979 00980 static void IM(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) 00981 { 00982 *p_bytes = 2; 00983 snprintf(dis, dis_size, "%s #$%02X", opcode, GetMemory((ushort)(addr + 1))); 00984 } 00985 00986 static void BRX(char *dis, int dis_size, char* opcode, ushort addr, bool *p_conditional, ushort *p_addr2, byte *p_bytes) 00987 { 00988 *p_bytes = 2; 00989 *p_conditional = true; 00990 sbyte offset = (sbyte)GetMemory((ushort)(addr + 1)); 00991 *p_addr2 = (ushort)(addr + 2 + offset); 00992 snprintf(dis, dis_size, "%s $%04X", opcode, *p_addr2); 00993 } 00994 00995 // JMP ($FFFF) 00996 // LDA $FFFF,X 00997 extern void DisassembleShort(ushort addr, bool *p_conditional, byte *p_bytes, ushort *p_addr2, char *dis, int dis_size) 00998 { 00999 *p_conditional = false; 01000 *p_addr2 = 0; 01001 *p_bytes = 1; 01002 01003 switch (GetMemory(addr)) 01004 { 01005 case 0x00: strcpy_s(dis, dis_size, "BRK"); return; 01006 case 0x01: IndX(dis, dis_size, "ORA", addr, p_bytes); return; 01007 case 0x05: ZP(dis, dis_size, "ORA", addr, p_bytes); return; 01008 case 0x06: ZP(dis, dis_size, "ASL", addr, p_bytes); return; 01009 case 0x08: strcpy_s(dis, dis_size, "PHP"); return; 01010 case 0x09: IM(dis, dis_size, "ORA", addr, p_bytes); return; 01011 case 0x0A: strcpy_s(dis, dis_size, "ASL A"); return; 01012 case 0x0D: ABS(dis, dis_size, "ORA", addr, p_bytes); return; 01013 case 0x0E: ABS(dis, dis_size, "ASL", addr, p_bytes); return; 01014 01015 case 0x10: BRX(dis, dis_size, "BPL", addr, p_conditional, p_addr2, p_bytes); return; 01016 case 0x11: IndY(dis, dis_size, "ORA", addr, p_bytes); return; 01017 case 0x15: ZPX(dis, dis_size, "ORA", addr, p_bytes); return; 01018 case 0x16: ZPX(dis, dis_size, "ASL", addr, p_bytes); return; 01019 case 0x18: strcpy_s(dis, dis_size, "CLC"); return; 01020 case 0x19: ABSY(dis, dis_size, "ORA", addr, p_bytes); return; 01021 case 0x1D: ABSX(dis, dis_size, "ORA", addr, p_bytes); return; 01022 case 0x1E: ABSX(dis, dis_size, "ASL", addr, p_bytes); return; 01023 01024 case 0x20: ABSAddr(dis, dis_size, "JSR", addr, p_addr2, p_bytes); return; 01025 case 0x21: IndX(dis, dis_size, "AND", addr, p_bytes); return; 01026 case 0x24: ZP(dis, dis_size, "BIT", addr, p_bytes); return; 01027 case 0x25: ZP(dis, dis_size, "AND", addr, p_bytes); return; 01028 case 0x26: ZP(dis, dis_size, "ROL", addr, p_bytes); return; 01029 case 0x28: strcpy_s(dis, dis_size, "PLP"); return; 01030 case 0x29: IM(dis, dis_size, "AND", addr, p_bytes); return; 01031 case 0x2A: strcpy_s(dis, dis_size, "ROL A"); return; 01032 case 0x2C: ABS(dis, dis_size, "BIT", addr, p_bytes); return; 01033 case 0x2D: ABS(dis, dis_size, "AND", addr, p_bytes); return; 01034 case 0x2E: ABS(dis, dis_size, "ROL", addr, p_bytes); return; 01035 01036 case 0x30: BRX(dis, dis_size, "BMI", addr, p_conditional, p_addr2, p_bytes); return; 01037 case 0x31: IndY(dis, dis_size, "AND", addr, p_bytes); return; 01038 case 0x35: ZPX(dis, dis_size, "AND", addr, p_bytes); return; 01039 case 0x36: ZPX(dis, dis_size, "ROL", addr, p_bytes); return; 01040 case 0x38: strcpy_s(dis, dis_size, "SEC"); return; 01041 case 0x39: ABSY(dis, dis_size, "AND", addr, p_bytes); return; 01042 case 0x3D: ABSX(dis, dis_size, "AND", addr, p_bytes); return; 01043 case 0x3E: ABSX(dis, dis_size, "ROL", addr, p_bytes); return; 01044 01045 case 0x40: strcpy_s(dis, dis_size, "RTI"); return; 01046 case 0x41: IndX(dis, dis_size, "EOR", addr, p_bytes); return; 01047 case 0x45: ZP(dis, dis_size, "EOR", addr, p_bytes); return; 01048 case 0x46: ZP(dis, dis_size, "LSR", addr, p_bytes); return; 01049 case 0x48: strcpy_s(dis, dis_size, "PHA"); return; 01050 case 0x49: IM(dis, dis_size, "EOR", addr, p_bytes); return; 01051 case 0x4A: strcpy_s(dis, dis_size, "LSR A"); return; 01052 case 0x4C: ABSAddr(dis, dis_size, "JMP", addr, p_addr2, p_bytes); return; 01053 case 0x4D: ABS(dis, dis_size, "EOR", addr, p_bytes); return; 01054 case 0x4E: ABS(dis, dis_size, "LSR", addr, p_bytes); return; 01055 01056 case 0x50: BRX(dis, dis_size, "BVC", addr, p_conditional, p_addr2, p_bytes); return; 01057 case 0x51: IndY(dis, dis_size, "EOR", addr, p_bytes); return; 01058 case 0x55: ZPX(dis, dis_size, "EOR", addr, p_bytes); return; 01059 case 0x56: ZPX(dis, dis_size, "LSR", addr, p_bytes); return; 01060 case 0x58: strcpy_s(dis, dis_size, "CLI"); return; 01061 case 0x59: ABSY(dis, dis_size, "EOR", addr, p_bytes); return; 01062 case 0x5D: ABSX(dis, dis_size, "EOR", addr, p_bytes); return; 01063 case 0x5E: ABSX(dis, dis_size, "LSR", addr, p_bytes); return; 01064 01065 case 0x60: strcpy_s(dis, dis_size, "RTS"); return; 01066 case 0x61: IndX(dis, dis_size, "ADC", addr, p_bytes); return; 01067 case 0x65: ZP(dis, dis_size, "ADC", addr, p_bytes); return; 01068 case 0x66: ZP(dis, dis_size, "ROR", addr, p_bytes); return; 01069 case 0x68: strcpy_s(dis, dis_size, "PLA"); return; 01070 case 0x69: IM(dis, dis_size, "ADC", addr, p_bytes); return; 01071 case 0x6A: strcpy_s(dis, dis_size, "ROR A"); return; 01072 case 0x6C: Ind(dis, dis_size, "JMP", addr, p_addr2, p_bytes); return; 01073 case 0x6D: ABS(dis, dis_size, "ADC", addr, p_bytes); return; 01074 case 0x6E: ABS(dis, dis_size, "ROR", addr, p_bytes); return; 01075 01076 case 0x70: BRX(dis, dis_size, "BVS", addr, p_conditional, p_addr2, p_bytes); return; 01077 case 0x71: IndY(dis, dis_size, "ADC", addr, p_bytes); return; 01078 case 0x75: ZPX(dis, dis_size, "ADC", addr, p_bytes); return; 01079 case 0x76: ZPX(dis, dis_size, "ROR", addr, p_bytes); return; 01080 case 0x78: strcpy_s(dis, dis_size, "SEI"); return; 01081 case 0x79: ABSY(dis, dis_size, "ADC", addr, p_bytes); return; 01082 case 0x7D: ABSX(dis, dis_size, "ADC", addr, p_bytes); return; 01083 case 0x7E: ABSX(dis, dis_size, "ROR", addr, p_bytes); return; 01084 01085 case 0x81: IndX(dis, dis_size, "STA", addr, p_bytes); return; 01086 case 0x84: ZP(dis, dis_size, "STY", addr, p_bytes); return; 01087 case 0x85: ZP(dis, dis_size, "STA", addr, p_bytes); return; 01088 case 0x86: ZP(dis, dis_size, "STX", addr, p_bytes); return; 01089 case 0x88: strcpy_s(dis, dis_size, "DEY"); return; 01090 case 0x8A: strcpy_s(dis, dis_size, "TXA"); return; 01091 case 0x8C: ABS(dis, dis_size, "STY", addr, p_bytes); return; 01092 case 0x8D: ABS(dis, dis_size, "STA", addr, p_bytes); return; 01093 case 0x8E: ABS(dis, dis_size, "STX", addr, p_bytes); return; 01094 01095 case 0x90: BRX(dis, dis_size, "BCC", addr, p_conditional, p_addr2, p_bytes); return; 01096 case 0x91: IndY(dis, dis_size, "STA", addr, p_bytes); return; 01097 case 0x94: ZPX(dis, dis_size, "STY", addr, p_bytes); return; 01098 case 0x95: ZPX(dis, dis_size, "STA", addr, p_bytes); return; 01099 case 0x96: ZPY(dis, dis_size, "STX", addr, p_bytes); return; 01100 case 0x98: strcpy_s(dis, dis_size, "TYA"); return; 01101 case 0x99: ABSY(dis, dis_size, "STA", addr, p_bytes); return; 01102 case 0x9A: strcpy_s(dis, dis_size, "TXS"); return; 01103 case 0x9D: ABSX(dis, dis_size, "STA", addr, p_bytes); return; 01104 01105 case 0xA0: IM(dis, dis_size, "LDY", addr, p_bytes); return; 01106 case 0xA1: IndX(dis, dis_size, "LDA", addr, p_bytes); return; 01107 case 0xA2: IM(dis, dis_size, "LDX", addr, p_bytes); return; 01108 case 0xA4: ZP(dis, dis_size, "LDY", addr, p_bytes); return; 01109 case 0xA5: ZP(dis, dis_size, "LDA", addr, p_bytes); return; 01110 case 0xA6: ZP(dis, dis_size, "LDX", addr, p_bytes); return; 01111 case 0xA8: strcpy_s(dis, dis_size, "TAY"); return; 01112 case 0xA9: IM(dis, dis_size, "LDA", addr, p_bytes); return; 01113 case 0xAA: strcpy_s(dis, dis_size, "TAX"); return; 01114 case 0xAC: ABS(dis, dis_size, "LDY", addr, p_bytes); return; 01115 case 0xAD: ABS(dis, dis_size, "LDA", addr, p_bytes); return; 01116 case 0xAE: ABS(dis, dis_size, "LDX", addr, p_bytes); return; 01117 01118 case 0xB0: BRX(dis, dis_size, "BCS", addr, p_conditional, p_addr2, p_bytes); return; 01119 case 0xB1: IndY(dis, dis_size, "LDA", addr, p_bytes); return; 01120 case 0xB4: ZPX(dis, dis_size, "LDY", addr, p_bytes); return; 01121 case 0xB5: ZPX(dis, dis_size, "LDA", addr, p_bytes); return; 01122 case 0xB6: ZPY(dis, dis_size, "LDX", addr, p_bytes); return; 01123 case 0xB8: strcpy_s(dis, dis_size, "CLV"); return; 01124 case 0xB9: ABSY(dis, dis_size, "LDA", addr, p_bytes); return; 01125 case 0xBA: strcpy_s(dis, dis_size, "TSX"); return; 01126 case 0xBC: ABSX(dis, dis_size, "LDY", addr, p_bytes); return; 01127 case 0xBD: ABSX(dis, dis_size, "LDA", addr, p_bytes); return; 01128 case 0xBE: ABSY(dis, dis_size, "LDX", addr, p_bytes); return; 01129 01130 case 0xC0: IM(dis, dis_size, "CPY", addr, p_bytes); return; 01131 case 0xC1: IndX(dis, dis_size, "CMP", addr, p_bytes); return; 01132 case 0xC4: ZP(dis, dis_size, "CPY", addr, p_bytes); return; 01133 case 0xC5: ZP(dis, dis_size, "CMP", addr, p_bytes); return; 01134 case 0xC6: ZP(dis, dis_size, "DEC", addr, p_bytes); return; 01135 case 0xC8: strcpy_s(dis, dis_size, "INY"); return; 01136 case 0xC9: IM(dis, dis_size, "CMP", addr, p_bytes); return; 01137 case 0xCA: strcpy_s(dis, dis_size, "DEX"); return; 01138 case 0xCC: ABS(dis, dis_size, "CPY", addr, p_bytes); return; 01139 case 0xCD: ABS(dis, dis_size, "CMP", addr, p_bytes); return; 01140 case 0xCE: ABS(dis, dis_size, "DEC", addr, p_bytes); return; 01141 01142 case 0xD0: BRX(dis, dis_size, "BNE", addr, p_conditional, p_addr2, p_bytes); return; 01143 case 0xD1: IndY(dis, dis_size, "CMP", addr, p_bytes); return; 01144 case 0xD5: ZPX(dis, dis_size, "CMP", addr, p_bytes); return; 01145 case 0xD6: ZPX(dis, dis_size, "DEC", addr, p_bytes); return; 01146 case 0xD8: strcpy_s(dis, dis_size, "CLD"); return; 01147 case 0xD9: ABSY(dis, dis_size, "CMP", addr, p_bytes); return; 01148 case 0xDD: ABSX(dis, dis_size, "CMP", addr, p_bytes); return; 01149 case 0xDE: ABSX(dis, dis_size, "DEC", addr, p_bytes); return; 01150 01151 case 0xE0: IM(dis, dis_size, "CPX", addr, p_bytes); return; 01152 case 0xE1: IndX(dis, dis_size, "SBC", addr, p_bytes); return; 01153 case 0xE4: ZP(dis, dis_size, "CPX", addr, p_bytes); return; 01154 case 0xE5: ZP(dis, dis_size, "SBC", addr, p_bytes); return; 01155 case 0xE6: ZP(dis, dis_size, "INC", addr, p_bytes); return; 01156 case 0xE8: strcpy_s(dis, dis_size, "INX"); return; 01157 case 0xE9: IM(dis, dis_size, "SBC", addr, p_bytes); return; 01158 case 0xEA: strcpy_s(dis, dis_size, "NOP"); return; 01159 case 0xEC: ABS(dis, dis_size, "CPX", addr, p_bytes); return; 01160 case 0xED: ABS(dis, dis_size, "SBC", addr, p_bytes); return; 01161 case 0xEE: ABS(dis, dis_size, "INC", addr, p_bytes); return; 01162 01163 case 0xF0: BRX(dis, dis_size, "BEQ", addr, p_conditional, p_addr2, p_bytes); return; 01164 case 0xF1: IndY(dis, dis_size, "SBC", addr, p_bytes); return; 01165 case 0xF5: ZPX(dis, dis_size, "SBC", addr, p_bytes); return; 01166 case 0xF6: ZPX(dis, dis_size, "INC", addr, p_bytes); return; 01167 case 0xF8: strcpy_s(dis, dis_size, "SED"); return; 01168 case 0xF9: ABSY(dis, dis_size, "SBC", addr, p_bytes); return; 01169 case 0xFD: ABSX(dis, dis_size, "SBC", addr, p_bytes); return; 01170 case 0xFE: ABSX(dis, dis_size, "INC", addr, p_bytes); return; 01171 01172 default: 01173 strcpy_s(dis, dis_size, "???"); 01174 return; 01175 //throw new Exception(string.Format("Invalid opcode {0:X2}", memory[addr])); 01176 } 01177 }
Generated on Mon Jul 18 2022 22:17:52 by
1.7.2