tms32082: MP interrupts + more PP disasm work (nw)

This commit is contained in:
Ville Linde 2013-08-09 17:20:05 +00:00
parent 633d639623
commit 8f09c447d2
4 changed files with 262 additions and 38 deletions

View File

@ -83,10 +83,14 @@ static char *format_address_mode(int mode, int areg, int s, int limx)
static void format_transfer(UINT64 op)
{
char buffer[128];
char *b = buffer;
int lmode = (op >> 35) & 0xf;
int gmode = (op >> 13) & 0xf;
print(" || ");
bool is_nop = false;
memset(buffer, 0, sizeof(char)*128);
switch (lmode)
{
@ -109,8 +113,8 @@ static void format_transfer(UINT64 op)
int dreg = (dstbank << 3) | dst;
int sreg = (srcbank << 3) | src;
print("%s", CONDITION_CODES[cond]);
print("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]);
b += sprintf(b, "%s", CONDITION_CODES[cond]);
b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]);
break;
}
case 0x01: // Format 8: Conditional DU ||Conditional Field Move
@ -125,8 +129,8 @@ static void format_transfer(UINT64 op)
int dreg = (dstbank << 3) | dst;
int sreg = (4 << 3) | src;
print("%s", CONDITION_CODES[cond]);
print("%s = [%s:%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]);
b += sprintf(b, "%s", CONDITION_CODES[cond]);
b += sprintf(b, "%s = [%s%d]%s", REG_NAMES[dreg], TRANSFER_SIZE[size], itm, REG_NAMES[sreg]);
break;
}
case 0x02: case 0x03: // Format 10: Conditional Non-D Data Unit
@ -139,14 +143,14 @@ static void format_transfer(UINT64 op)
int dreg = (adstbank << 3) | dst;
int sreg = (as1bank << 3) | src;
if (dreg == 0x20 && sreg == 0x20)
if (dreg == sreg)
{
print("nop");
is_nop = true;
}
else
{
print("%s", CONDITION_CODES[cond]);
print("%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]);
b += sprintf(b, "%s", CONDITION_CODES[cond]);
b += sprintf(b, "%s = %s", REG_NAMES[dreg], REG_NAMES[sreg]);
}
break;
}
@ -154,8 +158,25 @@ static void format_transfer(UINT64 op)
{
if (op & 0x4) // Format 9: Conditional DU || Conditional Global
{
print("%s", CONDITION_CODES[cond]);
print("cond du||cond global");
int bank = (op >> 18) & 0xf;
int le = ((op >> 16) & 2) | ((op >> 9) & 1);
int size = (op >> 7) & 0x3;
int s = (op & (1 << 6));
int reg = (op >> 10) & 0x7;
int ga = (op >> 3) & 0x7;
int gimx = (op >> 22) & 0x7;
int greg = (bank << 3) | reg;
b += sprintf(b, "%s", CONDITION_CODES[cond]);
switch (le)
{
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx), REG_NAMES[greg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, gimx)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, gimx)); break;
}
}
else // Format 5: Global (Long Offset)
{
@ -176,10 +197,10 @@ static void format_transfer(UINT64 op)
switch (le)
{
case 0: print("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break;
case 1: print("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break;
case 2: print("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break;
case 3: print("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break;
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset), REG_NAMES[greg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, s, offset)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[size], format_address_mode(gmode, ga, s, offset)); break;
}
}
break;
@ -196,17 +217,32 @@ static void format_transfer(UINT64 op)
{
case 0x00: // Format 2: Move || Local
{
print("move||local");
b += sprintf(b, "move||local <TODO>");
break;
}
case 0x01: // Format 3: Field Move || Local
{
print("field move||local");
b += sprintf(b, "field move||local <TODO>");
break;
}
case 0x02: case 0x03: // Format 6: Non-D DU || Local
{
print("non-d du||local");
int d = (op >> 32) & 0x7;
int s = (op & (1 << 28));
int size = (op >> 29) & 0x3;
int le = ((op >> 16) & 2) | ((op >> 31) & 1);
int la = (op >> 25) & 0x7;
int limx = op & 0x7;
int reg = (4 << 3) | d;
switch (le)
{
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx), REG_NAMES[reg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, limx)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, limx)); break;
}
break;
}
case 0x10: case 0x11: case 0x12: case 0x13: // Format 4: Local (Long Offset)
@ -234,10 +270,10 @@ static void format_transfer(UINT64 op)
switch (le)
{
case 0: print("&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break;
case 1: print("%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break;
case 2: print("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break;
case 3: print("%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break;
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset), REG_NAMES[reg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[reg], format_address_mode(lmode, la, s, offset)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[reg], TRANSFER_SIZE[size], format_address_mode(lmode, la, s, offset)); break;
}
break;
}
@ -265,10 +301,10 @@ static void format_transfer(UINT64 op)
// local transfer
switch (local_le)
{
case 0: print("&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break;
case 1: print("%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break;
case 2: print("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break;
case 3: print("%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break;
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx), REG_NAMES[lreg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[lreg], format_address_mode(lmode, la, local_s, local_imx)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[lreg], TRANSFER_SIZE[local_size], format_address_mode(lmode, la, local_s, local_imx)); break;
}
print(", ");
@ -276,16 +312,19 @@ static void format_transfer(UINT64 op)
// global transfer
switch (global_le)
{
case 0: print("&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break;
case 1: print("%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break;
case 2: print("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break;
case 3: print("%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break;
case 0: b += sprintf(b, "&%s%s = %s", TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx), REG_NAMES[greg]); break;
case 1: b += sprintf(b, "%s = %s", REG_NAMES[greg], format_address_mode(gmode, ga, global_s, global_imx)); break;
case 2: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break;
case 3: b += sprintf(b, "%s = &%s%s", REG_NAMES[greg], TRANSFER_SIZE[global_size], format_address_mode(gmode, ga, global_s, global_imx)); break;
}
break;
}
}
}
}
if (!is_nop)
print(" || %s", buffer);
}
static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_text, const char *b_text, const char *c_text)
@ -366,6 +405,10 @@ static void format_alu_op(int aluop, int a, const char *dst_text, const char *a_
print("%s = %s | %s", dst_text, a_text, b_text);
break;
case 0x44: // ~A & B & C | ~A & B & ~C = ~A & B
print("%s = ~%s & %s", dst_text, a_text, b_text);
break;
default:
print("%s = b%02X(%s, %s, %s)", dst_text, aluop, a_text, b_text, c_text);
break;
@ -386,7 +429,7 @@ static offs_t tms32082_disasm_pp(char *buffer, offs_t pc, const UINT8 *oprom)
case 0x6:
case 0x7: // Six-operand
{
print("A: six operand");
print("A: six operand <TODO>");
break;
}
@ -435,8 +478,22 @@ static offs_t tms32082_disasm_pp(char *buffer, offs_t pc, const UINT8 *oprom)
int aluop = (op >> 51) & 0xff;
int a = (op >> 59) & 1;
int s1reg = src1 | (0x4 << 3);
int dreg = dst | (0x4 << 3);
int adstbank;
int as1bank;
if ((op & 0x0101c000) == 0x00004000)
{
adstbank = (op >> 18) & 0xf;
as1bank = (op >> 6) & 0xf;
}
else
{
adstbank = 4;
as1bank = 4;
}
int s1reg = src1 | (as1bank << 3);
int dreg = dst | (adstbank << 3);
int dstcreg = dst | (0x4 << 3);
sprintf(dst_text, "%s", REG_NAMES[dreg]);
@ -500,10 +557,24 @@ static offs_t tms32082_disasm_pp(char *buffer, offs_t pc, const UINT8 *oprom)
int aluop = (op >> 51) & 0xff;
int a = (op >> 59) & 1;
int s1reg = src1 | (0x4 << 3);
int adstbank;
int as1bank;
if ((op & 0x0101c000) == 0x00004000)
{
adstbank = (op >> 18) & 0xf;
as1bank = (op >> 6) & 0xf;
}
else
{
adstbank = 4;
as1bank = 4;
}
int s1reg = src1 | (as1bank << 3);
int s2reg = src2 | (0x4 << 3);
int dstcreg = dst | (0x4 << 3);
int dreg = dst | (0x4 << 3);
int dreg = dst | (adstbank << 3);
sprintf(dst_text, "%s", REG_NAMES[dreg]);
switch (cl)

View File

@ -751,7 +751,7 @@ void tms32082_mp_device::execute_reg_long_imm()
{
UINT32 data = has_imm ? imm32 : m_reg[OP_SRC1()];
printf("CMND %08X\n", data);
processor_command(data);
break;
}

View File

@ -135,6 +135,12 @@ void tms32082_mp_device::device_start()
save_item(NAME(m_fetchpc));
save_item(NAME(m_reg));
save_item(NAME(m_acc));
save_item(NAME(m_in0p));
save_item(NAME(m_in1p));
save_item(NAME(m_outp));
save_item(NAME(m_ie));
save_item(NAME(m_intpen));
// Register state for debugger
state_add(MP_PC, "pc", m_pc).formatstr("%08X");
@ -180,6 +186,8 @@ void tms32082_mp_device::device_start()
state_add(MP_IN0P, "in0p", m_in0p).formatstr("%08X");
state_add(MP_IN1P, "in1p", m_in1p).formatstr("%08X");
state_add(MP_OUTP, "outp", m_outp).formatstr("%08X");
state_add(MP_IE, "ie", m_ie).formatstr("%08X");
state_add(MP_INTPEN, "intpen", m_intpen).formatstr("%08X");
state_add(STATE_GENPC, "curpc", m_pc).noshow();
@ -215,12 +223,74 @@ void tms32082_mp_device::device_reset()
m_acc[1] = 0;
m_acc[2] = 0;
m_acc[3] = 0;
m_in0p = 0;
m_in1p = 0;
m_outp = 0;
m_intpen = 0;
m_ie = 0;
}
void tms32082_mp_device::processor_command(UINT32 command)
{
printf("MP CMND %08X: ", command);
if (command & 0x80000000)
printf("Reset ");
if (command & 0x40000000)
printf("Halt ");
if (command & 0x20000000)
printf("Unhalt ");
if (command & 0x10000000)
printf("ICR ");
if (command & 0x08000000)
printf("DCR ");
if (command & 0x00004000)
printf("Task ");
if (command & 0x00002000)
printf("Msg ");
printf("to: ");
if (command & 0x00000400)
printf("VC ");
if (command & 0x00000200)
printf("TC ");
if (command & 0x00000100)
printf("MP ");
if (command & 0x00000008)
printf("PP3 ");
if (command & 0x00000004)
printf("PP2 ");
if (command & 0x00000002)
printf("PP1 ");
if (command & 0x00000001)
printf("PP0 ");
printf("\n");
// PP0
if (command & 1)
{
if (command & 0x20004000)
{
// simulate PP behavior for now...
m_program->write_dword(0x00000084, 3);
}
}
}
UINT32 tms32082_mp_device::read_creg(int reg)
{
switch (reg)
{
case 0x4: // INTPEN
return m_intpen;
case 0x6: // IE
return m_ie;
case 0xa: // PPERROR
return 0xe0000;
@ -244,6 +314,21 @@ void tms32082_mp_device::write_creg(int reg, UINT32 data)
{
switch (reg)
{
case 0x4: // INTPEN
{
for (int i=0; i < 32; i++)
{
if (data & (1 << i))
m_intpen &= ~(1 << i);
}
break;
}
case 0x6: // IE
m_ie = data;
printf("IE = %08X\n", data);
break;
case 0x4000: // IN0P
m_in0p = data;
break;
@ -262,6 +347,54 @@ void tms32082_mp_device::write_creg(int reg, UINT32 data)
}
}
void tms32082_mp_device::check_interrupts()
{
if (m_ie & 1) // global interrupt mask
{
for (int i=1; i < 32; i++)
{
if (m_ie & m_intpen & (1 << i))
{
m_epc = (m_fetchpc & ~3);
m_epc |= (m_ie & 1); // save global interrupt mask
// TODO: user mode bit to EPC
m_eip = m_pc;
m_ie &= ~1; // clear global interrupt mask
// get new pc from vector table
m_fetchpc = m_pc = m_program->read_dword(0x01010180 + (i * 4));
return;
}
}
}
}
void tms32082_mp_device::execute_set_input(int inputnum, int state)
{
if (state == ASSERT_LINE)
{
switch (inputnum)
{
case INPUT_X1:
m_intpen |= (1 << 11);
break;
case INPUT_X2:
m_intpen |= (1 << 12);
break;
case INPUT_X3:
m_intpen |= (1 << 29);
break;
case INPUT_X4:
m_intpen |= (1 << 30);
break;
default:
break;
}
}
}
UINT32 tms32082_mp_device::fetch()
{
UINT32 w = m_direct->read_decrypted_dword(m_fetchpc);
@ -283,6 +416,9 @@ void tms32082_mp_device::execute_run()
while (m_icount > 0)
{
m_pc = m_fetchpc;
check_interrupts();
debugger_instruction_hook(this, m_pc);
m_ir = fetch();
@ -346,7 +482,7 @@ void tms32082_pp_device::state_string_export(const device_state_entry &entry, as
void tms32082_pp_device::device_reset()
{
m_pc = 0;
m_fetchpc = 0;
m_fetchpc = 0x400010a0;
}
void tms32082_pp_device::execute_run()

View File

@ -51,7 +51,17 @@ public:
MP_ACC3,
MP_IN0P,
MP_IN1P,
MP_OUTP
MP_OUTP,
MP_IE,
MP_INTPEN,
};
enum
{
INPUT_X1 = 1,
INPUT_X2 = 2,
INPUT_X3 = 3,
INPUT_X4 = 4,
};
DECLARE_READ32_MEMBER(mp_param_r);
@ -68,6 +78,7 @@ protected:
virtual UINT32 execute_max_cycles() const { return 1; }
virtual UINT32 execute_input_lines() const { return 0; }
virtual void execute_run();
virtual void execute_set_input(int inputnum, int state);
// device_memory_interface overrides
virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
@ -109,6 +120,10 @@ protected:
UINT32 m_in0p;
UINT32 m_in1p;
UINT32 m_outp;
UINT32 m_ie;
UINT32 m_intpen;
UINT32 m_epc;
UINT32 m_eip;
UINT32 *m_param_ram;
@ -117,6 +132,8 @@ protected:
address_space *m_program;
direct_read_data* m_direct;
void check_interrupts();
void processor_command(UINT32 command);
UINT32 fetch();
void delay_slot();
void execute();