mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +00:00
Add a disassembler for Sharp LH5801 processors
This commit is contained in:
parent
720eb5f08e
commit
6a3362ea9a
@ -33,7 +33,7 @@ Architectures:
|
||||
|
||||
6502, 8051, arm, arc, avr, bf, tms320 (c54x, c55x, c55+), gameboy
|
||||
csr, dcpu16, dalvik, i8080, mips, m68k, mips, msil, snes, nios II,
|
||||
sh, sparc, rar, powerpc, i386, x86-64, H8/300, malbolge, T8200
|
||||
sh, sparc, rar, powerpc, i386, x86-64, H8/300, malbolge, T8200, LH5801
|
||||
|
||||
File Formats:
|
||||
|
||||
|
837
libr/asm/arch/lh5801/lh5801.c
Normal file
837
libr/asm/arch/lh5801/lh5801.c
Normal file
@ -0,0 +1,837 @@
|
||||
/* SHARP LH 5801 disassembler -- instruction decoder,
|
||||
* Copyright (C) 2014 jn,
|
||||
* Released under the terms and conditions of the GNU LGPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This disassembler is based on the "SHARP PC-1500/A Systemhandbuch"
|
||||
* (system manual) as published by Günter Holtkötter GmbH.
|
||||
*
|
||||
* An english version is available at
|
||||
* http://www.pc1500.com/technical_reference_manual.html.
|
||||
*/
|
||||
|
||||
#include "lh5801.h"
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
|
||||
#define ARRAY_LENGTH(a) (sizeof(a)/sizeof((a)[0]))
|
||||
|
||||
const struct lh5801_insn_class_desc
|
||||
lh5801_insn_class_descs[LH5801_INSNC_NUMBER] = {
|
||||
[LH5801_INSNC_ADC] = { "adc", "add with carry" },
|
||||
[LH5801_INSNC_ADI] = { "adi", "add immediate" },
|
||||
[LH5801_INSNC_DCA] = { "dca", "decimal add" },
|
||||
[LH5801_INSNC_ADR] = { "adr", "add Rreg" },
|
||||
[LH5801_INSNC_SBC] = { "sbc", "subtract with carry" },
|
||||
[LH5801_INSNC_SBI] = { "sbi", "subtract immediate" },
|
||||
[LH5801_INSNC_DCS] = { "dcs", "decimal subtract" },
|
||||
[LH5801_INSNC_AND] = { "and", "and accumulator" },
|
||||
[LH5801_INSNC_ANI] = { "ani", "and immediate" },
|
||||
[LH5801_INSNC_ORA] = { "ora", "or accumulator" },
|
||||
[LH5801_INSNC_ORI] = { "ori", "or immediate" },
|
||||
[LH5801_INSNC_EOR] = { "eor", "exclusive or" },
|
||||
[LH5801_INSNC_EAI] = { "eai", "exclusive or accumulator, immediate" },
|
||||
[LH5801_INSNC_INC] = { "inc", "increment" },
|
||||
[LH5801_INSNC_DEC] = { "dec", "decrement" },
|
||||
[LH5801_INSNC_CPA] = { "cpa", "compare accumulator" },
|
||||
[LH5801_INSNC_CPI] = { "cpi", "compare immediate" },
|
||||
[LH5801_INSNC_BIT] = { "bit", "bit test" },
|
||||
[LH5801_INSNC_BII] = { "bii", "bit test immediate" },
|
||||
[LH5801_INSNC_LDA] = { "lda", "load accumulator" },
|
||||
[LH5801_INSNC_LDE] = { "lde", "load and decrement" },
|
||||
[LH5801_INSNC_LIN] = { "lin", "load and increment" },
|
||||
[LH5801_INSNC_LDI] = { "ldi", "load immediate" },
|
||||
[LH5801_INSNC_LDX] = { "ldx", "load Xreg" },
|
||||
[LH5801_INSNC_STA] = { "sta", "store accumulator" },
|
||||
[LH5801_INSNC_SDE] = { "sde", "store and decrement" },
|
||||
[LH5801_INSNC_SIN] = { "sin", "store and increment" },
|
||||
[LH5801_INSNC_STX] = { "stx", "store Xreg" },
|
||||
[LH5801_INSNC_PSH] = { "psh", "push" },
|
||||
[LH5801_INSNC_POP] = { "pop", "pop" },
|
||||
[LH5801_INSNC_ATT] = { "att", "accumulator to t (status register)" },
|
||||
[LH5801_INSNC_TTA] = { "tta", "t (status register) to accumulator" },
|
||||
[LH5801_INSNC_TIN] = { "tin", "transfer and increment" },
|
||||
[LH5801_INSNC_CIN] = { "cin", "compare and increment" },
|
||||
[LH5801_INSNC_ROL] = { "rol", "rotate left" },
|
||||
[LH5801_INSNC_ROR] = { "ror", "rotate right" },
|
||||
[LH5801_INSNC_SHL] = { "shl", "shift left" },
|
||||
[LH5801_INSNC_SHR] = { "shr", "shift right" },
|
||||
[LH5801_INSNC_DRL] = { "drl", "digit rotate left" },
|
||||
[LH5801_INSNC_DRR] = { "drr", "digit rotate right" },
|
||||
[LH5801_INSNC_AEX] = { "aex", "exchange accumulator" },
|
||||
[LH5801_INSNC_SEC] = { "sec", "set carry flag" },
|
||||
[LH5801_INSNC_REC] = { "rec", "reset carry flag" },
|
||||
[LH5801_INSNC_CDV] = { "cdv", "clear divider" },
|
||||
[LH5801_INSNC_ATP] = { "atp", "accumulator to port" },
|
||||
[LH5801_INSNC_SPU] = { "spu", "set PU" },
|
||||
[LH5801_INSNC_RPU] = { "rpu", "reset PU" },
|
||||
[LH5801_INSNC_SPV] = { "spv", "set PV" },
|
||||
[LH5801_INSNC_RPV] = { "rpv", "reset PV" },
|
||||
[LH5801_INSNC_SDP] = { "sdp", "set display" },
|
||||
[LH5801_INSNC_RDP] = { "rdp", "reset display" },
|
||||
[LH5801_INSNC_ITA] = { "ita", "IN to accumulator" },
|
||||
[LH5801_INSNC_SIE] = { "sie", "set interrupt enable" },
|
||||
[LH5801_INSNC_RIE] = { "rie", "reset interrupt enable" },
|
||||
[LH5801_INSNC_AM0] = { "am0", "accumulator to tm and 0" },
|
||||
[LH5801_INSNC_AM1] = { "am1", "accumulator to tm and 1" },
|
||||
[LH5801_INSNC_NOP] = { "nop", "no operation" },
|
||||
[LH5801_INSNC_HLT] = { "hlt", "halt" },
|
||||
[LH5801_INSNC_OFF] = { "off", "\"off\", reset BF" },
|
||||
[LH5801_INSNC_JMP] = { "jmp", "jump" },
|
||||
[LH5801_INSNC_BCH] = { "bch", "unconditional branch" },
|
||||
[LH5801_INSNC_BCC] = { "bcc", "conditional branch" },
|
||||
[LH5801_INSNC_LOP] = { "lop", "loop" },
|
||||
[LH5801_INSNC_SJP] = { "sjp", "subroutine jump (aka. call)" },
|
||||
[LH5801_INSNC_VEJ] = { "vej", "vector subroutine jump, short format" },
|
||||
[LH5801_INSNC_VMJ] = { "vmj", "vector subroutine jump, long format" },
|
||||
[LH5801_INSNC_VCC] = { "vcc", "conditional vector subroutine jump" },
|
||||
[LH5801_INSNC_RTN] = { "rtn", "return from subroutine" },
|
||||
[LH5801_INSNC_RTI] = { "rti", "return from interrupt" }
|
||||
};
|
||||
|
||||
/* These flags describe an instruction variant's properties with regard to
|
||||
* encoding and printing */
|
||||
enum lh5801_insn_format {
|
||||
/* An instruction can contain up to three immediate data bytes. */
|
||||
LH5801_IFMT_IMM0 = 0,
|
||||
LH5801_IFMT_IMM1,
|
||||
LH5801_IFMT_IMM2,
|
||||
LH5801_IFMT_IMM3,
|
||||
LH5801_IFMT_IMM_MASK = 3,
|
||||
|
||||
/* Instructions may either require an 0xFD prefix, require its absence,
|
||||
* or behave differently if it is found. */
|
||||
LH5801_IFMT_FD_NO = 0,
|
||||
LH5801_IFMT_FD_YES = 1 << 2,
|
||||
LH5801_IFMT_FD_MOD = 2 << 2, /* FD_MEM */
|
||||
LH5801_IFMT_FD_MASK = 3 << 2, /* ^- also take care of (ij) */
|
||||
|
||||
/* Some instructions encode access registers */
|
||||
LH5801_IFMT_RREG = 1 << 4, /* X,Y or U, encoded by two bits */
|
||||
LH5801_IFMT_AREG = 2 << 4, /* accumulator */
|
||||
LH5801_IFMT_SREG = 3 << 4, /* stack pointer */
|
||||
LH5801_IFMT_PREG = 4 << 4, /* program counter */
|
||||
LH5801_IFMT_REG_MASK = 7 << 4,
|
||||
|
||||
/* Branch and vector jump instructions may have a three-bit condition
|
||||
* code. */
|
||||
LH5801_IFMT_COND = 1 << 7,
|
||||
|
||||
/* Branch instructions may point forward or backward. */
|
||||
LH5801_IFMT_BCH = 1 << 8,
|
||||
|
||||
/* The short vector jump instruction (VEJ) */
|
||||
LH5801_IFMT_VEJ = 1 << 9,
|
||||
|
||||
/* Register access modes: full, low/high half, or memory pointed to */
|
||||
LH5801_IFMT_RFULL = 0,
|
||||
LH5801_IFMT_RLOW = 1 << 10,
|
||||
LH5801_IFMT_RHIGH = 2 << 10,
|
||||
LH5801_IFMT_RMEM = 3 << 10, /* <-- kill this, see above */
|
||||
LH5801_IFMT_RMODE_MASK = 3 << 10,
|
||||
};
|
||||
|
||||
#define LH5801_IFMT_IMMS(f) ((f)&LH5801_IFMT_IMM_MASK)
|
||||
#define LH5801_IFMT_RMODE(f) ((f)&LH5801_IFMT_RMODE_MASK)
|
||||
|
||||
static int lh5801_ifmt_fd_matches(enum lh5801_insn_format fmt, int fd)
|
||||
{
|
||||
switch (fmt & LH5801_IFMT_FD_MASK) {
|
||||
case LH5801_IFMT_FD_NO: return !fd;
|
||||
case LH5801_IFMT_FD_YES: return fd;
|
||||
case LH5801_IFMT_FD_MOD: return R_TRUE;
|
||||
default: assert(R_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Instruction (variant) description. */
|
||||
struct lh5801_insn_desc {
|
||||
ut8 iclass; /* enum lh5801_insn_class */
|
||||
|
||||
/* The common bits in this format */
|
||||
ut8 opcode;
|
||||
|
||||
ut16 format; /* enum lh5801_insn_format */
|
||||
};
|
||||
|
||||
const struct lh5801_insn_desc lh5801_insn_descs[] = {
|
||||
{ /* adc rl*/
|
||||
.iclass = LH5801_INSNC_ADC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x02,
|
||||
},
|
||||
{ /* adc rh*/
|
||||
.iclass = LH5801_INSNC_ADC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH,
|
||||
.opcode = 0x82,
|
||||
},
|
||||
{ /* adc (r) */
|
||||
.iclass = LH5801_INSNC_ADC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RMEM|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0x03,
|
||||
},
|
||||
{ /* adc (0000h) */
|
||||
.iclass = LH5801_INSNC_ADC,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xa3,
|
||||
},
|
||||
{ /* adi a, 00h */
|
||||
.iclass = LH5801_INSNC_ADI,
|
||||
.format = LH5801_IFMT_IMM1|LH5801_IFMT_AREG,
|
||||
.opcode = 0xb3
|
||||
},
|
||||
{ /* adi (r), 00h */
|
||||
.iclass = LH5801_INSNC_ADI,
|
||||
.format = LH5801_IFMT_IMM1|LH5801_IFMT_RREG|LH5801_IFMT_FD_MOD|LH5801_IFMT_RMEM,
|
||||
.opcode = 0x4f,
|
||||
},
|
||||
{ /* adi (0000h), 00h */
|
||||
.iclass = LH5801_INSNC_ADI,
|
||||
.format = LH5801_IFMT_IMM3|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xef
|
||||
},
|
||||
{ /* dca (r) */
|
||||
.iclass = LH5801_INSNC_DCA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0x8c,
|
||||
},
|
||||
{ /* adr r */
|
||||
.iclass = LH5801_INSNC_ADR,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xca,
|
||||
},
|
||||
{ /* sbc rl */
|
||||
.iclass = LH5801_INSNC_SBC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x00
|
||||
},
|
||||
{ /* sbc rh */
|
||||
.iclass = LH5801_INSNC_SBC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH,
|
||||
.opcode = 0x80
|
||||
},
|
||||
{ /* sbc (r) */
|
||||
.iclass = LH5801_INSNC_SBC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RMEM,
|
||||
.opcode = 0x01
|
||||
},
|
||||
{ /* sbc (0000h) */
|
||||
.iclass = LH5801_INSNC_SBC,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_RMEM,
|
||||
.opcode = 0xa1
|
||||
},
|
||||
{ /* sbi a,i */
|
||||
.iclass = LH5801_INSNC_SBI,
|
||||
.format = LH5801_IFMT_AREG|LH5801_IFMT_IMM1,
|
||||
.opcode = 0xb1
|
||||
},
|
||||
{ /* dcs (r) */
|
||||
.iclass = LH5801_INSNC_DCS,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RMEM,
|
||||
.opcode = 0x0c
|
||||
},
|
||||
|
||||
{ /* eai 00h */
|
||||
.iclass = LH5801_INSNC_EAI,
|
||||
.format = LH5801_IFMT_IMM1,
|
||||
.opcode = 0xbd
|
||||
},
|
||||
{ /* inc a */
|
||||
.iclass = LH5801_INSNC_INC,
|
||||
.format = LH5801_IFMT_AREG,
|
||||
.opcode = 0xdd,
|
||||
},
|
||||
{ /* inc rl */
|
||||
.iclass = LH5801_INSNC_INC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x40,
|
||||
},
|
||||
{ /* inc rh */
|
||||
.iclass = LH5801_INSNC_INC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH|LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x40,
|
||||
},
|
||||
{ /* inc r */
|
||||
.iclass = LH5801_INSNC_INC,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x44
|
||||
},
|
||||
{ /* dec a */
|
||||
.iclass = LH5801_INSNC_DEC,
|
||||
.format = LH5801_IFMT_AREG,
|
||||
.opcode = 0xdf,
|
||||
},
|
||||
{ /* dec rl */
|
||||
.iclass = LH5801_INSNC_DEC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x42,
|
||||
},
|
||||
{ /* dec rh */
|
||||
.iclass = LH5801_INSNC_DEC,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH|LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x42,
|
||||
},
|
||||
{ /* dec r */
|
||||
.iclass = LH5801_INSNC_DEC,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x46
|
||||
},
|
||||
{ /* cpa rl */
|
||||
.iclass = LH5801_INSNC_CPA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x06
|
||||
},
|
||||
{ /* cpa rh */
|
||||
.iclass = LH5801_INSNC_CPA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH,
|
||||
.opcode = 0x86
|
||||
},
|
||||
{ /* cpa (r) */
|
||||
.iclass = LH5801_INSNC_CPA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RMEM,
|
||||
.opcode = 0x07
|
||||
},
|
||||
{ /* cpa (0000h) */
|
||||
.iclass = LH5801_INSNC_CPA,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xa7
|
||||
},
|
||||
{ /* cpi rl,00h */
|
||||
.iclass = LH5801_INSNC_CPI,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x4e
|
||||
},
|
||||
{ /* cpi rh,00h */
|
||||
.iclass = LH5801_INSNC_CPI,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x4c
|
||||
},
|
||||
{ /* cpi a,00h */
|
||||
.iclass = LH5801_INSNC_CPI,
|
||||
.format = LH5801_IFMT_AREG|LH5801_IFMT_IMM1,
|
||||
.opcode = 0xb7
|
||||
},
|
||||
{ /* bit (r) */
|
||||
.iclass = LH5801_INSNC_BIT,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x0f
|
||||
},
|
||||
{ /* bit (0000h) */
|
||||
.iclass = LH5801_INSNC_BIT,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xaf
|
||||
},
|
||||
{ /* bii a,i */
|
||||
.iclass = LH5801_INSNC_BII,
|
||||
.format = LH5801_IFMT_AREG|LH5801_IFMT_IMM1,
|
||||
.opcode = 0xbf
|
||||
},
|
||||
{ /* bii (r),i */
|
||||
.iclass = LH5801_INSNC_BII,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_FD_MOD|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x4b
|
||||
},
|
||||
{ /* bii (0000h),i */
|
||||
.iclass = LH5801_INSNC_BII,
|
||||
.format = LH5801_IFMT_IMM3|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xed
|
||||
},
|
||||
{ /* lda rl */
|
||||
.iclass = LH5801_INSNC_LDA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x04,
|
||||
},
|
||||
{ /* lda rh */
|
||||
.iclass = LH5801_INSNC_LDA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH,
|
||||
.opcode = 0x84,
|
||||
},
|
||||
{ /* lda (r) */
|
||||
.iclass = LH5801_INSNC_LDA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0x05,
|
||||
},
|
||||
{ /* lda (0000h) */
|
||||
.iclass = LH5801_INSNC_LDA,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xa5,
|
||||
},
|
||||
{ /* lde r */
|
||||
.iclass = LH5801_INSNC_LDE,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x47,
|
||||
},
|
||||
{ /* lin r */
|
||||
.iclass = LH5801_INSNC_LIN,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x45,
|
||||
},
|
||||
{ /* ldi rl, i */
|
||||
.iclass = LH5801_INSNC_LDI,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x4a,
|
||||
},
|
||||
{ /* ldi rh, i */
|
||||
.iclass = LH5801_INSNC_LDI,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x48,
|
||||
},
|
||||
{ /* ldi a, i */
|
||||
.iclass = LH5801_INSNC_LDI,
|
||||
.format = LH5801_IFMT_AREG|LH5801_IFMT_IMM1,
|
||||
.opcode = 0xb5
|
||||
},
|
||||
{ /* ldi s, ij */
|
||||
.iclass = LH5801_INSNC_LDI,
|
||||
.format = LH5801_IFMT_AREG|LH5801_IFMT_IMM2,
|
||||
.opcode = 0xaa
|
||||
},
|
||||
|
||||
{ /* ldx r */
|
||||
.iclass = LH5801_INSNC_LDX,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_RREG,
|
||||
.opcode = 0x08,
|
||||
},
|
||||
{ /* ldx s */
|
||||
.iclass = LH5801_INSNC_LDX,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x48,
|
||||
},
|
||||
{ /* ldx p */
|
||||
.iclass = LH5801_INSNC_LDX,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x58
|
||||
},
|
||||
{ /* sta rl */
|
||||
.iclass = LH5801_INSNC_STA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RLOW,
|
||||
.opcode = 0x0a
|
||||
},
|
||||
{ /* sta rh */
|
||||
.iclass = LH5801_INSNC_STA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_RHIGH,
|
||||
.opcode = 0x08
|
||||
},
|
||||
{ /* sta (r) */
|
||||
.iclass = LH5801_INSNC_STA,
|
||||
.format = LH5801_IFMT_RREG|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0x0e
|
||||
},
|
||||
{ /* sta (0000h) */
|
||||
.iclass = LH5801_INSNC_STA,
|
||||
.format = LH5801_IFMT_IMM2|LH5801_IFMT_FD_MOD,
|
||||
.opcode = 0xae
|
||||
},
|
||||
{ /* sde r */
|
||||
.iclass = LH5801_INSNC_SDE,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x43
|
||||
},
|
||||
{ /* sin r */
|
||||
.iclass = LH5801_INSNC_SIN,
|
||||
.format = LH5801_IFMT_RREG,
|
||||
.opcode = 0x41
|
||||
},
|
||||
{ /* stx r */
|
||||
.iclass = LH5801_INSNC_STX,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_RREG,
|
||||
.opcode = 0x4a
|
||||
},
|
||||
{ /* stx s */
|
||||
.iclass = LH5801_INSNC_STX,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_SREG,
|
||||
.opcode = 0x4e
|
||||
},
|
||||
{ /* stx p */
|
||||
.iclass = LH5801_INSNC_STX,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_PREG,
|
||||
.opcode = 0x5e
|
||||
},
|
||||
{ /* psh a */
|
||||
.iclass = LH5801_INSNC_PSH,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_AREG,
|
||||
.opcode = 0xc8
|
||||
},
|
||||
{ /* psh r */
|
||||
.iclass = LH5801_INSNC_PSH,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_RREG,
|
||||
.opcode = 0x88
|
||||
},
|
||||
{ /* pop a */
|
||||
.iclass = LH5801_INSNC_POP,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_AREG,
|
||||
.opcode = 0x8a
|
||||
},
|
||||
{ /* pop r */
|
||||
.iclass = LH5801_INSNC_POP,
|
||||
.format = LH5801_IFMT_FD_YES|LH5801_IFMT_RREG,
|
||||
.opcode = 0x0a
|
||||
},
|
||||
{ /* att */
|
||||
.iclass = LH5801_INSNC_ATT,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xec
|
||||
},
|
||||
{ /* tta */
|
||||
.iclass = LH5801_INSNC_TTA,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xaa
|
||||
},
|
||||
{ /* tin */
|
||||
.iclass = LH5801_INSNC_TIN,
|
||||
.format = 0,
|
||||
.opcode = 0xf5
|
||||
},
|
||||
{ /* cin */
|
||||
.iclass = LH5801_INSNC_CIN,
|
||||
.format = 0,
|
||||
.opcode = 0xf7
|
||||
},
|
||||
{ /* rol */
|
||||
.iclass = LH5801_INSNC_ROL,
|
||||
.format = 0,
|
||||
.opcode = 0xdb
|
||||
},
|
||||
{ /* ror */
|
||||
.iclass = LH5801_INSNC_ROR,
|
||||
.format = 0,
|
||||
.opcode = 0xd1
|
||||
},
|
||||
{ /* shl */
|
||||
.iclass = LH5801_INSNC_SHL,
|
||||
.format = 0,
|
||||
.opcode = 0xd9
|
||||
},
|
||||
{ /* shr */
|
||||
.iclass = LH5801_INSNC_SHR,
|
||||
.format = 0,
|
||||
.opcode = 0xd5
|
||||
},
|
||||
|
||||
{ /* am0 */
|
||||
.iclass = LH5801_INSNC_AM0,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xce
|
||||
},
|
||||
{ /* am1 */
|
||||
.iclass = LH5801_INSNC_AM1,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xde
|
||||
},
|
||||
{ /* cdv */
|
||||
.iclass = LH5801_INSNC_CDV,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x8e
|
||||
},
|
||||
{ /* atp */
|
||||
.iclass = LH5801_INSNC_ATP,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xcc
|
||||
},
|
||||
{ /* sdp */
|
||||
.iclass = LH5801_INSNC_SDP,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xc1
|
||||
},
|
||||
{ /* rdp */
|
||||
.iclass = LH5801_INSNC_RDP,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xc0
|
||||
},
|
||||
{ /* spu */
|
||||
.iclass = LH5801_INSNC_SPU,
|
||||
.format = 0,
|
||||
.opcode = 0xe1
|
||||
},
|
||||
{ /* rpu */
|
||||
.iclass = LH5801_INSNC_RPU,
|
||||
.format = 0,
|
||||
.opcode = 0xe3
|
||||
},
|
||||
{ /* spv */
|
||||
.iclass = LH5801_INSNC_SPV,
|
||||
.format = 0,
|
||||
.opcode = 0xa8
|
||||
},
|
||||
{ /* rpv */
|
||||
.iclass = LH5801_INSNC_RPV,
|
||||
.format = 0,
|
||||
.opcode = 0xb8
|
||||
},
|
||||
{ /* ita */
|
||||
.iclass = LH5801_INSNC_ITA,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xba
|
||||
},
|
||||
{ /* rie */
|
||||
.iclass = LH5801_INSNC_RIE,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xbe
|
||||
},
|
||||
{ /* sie */
|
||||
.iclass = LH5801_INSNC_SIE,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x81
|
||||
},
|
||||
{ /* hlt */
|
||||
.iclass = LH5801_INSNC_HLT,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0xb1
|
||||
},
|
||||
{ /* off */
|
||||
.iclass = LH5801_INSNC_OFF,
|
||||
.format = LH5801_IFMT_FD_YES,
|
||||
.opcode = 0x4c
|
||||
},
|
||||
{ /* nop */
|
||||
.iclass = LH5801_INSNC_NOP,
|
||||
.format = 0,
|
||||
.opcode = 0x38
|
||||
},
|
||||
{ /* sec */
|
||||
.iclass = LH5801_INSNC_SEC,
|
||||
.format = 0,
|
||||
.opcode = 0xfb
|
||||
},
|
||||
{ /* rec */
|
||||
.iclass = LH5801_INSNC_REC,
|
||||
.format = 0,
|
||||
.opcode = 0xf9
|
||||
},
|
||||
{ /* jmp 0000h */
|
||||
.iclass = LH5801_INSNC_JMP,
|
||||
.format = LH5801_IFMT_IMM2,
|
||||
.opcode = 0xba
|
||||
},
|
||||
{ /* bch ±00h */
|
||||
.iclass = LH5801_INSNC_BCH,
|
||||
.format = LH5801_IFMT_BCH|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x8e
|
||||
},
|
||||
{ /* bcc ±00h */
|
||||
.iclass = LH5801_INSNC_BCC,
|
||||
.format = LH5801_IFMT_BCH|LH5801_IFMT_COND|LH5801_IFMT_IMM1,
|
||||
.opcode = 0x81
|
||||
},
|
||||
{ /* lop 02h */
|
||||
.iclass = LH5801_INSNC_LOP,
|
||||
.format = LH5801_IFMT_IMM1,
|
||||
.opcode = 0x88
|
||||
},
|
||||
{ /* sjp 0000h */
|
||||
.iclass = LH5801_INSNC_SJP,
|
||||
.format = LH5801_IFMT_IMM2,
|
||||
.opcode = 0xbe,
|
||||
},
|
||||
{ /* vej c0h */
|
||||
.iclass = LH5801_INSNC_VEJ,
|
||||
.format = LH5801_IFMT_VEJ,
|
||||
.opcode = 0xc0
|
||||
},
|
||||
|
||||
{ /* rtn */
|
||||
.iclass = LH5801_INSNC_RTN,
|
||||
.format = 0,
|
||||
.opcode = 0x9a
|
||||
},
|
||||
{ /* rti */
|
||||
.iclass = LH5801_INSNC_RTI,
|
||||
.format = 0,
|
||||
.opcode = 0x8a
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Decodes one instruction.
|
||||
* returns -1 on invalid instructions, the length on valid instructions,
|
||||
* and 0 when decoding wasn't possible due to a too small length */
|
||||
ssize_t lh5801_decode(struct lh5801_insn *insn, const ut8 *buf, size_t len)
|
||||
{
|
||||
int fd = (buf[0] == 0xfd);
|
||||
int type = -1;
|
||||
unsigned i;
|
||||
struct lh5801_insn_desc desc;
|
||||
|
||||
if (fd) {
|
||||
buf++;
|
||||
len--;
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* Find the correct opcode */
|
||||
for (i = 0; i < ARRAY_LENGTH(lh5801_insn_descs); i++) {
|
||||
ut8 byte = *buf;
|
||||
unsigned fmt;
|
||||
|
||||
desc = lh5801_insn_descs[i];
|
||||
fmt = desc.format;
|
||||
|
||||
if(!lh5801_ifmt_fd_matches(fmt, fd))
|
||||
continue;
|
||||
|
||||
/* HACKHACK */
|
||||
/* Ignore instructions referencing the register number 3. */
|
||||
if ((fmt & LH5801_IFMT_RREG) && (byte >> 4) % 4 == 3)
|
||||
continue; /* TODO: ^ write a macro */
|
||||
|
||||
/* Reduce the opcode byte to the relevant bits */
|
||||
if (fmt & LH5801_IFMT_RREG)
|
||||
byte &= 0xcf; /* xxRRxxxx */
|
||||
if (fmt & LH5801_IFMT_COND)
|
||||
byte &= 0xf1; /* xxxxCCCx */
|
||||
if (fmt & LH5801_IFMT_BCH)
|
||||
byte &= 0xef; /* xxxSxxxx */
|
||||
|
||||
if (byte == desc.opcode) {
|
||||
type = i;
|
||||
break;
|
||||
}
|
||||
|
||||
/* The short vector subroutine jump instructions require
|
||||
* special treatment. */
|
||||
if (fmt & LH5801_IFMT_VEJ) {
|
||||
if (!(byte & 1) && byte >= 0xc0 && byte <= 0xf6) {
|
||||
type = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type == -1)
|
||||
return -1;
|
||||
|
||||
/* fill the insn structure. */
|
||||
insn->iclass = desc.iclass;
|
||||
insn->type = type;
|
||||
insn->fd = fd;
|
||||
insn->opcode = buf[0];
|
||||
switch (LH5801_IFMT_IMMS(desc.format)) {
|
||||
case 3: insn->imm[2] = buf[3];
|
||||
case 2: insn->imm[1] = buf[2];
|
||||
case 1: insn->imm[0] = buf[1];
|
||||
}
|
||||
|
||||
/* return the instruction length */
|
||||
return fd + 1 + LH5801_IFMT_IMMS(desc.format);
|
||||
}
|
||||
|
||||
/* Print the accessed register. Buf must point to a buffer of at least eight
|
||||
* bytes. Only the return value should be used. */
|
||||
static char *print_reg(char *buf, const struct lh5801_insn *insn)
|
||||
{
|
||||
const struct lh5801_insn_desc desc = lh5801_insn_descs[insn->type];
|
||||
unsigned regnr = (insn->opcode >> 4) & 3;
|
||||
const char names[] = "xyu";
|
||||
char *saved_buf = buf;
|
||||
|
||||
/* Handle A, S, and P, before handling R */
|
||||
switch(desc.format & LH5801_IFMT_REG_MASK) {
|
||||
case LH5801_IFMT_AREG: return "a";
|
||||
case LH5801_IFMT_SREG: return "s";
|
||||
case LH5801_IFMT_PREG: return "p";
|
||||
}
|
||||
|
||||
if (regnr == 3)
|
||||
return "invalid";
|
||||
else switch (LH5801_IFMT_RMODE(desc.format)) {
|
||||
case LH5801_IFMT_RFULL:
|
||||
buf[0] = names[regnr];
|
||||
buf[1] = '\0';
|
||||
break;
|
||||
case LH5801_IFMT_RLOW:
|
||||
case LH5801_IFMT_RHIGH:
|
||||
buf[0] = names[regnr];
|
||||
buf[1] = (desc.format & LH5801_IFMT_RLOW)? 'l':'h';
|
||||
buf[2] = '\0';
|
||||
break;
|
||||
case LH5801_IFMT_RMEM:
|
||||
/* Note: LH5801_IFMT_FD_MOD is assumed here. */
|
||||
if (insn->fd)
|
||||
*(buf++) = '#';
|
||||
buf[0] = '(';
|
||||
buf[1] = names[regnr];
|
||||
buf[2] = ')';
|
||||
buf[3] = '\0';
|
||||
break;
|
||||
}
|
||||
return saved_buf;
|
||||
}
|
||||
|
||||
void lh5801_print_insn(char *out, size_t size, const struct lh5801_insn *insn)
|
||||
{
|
||||
const struct lh5801_insn_class_desc *iclass =
|
||||
&lh5801_insn_class_descs[insn->iclass];
|
||||
const struct lh5801_insn_desc desc = lh5801_insn_descs[insn->type];
|
||||
const char *mnem = iclass->mnem;
|
||||
char mnembuf[4];
|
||||
char regbuf[8];
|
||||
|
||||
/* Conditional instructions have special mnemonics. */
|
||||
if (desc.format & LH5801_IFMT_COND) {
|
||||
mnembuf[0] = mnem[0]; /* the first character is the same. */
|
||||
mnembuf[1] = "chzv"[(insn->opcode >> 2) % 4]; /* which flag */
|
||||
mnembuf[2] = (insn->opcode & 2)? 's':'r'; /* set or reset */
|
||||
mnembuf[3] = '\0';
|
||||
mnem = mnembuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* operand print modes:
|
||||
* IMM0: rl/rh, REG|LOW, REG|HIGH
|
||||
* r, REG
|
||||
* (r), REG|MEM -> would MEM imply FD_MOD?
|
||||
* s,p S, P
|
||||
* vej i VEJ
|
||||
* IMM1: IMM0,i IMM1
|
||||
* a,i ACCU
|
||||
* IMM2: ij (jump)
|
||||
* (ij)
|
||||
* s,ij (ldi)
|
||||
* IMM3: (ij),k
|
||||
*/
|
||||
|
||||
switch (desc.format & ~LH5801_IFMT_RMODE_MASK & ~LH5801_IFMT_COND
|
||||
& ~LH5801_IFMT_FD_MASK) {
|
||||
case LH5801_IFMT_VEJ:
|
||||
snprintf(out, size, "%s %02xh", mnem, insn->opcode);
|
||||
break;
|
||||
case LH5801_IFMT_IMM0:
|
||||
snprintf(out, size, "%s", mnem);
|
||||
break;
|
||||
case LH5801_IFMT_IMM0|LH5801_IFMT_RREG:
|
||||
case LH5801_IFMT_IMM0|LH5801_IFMT_AREG:
|
||||
case LH5801_IFMT_IMM0|LH5801_IFMT_SREG:
|
||||
case LH5801_IFMT_IMM0|LH5801_IFMT_PREG:
|
||||
strcpy(out, "yo");
|
||||
snprintf(out, size, "%s %s", mnem, print_reg(regbuf, insn));
|
||||
break;
|
||||
case LH5801_IFMT_IMM1:
|
||||
snprintf(out, size, "%s %02xh", mnem, insn->imm[0]);
|
||||
break;
|
||||
case LH5801_IFMT_IMM1|LH5801_IFMT_RREG:
|
||||
case LH5801_IFMT_IMM1|LH5801_IFMT_AREG:
|
||||
case LH5801_IFMT_IMM1|LH5801_IFMT_SREG:
|
||||
case LH5801_IFMT_IMM1|LH5801_IFMT_PREG:
|
||||
snprintf(out, size, "%s %s,%02xh", mnem,
|
||||
print_reg(regbuf, insn), insn->imm[0]);
|
||||
break;
|
||||
case LH5801_IFMT_IMM1|LH5801_IFMT_BCH:
|
||||
snprintf(out, size, "%s %c%02xh", mnem,
|
||||
(insn->opcode & 0x10)? '-':'+', insn->imm[0]);
|
||||
break;
|
||||
case LH5801_IFMT_IMM2: /* TODO: handle immediate memory access */
|
||||
snprintf(out, size, "%s %02x%02xh", mnem,
|
||||
insn->imm[0], insn->imm[1]);
|
||||
break;
|
||||
default:
|
||||
snprintf(out, size, "%s, BUG: unknown format 0x%x -> 0x%x",
|
||||
mnem, desc.format,
|
||||
desc.format & ~LH5801_IFMT_RMODE_MASK &
|
||||
~LH5801_IFMT_COND & ~LH5801_IFMT_FD_MASK);
|
||||
}
|
||||
}
|
112
libr/asm/arch/lh5801/lh5801.h
Normal file
112
libr/asm/arch/lh5801/lh5801.h
Normal file
@ -0,0 +1,112 @@
|
||||
/* SHARP LH 5801 disassembler -- instruction decoder,
|
||||
* Copyright (C) 2014 Jonathan Neuschäfer,
|
||||
* Released under the terms and conditions of the GNU LGPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This disassembler is based on the "SHARP PC-1500/A Systemhandbuch"
|
||||
* (system manual) as published by Günter Holtkötter GmbH.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
typedef uint8_t ut8;
|
||||
|
||||
/* Instruction classes. That's for example "add with carry". */
|
||||
enum lh5801_insn_class {
|
||||
LH5801_INSNC_ADC,
|
||||
LH5801_INSNC_ADI,
|
||||
LH5801_INSNC_DCA,
|
||||
LH5801_INSNC_ADR,
|
||||
LH5801_INSNC_SBC,
|
||||
LH5801_INSNC_SBI,
|
||||
LH5801_INSNC_DCS,
|
||||
LH5801_INSNC_AND,
|
||||
LH5801_INSNC_ANI,
|
||||
LH5801_INSNC_ORA,
|
||||
LH5801_INSNC_ORI,
|
||||
LH5801_INSNC_EOR,
|
||||
LH5801_INSNC_EAI,
|
||||
LH5801_INSNC_INC,
|
||||
LH5801_INSNC_DEC,
|
||||
LH5801_INSNC_CPA,
|
||||
LH5801_INSNC_CPI,
|
||||
LH5801_INSNC_BIT,
|
||||
LH5801_INSNC_BII,
|
||||
LH5801_INSNC_LDA,
|
||||
LH5801_INSNC_LDE,
|
||||
LH5801_INSNC_LIN,
|
||||
LH5801_INSNC_LDI,
|
||||
LH5801_INSNC_LDX,
|
||||
LH5801_INSNC_STA,
|
||||
LH5801_INSNC_SDE,
|
||||
LH5801_INSNC_SIN,
|
||||
LH5801_INSNC_STX,
|
||||
LH5801_INSNC_PSH,
|
||||
LH5801_INSNC_POP,
|
||||
LH5801_INSNC_ATT,
|
||||
LH5801_INSNC_TTA,
|
||||
LH5801_INSNC_TIN,
|
||||
LH5801_INSNC_CIN,
|
||||
LH5801_INSNC_ROL,
|
||||
LH5801_INSNC_ROR,
|
||||
LH5801_INSNC_SHL,
|
||||
LH5801_INSNC_SHR,
|
||||
LH5801_INSNC_DRL,
|
||||
LH5801_INSNC_DRR,
|
||||
LH5801_INSNC_AEX,
|
||||
LH5801_INSNC_SEC,
|
||||
LH5801_INSNC_REC,
|
||||
LH5801_INSNC_CDV,
|
||||
LH5801_INSNC_ATP,
|
||||
LH5801_INSNC_SPU,
|
||||
LH5801_INSNC_RPU,
|
||||
LH5801_INSNC_SPV,
|
||||
LH5801_INSNC_RPV,
|
||||
LH5801_INSNC_SDP,
|
||||
LH5801_INSNC_RDP,
|
||||
LH5801_INSNC_ITA,
|
||||
LH5801_INSNC_SIE,
|
||||
LH5801_INSNC_RIE,
|
||||
LH5801_INSNC_AM0,
|
||||
LH5801_INSNC_AM1,
|
||||
LH5801_INSNC_NOP,
|
||||
LH5801_INSNC_HLT,
|
||||
LH5801_INSNC_OFF,
|
||||
LH5801_INSNC_JMP,
|
||||
LH5801_INSNC_BCH,
|
||||
LH5801_INSNC_BCC,
|
||||
LH5801_INSNC_LOP,
|
||||
LH5801_INSNC_SJP,
|
||||
LH5801_INSNC_VEJ,
|
||||
LH5801_INSNC_VMJ,
|
||||
LH5801_INSNC_VCC,
|
||||
LH5801_INSNC_RTN,
|
||||
LH5801_INSNC_RTI,
|
||||
|
||||
LH5801_INSNC_NUMBER
|
||||
};
|
||||
|
||||
/* Instruction description. */
|
||||
struct lh5801_insn_class_desc {
|
||||
/* Assembler mnemonic and description (for ?d) */
|
||||
const char *mnem;
|
||||
const char *desc;
|
||||
|
||||
/* TODO: r2 insn type? */
|
||||
};
|
||||
|
||||
const struct lh5801_insn_class_desc
|
||||
lh5801_insn_class_descs[LH5801_INSNC_NUMBER];
|
||||
|
||||
/* A decoded instruction */
|
||||
struct lh5801_insn {
|
||||
ut8 iclass; /* an index into lh5801_insn_class_descs */
|
||||
ut8 type; /* an index into lh5801_insn_descs */
|
||||
ut8 fd;
|
||||
ut8 opcode;
|
||||
ut8 imm[3];
|
||||
};
|
||||
|
||||
ssize_t lh5801_decode(struct lh5801_insn *, const uint8_t *, size_t);
|
||||
void lh5801_print_insn(char *out, size_t size, const struct lh5801_insn *);
|
@ -18,6 +18,7 @@ ARCHS+=x86_as.mk x86_nz.mk cris_gnu.mk
|
||||
ARCHS+=ppc_gnu.mk ppc_cs.mk x86_olly.mk x86_udis.mk csr.mk x86_nasm.mk avr.mk
|
||||
ARCHS+=msil.mk sh.mk arm_winedbg.mk tms320.mk gb.mk snes.mk ebc.mk malbolge.mk ws.mk
|
||||
ARCHS+=6502.mk h8300.mk cr16.mk v850.mk spc700.mk propeller.mk msp430.mk i4004.mk z80_cr.mk
|
||||
ARCHS+=lh5801.mk
|
||||
include $(ARCHS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
44
libr/asm/p/asm_lh5801.c
Normal file
44
libr/asm/p/asm_lh5801.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* radare2, Sharp LH5801 disassembler.
|
||||
* (C) Copyright 2014-2015 jn, published under the LGPLv3 */
|
||||
|
||||
#include "../../arch/lh5801/lh5801.c"
|
||||
#include <r_asm.h>
|
||||
#include <r_types.h>
|
||||
|
||||
static int disassemble(RAsm *as, RAsmOp *op, const ut8 *buf, int len)
|
||||
{
|
||||
struct lh5801_insn insn;
|
||||
int consumed;
|
||||
|
||||
if (!op)
|
||||
return 0;
|
||||
|
||||
consumed = lh5801_decode (&insn, buf, len);
|
||||
if (consumed == -1 || consumed == 0) {
|
||||
snprintf(op->buf_asm, R_ASM_BUFSIZE, "invalid");
|
||||
op->size = 1;
|
||||
return 0;
|
||||
} else {
|
||||
lh5801_print_insn (op->buf_asm, R_ASM_BUFSIZE, &insn);
|
||||
op->size = consumed;
|
||||
//op->payload = lh5801_insn_descs[insn.type].format & 3;
|
||||
// ^ MAYBE?
|
||||
return op->size;
|
||||
}
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_lh5801 = {
|
||||
.name = "lh5801",
|
||||
.arch = "LH5801",
|
||||
.license = "LGPL3",
|
||||
.bits = 8,
|
||||
.desc = "SHARP LH5801 disassembler",
|
||||
.disassemble = &disassemble,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_ASM,
|
||||
.data = &r_asm_plugin_lh5801
|
||||
};
|
||||
#endif
|
9
libr/asm/p/lh5801.mk
Normal file
9
libr/asm/p/lh5801.mk
Normal file
@ -0,0 +1,9 @@
|
||||
OBJ_LH5801=asm_lh5801.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_LH5801}
|
||||
TARGET_LH5801=asm_lh5801.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_LH5801}
|
||||
|
||||
${TARGET_LH5801}: ${OBJ_LH5801}
|
||||
${CC} ${call libname,asm_lh5801} ${CFLAGS} -o ${TARGET_LH5801} ${OBJ_LH5801}
|
@ -210,6 +210,7 @@ extern RAsmPlugin r_asm_plugin_msp430;
|
||||
extern RAsmPlugin r_asm_plugin_i4004;
|
||||
extern RAsmPlugin r_asm_plugin_cris_gnu;
|
||||
extern RAsmPlugin r_asm_plugin_z80_cr;
|
||||
extern RAsmPlugin r_asm_plugin_lh5801;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
Loading…
Reference in New Issue
Block a user