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