Skip to content

Commit f677b99

Browse files
committed
Extend M680X support to RS08
1 parent 2db2061 commit f677b99

File tree

15 files changed

+724
-114
lines changed

15 files changed

+724
-114
lines changed

arch/M680X/M680XDisassembler.c

Lines changed: 96 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ typedef enum insn_hdlr_id {
7171
imm8i12x_hid,
7272
imm16i12x_hid,
7373
exti12x_hid,
74+
srt_hid,
75+
tny_hid,
76+
dirdir_hid,
77+
immdir_hid,
7478
HANDLER_ID_ENDING,
7579
} insn_hdlr_id;
7680

@@ -143,6 +147,7 @@ typedef struct insn_props {
143147
#include "hcs08.inc"
144148
#include "m6809.inc"
145149
#include "hd6309.inc"
150+
#include "rs08.inc"
146151

147152
#include "insn_props.inc"
148153

@@ -840,6 +845,8 @@ static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
840845
case opidxdr_hid:
841846
case idxX16_hid:
842847
case idxS16_hid:
848+
case dirdir_hid:
849+
case immdir_hid:
843850
if ((retval = read_byte(info, &ir, address + size + 1)))
844851
size += 2;
845852
break;
@@ -862,6 +869,8 @@ static bool is_sufficient_code_size(const m680x_info *info, uint16_t address,
862869
case idxX0_hid:
863870
case idxX0p_hid:
864871
case opidx_hid:
872+
case srt_hid:
873+
case tny_hid:
865874
retval = true;
866875
break;
867876

@@ -1820,6 +1829,42 @@ static void loop_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
18201829
add_insn_group(MI->flat_insn->detail, M680X_GRP_BRAREL);
18211830
}
18221831

1832+
// handler for RS08 specific TNY instruction
1833+
// The operand address is embedded in the the least 4 significant bits of the opcode
1834+
static void tny_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1835+
{
1836+
cs_m680x *m680x = &info->m680x;
1837+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1838+
1839+
op->type = M680X_OP_DIRECT;
1840+
op->direct_addr = (uint8_t)(MI->Opcode & 0x0F);
1841+
op->size = 1;
1842+
}
1843+
1844+
// handler for RS08 specific SRT instruction
1845+
// The operand address is embedded in the the least 5 significant bits of the opcode
1846+
static void srt_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1847+
{
1848+
cs_m680x *m680x = &info->m680x;
1849+
cs_m680x_op *op = &m680x->operands[m680x->op_count++];
1850+
1851+
op->type = M680X_OP_DIRECT;
1852+
op->direct_addr = (uint8_t)(MI->Opcode & 0x1F);
1853+
op->size = 1;
1854+
}
1855+
1856+
static void dirdir_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1857+
{
1858+
direct_hdlr(MI, info, address);
1859+
direct_hdlr(MI, info, address);
1860+
}
1861+
1862+
static void immdir_hdlr(MCInst *MI, m680x_info *info, uint16_t *address)
1863+
{
1864+
immediate_hdlr(MI, info, address);
1865+
direct_hdlr(MI, info, address);
1866+
}
1867+
18231868
static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
18241869
illegal_hdlr, relative8_hdlr, relative16_hdlr,
18251870
immediate_hdlr, // 8-bit
@@ -1832,7 +1877,8 @@ static void (*const g_insn_handler[])(MCInst *, m680x_info *, uint16_t *) = {
18321877
indexedS16_hdlr, indexedXp_hdlr, indexedX0p_hdlr, indexed12_hdlr,
18331878
indexed12_hdlr, // subset of indexed12
18341879
reg_reg12_hdlr, loop_hdlr, index_hdlr, imm_idx12_x_hdlr,
1835-
imm_idx12_x_hdlr, ext_idx12_x_hdlr,
1880+
imm_idx12_x_hdlr, ext_idx12_x_hdlr, srt_hdlr, tny_hdlr,
1881+
dirdir_hdlr, immdir_hdlr
18361882
}; /* handler function pointers */
18371883

18381884
/* Disasemble one instruction at address and store in str_buff */
@@ -1927,46 +1973,51 @@ static unsigned int m680x_disassemble(MCInst *MI, m680x_info *info,
19271973
}
19281974

19291975
// Tables to get the byte size of a register on the CPU
1930-
// based on an enum m680x_reg value.
1976+
// based on an enum m680x_reg value defined in m680x.h
19311977
// Invalid registers return 0.
1932-
static const uint8_t g_m6800_reg_byte_size[22] = {
1933-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1934-
0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1978+
static const uint8_t g_m6800_reg_byte_size[23] = {
1979+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
1980+
0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 0
19351981
};
19361982

1937-
static const uint8_t g_m6805_reg_byte_size[22] = {
1938-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1939-
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0
1983+
static const uint8_t g_m6805_reg_byte_size[23] = {
1984+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
1985+
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0
19401986
};
19411987

1942-
static const uint8_t g_m6808_reg_byte_size[22] = {
1943-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1944-
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0
1988+
static const uint8_t g_m6808_reg_byte_size[23] = {
1989+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
1990+
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 0, 0, 0
19451991
};
19461992

1947-
static const uint8_t g_m6801_reg_byte_size[22] = {
1948-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1949-
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0
1993+
static const uint8_t g_m6801_reg_byte_size[23] = {
1994+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
1995+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 2, 0, 0, 0
19501996
};
19511997

1952-
static const uint8_t g_m6811_reg_byte_size[22] = {
1953-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1954-
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0
1998+
static const uint8_t g_m6811_reg_byte_size[23] = {
1999+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
2000+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0
19552001
};
19562002

1957-
static const uint8_t g_cpu12_reg_byte_size[22] = {
1958-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1959-
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 2
2003+
static const uint8_t g_cpu12_reg_byte_size[23] = {
2004+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
2005+
0, 1, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 2, 2
19602006
};
19612007

1962-
static const uint8_t g_m6809_reg_byte_size[22] = {
1963-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1964-
0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0
2008+
static const uint8_t g_m6809_reg_byte_size[23] = {
2009+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
2010+
0, 1, 1, 0, 0, 0, 2, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0, 0
19652011
};
19662012

1967-
static const uint8_t g_hd6309_reg_byte_size[22] = {
1968-
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC T2 T3
1969-
0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0
2013+
static const uint8_t g_hd6309_reg_byte_size[23] = {
2014+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
2015+
0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 4, 2, 0, 0, 0
2016+
};
2017+
2018+
static const uint8_t g_rs08_reg_byte_size[23] = {
2019+
// A B E F 0 D W CC DP MD HX H X Y S U V Q PC SPC T2 T3
2020+
0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 2, 0, 0, 0, 2, 2, 0, 0
19702021
};
19712022

19722023
// Table to check for a valid register nibble on the M6809 CPU
@@ -2096,6 +2147,16 @@ static const cpu_tables g_cpu_tables[] = {
20962147
&g_m6808_reg_byte_size[0],
20972148
NULL,
20982149
{ M680X_INS_BCLR, M680X_INS_BSET } },
2150+
{ // M680X_CPU_TYPE_RS08
2151+
&g_rs08_inst_page1_table[0],
2152+
{ NULL, NULL },
2153+
{ 0, 0 },
2154+
{ 0x00, 0x00, 0x00 },
2155+
{ NULL, NULL, NULL },
2156+
{ 0, 0, 0 },
2157+
&g_rs08_reg_byte_size[0],
2158+
NULL,
2159+
{ M680X_INS_INVLD, M680X_INS_INVLD } },
20992160
};
21002161

21012162
static bool m680x_setup_internals(m680x_info *info, e_cpu_type cpu_type,
@@ -2157,6 +2218,9 @@ bool M680X_getInstruction(csh ud, const uint8_t *code, size_t code_len,
21572218
else if (handle->mode & CS_MODE_M680X_CPU12)
21582219
cpu_type = M680X_CPU_TYPE_CPU12;
21592220

2221+
else if (handle->mode & CS_MODE_M680X_RS08)
2222+
cpu_type = M680X_CPU_TYPE_RS08;
2223+
21602224
if (cpu_type != M680X_CPU_TYPE_INVALID &&
21612225
m680x_setup_internals(info, cpu_type, (uint16_t)address, code,
21622226
(uint16_t)code_len))
@@ -2221,6 +2285,12 @@ cs_err M680X_disassembler_init(cs_struct *ud)
22212285
return CS_ERR_MODE;
22222286
}
22232287

2288+
if (M680X_REG_ENDING != ARR_SIZE(g_rs08_reg_byte_size)) {
2289+
CS_ASSERT(M680X_REG_ENDING == ARR_SIZE(g_rs08_reg_byte_size));
2290+
2291+
return CS_ERR_MODE;
2292+
}
2293+
22242294
if (M680X_INS_ENDING != ARR_SIZE(g_insn_props)) {
22252295
CS_ASSERT(M680X_INS_ENDING == ARR_SIZE(g_insn_props));
22262296

arch/M680X/M680XDisassemblerInternals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef enum e_cpu_type {
2020
M680X_CPU_TYPE_CPU12, // M680X Motorola/Freescale CPU12 mode
2121
// used on M68HC12/HCS12
2222
M680X_CPU_TYPE_HCS08, // M680X Freescale HCS08 mode
23+
M680X_CPU_TYPE_RS08, // M680X Freescale RSS08 mode
2324
M680X_CPU_TYPE_ENDING,
2425
} e_cpu_type;
2526

arch/M680X/M680XInstPrinter.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020

2121
#ifndef CAPSTONE_DIET
2222
static const char s_reg_names[][10] = {
23-
"<invalid>", "a", "b", "e", "f", "0", "d", "w", "cc", "dp", "md",
24-
"hx", "h", "x", "y", "s", "u", "v", "q", "pc", "tmp2", "tmp3",
23+
"<invalid>", "a", "b", "e", "f", "0", "d", "w",
24+
"cc", "dp", "md", "hx", "h", "x", "y", "s",
25+
"u", "v", "q", "pc", "spc", "tmp2", "tmp3",
2526
};
2627

2728
static const char s_instruction_names[][6] = {
@@ -62,14 +63,14 @@ static const char s_instruction_names[][6] = {
6263
"rolb", "rold", "rolw", "rolx", "ror", "rora", "rorb", "rord",
6364
"rorw", "rorx", "rsp", "rtc", "rti", "rts", "sba", "sbc",
6465
"sbca", "sbcb", "sbcd", "sbcr", "sec", "sei", "sev", "sex",
65-
"sexw", "slp", "sta", "staa", "stab", "stb", "stbt", "std",
66-
"ste", "stf", "stop", "sthx", "stq", "sts", "stu", "stw",
67-
"stx", "sty", "sub", "suba", "subb", "subd", "sube", "subf",
68-
"subr", "subw", "swi", "swi2", "swi3", "sync", "tab", "tap",
69-
"tax", "tba", "tbeq", "tbl", "tbne", "test", "tfm", "tfr",
70-
"tim", "tpa", "tst", "tsta", "tstb", "tstd", "tste", "tstf",
71-
"tstw", "tstx", "tsx", "tsy", "txa", "txs", "tys", "wai",
72-
"wait", "wav", "wavr", "xgdx", "xgdy",
66+
"sexw", "sha", "sla", "slp", "sta", "staa", "stab", "stb",
67+
"stbt", "std", "ste", "stf", "stop", "sthx", "stq", "sts",
68+
"stu", "stw", "stx", "sty", "sub", "suba", "subb", "subd",
69+
"sube", "subf", "subr", "subw", "swi", "swi2", "swi3", "sync",
70+
"tab", "tap", "tax", "tba", "tbeq", "tbl", "tbne", "test",
71+
"tfm", "tfr", "tim", "tpa", "tst", "tsta", "tstb", "tstd",
72+
"tste", "tstf", "tstw", "tstx", "tsx", "tsy", "txa", "txs",
73+
"tys", "wai", "wait", "wav", "wavr", "xgdx", "xgdy",
7374
};
7475

7576
static const name_map s_group_names[] = {

arch/M680X/M680XModule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ cs_err M680X_global_init(cs_struct *ud)
3131
~(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 | CS_MODE_M680X_6805 |
3232
CS_MODE_M680X_6808 | CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
3333
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 | CS_MODE_M680X_CPU12 |
34-
CS_MODE_M680X_HCS08)) {
34+
CS_MODE_M680X_HCS08 | CS_MODE_M680X_RS08)) {
3535
// At least one mode is not supported by M680X
3636
return CS_ERR_MODE;
3737
}
@@ -40,7 +40,7 @@ cs_err M680X_global_init(cs_struct *ud)
4040
(CS_MODE_M680X_6800 | CS_MODE_M680X_6801 | CS_MODE_M680X_6805 |
4141
CS_MODE_M680X_6808 | CS_MODE_M680X_6809 | CS_MODE_M680X_6811 |
4242
CS_MODE_M680X_6301 | CS_MODE_M680X_6309 | CS_MODE_M680X_CPU12 |
43-
CS_MODE_M680X_HCS08))) {
43+
CS_MODE_M680X_HCS08 | CS_MODE_M680X_RS08))) {
4444
// At least the cpu type has to be selected. No default.
4545
return CS_ERR_MODE;
4646
}

arch/M680X/insn_props.inc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ static const insn_props g_insn_props[] = {
301301
{ NOG, uuuu, NOR, NOR, true, false }, // SEV
302302
{ NOG, wrrr, NOR, NOR, true, true }, // SEX
303303
{ NOG, rwww, M680X_REG_W, NOR, true, true }, // SEXW
304+
{ NOG, rwww, M680X_REG_SPC, M680X_REG_A, false, false }, // SHA
305+
{ NOG, rwww, M680X_REG_SPC, M680X_REG_A, false, false }, // SLA
304306
{ NOG, uuuu, NOR, NOR, false, false }, // SLP
305307
{ NOG, rwww, M680X_REG_A, NOR, true, false }, // STA
306308
{ NOG, rwww, M680X_REG_A, NOR, true, false }, // STAA

0 commit comments

Comments
 (0)