diff --git a/libr/asm/arch/gb/gbdis.c b/libr/asm/arch/gb/gbdis.c index b8d2a4bee1..2fc111a3ff 100644 --- a/libr/asm/arch/gb/gbdis.c +++ b/libr/asm/arch/gb/gbdis.c @@ -22,7 +22,7 @@ static int gbOpLength(int gboptype){ return 0; } -static int gbDisass(RAsmOp *op, const ut8 *buf, ut64 len){ +static int gbDisass(RAsmOp *op, const ut8 *buf, int len){ int foo = gbOpLength (gb_op[buf[0]].type); if (len + +#define SPC_OP 0 +#define SPC_ARG8_1 1 +#define SPC_ARG8_2 2 +#define SPC_ARG16 3 + +typedef struct spc_700_op_t { + char *name; + ut8 type; +} Spc700Op; + +static const Spc700Op spc_op_table[] = { + {"nop", SPC_OP}, + {"call [0xffde]", SPC_OP}, + {"set1 0x%02x.0", SPC_ARG8_1}, + {"bbs 0x%02x.0,0x%02x", SPC_ARG8_2}, + {"or A,0x%02x", SPC_ARG8_1}, + {"or A,!0x%04x", SPC_ARG16}, + {"or A,(X)", SPC_OP}, + {"or A,[0x%02x+X]", SPC_ARG8_1}, + {"or A,#0x%02x", SPC_ARG8_1}, + {"or 0x%02x,0x%02x", SPC_ARG8_2}, + {"or1 C,0x%02x.0x%02x", SPC_ARG8_2}, + {"asl 0x%02x", SPC_ARG8_1}, + {"asl !0x%04x", SPC_ARG16}, + {"push psw", SPC_OP}, + {"tset1 !0x%04x", SPC_ARG16}, + {"brk", SPC_OP}, + {"bpl 0x%02x", SPC_ARG8_1}, + {"call [0xffdc]", SPC_OP}, + {"clr1 0x%02x,0", SPC_ARG8_1}, + {"bbc 0x%02x.0,0x%02x", SPC_ARG8_2}, + {"or A,0x%02x+X", SPC_ARG8_1}, + {"or A,!0x%04x+X", SPC_ARG8_1}, + {"or A,!0x%04x+Y", SPC_ARG16}, + {"or A,[0x%02x]+Y", SPC_ARG8_1}, + {"or 0x%02x,#0x%02x", SPC_ARG8_2}, + {"or (X),(Y)", SPC_OP}, + {"decw 0x%02x", SPC_ARG8_1}, + {"asl 0x%02x+X", SPC_ARG8_1}, + {"asl A", SPC_OP}, + {"dec X", SPC_OP}, + {"cmp X,!0x%04x", SPC_ARG16}, + {"jmp [!0x%04x+X]", SPC_ARG16}, + {"clrp", SPC_OP}, + {"call [0xffda]", SPC_OP}, + {"set1 0x%02x.1", SPC_ARG8_1}, + {"bbs 0x%02x.1,0x%02x", SPC_ARG8_2}, + {"and A,0x%02x", SPC_ARG8_1}, + {"and A,!0x%04x", SPC_ARG16}, + {"and A,(X)", SPC_OP}, + {"and A,[0x%02x+X]", SPC_ARG8_1}, + {"and A,#0x%02x", SPC_ARG8_1}, + {"and 0x%02x,0x%02x", SPC_ARG8_2}, + {"or1 C,/0x%02x.0x%02x", SPC_ARG8_2}, + {"rol 0x%02x", SPC_ARG8_1}, + {"rol !0x%04x", SPC_ARG16}, + {"push A", SPC_OP}, + {"cbne 0x%02x,0x%02x", SPC_ARG8_2}, + {"bra 0x%02x", SPC_ARG8_1}, + {"bmi 0x%02x", SPC_ARG8_1}, + {"call [0xffd8]", SPC_OP}, + {"clr1 0x%02x.1", SPC_ARG8_1}, + {"bbc 0x%02x.1,0x%02x", SPC_ARG8_2}, + {"and A,0x%02x+X", SPC_ARG8_1}, + {"and A,!0x%04x+X", SPC_ARG16}, + {"and A,!0x%04x+Y", SPC_ARG16}, + {"and A,[0x%02x]+Y", SPC_ARG8_1}, + {"and 0x%02x,#0x%02x", SPC_ARG8_2}, + {"and (X),(Y)", SPC_OP}, + {"incw 0x%02x", SPC_ARG8_1}, + {"rol 0x%02x+X", SPC_ARG8_1}, + {"rol A", SPC_OP}, + {"inc X", SPC_OP}, + {"cmp X,0x%02x", SPC_ARG8_1}, + {"call !0x%04x", SPC_ARG16}, + {"call [0xffd6]", SPC_OP}, + {"set1 0x%02x.2", SPC_ARG8_1}, + {"bbs 0x%02x.2,0x%02x", SPC_ARG8_2}, + {"setp", SPC_OP}, + {"eor A,0x%02x", SPC_ARG8_1}, + {"eor A,!0x%04x", SPC_ARG16}, + {"eor A,(X)", SPC_OP}, + {"eor A,[0x%02x+X]", SPC_ARG8_1}, + {"eor A,#0x%02x", SPC_ARG8_1}, + {"eor 0x%02x,0x%02x", SPC_ARG8_2}, + {"and1 C,0x%02x.0x%02x", SPC_ARG8_2}, + {"lsr 0x%02x", SPC_ARG8_1}, + {"lsr !0x%04x", SPC_ARG16}, + {"push X", SPC_OP}, + {"tclr1 !0x%04x", SPC_ARG16}, + {"pcall 0x%02x", SPC_ARG8_1}, + {"bvc 0x%02x", SPC_ARG8_1}, + {"call [0xffd4]", SPC_OP}, + {"clr1 0x%02x.2", SPC_ARG8_1}, + {"bbc 0x%02x.2,0x%02x", SPC_ARG8_2}, + {"eor A,0x%02x+X", SPC_ARG8_1}, + {"eor A,!0x%04x+X", SPC_ARG16}, + {"eor A,!0x%04x+Y", SPC_ARG16}, + {"eor A,[0x%02x]+Y", SPC_ARG8_1}, + {"eor 0x%02x,#0x%02x", SPC_ARG8_2}, + {"eor (X),(Y)", SPC_OP}, + {"cmpw YA,0x%02x", SPC_ARG8_1}, + {"lsr 0x%02x+X", SPC_ARG8_1}, + {"lsr A", SPC_OP}, + {"mov X,A", SPC_OP}, + {"cmp Y,!0x%04x", SPC_ARG16}, + {"jmp !0x%04x", SPC_ARG16}, + {"clrc", SPC_OP}, + {"call [0xffd2]", SPC_OP}, + {"set1 0x%02x.3", SPC_ARG8_1}, + {"bbs 0x%02x.3,0x%02x", SPC_ARG8_2}, + {"cmp A,0x%02x", SPC_ARG8_1}, + {"cmp A,!0x%04x", SPC_ARG16}, + {"cmp A,(X)", SPC_OP}, + {"cmp A,[0x%02x+X]", SPC_ARG8_1}, + {"cmp A,#0x%02x", SPC_ARG8_1}, + {"cmp 0x%02x,0x%02x", SPC_ARG8_2}, + {"and1 C,/0x%02x.0x%02x", SPC_ARG8_2}, + {"ror 0x%02x", SPC_ARG8_1}, + {"ror !0x%04x", SPC_ARG16}, + {"push Y", SPC_OP}, + {"dbnz 0x%02x,0x%02x", SPC_ARG8_2}, + {"ret", SPC_OP}, + {"bvs 0x%02x", SPC_ARG8_1}, + {"call [0xffd0]", SPC_OP}, + {"clr1 0x%02x.3", SPC_ARG8_1}, + {"bbc 0x%02x.3,0x%02x", SPC_ARG8_2}, + {"cmp A,0x%02x+X", SPC_ARG8_1}, + {"cmp A,!0x%04x+X", SPC_ARG16}, + {"cmp A,!0x%04x+Y", SPC_ARG16}, + {"cmp A,[0x%02x]+Y", SPC_ARG8_1}, + {"cmp 0x%02x,#0x%02x", SPC_ARG8_2}, + {"cmp (X),(Y)", SPC_OP}, + {"addw YA,0x%02x", SPC_ARG8_1}, + {"ror 0x%02x+X", SPC_ARG8_1}, + {"ror A", SPC_OP}, + {"mov A,X", SPC_OP}, + {"cmp Y,0x%02x", SPC_ARG8_1}, + {"ret1", SPC_OP}, + {"setc", SPC_OP}, + {"call [0xffce]", SPC_OP}, + {"set1 0x%02x.4", SPC_ARG8_1}, + {"bbs 0x%02x.4,0x%02x", SPC_ARG8_2}, + {"adc A,0x%02x", SPC_ARG8_1}, + {"adc A,!0x%04x", SPC_ARG16}, + {"adc A,(X)", SPC_OP}, + {"adc A,[0x%02x+X]", SPC_ARG8_1}, + {"adc A,#0x%02x", SPC_ARG8_1}, + {"adc 0x%02x,0x%02x", SPC_ARG8_2}, + {"eor1 C,0x%02x.0x%02x", SPC_ARG8_2}, + {"dec 0x%02x", SPC_ARG8_1}, + {"dec !0x%04x", SPC_ARG16}, + {"mov Y,#0x%02x", SPC_ARG8_1}, + {"pop psw", SPC_OP}, + {"mov 0x%02x,#0x%02x", SPC_ARG8_2}, + {"bcc 0x%02x", SPC_ARG8_1}, + {"call [0xffcc]", SPC_OP}, + {"clr1 0x%02x.4", SPC_ARG8_1}, + {"bbc 0x%02x.4,0x%02x", SPC_ARG8_2}, + {"adc A,0x%02x+X", SPC_ARG8_1}, + {"adc A,!0x%04x+X", SPC_ARG16}, + {"adc A,!0x%04x+Y", SPC_ARG16}, + {"adc A,[0x%02x]+Y", SPC_ARG8_1}, + {"adc 0x%02x,#0x%02x", SPC_ARG8_2}, + {"adc (X),(Y)", SPC_OP}, + {"subw YA,0x%02x", SPC_ARG8_1}, + {"dec 0x%02x+X", SPC_ARG8_1}, + {"dec A", SPC_OP}, + {"mov X,SP", SPC_OP}, + {"div YA,X", SPC_OP}, + {"xcn A", SPC_OP}, + {"ei", SPC_OP}, + {"call [0xffca]", SPC_OP}, + {"set1 0x%02x.5", SPC_ARG8_1}, + {"bbs 0x%02x.5,0x%02x", SPC_ARG8_2}, + {"sbc A,0x%02x", SPC_ARG8_1}, + {"sbc A,!0x%04x", SPC_ARG16}, + {"sbc A,(X)", SPC_OP}, + {"sbc A,[0x%02x+X]", SPC_ARG8_1}, + {"sbc A,#0x%02x", SPC_ARG8_1}, + {"sbc 0x%02x,0x%02x", SPC_ARG8_2}, + {"mov1 C,0x%02x.0x%02x", SPC_ARG8_2}, + {"inc 0x%02x", SPC_ARG8_1}, + {"inc !0x%04x", SPC_ARG16}, + {"cmp Y,#0x%02x", SPC_ARG8_1}, + {"pop A", SPC_OP}, + {"mov (X)+,A", SPC_OP}, + {"bcs 0x%02x", SPC_ARG8_1}, + {"call [0xffc8]", SPC_OP}, + {"clr1 0x%02x.5", SPC_ARG8_1}, + {"bbc 0x%02x.5,0x%02x", SPC_ARG8_2}, + {"sbc A,0x%02x+X", SPC_ARG8_1}, + {"sbc A,!0x%04x+X", SPC_ARG16}, + {"sbc A,!0x%04x+Y", SPC_ARG16}, + {"sbc A,[0x%02x]+Y", SPC_ARG8_1}, + {"sbc 0x%02x,#0x%02x", SPC_ARG8_2}, + {"sbc (X),(Y)", SPC_OP}, + {"movw YA,0x%02x", SPC_ARG8_1}, + {"inc 0x%02x+X", SPC_ARG8_1}, + {"inc A", SPC_OP}, + {"mov SP,X", SPC_OP}, + {"das", SPC_OP}, + {"mov A,(X)+", SPC_OP}, + {"di", SPC_OP}, + {"call [0xffc6]", SPC_OP}, + {"set1 0x%02x.6", SPC_ARG8_1}, + {"bbs 0x%02x.6,0x%02x", SPC_ARG8_2}, + {"mov 0x%02x,A", SPC_ARG8_1}, + {"mov !0x%04x,A", SPC_ARG16}, + {"mov (X),A", SPC_OP}, + {"mov [0x%02x+X],A", SPC_ARG8_1}, + {"cmp X,#0x%02x", SPC_ARG8_1}, + {"mov !0x%04x,X", SPC_ARG16}, + {"and1 0x%02x.0x%02x,C", SPC_ARG8_2}, + {"mov 0x%02x,Y", SPC_ARG8_1}, + {"mov !0x%04x,Y", SPC_ARG16}, + {"mov X,#0x%02x", SPC_ARG8_1}, + {"pop X", SPC_OP}, + {"mul YA", SPC_OP}, + {"bne 0x%02x", SPC_ARG8_1}, + {"call [0xffc4]", SPC_OP}, + {"clr1 0x%02x.6", SPC_ARG8_1}, + {"bbc 0x%02x.6,0x%02x", SPC_ARG8_2}, + {"mov 0x%02x+X,A", SPC_ARG8_1}, + {"mov !0x%04x+X,A", SPC_ARG16}, + {"mov !0x%04x+Y,A", SPC_ARG16}, + {"mov [0x%02x]+Y,A", SPC_ARG8_1}, + {"mov 0x%02x,X", SPC_ARG8_1}, + {"mov 0x%02x+Y,X", SPC_ARG8_1}, + {"movw 0x%02x,YA", SPC_ARG8_1}, + {"mov 0x%02x+X,Y", SPC_ARG8_1}, + {"dec Y", SPC_OP}, + {"mov A,Y", SPC_OP}, + {"cbne 0x%02x+X,0x%02x", SPC_ARG8_2}, + {"daa", SPC_OP}, + {"clrv", SPC_OP}, + {"call [0xffc2]", SPC_OP}, + {"set1 0x%02x.7", SPC_ARG8_1}, + {"bbs 0x%02x.7,0x%02x", SPC_ARG8_2}, + {"mov A,0x%02x", SPC_ARG8_1}, + {"mov A,!0x%04x", SPC_ARG16}, + {"mov A,(X)", SPC_OP}, + {"mov A,[0x%02x+X]", SPC_ARG8_1}, + {"mov A,#0x%02x", SPC_ARG8_1}, + {"mov X,!0x%04x", SPC_ARG16}, + {"not1 0x%02x.0x%02x", SPC_ARG8_2}, + {"mov Y,0x%02x", SPC_ARG8_1}, + {"mov Y,!0x%04x", SPC_ARG16}, + {"notc", SPC_OP}, + {"pop Y", SPC_OP}, + {"sleep", SPC_OP}, + {"beq 0x%02x", SPC_ARG8_1}, + {"call [0xffc0]", SPC_OP}, + {"clr1 0x%02x.7", SPC_ARG8_1}, + {"bbc 0x%02x.7,0x%02x", SPC_ARG8_2}, + {"mov A,0x%02x+X", SPC_ARG8_1}, + {"mov A,!0x%04x+X", SPC_ARG16}, + {"mov A,!0x%04x+Y", SPC_ARG16}, + {"mov A,[0x%02x]+Y", SPC_ARG8_1}, + {"mov X,0x%02x", SPC_ARG8_1}, + {"mov X,0x%02x+Y", SPC_ARG8_1}, + {"mov 0x%02x,0x%02x", SPC_ARG8_2}, + {"mov Y,0x%02x+X", SPC_ARG8_1}, + {"inc Y", SPC_OP}, + {"mov Y,A", SPC_OP}, + {"dbnz Y,0x%02x", SPC_ARG8_1}, + {"stop", SPC_OP} +}; diff --git a/libr/asm/arch/spc700/spc700dis.c b/libr/asm/arch/spc700/spc700dis.c new file mode 100644 index 0000000000..3abad73fed --- /dev/null +++ b/libr/asm/arch/spc700/spc700dis.c @@ -0,0 +1,41 @@ +/* radare - LGPL - Copyright 2014 - condret@runas-racer.com */ + +#include +#include +#include +#include +#include "spc700_opcode_table.h" + +static int spc700OpLength(int spcoptype){ + switch(spcoptype) { + case SPC_OP: + return 1; + case SPC_ARG8_1: + return 2; + case SPC_ARG8_2: + case SPC_ARG16: + return 3; + } + return 0; +} + +static int spc700Disass(RAsmOp *op, const ut8 *buf, int len) { + int foo = spc700OpLength (spc_op_table[buf[0]].type); + if (len < foo) + return 0; + switch (spc_op_table[buf[0]].type) { + case SPC_OP: + sprintf (op->buf_asm, "%s", spc_op_table[buf[0]].name); + break; + case SPC_ARG8_1: + sprintf (op->buf_asm, spc_op_table[buf[0]].name, buf[1]); + break; + case SPC_ARG8_2: + sprintf (op->buf_asm, spc_op_table[buf[0]].name, buf[1], buf[2]); + break; + case SPC_ARG16: + sprintf (op->buf_asm, spc_op_table[buf[0]].name, buf[1]+0x100*buf[2]); + break; + } + return foo; +} diff --git a/libr/asm/p/Makefile b/libr/asm/p/Makefile index 4f7d0b383c..89ee992240 100644 --- a/libr/asm/p/Makefile +++ b/libr/asm/p/Makefile @@ -13,7 +13,7 @@ ALL_TARGETS= # TODO: rename to enabled plugins ARCHS=mips.mk sparc.mk java.mk bf.mk arm.mk dalvik.mk x86_as.mk x86_nz.mk ARCHS+=ppc.mk x86_olly.mk x86.mk csr.mk x86_nasm.mk psosvm.mk avr.mk -ARCHS+=msil.mk sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk 6502.mk h8300.mk cr16.mk v850.mk +ARCHS+=msil.mk sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk 6502.mk h8300.mk cr16.mk v850.mk spc700.mk include $(ARCHS) all: ${ALL_TARGETS} diff --git a/libr/asm/p/asm_spc700.c b/libr/asm/p/asm_spc700.c new file mode 100644 index 0000000000..caa6da9a4c --- /dev/null +++ b/libr/asm/p/asm_spc700.c @@ -0,0 +1,37 @@ +/* radare - LGPL - Copyright 2012-2014 - pancake + 2014 - condret */ + +// fork of asm_z80.c + +#include +#include +#include +#include +#include "../arch/spc700/spc700dis.c" + +static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) { + int dlen = spc700Disass(r_op, buf, len); + if(dlen < 0) dlen=0; + r_op->size = dlen; + return dlen; +} + +RAsmPlugin r_asm_plugin_spc700 = { + .name = "spc700", + .desc = "spc700, snes' sound-chip", + .arch = "spc700", + .license = "LGPL3", + .bits = 16, + .init = NULL, + .fini = NULL, + .disassemble = &disassemble, + .modify = NULL, + .assemble = NULL, +}; + +#ifndef CORELIB +struct r_lib_struct_t radare_plugin = { + .type = R_LIB_TYPE_ASM, + .data = &r_asm_plugin_spc700 +}; +#endif diff --git a/libr/asm/p/spc700.mk b/libr/asm/p/spc700.mk new file mode 100644 index 0000000000..7fc0912f5a --- /dev/null +++ b/libr/asm/p/spc700.mk @@ -0,0 +1,9 @@ +OBJ_SPC700=asm_spc700.o + +STATIC_OBJ+=${OBJ_SPC700} +TARGET_SPC700=asm_spc700.${EXT_SO} + +ALL_TARGETS+=${TARGET_SPC700} + +${TARGET_SPC700}: ${OBJ_SPC700} + ${CC} ${call libname,asm_spc700} ${CFLAGS} -o ${TARGET_SPC700} ${OBJ_SPC700} diff --git a/libr/include/r_asm.h b/libr/include/r_asm.h index 1e83e50d1e..4f18cc99d6 100644 --- a/libr/include/r_asm.h +++ b/libr/include/r_asm.h @@ -200,6 +200,7 @@ extern RAsmPlugin r_asm_plugin_v850; extern RAsmPlugin r_asm_plugin_sysz; extern RAsmPlugin r_asm_plugin_sparc_cs; extern RAsmPlugin r_asm_plugin_xcore_cs; +extern RAsmPlugin r_asm_plugin_spc700; #endif #ifdef __cplusplus diff --git a/plugins.def.cfg b/plugins.def.cfg index 353ca1042c..5d9c480bef 100644 --- a/plugins.def.cfg +++ b/plugins.def.cfg @@ -44,6 +44,7 @@ asm.malbolge asm.ws asm.cr16 asm.v850 +asm.spc700 anal.sh anal.x86_cs anal.x86_udis