SPARC core improvements (nw) [Ryan Holtz]

fixes peculiarities with PSR e.g. ICC overwritten on trap
improved fcode logging
This commit is contained in:
Vas Crabb 2016-07-11 20:10:27 +10:00
parent 7f3ced8c96
commit b371656296
4 changed files with 243 additions and 169 deletions

View File

@ -102,25 +102,34 @@ void mb86901_device::device_start()
if (pos >= filesize) if (pos >= filesize)
break; break;
// read description // read description up to the first space
std::string description; std::string description;
while (buf[pos] != ';' && pos < filesize) while (buf[pos] != ' ' && pos < filesize)
{ {
description += char(buf[pos]); description += char(buf[pos]);
pos++; pos++;
} }
if (pos >= filesize)
break;
// skip everything else up to the trailing semicolon
while (buf[pos] != ';' && pos < filesize)
pos++;
if (pos >= filesize) if (pos >= filesize)
break; break;
if (buf[pos] == ';') if (buf[pos] == ';')
pos++; pos++;
m_ss1_fcode_table[opcode & ~1] = description; m_ss1_fcode_table[opcode] = description;
} }
delete [] buf; delete [] buf;
} }
m_log_fcodes = false;
#endif #endif
m_bp_reset_in = false; m_bp_reset_in = false;
m_bp_fpu_present = false; m_bp_fpu_present = false;
m_bp_cp_present = false; m_bp_cp_present = false;
@ -397,18 +406,8 @@ void mb86901_device::device_reset()
TBR = 0; TBR = 0;
Y = 0; Y = 0;
m_impl = 0; PSR = PSR_S_MASK | PSR_PS_MASK;
m_ver = 0;
m_icc = 0;
m_ec = false;
m_ef = false;
m_pil = 0;
m_s = true;
m_ps = true;
m_et = false;
m_cwp = 0;
MAKE_PSR;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
m_regs[i] = m_r + i; m_regs[i] = m_r + i;
@ -1006,7 +1005,7 @@ void mb86901_device::execute_mulscc(UINT32 op)
C <- (operand1<31> and operand2<31>) or C <- (operand1<31> and operand2<31>) or
((not result<31>) and (operand1<31> or operand2<31>)) ((not result<31>) and (operand1<31> or operand2<31>))
*/ */
UINT32 operand1 = (ICC_N != ICC_V ? 0x80000000 : 0) | (RS1REG >> 1); UINT32 operand1 = ((ICC_N != ICC_V) ? 0x80000000 : 0) | (RS1REG >> 1);
UINT32 operand2 = (Y & 1) ? (USEIMM ? SIMM13 : RS2REG) : 0; UINT32 operand2 = (Y & 1) ? (USEIMM ? SIMM13 : RS2REG) : 0;
@ -1072,7 +1071,6 @@ void mb86901_device::execute_rdsr(UINT32 op)
} }
else if (RDPSR) else if (RDPSR)
{ {
MAKE_PSR;
RDREG = PSR; RDREG = PSR;
} }
else if (RDWIM) else if (RDWIM)
@ -1174,7 +1172,6 @@ void mb86901_device::execute_wrsr(UINT32 op)
{ {
PSR = result &~ PSR_ZERO_MASK; PSR = result &~ PSR_ZERO_MASK;
} }
BREAK_PSR;
} }
else if (WRWIM) else if (WRWIM)
{ {
@ -1246,9 +1243,9 @@ void mb86901_device::execute_rett(UINT32 op)
) )
*/ */
UINT8 new_cwp = (CWP + 1) % NWINDOWS; UINT8 new_cwp = ((PSR & PSR_CWP_MASK) + 1) % NWINDOWS;
UINT32 address = RS1REG + (USEIMM ? SIMM13 : RS2REG); UINT32 address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (ET) if (PSR & PSR_ET_MASK)
{ {
m_trap = 1; m_trap = 1;
if (IS_USER) if (IS_USER)
@ -1286,14 +1283,19 @@ void mb86901_device::execute_rett(UINT32 op)
} }
else else
{ {
ET = 1; PSR |= PSR_ET_MASK;
PC = nPC; PC = nPC;
nPC = address; nPC = address;
CWP = new_cwp;
S = PS; PSR &= ~PSR_CWP_MASK;
PSR |= new_cwp;
if (PSR & PSR_PS_MASK)
PSR |= PSR_S_MASK;
else
PSR &= ~PSR_S_MASK;
} }
MAKE_PSR;
update_gpr_pointers(); update_gpr_pointers();
} }
@ -1342,7 +1344,7 @@ void mb86901_device::execute_saverestore(UINT32 op)
UINT32 result = 0; UINT32 result = 0;
if (SAVE) if (SAVE)
{ {
UINT8 new_cwp = ((CWP + NWINDOWS) - 1) % NWINDOWS; UINT8 new_cwp = (((PSR & PSR_CWP_MASK) + NWINDOWS) - 1) % NWINDOWS;
if ((WIM & (1 << new_cwp)) != 0) if ((WIM & (1 << new_cwp)) != 0)
{ {
m_trap = 1; m_trap = 1;
@ -1351,12 +1353,13 @@ void mb86901_device::execute_saverestore(UINT32 op)
else else
{ {
result = rs1 + operand2; result = rs1 + operand2;
CWP = new_cwp; PSR &= ~PSR_CWP_MASK;
PSR |= new_cwp;
} }
} }
else if (RESTORE) else if (RESTORE)
{ {
UINT8 new_cwp = (CWP + 1) % NWINDOWS; UINT8 new_cwp = ((PSR & PSR_CWP_MASK) + 1) % NWINDOWS;
if ((WIM & (1 << new_cwp)) != 0) if ((WIM & (1 << new_cwp)) != 0)
{ {
m_trap = 1; m_trap = 1;
@ -1365,11 +1368,11 @@ void mb86901_device::execute_saverestore(UINT32 op)
else else
{ {
result = rs1 + operand2; result = rs1 + operand2;
CWP = new_cwp; PSR &= ~PSR_CWP_MASK;
PSR |= new_cwp;
} }
} }
MAKE_PSR;
update_gpr_pointers(); update_gpr_pointers();
if (m_trap == 0 && RD != 0) if (m_trap == 0 && RD != 0)
@ -1546,11 +1549,12 @@ void mb86901_device::execute_group2(UINT32 op)
void mb86901_device::update_gpr_pointers() void mb86901_device::update_gpr_pointers()
{ {
int cwp = PSR & PSR_CWP_MASK;
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
{ {
m_regs[ 8 + i] = &m_r[8 + (( 0 + m_cwp * 16 + i) % (NWINDOWS * 16))]; m_regs[ 8 + i] = &m_r[8 + (( 0 + cwp * 16 + i) % (NWINDOWS * 16))];
m_regs[16 + i] = &m_r[8 + (( 8 + m_cwp * 16 + i) % (NWINDOWS * 16))]; m_regs[16 + i] = &m_r[8 + (( 8 + cwp * 16 + i) % (NWINDOWS * 16))];
m_regs[24 + i] = &m_r[8 + ((16 + m_cwp * 16 + i) % (NWINDOWS * 16))]; m_regs[24 + i] = &m_r[8 + ((16 + cwp * 16 + i) % (NWINDOWS * 16))];
} }
} }
@ -1705,12 +1709,12 @@ void mb86901_device::execute_store(UINT32 op)
address = RS1REG + RS2REG; address = RS1REG + RS2REG;
addr_space = ASI; addr_space = ASI;
} }
if ((STF || STDF || STFSR || STDFQ) && (!EF || !m_bp_fpu_present)) if ((STF || STDF || STFSR || STDFQ) && (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present))
{ {
m_trap = 1; m_trap = 1;
m_fp_disabled = 1; m_fp_disabled = 1;
} }
if ((STC || STDC || STCSR || STDCQ) && (!EC || !m_bp_cp_present)) if ((STC || STDC || STCSR || STDCQ) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present))
{ {
m_trap = 1; m_trap = 1;
m_cp_disabled = 1; m_cp_disabled = 1;
@ -2032,12 +2036,12 @@ void mb86901_device::execute_load(UINT32 op)
if (!m_trap) if (!m_trap)
{ {
if ((LDF || LDDF || LDFSR) && (EF == 0 || m_bp_fpu_present == 0)) if ((LDF || LDDF || LDFSR) && (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0))
{ {
m_trap = 1; m_trap = 1;
m_fp_disabled = 1; m_fp_disabled = 1;
} }
else if ((LDC || LDDC || LDCSR) && (EC == 0 || m_bp_cp_present == 0)) else if ((LDC || LDDC || LDCSR) && (!(PSR & PSR_EC_MASK) || m_bp_cp_present == 0))
{ {
m_trap = 1; m_trap = 1;
m_cp_disabled = 1; m_cp_disabled = 1;
@ -2118,10 +2122,8 @@ void mb86901_device::execute_load(UINT32 op)
if (!m_trap) if (!m_trap)
{ {
if ((RD != 0) && (LD || LDA || LDSH || LDSHA || LDUHA || LDUH || LDSB || LDSBA || LDUB || LDUBA)) if (RD == 0) { }
{ else if (LD || LDA || LDSH || LDSHA || LDUHA || LDUH || LDSB || LDSBA || LDUB || LDUBA) RDREG = word0;
RDREG = word0;
}
else if (LDF) FDREG = word0; else if (LDF) FDREG = word0;
else if (LDC) { } // implementation-dependent actions else if (LDC) { } // implementation-dependent actions
else if (LDFSR) FSR = word0; else if (LDFSR) FSR = word0;
@ -2559,7 +2561,7 @@ void mb86901_device::select_trap()
m_trap = 0; m_trap = 0;
return; return;
} }
else if (!ET) else if (!(PSR & PSR_ET_MASK))
{ {
m_execute_mode = 0; m_execute_mode = 0;
m_error_mode = 1; m_error_mode = 1;
@ -2722,11 +2724,19 @@ void mb86901_device::execute_trap()
if (!m_error_mode) if (!m_error_mode)
{ {
ET = 0; PSR &= ~PSR_ET_MASK;
PS = S;
S = 1; if (IS_USER)
CWP = ((CWP + NWINDOWS) - 1) % NWINDOWS; PSR &= ~PSR_PS_MASK;
MAKE_PSR; else
PSR |= PSR_PS_MASK;
PSR |= PSR_S_MASK;
int cwp = PSR & PSR_CWP_MASK;
PSR &= ~PSR_CWP_MASK;
PSR |= ((cwp + NWINDOWS) - 1) % NWINDOWS;
update_gpr_pointers(); update_gpr_pointers();
if (m_annul == 0) if (m_annul == 0)
@ -2855,12 +2865,12 @@ void mb86901_device::dispatch_instruction(UINT32 op)
m_trap = 1; m_trap = 1;
m_illegal_instruction = 1; m_illegal_instruction = 1;
} }
if (((OP == OP_ALU && (FPOP1 || FPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_FBFCC)) && (!EF || !m_bp_fpu_present)) if (((OP == OP_ALU && (FPOP1 || FPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_FBFCC)) && (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present))
{ {
m_trap = 1; m_trap = 1;
m_fp_disabled = 1; m_fp_disabled = 1;
} }
if (((OP == OP_ALU && (CPOP1 || CPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_CBCCC)) && (!EC || !m_bp_cp_present)) if (((OP == OP_ALU && (CPOP1 || CPOP2)) || (OP == OP_TYPE0 && OP2 == OP2_CBCCC)) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present))
{ {
m_trap = 1; m_trap = 1;
m_cp_disabled = 1; m_cp_disabled = 1;
@ -2947,7 +2957,7 @@ void mb86901_device::execute_step()
m_reset_mode = 1; m_reset_mode = 1;
return; return;
} }
else if (ET && (m_bp_irl == 15 || m_bp_irl > PIL)) else if ((PSR & PSR_ET_MASK) && (m_bp_irl == 15 || m_bp_irl > ((PSR >> PSR_PIL_SHIFT) & PSR_PIL_MASK)))
{ {
m_trap = 1; m_trap = 1;
m_interrupt_level = m_bp_irl; m_interrupt_level = m_bp_irl;
@ -2956,6 +2966,7 @@ void mb86901_device::execute_step()
if (m_trap) if (m_trap)
{ {
execute_trap(); execute_trap();
BREAK_PSR;
debugger_instruction_hook(this, PC); debugger_instruction_hook(this, PC);
} }
@ -2967,54 +2978,9 @@ void mb86901_device::execute_step()
UINT32 op = read_sized_word(addr_space, PC, 4); UINT32 op = read_sized_word(addr_space, PC, 4);
#if LOG_FCODES #if LOG_FCODES
if (PC == 0xffef0000) //if (m_log_fcodes)
{ {
UINT32 opcode = read_sized_word(11, REG(5), 2); log_fcodes();
if (!(REG(5) & 2))
{
opcode >>= 16;
}
UINT32 handler_base = opcode << 2;
handler_base += REG(2); // l1 = r2 + opcode << 2
UINT32 entry_point = read_sized_word(11, handler_base, 2);
if (!(handler_base & 2))
{
entry_point >>= 16;
}
entry_point <<= 2;
entry_point += REG(2); // l0 = r2 + entry_point << 2
#if 0
// Doesn't seem to work
UINT32 name_length_addr = (REG(2) + ((opcode & ~1) << 2)) - 1;
UINT32 name_length_shift = (3 - (name_length_addr & 3)) * 8;
UINT32 name_length = (read_sized_word(11, name_length_addr, 1) >> name_length_shift) & 0x7f;
UINT32 name_start_addr = name_length_addr - name_length;
char name_buf[129];
memset(name_buf, 0, 129);
if (name_length > 0)
{
for (int i = 0; i < name_length; i++)
{
UINT32 char_addr = name_start_addr + i;
UINT32 char_shift = (3 - (char_addr & 3)) * 8;
name_buf[i] = (read_sized_word(11, char_addr, 1) >> char_shift) & 0xff;
}
}
#endif
disassemble_ss1_fcode(REG(5), opcode, handler_base, entry_point, REG(7));
}
else if (PC == m_ss1_next_entry_point)
{
disassemble_ss1_fcode(m_ss1_next_pc, m_ss1_next_opcode, m_ss1_next_handler_base, m_ss1_next_entry_point, m_ss1_next_stack);
m_ss1_next_pc = ~0;
m_ss1_next_opcode = ~0;
m_ss1_next_handler_base = ~0;
m_ss1_next_entry_point = ~0;
m_ss1_next_stack = ~0;
} }
#endif #endif
@ -3122,6 +3088,7 @@ void mb86901_device::execute_run()
continue; continue;
} }
BREAK_PSR;
debugger_instruction_hook(this, PC); debugger_instruction_hook(this, PC);
if (m_reset_mode) if (m_reset_mode)

View File

@ -85,6 +85,12 @@ public:
template<typename T> static void add_asi_desc(device_t &device, const T &desc) { return downcast<mb86901_device &>(device).add_asi_desc(desc); } template<typename T> static void add_asi_desc(device_t &device, const T &desc) { return downcast<mb86901_device &>(device).add_asi_desc(desc); }
#if LOG_FCODES
void enable_log_fcodes(bool enable) { m_log_fcodes = enable; }
#else
void enable_log_fcodes(bool /*enable*/) { }
#endif
protected: protected:
template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); } template<typename T> void add_asi_desc(const T &desc) { m_dasm.add_asi_desc(desc); }
@ -133,6 +139,7 @@ protected:
#if LOG_FCODES #if LOG_FCODES
void indent(); void indent();
void disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 handler_base, UINT32 entry_point, UINT32 stack); void disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 handler_base, UINT32 entry_point, UINT32 stack);
void log_fcodes();
#endif #endif
// address spaces // address spaces
@ -248,6 +255,7 @@ protected:
UINT32 m_ss1_next_entry_point; UINT32 m_ss1_next_entry_point;
UINT32 m_ss1_next_stack; UINT32 m_ss1_next_stack;
std::map<UINT16, std::string> m_ss1_fcode_table; std::map<UINT16, std::string> m_ss1_fcode_table;
bool m_log_fcodes;
#endif #endif
// processor configuration // processor configuration

View File

@ -68,14 +68,9 @@
#define TEST_ICC_NZ(x) do { m_psr &= ~PSR_ICC_MASK; m_psr |= (x & 0x80000000) ? PSR_N_MASK : 0; m_psr |= (x == 0) ? PSR_Z_MASK : 0; } while (0) #define TEST_ICC_NZ(x) do { m_psr &= ~PSR_ICC_MASK; m_psr |= (x & 0x80000000) ? PSR_N_MASK : 0; m_psr |= (x == 0) ? PSR_Z_MASK : 0; } while (0)
#define MAKE_PSR do { m_psr = (m_impl << PSR_IMPL_SHIFT) | (m_ver << PSR_VER_SHIFT) | (m_icc << PSR_ICC_SHIFT) | (m_ec ? PSR_EC_MASK : 0) | (m_ef ? PSR_EF_MASK : 0) | (m_pil << PSR_PIL_SHIFT) | (m_s ? PSR_S_MASK : 0) | (m_ps ? PSR_PS_MASK : 0) | (m_et ? PSR_ET_MASK : 0) | m_cwp; } while(0)
#define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; } while(0) #define BREAK_PSR do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; m_ec = m_psr & PSR_EC_MASK; m_ef = m_psr & PSR_EF_MASK; m_pil = (m_psr & PSR_PIL_MASK) >> PSR_PIL_SHIFT; m_s = m_psr & PSR_S_MASK; m_ps = m_psr & PSR_PS_MASK; m_et = m_psr & PSR_ET_MASK; m_cwp = m_psr & PSR_CWP_MASK; } while(0)
#define MAKE_ICC do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; } while(0) #define MAKE_ICC do { m_icc = (m_psr & PSR_ICC_MASK) >> PSR_ICC_SHIFT; } while(0)
#define CWP m_cwp
#define S m_s
#define PS m_ps
#define IS_SUPERVISOR (m_psr & PSR_S_MASK) #define IS_SUPERVISOR (m_psr & PSR_S_MASK)
#define IS_USER (!IS_SUPERVISOR) #define IS_USER (!IS_SUPERVISOR)
@ -145,11 +140,6 @@
#define Y m_y #define Y m_y
#define ET m_et
#define EF m_ef
#define EC m_ec
#define PIL m_pil
#define MAE m_mae #define MAE m_mae
#define HOLD_BUS m_hold_bus #define HOLD_BUS m_hold_bus

View File

@ -7,9 +7,64 @@
// //
//================================================================ //================================================================
void mb86901_device::log_fcodes()
{
if (PC != 0xffef0000 && PC != m_ss1_next_entry_point)
return;
if (PC == 0xffef0000)
{
UINT32 opcode = read_sized_word(11, REG(5), 2);
if (!(REG(5) & 2))
{
opcode >>= 16;
}
if (opcode == 0x4627)
{
m_log_fcodes = true;
//machine().debugger().debug_break();
}
else if (!m_log_fcodes)
{
return;
}
else if (opcode == 0x0cb8)
{
m_log_fcodes = false;
}
UINT32 handler_base = opcode << 2;
handler_base += REG(2); // l1 = r2 + opcode << 2
UINT32 entry_point = read_sized_word(11, handler_base, 2);
if (!(handler_base & 2))
{
entry_point >>= 16;
}
entry_point <<= 2;
entry_point += REG(2); // l0 = r2 + entry_point << 2
disassemble_ss1_fcode(REG(5), opcode, handler_base, entry_point, REG(7));
}
else if (PC == m_ss1_next_entry_point && m_log_fcodes)
{
disassemble_ss1_fcode(m_ss1_next_pc, m_ss1_next_opcode, m_ss1_next_handler_base, m_ss1_next_entry_point, m_ss1_next_stack);
m_ss1_next_pc = ~0;
m_ss1_next_opcode = ~0;
m_ss1_next_handler_base = ~0;
m_ss1_next_entry_point = ~0;
m_ss1_next_stack = ~0;
}
}
void mb86901_device::indent() void mb86901_device::indent()
{ {
UINT32 program_depth = (0xffeff000 - (REG(6) - 4)) / 4; UINT32 program_depth = (0xffeff000 - (REG(6) - 4)) / 4;
if (program_depth < 15)
return;
program_depth -= 15;
for (int i = 0; i < program_depth; i++) for (int i = 0; i < program_depth; i++)
{ {
printf(" "); printf(" ");
@ -18,18 +73,72 @@ void mb86901_device::indent()
void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 handler_base, UINT32 entry_point, UINT32 stack) void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 handler_base, UINT32 entry_point, UINT32 stack)
{ {
std::string opdesc = m_ss1_fcode_table[opcode & ~1]; std::string opdesc = m_ss1_fcode_table[opcode];
if (opdesc.length() == 0) if (opdesc.length() == 0)
opdesc = "[unknown]"; opdesc = "[unknown]";
indent(); printf("\n");
indent(); printf("Stacks before this forth code:\n");
indent(); printf("Data Return\n");
indent(); printf("-------- --------\n");
UINT32 data_stack[8];
UINT32 return_stack[8];
UINT32 data_entries = (0xffefebe4 - (stack - 4)) / 4;
UINT32 return_entries = (0xffeff000 - (REG(6) - 4)) / 4;
data_stack[0] = REG(4);
for (int i = 0; i < data_entries && i < 7; i++)
{
data_stack[i + 1] = read_sized_word(11, REG(7) + i * 4, 4);
}
data_entries++;
for (int i = 0; i < return_entries && i < 8; i++)
{
return_stack[i] = read_sized_word(11, REG(6) + i * 4, 4);
}
UINT32 total_lines = 0;
if (data_entries > total_lines)
total_lines = data_entries;
if (return_entries > total_lines)
total_lines = return_entries;
if (total_lines > 8)
total_lines = 8;
for (int i = 0; i < total_lines; i++)
{
indent();
if (i < data_entries)
printf("%08x", data_stack[i]);
else
printf(" ");
if (i < return_entries)
printf(" %08x\n", return_stack[i]);
else
printf("\n");
}
UINT32 base = 0xffe87954;
UINT32 exact_op = (r5 - base) / 4;
UINT32 base_op = exact_op;
while (m_ss1_fcode_table[base_op].length() == 0)
base_op--;
UINT32 dist = (exact_op - base_op) * 4;
if (entry_point == 0xffe87964) if (entry_point == 0xffe87964)
{ {
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; call %08x\n", r5, opcode, entry_point, opdesc.c_str(), handler_base + 2); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; call %08x\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), handler_base + 2);
indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4); indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4);
} }
else if (entry_point == 0xffe87974) else if (entry_point == 0xffe87974)
{ {
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push handler_base+2 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), handler_base + 2); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push handler_base+2 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), handler_base + 2);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
} }
else if (entry_point == 0xffe8799c) else if (entry_point == 0xffe8799c)
@ -38,7 +147,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 half = read_sized_word(11, address, 2); UINT32 half = read_sized_word(11, address, 2);
if (!(address & 2)) half >>= 16; if (!(address & 2)) half >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; add halfword at handler_base+2 (%04x) to VM base pointer (%08x) and push onto stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), half, REG(3), REG(3) + half); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; add halfword at handler_base+2 (%04x) to VM base pointer (%08x) and push onto stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), half, REG(3), REG(3) + half);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
} }
else if (entry_point == 0xffe879e4) else if (entry_point == 0xffe879e4)
@ -53,7 +162,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = half0 | half1; UINT32 value = half0 | half1;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push immediate word from handler table (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push immediate word from handler table (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
} }
else if (entry_point == 0xffe879c4) else if (entry_point == 0xffe879c4)
@ -72,7 +181,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 dest = REG(2) + (l0_2 << 2); UINT32 dest = REG(2) + (l0_2 << 2);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; SPARC branch to %08x, calcs: g2(%08x) + halfword[g2(%04x) + (halfword[g3(%08x) + halfword[entry_point(%04x) + 2](%04x)](%04x) << 2)](%08x)\n", r5, opcode, entry_point, opdesc.c_str(), dest, REG(2), REG(2), REG(3), handler_base, l0, handler_base_2, l0_2); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; SPARC branch to %08x, calcs: g2(%08x) + halfword[g2(%04x) + (halfword[g3(%08x) + halfword[entry_point(%04x) + 2](%04x)](%04x) << 2)](%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), dest, REG(2), REG(2), REG(3), handler_base, l0, handler_base_2, l0_2);
indent(); printf(" // target func: %08x\n", l0_2 << 2); indent(); printf(" // target func: %08x\n", l0_2 << 2);
switch (l0_2 << 2) switch (l0_2 << 2)
{ {
@ -97,7 +206,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = half0 | half1; UINT32 value = half0 | half1;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; add 32-bit word (%08x) from handler table to top of stack (%08x + %08x = %08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), value, REG(4) + value); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; add 32-bit word (%08x) from handler table to top of stack (%08x + %08x = %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), value, REG(4) + value);
} }
else else
{ {
@ -115,7 +224,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = half0 | half1; UINT32 value = half0 | half1;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push immediate word from instructions (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push immediate word from instructions (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
} }
@ -126,7 +235,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = read_sized_word(11, address, 2); UINT32 value = read_sized_word(11, address, 2);
if (!(address & 2)) value >>= 16; if (!(address & 2)) value >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push immediate halfword from instructions (%04x)\n", r5, opcode, entry_point, opdesc.c_str(), value); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push immediate halfword from instructions (%04x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
} }
@ -137,7 +246,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 new_opcode = read_sized_word(11, address, 2); UINT32 new_opcode = read_sized_word(11, address, 2);
if (!(address & 2)) new_opcode >>= 16; if (!(address & 2)) new_opcode >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop stack top (%08x) as an opcode to execute\n", r5, opcode, entry_point, opdesc.c_str(), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop stack top (%08x) as an opcode to execute\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
indent(); printf(" // inserted opcode:\n"); indent(); printf(" // inserted opcode:\n");
@ -163,7 +272,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
if (!(address & 2)) pc_offset >>= 16; if (!(address & 2)) pc_offset >>= 16;
// advance program counter by amount specified as parameter // advance program counter by amount specified as parameter
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; advance program counter by amount specified as parameter (%08x = %08x + %04x)\n", r5, opcode, entry_point, opdesc.c_str(), r5 + 2 + pc_offset, r5 + 2, pc_offset); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; advance program counter by amount specified as parameter (%08x = %08x + %04x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), r5 + 2 + pc_offset, r5 + 2, pc_offset);
break; break;
} }
@ -175,7 +284,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 target = r5 + 2 + offset; UINT32 target = r5 + 2 + offset;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop data stack top (%08x) and if zero, jump to %08x\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), target); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop data stack top (%08x) and if zero, jump to %08x\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, REG(7), 4), target);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -192,7 +301,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
if (!(address & 2)) offset >>= 16; if (!(address & 2)) offset >>= 16;
UINT32 target = r5 + 2 + offset; UINT32 target = r5 + 2 + offset;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop data stack top and add to program stack top (%08x = %08x + %08x)\n", r5, opcode, entry_point, opdesc.c_str(), result, value, r4); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop data stack top and add to program stack top (%08x = %08x + %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), result, value, r4);
indent(); printf(" // if no addition overflow, jump to %08x\n", target); indent(); printf(" // if no addition overflow, jump to %08x\n", target);
indent(); printf(" // if addition overflow, pop 3 words off program stack\n"); indent(); printf(" // if addition overflow, pop 3 words off program stack\n");
if (arithmetic_overflow) if (arithmetic_overflow)
@ -218,7 +327,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 target = r5 + 2 + offset; UINT32 target = r5 + 2 + offset;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; branch relative to %08x if data stack second (%08x) == data stack top (%08x), pop_data result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), target, l0_2, handler_base_2, popped_g4); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; branch relative to %08x if data stack second (%08x) == data stack top (%08x), pop_data result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), target, l0_2, handler_base_2, popped_g4);
if (handler_base_2 == l0_2) if (handler_base_2 == l0_2)
{ {
indent(); printf(" // branch will be taken\n"); indent(); printf(" // branch will be taken\n");
@ -240,7 +349,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
{ {
UINT32 word0 = read_sized_word(11, REG(6), 4); UINT32 word0 = read_sized_word(11, REG(6), 4);
UINT32 word1 = read_sized_word(11, REG(6) + 4, 4); UINT32 word1 = read_sized_word(11, REG(6) + 4, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) to data stack, add the top two values on the program stack, store in result (%08x = %08x + %08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), word0 + word1, word0, word1); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) to data stack, add the top two values on the program stack, store in result (%08x = %08x + %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), word0 + word1, word0, word1);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
} }
@ -249,7 +358,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
{ {
UINT32 address = stack; UINT32 address = stack;
UINT32 word = read_sized_word(11, address, 4); UINT32 word = read_sized_word(11, address, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; logical-AND result with data stack pop, store in result (%08x = %08x & %08x)\n", r5, opcode, entry_point, opdesc.c_str(), word & REG(4), word, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; logical-AND result with data stack pop, store in result (%08x = %08x & %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), word & REG(4), word, REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -258,20 +367,20 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
{ {
UINT32 address = stack; UINT32 address = stack;
UINT32 word = read_sized_word(11, address, 4); UINT32 word = read_sized_word(11, address, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; logical-OR result with data stack pop, store in result: %08x = %08x & %08x\n", r5, opcode, entry_point, opdesc.c_str(), word | REG(4), word, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; logical-OR result with data stack pop, store in result: %08x = %08x & %08x\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), word | REG(4), word, REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
case 0x0136: case 0x0136:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; invert result (%08x -> %08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), REG(4) ^ 0xffffffff); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; invert result (%08x -> %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), REG(4) ^ 0xffffffff);
break; break;
case 0x014f: case 0x014f:
{ {
UINT32 address = stack; UINT32 address = stack;
UINT32 word = read_sized_word(11, address, 4); UINT32 word = read_sized_word(11, address, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; add result to data stack pop, store in result: %08x = %08x + %08x\n", r5, opcode, entry_point, opdesc.c_str(), word + REG(4), word, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; add result to data stack pop, store in result: %08x = %08x + %08x\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), word + REG(4), word, REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -280,30 +389,30 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
{ {
UINT32 address = stack; UINT32 address = stack;
UINT32 word = read_sized_word(11, address, 4); UINT32 word = read_sized_word(11, address, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; subtract result from data stack pop, store in result: %08x = %08x - %08x\n", r5, opcode, entry_point, opdesc.c_str(), word - REG(4), word, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; subtract result from data stack pop, store in result: %08x = %08x - %08x\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), word - REG(4), word, REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
case 0x017f: case 0x017f:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack, set result to address of opcode dispatcher\n", r5, opcode, entry_point, opdesc.c_str(), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack, set result to address of opcode dispatcher\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x01a9: case 0x01a9:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto program stack, pop result from data stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto program stack, pop result from data stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4));
indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4); indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
case 0x01b1: case 0x01b1:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack, pop result from program stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, REG(6), 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack, pop result from program stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, REG(6), 4));
indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) + 4, (0xffeff000 - (REG(6) + 4)) / 4); indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) + 4, (0xffeff000 - (REG(6) + 4)) / 4);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x01b9: case 0x01b9:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack, assign program stack top to result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, REG(6), 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack, assign program stack top to result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, REG(6), 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
@ -320,29 +429,29 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = half0 | half1; UINT32 value = half0 | half1;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; return (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; return (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value);
indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) + 4, (0xffeff000 - (REG(6) + 4)) / 4); indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) + 4, (0xffeff000 - (REG(6) + 4)) / 4);
break; break;
} }
case 0x01cd: case 0x01cd:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; insert result (%08x) between data stack top (%08x) and next data stack entry\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; insert result (%08x) between data stack top (%08x) and next data stack entry\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x01d5: case 0x01d5:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; throw away the word at the top of the data stack\n", r5, opcode, entry_point, opdesc.c_str()); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; throw away the word at the top of the data stack\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str());
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
case 0x01f4: case 0x01f4:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if result (%08x) >= 0, set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), (REG(4) >= 0) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if result (%08x) >= 0, set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), (REG(4) >= 0) ? 0 : ~0);
break; break;
case 0x0217: case 0x0217:
{ {
UINT32 value = read_sized_word(11, stack, 4); UINT32 value = read_sized_word(11, stack, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if pop_data (%08x) >= result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), (value >= REG(4)) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if pop_data (%08x) >= result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), (value >= REG(4)) ? 0 : ~0);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -350,7 +459,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
case 0x022b: case 0x022b:
{ {
UINT32 value = read_sized_word(11, stack, 4); UINT32 value = read_sized_word(11, stack, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if pop_data (%08x) != result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), (value != REG(4)) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if pop_data (%08x) != result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), (value != REG(4)) ? 0 : ~0);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -358,7 +467,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
case 0x0236: case 0x0236:
{ {
UINT32 value = read_sized_word(11, stack, 4); UINT32 value = read_sized_word(11, stack, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if pop_data (%08x) == result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), (value == REG(4)) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if pop_data (%08x) == result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), (value == REG(4)) ? 0 : ~0);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -366,7 +475,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
case 0x026d: case 0x026d:
{ {
UINT32 value = read_sized_word(11, stack, 4); UINT32 value = read_sized_word(11, stack, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if pop_data (%08x) < result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), (value < REG(4)) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if pop_data (%08x) < result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), (value < REG(4)) ? 0 : ~0);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
@ -374,61 +483,61 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
case 0x0278: case 0x0278:
{ {
UINT32 value = read_sized_word(11, stack, 4); UINT32 value = read_sized_word(11, stack, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if pop_data (%08x) > result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4), (value > REG(4)) ? 0 : ~0); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if pop_data (%08x) > result (%08x), set result to 0, otherwise -1 (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4), (value > REG(4)) ? 0 : ~0);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (stack + 4)) / 4);
break; break;
} }
case 0x0289: case 0x0289:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) to data stack\n", r5, opcode, entry_point, opdesc.c_str(), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) to data stack\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x0283: case 0x0283:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop result from data stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop result from data stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4));
break; break;
case 0x028f: case 0x028f:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack, assign previous top (%08x) to result\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack, assign previous top (%08x) to result\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x0296: case 0x0296:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; swap result (%08x) with top of data stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; swap result (%08x) with top of data stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4));
break; break;
case 0x029d: case 0x029d:
{ {
UINT32 top = read_sized_word(11, stack, 4); UINT32 top = read_sized_word(11, stack, 4);
UINT32 next = read_sized_word(11, stack + 4, 4); UINT32 next = read_sized_word(11, stack + 4, 4);
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; swap the top two values of the data stack (%08x <-> %08x), exchange second value with result (%08x <-> %08x)\n", r5, opcode, entry_point, opdesc.c_str(), top, next, REG(4), next); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; swap the top two values of the data stack (%08x <-> %08x), exchange second value with result (%08x <-> %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), top, next, REG(4), next);
break; break;
} }
case 0x02af: case 0x02af:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop_data to throw away data_top, then pop_data into result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack + 4, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop_data to throw away data_top, then pop_data into result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack + 4, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4);
break; break;
case 0x02b6: case 0x02b6:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; duplicate top of data stack (%08x) and push the result (%08x) in between\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; duplicate top of data stack (%08x) and push the result (%08x) in between\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 8, (0xffefebe4 - (REG(7) - 8)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 8, (0xffefebe4 - (REG(7) - 8)) / 4);
break; break;
case 0x02e2: case 0x02e2:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; load result with value on data stack (%08x) indexed by result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack + (REG(4) << 2), 4), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; load result with value on data stack (%08x) indexed by result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack + (REG(4) << 2), 4), REG(4));
break; break;
case 0x02f2: case 0x02f2:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; decrement result (%08x = %08x - 1)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4) - 1, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; decrement result (%08x = %08x - 1)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4) - 1, REG(4));
break; break;
case 0x0306: case 0x0306:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; shift result left by 1 bit (%08x = %08x << 1)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4) << 1, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; shift result left by 1 bit (%08x = %08x << 1)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4) << 1, REG(4));
break; break;
case 0x031e: case 0x031e:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; store 0 at address contained by result (%08x), pop word from data stack into result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; store 0 at address contained by result (%08x), pop word from data stack into result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), read_sized_word(11, stack, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (REG(7) + 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 4, (0xffefebe4 - (REG(7) + 4)) / 4);
break; break;
@ -444,7 +553,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 value = half0 | half1; UINT32 value = half0 | half1;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; load result with word (%08x) at result address (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; load result with word (%08x) at result address (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4));
break; break;
} }
@ -453,7 +562,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 address = REG(4); UINT32 address = REG(4);
UINT32 value = read_sized_word(11, address, 2); UINT32 value = read_sized_word(11, address, 2);
if (!(address & 2)) value >>= 16; if (!(address & 2)) value >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; load result with unsigned halfword (%04x) at result address (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; load result with unsigned halfword (%04x) at result address (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4));
break; break;
} }
@ -462,32 +571,32 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 address = REG(4); UINT32 address = REG(4);
UINT32 value = read_sized_word(11, address, 1); UINT32 value = read_sized_word(11, address, 1);
value >>= (3 - (address & 3)) * 8; value >>= (3 - (address & 3)) * 8;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; load result with unsigned byte (%02x) at result address (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), value, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; load result with unsigned byte (%02x) at result address (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), value, REG(4));
break; break;
} }
case 0x0381: case 0x0381:
case 0x0382: case 0x0382:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop_data (%08x) into address contained by result (%08x), pop_data (%08x) into result\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), REG(4), read_sized_word(11, stack + 4, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop_data (%08x) into address contained by result (%08x), pop_data (%08x) into result\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), REG(4), read_sized_word(11, stack + 4, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4);
break; break;
case 0x045a: case 0x045a:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop word from data stack and add it to result << 2, (%08x = %08x + (%08x << 2))\n", r5, opcode, entry_point, opdesc.c_str(), (REG(4) << 2) + read_sized_word(11, stack, 4), read_sized_word(11, stack, 4), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop word from data stack and add it to result << 2, (%08x = %08x + (%08x << 2))\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), (REG(4) << 2) + read_sized_word(11, stack, 4), read_sized_word(11, stack, 4), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x0462: case 0x0462:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop word from data stack and add it to result << 1, (%08x = %08x + (%08x << 1))\n", r5, opcode, entry_point, opdesc.c_str(), (REG(4) << 1) + read_sized_word(11, stack, 4), read_sized_word(11, stack, 4), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop word from data stack and add it to result << 1, (%08x = %08x + (%08x << 1))\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), (REG(4) << 1) + read_sized_word(11, stack, 4), read_sized_word(11, stack, 4), REG(4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x046a: case 0x046a:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; increment result (%08x = %08x + 1\n", r5, opcode, entry_point, opdesc.c_str(), REG(4) + 1, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; increment result (%08x = %08x + 1\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4) + 1, REG(4));
break; break;
case 0x047e: case 0x047e:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; add 2 to result (%08x = %08x + 2\n", r5, opcode, entry_point, opdesc.c_str(), REG(4) + 2, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; add 2 to result (%08x = %08x + 2\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4) + 2, REG(4));
break; break;
case 0x04ff: case 0x04ff:
@ -496,7 +605,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 next_op = read_sized_word(11, address, 2); UINT32 next_op = read_sized_word(11, address, 2);
if (!(address & 2)) next_op >>= 16; if (!(address & 2)) next_op >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push_data result (%08x), load result with entry_point for next opcode (%08x = %08x + %08x, op %04x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), REG(2) + (next_op << 2), REG(2), next_op << 2, next_op); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push_data result (%08x), load result with entry_point for next opcode (%08x = %08x + %08x, op %04x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), REG(2) + (next_op << 2), REG(2), next_op << 2, next_op);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
} }
@ -506,7 +615,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 byte_addr = read_sized_word(11, REG(6), 4); UINT32 byte_addr = read_sized_word(11, REG(6), 4);
UINT32 address_shift = (3 - (byte_addr & 3)) * 8; UINT32 address_shift = (3 - (byte_addr & 3)) * 8;
UINT8 value = read_sized_word(11, byte_addr, 1) >> address_shift; UINT8 value = read_sized_word(11, byte_addr, 1) >> address_shift;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack\n", r5, opcode, entry_point, opdesc.c_str(), REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4));
indent(); printf(" // load result with byte pointed to by top of program stack (%02x)\n", value); indent(); printf(" // load result with byte pointed to by top of program stack (%02x)\n", value);
indent(); printf(" // push address of next byte (%08x) onto data stack\n", byte_addr + 1); indent(); printf(" // push address of next byte (%08x) onto data stack\n", byte_addr + 1);
indent(); printf(" // add (result + 3) to program_top and clear the low bit (now %08x)\n", (byte_addr + value + 3) & ~1); indent(); printf(" // add (result + 3) to program_top and clear the low bit (now %08x)\n", (byte_addr + value + 3) & ~1);
@ -521,7 +630,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 g2_offset = read_sized_word(11, address, 2); UINT32 g2_offset = read_sized_word(11, address, 2);
if (!(address & 2)) g2_offset >>= 16; if (!(address & 2)) g2_offset >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; add halfword at address in result (%08x) to forth table base pointer (%08x) and store in result (%08x = %08x + %08x)\n", r5, opcode, entry_point, opdesc.c_str(), address, REG(2), REG(2) + g2_offset, REG(2), g2_offset); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; add halfword at address in result (%08x) to forth table base pointer (%08x) and store in result (%08x = %08x + %08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), address, REG(2), REG(2) + g2_offset, REG(2), g2_offset);
break; break;
} }
@ -531,7 +640,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 next_op = read_sized_word(11, address, 2); UINT32 next_op = read_sized_word(11, address, 2);
if (!(address & 2)) next_op >>= 16; if (!(address & 2)) next_op >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; load result with entry_point for opcode (%08x = %08x + %08x, op %04x) pointed to by result (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), REG(2) + (next_op << 2), REG(2), next_op << 2, next_op, REG(4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; load result with entry_point for opcode (%08x = %08x + %08x, op %04x) pointed to by result (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(2) + (next_op << 2), REG(2), next_op << 2, next_op, REG(4));
break; break;
} }
@ -540,7 +649,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
{ {
UINT32 stack_top = read_sized_word(11, stack, 4); UINT32 stack_top = read_sized_word(11, stack, 4);
UINT32 new_opcode = (stack_top - REG(2)) >> 2; UINT32 new_opcode = (stack_top - REG(2)) >> 2;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop word (%08x) from the data stack, turn it into a 16-bit opcode (%04x)\n", r5, opcode, entry_point, opdesc.c_str(), stack_top, new_opcode); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop word (%08x) from the data stack, turn it into a 16-bit opcode (%04x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), stack_top, new_opcode);
indent(); printf(" // store the opcode at the address contained in the result (%08x)\n", REG(4)); indent(); printf(" // store the opcode at the address contained in the result (%08x)\n", REG(4));
indent(); printf(" // pop word from the data stack into to the result (%08x)\n", read_sized_word(11, stack + 4, 4)); indent(); printf(" // pop word from the data stack into to the result (%08x)\n", read_sized_word(11, stack + 4, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 8, (0xffefebe4 - (stack + 8)) / 4);
@ -548,12 +657,12 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
} }
case 0x05fe: case 0x05fe:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) onto data stack, load base pointer of Fcode table (%08x) into result\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), REG(2)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) onto data stack, load base pointer of Fcode table (%08x) into result\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), REG(2));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x0613: case 0x0613:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; if result (%08x) is equal to g2 (%08x), push result to data stack and load with 0, else push nothing and load with ~0\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), REG(2)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; if result (%08x) is equal to g2 (%08x), push result to data stack and load with 0, else push nothing and load with ~0\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), REG(2));
if (REG(4) == REG(2)) if (REG(4) == REG(2))
{ {
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
@ -562,7 +671,7 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
case 0x0668: case 0x0668:
{ {
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; some complex junk I don't understand, the amount of asm in this function is a PITA.\n", r5, opcode, entry_point, opdesc.c_str()); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; some complex junk I don't understand, the amount of asm in this function is a PITA.\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str());
indent(); printf(" // basically it involves a bunch of comparisons between whatever's on the top of the stack, the\n"); indent(); printf(" // basically it involves a bunch of comparisons between whatever's on the top of the stack, the\n");
indent(); printf(" // current result, and some other weird junk like 0x20000000\n"); indent(); printf(" // current result, and some other weird junk like 0x20000000\n");
indent(); printf(" // like seriously, this function is a couple hundred lines of asm long\n"); indent(); printf(" // like seriously, this function is a couple hundred lines of asm long\n");
@ -570,13 +679,13 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
} }
case 0x3d38: case 0x3d38:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; call ffe8fe90\n", r5, opcode, entry_point, opdesc.c_str()); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; call ffe8fe90\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str());
indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4); indent(); printf(" // program stack now %08x (%d words deep)\n", REG(6) - 4, (0xffeff000 - (REG(6) - 4)) / 4);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
case 0x3fd2: case 0x3fd2:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; pop address from data stack (%08x), pop data from data stack (%08x)\n", r5, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), read_sized_word(11, stack + 4, 4)); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; pop address from data stack (%08x), pop data from data stack (%08x)\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), read_sized_word(11, stack, 4), read_sized_word(11, stack + 4, 4));
indent(); printf(" // address at ASI specified by result (%d), then pop word from data stack (%08x) into result\n", REG(4), read_sized_word(11, stack + 8, 4)); indent(); printf(" // address at ASI specified by result (%d), then pop word from data stack (%08x) into result\n", REG(4), read_sized_word(11, stack + 8, 4));
indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 12, (0xffefebe4 - (stack + 12)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack + 12, (0xffefebe4 - (stack + 12)) / 4);
break; break;
@ -591,14 +700,14 @@ void mb86901_device::disassemble_ss1_fcode(UINT32 r5, UINT32 opcode, UINT32 hand
UINT32 new_result = read_sized_word(11, address, 2); UINT32 new_result = read_sized_word(11, address, 2);
if (!(address & 2)) new_result >>= 16; if (!(address & 2)) new_result >>= 16;
indent(); printf("Opcode at %08x: %04x, entry is at %08x // %s ; push result (%08x) to data stack, load halfword (%04x) from handler table\n", r5, opcode, entry_point, opdesc.c_str(), REG(4), g3_offset); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s ; push result (%08x) to data stack, load halfword (%04x) from handler table\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str(), REG(4), g3_offset);
indent(); printf(" // use g3 (%08x) plus first halfword as the address (%08x) from which to load a halfword (%04x) into result\n", REG(3), address, new_result); indent(); printf(" // use g3 (%08x) plus first halfword as the address (%08x) from which to load a halfword (%04x) into result\n", REG(3), address, new_result);
indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4); indent(); printf(" // data stack now %08x (%d words deep)\n", stack - 4, (0xffefebe4 - (stack - 4)) / 4);
break; break;
} }
default: default:
indent(); printf("Opcode at %08x: %04x, entry is at %08x // unknown\n", r5, opcode, entry_point); indent(); printf("Opcode at %08x (%04x + %x): %04x, entry is at %08x // %s: unknown\n", r5, base_op, dist, opcode, entry_point, opdesc.c_str());
break; break;
} }
} }