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@5:29115d8441cc, 2020-04-13 (annotated)
- Committer:
- davervw
- Date:
- Mon Apr 13 05:44:17 2020 +0000
- Revision:
- 5:29115d8441cc
- Parent:
- 4:8476be802690
- Child:
- 9:a0c6747e539f
C64 emulation on STM32F429 Discovery board with builtin LCD and USB keyboard support (OTG). More info at davevw.com or github.com/davervw
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
davervw | 4:8476be802690 | 1 | // emu6502.cpp - Emu6502 - MOS6502 Emulator |
davervw | 0:90de1cbc8a5f | 2 | // |
davervw | 0:90de1cbc8a5f | 3 | //////////////////////////////////////////////////////////////////////////////// |
davervw | 0:90de1cbc8a5f | 4 | // |
davervw | 4:8476be802690 | 5 | // C64-stm429_discovery |
davervw | 4:8476be802690 | 6 | // C64/6502 Emulator targeting STM32F429 LCD/USBHOST |
davervw | 4:8476be802690 | 7 | // [ported from c-simple-emu-cbm (C Portable Version - for console)] |
davervw | 0:90de1cbc8a5f | 8 | // |
davervw | 0:90de1cbc8a5f | 9 | // MIT License |
davervw | 0:90de1cbc8a5f | 10 | // |
davervw | 0:90de1cbc8a5f | 11 | // Copyright(c) 2020 by David R.Van Wagner |
davervw | 0:90de1cbc8a5f | 12 | // davevw.com |
davervw | 0:90de1cbc8a5f | 13 | // |
davervw | 0:90de1cbc8a5f | 14 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
davervw | 0:90de1cbc8a5f | 15 | // of this software and associated documentation files (the "Software"), to deal |
davervw | 0:90de1cbc8a5f | 16 | // in the Software without restriction, including without limitation the rights |
davervw | 0:90de1cbc8a5f | 17 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
davervw | 0:90de1cbc8a5f | 18 | // copies of the Software, and to permit persons to whom the Software is |
davervw | 0:90de1cbc8a5f | 19 | // furnished to do so, subject to the following conditions: |
davervw | 0:90de1cbc8a5f | 20 | // |
davervw | 0:90de1cbc8a5f | 21 | // The above copyright notice and this permission notice shall be included in all |
davervw | 0:90de1cbc8a5f | 22 | // copies or substantial portions of the Software. |
davervw | 0:90de1cbc8a5f | 23 | // |
davervw | 0:90de1cbc8a5f | 24 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
davervw | 0:90de1cbc8a5f | 25 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
davervw | 0:90de1cbc8a5f | 26 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE |
davervw | 0:90de1cbc8a5f | 27 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
davervw | 0:90de1cbc8a5f | 28 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
davervw | 0:90de1cbc8a5f | 29 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
davervw | 0:90de1cbc8a5f | 30 | // SOFTWARE. |
davervw | 0:90de1cbc8a5f | 31 | // |
davervw | 0:90de1cbc8a5f | 32 | //////////////////////////////////////////////////////////////////////////////// |
davervw | 0:90de1cbc8a5f | 33 | |
davervw | 0:90de1cbc8a5f | 34 | //#define snprintf sprintf_s |
davervw | 0:90de1cbc8a5f | 35 | |
davervw | 0:90de1cbc8a5f | 36 | #include <mbed.h> |
davervw | 0:90de1cbc8a5f | 37 | #include "emu6502.h" |
davervw | 0:90de1cbc8a5f | 38 | |
davervw | 0:90de1cbc8a5f | 39 | // globals |
davervw | 0:90de1cbc8a5f | 40 | byte A = 0; |
davervw | 0:90de1cbc8a5f | 41 | byte X = 0; |
davervw | 0:90de1cbc8a5f | 42 | byte Y = 0; |
davervw | 0:90de1cbc8a5f | 43 | byte S = 0xFF; |
davervw | 0:90de1cbc8a5f | 44 | bool N = false; |
davervw | 0:90de1cbc8a5f | 45 | bool V = false; |
davervw | 0:90de1cbc8a5f | 46 | bool B = false; |
davervw | 0:90de1cbc8a5f | 47 | bool D = false; |
davervw | 0:90de1cbc8a5f | 48 | bool I = false; |
davervw | 0:90de1cbc8a5f | 49 | bool Z = false; |
davervw | 0:90de1cbc8a5f | 50 | bool C = false; |
davervw | 0:90de1cbc8a5f | 51 | ushort PC = 0; |
davervw | 0:90de1cbc8a5f | 52 | bool trace = false; |
davervw | 0:90de1cbc8a5f | 53 | bool step = false; |
davervw | 0:90de1cbc8a5f | 54 | |
davervw | 0:90de1cbc8a5f | 55 | extern void ResetRun(bool (*ExecutePatch)(void)) |
davervw | 0:90de1cbc8a5f | 56 | { |
davervw | 0:90de1cbc8a5f | 57 | ushort addr = (ushort)((GetMemory(0xFFFC) | (GetMemory(0xFFFD) << 8))); // RESET vector |
davervw | 0:90de1cbc8a5f | 58 | Execute(addr, ExecutePatch); |
davervw | 0:90de1cbc8a5f | 59 | } |
davervw | 0:90de1cbc8a5f | 60 | |
davervw | 0:90de1cbc8a5f | 61 | #ifndef WIN32 |
davervw | 0:90de1cbc8a5f | 62 | static void strcpy_s(char* dest, size_t size, const char* src) |
davervw | 0:90de1cbc8a5f | 63 | { |
davervw | 0:90de1cbc8a5f | 64 | strncpy(dest, src, size); |
davervw | 0:90de1cbc8a5f | 65 | } |
davervw | 0:90de1cbc8a5f | 66 | |
davervw | 0:90de1cbc8a5f | 67 | static void strcat_s(char* dest, size_t size, const char* src) |
davervw | 0:90de1cbc8a5f | 68 | { |
davervw | 0:90de1cbc8a5f | 69 | strncat(dest, src, size); |
davervw | 0:90de1cbc8a5f | 70 | } |
davervw | 0:90de1cbc8a5f | 71 | #endif |
davervw | 0:90de1cbc8a5f | 72 | |
davervw | 0:90de1cbc8a5f | 73 | static void PHP() |
davervw | 0:90de1cbc8a5f | 74 | { |
davervw | 0:90de1cbc8a5f | 75 | int flags = (N ? 0x80 : 0) |
davervw | 0:90de1cbc8a5f | 76 | | (V ? 0x40 : 0) |
davervw | 0:90de1cbc8a5f | 77 | | (B ? 0x10 : 0) |
davervw | 0:90de1cbc8a5f | 78 | | (D ? 0x08 : 0) |
davervw | 0:90de1cbc8a5f | 79 | | (I ? 0x04 : 0) |
davervw | 0:90de1cbc8a5f | 80 | | (Z ? 0x02 : 0) |
davervw | 0:90de1cbc8a5f | 81 | | (C ? 0x01 : 0); |
davervw | 0:90de1cbc8a5f | 82 | Push(flags); |
davervw | 0:90de1cbc8a5f | 83 | } |
davervw | 0:90de1cbc8a5f | 84 | |
davervw | 0:90de1cbc8a5f | 85 | extern byte LO(ushort value) |
davervw | 0:90de1cbc8a5f | 86 | { |
davervw | 0:90de1cbc8a5f | 87 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 88 | } |
davervw | 0:90de1cbc8a5f | 89 | |
davervw | 0:90de1cbc8a5f | 90 | extern byte HI(ushort value) |
davervw | 0:90de1cbc8a5f | 91 | { |
davervw | 0:90de1cbc8a5f | 92 | return (byte)(value >> 8); |
davervw | 0:90de1cbc8a5f | 93 | } |
davervw | 0:90de1cbc8a5f | 94 | |
davervw | 0:90de1cbc8a5f | 95 | static void BRK(byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 96 | { |
davervw | 0:90de1cbc8a5f | 97 | ++PC; |
davervw | 0:90de1cbc8a5f | 98 | Push(HI(PC)); |
davervw | 0:90de1cbc8a5f | 99 | Push(LO(PC)); |
davervw | 4:8476be802690 | 100 | PHP(); |
davervw | 0:90de1cbc8a5f | 101 | B = true; |
davervw | 0:90de1cbc8a5f | 102 | PC = (ushort)(GetMemory(0xFFFE) + (GetMemory(0xFFFF) << 8)); |
davervw | 0:90de1cbc8a5f | 103 | *p_bytes = 0; |
davervw | 0:90de1cbc8a5f | 104 | } |
davervw | 0:90de1cbc8a5f | 105 | |
davervw | 0:90de1cbc8a5f | 106 | static byte Subtract(byte reg, byte value, bool *p_overflow) |
davervw | 0:90de1cbc8a5f | 107 | { |
davervw | 0:90de1cbc8a5f | 108 | bool old_reg_neg = (reg & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 109 | bool value_neg = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 110 | int result = reg - value - (C ? 0 : 1); |
davervw | 0:90de1cbc8a5f | 111 | N = (result & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 112 | C = (result >= 0); |
davervw | 0:90de1cbc8a5f | 113 | Z = (result == 0); |
davervw | 0:90de1cbc8a5f | 114 | bool result_neg = (result & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 115 | *p_overflow = (old_reg_neg && !value_neg && !result_neg) // neg - pos = pos |
davervw | 0:90de1cbc8a5f | 116 | || (!old_reg_neg && value_neg && result_neg); // pos - neg = neg |
davervw | 0:90de1cbc8a5f | 117 | return (byte)result; |
davervw | 0:90de1cbc8a5f | 118 | } |
davervw | 0:90de1cbc8a5f | 119 | |
davervw | 0:90de1cbc8a5f | 120 | static byte SubtractWithoutOverflow(byte reg, byte value) |
davervw | 0:90de1cbc8a5f | 121 | { |
davervw | 0:90de1cbc8a5f | 122 | C = true; // init for CMP, etc. |
davervw | 0:90de1cbc8a5f | 123 | bool unused; |
davervw | 0:90de1cbc8a5f | 124 | return Subtract(reg, value, &unused); |
davervw | 0:90de1cbc8a5f | 125 | } |
davervw | 0:90de1cbc8a5f | 126 | |
davervw | 0:90de1cbc8a5f | 127 | static void CMP(byte value) |
davervw | 0:90de1cbc8a5f | 128 | { |
davervw | 0:90de1cbc8a5f | 129 | SubtractWithoutOverflow(A, value); |
davervw | 0:90de1cbc8a5f | 130 | } |
davervw | 0:90de1cbc8a5f | 131 | |
davervw | 0:90de1cbc8a5f | 132 | static void CPX(byte value) |
davervw | 0:90de1cbc8a5f | 133 | { |
davervw | 0:90de1cbc8a5f | 134 | SubtractWithoutOverflow(X, value); |
davervw | 0:90de1cbc8a5f | 135 | } |
davervw | 0:90de1cbc8a5f | 136 | |
davervw | 0:90de1cbc8a5f | 137 | static void CPY(byte value) |
davervw | 0:90de1cbc8a5f | 138 | { |
davervw | 0:90de1cbc8a5f | 139 | SubtractWithoutOverflow(Y, value); |
davervw | 0:90de1cbc8a5f | 140 | } |
davervw | 0:90de1cbc8a5f | 141 | |
davervw | 0:90de1cbc8a5f | 142 | static void SetReg(byte *p_reg, int value) |
davervw | 0:90de1cbc8a5f | 143 | { |
davervw | 0:90de1cbc8a5f | 144 | *p_reg = (byte)value; |
davervw | 0:90de1cbc8a5f | 145 | Z = (*p_reg == 0); |
davervw | 0:90de1cbc8a5f | 146 | N = ((*p_reg & 0x80) != 0); |
davervw | 0:90de1cbc8a5f | 147 | } |
davervw | 0:90de1cbc8a5f | 148 | |
davervw | 0:90de1cbc8a5f | 149 | static void SetA(int value) |
davervw | 0:90de1cbc8a5f | 150 | { |
davervw | 0:90de1cbc8a5f | 151 | SetReg(&A, value); |
davervw | 0:90de1cbc8a5f | 152 | } |
davervw | 0:90de1cbc8a5f | 153 | |
davervw | 0:90de1cbc8a5f | 154 | static void SetX(int value) |
davervw | 0:90de1cbc8a5f | 155 | { |
davervw | 0:90de1cbc8a5f | 156 | SetReg(&X, value); |
davervw | 0:90de1cbc8a5f | 157 | } |
davervw | 0:90de1cbc8a5f | 158 | |
davervw | 0:90de1cbc8a5f | 159 | static void SetY(int value) |
davervw | 0:90de1cbc8a5f | 160 | { |
davervw | 0:90de1cbc8a5f | 161 | SetReg(&Y, value); |
davervw | 0:90de1cbc8a5f | 162 | } |
davervw | 0:90de1cbc8a5f | 163 | |
davervw | 0:90de1cbc8a5f | 164 | static void SBC(byte value) |
davervw | 0:90de1cbc8a5f | 165 | { |
davervw | 0:90de1cbc8a5f | 166 | if (D) |
davervw | 0:90de1cbc8a5f | 167 | { |
davervw | 0:90de1cbc8a5f | 168 | int A_dec = (A & 0xF) + ((A >> 4) * 10); |
davervw | 0:90de1cbc8a5f | 169 | int value_dec = (value & 0xF) + ((value >> 4) * 10); |
davervw | 0:90de1cbc8a5f | 170 | int result_dec = A_dec - value_dec - (C ? 0 : 1); |
davervw | 0:90de1cbc8a5f | 171 | C = (result_dec >= 0); |
davervw | 0:90de1cbc8a5f | 172 | if (!C) |
davervw | 0:90de1cbc8a5f | 173 | result_dec = -result_dec; // absolute value |
davervw | 0:90de1cbc8a5f | 174 | int result = (result_dec % 10) | (((result_dec / 10) % 10) << 4); |
davervw | 0:90de1cbc8a5f | 175 | SetA(result); |
davervw | 0:90de1cbc8a5f | 176 | N = false; // undefined? |
davervw | 0:90de1cbc8a5f | 177 | V = false; // undefined? |
davervw | 0:90de1cbc8a5f | 178 | } |
davervw | 0:90de1cbc8a5f | 179 | else |
davervw | 0:90de1cbc8a5f | 180 | { |
davervw | 0:90de1cbc8a5f | 181 | byte result = Subtract(A, value, &V); |
davervw | 0:90de1cbc8a5f | 182 | SetA(result); |
davervw | 0:90de1cbc8a5f | 183 | } |
davervw | 0:90de1cbc8a5f | 184 | } |
davervw | 0:90de1cbc8a5f | 185 | |
davervw | 4:8476be802690 | 186 | static void ADDC(byte value) |
davervw | 0:90de1cbc8a5f | 187 | { |
davervw | 0:90de1cbc8a5f | 188 | int result; |
davervw | 0:90de1cbc8a5f | 189 | if (D) |
davervw | 0:90de1cbc8a5f | 190 | { |
davervw | 0:90de1cbc8a5f | 191 | int A_dec = (A & 0xF) + ((A >> 4) * 10); |
davervw | 0:90de1cbc8a5f | 192 | int value_dec = (value & 0xF) + ((value >> 4) * 10); |
davervw | 0:90de1cbc8a5f | 193 | int result_dec = A_dec + value_dec + (C ? 1 : 0); |
davervw | 0:90de1cbc8a5f | 194 | C = (result_dec > 99); |
davervw | 0:90de1cbc8a5f | 195 | result = (result_dec % 10) | (((result_dec / 10) % 10) << 4); |
davervw | 0:90de1cbc8a5f | 196 | SetA(result); |
davervw | 0:90de1cbc8a5f | 197 | Z = (result_dec == 0); // BCD quirk -- 100 doesn't set Z |
davervw | 0:90de1cbc8a5f | 198 | V = false; |
davervw | 0:90de1cbc8a5f | 199 | } |
davervw | 0:90de1cbc8a5f | 200 | else |
davervw | 0:90de1cbc8a5f | 201 | { |
davervw | 0:90de1cbc8a5f | 202 | bool A_old_neg = (A & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 203 | bool value_neg = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 204 | result = A + value + (C ? 1 : 0); |
davervw | 0:90de1cbc8a5f | 205 | C = (result & 0x100) != 0; |
davervw | 0:90de1cbc8a5f | 206 | SetA(result); |
davervw | 0:90de1cbc8a5f | 207 | bool result_neg = (result & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 208 | V = (!A_old_neg && !value_neg && result_neg) // pos + pos = neg: overflow |
davervw | 0:90de1cbc8a5f | 209 | || (A_old_neg && value_neg && !result_neg); // neg + neg = pos: overflow |
davervw | 0:90de1cbc8a5f | 210 | } |
davervw | 0:90de1cbc8a5f | 211 | } |
davervw | 0:90de1cbc8a5f | 212 | |
davervw | 0:90de1cbc8a5f | 213 | static void ORA(int value) |
davervw | 0:90de1cbc8a5f | 214 | { |
davervw | 0:90de1cbc8a5f | 215 | SetA(A | value); |
davervw | 0:90de1cbc8a5f | 216 | } |
davervw | 0:90de1cbc8a5f | 217 | |
davervw | 0:90de1cbc8a5f | 218 | static void EOR(int value) |
davervw | 0:90de1cbc8a5f | 219 | { |
davervw | 0:90de1cbc8a5f | 220 | SetA(A ^ value); |
davervw | 0:90de1cbc8a5f | 221 | } |
davervw | 0:90de1cbc8a5f | 222 | |
davervw | 0:90de1cbc8a5f | 223 | static void AND(int value) |
davervw | 0:90de1cbc8a5f | 224 | { |
davervw | 0:90de1cbc8a5f | 225 | SetA(A & value); |
davervw | 0:90de1cbc8a5f | 226 | } |
davervw | 0:90de1cbc8a5f | 227 | |
davervw | 0:90de1cbc8a5f | 228 | static void BIT(byte value) |
davervw | 0:90de1cbc8a5f | 229 | { |
davervw | 0:90de1cbc8a5f | 230 | Z = (A & value) == 0; |
davervw | 0:90de1cbc8a5f | 231 | N = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 232 | V = (value & 0x40) != 0; |
davervw | 0:90de1cbc8a5f | 233 | } |
davervw | 0:90de1cbc8a5f | 234 | |
davervw | 0:90de1cbc8a5f | 235 | static byte ASL(int value) |
davervw | 0:90de1cbc8a5f | 236 | { |
davervw | 0:90de1cbc8a5f | 237 | C = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 238 | value = (byte)(value << 1); |
davervw | 0:90de1cbc8a5f | 239 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 240 | N = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 241 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 242 | } |
davervw | 0:90de1cbc8a5f | 243 | |
davervw | 0:90de1cbc8a5f | 244 | static byte LSR(int value) |
davervw | 0:90de1cbc8a5f | 245 | { |
davervw | 0:90de1cbc8a5f | 246 | C = (value & 0x01) != 0; |
davervw | 0:90de1cbc8a5f | 247 | value = (byte)(value >> 1); |
davervw | 0:90de1cbc8a5f | 248 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 249 | N = false; |
davervw | 0:90de1cbc8a5f | 250 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 251 | } |
davervw | 0:90de1cbc8a5f | 252 | |
davervw | 0:90de1cbc8a5f | 253 | static byte ROL(int value) |
davervw | 0:90de1cbc8a5f | 254 | { |
davervw | 0:90de1cbc8a5f | 255 | bool newC = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 256 | value = (byte)((value << 1) | (C ? 1 : 0)); |
davervw | 0:90de1cbc8a5f | 257 | C = newC; |
davervw | 0:90de1cbc8a5f | 258 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 259 | N = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 260 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 261 | } |
davervw | 0:90de1cbc8a5f | 262 | |
davervw | 0:90de1cbc8a5f | 263 | static byte ROR(int value) |
davervw | 0:90de1cbc8a5f | 264 | { |
davervw | 0:90de1cbc8a5f | 265 | bool newC = (value & 0x01) != 0; |
davervw | 0:90de1cbc8a5f | 266 | N = C; |
davervw | 0:90de1cbc8a5f | 267 | value = (byte)((value >> 1) | (C ? 0x80 : 0)); |
davervw | 0:90de1cbc8a5f | 268 | C = newC; |
davervw | 0:90de1cbc8a5f | 269 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 270 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 271 | } |
davervw | 0:90de1cbc8a5f | 272 | |
davervw | 0:90de1cbc8a5f | 273 | extern void Push(int value) |
davervw | 0:90de1cbc8a5f | 274 | { |
davervw | 0:90de1cbc8a5f | 275 | SetMemory((ushort)(0x100 + (S--)), (byte)value); |
davervw | 0:90de1cbc8a5f | 276 | } |
davervw | 0:90de1cbc8a5f | 277 | |
davervw | 0:90de1cbc8a5f | 278 | extern byte Pop(void) |
davervw | 0:90de1cbc8a5f | 279 | { |
davervw | 0:90de1cbc8a5f | 280 | return GetMemory((ushort)(0x100 + (++S))); |
davervw | 0:90de1cbc8a5f | 281 | } |
davervw | 0:90de1cbc8a5f | 282 | |
davervw | 0:90de1cbc8a5f | 283 | static void PLP() |
davervw | 0:90de1cbc8a5f | 284 | { |
davervw | 0:90de1cbc8a5f | 285 | int flags = Pop(); |
davervw | 0:90de1cbc8a5f | 286 | N = (flags & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 287 | V = (flags & 0x40) != 0; |
davervw | 0:90de1cbc8a5f | 288 | B = (flags & 0x10) != 0; |
davervw | 0:90de1cbc8a5f | 289 | D = (flags & 0x08) != 0; |
davervw | 0:90de1cbc8a5f | 290 | I = (flags & 0x04) != 0; |
davervw | 0:90de1cbc8a5f | 291 | Z = (flags & 0x02) != 0; |
davervw | 0:90de1cbc8a5f | 292 | C = (flags & 0x01) != 0; |
davervw | 0:90de1cbc8a5f | 293 | } |
davervw | 0:90de1cbc8a5f | 294 | |
davervw | 0:90de1cbc8a5f | 295 | static void PHA() |
davervw | 0:90de1cbc8a5f | 296 | { |
davervw | 0:90de1cbc8a5f | 297 | Push(A); |
davervw | 0:90de1cbc8a5f | 298 | } |
davervw | 0:90de1cbc8a5f | 299 | |
davervw | 0:90de1cbc8a5f | 300 | static void PLA() |
davervw | 0:90de1cbc8a5f | 301 | { |
davervw | 0:90de1cbc8a5f | 302 | SetA(Pop()); |
davervw | 0:90de1cbc8a5f | 303 | } |
davervw | 0:90de1cbc8a5f | 304 | |
davervw | 0:90de1cbc8a5f | 305 | static void CLC() |
davervw | 0:90de1cbc8a5f | 306 | { |
davervw | 0:90de1cbc8a5f | 307 | C = false; |
davervw | 0:90de1cbc8a5f | 308 | } |
davervw | 0:90de1cbc8a5f | 309 | |
davervw | 0:90de1cbc8a5f | 310 | static void CLD() |
davervw | 0:90de1cbc8a5f | 311 | { |
davervw | 0:90de1cbc8a5f | 312 | D = false; |
davervw | 0:90de1cbc8a5f | 313 | } |
davervw | 0:90de1cbc8a5f | 314 | |
davervw | 0:90de1cbc8a5f | 315 | static void CLI() |
davervw | 0:90de1cbc8a5f | 316 | { |
davervw | 0:90de1cbc8a5f | 317 | I = false; |
davervw | 0:90de1cbc8a5f | 318 | } |
davervw | 0:90de1cbc8a5f | 319 | |
davervw | 0:90de1cbc8a5f | 320 | static void CLV() |
davervw | 0:90de1cbc8a5f | 321 | { |
davervw | 0:90de1cbc8a5f | 322 | V = false; |
davervw | 0:90de1cbc8a5f | 323 | } |
davervw | 0:90de1cbc8a5f | 324 | |
davervw | 0:90de1cbc8a5f | 325 | static void SEC() |
davervw | 0:90de1cbc8a5f | 326 | { |
davervw | 0:90de1cbc8a5f | 327 | C = true; |
davervw | 0:90de1cbc8a5f | 328 | } |
davervw | 0:90de1cbc8a5f | 329 | |
davervw | 0:90de1cbc8a5f | 330 | static void SED() |
davervw | 0:90de1cbc8a5f | 331 | { |
davervw | 0:90de1cbc8a5f | 332 | D = true; |
davervw | 0:90de1cbc8a5f | 333 | } |
davervw | 0:90de1cbc8a5f | 334 | |
davervw | 0:90de1cbc8a5f | 335 | static void SEI() |
davervw | 0:90de1cbc8a5f | 336 | { |
davervw | 0:90de1cbc8a5f | 337 | I = true; |
davervw | 0:90de1cbc8a5f | 338 | } |
davervw | 0:90de1cbc8a5f | 339 | |
davervw | 0:90de1cbc8a5f | 340 | static byte INC(byte value) |
davervw | 0:90de1cbc8a5f | 341 | { |
davervw | 0:90de1cbc8a5f | 342 | ++value; |
davervw | 0:90de1cbc8a5f | 343 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 344 | N = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 345 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 346 | } |
davervw | 0:90de1cbc8a5f | 347 | |
davervw | 0:90de1cbc8a5f | 348 | static void INX() |
davervw | 0:90de1cbc8a5f | 349 | { |
davervw | 0:90de1cbc8a5f | 350 | X = INC(X); |
davervw | 0:90de1cbc8a5f | 351 | } |
davervw | 0:90de1cbc8a5f | 352 | |
davervw | 0:90de1cbc8a5f | 353 | static void INY() |
davervw | 0:90de1cbc8a5f | 354 | { |
davervw | 0:90de1cbc8a5f | 355 | Y = INC(Y); |
davervw | 0:90de1cbc8a5f | 356 | } |
davervw | 0:90de1cbc8a5f | 357 | |
davervw | 0:90de1cbc8a5f | 358 | static byte DEC(byte value) |
davervw | 0:90de1cbc8a5f | 359 | { |
davervw | 0:90de1cbc8a5f | 360 | --value; |
davervw | 0:90de1cbc8a5f | 361 | Z = (value == 0); |
davervw | 0:90de1cbc8a5f | 362 | N = (value & 0x80) != 0; |
davervw | 0:90de1cbc8a5f | 363 | return (byte)value; |
davervw | 0:90de1cbc8a5f | 364 | } |
davervw | 0:90de1cbc8a5f | 365 | |
davervw | 0:90de1cbc8a5f | 366 | static void DEX() |
davervw | 0:90de1cbc8a5f | 367 | { |
davervw | 0:90de1cbc8a5f | 368 | X = DEC(X); |
davervw | 0:90de1cbc8a5f | 369 | } |
davervw | 0:90de1cbc8a5f | 370 | |
davervw | 0:90de1cbc8a5f | 371 | static void DEY() |
davervw | 0:90de1cbc8a5f | 372 | { |
davervw | 0:90de1cbc8a5f | 373 | Y = DEC(Y); |
davervw | 0:90de1cbc8a5f | 374 | } |
davervw | 0:90de1cbc8a5f | 375 | |
davervw | 0:90de1cbc8a5f | 376 | static void NOP() |
davervw | 0:90de1cbc8a5f | 377 | { |
davervw | 0:90de1cbc8a5f | 378 | } |
davervw | 0:90de1cbc8a5f | 379 | |
davervw | 0:90de1cbc8a5f | 380 | static void TXA() |
davervw | 0:90de1cbc8a5f | 381 | { |
davervw | 0:90de1cbc8a5f | 382 | SetReg(&A, X); |
davervw | 0:90de1cbc8a5f | 383 | } |
davervw | 0:90de1cbc8a5f | 384 | |
davervw | 0:90de1cbc8a5f | 385 | static void TAX() |
davervw | 0:90de1cbc8a5f | 386 | { |
davervw | 0:90de1cbc8a5f | 387 | SetReg(&X, A); |
davervw | 0:90de1cbc8a5f | 388 | } |
davervw | 0:90de1cbc8a5f | 389 | |
davervw | 0:90de1cbc8a5f | 390 | static void TYA() |
davervw | 0:90de1cbc8a5f | 391 | { |
davervw | 0:90de1cbc8a5f | 392 | SetReg(&A, Y); |
davervw | 0:90de1cbc8a5f | 393 | } |
davervw | 0:90de1cbc8a5f | 394 | |
davervw | 0:90de1cbc8a5f | 395 | static void TAY() |
davervw | 0:90de1cbc8a5f | 396 | { |
davervw | 0:90de1cbc8a5f | 397 | SetReg(&Y, A); |
davervw | 0:90de1cbc8a5f | 398 | } |
davervw | 0:90de1cbc8a5f | 399 | |
davervw | 0:90de1cbc8a5f | 400 | static void TXS() |
davervw | 0:90de1cbc8a5f | 401 | { |
davervw | 0:90de1cbc8a5f | 402 | S = X; |
davervw | 0:90de1cbc8a5f | 403 | } |
davervw | 0:90de1cbc8a5f | 404 | |
davervw | 0:90de1cbc8a5f | 405 | static void TSX() |
davervw | 0:90de1cbc8a5f | 406 | { |
davervw | 0:90de1cbc8a5f | 407 | SetReg(&X, S); |
davervw | 0:90de1cbc8a5f | 408 | } |
davervw | 0:90de1cbc8a5f | 409 | |
davervw | 0:90de1cbc8a5f | 410 | static ushort GetBR(ushort addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 411 | { |
davervw | 0:90de1cbc8a5f | 412 | *p_conditional = true; |
davervw | 0:90de1cbc8a5f | 413 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 414 | sbyte offset = (sbyte)GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 415 | ushort addr2 = (ushort)(addr + 2 + offset); |
davervw | 0:90de1cbc8a5f | 416 | return addr2; |
davervw | 0:90de1cbc8a5f | 417 | } |
davervw | 0:90de1cbc8a5f | 418 | |
davervw | 0:90de1cbc8a5f | 419 | static void BR(bool branch, ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 420 | { |
davervw | 0:90de1cbc8a5f | 421 | ushort addr2 = GetBR(*p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 422 | if (branch) |
davervw | 0:90de1cbc8a5f | 423 | { |
davervw | 0:90de1cbc8a5f | 424 | *p_addr = addr2; |
davervw | 0:90de1cbc8a5f | 425 | *p_bytes = 0; // don't advance addr |
davervw | 0:90de1cbc8a5f | 426 | } |
davervw | 0:90de1cbc8a5f | 427 | } |
davervw | 0:90de1cbc8a5f | 428 | |
davervw | 0:90de1cbc8a5f | 429 | static void BPL(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 430 | { |
davervw | 0:90de1cbc8a5f | 431 | BR(!N, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 432 | } |
davervw | 0:90de1cbc8a5f | 433 | |
davervw | 0:90de1cbc8a5f | 434 | static void BMI(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 435 | { |
davervw | 0:90de1cbc8a5f | 436 | BR(N, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 437 | } |
davervw | 0:90de1cbc8a5f | 438 | |
davervw | 0:90de1cbc8a5f | 439 | static void BCC(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 440 | { |
davervw | 0:90de1cbc8a5f | 441 | BR(!C, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 442 | } |
davervw | 0:90de1cbc8a5f | 443 | |
davervw | 0:90de1cbc8a5f | 444 | static void BCS(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 445 | { |
davervw | 0:90de1cbc8a5f | 446 | BR(C, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 447 | } |
davervw | 0:90de1cbc8a5f | 448 | |
davervw | 0:90de1cbc8a5f | 449 | static void BVC(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 450 | { |
davervw | 0:90de1cbc8a5f | 451 | BR(!V, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 452 | } |
davervw | 0:90de1cbc8a5f | 453 | |
davervw | 0:90de1cbc8a5f | 454 | static void BVS(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 455 | { |
davervw | 0:90de1cbc8a5f | 456 | BR(V, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 457 | } |
davervw | 0:90de1cbc8a5f | 458 | |
davervw | 0:90de1cbc8a5f | 459 | static void BNE(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 460 | { |
davervw | 0:90de1cbc8a5f | 461 | BR(!Z, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 462 | } |
davervw | 0:90de1cbc8a5f | 463 | |
davervw | 0:90de1cbc8a5f | 464 | static void BEQ(ushort *p_addr, bool *p_conditional, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 465 | { |
davervw | 0:90de1cbc8a5f | 466 | BR(Z, p_addr, p_conditional, p_bytes); |
davervw | 0:90de1cbc8a5f | 467 | } |
davervw | 0:90de1cbc8a5f | 468 | |
davervw | 0:90de1cbc8a5f | 469 | static void JSR(ushort *p_addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 470 | { |
davervw | 0:90de1cbc8a5f | 471 | *p_bytes = 3; // for next calculation |
davervw | 0:90de1cbc8a5f | 472 | ushort addr2 = (ushort)(*p_addr + *p_bytes - 1); |
davervw | 0:90de1cbc8a5f | 473 | ushort addr3 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 474 | Push(HI(addr2)); |
davervw | 0:90de1cbc8a5f | 475 | Push(LO(addr2)); |
davervw | 0:90de1cbc8a5f | 476 | *p_addr = addr3; |
davervw | 0:90de1cbc8a5f | 477 | *p_bytes = 0; // addr already changed |
davervw | 0:90de1cbc8a5f | 478 | } |
davervw | 0:90de1cbc8a5f | 479 | |
davervw | 0:90de1cbc8a5f | 480 | static void RTS(ushort *p_addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 481 | { |
davervw | 0:90de1cbc8a5f | 482 | byte lo = Pop(); |
davervw | 0:90de1cbc8a5f | 483 | byte hi = Pop(); |
davervw | 0:90de1cbc8a5f | 484 | *p_bytes = 1; // make sure caller increases addr by one |
davervw | 0:90de1cbc8a5f | 485 | *p_addr = (ushort)((hi << 8) | lo); |
davervw | 0:90de1cbc8a5f | 486 | } |
davervw | 0:90de1cbc8a5f | 487 | |
davervw | 0:90de1cbc8a5f | 488 | static void RTI(ushort *p_addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 489 | { |
davervw | 0:90de1cbc8a5f | 490 | PLP(); |
davervw | 4:8476be802690 | 491 | byte lo = Pop(); |
davervw | 0:90de1cbc8a5f | 492 | byte hi = Pop(); |
davervw | 0:90de1cbc8a5f | 493 | *p_bytes = 0; // make sure caller does not increase addr by one |
davervw | 0:90de1cbc8a5f | 494 | *p_addr = (ushort)((hi << 8) | lo); |
davervw | 0:90de1cbc8a5f | 495 | } |
davervw | 0:90de1cbc8a5f | 496 | |
davervw | 0:90de1cbc8a5f | 497 | static void JMP(ushort *p_addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 498 | { |
davervw | 0:90de1cbc8a5f | 499 | *p_bytes = 0; // caller should not advance address |
davervw | 0:90de1cbc8a5f | 500 | ushort addr2 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 501 | *p_addr = addr2; |
davervw | 0:90de1cbc8a5f | 502 | } |
davervw | 0:90de1cbc8a5f | 503 | |
davervw | 0:90de1cbc8a5f | 504 | static void JMPIND(ushort *p_addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 505 | { |
davervw | 0:90de1cbc8a5f | 506 | *p_bytes = 0; // caller should not advance address |
davervw | 0:90de1cbc8a5f | 507 | ushort addr2 = (ushort)(GetMemory((ushort)(*p_addr + 1)) | (GetMemory((ushort)(*p_addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 508 | ushort addr3; |
davervw | 0:90de1cbc8a5f | 509 | if ((addr2 & 0xFF) == 0xFF) // JMP($XXFF) won't go over page boundary |
davervw | 0:90de1cbc8a5f | 510 | addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 - 0xFF)) << 8)); // 6502 "bug" - will use XXFF and XX00 as source of address |
davervw | 0:90de1cbc8a5f | 511 | else |
davervw | 0:90de1cbc8a5f | 512 | addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)); |
davervw | 0:90de1cbc8a5f | 513 | *p_addr = addr3; |
davervw | 0:90de1cbc8a5f | 514 | } |
davervw | 0:90de1cbc8a5f | 515 | |
davervw | 0:90de1cbc8a5f | 516 | // "A:FF X:FF Y:FF S:FF P:XX-XXXXX" |
davervw | 0:90de1cbc8a5f | 517 | static void GetDisplayState(char *state, int state_size) |
davervw | 0:90de1cbc8a5f | 518 | { |
davervw | 0:90de1cbc8a5f | 519 | snprintf(state, state_size, "A:%02X X:%02X Y:%02X S:%02X P:%c%c-%c%c%c%c%c", |
davervw | 0:90de1cbc8a5f | 520 | A, |
davervw | 0:90de1cbc8a5f | 521 | X, |
davervw | 0:90de1cbc8a5f | 522 | Y, |
davervw | 0:90de1cbc8a5f | 523 | S, |
davervw | 0:90de1cbc8a5f | 524 | N ? 'N' : ' ', |
davervw | 0:90de1cbc8a5f | 525 | V ? 'V' : ' ', |
davervw | 0:90de1cbc8a5f | 526 | B ? 'B' : ' ', |
davervw | 0:90de1cbc8a5f | 527 | D ? 'D' : ' ', |
davervw | 0:90de1cbc8a5f | 528 | I ? 'I' : ' ', |
davervw | 0:90de1cbc8a5f | 529 | Z ? 'Z' : ' ', |
davervw | 0:90de1cbc8a5f | 530 | C ? 'C' : ' ' |
davervw | 0:90de1cbc8a5f | 531 | ); |
davervw | 0:90de1cbc8a5f | 532 | } |
davervw | 0:90de1cbc8a5f | 533 | |
davervw | 0:90de1cbc8a5f | 534 | static byte GetIndX(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 535 | { |
davervw | 0:90de1cbc8a5f | 536 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 537 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) + X); |
davervw | 0:90de1cbc8a5f | 538 | return GetMemory((ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8))); |
davervw | 0:90de1cbc8a5f | 539 | } |
davervw | 0:90de1cbc8a5f | 540 | |
davervw | 0:90de1cbc8a5f | 541 | static void SetIndX(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 542 | { |
davervw | 0:90de1cbc8a5f | 543 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 544 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) + X); |
davervw | 0:90de1cbc8a5f | 545 | ushort addr3 = (ushort)(GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)); |
davervw | 0:90de1cbc8a5f | 546 | SetMemory(addr3, value); |
davervw | 0:90de1cbc8a5f | 547 | } |
davervw | 0:90de1cbc8a5f | 548 | |
davervw | 0:90de1cbc8a5f | 549 | static byte GetIndY(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 550 | { |
davervw | 0:90de1cbc8a5f | 551 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 552 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 553 | ushort addr3 = (ushort)((GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)) + Y); |
davervw | 0:90de1cbc8a5f | 554 | return GetMemory(addr3); |
davervw | 0:90de1cbc8a5f | 555 | } |
davervw | 0:90de1cbc8a5f | 556 | |
davervw | 0:90de1cbc8a5f | 557 | static void SetIndY(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 558 | { |
davervw | 0:90de1cbc8a5f | 559 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 560 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 561 | ushort addr3 = (ushort)((GetMemory(addr2) | (GetMemory((ushort)(addr2 + 1)) << 8)) + Y); |
davervw | 0:90de1cbc8a5f | 562 | SetMemory(addr3, value); |
davervw | 0:90de1cbc8a5f | 563 | } |
davervw | 0:90de1cbc8a5f | 564 | |
davervw | 0:90de1cbc8a5f | 565 | static byte GetZP(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 566 | { |
davervw | 0:90de1cbc8a5f | 567 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 568 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 569 | return GetMemory(addr2); |
davervw | 0:90de1cbc8a5f | 570 | } |
davervw | 0:90de1cbc8a5f | 571 | |
davervw | 0:90de1cbc8a5f | 572 | static void SetZP(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 573 | { |
davervw | 0:90de1cbc8a5f | 574 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 575 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 576 | SetMemory(addr2, value); |
davervw | 0:90de1cbc8a5f | 577 | } |
davervw | 0:90de1cbc8a5f | 578 | |
davervw | 0:90de1cbc8a5f | 579 | static byte GetZPX(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 580 | { |
davervw | 0:90de1cbc8a5f | 581 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 582 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 583 | return GetMemory((byte)(addr2 + X)); |
davervw | 0:90de1cbc8a5f | 584 | } |
davervw | 0:90de1cbc8a5f | 585 | |
davervw | 0:90de1cbc8a5f | 586 | static void SetZPX(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 587 | { |
davervw | 0:90de1cbc8a5f | 588 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 589 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 590 | SetMemory((byte)(addr2 + X), value); |
davervw | 0:90de1cbc8a5f | 591 | } |
davervw | 0:90de1cbc8a5f | 592 | |
davervw | 0:90de1cbc8a5f | 593 | static byte GetZPY(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 594 | { |
davervw | 0:90de1cbc8a5f | 595 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 596 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 597 | return GetMemory((byte)(addr2 + Y)); |
davervw | 0:90de1cbc8a5f | 598 | } |
davervw | 0:90de1cbc8a5f | 599 | |
davervw | 0:90de1cbc8a5f | 600 | static void SetZPY(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 601 | { |
davervw | 0:90de1cbc8a5f | 602 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 603 | ushort addr2 = GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 604 | SetMemory((byte)(addr2 + Y), value); |
davervw | 0:90de1cbc8a5f | 605 | } |
davervw | 0:90de1cbc8a5f | 606 | |
davervw | 0:90de1cbc8a5f | 607 | static byte GetABS(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 608 | { |
davervw | 0:90de1cbc8a5f | 609 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 610 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 611 | return GetMemory(addr2); |
davervw | 0:90de1cbc8a5f | 612 | } |
davervw | 0:90de1cbc8a5f | 613 | |
davervw | 0:90de1cbc8a5f | 614 | static void SetABS(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 615 | { |
davervw | 0:90de1cbc8a5f | 616 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 617 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 618 | SetMemory(addr2, value); |
davervw | 0:90de1cbc8a5f | 619 | } |
davervw | 0:90de1cbc8a5f | 620 | |
davervw | 0:90de1cbc8a5f | 621 | static byte GetABSX(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 622 | { |
davervw | 0:90de1cbc8a5f | 623 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 624 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 625 | return GetMemory((ushort)(addr2 + X)); |
davervw | 0:90de1cbc8a5f | 626 | } |
davervw | 0:90de1cbc8a5f | 627 | |
davervw | 0:90de1cbc8a5f | 628 | static void SetABSX(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 629 | { |
davervw | 0:90de1cbc8a5f | 630 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 631 | ushort addr2 = (ushort)((GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)) + X); |
davervw | 0:90de1cbc8a5f | 632 | SetMemory(addr2, value); |
davervw | 0:90de1cbc8a5f | 633 | } |
davervw | 0:90de1cbc8a5f | 634 | |
davervw | 0:90de1cbc8a5f | 635 | static byte GetABSY(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 636 | { |
davervw | 0:90de1cbc8a5f | 637 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 638 | ushort addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 639 | return GetMemory((ushort)(addr2 + Y)); |
davervw | 0:90de1cbc8a5f | 640 | } |
davervw | 0:90de1cbc8a5f | 641 | |
davervw | 0:90de1cbc8a5f | 642 | static void SetABSY(byte value, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 643 | { |
davervw | 0:90de1cbc8a5f | 644 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 645 | ushort addr2 = (ushort)((GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)) + Y); |
davervw | 0:90de1cbc8a5f | 646 | SetMemory(addr2, value); |
davervw | 0:90de1cbc8a5f | 647 | } |
davervw | 0:90de1cbc8a5f | 648 | |
davervw | 0:90de1cbc8a5f | 649 | static byte GetIM(ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 650 | { |
davervw | 0:90de1cbc8a5f | 651 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 652 | return GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 653 | } |
davervw | 0:90de1cbc8a5f | 654 | |
davervw | 0:90de1cbc8a5f | 655 | extern void Execute(ushort addr, bool (*ExecutePatch)(void)) |
davervw | 0:90de1cbc8a5f | 656 | { |
davervw | 0:90de1cbc8a5f | 657 | bool conditional; |
davervw | 0:90de1cbc8a5f | 658 | byte bytes; |
davervw | 0:90de1cbc8a5f | 659 | |
davervw | 4:8476be802690 | 660 | Timer timer; |
davervw | 4:8476be802690 | 661 | const double interrupt_time = 1.0 / 60.0 ; // 60 times per second |
davervw | 4:8476be802690 | 662 | timer.start(); |
davervw | 4:8476be802690 | 663 | double timer_then = timer.read(); |
davervw | 4:8476be802690 | 664 | |
davervw | 0:90de1cbc8a5f | 665 | PC = addr; |
davervw | 0:90de1cbc8a5f | 666 | |
davervw | 0:90de1cbc8a5f | 667 | while (true) |
davervw | 0:90de1cbc8a5f | 668 | { |
davervw | 0:90de1cbc8a5f | 669 | while (true) |
davervw | 0:90de1cbc8a5f | 670 | { |
davervw | 4:8476be802690 | 671 | if (!I && (timer.read()-timer_then) >= interrupt_time) // IRQ |
davervw | 4:8476be802690 | 672 | { |
davervw | 4:8476be802690 | 673 | timer_then = timer.read(); // reset timer |
davervw | 4:8476be802690 | 674 | Push(HI(PC)); |
davervw | 4:8476be802690 | 675 | Push(LO(PC)); |
davervw | 4:8476be802690 | 676 | PHP(); |
davervw | 4:8476be802690 | 677 | I = true; |
davervw | 4:8476be802690 | 678 | PC = (GetMemory(0xfffe) | (GetMemory(0xffff) << 8)); |
davervw | 4:8476be802690 | 679 | } |
davervw | 4:8476be802690 | 680 | else |
davervw | 0:90de1cbc8a5f | 681 | { |
davervw | 4:8476be802690 | 682 | bytes = 1; |
davervw | 4:8476be802690 | 683 | bool breakpoint = false; |
davervw | 4:8476be802690 | 684 | //if (Breakpoints.Contains(PC)) |
davervw | 4:8476be802690 | 685 | // breakpoint = true; |
davervw | 4:8476be802690 | 686 | if (trace || breakpoint || step) |
davervw | 4:8476be802690 | 687 | { |
davervw | 4:8476be802690 | 688 | ushort addr2; |
davervw | 4:8476be802690 | 689 | char line[27]; |
davervw | 4:8476be802690 | 690 | char dis[13]; |
davervw | 4:8476be802690 | 691 | DisassembleLong(PC, &conditional, &bytes, &addr2, dis, sizeof(dis), line, sizeof(line)); |
davervw | 4:8476be802690 | 692 | char state[33]; |
davervw | 4:8476be802690 | 693 | GetDisplayState(state, sizeof(state)); |
davervw | 4:8476be802690 | 694 | char full_line[80]; |
davervw | 4:8476be802690 | 695 | snprintf(full_line, sizeof(full_line), "%-30s%s\n", line, state); |
davervw | 4:8476be802690 | 696 | #ifdef WIN32 |
davervw | 4:8476be802690 | 697 | OutputDebugStringA(full_line); |
davervw | 4:8476be802690 | 698 | #else |
davervw | 4:8476be802690 | 699 | printf("%s", full_line); |
davervw | 4:8476be802690 | 700 | #endif |
davervw | 4:8476be802690 | 701 | if (step) |
davervw | 4:8476be802690 | 702 | step = step; // user can put debug breakpoint here to allow stepping |
davervw | 4:8476be802690 | 703 | if (breakpoint) |
davervw | 4:8476be802690 | 704 | breakpoint = breakpoint; // user can put debug breakpoint here to allow break |
davervw | 4:8476be802690 | 705 | } |
davervw | 4:8476be802690 | 706 | if (ExecutePatch != 0 && !ExecutePatch()) // allow execute to be overriden at a specific address |
davervw | 4:8476be802690 | 707 | break; |
davervw | 0:90de1cbc8a5f | 708 | } |
davervw | 0:90de1cbc8a5f | 709 | } |
davervw | 0:90de1cbc8a5f | 710 | |
davervw | 0:90de1cbc8a5f | 711 | switch (GetMemory(PC)) |
davervw | 0:90de1cbc8a5f | 712 | { |
davervw | 0:90de1cbc8a5f | 713 | case 0x00: BRK(&bytes); break; |
davervw | 0:90de1cbc8a5f | 714 | case 0x01: ORA(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 715 | case 0x05: ORA(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 716 | case 0x06: SetZP(ASL(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 717 | case 0x08: PHP(); break; |
davervw | 0:90de1cbc8a5f | 718 | case 0x09: ORA(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 719 | case 0x0A: SetA(ASL(A)); break; |
davervw | 0:90de1cbc8a5f | 720 | case 0x0D: ORA(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 721 | case 0x0E: SetABS(ASL(GetABS(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 722 | |
davervw | 0:90de1cbc8a5f | 723 | case 0x10: BPL(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 724 | case 0x11: ORA(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 725 | case 0x15: ORA(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 726 | case 0x16: SetZPX(ASL(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 727 | case 0x18: CLC(); break; |
davervw | 0:90de1cbc8a5f | 728 | case 0x19: ORA(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 729 | case 0x1D: ORA(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 730 | case 0x1E: SetABSX(ASL(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 731 | |
davervw | 0:90de1cbc8a5f | 732 | case 0x20: JSR(&PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 733 | case 0x21: AND(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 734 | case 0x24: BIT(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 735 | case 0x25: AND(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 736 | case 0x26: SetZP(ROL(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 737 | case 0x28: PLP(); break; |
davervw | 0:90de1cbc8a5f | 738 | case 0x29: AND(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 739 | case 0x2A: SetA(ROL(A)); break; |
davervw | 0:90de1cbc8a5f | 740 | case 0x2C: BIT(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 741 | case 0x2D: AND(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 742 | case 0x2E: ROL(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 743 | |
davervw | 0:90de1cbc8a5f | 744 | case 0x30: BMI(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 745 | case 0x31: AND(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 746 | case 0x35: AND(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 747 | case 0x36: SetZPX(ROL(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 748 | case 0x38: SEC(); break; |
davervw | 0:90de1cbc8a5f | 749 | case 0x39: AND(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 750 | case 0x3D: AND(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 751 | case 0x3E: SetABSX(ROL(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 752 | |
davervw | 0:90de1cbc8a5f | 753 | case 0x40: RTI(&PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 754 | case 0x41: EOR(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 755 | case 0x45: EOR(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 756 | case 0x46: SetZP(LSR(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 757 | case 0x48: PHA(); break; |
davervw | 0:90de1cbc8a5f | 758 | case 0x49: EOR(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 759 | case 0x4A: SetA(LSR(A)); break; |
davervw | 0:90de1cbc8a5f | 760 | case 0x4C: JMP(&PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 761 | case 0x4D: EOR(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 762 | case 0x4E: LSR(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 763 | |
davervw | 0:90de1cbc8a5f | 764 | case 0x50: BVC(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 765 | case 0x51: EOR(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 766 | case 0x55: EOR(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 767 | case 0x56: SetZPX(LSR(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 768 | case 0x58: CLI(); break; |
davervw | 0:90de1cbc8a5f | 769 | case 0x59: EOR(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 770 | case 0x5D: EOR(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 771 | case 0x5E: SetABSX(LSR(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 772 | |
davervw | 0:90de1cbc8a5f | 773 | case 0x60: RTS(&PC, &bytes); break; |
davervw | 4:8476be802690 | 774 | case 0x61: ADDC(GetIndX(PC, &bytes)); break; |
davervw | 4:8476be802690 | 775 | case 0x65: ADDC(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 776 | case 0x66: SetZP(ROR(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 777 | case 0x68: PLA(); break; |
davervw | 4:8476be802690 | 778 | case 0x69: ADDC(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 779 | case 0x6A: SetA(ROR(A)); break; |
davervw | 0:90de1cbc8a5f | 780 | case 0x6C: JMPIND(&PC, &bytes); break; |
davervw | 4:8476be802690 | 781 | case 0x6D: ADDC(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 782 | case 0x6E: SetABS(ROR(GetABS(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 783 | |
davervw | 0:90de1cbc8a5f | 784 | case 0x70: BVS(&PC, &conditional, &bytes); break; |
davervw | 4:8476be802690 | 785 | case 0x71: ADDC(GetIndY(PC, &bytes)); break; |
davervw | 4:8476be802690 | 786 | case 0x75: ADDC(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 787 | case 0x76: SetZPX(ROR(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 788 | case 0x78: SEI(); break; |
davervw | 4:8476be802690 | 789 | case 0x79: ADDC(GetABSY(PC, &bytes)); break; |
davervw | 4:8476be802690 | 790 | case 0x7D: ADDC(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 791 | case 0x7E: SetABSX(ROR(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 792 | |
davervw | 0:90de1cbc8a5f | 793 | case 0x81: SetIndX(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 794 | case 0x84: SetZP(Y, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 795 | case 0x85: SetZP(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 796 | case 0x86: SetZP(X, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 797 | case 0x88: DEY(); break; |
davervw | 0:90de1cbc8a5f | 798 | case 0x8A: TXA(); break; |
davervw | 0:90de1cbc8a5f | 799 | case 0x8C: SetABS(Y, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 800 | case 0x8D: SetABS(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 801 | case 0x8E: SetABS(X, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 802 | |
davervw | 0:90de1cbc8a5f | 803 | case 0x90: BCC(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 804 | case 0x91: SetIndY(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 805 | case 0x94: SetZPX(Y, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 806 | case 0x95: SetZPX(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 807 | case 0x96: SetZPY(X, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 808 | case 0x98: TYA(); break; |
davervw | 0:90de1cbc8a5f | 809 | case 0x99: SetABSY(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 810 | case 0x9A: TXS(); break; |
davervw | 0:90de1cbc8a5f | 811 | case 0x9D: SetABSX(A, PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 812 | |
davervw | 0:90de1cbc8a5f | 813 | case 0xA0: SetY(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 814 | case 0xA1: SetA(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 815 | case 0xA2: SetX(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 816 | case 0xA4: SetY(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 817 | case 0xA5: SetA(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 818 | case 0xA6: SetX(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 819 | case 0xA8: TAY(); break; |
davervw | 0:90de1cbc8a5f | 820 | case 0xA9: SetA(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 821 | case 0xAA: TAX(); break; |
davervw | 0:90de1cbc8a5f | 822 | case 0xAC: SetY(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 823 | case 0xAD: SetA(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 824 | case 0xAE: SetX(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 825 | |
davervw | 0:90de1cbc8a5f | 826 | case 0xB0: BCS(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 827 | case 0xB1: SetA(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 828 | case 0xB4: SetY(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 829 | case 0xB5: SetA(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 830 | case 0xB6: SetX(GetZPY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 831 | case 0xB8: CLV(); break; |
davervw | 0:90de1cbc8a5f | 832 | case 0xB9: SetA(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 833 | case 0xBA: TSX(); break; |
davervw | 0:90de1cbc8a5f | 834 | case 0xBC: SetY(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 835 | case 0xBD: SetA(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 836 | case 0xBE: SetX(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 837 | |
davervw | 0:90de1cbc8a5f | 838 | case 0xC0: CPY(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 839 | case 0xC1: CMP(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 840 | case 0xC4: CPY(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 841 | case 0xC5: CMP(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 842 | case 0xC6: SetZP(DEC(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 843 | case 0xC8: INY(); break; |
davervw | 0:90de1cbc8a5f | 844 | case 0xC9: CMP(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 845 | case 0xCA: DEX(); break; |
davervw | 0:90de1cbc8a5f | 846 | case 0xCC: CPY(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 847 | case 0xCD: CMP(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 848 | case 0xCE: SetABS(DEC(GetABS(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 849 | |
davervw | 0:90de1cbc8a5f | 850 | case 0xD0: BNE(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 851 | case 0xD1: CMP(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 852 | case 0xD5: CMP(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 853 | case 0xD6: SetZPX(DEC(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 854 | case 0xD8: CLD(); break; |
davervw | 0:90de1cbc8a5f | 855 | case 0xD9: CMP(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 856 | case 0xDD: CMP(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 857 | case 0xDE: SetABSX(DEC(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 858 | |
davervw | 0:90de1cbc8a5f | 859 | case 0xE0: CPX(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 860 | case 0xE1: SBC(GetIndX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 861 | case 0xE4: CPX(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 862 | case 0xE5: SBC(GetZP(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 863 | case 0xE6: SetZP(INC(GetZP(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 864 | case 0xE8: INX(); break; |
davervw | 0:90de1cbc8a5f | 865 | case 0xE9: SBC(GetIM(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 866 | case 0xEA: NOP(); break; |
davervw | 0:90de1cbc8a5f | 867 | case 0xEC: CPX(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 868 | case 0xED: SBC(GetABS(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 869 | case 0xEE: SetABS(INC(GetABS(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 870 | |
davervw | 0:90de1cbc8a5f | 871 | case 0xF0: BEQ(&PC, &conditional, &bytes); break; |
davervw | 0:90de1cbc8a5f | 872 | case 0xF1: SBC(GetIndY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 873 | case 0xF5: SBC(GetZPX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 874 | case 0xF6: SetZPX(INC(GetZPX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 875 | case 0xF8: SED(); break; |
davervw | 0:90de1cbc8a5f | 876 | case 0xF9: SBC(GetABSY(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 877 | case 0xFD: SBC(GetABSX(PC, &bytes)); break; |
davervw | 0:90de1cbc8a5f | 878 | case 0xFE: SetABSX(INC(GetABSX(PC, &bytes)), PC, &bytes); break; |
davervw | 0:90de1cbc8a5f | 879 | |
davervw | 0:90de1cbc8a5f | 880 | default: |
davervw | 0:90de1cbc8a5f | 881 | { |
davervw | 0:90de1cbc8a5f | 882 | printf("Invalid opcode %02X at %04X", GetMemory(PC), PC); |
davervw | 0:90de1cbc8a5f | 883 | exit(1); |
davervw | 0:90de1cbc8a5f | 884 | } |
davervw | 0:90de1cbc8a5f | 885 | } |
davervw | 0:90de1cbc8a5f | 886 | |
davervw | 0:90de1cbc8a5f | 887 | PC += bytes; |
davervw | 0:90de1cbc8a5f | 888 | } |
davervw | 0:90de1cbc8a5f | 889 | } |
davervw | 0:90de1cbc8a5f | 890 | |
davervw | 0:90de1cbc8a5f | 891 | // Examples: |
davervw | 0:90de1cbc8a5f | 892 | // FFFF FF FF FF JMP ($FFFF) |
davervw | 0:90de1cbc8a5f | 893 | // FFFF FF FF FF LDA $FFFF,X |
davervw | 0:90de1cbc8a5f | 894 | extern void DisassembleLong(ushort addr, bool *p_conditional, byte *p_bytes, ushort *p_addr2, char *dis, int dis_size, char *line, int line_size) |
davervw | 0:90de1cbc8a5f | 895 | { |
davervw | 0:90de1cbc8a5f | 896 | DisassembleShort(addr, p_conditional, p_bytes, p_addr2, dis, dis_size); |
davervw | 0:90de1cbc8a5f | 897 | snprintf(line, line_size, "%04X ", addr); |
davervw | 0:90de1cbc8a5f | 898 | for (int i = 0; i < 3; ++i) |
davervw | 0:90de1cbc8a5f | 899 | { |
davervw | 0:90de1cbc8a5f | 900 | if (i < *p_bytes) |
davervw | 0:90de1cbc8a5f | 901 | snprintf(line+strlen(line), line_size-strlen(line), "%02X ", GetMemory((ushort)(addr + i))); |
davervw | 0:90de1cbc8a5f | 902 | else |
davervw | 0:90de1cbc8a5f | 903 | strcat_s(line, line_size, " "); |
davervw | 0:90de1cbc8a5f | 904 | } |
davervw | 0:90de1cbc8a5f | 905 | strcat_s(line, line_size, dis); |
davervw | 0:90de1cbc8a5f | 906 | } |
davervw | 0:90de1cbc8a5f | 907 | |
davervw | 0:90de1cbc8a5f | 908 | static void Ind(char *dis, int dis_size, char* opcode, ushort addr, ushort *p_addr2, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 909 | { |
davervw | 0:90de1cbc8a5f | 910 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 911 | ushort addr1 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 912 | *p_addr2 = (ushort)(GetMemory(addr1) | (GetMemory((ushort)(addr1 + 1)) << 8)); |
davervw | 0:90de1cbc8a5f | 913 | snprintf(dis, dis_size, "%s ($%0X4)", opcode, addr1); |
davervw | 0:90de1cbc8a5f | 914 | } |
davervw | 0:90de1cbc8a5f | 915 | |
davervw | 0:90de1cbc8a5f | 916 | static void IndX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 917 | { |
davervw | 0:90de1cbc8a5f | 918 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 919 | snprintf(dis, dis_size, "%s ($%02X,X)", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 920 | } |
davervw | 0:90de1cbc8a5f | 921 | |
davervw | 0:90de1cbc8a5f | 922 | static void IndY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 923 | { |
davervw | 0:90de1cbc8a5f | 924 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 925 | snprintf(dis, dis_size, "%s ($%02X),Y", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 926 | } |
davervw | 0:90de1cbc8a5f | 927 | |
davervw | 0:90de1cbc8a5f | 928 | static void ZP(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 929 | { |
davervw | 0:90de1cbc8a5f | 930 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 931 | snprintf(dis, dis_size, "%s $%02X", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 932 | } |
davervw | 0:90de1cbc8a5f | 933 | |
davervw | 0:90de1cbc8a5f | 934 | static void ZPX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 935 | { |
davervw | 0:90de1cbc8a5f | 936 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 937 | snprintf(dis, dis_size, "%s $%02X,X", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 938 | } |
davervw | 0:90de1cbc8a5f | 939 | |
davervw | 0:90de1cbc8a5f | 940 | static void ZPY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 941 | { |
davervw | 0:90de1cbc8a5f | 942 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 943 | snprintf(dis, dis_size, "%s $%02X,Y", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 944 | } |
davervw | 0:90de1cbc8a5f | 945 | |
davervw | 0:90de1cbc8a5f | 946 | static void ABS(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 947 | { |
davervw | 0:90de1cbc8a5f | 948 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 949 | snprintf(dis, dis_size, "%s $%04X", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 950 | } |
davervw | 0:90de1cbc8a5f | 951 | |
davervw | 0:90de1cbc8a5f | 952 | static void ABSAddr(char *dis, int dis_size, char* opcode, ushort addr, ushort *p_addr2, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 953 | { |
davervw | 0:90de1cbc8a5f | 954 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 955 | *p_addr2 = (ushort)(GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 956 | snprintf(dis, dis_size, "%s $%04X", opcode, *p_addr2); |
davervw | 0:90de1cbc8a5f | 957 | } |
davervw | 0:90de1cbc8a5f | 958 | |
davervw | 0:90de1cbc8a5f | 959 | static void ABSX(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 960 | { |
davervw | 0:90de1cbc8a5f | 961 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 962 | snprintf(dis, dis_size, "%s $%04X,X", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 963 | } |
davervw | 0:90de1cbc8a5f | 964 | |
davervw | 0:90de1cbc8a5f | 965 | static void ABSY(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 966 | { |
davervw | 0:90de1cbc8a5f | 967 | *p_bytes = 3; |
davervw | 0:90de1cbc8a5f | 968 | snprintf(dis, dis_size, "%s $%04X,Y", opcode, GetMemory((ushort)(addr + 1)) | (GetMemory((ushort)(addr + 2)) << 8)); |
davervw | 0:90de1cbc8a5f | 969 | } |
davervw | 0:90de1cbc8a5f | 970 | |
davervw | 0:90de1cbc8a5f | 971 | static void IM(char *dis, int dis_size, char* opcode, ushort addr, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 972 | { |
davervw | 0:90de1cbc8a5f | 973 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 974 | snprintf(dis, dis_size, "%s #$%02X", opcode, GetMemory((ushort)(addr + 1))); |
davervw | 0:90de1cbc8a5f | 975 | } |
davervw | 0:90de1cbc8a5f | 976 | |
davervw | 0:90de1cbc8a5f | 977 | static void BRX(char *dis, int dis_size, char* opcode, ushort addr, bool *p_conditional, ushort *p_addr2, byte *p_bytes) |
davervw | 0:90de1cbc8a5f | 978 | { |
davervw | 0:90de1cbc8a5f | 979 | *p_bytes = 2; |
davervw | 0:90de1cbc8a5f | 980 | *p_conditional = true; |
davervw | 0:90de1cbc8a5f | 981 | sbyte offset = (sbyte)GetMemory((ushort)(addr + 1)); |
davervw | 0:90de1cbc8a5f | 982 | *p_addr2 = (ushort)(addr + 2 + offset); |
davervw | 0:90de1cbc8a5f | 983 | snprintf(dis, dis_size, "%s $%04X", opcode, *p_addr2); |
davervw | 0:90de1cbc8a5f | 984 | } |
davervw | 0:90de1cbc8a5f | 985 | |
davervw | 0:90de1cbc8a5f | 986 | // JMP ($FFFF) |
davervw | 0:90de1cbc8a5f | 987 | // LDA $FFFF,X |
davervw | 0:90de1cbc8a5f | 988 | extern void DisassembleShort(ushort addr, bool *p_conditional, byte *p_bytes, ushort *p_addr2, char *dis, int dis_size) |
davervw | 0:90de1cbc8a5f | 989 | { |
davervw | 0:90de1cbc8a5f | 990 | *p_conditional = false; |
davervw | 0:90de1cbc8a5f | 991 | *p_addr2 = 0; |
davervw | 0:90de1cbc8a5f | 992 | *p_bytes = 1; |
davervw | 0:90de1cbc8a5f | 993 | |
davervw | 0:90de1cbc8a5f | 994 | switch (GetMemory(addr)) |
davervw | 0:90de1cbc8a5f | 995 | { |
davervw | 0:90de1cbc8a5f | 996 | case 0x00: strcpy_s(dis, dis_size, "BRK"); return; |
davervw | 0:90de1cbc8a5f | 997 | case 0x01: IndX(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 998 | case 0x05: ZP(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 999 | case 0x06: ZP(dis, dis_size, "ASL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1000 | case 0x08: strcpy_s(dis, dis_size, "PHP"); return; |
davervw | 0:90de1cbc8a5f | 1001 | case 0x09: IM(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1002 | case 0x0A: strcpy_s(dis, dis_size, "ASL A"); return; |
davervw | 0:90de1cbc8a5f | 1003 | case 0x0D: ABS(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1004 | case 0x0E: ABS(dis, dis_size, "ASL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1005 | |
davervw | 0:90de1cbc8a5f | 1006 | case 0x10: BRX(dis, dis_size, "BPL", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1007 | case 0x11: IndY(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1008 | case 0x15: ZPX(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1009 | case 0x16: ZPX(dis, dis_size, "ASL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1010 | case 0x18: strcpy_s(dis, dis_size, "CLC"); return; |
davervw | 0:90de1cbc8a5f | 1011 | case 0x19: ABSY(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1012 | case 0x1D: ABSX(dis, dis_size, "ORA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1013 | case 0x1E: ABSX(dis, dis_size, "ASL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1014 | |
davervw | 0:90de1cbc8a5f | 1015 | case 0x20: ABSAddr(dis, dis_size, "JSR", addr, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1016 | case 0x21: IndX(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1017 | case 0x24: ZP(dis, dis_size, "BIT", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1018 | case 0x25: ZP(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1019 | case 0x26: ZP(dis, dis_size, "ROL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1020 | case 0x28: strcpy_s(dis, dis_size, "PLP"); return; |
davervw | 0:90de1cbc8a5f | 1021 | case 0x29: IM(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1022 | case 0x2A: strcpy_s(dis, dis_size, "ROL A"); return; |
davervw | 0:90de1cbc8a5f | 1023 | case 0x2C: ABS(dis, dis_size, "BIT", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1024 | case 0x2D: ABS(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1025 | case 0x2E: ABS(dis, dis_size, "ROL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1026 | |
davervw | 0:90de1cbc8a5f | 1027 | case 0x30: BRX(dis, dis_size, "BMI", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1028 | case 0x31: IndY(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1029 | case 0x35: ZPX(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1030 | case 0x36: ZPX(dis, dis_size, "ROL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1031 | case 0x38: strcpy_s(dis, dis_size, "SEC"); return; |
davervw | 0:90de1cbc8a5f | 1032 | case 0x39: ABSY(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1033 | case 0x3D: ABSX(dis, dis_size, "AND", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1034 | case 0x3E: ABSX(dis, dis_size, "ROL", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1035 | |
davervw | 0:90de1cbc8a5f | 1036 | case 0x40: strcpy_s(dis, dis_size, "RTI"); return; |
davervw | 0:90de1cbc8a5f | 1037 | case 0x41: IndX(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1038 | case 0x45: ZP(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1039 | case 0x46: ZP(dis, dis_size, "LSR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1040 | case 0x48: strcpy_s(dis, dis_size, "PHA"); return; |
davervw | 0:90de1cbc8a5f | 1041 | case 0x49: IM(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1042 | case 0x4A: strcpy_s(dis, dis_size, "LSR A"); return; |
davervw | 0:90de1cbc8a5f | 1043 | case 0x4C: ABSAddr(dis, dis_size, "JMP", addr, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1044 | case 0x4D: ABS(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1045 | case 0x4E: ABS(dis, dis_size, "LSR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1046 | |
davervw | 0:90de1cbc8a5f | 1047 | case 0x50: BRX(dis, dis_size, "BVC", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1048 | case 0x51: IndY(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1049 | case 0x55: ZPX(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1050 | case 0x56: ZPX(dis, dis_size, "LSR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1051 | case 0x58: strcpy_s(dis, dis_size, "CLI"); return; |
davervw | 0:90de1cbc8a5f | 1052 | case 0x59: ABSY(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1053 | case 0x5D: ABSX(dis, dis_size, "EOR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1054 | case 0x5E: ABSX(dis, dis_size, "LSR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1055 | |
davervw | 0:90de1cbc8a5f | 1056 | case 0x60: strcpy_s(dis, dis_size, "RTS"); return; |
davervw | 0:90de1cbc8a5f | 1057 | case 0x61: IndX(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1058 | case 0x65: ZP(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1059 | case 0x66: ZP(dis, dis_size, "ROR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1060 | case 0x68: strcpy_s(dis, dis_size, "PLA"); return; |
davervw | 0:90de1cbc8a5f | 1061 | case 0x69: IM(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1062 | case 0x6A: strcpy_s(dis, dis_size, "ROR A"); return; |
davervw | 0:90de1cbc8a5f | 1063 | case 0x6C: Ind(dis, dis_size, "JMP", addr, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1064 | case 0x6D: ABS(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1065 | case 0x6E: ABS(dis, dis_size, "ROR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1066 | |
davervw | 0:90de1cbc8a5f | 1067 | case 0x70: BRX(dis, dis_size, "BVS", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1068 | case 0x71: IndY(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1069 | case 0x75: ZPX(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1070 | case 0x76: ZPX(dis, dis_size, "ROR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1071 | case 0x78: strcpy_s(dis, dis_size, "SEI"); return; |
davervw | 0:90de1cbc8a5f | 1072 | case 0x79: ABSY(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1073 | case 0x7D: ABSX(dis, dis_size, "ADC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1074 | case 0x7E: ABSX(dis, dis_size, "ROR", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1075 | |
davervw | 0:90de1cbc8a5f | 1076 | case 0x81: IndX(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1077 | case 0x84: ZP(dis, dis_size, "STY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1078 | case 0x85: ZP(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1079 | case 0x86: ZP(dis, dis_size, "STX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1080 | case 0x88: strcpy_s(dis, dis_size, "DEY"); return; |
davervw | 0:90de1cbc8a5f | 1081 | case 0x8A: strcpy_s(dis, dis_size, "TXA"); return; |
davervw | 0:90de1cbc8a5f | 1082 | case 0x8C: ABS(dis, dis_size, "STY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1083 | case 0x8D: ABS(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1084 | case 0x8E: ABS(dis, dis_size, "STX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1085 | |
davervw | 0:90de1cbc8a5f | 1086 | case 0x90: BRX(dis, dis_size, "BCC", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1087 | case 0x91: IndY(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1088 | case 0x94: ZPX(dis, dis_size, "STY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1089 | case 0x95: ZPX(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1090 | case 0x96: ZPY(dis, dis_size, "STX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1091 | case 0x98: strcpy_s(dis, dis_size, "TYA"); return; |
davervw | 0:90de1cbc8a5f | 1092 | case 0x99: ABSY(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1093 | case 0x9A: strcpy_s(dis, dis_size, "TXS"); return; |
davervw | 0:90de1cbc8a5f | 1094 | case 0x9D: ABSX(dis, dis_size, "STA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1095 | |
davervw | 0:90de1cbc8a5f | 1096 | case 0xA0: IM(dis, dis_size, "LDY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1097 | case 0xA1: IndX(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1098 | case 0xA2: IM(dis, dis_size, "LDX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1099 | case 0xA4: ZP(dis, dis_size, "LDY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1100 | case 0xA5: ZP(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1101 | case 0xA6: ZP(dis, dis_size, "LDX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1102 | case 0xA8: strcpy_s(dis, dis_size, "TAY"); return; |
davervw | 0:90de1cbc8a5f | 1103 | case 0xA9: IM(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1104 | case 0xAA: strcpy_s(dis, dis_size, "TAX"); return; |
davervw | 0:90de1cbc8a5f | 1105 | case 0xAC: ABS(dis, dis_size, "LDY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1106 | case 0xAD: ABS(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1107 | case 0xAE: ABS(dis, dis_size, "LDX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1108 | |
davervw | 0:90de1cbc8a5f | 1109 | case 0xB0: BRX(dis, dis_size, "BCS", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1110 | case 0xB1: IndY(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1111 | case 0xB4: ZPX(dis, dis_size, "LDY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1112 | case 0xB5: ZPX(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1113 | case 0xB6: ZPY(dis, dis_size, "LDX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1114 | case 0xB8: strcpy_s(dis, dis_size, "CLV"); return; |
davervw | 0:90de1cbc8a5f | 1115 | case 0xB9: ABSY(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1116 | case 0xBA: strcpy_s(dis, dis_size, "TSX"); return; |
davervw | 0:90de1cbc8a5f | 1117 | case 0xBC: ABSX(dis, dis_size, "LDY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1118 | case 0xBD: ABSX(dis, dis_size, "LDA", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1119 | case 0xBE: ABSY(dis, dis_size, "LDX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1120 | |
davervw | 0:90de1cbc8a5f | 1121 | case 0xC0: IM(dis, dis_size, "CPY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1122 | case 0xC1: IndX(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1123 | case 0xC4: ZP(dis, dis_size, "CPY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1124 | case 0xC5: ZP(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1125 | case 0xC6: ZP(dis, dis_size, "DEC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1126 | case 0xC8: strcpy_s(dis, dis_size, "INY"); return; |
davervw | 0:90de1cbc8a5f | 1127 | case 0xC9: IM(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1128 | case 0xCA: strcpy_s(dis, dis_size, "DEX"); return; |
davervw | 0:90de1cbc8a5f | 1129 | case 0xCC: ABS(dis, dis_size, "CPY", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1130 | case 0xCD: ABS(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1131 | case 0xCE: ABS(dis, dis_size, "DEC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1132 | |
davervw | 0:90de1cbc8a5f | 1133 | case 0xD0: BRX(dis, dis_size, "BNE", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1134 | case 0xD1: IndY(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1135 | case 0xD5: ZPX(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1136 | case 0xD6: ZPX(dis, dis_size, "DEC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1137 | case 0xD8: strcpy_s(dis, dis_size, "CLD"); return; |
davervw | 0:90de1cbc8a5f | 1138 | case 0xD9: ABSY(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1139 | case 0xDD: ABSX(dis, dis_size, "CMP", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1140 | case 0xDE: ABSX(dis, dis_size, "DEC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1141 | |
davervw | 0:90de1cbc8a5f | 1142 | case 0xE0: IM(dis, dis_size, "CPX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1143 | case 0xE1: IndX(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1144 | case 0xE4: ZP(dis, dis_size, "CPX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1145 | case 0xE5: ZP(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1146 | case 0xE6: ZP(dis, dis_size, "INC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1147 | case 0xE8: strcpy_s(dis, dis_size, "INX"); return; |
davervw | 0:90de1cbc8a5f | 1148 | case 0xE9: IM(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1149 | case 0xEA: strcpy_s(dis, dis_size, "NOP"); return; |
davervw | 0:90de1cbc8a5f | 1150 | case 0xEC: ABS(dis, dis_size, "CPX", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1151 | case 0xED: ABS(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1152 | case 0xEE: ABS(dis, dis_size, "INC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1153 | |
davervw | 0:90de1cbc8a5f | 1154 | case 0xF0: BRX(dis, dis_size, "BEQ", addr, p_conditional, p_addr2, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1155 | case 0xF1: IndY(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1156 | case 0xF5: ZPX(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1157 | case 0xF6: ZPX(dis, dis_size, "INC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1158 | case 0xF8: strcpy_s(dis, dis_size, "SED"); return; |
davervw | 0:90de1cbc8a5f | 1159 | case 0xF9: ABSY(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1160 | case 0xFD: ABSX(dis, dis_size, "SBC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1161 | case 0xFE: ABSX(dis, dis_size, "INC", addr, p_bytes); return; |
davervw | 0:90de1cbc8a5f | 1162 | |
davervw | 0:90de1cbc8a5f | 1163 | default: |
davervw | 0:90de1cbc8a5f | 1164 | strcpy_s(dis, dis_size, "???"); |
davervw | 0:90de1cbc8a5f | 1165 | return; |
davervw | 0:90de1cbc8a5f | 1166 | //throw new Exception(string.Format("Invalid opcode {0:X2}", memory[addr])); |
davervw | 0:90de1cbc8a5f | 1167 | } |
davervw | 0:90de1cbc8a5f | 1168 | } |