diff options
Diffstat (limited to 'contrib/nosefart/dis6502.c')
-rw-r--r-- | contrib/nosefart/dis6502.c | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/contrib/nosefart/dis6502.c b/contrib/nosefart/dis6502.c new file mode 100644 index 000000000..ff552d219 --- /dev/null +++ b/contrib/nosefart/dis6502.c @@ -0,0 +1,474 @@ +/* +** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) +** +** +** This program is free software; you can redistribute it and/or +** modify it under the terms of version 2 of the GNU Library General +** Public License as published by the Free Software Foundation. +** +** This program is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** Library General Public License for more details. To obtain a +** copy of the GNU Library General Public License, write to the Free +** Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +** +** Any permitted reproduction of these routines, in whole or in part, +** must bear this legend. +** +** +** dis6502.c +** +** 6502 disassembler based on code from John Saeger +** $Id: dis6502.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ +*/ + +#include "types.h" +#include "log.h" +#include "nes6502.h" +#include "dis6502.h" + +#ifdef NES6502_DEBUG + +/* addressing modes */ +enum { _imp, _acc, _rel, _imm, _abs, _abs_x, _abs_y, _zero, _zero_x, _zero_y, _ind, _ind_x, _ind_y }; + +/* keep a filthy local copy of PC to +** reduce the amount of parameter passing +*/ +static uint32 pc_reg; + + +static uint8 dis_op8(void) +{ + return (nes6502_getbyte(pc_reg + 1)); +} + +static uint16 dis_op16(void) +{ + return (nes6502_getbyte(pc_reg + 1) + (nes6502_getbyte(pc_reg + 2) << 8)); +} + +static void dis_show_ind(void) +{ + log_printf("(%04X) ", dis_op16()); +} + +static void dis_show_ind_x(void) +{ + log_printf("(%02X,x) ", dis_op8()); +} + +static void dis_show_ind_y(void) +{ + log_printf("(%02X),y ", dis_op8()); +} + +static void dis_show_zero_x(void) +{ + log_printf(" %02X,x ", dis_op8()); +} + +static void dis_show_zero_y(void) +{ + log_printf(" %02X,y ", dis_op8()); +} + +static void dis_show_abs_y(void) +{ + log_printf(" %04X,y ", dis_op16()); +} + +static void dis_show_abs_x(void) +{ + log_printf(" %04X,x ", dis_op16()); +} + +static void dis_show_zero(void) +{ + log_printf(" %02X ", dis_op8()); +} + +static void dis_show_abs(void) +{ + log_printf(" %04X ", dis_op16()); +} + +static void dis_show_immediate(void) +{ + log_printf("#%02X ", dis_op8()); +} + +static void dis_show_acc(void) +{ + log_printf(" a "); +} + +static void dis_show_relative(void) +{ + int target; + + target = (int8) dis_op8(); + target += (pc_reg + 2); + log_printf(" %04X ", target); +} + +static void dis_show_code(int optype) +{ + log_printf("%02X ", nes6502_getbyte(pc_reg)); + + switch (optype) + { + case _imp: + case _acc: + log_printf(" "); + break; + + case _rel: + case _imm: + case _zero: + case _zero_x: + log_printf("%02X ", nes6502_getbyte(pc_reg + 1)); + break; + + case _abs: + case _abs_x: + case _abs_y: + case _ind: + case _ind_x: + case _ind_y: + log_printf("%02X %02X ", nes6502_getbyte(pc_reg + 1), nes6502_getbyte(pc_reg + 2)); + break; + } +} + +static void dis_show_op(char *opstr, int optype) +{ + dis_show_code(optype); + log_printf("%s ", opstr); + + switch(optype) + { + case _imp: log_printf(" "); break; + case _acc: dis_show_acc(); break; + case _rel: dis_show_relative(); break; + case _imm: dis_show_immediate(); break; + case _abs: dis_show_abs(); break; + case _abs_x: dis_show_abs_x(); break; + case _abs_y: dis_show_abs_y(); break; + case _zero: dis_show_zero(); break; + case _zero_x: dis_show_zero_x(); break; + case _ind: dis_show_ind(); break; + case _ind_x: dis_show_ind_x(); break; + case _ind_y: dis_show_ind_y(); break; + } +} + +void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 S) +{ + pc_reg = PC; + + log_printf("%04X: ", pc_reg); + + switch(nes6502_getbyte(pc_reg)) + { + case 0x00: dis_show_op("brk",_imp); break; + case 0x01: dis_show_op("ora",_ind_x); break; + case 0x02: dis_show_op("jam",_imp); break; + case 0x03: dis_show_op("slo",_ind_x); break; + case 0x04: dis_show_op("nop",_zero); break; + case 0x05: dis_show_op("ora",_zero); break; + case 0x06: dis_show_op("asl",_zero); break; + case 0x07: dis_show_op("slo",_zero); break; + case 0x08: dis_show_op("php",_imp); break; + case 0x09: dis_show_op("ora",_imm); break; + case 0x0a: dis_show_op("asl",_acc); break; + case 0x0b: dis_show_op("anc",_imm); break; + case 0x0c: dis_show_op("nop",_abs); break; + case 0x0d: dis_show_op("ora",_abs); break; + case 0x0e: dis_show_op("asl",_abs); break; + case 0x0f: dis_show_op("slo",_abs); break; + + case 0x10: dis_show_op("bpl",_rel); break; + case 0x11: dis_show_op("ora",_ind_y); break; + case 0x12: dis_show_op("jam",_imp); break; + case 0x13: dis_show_op("slo",_ind_y); break; + case 0x14: dis_show_op("nop",_zero_x); break; + case 0x15: dis_show_op("ora",_zero_x); break; + case 0x16: dis_show_op("asl",_zero_x); break; + case 0x17: dis_show_op("slo",_zero_x); break; + case 0x18: dis_show_op("clc",_imp); break; + case 0x19: dis_show_op("ora",_abs_y); break; + case 0x1a: dis_show_op("nop",_imp); break; + case 0x1b: dis_show_op("slo",_abs_y); break; + case 0x1c: dis_show_op("nop",_abs_x); break; + case 0x1d: dis_show_op("ora",_abs_x); break; + case 0x1e: dis_show_op("asl",_abs_x); break; + case 0x1f: dis_show_op("slo",_abs_x); break; + + case 0x20: dis_show_op("jsr",_abs); break; + case 0x21: dis_show_op("and",_ind_x); break; + case 0x22: dis_show_op("jam",_imp); break; + case 0x23: dis_show_op("rla",_ind_x); break; + case 0x24: dis_show_op("bit",_zero); break; + case 0x25: dis_show_op("and",_zero); break; + case 0x26: dis_show_op("rol",_zero); break; + case 0x27: dis_show_op("rla",_zero); break; + case 0x28: dis_show_op("plp",_imp); break; + case 0x29: dis_show_op("and",_imm); break; + case 0x2a: dis_show_op("rol",_acc); break; + case 0x2b: dis_show_op("anc",_imm); break; + case 0x2c: dis_show_op("bit",_abs); break; + case 0x2d: dis_show_op("and",_abs); break; + case 0x2e: dis_show_op("rol",_abs); break; + case 0x2f: dis_show_op("rla",_abs); break; + + case 0x30: dis_show_op("bmi",_rel); break; + case 0x31: dis_show_op("and",_ind_y); break; + case 0x32: dis_show_op("jam",_imp); break; + case 0x33: dis_show_op("rla",_ind_y); break; +/* case 0x34: dis_show_op("nop",_zero); break;*/ + case 0x34: dis_show_op("nop",_imp); break; + case 0x35: dis_show_op("and",_zero_x); break; + case 0x36: dis_show_op("rol",_zero_x); break; + case 0x37: dis_show_op("rla",_zero_x); break; + case 0x38: dis_show_op("sec",_imp); break; + case 0x39: dis_show_op("and",_abs_y); break; + case 0x3a: dis_show_op("nop",_imp); break; + case 0x3b: dis_show_op("rla",_abs_y); break; +/* case 0x3c: dis_show_op("nop",_imp); break;*/ + case 0x3c: dis_show_op("nop",_abs_x); break; + case 0x3d: dis_show_op("and",_abs_x); break; + case 0x3e: dis_show_op("rol",_abs_x); break; + case 0x3f: dis_show_op("rla",_abs_x); break; + + case 0x40: dis_show_op("rti",_imp); break; + case 0x41: dis_show_op("eor",_ind_x); break; + case 0x42: dis_show_op("jam",_imp); break; + case 0x43: dis_show_op("sre",_ind_x); break; + case 0x44: dis_show_op("nop",_zero); break; + case 0x45: dis_show_op("eor",_zero); break; + case 0x46: dis_show_op("lsr",_zero); break; + case 0x47: dis_show_op("sre",_zero); break; + case 0x48: dis_show_op("pha",_imp); break; + case 0x49: dis_show_op("eor",_imm); break; + case 0x4a: dis_show_op("lsr",_acc); break; + case 0x4b: dis_show_op("asr",_imm); break; + case 0x4c: dis_show_op("jmp",_abs); break; + case 0x4d: dis_show_op("eor",_abs); break; + case 0x4e: dis_show_op("lsr",_abs); break; + case 0x4f: dis_show_op("sre",_abs); break; + + case 0x50: dis_show_op("bvc",_rel); break; + case 0x51: dis_show_op("eor",_ind_y); break; + case 0x52: dis_show_op("jam",_imp); break; + case 0x53: dis_show_op("sre",_ind_y); break; + case 0x54: dis_show_op("nop",_zero_x); break; + case 0x55: dis_show_op("eor",_zero_x); break; + case 0x56: dis_show_op("lsr",_zero_x); break; + case 0x57: dis_show_op("sre",_zero_x); break; + case 0x58: dis_show_op("cli",_imp); break; + case 0x59: dis_show_op("eor",_abs_y); break; + case 0x5a: dis_show_op("nop",_imp); break; + case 0x5b: dis_show_op("sre",_abs_y); break; + case 0x5c: dis_show_op("nop",_abs_x); break; + case 0x5d: dis_show_op("eor",_abs_x); break; + case 0x5e: dis_show_op("lsr",_abs_x); break; + case 0x5f: dis_show_op("sre",_abs_x); break; + + case 0x60: dis_show_op("rts",_imp); break; + case 0x61: dis_show_op("adc",_ind_x); break; + case 0x62: dis_show_op("jam",_imp); break; + case 0x63: dis_show_op("rra",_ind_x); break; + case 0x64: dis_show_op("nop",_zero); break; + case 0x65: dis_show_op("adc",_zero); break; + case 0x66: dis_show_op("ror",_zero); break; + case 0x67: dis_show_op("rra",_zero); break; + case 0x68: dis_show_op("pla",_imp); break; + case 0x69: dis_show_op("adc",_imm); break; + case 0x6a: dis_show_op("ror",_acc); break; + case 0x6b: dis_show_op("arr",_imm); break; + case 0x6c: dis_show_op("jmp",_ind); break; + case 0x6d: dis_show_op("adc",_abs); break; + case 0x6e: dis_show_op("ror",_abs); break; + case 0x6f: dis_show_op("rra",_abs); break; + + case 0x70: dis_show_op("bvs",_rel); break; + case 0x71: dis_show_op("adc",_ind_y); break; + case 0x72: dis_show_op("jam",_imp); break; + case 0x73: dis_show_op("rra",_ind_y); break; + case 0x74: dis_show_op("nop",_zero_x); break; + case 0x75: dis_show_op("adc",_zero_x); break; + case 0x76: dis_show_op("ror",_zero_x); break; + case 0x77: dis_show_op("rra",_zero_x); break; + case 0x78: dis_show_op("sei",_imp); break; + case 0x79: dis_show_op("adc",_abs_y); break; + case 0x7a: dis_show_op("nop",_imp); break; + case 0x7b: dis_show_op("rra",_abs_y); break; + case 0x7c: dis_show_op("nop",_abs_x); break; + case 0x7d: dis_show_op("adc",_abs_x); break; + case 0x7e: dis_show_op("ror",_abs_x); break; + case 0x7f: dis_show_op("rra",_abs_x); break; + + case 0x80: dis_show_op("nop",_imm); break; + case 0x81: dis_show_op("sta",_ind_x); break; + case 0x82: dis_show_op("nop",_imm); break; + case 0x83: dis_show_op("sax",_ind_x); break; + case 0x84: dis_show_op("sty",_zero); break; + case 0x85: dis_show_op("sta",_zero); break; + case 0x86: dis_show_op("stx",_zero); break; + case 0x87: dis_show_op("sax",_zero); break; + case 0x88: dis_show_op("dey",_imp); break; + case 0x89: dis_show_op("nop",_imm); break; + case 0x8a: dis_show_op("txa",_imp); break; + case 0x8b: dis_show_op("ane",_imm); break; + case 0x8c: dis_show_op("sty",_abs); break; + case 0x8d: dis_show_op("sta",_abs); break; + case 0x8e: dis_show_op("stx",_abs); break; + case 0x8f: dis_show_op("sax",_abs); break; + + case 0x90: dis_show_op("bcc",_rel); break; + case 0x91: dis_show_op("sta",_ind_y); break; + case 0x92: dis_show_op("jam",_imp); break; + case 0x93: dis_show_op("sha",_ind_y); break; + case 0x94: dis_show_op("sty",_zero_x); break; + case 0x95: dis_show_op("sta",_zero_x); break; + case 0x96: dis_show_op("stx",_zero_y); break; + case 0x97: dis_show_op("sax",_zero_y); break; + case 0x98: dis_show_op("tya",_imp); break; + case 0x99: dis_show_op("sta",_abs_y); break; + case 0x9a: dis_show_op("txs",_imp); break; + case 0x9b: dis_show_op("shs",_abs_y); break; + case 0x9c: dis_show_op("shy",_abs_x); break; + case 0x9d: dis_show_op("sta",_abs_x); break; + case 0x9e: dis_show_op("shx",_abs_y); break; + case 0x9f: dis_show_op("sha",_abs_y); break; + + case 0xa0: dis_show_op("ldy",_imm); break; + case 0xa1: dis_show_op("lda",_ind_x); break; + case 0xa2: dis_show_op("ldx",_imm); break; + case 0xa3: dis_show_op("lax",_ind_x); break; + case 0xa4: dis_show_op("ldy",_zero); break; + case 0xa5: dis_show_op("lda",_zero); break; + case 0xa6: dis_show_op("ldx",_zero); break; + case 0xa7: dis_show_op("lax",_zero); break; + case 0xa8: dis_show_op("tay",_imp); break; + case 0xa9: dis_show_op("lda",_imm); break; + case 0xaa: dis_show_op("tax",_imp); break; + case 0xab: dis_show_op("lxa",_imm); break; + case 0xac: dis_show_op("ldy",_abs); break; + case 0xad: dis_show_op("lda",_abs); break; + case 0xae: dis_show_op("ldx",_abs); break; + case 0xaf: dis_show_op("lax",_abs); break; + + case 0xb0: dis_show_op("bcs",_rel); break; + case 0xb1: dis_show_op("lda",_ind_y); break; + case 0xb2: dis_show_op("jam",_imp); break; + case 0xb3: dis_show_op("lax",_ind_y); break; + case 0xb4: dis_show_op("ldy",_zero_x); break; + case 0xb5: dis_show_op("lda",_zero_x); break; + case 0xb6: dis_show_op("ldx",_zero_y); break; + case 0xb7: dis_show_op("lax",_zero_y); break; + case 0xb8: dis_show_op("clv",_imp); break; + case 0xb9: dis_show_op("lda",_abs_y); break; + case 0xba: dis_show_op("tsx",_imp); break; + case 0xbb: dis_show_op("las",_abs_y); break; + case 0xbc: dis_show_op("ldy",_abs_x); break; + case 0xbd: dis_show_op("lda",_abs_x); break; + case 0xbe: dis_show_op("ldx",_abs_y); break; + case 0xbf: dis_show_op("lax",_abs_y); break; + + case 0xc0: dis_show_op("cpy",_imm); break; + case 0xc1: dis_show_op("cmp",_ind_x); break; + case 0xc2: dis_show_op("nop",_imm); break; + case 0xc3: dis_show_op("dcp",_ind_x); break; + case 0xc4: dis_show_op("cpy",_zero); break; + case 0xc5: dis_show_op("cmp",_zero); break; + case 0xc6: dis_show_op("dec",_zero); break; + case 0xc7: dis_show_op("dcp",_zero); break; + case 0xc8: dis_show_op("iny",_imp); break; + case 0xc9: dis_show_op("cmp",_imm); break; + case 0xca: dis_show_op("dex",_imp); break; + case 0xcb: dis_show_op("sbx",_imm); break; + case 0xcc: dis_show_op("cpy",_abs); break; + case 0xcd: dis_show_op("cmp",_abs); break; + case 0xce: dis_show_op("dec",_abs); break; + case 0xcf: dis_show_op("dcp",_abs); break; + + case 0xd0: dis_show_op("bne",_rel); break; + case 0xd1: dis_show_op("cmp",_ind_y); break; + case 0xd2: dis_show_op("jam",_imp); break; + case 0xd3: dis_show_op("dcp",_ind_y); break; + case 0xd4: dis_show_op("nop",_zero_x); break; + case 0xd5: dis_show_op("cmp",_zero_x); break; + case 0xd6: dis_show_op("dec",_zero_x); break; + case 0xd7: dis_show_op("dcp",_zero_x); break; + case 0xd8: dis_show_op("cld",_imp); break; + case 0xd9: dis_show_op("cmp",_abs_y); break; + case 0xda: dis_show_op("nop",_imp); break; + case 0xdb: dis_show_op("dcp",_abs_y); break; + case 0xdc: dis_show_op("nop",_abs_x); break; + case 0xdd: dis_show_op("cmp",_abs_x); break; + case 0xde: dis_show_op("dec",_abs_x); break; + case 0xdf: dis_show_op("dcp",_abs_x); break; + + case 0xe0: dis_show_op("cpx",_imm); break; + case 0xe1: dis_show_op("sbc",_ind_x); break; + case 0xe2: dis_show_op("nop",_imm); break; + case 0xe3: dis_show_op("isb",_ind_x); break; + case 0xe4: dis_show_op("cpx",_zero); break; + case 0xe5: dis_show_op("sbc",_zero); break; + case 0xe6: dis_show_op("inc",_zero); break; + case 0xe7: dis_show_op("isb",_zero); break; + case 0xe8: dis_show_op("inx",_imp); break; + case 0xe9: dis_show_op("sbc",_imm); break; + case 0xea: dis_show_op("nop",_imp); break; + case 0xeb: dis_show_op("sbc",_imm); break; + case 0xec: dis_show_op("cpx",_abs); break; + case 0xed: dis_show_op("sbc",_abs); break; + case 0xee: dis_show_op("inc",_abs); break; + case 0xef: dis_show_op("isb",_abs); break; + + case 0xf0: dis_show_op("beq",_rel); break; + case 0xf1: dis_show_op("sbc",_ind_y); break; + case 0xf2: dis_show_op("jam",_imp); break; + case 0xf3: dis_show_op("isb",_ind_y); break; + case 0xf4: dis_show_op("nop",_zero_x); break; + case 0xf5: dis_show_op("sbc",_zero_x); break; + case 0xf6: dis_show_op("inc",_zero_x); break; + case 0xf7: dis_show_op("isb",_zero_x); break; + case 0xf8: dis_show_op("sed",_imp); break; + case 0xf9: dis_show_op("sbc",_abs_y); break; + case 0xfa: dis_show_op("nop",_imp); break; + case 0xfb: dis_show_op("isb",_abs_y); break; + case 0xfc: dis_show_op("nop",_abs_x); break; + case 0xfd: dis_show_op("sbc",_abs_x); break; + case 0xfe: dis_show_op("inc",_abs_x); break; + case 0xff: dis_show_op("isb",_abs_x); break; + } + + log_printf("%c%c1%c%c%c%c%c %02X %02X %02X %02X\n", + (P & N_FLAG) ? 'N' : 'n', + (P & V_FLAG) ? 'V' : 'v', + (P & V_FLAG) ? 'B' : 'b', + (P & V_FLAG) ? 'D' : 'd', + (P & V_FLAG) ? 'I' : 'i', + (P & V_FLAG) ? 'Z' : 'z', + (P & V_FLAG) ? 'C' : 'c', + A, X, Y, S); +} + +#endif /* NES6502_DEBUG */ + +/* +** $Log: dis6502.c,v $ +** Revision 1.2 2003/12/05 15:55:01 f1rmb +** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... +** +** Revision 1.1 2003/01/08 07:04:35 tmmm +** initial import of Nosefart sources +** +** Revision 1.4 2000/06/09 15:12:25 matt +** initial revision +** +*/ |