diff --git a/libr/asm/arch/gb/gbasm.c b/libr/asm/arch/gb/gbasm.c new file mode 100644 index 0000000000..628fb8add7 --- /dev/null +++ b/libr/asm/arch/gb/gbasm.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +static void str_op (char *c) +{ + if ((c[0] <= 'Z') && (c[0] >= 'A')) + c[0] += 0x20; +} + +static int gbAsm (RAsm *a, RAsmOp *op, const char *buf) +{ + int mn_len, i, len = 1; + ut32 mn = 0; + if (!a || !op || !buf) + return 0; + strncpy (op->buf_asm, buf, R_ASM_BUFSIZE); + r_str_replace (op->buf_asm, " ", " ", R_TRUE); + r_str_replace (op->buf_asm, " ,", ",", R_TRUE); + mn_len = r_str_do_until_token (str_op, op->buf_asm, ' '); + if (mn_len < 2 || mn_len > 4) + return 0; + for (i = 0; i < mn_len; i++) + mn = (mn << 8) | op->buf_asm[i]; + switch (mn) { + case (int)'nop': + op->buf[0] = 0x00; + break; + case (int)'rlca': + op->buf[0] = 0x07; + break; + case (int)'rrca': + op->buf[0] = 0xf0; + break; + case (int)'stop': + op->buf[0] = 0x10; + break; + case (int)'rla': + op->buf[0] = 0x17; + break; + case (int)'rra': + op->buf[0] = 0x1f; + break; + case (int)'daa': + op->buf[0] = 0x27; + break; + case (int)'cpl': + op->buf[0] = 0x2f; + break; + case (int)'scf': + op->buf[0] = 0x37; + break; + case (int)'ccf': + op->buf[0] = 0x3f; + break; + case (int)'halt': + op->buf[0] = 0x76; + break; + case (int)'ret': + op->buf[0] = 0xc9; + break; + case (int)'di': + op->buf[0] = 0xf3; + break; + case (int)'ei': + op->buf[0] = 0xfb; + break; + default: + len = 0; + break; + } + return op->size = len; +} diff --git a/libr/asm/p/asm_gb.c b/libr/asm/p/asm_gb.c index 3676fb27a4..c533ba972f 100644 --- a/libr/asm/p/asm_gb.c +++ b/libr/asm/p/asm_gb.c @@ -1,5 +1,5 @@ /* radare - LGPL - Copyright 2012-2014 - pancake - 2013 - condret */ + 2013-2015 - condret */ // fork of asm_z80.c @@ -8,6 +8,7 @@ #include #include #include "../arch/gb/gbdis.c" +#include "../arch/gb/gbasm.c" static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) { int dlen = gbDisass(r_op,buf,len); @@ -16,6 +17,10 @@ static int disassemble(RAsm *a, RAsmOp *r_op, const ut8 *buf, int len) { return dlen; } +static int assemble(RAsm *a, RAsmOp *r_op, const char *buf) { + return gbAsm (a, r_op, buf); +} + RAsmPlugin r_asm_plugin_gb = { .name = "gb", .desc = "GameBoy(TM) (z80-like)", @@ -26,7 +31,7 @@ RAsmPlugin r_asm_plugin_gb = { .fini = NULL, .disassemble = &disassemble, .modify = NULL, - .assemble = NULL, + .assemble = &assemble, }; #ifndef CORELIB diff --git a/libr/include/r_util.h b/libr/include/r_util.h index 855e96f677..cd80d41c3b 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -548,6 +548,10 @@ R_API int r_str_delta(char *p, char a, char b); R_API void r_str_filter(char *str, int len); R_API const char * r_str_tok (const char *str1, const char b, size_t len); +typedef void (*str_operation)(char *c); + +R_API int r_str_do_until_token (str_operation op, char *str, const char tok); + R_API int r_str_re_match(const char *str, const char *reg); R_API int r_str_re_replace(const char *str, const char *reg, const char *sub); R_API int r_str_unescape(char *buf); diff --git a/libr/util/str.c b/libr/util/str.c index dfc1bbb731..e58e79232d 100644 --- a/libr/util/str.c +++ b/libr/util/str.c @@ -1847,6 +1847,17 @@ R_API const char * r_str_tok (const char *str1, const char b, size_t len) { return p; } +R_API int r_str_do_until_token (str_operation op, char *str, const char tok) +{ + int ret; + if (!str) + return -1; + if (!op) + for (ret = 0; (str[ret] != tok) && str[ret]; ret++) { } + else for (ret = 0; (str[ret] != tok) && str[ret]; ret++) { op (str+ret); } + return ret; +} + R_API const char *r_str_pad(const char ch, int sz) { static char pad[1024]; if (sz<0) sz = 0;