Created
July 11, 2024 14:42
-
-
Save ske2004/ba06d454332dd3aa48ad9c95cb519abc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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