mirror of
https://github.com/emu-russia/pureikyubu.git
synced 2025-04-02 10:42:15 -04:00
194 lines
2.8 KiB
C++
194 lines
2.8 KiB
C++
// Matsushita MN102 instruction analyzer.
|
|
|
|
#pragma once
|
|
|
|
namespace DVD
|
|
{
|
|
|
|
enum class MnInstruction
|
|
{
|
|
Unknown = 0,
|
|
|
|
MOV,
|
|
MOVX,
|
|
MOVB,
|
|
MOVBU,
|
|
EXT,
|
|
EXTX,
|
|
EXTXU,
|
|
EXTXB,
|
|
EXTXBU,
|
|
ADD,
|
|
ADDC,
|
|
ADDNF,
|
|
SUB,
|
|
SUBC,
|
|
MUL,
|
|
MULU,
|
|
DIVU,
|
|
CMP,
|
|
AND,
|
|
OR,
|
|
XOR,
|
|
NOT,
|
|
ASR,
|
|
LSR,
|
|
ROR,
|
|
ROL,
|
|
BTST,
|
|
BSET,
|
|
BCLR,
|
|
Bcc,
|
|
BccX,
|
|
JMP,
|
|
JSR,
|
|
NOP,
|
|
RTS,
|
|
RTI
|
|
};
|
|
|
|
enum class MnOperand
|
|
{
|
|
Unknown = 0,
|
|
|
|
// Registers
|
|
D0,
|
|
D1,
|
|
D2,
|
|
D3,
|
|
A0,
|
|
A1,
|
|
A2,
|
|
A3,
|
|
|
|
// Immediate
|
|
Imm8,
|
|
Imm16,
|
|
Imm24,
|
|
|
|
// Register indirect
|
|
Ind_A0,
|
|
Ind_A1,
|
|
Ind_A2,
|
|
Ind_A3,
|
|
|
|
// Register relative indirect
|
|
D8_A0,
|
|
D8_A1,
|
|
D8_A2,
|
|
D8_A3,
|
|
D16_A0,
|
|
D16_A1,
|
|
D16_A2,
|
|
D16_A3,
|
|
D24_A0,
|
|
D24_A1,
|
|
D24_A2,
|
|
D24_A3,
|
|
D8_PC,
|
|
D16_PC,
|
|
D24_PC,
|
|
|
|
// Absolute
|
|
Abs16,
|
|
Abs24,
|
|
|
|
// Indirect Register
|
|
Ind_D0_A0,
|
|
Ind_D0_A1,
|
|
Ind_D0_A2,
|
|
Ind_D0_A3,
|
|
Ind_D1_A0,
|
|
Ind_D1_A1,
|
|
Ind_D1_A2,
|
|
Ind_D1_A3,
|
|
Ind_D2_A0,
|
|
Ind_D2_A1,
|
|
Ind_D2_A2,
|
|
Ind_D2_A3,
|
|
Ind_D3_A0,
|
|
Ind_D3_A1,
|
|
Ind_D3_A2,
|
|
Ind_D3_A3,
|
|
|
|
MDR,
|
|
PSW,
|
|
|
|
};
|
|
|
|
// Condition code for branch instructions
|
|
enum class MnCond
|
|
{
|
|
Unknown = -1,
|
|
|
|
LT = 0,
|
|
GT = 1,
|
|
GE = 2,
|
|
LE = 3,
|
|
CS = 4,
|
|
HI = 5,
|
|
CC = 6,
|
|
LS = 7,
|
|
EQ = 8,
|
|
NE = 9,
|
|
RA = 0xa,
|
|
|
|
VC = 0xc,
|
|
VS = 0xd,
|
|
NC = 0xe,
|
|
NS = 0xf,
|
|
};
|
|
|
|
union MnInstrImmed
|
|
{
|
|
uint8_t Uint8;
|
|
uint16_t Uint16;
|
|
uint32_t Uint24;
|
|
};
|
|
|
|
#define MnInstrInfoOperands 2
|
|
|
|
struct MnInstrInfo
|
|
{
|
|
size_t instrSize; // In bytes
|
|
uint8_t instrBytes[5]; // Saved instruction bytes
|
|
|
|
MnInstruction instr;
|
|
|
|
size_t numOp;
|
|
MnOperand op[MnInstrInfoOperands];
|
|
int opBits[MnInstrInfoOperands]; // If one of the operands is in the form (Di, An), then Di and An saved as one
|
|
|
|
MnInstrImmed imm;
|
|
|
|
bool flow; // Kind of branch (can break instruction flow)
|
|
|
|
MnCond cc; // Condition code for branches
|
|
|
|
};
|
|
|
|
class MnAnalyze
|
|
{
|
|
uint8_t* instrPtr = nullptr; // Temporary pointer
|
|
|
|
bool Main(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F0(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F1(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F2(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F3(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F4(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F5(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool F7(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
|
|
bool FetchImm8(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool FetchImm16(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
bool FetchImm24(uint8_t* instrPtr, size_t instrMaxSize, MnInstrInfo* info);
|
|
|
|
bool AddOp(MnInstrInfo* info, MnOperand op, int bits);
|
|
|
|
public:
|
|
|
|
bool Analyze(uint8_t * instrPtr, size_t instrMaxSize, MnInstrInfo * info);
|
|
|
|
};
|
|
}
|