1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
// license:BSD-3-Clause
// copyright-holders:hap
/*
AMI S2000-family disassembler
*/
#include "emu.h"
#include "amis2000d.h"
const char *const amis2000_disassembler::s_mnemonics[] =
{
"LAB", "LAE", "LAI", "LBE", "LBEP", "LBF", "LBZ", "XAB", "XABU", "XAE",
"LAM", "XC", "XCI", "XCD", "STM", "RSM",
"ADD", "ADCS", "ADIS", "AND", "XOR", "CMA", "STC", "RSC", "SF1", "RF1", "SF2", "RF2",
"SAM", "SZM", "SBE", "SZC", "SOS", "SZK", "SZI", "TF1", "TF2",
"PP", "JMP", "JMS", "RT", "RTS", "NOP", "HALT",
"INP", "OUT", "DISB", "DISN", "MVS", "PSH", "PSL", "EUR"
};
// number of bits per opcode parameter, negative indicates complement
const s8 amis2000_disassembler::s_bits[] =
{
0, 0, 4, 2, 2, 2, 2, 0, 0, 0,
-2, -2, -2, -2, 2, 2,
0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 0, 0, 0, 0, 0, 0,
-4, 6, 6, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
const u32 amis2000_disassembler::s_flags[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, STEP_OVER, STEP_OUT, STEP_OUT, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
const u8 amis2000_disassembler::s2000_mnemonic[0x100] =
{
/* 0x00 */
mNOP, mHALT, mRT, mRTS, mPSH, mPSL, mAND, mSOS,
mSBE, mSZC, mSTC, mRSC, mLAE, mXAE, mINP, mEUR,
/* 0x10 */
mCMA, mXABU, mLAB, mXAB, mADCS, mXOR, mADD, mSAM,
mDISB, mMVS, mOUT, mDISN, mSZM, mSZM, mSZM, mSZM,
/* 0x20 */
mSTM, mSTM, mSTM, mSTM, mRSM, mRSM, mRSM, mRSM,
mSZK, mSZI, mRF1, mSF1, mRF2, mSF2, mTF1, mTF2,
mXCI, mXCI, mXCI, mXCI, mXCD, mXCD, mXCD, mXCD,
mXC, mXC, mXC, mXC, mLAM, mLAM, mLAM, mLAM,
/* 0x40 */
mLBZ, mLBZ, mLBZ, mLBZ, mLBF, mLBF, mLBF, mLBF,
mLBE, mLBE, mLBE, mLBE, mLBEP, mLBEP, mLBEP, mLBEP,
mADIS, mADIS, mADIS, mADIS, mADIS, mADIS, mADIS, mADIS,
mADIS, mADIS, mADIS, mADIS, mADIS, mADIS, mADIS, mADIS,
mPP, mPP, mPP, mPP, mPP, mPP, mPP, mPP,
mPP, mPP, mPP, mPP, mPP, mPP, mPP, mPP,
mLAI, mLAI, mLAI, mLAI, mLAI, mLAI, mLAI, mLAI,
mLAI, mLAI, mLAI, mLAI, mLAI, mLAI, mLAI, mLAI,
/* 0x80 */
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS, mJMS,
/* 0xc0 */
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP,
mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP, mJMP
};
offs_t amis2000_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms)
{
u8 op = opcodes.r8(pc);
u8 instr = s2000_mnemonic[op];
util::stream_format(stream, "%-5s ", s_mnemonics[instr]);
// opcode parameter
int mask = s_bits[instr];
bool complement = (mask < 0);
if (mask < 0)
mask = -mask;
mask = (1 << mask) - 1;
if (mask != 0)
{
u8 param = op;
if (complement)
param = ~param;
param &= mask;
if (mask < 0x10)
util::stream_format(stream, "%d", param);
else
util::stream_format(stream, "$%02X", param);
}
return 1 | s_flags[instr] | SUPPORTED;
}
u32 amis2000_disassembler::opcode_alignment() const
{
return 1;
}
|