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