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
120
121
122
123
124
125
126
127
128
129
130
|
// license:BSD-3-Clause
// copyright-holders:hap
/*
AMI S2000-family disassembler
*/
#include "emu.h"
#include "amis2000d.h"
// common lookup tables
enum amis2000_disassembler::e_mnemonics : unsigned
{
mLAB = 0, mLAE, mLAI, mLBE, mLBEP, mLBF, mLBZ, mXAB, mXABU, mXAE,
mLAM, mXC, mXCI, mXCD, mSTM, mRSM,
mADD, mADCS, mADIS, mAND, mXOR, mCMA, mSTC, mRSC, mSF1, mRF1, mSF2, mRF2,
mSAM, mSZM, mSBE, mSZC, mSOS, mSZK, mSZI, mTF1, mTF2,
mPP, mJMP, mJMS, mRT, mRTS, mNOP, mHALT,
mINP, mOUT, mDISB, mDISN, mMVS, mPSH, mPSL, mEUR
};
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, STEP_COND, STEP_COND, 0, 0,
0, STEP_COND, STEP_COND, 0, 0, 0, 0, 0, 0, 0, 0, 0,
STEP_COND, STEP_COND, STEP_COND, STEP_COND, STEP_COND, STEP_COND, STEP_COND, STEP_COND, STEP_COND,
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
};
// disasm
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, "%-6s", 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;
}
|