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@4:8476be802690, 2020-04-13 (annotated)
- Committer:
- davervw
- Date:
- Mon Apr 13 05:36:43 2020 +0000
- Revision:
- 4:8476be802690
- Parent:
- 0:90de1cbc8a5f
- Child:
- 9:a0c6747e539f
terminal console portable version ported to specifically support STM32F429 Discovery board with included 320x240 LCD, and using USBHOST HID keyboard too. So, full screen editing, commodore fonts, color, and keyboard, with STOP key (ESC), and IRQs.
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 | } |