Skip to content

Instantly share code, notes, and snippets.

@ske2004
Created July 11, 2024 14:42
Show Gist options
  • Save ske2004/ba06d454332dd3aa48ad9c95cb519abc to your computer and use it in GitHub Desktop.
Save ske2004/ba06d454332dd3aa48ad9c95cb519abc to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#define ADDR_MODE_COUNT 13
enum instr {
ADC, AND, ASL,
BCC, BCS, BEQ, BIT, BMI, BNE, BPL, BRK, BVC, BVS,
CLC, CLD, CLI, CLV, CMP, CPX, CPY,
DEC, DEX, DEY,
EOR,
INC, INX, INY,
JMP, JSR,
LDA, LDX, LDY, LSR,
NOP,
ORA,
PHA, PHP, PLA, PLP,
ROL, ROR, RTI, RTS,
SBC, SEC, SED, SEI, STA, STX, STY,
TAX, TAY, TSX, TXA, TXS, TYA, _ICOUNT
};
const char *strmap[] = {
"ADC", "AND", "ASL",
"BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRK", "BVC", "BVS",
"CLC", "CLD", "CLI", "CLV", "CMP", "CPX", "CPY",
"DEC", "DEX", "DEY",
"EOR",
"INC", "INX", "INY",
"JMP", "JSR",
"LDA", "LDX", "LDY", "LSR",
"NOP",
"ORA",
"PHA", "PHP", "PLA", "PLP",
"ROL", "ROR", "RTI", "RTS",
"SBC", "SEC", "SED", "SEI", "STA", "STX", "STY",
"TAX", "TAY", "TSX", "TXA", "TXS", "TYA",
};
// 0xFF - Invalid addressing mode
// Addressing modes in this order:
// Acc Abs AbX AbY Imm Imp Ind Xnd InY Rel Zpg ZpX ZpY
const uint8_t opctbl[] = {
/*ADC*/ 0xFF,0x6D,0x7D,0x79,0x69,0xFF,0xFF,0x61,0x71,0xFF,0x65,0x75,0xFF,
/*AND*/ 0xFF,0x2D,0x3D,0x39,0x29,0xFF,0xFF,0x21,0x31,0xFF,0x25,0x35,0xFF,
/*ASL*/ 0x0A,0x0E,0x1E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x06,0x16,0xFF,
/*BCC*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x90,0xFF,0xFF,0xFF,
/*BCS*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xB0,0xFF,0xFF,0xFF,
/*BEQ*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xF0,0xFF,0xFF,0xFF,
/*BIT*/ 0xFF,0x2C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x24,0xFF,0xFF,
/*BMI*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x30,0xFF,0xFF,0xFF,
/*BNE*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xD0,0xFF,0xFF,0xFF,
/*BPL*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x10,0xFF,0xFF,0xFF,
/*BRK*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*BVC*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x50,0xFF,0xFF,0xFF,
/*BVS*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x70,0xFF,0xFF,0xFF,
/*CLC*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x18,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*CLD*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xD8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*CLI*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x58,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*CLV*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xB8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*CMP*/ 0xFF,0xCD,0xDD,0xD9,0xC9,0xFF,0xFF,0xC1,0xD1,0xFF,0xC5,0xD5,0xFF,
/*CPX*/ 0xFF,0xEC,0xFF,0xFF,0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xE4,0xFF,0xFF,
/*CPY*/ 0xFF,0xCC,0xFF,0xFF,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC4,0xFF,0xFF,
/*DEC*/ 0xFF,0xCE,0xDE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC6,0xD6,0xFF,
/*DEX*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xCA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*DEY*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x88,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*EOR*/ 0xFF,0x4D,0x5D,0x59,0x49,0xFF,0xFF,0x41,0x51,0xFF,0x45,0x55,0xFF,
/*INC*/ 0xFF,0xEE,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE6,0xF6,0xFF,
/*INX*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xE8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*INY*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*JMP*/ 0xFF,0x4C,0xFF,0xFF,0xFF,0xFF,0x6C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*JSR*/ 0xFF,0x20,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*LDA*/ 0xFF,0xAD,0xBD,0xB9,0xA9,0xFF,0xFF,0xA1,0xB1,0xFF,0xA5,0xB5,0xFF,
/*LDX*/ 0xFF,0xAE,0xFF,0xBE,0xA2,0xFF,0xFF,0xFF,0xFF,0xFF,0xA6,0xFF,0xB6,
/*LDY*/ 0xFF,0xAC,0xBC,0xFF,0xA0,0xFF,0xFF,0xFF,0xFF,0xFF,0xA4,0xB4,0xFF,
/*LSR*/ 0x4A,0x4E,0x5E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x46,0x56,0xFF,
/*NOP*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xEA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*ORA*/ 0xFF,0x0D,0x1D,0x19,0x09,0xFF,0xFF,0x01,0x11,0xFF,0x05,0x15,0xFF,
/*PHA*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x48,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*PHP*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x08,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*PLA*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x68,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*PLP*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x28,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*ROL*/ 0x2A,0x2E,0x3E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x26,0x36,0xFF,
/*ROR*/ 0x6A,0x6E,0x7E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x66,0x76,0xFF,
/*RTI*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x40,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*RTS*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x60,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*SBC*/ 0xFF,0xED,0xFD,0xF9,0xE9,0xFF,0xFF,0xE1,0xF1,0xFF,0xE5,0xF5,0xFF,
/*SEC*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x38,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*SED*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*SEI*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x78,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*STA*/ 0xFF,0x8D,0x9D,0x99,0xFF,0xFF,0xFF,0x81,0x91,0xFF,0x85,0x95,0xFF,
/*STX*/ 0xFF,0x8E,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x86,0xFF,0x96,
/*STY*/ 0xFF,0x8C,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x84,0x94,0xFF,
/*TAX*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xAA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*TAY*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xA8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*TSX*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0xBA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*TXA*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x8A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*TXS*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x9A,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
/*TYA*/ 0xFF,0xFF,0xFF,0xFF,0xFF,0x98,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
uint8_t instrtbl[256];
uint8_t addrtbl[256];
uint8_t *data;
void p_acc() { printf("A"); }
void p_abs() { printf("$%04X", ((uint16_t*)data)[0]); data += 2; }
void p_abx() { printf("$%04X,X", ((uint16_t*)data)[0]); data += 2; }
void p_aby() { printf("$%04X,Y", ((uint16_t*)data)[0]); data += 2; }
void p_imm() { printf("#$%02X", data[0]); data += 1; }
void p_imp() { }
void p_ind() { printf("($%04X)", ((uint16_t*)data)[0]); data += 2; }
void p_xnd() { printf("($%02X,X)", data[0]); data += 1; }
void p_iny() { printf("($%02X),Y", data[0]); data += 1; }
void p_rel() { printf("$%02X", data[0]); data += 1; }
void p_zpg() { printf("$%02X", data[0]); data += 1; }
void p_zpx() { printf("$%02X,X", data[0]); data += 1; }
void p_zpy() { printf("$%02X,Y", data[0]); data += 1; }
void (*printers[])() = { p_acc, p_abs, p_abx, p_aby, p_imm, p_imp, p_ind, p_xnd, p_iny, p_rel, p_zpg, p_zpx, p_zpy };
int main(int argc, char **argv) {
if (argc != 2) {
fprintf(stderr, "Usage: %s <6502 binary>\n", argv[0]);
return 1;
}
FILE *fp = fopen(argv[1], "rb");
if (!fp) {
perror(argv[1]);
return 1;
}
fseek(fp, 0, SEEK_END);
size_t fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
uint8_t *mem = malloc(fsize);
fread(mem, 1, fsize, fp);
fclose(fp);
data = mem;
memset(instrtbl, 0xFF, sizeof(instrtbl));
memset(addrtbl, 0xFF, sizeof(addrtbl));
for (int i = 0; i < ADDR_MODE_COUNT*_ICOUNT; i++) {
if (opctbl[i] != 0xFF) {
instrtbl[opctbl[i]] = i/ADDR_MODE_COUNT;
addrtbl[opctbl[i]] = i%ADDR_MODE_COUNT;
}
}
while (data-mem < fsize) {
uint8_t opc = *data++;
if (instrtbl[opc] == 0xFF) {
printf("Invalid instruction: $%X\n", opc);
break;
}
if (addrtbl[opc] == 0xFF) {
printf("Invalid addressing mode for %s\n", strmap[instrtbl[opc]]);
break;
}
printf("%s ", strmap[instrtbl[opc]]);
printers[addrtbl[opc]]();
printf("\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment