summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2025-03-29 04:53:34 +1100
committer Vas Crabb <vas@vastheman.com>2025-03-29 04:56:48 +1100
commit40a0638ba76b91b0b213788ed5a6b259fa5b84a5 (patch)
tree22a38fdebcfafa96a6165e1a346ecaaf4bd52d29 /src/devices/cpu
parent345ab51e9dfc6c4a13a27a453da896873eab6de0 (diff)
-cpu/e132xs: General cleanup and usability improvements:
* Aligned the operand field in disassembly. * Calculate results of immediate values against the PC to make position-independent code easier to read without constantly using a calculator (e.g. this shows destinations for call Rd, PC, imm). * Added more symbols to the UML helper to make logged generated code more readable. * Made single-instruction-per-sequence mode configurable rather than a compile-time option. * Got rid of a criminal amount of copy/paste in the disassembler, and got rid of all the deprecated strcpy calls. * Got rid of some duplicated constants, changed some constants from macros to enumerated values or constexpr globals. * Reduced the amound of stuff in headers that doesn't need to be there. -cpu/drcbex64.cpp: Don't construct std::function objects during code generation - they require allocation. -eolith/eolith.cpp: Turned single-instruction-per-sequence mode on for now until someone works out why turning it off causes Raccoon World to generate so much code it's unplayably slow.
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/drcbex64.cpp29
-rw-r--r--src/devices/cpu/e132xs/32xsdasm.cpp1548
-rw-r--r--src/devices/cpu/e132xs/32xsdasm.h19
-rw-r--r--src/devices/cpu/e132xs/32xsdefs.h98
-rw-r--r--src/devices/cpu/e132xs/e132xs.cpp18
-rw-r--r--src/devices/cpu/e132xs/e132xs.h50
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc.cpp7
-rw-r--r--src/devices/cpu/e132xs/e132xsdrc_ops.hxx18
-rw-r--r--src/devices/cpu/e132xs/e132xsfe.cpp4
9 files changed, 460 insertions, 1331 deletions
diff --git a/src/devices/cpu/drcbex64.cpp b/src/devices/cpu/drcbex64.cpp
index 776bd17e29c..45d442e8576 100644
--- a/src/devices/cpu/drcbex64.cpp
+++ b/src/devices/cpu/drcbex64.cpp
@@ -594,7 +594,9 @@ private:
// alu and shift operation helpers
static bool ones(u64 const value, unsigned const size) noexcept { return (size == 4) ? u32(value) == 0xffffffffU : value == 0xffffffff'ffffffffULL; }
- void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const &param, std::function<bool(asmjit::x86::Assembler &a, asmjit::Operand const &dst, be_parameter const &src)> optimize = [](asmjit::x86::Assembler &a, asmjit::Operand dst, be_parameter const &src) { return false; });
+ template <typename T>
+ void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const &param, T &&optimize);
+ void alu_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, asmjit::Operand const &dst, be_parameter const &param) { alu_op_param(a, opcode, dst, param, [] (asmjit::x86::Assembler &a, asmjit::Operand dst, be_parameter const &src) { return false; }); }
void shift_op_param(asmjit::x86::Assembler &a, asmjit::x86::Inst::Id const opcode, size_t opsize, asmjit::Operand const &dst, be_parameter const &param, u8 update_flags);
// parameter helpers
@@ -1401,7 +1403,8 @@ void drcbe_x64::get_info(drcbe_info &info) const noexcept
break;
}
-void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const &dst, be_parameter const &param, std::function<bool(Assembler &a, Operand const &dst, be_parameter const &src)> optimize)
+template <typename T>
+void drcbe_x64::alu_op_param(Assembler &a, Inst::Id const opcode, Operand const &dst, be_parameter const &param, T &&optimize)
{
bool const is64 = dst.x86RmSize() == 8;
@@ -3945,7 +3948,7 @@ void drcbe_x64::op_roland(Assembler &a, const instruction &inst)
a.rol(dstreg, cl);
}
alu_op_param(a, Inst::kIdAnd, dstreg, maskp,
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// all-one cases
if (ones(src.immediate(), inst.size()))
@@ -4277,7 +4280,7 @@ void drcbe_x64::op_add(Assembler &a, const instruction &inst)
{
// dstp == src1p in memory
alu_op_param(a, Inst::kIdAdd, MABS(dstp.memory(), inst.size()), src2p, // add [dstp],src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize zero case
return (!inst.flags() && !src.immediate());
@@ -4309,7 +4312,7 @@ void drcbe_x64::op_add(Assembler &a, const instruction &inst)
mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p
alu_op_param(a, Inst::kIdAdd, dstreg, src2p, // add dstreg,src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize zero case
return (!inst.flags() && !src.immediate() && (inst.size() != 4));
@@ -4375,7 +4378,7 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst)
{
// dstp == src1p in memory
alu_op_param(a, Inst::kIdSub, MABS(dstp.memory(), inst.size()), src2p, // sub [dstp],src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize zero case
return (!inst.flags() && !src.immediate());
@@ -4398,7 +4401,7 @@ void drcbe_x64::op_sub(Assembler &a, const instruction &inst)
mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p
alu_op_param(a, Inst::kIdSub, dstreg, src2p, // sub dstreg,src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize zero case
return (!inst.flags() && !src.immediate() && (inst.size() != 4));
@@ -5006,7 +5009,7 @@ void drcbe_x64::op_test(Assembler &a, const instruction &inst)
mov_reg_param(a, src1reg, src1p);
alu_op_param(a, Inst::kIdTest, src1reg, src2p,
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-one cases
if (ones(src.immediate(), inst.size()))
@@ -5042,7 +5045,7 @@ void drcbe_x64::op_or(Assembler &a, const instruction &inst)
{
// dstp == src1p in memory
alu_op_param(a, Inst::kIdOr, MABS(dstp.memory(), inst.size()), src2p, // or [dstp],src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-zero and all-one cases
if (!inst.flags() && ones(src.immediate(), inst.size()))
@@ -5066,7 +5069,7 @@ void drcbe_x64::op_or(Assembler &a, const instruction &inst)
mov_reg_param(a, dstreg, src1p); // mov dstreg,src1p
alu_op_param(a, Inst::kIdOr, dstreg, src2p, // or dstreg,src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-zero and all-one cases
if (!inst.flags() && ones(src.immediate(), inst.size()))
@@ -5120,7 +5123,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst)
{
// dstp == src1p in memory
alu_op_param(a, Inst::kIdXor, MABS(dstp.memory(), inst.size()), src2p, // xor [dstp],src2p
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-zero and all-one cases
if (!inst.flags() && ones(src.immediate(), inst.size()))
@@ -5140,7 +5143,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst)
Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg());
alu_op_param(a, Inst::kIdXor, dst, src2p,
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-zero and all-one cases
if (!inst.flags() && ones(src.immediate(), inst.size()))
@@ -5173,7 +5176,7 @@ void drcbe_x64::op_xor(Assembler &a, const instruction &inst)
mov_reg_param(a, dstreg, src1p);
alu_op_param(a, Inst::kIdXor, dstreg, src2p,
- [inst](Assembler &a, Operand const &dst, be_parameter const &src)
+ [inst] (Assembler &a, Operand const &dst, be_parameter const &src)
{
// optimize all-zero and all-one cases
if (!inst.flags() && ones(src.immediate(), inst.size()))
diff --git a/src/devices/cpu/e132xs/32xsdasm.cpp b/src/devices/cpu/e132xs/32xsdasm.cpp
index 71fc4ce4c40..1c19d4110ba 100644
--- a/src/devices/cpu/e132xs/32xsdasm.cpp
+++ b/src/devices/cpu/e132xs/32xsdasm.cpp
@@ -36,6 +36,24 @@ const char *const SETxx[] =
"SETSEM", "SETTHM", "SETSTM", "SETHEM", "SETEM", "SETNEM", "SETVM", "SETNVM"
};
+const char *const Fxxx[] =
+{
+ "FADD", "FADDD", "FSUB", "FSUBD" "FMUL", "FMULD", "FDIV", "FDIVD",
+ "FCMP", "FCMPD", "FCMPU", "FCMPUD", "FCVT", "FCVTD"
+};
+
+const char *const Bxx[] =
+{
+ "BV", "BNV", "BE", "BNE", "BC", "BNC", "BSE", "BHT",
+ "BN", "BNN", "BLE", "BGT", "BR"
+};
+
+const char *const TRAPxx[] =
+{
+ nullptr, nullptr, nullptr, nullptr, "TRAPLE", "TRAPGT", "TRAPLT", "TRAPGE",
+ "TRAPSE", "TRAPHT", "TRAPST", "TRAPHE", "TRAPE", "TRAPNE", "TRAPV", "TRAP"
+};
+
#define DESTCODE(op) ((op & 0x00f0) >> 4)
#define SOURCECODE(op) (op & 0x000f)
@@ -44,64 +62,90 @@ const char *const SETxx[] =
#define DASM_N_VALUE(op) ((((op & 0x100) >> 8) << 4 ) | (op & 0x0f))
-} // anonymous namespace
-
-void hyperstone_disassembler::LL_format(char *source, char *dest, uint16_t op)
+void LL_format(std::string_view &source, std::string_view &dest, uint16_t op)
{
- strcpy(source, L_REG[SOURCECODE(op)]);
- strcpy(dest, L_REG[DESTCODE(op)]);
+ source = L_REG[SOURCECODE(op)];
+ dest = L_REG[DESTCODE(op)];
}
-void hyperstone_disassembler::LR_format(char *source, char *dest, uint16_t op)
+void LR_format(std::string_view &source, std::string_view &dest, uint16_t op)
{
if (SOURCEBIT(op))
- strcpy(source, L_REG[SOURCECODE(op)]);
+ source = L_REG[SOURCECODE(op)];
else
- strcpy(source, G_REG[SOURCECODE(op)]);
+ source = G_REG[SOURCECODE(op)];
- strcpy(dest, L_REG[DESTCODE(op)]);
+ dest = L_REG[DESTCODE(op)];
}
-void hyperstone_disassembler::RR_format(char *source, char *dest, uint16_t op, unsigned h_flag)
+void RR_format(std::string_view &source, std::string_view &dest, uint16_t op, unsigned h_flag)
{
if (SOURCEBIT(op))
- strcpy(source, L_REG[SOURCECODE(op)]);
+ source = L_REG[SOURCECODE(op)];
else
- strcpy(source, G_REG[SOURCECODE(op) + h_flag * 16]);
+ source = G_REG[SOURCECODE(op) + h_flag * 16];
if (DESTBIT(op))
- {
- strcpy(dest, L_REG[DESTCODE(op)]);
- }
+ dest = L_REG[DESTCODE(op)];
else
- {
- strcpy(dest, G_REG[DESTCODE(op) + h_flag * 16]);
- }
+ dest = G_REG[DESTCODE(op) + h_flag * 16];
+}
+
+uint8_t Ln_format(std::string_view &dest, uint16_t op)
+{
+ dest = L_REG[DESTCODE(op)];
+
+ return DASM_N_VALUE(op);
+}
+
+uint8_t Rn_format(std::string_view &dest, uint16_t op)
+{
+ if (DESTBIT(op))
+ dest = L_REG[DESTCODE(op)];
+ else
+ dest = G_REG[DESTCODE(op)];
+
+ return DASM_N_VALUE(op);
}
-uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes)
+
+void format_addsub(
+ std::ostream &stream,
+ std::string_view inst,
+ std::string_view dest,
+ std::string_view source,
+ uint8_t source_bit,
+ uint8_t source_code)
+{
+ util::stream_format(stream, "%-7s %s, %s",
+ inst,
+ dest,
+ (!source_bit && (source_code == SR_REGISTER)) ? "C" : source);
+}
+
+} // anonymous namespace
+
+
+
+uint32_t hyperstone_disassembler::LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes)
{
uint16_t next_op;
uint32_t const_val;
if (SOURCEBIT(op))
- {
- strcpy(source, L_REG[SOURCECODE(op)]);
- }
+ source = L_REG[SOURCECODE(op)];
else
- {
- strcpy(source, G_REG[SOURCECODE(op)]);
- }
+ source = G_REG[SOURCECODE(op)];
- strcpy(dest, L_REG[DESTCODE(op)]);
+ dest = L_REG[DESTCODE(op)];
size = 4;
pc += 2;
next_op = opcodes.r16(pc);
- if( E_BIT(next_op) )
+ if (E_BIT(next_op))
{
uint16_t next_op2;
@@ -112,53 +156,41 @@ uint32_t hyperstone_disassembler::LRconst_format(char *source, char *dest, uint1
const_val = next_op2;
const_val |= ((next_op & 0x3fff) << 16 );
- if( S_BIT_CONST(next_op) )
- {
+ if (S_BIT_CONST(next_op))
const_val |= 0xc0000000;
- }
}
else
{
const_val = next_op & 0x3fff;
- if( S_BIT_CONST(next_op) )
- {
+ if (S_BIT_CONST(next_op))
const_val |= 0xffffc000;
- }
}
return const_val;
}
-uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes)
+uint32_t hyperstone_disassembler::RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes)
{
uint16_t next_op;
uint32_t const_val;
- if( SOURCEBIT(op) )
- {
- strcpy(source, L_REG[SOURCECODE(op)]);
- }
+ if (SOURCEBIT(op))
+ source = L_REG[SOURCECODE(op)];
else
- {
- strcpy(source, G_REG[SOURCECODE(op)]);
- }
+ source = G_REG[SOURCECODE(op)];
- if( DESTBIT(op) )
- {
- strcpy(dest, L_REG[DESTCODE(op)]);
- }
+ if (DESTBIT(op))
+ dest = L_REG[DESTCODE(op)];
else
- {
- strcpy(dest, G_REG[DESTCODE(op)]);
- }
+ dest = G_REG[DESTCODE(op)];
size = 4;
pc += 2;
next_op = opcodes.r16(pc);
- if( E_BIT(next_op) )
+ if (E_BIT(next_op))
{
uint16_t next_op2;
@@ -169,7 +201,7 @@ uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint1
const_val = next_op2;
const_val |= ((next_op & 0x3fff) << 16 );
- if( S_BIT_CONST(next_op) )
+ if (S_BIT_CONST(next_op))
{
const_val |= 0xc0000000;
}
@@ -178,16 +210,14 @@ uint32_t hyperstone_disassembler::RRconst_format(char *source, char *dest, uint1
{
const_val = next_op & 0x3fff;
- if( S_BIT_CONST(next_op) )
- {
+ if (S_BIT_CONST(next_op))
const_val |= 0xffffc000;
- }
}
return const_val;
}
-int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag)
+int32_t hyperstone_disassembler::Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag)
{
uint16_t imm1, imm2;
int32_t ret;
@@ -195,9 +225,9 @@ int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc
int n = DASM_N_VALUE(op);
if (DESTBIT(op))
- strcpy(dest, L_REG[DESTCODE(op)]);
+ dest = L_REG[DESTCODE(op)];
else
- strcpy(dest, G_REG[DESTCODE(op) + h_flag * 16]);
+ dest = G_REG[DESTCODE(op) + h_flag * 16];
switch (n)
{
@@ -271,27 +301,6 @@ int32_t hyperstone_disassembler::Rimm_format(char *dest, uint16_t op, offs_t &pc
}
}
-uint8_t hyperstone_disassembler::Ln_format(char *dest, uint16_t op)
-{
- strcpy(dest, L_REG[DESTCODE(op)]);
-
- return DASM_N_VALUE(op);
-}
-
-uint8_t hyperstone_disassembler::Rn_format(char *dest, uint16_t op)
-{
- if( DESTBIT(op) )
- {
- strcpy(dest, L_REG[DESTCODE(op)]);
- }
- else
- {
- strcpy(dest, G_REG[DESTCODE(op)]);
- }
-
- return DASM_N_VALUE(op);
-}
-
int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes)
{
int32_t ret;
@@ -324,29 +333,21 @@ int32_t hyperstone_disassembler::PCrel_format(uint16_t op, offs_t pc, const data
return (pc + ret);
}
-uint32_t hyperstone_disassembler::RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes)
+uint32_t hyperstone_disassembler::RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes)
{
uint32_t ret;
- if( SOURCEBIT(op) )
- {
- strcpy(source, L_REG[SOURCECODE(op)]);
- }
+ if (SOURCEBIT(op))
+ source = L_REG[SOURCECODE(op)];
else
- {
- strcpy(source, G_REG[SOURCECODE(op)]);
- }
+ source = G_REG[SOURCECODE(op)];
- if( DESTBIT(op) )
- {
- strcpy(dest, L_REG[DESTCODE(op)]);
- }
+ if (DESTBIT(op))
+ dest = L_REG[DESTCODE(op)];
else
- {
- strcpy(dest, G_REG[DESTCODE(op)]);
- }
+ dest = G_REG[DESTCODE(op)];
- if( E_BIT(next_op) )
+ if (E_BIT(next_op))
{
uint16_t next;
@@ -388,7 +389,7 @@ hyperstone_disassembler::hyperstone_disassembler(config *conf) : m_config(conf)
/*****************************/
offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer &params)
{
- char source[5] = "\0", dest[5] = "\0";
+ std::string_view source, dest;
uint32_t flags = 0;
uint16_t op = opcodes.r16(pc);
@@ -419,11 +420,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
if( !source_bit && source_code == SR_REGISTER )
{
- util::stream_format(stream, "CHKZ %s, 0", dest);
+ util::stream_format(stream, "CHKZ %s, 0", dest);
}
else
{
- util::stream_format(stream, "CHK %s, %s", dest, source);
+ util::stream_format(stream, "CHK %s, %s", dest, source);
}
}
@@ -437,41 +438,33 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
if( dest_code == PC_REGISTER && !dest_bit )
{
RR_format(source, dest, op, 0);
- util::stream_format(stream, "RET PC, %s", source);
+ util::stream_format(stream, "RET PC, %s", source);
flags = STEP_OUT;
}
else if( source_code == SR_REGISTER && !source_bit )
{
- util::stream_format(stream, "MOVD %s, 0", dest);
+ util::stream_format(stream, "MOVD %s, 0", dest);
}
else
{
- util::stream_format(stream, "MOVD %s, %s", dest, source);
+ util::stream_format(stream, "MOVD %s, %s", dest, source);
}
break;
// DIVU
- case 0x08: case 0x09: case 0x0a: case 0x0b:
-
- RR_format(source, dest, op, 0);
- util::stream_format(stream, "DIVU %s, %s", dest, source);
-
- break;
-
// DIVS
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "DIVS %s, %s", dest, source);
+ util::stream_format(stream, "DIV%c %s, %s", (op_num & 0x4) ? 'S' : 'U', dest, source);
break;
// XMx - XXx
case 0x10: case 0x11: case 0x12: case 0x13:
{
- int xcode;
-
RR_format(source, dest, op, 0);
size = 4;
@@ -479,7 +472,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
pc += 2;
op = opcodes.r16(pc);
- xcode = X_CODE(op);
+ const int xcode = X_CODE(op);
if( xcode < 4 )
{
@@ -501,12 +494,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
lim = op & 0xfff;
}
- util::stream_format(stream, "XM%x %s, %s, $%x", (uint8_t)(float) pow(2.0, xcode), dest, source, lim);
-
+ util::stream_format(stream, "XM%x %s, %s, $%x", 1 << xcode, dest, source, lim);
}
else
{
- util::stream_format(stream, "XX%x %s, %s, 0", (uint8_t)(float) pow(2.0, (xcode - 4)), dest, source);
+ util::stream_format(stream, "XX%x %s, %s, 0", 1 << (xcode - 4), dest, source);
}
break;
@@ -516,42 +508,26 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x14: case 0x15: case 0x16: case 0x17:
{
uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes);
-
- util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val);
+ util::stream_format(stream, "MASK %s, %s, $%x", dest, source, const_val);
+ if (!source_bit && (source_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t((pc + size) & const_val));
break;
}
// SUM
- case 0x18: case 0x19: case 0x1a: case 0x1b:
- {
- uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "SUM %s, C, $%x", dest, const_val);
- }
- else
- {
- util::stream_format(stream, "SUM %s, %s, $%x", dest, source, const_val);
- }
-
- break;
- }
-
// SUMS
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
case 0x1c: case 0x1d: case 0x1e: case 0x1f:
{
uint32_t const_val = RRconst_format(source, dest, op, pc, opcodes);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "SUMS %s, C, $%x", dest, const_val);
- }
- else
- {
- util::stream_format(stream, "SUMS %s, %s, $%x", dest, source, const_val);
- }
+ util::stream_format(stream, "SUM%c %s, %s, $%x",
+ (op_num & 0x4) ? 'S' : ' ',
+ dest,
+ (!source_bit && (source_code == SR_REGISTER)) ? "C" : source,
+ const_val);
+ if (!source_bit && (source_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + const_val));
break;
}
@@ -560,15 +536,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x20: case 0x21: case 0x22: case 0x23:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "CMP %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "CMP %s, %s", dest, source);
- }
+ format_addsub(stream, "CMP", dest, source, source_bit, source_code);
break;
@@ -576,39 +544,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x24: case 0x25: case 0x26: case 0x27:
RR_format(source, dest, op, h_flag);
- util::stream_format(stream, "MOV %s, %s", dest, source);
+ util::stream_format(stream, "MOV %s, %s", dest, source);
break;
// ADD
- case 0x28: case 0x29: case 0x2a: case 0x2b:
-
- RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "ADD %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "ADD %s, %s", dest, source);
- }
-
- break;
-
// ADDS
+ case 0x28: case 0x29: case 0x2a: case 0x2b:
case 0x2c: case 0x2d: case 0x2e: case 0x2f:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "ADDS %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "ADDS %s, %s", dest, source);
- }
+ format_addsub(stream, (op_num & 0x4) ? "ADDS" : "ADD", dest, source, source_bit, source_code);
break;
@@ -616,7 +562,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x30: case 0x31: case 0x32: case 0x33:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "CMPB %s, %s", dest, source);
+ util::stream_format(stream, "CMPB %s, %s", dest, source);
break;
@@ -624,7 +570,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x34: case 0x35: case 0x36: case 0x37:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "ANDN %s, %s", dest, source);
+ util::stream_format(stream, "ANDN %s, %s", dest, source);
break;
@@ -632,7 +578,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x38: case 0x39: case 0x3a: case 0x3b:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "OR %s, %s", dest, source);
+ util::stream_format(stream, "OR %s, %s", dest, source);
break;
@@ -640,7 +586,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x3c: case 0x3d: case 0x3e: case 0x3f:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "XOR %s, %s", dest, source);
+ util::stream_format(stream, "XOR %s, %s", dest, source);
break;
@@ -648,15 +594,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x40: case 0x41: case 0x42: case 0x43:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "SUBC %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "SUBC %s, %s", dest, source);
- }
+ format_addsub(stream, "SUBC", dest, source, source_bit, source_code);
break;
@@ -665,39 +603,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
RR_format(source, dest, op, 0);
- util::stream_format(stream, "NOT %s, %s", dest, source);
+ util::stream_format(stream, "NOT %s, %s", dest, source);
break;
// SUB
- case 0x48: case 0x49: case 0x4a: case 0x4b:
-
- RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "SUB %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "SUB %s, %s", dest, source);
- }
-
- break;
-
// SUBS
+ case 0x48: case 0x49: case 0x4a: case 0x4b:
case 0x4c: case 0x4d: case 0x4e: case 0x4f:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "SUBS %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "SUBS %s, %s", dest, source);
- }
+ format_addsub(stream, (op_num & 0x4) ? "SUBS" : "SUB", dest, source, source_bit, source_code);
break;
@@ -705,15 +621,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x50: case 0x51: case 0x52: case 0x53:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "ADDC %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "ADDC %s, %s", dest, source);
- }
+ format_addsub(stream, "ADDC", dest, source, source_bit, source_code);
break;
@@ -721,39 +629,17 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x54: case 0x55: case 0x56: case 0x57:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "AND %s, %s", dest, source);
+ util::stream_format(stream, "AND %s, %s", dest, source);
break;
// NEG
- case 0x58: case 0x59: case 0x5a: case 0x5b:
-
- RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "NEG %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "NEG %s, %s", dest, source);
- }
-
- break;
-
// NEGS
+ case 0x58: case 0x59: case 0x5a: case 0x5b:
case 0x5c: case 0x5d: case 0x5e: case 0x5f:
RR_format(source, dest, op, 0);
-
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "NEGS %s, C", dest);
- }
- else
- {
- util::stream_format(stream, "NEGS %s, %s", dest, source);
- }
+ format_addsub(stream, (op_num & 0x4) ? "NEGS" : "NEG", dest, source, source_bit, source_code);
break;
@@ -762,7 +648,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- util::stream_format(stream, "CMPI %s, $%x", dest, imm);
+ util::stream_format(stream, "CMPI %s, $%x", dest, imm);
break;
}
@@ -772,7 +658,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, h_flag);
- util::stream_format(stream, "MOVI %s, $%x", dest, imm);
+ util::stream_format(stream, "MOVI %s, $%x", dest, imm);
break;
}
@@ -782,13 +668,15 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- if( !DASM_N_VALUE(op) )
+ if (!DASM_N_VALUE(op))
{
- util::stream_format(stream, "ADDI %s, CZ", dest);
+ util::stream_format(stream, "ADDI %s, CZ", dest);
}
else
{
- util::stream_format(stream, "ADDI %s, $%x", dest, imm);
+ util::stream_format(stream, "ADDI %s, $%x", dest, imm);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + imm));
}
break;
@@ -799,13 +687,15 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- if( !DASM_N_VALUE(op) )
+ if (!DASM_N_VALUE(op))
{
- util::stream_format(stream, "ADDSI %s, CZ", dest);
+ util::stream_format(stream, "ADDSI %s, CZ", dest);
}
else
{
- util::stream_format(stream, "ADDSI %s, $%x", dest, imm);
+ util::stream_format(stream, "ADDSI %s, $%x", dest, imm);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + imm));
}
break;
@@ -816,16 +706,16 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- if( !DASM_N_VALUE(op) )
+ if (!DASM_N_VALUE(op))
{
- util::stream_format(stream, "CMPBI %s, ANYBZ", dest);
+ util::stream_format(stream, "CMPBI %s, ANYBZ", dest);
}
else
{
- if( DASM_N_VALUE(op) == 31 )
+ if (DASM_N_VALUE(op) == 31)
imm = 0x7fffffff; //bit 31 = 0, others = 1
- util::stream_format(stream, "CMPBI %s, $%x", dest, imm);
+ util::stream_format(stream, "CMPBI %s, $%x", dest, imm);
}
break;
@@ -836,10 +726,12 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- if( DASM_N_VALUE(op) == 31 )
+ if (DASM_N_VALUE(op) == 31)
imm = 0x7fffffff; //bit 31 = 0, others = 1
- util::stream_format(stream, "ANDNI %s, $%x", dest, imm);
+ util::stream_format(stream, "ANDNI %s, $%x", dest, imm);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t((pc + size) & ~imm));
break;
}
@@ -849,7 +741,9 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- util::stream_format(stream, "ORI %s, $%x", dest, imm);
+ util::stream_format(stream, "ORI %s, $%x", dest, imm);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t((pc + size) | imm));
break;
}
@@ -859,64 +753,36 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t imm = Rimm_format(dest, op, pc, opcodes, 0);
- util::stream_format(stream, "XORI %s, $%x", dest, imm);
+ util::stream_format(stream, "XORI %s, $%x", dest, imm);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t((pc + size) ^ imm));
break;
}
// SHRDI
- case 0x80: case 0x81:
- {
- uint8_t n = Ln_format(dest, op);
-
- util::stream_format(stream, "SHRDI %s, $%x", dest, n);
-
- break;
- }
-
- // SHRD
- case 0x82:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "SHRD %s, %s", dest, source);
-
- break;
-
- // SHR
- case 0x83:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "SHR %s, %s", dest, source);
-
- break;
-
// SARDI
+ case 0x80: case 0x81:
case 0x84: case 0x85:
{
uint8_t n = Ln_format(dest, op);
- util::stream_format(stream, "SARDI %s, $%x", dest, n);
+ util::stream_format(stream, "S%cRDI %s, $%x", (op_num & 0x4) ? 'A' : 'H', dest, n);
break;
}
- // SARD
- case 0x86:
+ case 0x82: // SHRD
+ case 0x83: // SHR
+ case 0x86: // SARD
+ case 0x87: // SAR
LL_format(source, dest, op);
-
- util::stream_format(stream, "SARD %s, %s", dest, source);
-
- break;
-
- // SAR
- case 0x87:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "SAR %s, %s", dest, source);
+ util::stream_format(stream, "S%cR%c %s, %s",
+ (op_num & 0x4) ? 'A' : 'H',
+ (op_num & 0x1) ? ' ' : 'D',
+ dest,
+ source);
break;
@@ -925,26 +791,18 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint8_t n = Ln_format(dest, op);
- util::stream_format(stream, "SHLDI %s, $%x", dest, n);
+ util::stream_format(stream, "SHLDI %s, $%x", dest, n);
break;
}
// SHLD
- case 0x8a:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "SHLD %s, %s", dest, source);
-
- break;
-
// SHL
+ case 0x8a:
case 0x8b:
LL_format(source, dest, op);
-
- util::stream_format(stream, "SHL %s, %s", dest, source);
+ util::stream_format(stream, "SHL%c %s, %s", (op_num & 0x1) ? ' ' : 'D', dest, source);
break;
@@ -960,8 +818,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x8e:
LL_format(source, dest, op);
-
- util::stream_format(stream, "TESTLZ %s, %s", dest, source);
+ util::stream_format(stream, "TESTLZ %s, %s", dest, source);
break;
@@ -969,407 +826,154 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0x8f:
LL_format(source, dest, op);
-
- util::stream_format(stream, "ROL %s, %s", dest, source);
+ util::stream_format(stream, "ROL %s, %s", dest, source);
break;
// LDxx.D/A/IOD/IOA
+ // STxx.D/A/IOD/IOA
case 0x90: case 0x91: case 0x92: case 0x93:
+ case 0x98: case 0x99: case 0x9a: case 0x9b:
{
- uint16_t next_op = opcodes.r16(pc + 2);
- uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
+ const uint16_t next_op = opcodes.r16(pc + 2);
+ const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
- if( size == 2 )
+ if (size == 2)
size = 4;
- if( dest_code == SR_REGISTER && !dest_bit )
- {
- switch( DD( next_op ) )
- {
- case 0:
- // LDBS.A
- util::stream_format(stream, "LDBS.A 0, %s, $%x", source, dis);
- break;
-
- case 1:
- // LDBU.A
- util::stream_format(stream, "LDBU.A 0, %s, $%x", source, dis);
- break;
-
- case 2:
- // LDHS.A
- if( dis & 1 )
- {
- util::stream_format(stream, "LDHS.A 0, %s, $%x", source, dis & ~1);
- }
- // LDHU.A
- else
- {
- util::stream_format(stream, "LDHU.A 0, %s, $%x", source, dis & ~1);
- }
-
- break;
-
- case 3:
- // LDD.IOA
- if( (dis & 3) == 3 )
- {
- util::stream_format(stream, "LDD.IOA 0, %s, $%x", source, dis & ~3);
- }
- // LDW.IOA
- else if( (dis & 3) == 2 )
- {
- util::stream_format(stream, "LDW.IOA 0, %s, $%x", source, dis & ~3);
- }
- // LDD.A
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "LDD.A 0, %s, $%x", source, dis & ~1);
- }
- // LDW.A
- else
- {
- util::stream_format(stream, "LDW.A 0, %s, $%x", source, dis & ~1);
- }
-
- break;
- }
- }
- else
- {
- switch( DD( next_op ) )
- {
- case 0:
- // LDBS.D
- util::stream_format(stream, "LDBS.D %s, %s, $%x", dest, source, dis);
- break;
-
- case 1:
- // LDBU.D
- util::stream_format(stream, "LDBU.D %s, %s, $%x", dest, source, dis);
- break;
-
- case 2:
- // LDHS.D
- if( dis & 1 )
- {
- util::stream_format(stream, "LDHS.D %s, %s, $%x", dest, source, dis & ~1);
- }
- // LDHU.D
- else
- {
- util::stream_format(stream, "LDHU.D %s, %s, $%x", dest, source, dis & ~1);
- }
- break;
-
- case 3:
- // LDD.IOD
- if( (dis & 3) == 3 )
- {
- util::stream_format(stream, "LDD.IOD %s, %s, $%x", dest, source, dis & ~3);
- }
- // LDW.IOD
- else if( (dis & 3) == 2 )
- {
- util::stream_format(stream, "LDW.IOD %s, %s, $%x", dest, source, dis & ~3);
- }
- // LDD.D
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "LDD.D %s, %s, $%x", dest, source, dis & ~1);
- }
- // LDW.D
- else
- {
- util::stream_format(stream, "LDW.D %s, %s, $%x", dest, source, dis & ~1);
- }
-
- break;
- }
- }
-
- break;
- }
-
- // LDxx.N/S
- case 0x94: case 0x95: case 0x96: case 0x97:
- {
- uint16_t next_op = opcodes.r16(pc + 2);
- uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
+ if ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER))
+ source = "0";
- if( size == 2 )
- size = 4;
+ if (!dest_bit && (dest_code == SR_REGISTER))
+ dest = "0";
- if( (dest_code == PC_REGISTER && !dest_bit) || (dest_code == SR_REGISTER && !dest_bit) )
- {
- util::stream_format(stream, "Reserved");
- break;
- }
+ const std::string_view inst = (op_num & 0x8) ? "ST" : "LD";
+ const char mode = (!dest_bit && (dest_code == SR_REGISTER)) ? 'A' : 'D';
- switch( DD( next_op ) )
+ switch (DD(next_op))
{
case 0:
- // LDBS.N
- util::stream_format(stream, "LDBS.N %s, %s, $%x", dest, source, dis);
+ // LD/STBS.D/A
+ util::stream_format(stream, "%sBS.%c %s, %s, $%x", inst, mode, dest, source, dis);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
break;
case 1:
- // LDBU.N
- util::stream_format(stream, "LDBU.N %s, %s, $%x", dest, source, dis);
+ // LD/STBU.D/A
+ util::stream_format(stream, "%sBU.%c %s, %s, $%x", inst, mode, dest, source, dis);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
break;
case 2:
- // LDHS.N
- if( dis & 1 )
- {
- util::stream_format(stream, "LDHS.N %s, %s, $%x", dest, source, dis & ~1);
- }
- // LDHU.N
- else
- {
- util::stream_format(stream, "LDHU.N %s, %s, $%x", dest, source, dis & ~1);
- }
-
+ // LD/STHU.D/A
+ // LD/STHS.D/A
+ util::stream_format(stream, "%sH%c.%c %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', mode, dest, source, dis & ~1);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1)));
break;
case 3:
- // LDW.S
- if( (dis & 3) == 3 )
+ if (dis & 2)
{
- util::stream_format(stream, "LDW.S %s, %s, $%x", dest, source, dis & ~3);
+ // LD/STW.IOD/A
+ // LD/STD.IOD/A
+ util::stream_format(stream, "%s%c.IO%c %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', mode, dest, source, dis & ~3);
}
- // Reserved
- else if( (dis & 3) == 2 )
- {
- util::stream_format(stream, "Reserved");
- }
- // LDD.N
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "LDD.N %s, %s, $%x", dest, source, dis & ~1);
- }
- // LDW.N
else
{
- util::stream_format(stream, "LDW.N %s, %s, $%x", dest, source, dis & ~1);
+ // LD/STW.D/A
+ // LD/STD.D/A
+ util::stream_format(stream, "%s%c.%c %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', mode, dest, source, dis & ~3);
}
-
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
break;
}
-
- break;
- }
-
- // STxx.D/A/IOD/IOA
- case 0x98: case 0x99: case 0x9a: case 0x9b:
- {
- uint16_t next_op = opcodes.r16(pc + 2);
- uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
-
- if( size == 2 )
- size = 4;
-
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- if( dest_code == SR_REGISTER && !dest_bit )
- {
- switch( DD( next_op ) )
- {
- case 0:
- // STBS.A
- util::stream_format(stream, "STBS.A 0, %s, $%x", source, dis);
- break;
-
- case 1:
- // STBU.A
- util::stream_format(stream, "STBU.A 0, %s, $%x", source, dis);
- break;
-
- case 2:
- // STHS.A
- if( dis & 1 )
- {
- util::stream_format(stream, "STHS.A 0, %s, $%x", source, dis & ~1);
- }
- // STHU.A
- else
- {
- util::stream_format(stream, "STHU.A 0, %s, $%x", source, dis & ~1);
- }
-
- break;
-
- case 3:
- // STD.IOA
- if( (dis & 3) == 3 )
- {
- util::stream_format(stream, "STD.IOA 0, %s, $%x", source, dis & ~3);
- }
- // STW.IOA
- else if( (dis & 3) == 2 )
- {
- util::stream_format(stream, "STW.IOA 0, %s, $%x", source, dis & ~3);
- }
- // STD.A
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "STD.A 0, %s, $%x", source, dis & ~1);
- }
- // STW.A
- else
- {
- util::stream_format(stream, "STW.A 0, %s, $%x", source, dis & ~1);
- }
-
- break;
- }
- }
- else
- {
- switch( DD( next_op ) )
- {
- case 0:
- // STBS.D
- util::stream_format(stream, "STBS.D %s, %s, $%x", dest, source, dis);
- break;
-
- case 1:
- // STBU.D
- util::stream_format(stream, "STBU.D %s, %s, $%x", dest, source, dis);
- break;
-
- case 2:
- // STHS.D
- if( dis & 1 )
- {
- util::stream_format(stream, "STHS.D %s, %s, $%x", dest, source, dis & ~1);
- }
- // STHU.D
- else
- {
- util::stream_format(stream, "STHU.D %s, %s, $%x", dest, source, dis & ~1);
- }
- break;
-
- case 3:
- // STD.IOD
- if( (dis & 3) == 3 )
- {
- util::stream_format(stream, "STD.IOD %s, %s, $%x", dest, source, dis & ~3);
- }
- // STW.IOD
- else if( (dis & 3) == 2 )
- {
- util::stream_format(stream, "STW.IOD %s, %s, $%x", dest, source, dis & ~3);
- }
- // STD.D
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "STD.D %s, %s, $%x", dest, source, dis & ~1);
- }
- // STW.D
- else
- {
- util::stream_format(stream, "STW.D %s, %s, $%x", dest, source, dis & ~1);
- }
-
- break;
- }
- }
-
break;
}
+ // LDxx.N/S
// STxx.N/S
+ case 0x94: case 0x95: case 0x96: case 0x97:
case 0x9c: case 0x9d: case 0x9e: case 0x9f:
{
- uint16_t next_op = opcodes.r16(pc + 2);
- uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
+ const uint16_t next_op = opcodes.r16(pc + 2);
+ const uint32_t dis = RRdis_format(source, dest, op, next_op, pc, opcodes);
- if( size == 2 )
+ if (size == 2)
size = 4;
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- if( (dest_code == PC_REGISTER && !dest_bit) || (dest_code == SR_REGISTER && !dest_bit) )
+ if (!dest_bit && ((dest_code == PC_REGISTER) || (dest_code == SR_REGISTER)))
{
util::stream_format(stream, "Reserved");
break;
}
- switch( DD( next_op ) )
+ if ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER))
+ source = "0";
+
+ const std::string_view inst = (op_num & 0x8) ? "ST" : "LD";
+
+ switch (DD(next_op))
{
case 0:
- // STBS.N
- util::stream_format(stream, "STBS.N %s, %s, $%x", dest, source, dis);
+ // LD/STBS.N
+ util::stream_format(stream, "%sBS.N %s, %s, $%x", inst, dest, source, dis);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
break;
case 1:
- // STBU.N
- util::stream_format(stream, "STBU.N %s, %s, $%x", dest, source, dis);
+ // LD/STBU.N
+ util::stream_format(stream, "%sBU.N %s, %s, $%x", inst, dest, source, dis);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + dis));
break;
case 2:
- // STHS.N
- if( dis & 1 )
- {
- util::stream_format(stream, "STHS.N %s, %s, $%x", dest, source, dis & ~1);
- }
- // STHU.N
- else
- {
- util::stream_format(stream, "STHU.N %s, %s, $%x", dest, source, dis & ~1);
- }
-
+ // LD/STHU.N
+ // LD/STHS.N
+ util::stream_format(stream, "%sH%c.N %s, %s, $%x", inst, (dis & 1) ? 'S' : 'U', dest, source, dis & ~1);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~1)));
break;
case 3:
- // STW.S
- if( (dis & 3) == 3 )
+ if ((dis & 3) == 3)
{
- util::stream_format(stream, "STW.S %s, %s, $%x", dest, source, dis & ~3);
+ // LD/STW.S
+ util::stream_format(stream, "%sW.S %s, %s, $%x", inst, dest, source, dis & ~3);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
}
- // Reserved
- else if( (dis & 3) == 2 )
+ else if ((dis & 3) == 2)
{
+ // Reserved
util::stream_format(stream, "Reserved");
}
- // STD.N
- else if( (dis & 3) == 1 )
- {
- util::stream_format(stream, "STD.N %s, %s, $%x", dest, source, dis & ~1);
- }
- // STW.N
else
{
- util::stream_format(stream, "STW.N %s, %s, $%x", dest, source, dis & ~1);
+ // LD/STW.N
+ // LD/STD.N
+ util::stream_format(stream, "%s%c.N %s, %s, $%x", inst, (dis & 1) ? 'D' : 'W', dest, source, dis & ~3);
+ if (!dest_bit && (dest_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + (dis & ~3)));
}
-
break;
}
-
break;
}
// SHRI
- case 0xa0: case 0xa1: case 0xa2: case 0xa3:
- {
- uint8_t n = Rn_format(dest, op);
-
- util::stream_format(stream, "SHRI %s, $%x", dest, n);
-
- break;
- }
-
// SARI
+ case 0xa0: case 0xa1: case 0xa2: case 0xa3:
case 0xa4: case 0xa5: case 0xa6: case 0xa7:
{
uint8_t n = Rn_format(dest, op);
- util::stream_format(stream, "SARI %s, $%x", dest, n);
+ util::stream_format(stream, "S%cRI %s, $%x", (op_num & 0x4) ? 'A' : 'H', dest, n);
break;
}
@@ -1385,20 +989,13 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
}
// MULU
- case 0xb0: case 0xb1: case 0xb2: case 0xb3:
-
- RR_format(source, dest, op, 0);
-
- util::stream_format(stream, "MULU %s, %s", dest, source);
-
- break;
-
// MULS
+ case 0xb0: case 0xb1: case 0xb2: case 0xb3:
case 0xb4: case 0xb5: case 0xb6: case 0xb7:
RR_format(source, dest, op, 0);
- util::stream_format(stream, "MULS %s, %s", dest, source);
+ util::stream_format(stream, "MUL%c %s, %s", (op_num & 0x4) ? 'S' : 'U', dest, source);
break;
@@ -1413,11 +1010,11 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
}
else if( dest_code == SR_REGISTER && !dest_bit )
{
- util::stream_format(stream, "FETCH $%x", (n / 2) + 1);
+ util::stream_format(stream, "FETCH $%x", (n / 2) + 1);
}
else
{
- util::stream_format(stream, "%s %s", SETxx[n], dest);
+ util::stream_format(stream, "%-7s %s", SETxx[n], dest);
}
break;
@@ -1427,134 +1024,27 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0xbc: case 0xbd: case 0xbe: case 0xbf:
RR_format(source, dest, op, 0);
-
- util::stream_format(stream, "MUL %s, %s", dest, source);
-
- break;
-
- // FADD
- case 0xc0:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FADD %s, %s", dest, source);
+ util::stream_format(stream, "MUL %s, %s", dest, source);
break;
- // FADDD
- case 0xc1:
+ case 0xc0: // FADD
+ case 0xc1: // FADDD
+ case 0xc2: // FSUB
+ case 0xc3: // FSUBD
+ case 0xc4: // FMUL
+ case 0xc5: // FMULD
+ case 0xc6: // FDIV
+ case 0xc7: // FDIVD
+ case 0xc8: // FCMP
+ case 0xc9: // FCMPD
+ case 0xca: // FCMPU
+ case 0xcb: // FCMPUD
+ case 0xcc: // FCVT
+ case 0xcd: // FCVTD
LL_format(source, dest, op);
-
- util::stream_format(stream, "FADDD %s, %s", dest, source);
-
- break;
-
- // FSUB
- case 0xc2:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FSUB %s, %s", dest, source);
-
- break;
-
- // FSUBD
- case 0xc3:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FSUBD %s, %s", dest, source);
-
- break;
-
- // FMUL
- case 0xc4:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FMUL %s, %s", dest, source);
-
- break;
-
- // FMULD
- case 0xc5:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FMULD %s, %s", dest, source);
-
- break;
-
- // FDIV
- case 0xc6:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FDIV %s, %s", dest, source);
-
- break;
-
- // FDIVD
- case 0xc7:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FDIVD %s, %s", dest, source);
-
- break;
-
- // FCMP
- case 0xc8:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCMP %s, %s", dest, source);
-
- break;
-
- // FCMPD
- case 0xc9:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCMPD %s, %s", dest, source);
-
- break;
-
- // FCMPU
- case 0xca:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCMPU %s, %s", dest, source);
-
- break;
-
- // FCMPUD
- case 0xcb:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCMPUD %s, %s", dest, source);
-
- break;
-
- // FCVT
- case 0xcc:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCVT %s, %s", dest, source);
-
- break;
-
- // FCVTD
- case 0xcd:
-
- LL_format(source, dest, op);
-
- util::stream_format(stream, "FCVTD %s, %s", dest, source);
+ util::stream_format(stream, "%-7s %s, %s", Fxxx[op_num & 0xf], dest, source);
break;
@@ -1642,234 +1132,50 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0xcf:
LL_format(source, dest, op);
-
- util::stream_format(stream, "DO %s, %s", dest, source);
-
- break;
-
- // LDW.R
- case 0xd0: case 0xd1:
-
- LR_format(source, dest, op);
-
- util::stream_format(stream, "LDW.R %s, %s", dest, source);
-
- break;
-
- // LDD.R
- case 0xd2: case 0xd3:
-
- LR_format(source, dest, op);
-
- util::stream_format(stream, "LDD.R %s, %s", dest, source);
-
- break;
-
- // LDW.P
- case 0xd4: case 0xd5:
-
- LR_format(source, dest, op);
-
- util::stream_format(stream, "LDW.P %s, %s", dest, source);
-
- break;
-
- // LDD.P
- case 0xd6: case 0xd7:
-
- LR_format(source, dest, op);
-
- util::stream_format(stream, "LDD.P %s, %s", dest, source);
-
- break;
-
- // STW.R
- case 0xd8: case 0xd9:
-
- LR_format(source, dest, op);
-
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- util::stream_format(stream, "STW.R %s, %s", dest, source);
-
- break;
-
- // STD.R
- case 0xda: case 0xdb:
-
- LR_format(source, dest, op);
-
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- util::stream_format(stream, "STD.R %s, %s", dest, source);
-
- break;
-
- // STW.P
- case 0xdc: case 0xdd:
-
- LR_format(source, dest, op);
-
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- util::stream_format(stream, "STW.P %s, %s", dest, source);
+ util::stream_format(stream, "DO %s, %s", dest, source);
break;
- // STD.P
- case 0xde: case 0xdf:
+ case 0xd0: case 0xd1: // LDW.R
+ case 0xd2: case 0xd3: // LDD.R
+ case 0xd4: case 0xd5: // LDW.P
+ case 0xd6: case 0xd7: // LDD.P
+ case 0xd8: case 0xd9: // STW.R
+ case 0xda: case 0xdb: // STD.R
+ case 0xdc: case 0xdd: // STW.P
+ case 0xde: case 0xdf: // STD.P
LR_format(source, dest, op);
-
- if( source_code == SR_REGISTER && !source_bit )
- strcpy(source,"0");
-
- util::stream_format(stream, "STD.P %s, %s", dest, source);
-
- break;
-
- // DBV
- case 0xe0:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBV $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBNV
- case 0xe1:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBNV $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBE
- case 0xe2:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBE $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBNE
- case 0xe3:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBNE $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBC
- case 0xe4:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBC $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBNC
- case 0xe5:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBNC $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBSE
- case 0xe6:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBSE $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBHT
- case 0xe7:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBHT $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBN
- case 0xe8:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBN $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBNN
- case 0xe9:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBNN $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBLE
- case 0xea:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBLE $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBGT
- case 0xeb:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "DBGT $%x", rel);
- flags = STEP_COND | step_over_extra(1);
-
- break;
- }
-
- // DBR
- case 0xec:
+ util::stream_format(stream, "%s%c.%c %s, %s",
+ (op_num & 0x8) ? "ST" : "LD",
+ (op_num & 0x2) ? 'D' : 'W',
+ (op_num & 0x4) ? 'P' : 'R',
+ dest,
+ ((op_num & 0x8) && !source_bit && (source_code == SR_REGISTER)) ? "0" : source);
+
+ break;
+
+ case 0xe0: // DBV
+ case 0xe1: // DBNV
+ case 0xe2: // DBE
+ case 0xe3: // DBNE
+ case 0xe4: // DBC
+ case 0xe5: // DBNC
+ case 0xe6: // DBSE
+ case 0xe7: // DBHT
+ case 0xe8: // DBN
+ case 0xe9: // DBNN
+ case 0xea: // DBLE
+ case 0xeb: // DBGT
+ case 0xec: // DBR
{
int32_t rel = PCrel_format(op, pc, opcodes) + 2;
- util::stream_format(stream, "DBR $%x", rel);
- flags = STEP_COND | step_over_extra(1);
+ util::stream_format(stream, "D%-6s $%x", Bxx[op_num & 0xf], rel);
+ if (op_num != 0xec)
+ {
+ flags = STEP_COND | step_over_extra(1);
+ }
break;
}
@@ -1878,7 +1184,7 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
case 0xed:
LL_format(source, dest, op);
- util::stream_format(stream, "FRAME %s, %s", dest, source);
+ util::stream_format(stream, "FRAME %s, %s", dest, source);
break;
@@ -1887,158 +1193,35 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
{
uint32_t const_val = LRconst_format(source, dest, op, pc, opcodes);
- if( source_code == SR_REGISTER && !source_bit )
- {
- util::stream_format(stream, "CALL %s, 0, $%x", dest, const_val);
- flags = STEP_OVER;
- }
- else
- {
- util::stream_format(stream, "CALL %s, %s, $%x", dest, source, const_val);
- flags = STEP_OVER;
- }
-
- break;
- }
-
- // BV
- case 0xf0:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BV $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BNV
- case 0xf1:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BNV $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BE
- case 0xf2:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BE $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BNE
- case 0xf3:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BNE $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BC
- case 0xf4:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BC $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BNC
- case 0xf5:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BNC $%x", rel);
- flags = STEP_COND;
+ util::stream_format(stream, "CALL %s, %s, $%x", dest, (!source_bit && (source_code == SR_REGISTER)) ? "0" : source, const_val);
+ if (!source_bit && (source_code == PC_REGISTER))
+ util::stream_format(stream, " ; $%x", uint32_t(pc + size + const_val));
+ flags = STEP_OVER;
break;
}
- // BSE
- case 0xf6:
+ case 0xf0: // BV
+ case 0xf1: // BNV
+ case 0xf2: // BE
+ case 0xf3: // BNE
+ case 0xf4: // BC
+ case 0xf5: // BNC
+ case 0xf6: // BSE
+ case 0xf7: // BHT
+ case 0xf8: // BN
+ case 0xf9: // BNN
+ case 0xfa: // BLE
+ case 0xfb: // BGT
+ case 0xfc: // BR
{
int32_t rel = PCrel_format(op, pc, opcodes) + 2;
- util::stream_format(stream, "BSE $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BHT
- case 0xf7:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BHT $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BN
- case 0xf8:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BN $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BNN
- case 0xf9:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BNN $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BLE
- case 0xfa:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BLE $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BGT
- case 0xfb:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BGT $%x", rel);
- flags = STEP_COND;
-
- break;
- }
-
- // BR
- case 0xfc:
- {
- int32_t rel = PCrel_format(op, pc, opcodes) + 2;
-
- util::stream_format(stream, "BR $%x", rel);
+ util::stream_format(stream, "%-7s $%x", Bxx[op_num & 0xf], rel);
+ if (op_num != 0xfc)
+ {
+ flags = STEP_COND;
+ }
break;
}
@@ -2049,79 +1232,14 @@ offs_t hyperstone_disassembler::disassemble(std::ostream &stream, offs_t pc, con
uint8_t code = ((op & 0x300) >> 6) | (op & 0x03);
uint8_t trapno = (op & 0xfc) >> 2;
- switch( code )
+ util::stream_format(stream, "%-7s %d", TRAPxx[code], trapno);
+ if (code == TRAP)
{
- case TRAPLE:
- util::stream_format(stream, "TRAPLE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPGT:
- util::stream_format(stream, "TRAPGT %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPLT:
- util::stream_format(stream, "TRAPLT %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPGE:
- util::stream_format(stream, "TRAPGE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPSE:
- util::stream_format(stream, "TRAPSE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPHT:
- util::stream_format(stream, "TRAPHT %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPST:
- util::stream_format(stream, "TRAPST %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPHE:
- util::stream_format(stream, "TRAPHE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPE:
- util::stream_format(stream, "TRAPE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPNE:
- util::stream_format(stream, "TRAPNE %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAPV:
- util::stream_format(stream, "TRAPV %d", trapno);
- flags = STEP_OVER | STEP_COND;
-
- break;
-
- case TRAP:
- util::stream_format(stream, "TRAP %d", trapno);
- flags = STEP_OVER;
-
- break;
+ flags = STEP_OVER;
+ }
+ else
+ {
+ flags = STEP_OVER | STEP_COND;
}
break;
diff --git a/src/devices/cpu/e132xs/32xsdasm.h b/src/devices/cpu/e132xs/32xsdasm.h
index 60f1c3974fd..32f9c6df587 100644
--- a/src/devices/cpu/e132xs/32xsdasm.h
+++ b/src/devices/cpu/e132xs/32xsdasm.h
@@ -12,10 +12,14 @@
#pragma once
+#include <string_view>
+
+
class hyperstone_disassembler : public util::disasm_interface
{
public:
- struct config {
+ struct config
+ {
virtual ~config() = default;
virtual bool get_h() const = 0;
@@ -32,16 +36,11 @@ private:
int size;
- void LL_format(char *source, char *dest, uint16_t op);
- void LR_format(char *source, char *dest, uint16_t op);
- void RR_format(char *source, char *dest, uint16_t op, unsigned h_flag);
- uint32_t LRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes);
- uint32_t RRconst_format(char *source, char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes);
- int32_t Rimm_format(char *dest, uint16_t op, offs_t &pc, const data_buffer &opcodes, unsigned h_flag);
- uint8_t Ln_format(char *dest, uint16_t op);
- uint8_t Rn_format(char *dest, uint16_t op);
+ uint32_t LRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes);
+ uint32_t RRconst_format(std::string_view &source, std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes);
+ int32_t Rimm_format(std::string_view &dest, uint16_t op, offs_t pc, const data_buffer &opcodes, unsigned h_flag);
int32_t PCrel_format(uint16_t op, offs_t pc, const data_buffer &opcodes);
- uint32_t RRdis_format(char *source, char *dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes);
+ uint32_t RRdis_format(std::string_view &source, std::string_view &dest, uint16_t op, uint16_t next_op, offs_t pc, const data_buffer &opcodes);
};
#endif
diff --git a/src/devices/cpu/e132xs/32xsdefs.h b/src/devices/cpu/e132xs/32xsdefs.h
index 04a28dc6739..13f82870706 100644
--- a/src/devices/cpu/e132xs/32xsdefs.h
+++ b/src/devices/cpu/e132xs/32xsdefs.h
@@ -9,18 +9,30 @@
COMPILE-TIME DEFINITIONS
***************************************************************************/
-#define PC_REGISTER 0
-#define SR_REGISTER 1
-#define SP_REGISTER 18
-#define UB_REGISTER 19
-#define BCR_REGISTER 20
-#define TPR_REGISTER 21
-#define TCR_REGISTER 22
-#define TR_REGISTER 23
-#define WCR_REGISTER 24
-#define ISR_REGISTER 25
-#define FCR_REGISTER 26
-#define MCR_REGISTER 27
+// compilation boundaries -- how far back/forward does the analysis extend?
+enum : u32
+{
+ COMPILE_BACKWARDS_BYTES = 128,
+ COMPILE_FORWARDS_BYTES = 512,
+ COMPILE_MAX_INSTRUCTIONS = (COMPILE_BACKWARDS_BYTES / 2) + (COMPILE_FORWARDS_BYTES / 2),
+ COMPILE_MAX_SEQUENCE = 64
+};
+
+enum
+{
+ PC_REGISTER = 0,
+ SR_REGISTER = 1,
+ SP_REGISTER = 18,
+ UB_REGISTER = 19,
+ BCR_REGISTER = 20,
+ TPR_REGISTER = 21,
+ TCR_REGISTER = 22,
+ TR_REGISTER = 23,
+ WCR_REGISTER = 24,
+ ISR_REGISTER = 25,
+ FCR_REGISTER = 26,
+ MCR_REGISTER = 27
+};
#define X_CODE(val) ((val & 0x7000) >> 12)
#define E_BIT(val) ((val & 0x8000) >> 15)
@@ -59,34 +71,40 @@
#define EMSUBD 0x11e
#define EHCFFTSD 0x296
-/* IRQ numbers */
-#define IRQ_INT1 0
-#define IRQ_INT2 1
-#define IRQ_INT3 2
-#define IRQ_INT4 3
-#define IRQ_IO1 4
-#define IRQ_IO2 5
-#define IRQ_IO3 6
-
-/* Trap numbers */
-#define TRAPNO_IO2 48
-#define TRAPNO_IO1 49
-#define TRAPNO_INT4 50
-#define TRAPNO_INT3 51
-#define TRAPNO_INT2 52
-#define TRAPNO_INT1 53
-#define TRAPNO_IO3 54
-#define TRAPNO_TIMER 55
-#define TRAPNO_RESERVED1 56
-#define TRAPNO_TRACE_EXCEPTION 57
-#define TRAPNO_PARITY_ERROR 58
-#define TRAPNO_EXTENDED_OVERFLOW 59
-#define TRAPNO_RANGE_ERROR 60
-#define TRAPNO_PRIVILEGE_ERROR TRAPNO_RANGE_ERROR
-#define TRAPNO_FRAME_ERROR TRAPNO_RANGE_ERROR
-#define TRAPNO_RESERVED2 61
-#define TRAPNO_RESET 62 // reserved if not mapped @ MEM3
-#define TRAPNO_ERROR_ENTRY 63 // for instruction code of all ones
+// IRQ numbers
+enum
+{
+ IRQ_INT1 = 0,
+ IRQ_INT2 = 1,
+ IRQ_INT3 = 2,
+ IRQ_INT4 = 3,
+ IRQ_IO1 = 4,
+ IRQ_IO2 = 5,
+ IRQ_IO3 = 6
+};
+
+// Trap numbers
+enum
+{
+ TRAPNO_IO2 = 48,
+ TRAPNO_IO1 = 49,
+ TRAPNO_INT4 = 50,
+ TRAPNO_INT3 = 51,
+ TRAPNO_INT2 = 52,
+ TRAPNO_INT1 = 53,
+ TRAPNO_IO3 = 54,
+ TRAPNO_TIMER = 55,
+ TRAPNO_RESERVED1 = 56,
+ TRAPNO_TRACE_EXCEPTION = 57,
+ TRAPNO_PARITY_ERROR = 58,
+ TRAPNO_EXTENDED_OVERFLOW = 59,
+ TRAPNO_RANGE_ERROR = 60,
+ TRAPNO_PRIVILEGE_ERROR = TRAPNO_RANGE_ERROR,
+ TRAPNO_FRAME_ERROR = TRAPNO_RANGE_ERROR,
+ TRAPNO_RESERVED2 = 61,
+ TRAPNO_RESET = 62, // reserved if not mapped @ MEM3
+ TRAPNO_ERROR_ENTRY = 63 // for instruction code of all ones
+};
/* Trap codes */
#define TRAPLE 4
diff --git a/src/devices/cpu/e132xs/e132xs.cpp b/src/devices/cpu/e132xs/e132xs.cpp
index 8e444a66a05..aa10195a221 100644
--- a/src/devices/cpu/e132xs/e132xs.cpp
+++ b/src/devices/cpu/e132xs/e132xs.cpp
@@ -120,6 +120,7 @@ hyperstone_device::hyperstone_device(
, m_drcuml(nullptr)
, m_drcfe(nullptr)
, m_drcoptions(0)
+ , m_single_instruction_mode(false)
, m_cache_dirty(0)
, m_entry(nullptr)
, m_nocode(nullptr)
@@ -999,9 +1000,18 @@ void hyperstone_device::device_start()
m_drcuml = std::make_unique<drcuml_state>(*this, m_cache, umlflags, 4, 32, 1);
// add UML symbols-
- m_drcuml->symbol_add(&m_core->global_regs[0], sizeof(uint32_t), "pc");
- m_drcuml->symbol_add(&m_core->global_regs[1], sizeof(uint32_t), "sr");
- m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
+ m_drcuml->symbol_add(&m_core->global_regs[PC_REGISTER], sizeof(m_core->global_regs[PC_REGISTER]), "pc");
+ m_drcuml->symbol_add(&m_core->global_regs[SR_REGISTER], sizeof(m_core->global_regs[SR_REGISTER]), "sr");
+ m_drcuml->symbol_add(&m_core->global_regs[SP_REGISTER], sizeof(m_core->global_regs[SP_REGISTER]), "sp");
+ m_drcuml->symbol_add(&m_core->global_regs[UB_REGISTER], sizeof(m_core->global_regs[UB_REGISTER]), "ub");
+ m_drcuml->symbol_add(&m_core->trap_entry, sizeof(m_core->trap_entry), "trap_entry");
+ m_drcuml->symbol_add(&m_core->delay_pc, sizeof(m_core->delay_pc), "delay_pc");
+ m_drcuml->symbol_add(&m_core->delay_slot, sizeof(m_core->delay_slot), "delay_slot");
+ m_drcuml->symbol_add(&m_core->delay_slot_taken, sizeof(m_core->delay_slot_taken), "delay_slot_taken");
+ m_drcuml->symbol_add(&m_core->intblock, sizeof(m_core->intblock), "intblock");
+ m_drcuml->symbol_add(&m_core->arg0, sizeof(m_core->arg0), "arg0");
+ m_drcuml->symbol_add(&m_core->arg1, sizeof(m_core->arg1), "arg1");
+ m_drcuml->symbol_add(&m_core->icount, sizeof(m_core->icount), "icount");
char buf[4];
buf[3] = '\0';
@@ -1040,7 +1050,7 @@ void hyperstone_device::device_start()
m_drcuml->symbol_add(&m_core->arg1, sizeof(uint32_t), "arg1");
/* initialize the front-end helper */
- m_drcfe = std::make_unique<e132xs_frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, SINGLE_INSTRUCTION_MODE ? 1 : COMPILE_MAX_SEQUENCE);
+ m_drcfe = std::make_unique<e132xs_frontend>(*this, COMPILE_BACKWARDS_BYTES, COMPILE_FORWARDS_BYTES, m_single_instruction_mode ? 1 : COMPILE_MAX_SEQUENCE);
/* mark the cache dirty so it is updated on next execute */
m_cache_dirty = true;
diff --git a/src/devices/cpu/e132xs/e132xs.h b/src/devices/cpu/e132xs/e132xs.h
index 8cf30c0c78b..b1bb744d5dd 100644
--- a/src/devices/cpu/e132xs/e132xs.h
+++ b/src/devices/cpu/e132xs/e132xs.h
@@ -32,10 +32,6 @@
CONSTANTS
***************************************************************************/
-/* map variables */
-#define MAPVAR_PC M0
-#define MAPVAR_CYCLES M1
-
#define E132XS_STRICT_VERIFY 0x0001 /* verify all instructions */
#define SINGLE_INSTRUCTION_MODE (0)
@@ -116,18 +112,12 @@ class hyperstone_device : public cpu_device, public hyperstone_disassembler::con
friend class e132xs_frontend;
public:
+ // configuration
+ void set_single_instruction_mode(bool val) { m_single_instruction_mode = val; }
+
virtual ~hyperstone_device() override;
protected:
- // compilation boundaries -- how far back/forward does the analysis extend?
- enum : u32
- {
- COMPILE_BACKWARDS_BYTES = 128,
- COMPILE_FORWARDS_BYTES = 512,
- COMPILE_MAX_INSTRUCTIONS = (COMPILE_BACKWARDS_BYTES / 4) + (COMPILE_FORWARDS_BYTES / 4),
- COMPILE_MAX_SEQUENCE = 64
- };
-
// exit codes
enum : int
{
@@ -230,31 +220,16 @@ protected:
IS_TIMER = 1
};
- enum
- {
- EXCEPTION_IO2 = 48,
- EXCEPTION_IO1 = 49,
- EXCEPTION_INT4 = 50,
- EXCEPTION_INT3 = 51,
- EXCEPTION_INT2 = 52,
- EXCEPTION_INT1 = 53,
- EXCEPTION_IO3 = 54,
- EXCEPTION_TIMER = 55,
- EXCEPTION_RESERVED1 = 56,
- EXCEPTION_TRACE = 57,
- EXCEPTION_PARITY_ERROR = 58,
- EXCEPTION_EXTENDED_OVERFLOW = 59,
- EXCEPTION_RANGE_ERROR = 60,
- EXCEPTION_PRIVILEGE_ERROR = EXCEPTION_RANGE_ERROR,
- EXCEPTION_FRAME_ERROR = EXCEPTION_RANGE_ERROR,
- EXCEPTION_RESERVED2 = 61,
- EXCEPTION_RESET = 62, // reserved if not mapped @ MEM3
- EXCEPTION_ERROR_ENTRY = 63, // for instruction code of all ones
- };
-
// construction/destruction
- hyperstone_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock,
- const device_type type, uint32_t prg_data_width, uint32_t io_data_width, address_map_constructor internal_map);
+ hyperstone_device(
+ const machine_config &mconfig,
+ const char *tag,
+ device_t *owner,
+ uint32_t clock,
+ const device_type type,
+ uint32_t prg_data_width,
+ uint32_t io_data_width,
+ address_map_constructor internal_map);
// device_t implementation
virtual void device_start() override ATTR_COLD;
@@ -441,6 +416,7 @@ private:
std::unique_ptr<drcuml_state> m_drcuml;
std::unique_ptr<e132xs_frontend> m_drcfe;
uint32_t m_drcoptions;
+ bool m_single_instruction_mode;
uint8_t m_cache_dirty;
uml::code_handle *m_entry;
diff --git a/src/devices/cpu/e132xs/e132xsdrc.cpp b/src/devices/cpu/e132xs/e132xsdrc.cpp
index 5a8be5a872b..98dd0b76953 100644
--- a/src/devices/cpu/e132xs/e132xsdrc.cpp
+++ b/src/devices/cpu/e132xs/e132xsdrc.cpp
@@ -7,6 +7,11 @@
#include "32xsdefs.h"
+/* map variables */
+#define MAPVAR_PC M0
+#define MAPVAR_CYCLES M1
+
+
struct hyperstone_device::compiler_state
{
private:
@@ -824,7 +829,7 @@ void hyperstone_device::generate_sequence_instruction(drcuml_block &block, compi
}
if (BIT(compiler.mode(), 1) && !desc->delayslots)
- UML_EXHc(block, uml::COND_Z, *m_exception, EXCEPTION_TRACE);
+ UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_TRACE_EXCEPTION);
}
else
{
diff --git a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
index d0d392bd068..affe8526819 100644
--- a/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
+++ b/src/devices/cpu/e132xs/e132xsdrc_ops.hxx
@@ -203,7 +203,7 @@ void hyperstone_device::generate_set_global_register_low(drcuml_block &block, co
UML_AND(block, I4, I4, ~0x40); // keep reserved bit clear
}
UML_MOV(block, DRC_SR, I4);
- UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
UML_LABEL(block, no_exception);
if (src.is_immediate())
{
@@ -725,7 +725,7 @@ void hyperstone_device::generate_chk(drcuml_block &block, compiler_state &compil
UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
UML_MOV(block, DRC_SR, I2);
- UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
if (!unconditional)
UML_LABEL(block, done);
@@ -783,7 +783,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
UML_XOR(block, I3, I3, ~uint32_t(0));
UML_AND(block, I3, I3, S_MASK | L_MASK);
UML_TEST(block, I3, I2);
- UML_EXHc(block, uml::COND_NZ, *m_exception, EXCEPTION_PRIVILEGE_ERROR);
+ UML_EXHc(block, uml::COND_NZ, *m_exception, TRAPNO_PRIVILEGE_ERROR);
}
else
{
@@ -794,7 +794,7 @@ void hyperstone_device::generate_movd(drcuml_block &block, compiler_state &compi
UML_SHL(block, I3, I3, S_SHIFT - L_SHIFT); // I3(18) = L || !L'
UML_OR(block, I3, I3, I2); // I3(18) = L || !L' || S'
UML_TEST(block, I3, S_MASK);
- UML_EXHc(block, uml::COND_Z, *m_exception, EXCEPTION_PRIVILEGE_ERROR);
+ UML_EXHc(block, uml::COND_Z, *m_exception, TRAPNO_PRIVILEGE_ERROR);
}
const int pop_next = compiler.next_label();
@@ -970,7 +970,7 @@ void hyperstone_device::generate_divsu(drcuml_block &block, compiler_state &comp
UML_LABEL(block, no_result);
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK | V_MASK, 0, ILC_MASK | P_MASK | V_MASK);
- UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
UML_LABEL(block, done);
}
@@ -1017,7 +1017,7 @@ void hyperstone_device::generate_xm(drcuml_block &block, compiler_state &compile
UML_ROLINS(block, I2, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
UML_MOV(block, DRC_SR, I2);
- UML_EXH(block, *m_exception, EXCEPTION_RANGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_RANGE_ERROR);
UML_LABEL(block, done);
}
}
@@ -1192,7 +1192,7 @@ void hyperstone_device::generate_mov(drcuml_block &block, compiler_state &compil
const int no_exception = compiler.next_label();
UML_TEST(block, DRC_SR, H_MASK);
UML_JMPc(block, uml::COND_Z, no_exception);
- UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
UML_JMP(block, done);
UML_LABEL(block, no_exception);
}
@@ -1666,7 +1666,7 @@ void hyperstone_device::generate_movi(drcuml_block &block, compiler_state &compi
const int no_exception = compiler.next_label();
UML_TEST(block, I2, H_MASK);
UML_JMPc(block, uml::COND_Z, no_exception);
- UML_EXH(block, *m_exception, EXCEPTION_PRIVILEGE_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_PRIVILEGE_ERROR);
UML_LABEL(block, no_exception);
}
@@ -3932,7 +3932,7 @@ void hyperstone_device::generate_frame(drcuml_block &block, compiler_state &comp
UML_TEST(block, I4, ~uint32_t(0));
UML_JMPc(block, uml::COND_Z, done);
UML_ROLINS(block, DRC_SR, ((desc->length >> 1) << ILC_SHIFT) | P_MASK, 0, ILC_MASK | P_MASK);
- UML_EXH(block, *m_exception, EXCEPTION_FRAME_ERROR);
+ UML_EXH(block, *m_exception, TRAPNO_FRAME_ERROR);
UML_LABEL(block, done);
}
diff --git a/src/devices/cpu/e132xs/e132xsfe.cpp b/src/devices/cpu/e132xs/e132xsfe.cpp
index ec5c8df4442..729bdad1a9f 100644
--- a/src/devices/cpu/e132xs/e132xsfe.cpp
+++ b/src/devices/cpu/e132xs/e132xsfe.cpp
@@ -179,7 +179,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
desc.regin[0] |= 1 << gsrcf_code;
desc.regout[0] |= 1 << gdst_code;
desc.regout[0] |= 1 << gdstf_code;
- if (gdst_code == 0)
+ if (gdst_code == PC_REGISTER)
{
desc.targetpc = BRANCH_TARGET_DYNAMIC;
desc.flags |= OPFLAG_READS_MEMORY | OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE | OPFLAG_CAN_CAUSE_EXCEPTION | OPFLAG_CAN_CHANGE_MODES;
@@ -1170,7 +1170,7 @@ bool e132xs_frontend::describe(opcode_desc &desc, const opcode_desc *prev)
desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op);
break;
case 0xec: // dbr
- desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH;
+ desc.flags |= OPFLAG_IS_UNCONDITIONAL_BRANCH | OPFLAG_END_SEQUENCE;
desc.delayslots = 1;
desc.length = (op & 0x80) ? 4 : 2;
desc.targetpc = desc.physpc + desc.length + decode_pcrel(desc, op);