Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- // <Alcaro> yeah you're not going to make me install yiff in alcarobot.
- enum AddressingModes {
- Implied,
- Zeropage,
- ZeropageX,
- ZeropageY,
- Immediate,
- Absolute,
- AbsoluteX,
- AbsoluteY,
- Relative,
- Indirect,
- IndirectX,
- IndirectY
- };
- static struct Opcode {
- unsigned char Code;
- char *Name;
- char Mode;
- } Opcodes[] = {
- {0x00, "BRK" ,Implied},
- {0x01, "ORA" ,IndirectX},
- {0x02, "KIL" ,Implied},
- {0x03, "SLO" ,IndirectX},
- {0x04, "DOP" ,Zeropage},
- {0x05, "ORA" ,Zeropage},
- {0x06, "ASL" ,Zeropage},
- {0x07, "SLO" ,Zeropage},
- {0x08, "PHP" ,Implied},
- {0x09, "ORA" ,Immediate},
- {0x0A, "ASL" ,Implied},
- {0x0B, "ANC" ,Immediate},
- {0x0C, "NOP" ,Absolute},
- {0x0D, "ORA" ,Absolute},
- {0x0E, "ASL" ,Absolute},
- {0x0F, "SLO" ,Absolute},
- {0x10, "BPL" ,Relative},
- {0x11, "ORA" ,IndirectY},
- {0x12, "KIL" ,Implied},
- {0x13, "SLO" ,IndirectY},
- {0x14, "NOP" ,ZeropageX},
- {0x15, "ORA" ,ZeropageX},
- {0x16, "ASL" ,ZeropageX},
- {0x17, "SLO" ,ZeropageX},
- {0x18, "CLC" ,Implied},
- {0x19, "ORA" ,AbsoluteY},
- {0x1A, "NOP" ,Implied},
- {0x1B, "SLO" ,AbsoluteY},
- {0x1C, "NOP" ,AbsoluteX},
- {0x1D, "ORA" ,AbsoluteX},
- {0x1E, "ASL" ,AbsoluteX},
- {0x1F, "SLO" ,AbsoluteX},
- {0x20, "JSR" ,Absolute},
- {0x21, "AND" ,IndirectX},
- {0x22, "KIL" ,Implied},
- {0x23, "RLA" ,IndirectY},
- {0x24, "BIT" ,Zeropage},
- {0x25, "AND" ,Zeropage},
- {0x26, "ROL" ,Zeropage},
- {0x27, "RLA" ,Zeropage},
- {0x28, "PLP" ,Implied},
- {0x29, "AND" ,Immediate},
- {0x2A, "ROL" ,Implied},
- {0x2B, "AND" ,Immediate},
- {0x2C, "BIT" ,Absolute},
- {0x2D, "AND" ,Absolute},
- {0x2E, "ROL" ,Absolute},
- {0x2F, "RLA" ,Absolute},
- {0x30, "BMI" ,Relative},
- {0x31, "AND" ,IndirectY},
- {0x32, "KIL" ,Implied},
- {0x33, "RLA" ,IndirectY},
- {0x34, "NOP" ,ZeropageX},
- {0x35, "AND" ,ZeropageX},
- {0x36, "ROL" ,ZeropageX},
- {0x37, "RLA" ,ZeropageX},
- {0x38, "SEC" ,Implied},
- {0x39, "AND" ,AbsoluteY},
- {0x3A, "NOP" ,Implied},
- {0x3B, "RLA" ,AbsoluteY},
- {0x3C, "NOP" ,AbsoluteX},
- {0x3D, "AND" ,AbsoluteX},
- {0x3E, "ROL" ,AbsoluteX},
- {0x3F, "RLA" ,AbsoluteX},
- {0x40, "RTI" ,Implied},
- {0x41, "EOR" ,IndirectX},
- {0x42, "KIL" ,Implied},
- {0x43, "SRE" ,IndirectX},
- {0x44, "NOP" ,Zeropage},
- {0x45, "EOR" ,Zeropage},
- {0x46, "LSR" ,Zeropage},
- {0x47, "SRE" ,Zeropage},
- {0x48, "PHA" ,Implied},
- {0x49, "EOR" ,Immediate},
- {0x4A, "LSR" ,Implied},
- {0x4B, "ALR" ,Immediate},
- {0x4C, "JMP" ,Absolute},
- {0x4D, "EOR" ,Absolute},
- {0x4E, "LSR" ,Absolute},
- {0x4F, "SRE" ,Absolute},
- {0x50, "BVC" ,Relative},
- {0x51, "EOR" ,IndirectY},
- {0x52, "KIL" ,Implied},
- {0x53, "SRE" ,IndirectY},
- {0x54, "NOP" ,ZeropageX},
- {0x55, "EOR" ,ZeropageX},
- {0x56, "LSR" ,ZeropageX},
- {0x57, "SRE" ,ZeropageX},
- {0x58, "CLI" ,Implied},
- {0x59, "EOR" ,AbsoluteY},
- {0x5A, "NOP" ,Implied},
- {0x5B, "SRE" ,AbsoluteY},
- {0x5C, "NOP" ,AbsoluteX},
- {0x5D, "EOR" ,AbsoluteX},
- {0x5E, "LSR" ,AbsoluteX},
- {0x5F, "SRE" ,AbsoluteX},
- {0x60, "RTS" ,Implied},
- {0x61, "ADC" ,IndirectX},
- {0x62, "KIL" ,Implied},
- {0x63, "RRA" ,IndirectX},
- {0x64, "NOP" ,Zeropage},
- {0x65, "ADC" ,Zeropage},
- {0x66, "ROR" ,Zeropage},
- {0x67, "RRA" ,Zeropage},
- {0x68, "PLA" ,Implied},
- {0x69, "ADC" ,Immediate},
- {0x6A, "ROR" ,Implied},
- {0x6B, "ARR" ,Immediate},
- {0x6C, "JMP" ,Indirect},
- {0x6D, "ADC" ,Absolute},
- {0x6E, "ROR" ,Absolute},
- {0x6F, "RRA" ,Absolute},
- {0x70, "BVS" ,Relative},
- {0x71, "ADC" ,IndirectY},
- {0x72, "KIL" ,Implied},
- {0x73, "RRA" ,IndirectY},
- {0x74, "NOP" ,ZeropageX},
- {0x75, "ADC" ,ZeropageX},
- {0x76, "ROR" ,ZeropageX},
- {0x77, "RRA" ,ZeropageX},
- {0x78, "SEI" ,Implied},
- {0x79, "ADC" ,AbsoluteY},
- {0x7A, "NOP" ,Implied},
- {0x7B, "RRA" ,AbsoluteY},
- {0x7C, "NOP" ,AbsoluteX},
- {0x7D, "ADC" ,AbsoluteX},
- {0x7E, "ROR" ,AbsoluteX},
- {0x7F, "RRA" ,AbsoluteX},
- {0x80, "NOP" ,Immediate},
- {0x81, "STA" ,Indirect},
- {0x82, "NOP" ,Immediate},
- {0x83, "SAX" ,IndirectX},
- {0x84, "STY" ,Zeropage},
- {0x85, "STA" ,Zeropage},
- {0x86, "STX" ,Zeropage},
- {0x87, "SAX" ,Zeropage},
- {0x88, "DEY" ,Implied},
- {0x89, "NOP" ,Immediate},
- {0x8A, "TXA" ,Implied},
- {0x8B, "XAA" ,Immediate},
- {0x8C, "STY" ,Absolute},
- {0x8D, "STA" ,Absolute},
- {0x8E, "STX" ,Absolute},
- {0x8F, "SAX" ,Absolute},
- {0x90, "BCC" ,Relative},
- {0x91, "STA" ,IndirectY},
- {0x92, "KIL" ,Implied},
- {0x93, "AHX" ,IndirectY},
- {0x94, "STY" ,ZeropageY},
- {0x95, "STA" ,ZeropageX},
- {0x96, "STX" ,ZeropageY},
- {0x97, "SAX" ,ZeropageY},
- {0x98, "TYA" ,Implied},
- {0x99, "STA" ,AbsoluteY},
- {0x9A, "TXS" ,Implied},
- {0x9B, "TAS" ,AbsoluteY},
- {0x9C, "SHY" ,AbsoluteX},
- {0x9D, "STA" ,AbsoluteX},
- {0x9E, "SHX" ,AbsoluteY},
- {0x9F, "AHX" ,AbsoluteY},
- {0xA0, "LDY" ,Immediate},
- {0xA1, "LDA" ,IndirectX},
- {0xA2, "LDX" ,Immediate},
- {0xA3, "LAX" ,IndirectX},
- {0xA4, "LDY" ,Zeropage},
- {0xA5, "LDA" ,Zeropage},
- {0xA6, "LDX" ,Zeropage},
- {0xA7, "LAX" ,Zeropage},
- {0xA8, "TAY" ,Implied},
- {0xA9, "LDA" ,Immediate},
- {0xAA, "TAX" ,Implied},
- {0xAB, "LAX" ,Immediate},
- {0xAC, "LDY" ,Absolute},
- {0xAD, "LDA" ,Absolute},
- {0xAE, "LDX" ,Absolute},
- {0xAF, "LAX" ,Absolute},
- {0xB0, "BCS" ,Relative},
- {0xB1, "LDA" ,IndirectY},
- {0xB2, "KIL" ,Implied},
- {0xB3, "LAX" ,IndirectY},
- {0xB4, "LDY" ,ZeropageX},
- {0xB5, "LDA" ,ZeropageX},
- {0xB6, "LDX" ,ZeropageY},
- {0xB7, "LAX" ,ZeropageY},
- {0xB8, "CLV" ,Implied},
- {0xB9, "LDA" ,AbsoluteY},
- {0xBA, "TSX" ,Implied},
- {0xBB, "LAS" ,AbsoluteY},
- {0xBC, "LDY" ,AbsoluteX},
- {0xBD, "LDA" ,AbsoluteX},
- {0xBE, "LDX" ,AbsoluteY},
- {0xBF, "LAX" ,AbsoluteY},
- {0xC0, "CPY" ,Immediate},
- {0xC1, "CMP" ,IndirectX},
- {0xC2, "NOP" ,Immediate},
- {0xC3, "DCP" ,IndirectX},
- {0xC4, "CPY" ,Zeropage},
- {0xC5, "CMP" ,Zeropage},
- {0xC6, "DEC" ,Zeropage},
- {0xC7, "DCP" ,Zeropage},
- {0xC8, "INY" ,Implied},
- {0xC9, "CMP" ,Immediate},
- {0xCA, "DEX" ,Implied},
- {0xCB, "AXS" ,Immediate},
- {0xCC, "CPY" ,Absolute},
- {0xCD, "CMP" ,Absolute},
- {0xCE, "DEC" ,Absolute},
- {0xCF, "DCP" ,Absolute},
- {0xD0, "BNE" ,Relative},
- {0xD1, "CMP" ,IndirectY},
- {0xD2, "KIL" ,Implied},
- {0xD3, "DCP" ,IndirectY},
- {0xD4, "NOP" ,ZeropageX},
- {0xD5, "CMP" ,ZeropageX},
- {0xD6, "DEC" ,ZeropageX},
- {0xD7, "DCP" ,ZeropageX},
- {0xD8, "CLD" ,Implied},
- {0xD9, "CMP" ,AbsoluteY},
- {0xDA, "NOP" ,Implied},
- {0xDB, "DCP" ,AbsoluteY},
- {0xDC, "NOP" ,AbsoluteX},
- {0xDD, "CMP" ,AbsoluteX},
- {0xDE, "DEC" ,AbsoluteX},
- {0xDF, "DCP" ,AbsoluteX},
- {0xE0, "CPX" ,Immediate},
- {0xE1, "SBC" ,IndirectX},
- {0xE2, "NOP" ,Immediate},
- {0xE3, "ISC" ,IndirectX},
- {0xE4, "CPX" ,Zeropage},
- {0xE5, "SBC" ,Zeropage},
- {0xE6, "INC" ,Zeropage},
- {0xE7, "ISC" ,Zeropage},
- {0xE8, "INX" ,Implied},
- {0xE9, "SBC" ,Immediate},
- {0xEA, "NOP" ,Implied},
- {0xEB, "SBC" ,Immediate},
- {0xEC, "CPX" ,Absolute},
- {0xED, "SBC" ,Absolute},
- {0xEE, "INC" ,Absolute},
- {0xEF, "ISC" ,Absolute},
- {0xF0, "BEQ" ,Relative},
- {0xF1, "SBC" ,IndirectY},
- {0xF2, "KIL" ,Implied},
- {0xF3, "ISC" ,IndirectY},
- {0xF4, "NOP" ,ZeropageX},
- {0xF5, "SBC" ,ZeropageX},
- {0xF6, "INC" ,ZeropageX},
- {0xF7, "ISC" ,ZeropageX},
- {0xF8, "SED" ,Implied},
- {0xF9, "SBC" ,AbsoluteY},
- {0xFA, "NOP" ,Implied},
- {0xFB, "ISC" ,AbsoluteY},
- {0xFC, "NOP" ,AbsoluteX},
- {0xFD, "SBC" ,AbsoluteX},
- {0xFE, "INC" ,AbsoluteX},
- {0xFF, "ISC" ,AbsoluteX},
- };
- static struct Names {
- unsigned char High;
- unsigned char Low;
- char *Name;
- } Labels[] = {
- {0x20,0x00,"PPUCTRL"},
- {0x20,0x01,"PPUMASK"},
- {0x20,0x02,"PPUSTATUS"},
- {0x20,0x03,"OAMADDR"},
- {0x20,0x04,"OAMDATA"},
- {0x20,0x05,"PPUSCROLL"},
- {0x20,0x06,"PPUADDR"},
- {0x20,0x07,"PPUDATA"},
- {0x40,0x00,"SQ1_VOL"},
- {0x40,0x01,"SQ1_SWEEP"},
- {0x40,0x02,"SQ1_LO"},
- {0x40,0x03,"SQ1_HI"},
- {0x40,0x04,"SQ2_VOL"},
- {0x40,0x05,"SQ2_SWEEP"},
- {0x40,0x06,"SQ2_LO"},
- {0x40,0x07,"SQ2_HI"},
- {0x40,0x08,"TRI_LINEAR"},
- {0x40,0x0a,"TRI_LO"},
- {0x40,0x0b,"TRI_HI"},
- {0x40,0x0c,"NOISE_VOL"},
- {0x40,0x0e,"NOISE_LO"},
- {0x40,0x0f,"NOISE_HI"},
- {0x40,0x10,"DMC_FREQ"},
- {0x40,0x11,"DMC_RAW"},
- {0x40,0x12,"DMC_START"},
- {0x40,0x13,"DMC_LEN"},
- {0x40,0x14,"OAM_DMA"},
- {0x40,0x15,"SND_CHN"},
- {0x40,0x16,"JOY1"},
- {0x40,0x17,"APUCTRL"},
- {0x00,0x00,NULL},
- };
- // {0x40,0x17,"JOY2"},
- static int chk_strtol(char **Peek, char *End) { // returns an errorcode when out of bytes
- if(*Peek>=End) return -1;
- return(strtol(*Peek,Peek,16));
- }
- char *FormatAddress(char *Poke, int Low, int High, unsigned char Mode) {
- // todo: when only given part of an opcode ( like "8D" and nothing else after it ), don't act like
- // there's a value there
- char AddrBuffer[70];
- char OutPoke[70];
- strcpy(Poke, "wut");
- switch(Mode) {
- case Implied: // wut, in that case we don't need this function
- strcpy(AddrBuffer,"");
- break;
- case Relative: // meh
- strcpy(AddrBuffer,"--");
- break;
- case Zeropage:
- case ZeropageX:
- case ZeropageY:
- case Immediate:
- if(Low != -1)
- sprintf(AddrBuffer,"$%s%x",(Low>15?"":"0"),Low);
- else
- sprintf(AddrBuffer,"$??");
- break;
- case Absolute:
- case AbsoluteX:
- case AbsoluteY:
- if(Low != -1 && High != -1)
- sprintf(AddrBuffer,"$%s%x%s%x",(High>15 ? "" : "0"),High, (Low > 15 ? "" : "0"), Low );
- else if(High == -1)
- sprintf(AddrBuffer,"$%s%x??",(Low>15 ? "" : "0"),Low);
- else
- sprintf(AddrBuffer,"$????",(Low>15 ? "" : "0"),Low);
- int LabelMatch;
- for(LabelMatch=0; Labels[LabelMatch].Name != NULL ; LabelMatch++) {
- if(Labels[LabelMatch].High == High && Labels[LabelMatch].Low == Low) {
- strcpy(AddrBuffer, Labels[LabelMatch].Name);
- break;
- }
- }
- break;
- case Indirect:
- case IndirectX:
- case IndirectY:
- sprintf(AddrBuffer,"$%s%x",(Low>15?"":"0"),Low);
- break;
- default:
- // printf("unhandled mode %i \n", Mode);
- break;
- }
- switch(Mode) {
- case Absolute:
- case Zeropage:
- sprintf(Poke, "%s", AddrBuffer);
- break;
- case Immediate:
- sprintf(Poke, "#%s", AddrBuffer);
- break;
- case ZeropageX:
- case AbsoluteX:
- sprintf(Poke, "%s,x", AddrBuffer);
- break;
- case ZeropageY:
- case AbsoluteY:
- sprintf(Poke, "%s,y", AddrBuffer);
- break;
- case Relative:
- sprintf(Poke, "--");
- break;
- case Indirect:
- sprintf(Poke, "(%s)", AddrBuffer);
- break;
- case IndirectX:
- sprintf(Poke, "(%s,x)", AddrBuffer);
- break;
- case IndirectY:
- sprintf(Poke, "(%s),y", AddrBuffer);
- break;
- }
- return(Poke);
- }
- static int NS_NES_Disassemble(char *Input) {
- char OutBuffer[512]; //
- char ThisOpcode[100]; //
- char AddrBuffer[100]; //
- char *Peek = Input; // start of hex
- char *End = Input + strlen(Input); // end of hex
- unsigned char Code; // opcode
- unsigned char High; //
- unsigned char Low; //
- unsigned char Mode; //
- strcpy(OutBuffer,"");
- while(Peek < End) { // still more opcodes?
- Code = strtol(Peek, &Peek, 16);
- Mode = Opcodes[Code].Mode;
- switch(Mode) { // different addressing modes will have
- // a different number of bytes after the op
- case Zeropage:
- case ZeropageX:
- case ZeropageY:
- case Immediate:
- case IndirectX:
- case IndirectY:
- case Relative:
- High = -1;
- Low = chk_strtol(&Peek, End);
- break;
- case Absolute:
- case AbsoluteX:
- case AbsoluteY:
- case Indirect:
- Low = chk_strtol(&Peek, End);
- High = chk_strtol(&Peek, End);
- break;
- }
- // generate address string for the addressing mode
- FormatAddress(AddrBuffer,Low,High,Mode);
- // add onto the list
- sprintf(ThisOpcode, "%s %s \\ ",Opcodes[Code].Name, AddrBuffer);
- strcat(OutBuffer,ThisOpcode);
- }
- // turn the last slash into a null
- OutBuffer[strlen(OutBuffer)-3] = 0;
- printf("%s \n", OutBuffer); // Here's your string to give to send()
- }
- int main() {
- NS_NES_Disassemble("a9 01 8d 37 13 8d 07 20");
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement