fork of PCE focusing on macplus, supporting DaynaPort SCSI network emulation
at master 415 lines 18 kB view raw
1/***************************************************************************** 2 * pce * 3 *****************************************************************************/ 4 5/***************************************************************************** 6 * File name: src/cpu/e6502/disasm.c * 7 * Created: 2004-05-25 by Hampa Hug <hampa@hampa.ch> * 8 * Copyright: (C) 2004-2022 Hampa Hug <hampa@hampa.ch> * 9 *****************************************************************************/ 10 11/***************************************************************************** 12 * This program is free software. You can redistribute it and / or modify it * 13 * under the terms of the GNU General Public License version 2 as published * 14 * by the Free Software Foundation. * 15 * * 16 * This program is distributed in the hope that it will be useful, but * 17 * WITHOUT ANY WARRANTY, without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General * 19 * Public License for more details. * 20 *****************************************************************************/ 21 22 23#include <string.h> 24 25#include "e6502.h" 26#include "internal.h" 27 28 29#define E6502_MODE_IMP 1 30#define E6502_MODE_IMM 2 31#define E6502_MODE_ZPG 3 32#define E6502_MODE_ZPG_X 4 33#define E6502_MODE_ZPG_Y 5 34#define E6502_MODE_ABS 6 35#define E6502_MODE_ABS_Y 7 36#define E6502_MODE_ABS_X 8 37#define E6502_MODE_IDX_IND_X 9 38#define E6502_MODE_IND_IDX_Y 10 39#define E6502_MODE_DB 11 40#define E6502_MODE_BRA 12 41#define E6502_MODE_JMP 13 42#define E6502_MODE_A 14 43 44 45typedef struct { 46 unsigned char opcode; 47 const char *mnemonic; 48 unsigned char mode; 49 unsigned char size; 50 unsigned char cycles; 51 unsigned flags; 52} e6502_dop_t; 53 54static 55e6502_dop_t doptab[256] = { 56 { 0x00, "BRK", E6502_MODE_IMP, 1, 7, 0 }, 57 { 0x01, "ORA", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 58 { 0x02, "DB", E6502_MODE_DB, 1, 1, 0 }, 59 { 0x03, "SLO", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND }, 60 { 0x04, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND }, 61 { 0x05, "ORA", E6502_MODE_ZPG, 2, 3, 0 }, 62 { 0x06, "ASL", E6502_MODE_ZPG, 2, 5, 0 }, 63 { 0x07, "SLO", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND }, 64 { 0x08, "PHP", E6502_MODE_IMP, 1, 3, 0 }, 65 { 0x09, "ORA", E6502_MODE_IMM, 2, 2, 0 }, 66 { 0x0a, "ASL", E6502_MODE_A, 1, 2, 0 }, 67 { 0x0b, "DB", E6502_MODE_DB, 1, 1, 0 }, 68 { 0x0c, "NOP", E6502_MODE_ABS, 3, 4, E6502_OPF_UND }, 69 { 0x0d, "ORA", E6502_MODE_ABS, 3, 4, 0 }, 70 { 0x0e, "ASL", E6502_MODE_ABS, 3, 6, 0 }, 71 { 0x0f, "SLO", E6502_MODE_ABS, 3, 6, E6502_OPF_UND }, 72 { 0x10, "BPL", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 73 { 0x11, "ORA", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 74 { 0x12, "DB", E6502_MODE_DB, 1, 1, 0 }, 75 { 0x13, "SLO", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND }, 76 { 0x14, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 77 { 0x15, "ORA", E6502_MODE_ZPG_X, 2, 4, 0 }, 78 { 0x16, "ASL", E6502_MODE_ZPG_X, 2, 6, 0 }, 79 { 0x17, "SLO", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND }, 80 { 0x18, "CLC", E6502_MODE_IMP, 1, 2, 0 }, 81 { 0x19, "ORA", E6502_MODE_ABS_Y, 3, 4, 0 }, 82 { 0x1a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 83 { 0x1b, "SLO", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND }, 84 { 0x1c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 85 { 0x1d, "ORA", E6502_MODE_ABS_X, 3, 4, 0 }, 86 { 0x1e, "ASL", E6502_MODE_ABS_X, 3, 7, 0 }, 87 { 0x1f, "SLO", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND }, 88 { 0x20, "JSR", E6502_MODE_JMP, 3, 6, E6502_OPF_JSR }, 89 { 0x21, "AND", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 90 { 0x22, "DB", E6502_MODE_DB, 1, 1, 0 }, 91 { 0x23, "RLA", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND }, 92 { 0x24, "BIT", E6502_MODE_ZPG, 2, 3, 0 }, 93 { 0x25, "AND", E6502_MODE_ZPG, 2, 3, 0 }, 94 { 0x26, "ROL", E6502_MODE_ZPG, 2, 5, 0 }, 95 { 0x27, "RLA", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND }, 96 { 0x28, "PLP", E6502_MODE_IMP, 1, 4, 0 }, 97 { 0x29, "AND", E6502_MODE_IMM, 2, 2, 0 }, 98 { 0x2a, "ROL", E6502_MODE_A, 1, 2, 0 }, 99 { 0x2b, "DB", E6502_MODE_DB, 1, 1, 0 }, 100 { 0x2c, "BIT", E6502_MODE_ABS, 3, 4, 0 }, 101 { 0x2d, "AND", E6502_MODE_ABS, 3, 4, 0 }, 102 { 0x2e, "ROL", E6502_MODE_ABS, 3, 6, 0 }, 103 { 0x2f, "RLA", E6502_MODE_ABS, 3, 6, E6502_OPF_UND }, 104 { 0x30, "BMI", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 105 { 0x31, "AND", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 106 { 0x32, "DB", E6502_MODE_DB, 1, 1, 0 }, 107 { 0x33, "RLA", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND }, 108 { 0x34, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 109 { 0x35, "AND", E6502_MODE_ZPG_X, 2, 4, 0 }, 110 { 0x36, "ROL", E6502_MODE_ZPG_X, 2, 6, 0 }, 111 { 0x37, "RLA", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND }, 112 { 0x38, "SEC", E6502_MODE_IMP, 1, 2, 0 }, 113 { 0x39, "AND", E6502_MODE_ABS_Y, 3, 4, 0 }, 114 { 0x3a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 115 { 0x3b, "RLA", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND }, 116 { 0x3c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 117 { 0x3d, "AND", E6502_MODE_ABS_X, 3, 4, 0 }, 118 { 0x3e, "ROL", E6502_MODE_ABS_X, 3, 7, 0 }, 119 { 0x3f, "RLA", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND }, 120 { 0x40, "RTI", E6502_MODE_IMP, 1, 6, E6502_OPF_RTI }, 121 { 0x41, "EOR", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 122 { 0x42, "DB", E6502_MODE_DB, 1, 1, 0 }, 123 { 0x43, "SRE", E6502_MODE_IDX_IND_X, 2, 8, E6502_OPF_UND }, 124 { 0x44, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND }, 125 { 0x45, "EOR", E6502_MODE_ZPG, 2, 3, 0 }, 126 { 0x46, "LSR", E6502_MODE_ZPG, 2, 5, 0 }, 127 { 0x47, "SRE", E6502_MODE_ZPG, 2, 5, E6502_OPF_UND }, 128 { 0x48, "PHA", E6502_MODE_IMP, 1, 3, 0 }, 129 { 0x49, "EOR", E6502_MODE_IMM, 2, 2, 0 }, 130 { 0x4a, "LSR", E6502_MODE_A, 1, 2, 0 }, 131 { 0x4b, "DB", E6502_MODE_DB, 1, 1, 0 }, 132 { 0x4c, "JMP", E6502_MODE_JMP, 3, 3, E6502_OPF_BRA }, 133 { 0x4d, "EOR", E6502_MODE_ABS, 3, 4, 0 }, 134 { 0x4e, "LSR", E6502_MODE_ABS, 3, 6, 0 }, 135 { 0x4f, "SRE", E6502_MODE_ABS, 3, 6, E6502_OPF_UND }, 136 { 0x50, "BVC", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 137 { 0x51, "EOR", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 138 { 0x52, "DB", E6502_MODE_DB, 1, 1, 0 }, 139 { 0x53, "SRE", E6502_MODE_IND_IDX_Y, 2, 8, E6502_OPF_UND }, 140 { 0x54, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 141 { 0x55, "EOR", E6502_MODE_ZPG_X, 2, 4, 0 }, 142 { 0x56, "LSR", E6502_MODE_ZPG_X, 2, 6, 0 }, 143 { 0x57, "SRE", E6502_MODE_ZPG_X, 2, 6, E6502_OPF_UND }, 144 { 0x58, "CLI", E6502_MODE_IMP, 1, 2, 0 }, 145 { 0x59, "EOR", E6502_MODE_ABS_Y, 3, 4, 0 }, 146 { 0x5a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 147 { 0x5b, "SRE", E6502_MODE_ABS_Y, 3, 7, E6502_OPF_UND }, 148 { 0x5c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 149 { 0x5d, "EOR", E6502_MODE_IDX_IND_X, 3, 4, 0 }, 150 { 0x5e, "LSR", E6502_MODE_ABS_X, 3, 7, 0 }, 151 { 0x5f, "SRE", E6502_MODE_ABS_X, 3, 7, E6502_OPF_UND }, 152 { 0x60, "RTS", E6502_MODE_IMP, 1, 6, E6502_OPF_RTS }, 153 { 0x61, "ADC", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 154 { 0x62, "DB", E6502_MODE_DB, 1, 1, 0 }, 155 { 0x63, "DB", E6502_MODE_DB, 1, 1, 0 }, 156 { 0x64, "NOP", E6502_MODE_ZPG, 2, 3, E6502_OPF_UND }, 157 { 0x65, "ADC", E6502_MODE_ZPG, 2, 3, 0 }, 158 { 0x66, "ROR", E6502_MODE_ZPG, 2, 5, 0 }, 159 { 0x67, "DB", E6502_MODE_DB, 1, 1, 0 }, 160 { 0x68, "PLA", E6502_MODE_IMP, 1, 4, 0 }, 161 { 0x69, "ADC", E6502_MODE_IMM, 2, 2, 0 }, 162 { 0x6a, "ROR", E6502_MODE_A, 1, 2, 0 }, 163 { 0x6b, "DB", E6502_MODE_DB, 1, 1, 0 }, 164 { 0x6c, "JMP", E6502_MODE_ABS, 3, 5, E6502_OPF_BRA }, 165 { 0x6d, "ADC", E6502_MODE_ABS, 3, 4, 0 }, 166 { 0x6e, "ROR", E6502_MODE_ABS, 3, 6, 0 }, 167 { 0x6f, "DB", E6502_MODE_DB, 1, 1, 0 }, 168 { 0x70, "BVS", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 169 { 0x71, "ADC", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 170 { 0x72, "DB", E6502_MODE_DB, 1, 1, 0 }, 171 { 0x73, "DB", E6502_MODE_DB, 1, 1, 0 }, 172 { 0x74, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 173 { 0x75, "ADC", E6502_MODE_ZPG_X, 2, 4, 0 }, 174 { 0x76, "ROR", E6502_MODE_ZPG_X, 2, 6, 0 }, 175 { 0x77, "DB", E6502_MODE_DB, 1, 1, 0 }, 176 { 0x78, "SEI", E6502_MODE_IMP, 1, 2, 0 }, 177 { 0x79, "ADC", E6502_MODE_ABS_Y, 3, 4, 0 }, 178 { 0x7a, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 179 { 0x7b, "DB", E6502_MODE_DB, 1, 1, 0 }, 180 { 0x7c, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 181 { 0x7d, "ADC", E6502_MODE_ABS_X, 3, 4, 0 }, 182 { 0x7e, "ROR", E6502_MODE_ABS_X, 3, 7, 0 }, 183 { 0x7f, "DB", E6502_MODE_DB, 1, 1, 0 }, 184 { 0x80, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND }, 185 { 0x81, "STA", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 186 { 0x82, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND }, 187 { 0x83, "DB", E6502_MODE_DB, 1, 1, 0 }, 188 { 0x84, "STY", E6502_MODE_ZPG, 2, 3, 0 }, 189 { 0x85, "STA", E6502_MODE_ZPG, 2, 3, 0 }, 190 { 0x86, "STX", E6502_MODE_ZPG, 2, 3, 0 }, 191 { 0x87, "DB", E6502_MODE_DB, 1, 1, 0 }, 192 { 0x88, "DEY", E6502_MODE_IMP, 1, 2, 0 }, 193 { 0x89, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND }, 194 { 0x8a, "TXA", E6502_MODE_IMP, 1, 2, 0 }, 195 { 0x8b, "DB", E6502_MODE_DB, 1, 1, 0 }, 196 { 0x8c, "STY", E6502_MODE_ABS, 3, 4, 0 }, 197 { 0x8d, "STA", E6502_MODE_ABS, 3, 4, 0 }, 198 { 0x8e, "STX", E6502_MODE_ABS, 3, 4, 0 }, 199 { 0x8f, "DB", E6502_MODE_DB, 1, 1, 0 }, 200 { 0x90, "BCC", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 201 { 0x91, "STA", E6502_MODE_IND_IDX_Y, 2, 6, 0 }, 202 { 0x92, "DB", E6502_MODE_DB, 1, 1, 0 }, 203 { 0x93, "DB", E6502_MODE_DB, 1, 1, 0 }, 204 { 0x94, "STY", E6502_MODE_ZPG_X, 2, 4, 0 }, 205 { 0x95, "STA", E6502_MODE_ZPG_X, 2, 4, 0 }, 206 { 0x96, "STX", E6502_MODE_ZPG_Y, 2, 4, 0 }, 207 { 0x97, "DB", E6502_MODE_DB, 1, 1, 0 }, 208 { 0x98, "TYA", E6502_MODE_IMP, 1, 2, 0 }, 209 { 0x99, "STA", E6502_MODE_ABS_Y, 3, 5, 0 }, 210 { 0x9a, "TXS", E6502_MODE_IMP, 1, 2, 0 }, 211 { 0x9b, "DB", E6502_MODE_DB, 1, 1, 0 }, 212 { 0x9c, "DB", E6502_MODE_DB, 1, 1, 0 }, 213 { 0x9d, "STA", E6502_MODE_ABS_X, 3, 5, 0 }, 214 { 0x9e, "DB", E6502_MODE_DB, 1, 1, 0 }, 215 { 0x9f, "DB", E6502_MODE_DB, 1, 1, 0 }, 216 { 0xa0, "LDY", E6502_MODE_IMM, 2, 2, 0 }, 217 { 0xa1, "LDA", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 218 { 0xa2, "LDX", E6502_MODE_IMM, 2, 2, 0 }, 219 { 0xa3, "DB", E6502_MODE_DB, 1, 1, 0 }, 220 { 0xa4, "LDY", E6502_MODE_ZPG, 2, 3, 0 }, 221 { 0xa5, "LDA", E6502_MODE_ZPG, 2, 3, 0 }, 222 { 0xa6, "LDX", E6502_MODE_ZPG, 2, 3, 0 }, 223 { 0xa7, "DB", E6502_MODE_DB, 1, 1, 0 }, 224 { 0xa8, "TAY", E6502_MODE_IMP, 1, 2, 0 }, 225 { 0xa9, "LDA", E6502_MODE_IMM, 2, 2, 0 }, 226 { 0xaa, "TAX", E6502_MODE_IMP, 1, 2, 0 }, 227 { 0xab, "DB", E6502_MODE_DB, 1, 1, 0 }, 228 { 0xac, "LDY", E6502_MODE_ABS, 3, 4, 0 }, 229 { 0xad, "LDA", E6502_MODE_ABS, 3, 4, 0 }, 230 { 0xae, "LDX", E6502_MODE_ABS, 3, 4, 0 }, 231 { 0xaf, "DB", E6502_MODE_DB, 1, 1, 0 }, 232 { 0xb0, "BCS", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 233 { 0xb1, "LDA", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 234 { 0xb2, "DB", E6502_MODE_DB, 1, 1, 0 }, 235 { 0xb3, "DB", E6502_MODE_DB, 1, 1, 0 }, 236 { 0xb4, "LDY", E6502_MODE_ZPG_X, 2, 4, 0 }, 237 { 0xb5, "LDA", E6502_MODE_ZPG_X, 2, 4, 0 }, 238 { 0xb6, "LDX", E6502_MODE_ZPG_Y, 2, 4, 0 }, 239 { 0xb7, "DB", E6502_MODE_DB, 1, 1, 0 }, 240 { 0xb8, "CLV", E6502_MODE_IMP, 1, 2, 0 }, 241 { 0xb9, "LDA", E6502_MODE_ABS_Y, 3, 4, 0 }, 242 { 0xba, "TSX", E6502_MODE_IMP, 1, 2, 0 }, 243 { 0xbb, "DB", E6502_MODE_DB, 1, 1, 0 }, 244 { 0xbc, "LDY", E6502_MODE_ABS_X, 3, 4, 0 }, 245 { 0xbd, "LDA", E6502_MODE_ABS_X, 3, 4, 0 }, 246 { 0xbe, "LDX", E6502_MODE_ABS_Y, 3, 4, 0 }, 247 { 0xbf, "DB", E6502_MODE_DB, 1, 1, 0 }, 248 { 0xc0, "CPY", E6502_MODE_IMM, 2, 2, 0 }, 249 { 0xc1, "CMP", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 250 { 0xc2, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND }, 251 { 0xc3, "DB", E6502_MODE_DB, 1, 1, 0 }, 252 { 0xc4, "CPY", E6502_MODE_ZPG, 2, 3, 0 }, 253 { 0xc5, "CMP", E6502_MODE_ZPG, 2, 3, 0 }, 254 { 0xc6, "DEC", E6502_MODE_ZPG, 2, 5, 0 }, 255 { 0xc7, "DB", E6502_MODE_DB, 1, 1, 0 }, 256 { 0xc8, "INY", E6502_MODE_IMP, 1, 2, 0 }, 257 { 0xc9, "CMP", E6502_MODE_IMM, 2, 2, 0 }, 258 { 0xca, "DEX", E6502_MODE_IMP, 1, 2, 0 }, 259 { 0xcb, "DB", E6502_MODE_DB, 1, 1, 0 }, 260 { 0xcc, "CPY", E6502_MODE_ABS, 3, 4, 0 }, 261 { 0xcd, "CMP", E6502_MODE_ABS, 3, 4, 0 }, 262 { 0xce, "DEC", E6502_MODE_ABS, 3, 6, 0 }, 263 { 0xcf, "DB", E6502_MODE_DB, 1, 1, 0 }, 264 { 0xd0, "BNE", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 265 { 0xd1, "CMP", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 266 { 0xd2, "DB", E6502_MODE_DB, 1, 1, 0 }, 267 { 0xd3, "DB", E6502_MODE_DB, 1, 1, 0 }, 268 { 0xd4, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 269 { 0xd5, "CMP", E6502_MODE_ZPG_X, 2, 4, 0 }, 270 { 0xd6, "DEC", E6502_MODE_ZPG_X, 2, 6, 0 }, 271 { 0xd7, "DB", E6502_MODE_DB, 1, 1, 0 }, 272 { 0xd8, "CLD", E6502_MODE_IMP, 1, 2, 0 }, 273 { 0xd9, "CMP", E6502_MODE_ABS_Y, 3, 4, 0 }, 274 { 0xda, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 275 { 0xdb, "DB", E6502_MODE_DB, 1, 1, 0 }, 276 { 0xdc, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 277 { 0xdd, "CMP", E6502_MODE_ABS_X, 3, 4, 0 }, 278 { 0xde, "DEC", E6502_MODE_ABS_X, 3, 7, 0 }, 279 { 0xdf, "DB", E6502_MODE_DB, 1, 1, 0 }, 280 { 0xe0, "CPX", E6502_MODE_IMM, 2, 2, 0 }, 281 { 0xe1, "SBC", E6502_MODE_IDX_IND_X, 2, 6, 0 }, 282 { 0xe2, "NOP", E6502_MODE_IMM, 2, 2, E6502_OPF_UND }, 283 { 0xe3, "DB", E6502_MODE_DB, 1, 1, 0 }, 284 { 0xe4, "CPX", E6502_MODE_ZPG, 2, 3, 0 }, 285 { 0xe5, "SBC", E6502_MODE_ZPG, 2, 3, 0 }, 286 { 0xe6, "INC", E6502_MODE_ZPG, 2, 5, 0 }, 287 { 0xe7, "DB", E6502_MODE_DB, 1, 1, 0 }, 288 { 0xe8, "INX", E6502_MODE_IMP, 1, 2, 0 }, 289 { 0xe9, "SBC", E6502_MODE_IMM, 2, 2, 0 }, 290 { 0xea, "NOP", E6502_MODE_IMP, 1, 2, 0 }, 291 { 0xeb, "DB", E6502_MODE_DB, 1, 1, 0 }, 292 { 0xec, "CPX", E6502_MODE_ABS, 3, 4, 0 }, 293 { 0xed, "SBC", E6502_MODE_ABS, 3, 4, 0 }, 294 { 0xee, "INC", E6502_MODE_ABS, 3, 6, 0 }, 295 { 0xef, "DB", E6502_MODE_DB, 1, 1, 0 }, 296 { 0xf0, "BEQ", E6502_MODE_BRA, 2, 2, E6502_OPF_BRA }, 297 { 0xf1, "SBC", E6502_MODE_IND_IDX_Y, 2, 5, 0 }, 298 { 0xf2, "DB", E6502_MODE_DB, 1, 1, 0 }, 299 { 0xf3, "DB", E6502_MODE_DB, 1, 1, 0 }, 300 { 0xf4, "NOP", E6502_MODE_ZPG_X, 2, 4, E6502_OPF_UND }, 301 { 0xf5, "SBC", E6502_MODE_ZPG_X, 2, 4, 0 }, 302 { 0xf6, "INC", E6502_MODE_ZPG_X, 2, 6, 0 }, 303 { 0xf7, "DB", E6502_MODE_DB, 1, 1, 0 }, 304 { 0xf8, "SED", E6502_MODE_IMP, 1, 2, 0 }, 305 { 0xf9, "SBC", E6502_MODE_ABS_Y, 3, 4, 0 }, 306 { 0xfa, "NOP", E6502_MODE_IMP, 1, 2, E6502_OPF_UND }, 307 { 0xfb, "DB", E6502_MODE_DB, 1, 1, 0 }, 308 { 0xfc, "NOP", E6502_MODE_ABS_X, 3, 4, E6502_OPF_UND }, 309 { 0xfd, "SBC", E6502_MODE_ABS_X, 3, 4, 0 }, 310 { 0xfe, "INC", E6502_MODE_ABS_X, 3, 7, 0 }, 311 { 0xff, "DB", E6502_MODE_DB, 1, 1, 0 } 312}; 313 314 315void e6502_disasm (e6502_disasm_t *op, unsigned char *src, unsigned short pc) 316{ 317 unsigned i; 318 unsigned opc; 319 e6502_dop_t *tab; 320 321 opc = src[0] & 0xff; 322 tab = &doptab[opc]; 323 324 op->pc = pc; 325 op->flags = tab->flags; 326 op->dat_n = tab->size; 327 op->arg_n = 1; 328 329 strcpy (op->op, tab->mnemonic); 330 331 for (i = 0; i < tab->size; i++) { 332 op->dat[i] = src[i]; 333 } 334 335 switch (tab->mode) { 336 case E6502_MODE_IDX_IND_X: 337 sprintf (op->arg1, "[[%02x + X]]", (unsigned) src[1]); 338 break; 339 340 case E6502_MODE_ZPG: 341 sprintf (op->arg1, "[%02x]", (unsigned) src[1]); 342 break; 343 344 case E6502_MODE_IMM: 345 sprintf (op->arg1, "#%02X", src[1] & 0xff); 346 break; 347 348 case E6502_MODE_ABS: 349 sprintf (op->arg1, "[%04X]", (unsigned) e6502_mk_uint16 (src[1], src[2])); 350 break; 351 352 case E6502_MODE_IND_IDX_Y: 353 sprintf (op->arg1, "[[%02X] + Y]", (unsigned) src[1]); 354 break; 355 356 case E6502_MODE_ZPG_X: 357 sprintf (op->arg1, "[%02X + X]", (unsigned) src[1]); 358 break; 359 360 case E6502_MODE_ZPG_Y: 361 sprintf (op->arg1, "[%02X + Y]", (unsigned) src[1]); 362 break; 363 364 case E6502_MODE_ABS_Y: 365 sprintf (op->arg1, "[%04X + Y]", (unsigned) e6502_mk_uint16 (src[1], src[2])); 366 break; 367 368 case E6502_MODE_ABS_X: 369 sprintf (op->arg1, "[%04X + X]", (unsigned) e6502_mk_uint16 (src[1], src[2])); 370 break; 371 372 case E6502_MODE_IMP: 373 op->arg_n = 0; 374 break; 375 376 case E6502_MODE_DB: 377 sprintf (op->arg1, "#%02X", src[0] & 0xff); 378 break; 379 380 case E6502_MODE_BRA: 381 sprintf (op->arg1, "%04X", 382 (unsigned) ((op->pc + 2 + e6502_mk_sint16 (src[1])) & 0xffff) 383 ); 384 break; 385 386 case E6502_MODE_JMP: 387 sprintf (op->arg1, "%04X", (unsigned) e6502_mk_uint16 (src[1], src[2])); 388 break; 389 390 case E6502_MODE_A: 391 strcpy (op->arg1, "A"); 392 break; 393 394 default: 395 strcpy (op->arg1, "???"); 396 break; 397 } 398} 399 400void e6502_disasm_mem (e6502_t *c, e6502_disasm_t *op, unsigned short pc) 401{ 402 unsigned i; 403 unsigned char src[4]; 404 405 for (i = 0; i < 4; i++) { 406 src[i] = e6502_get_mem8 (c, (pc + i) & 0xffff); 407 } 408 409 e6502_disasm (op, src, pc); 410} 411 412void e6502_disasm_cur (e6502_t *c, e6502_disasm_t *op) 413{ 414 e6502_disasm_mem (c, op, e6502_get_pc (c)); 415}