mirror of
https://github.com/holub/mame
synced 2025-04-22 08:22:15 +03:00
nios2: Preliminary execution core and gdb support
This commit is contained in:
parent
04ac8329dc
commit
70deb80170
@ -4,7 +4,9 @@
|
||||
|
||||
Altera Nios II soft processor
|
||||
|
||||
Currently this device is just a stub with no actual execution core.
|
||||
Currently only a rudimentary execution core is provided. No attempt
|
||||
has been made yet to emulate correct timings, pipelining, cache
|
||||
control, interrupts, trap instructions, etc.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
@ -20,6 +22,7 @@ nios2_device::nios2_device(const machine_config &mconfig, const char *tag, devic
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 32, 32, 0)
|
||||
{
|
||||
std::fill(std::begin(m_gpr), std::end(m_gpr), 0);
|
||||
std::fill(std::begin(m_ctl), std::end(m_ctl), 0);
|
||||
}
|
||||
|
||||
std::unique_ptr<util::disasm_interface> nios2_device::create_disassembler()
|
||||
@ -34,8 +37,19 @@ device_memory_interface::space_config_vector nios2_device::memory_space_config()
|
||||
};
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
static const char *const s_ctl_names[16] =
|
||||
{
|
||||
"status", "estatus", "bstatus", "ienable", "ipending", "cpuid", "ctl6", "exception",
|
||||
"pteaddr", "tlbacc", "tlbmisc", "eccinj", "badaddr", "config", "mpubase", "mpuacc"
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
void nios2_device::device_start()
|
||||
{
|
||||
space(AS_PROGRAM).specific(m_space);
|
||||
space(AS_PROGRAM).cache(m_cache);
|
||||
|
||||
set_icountptr(m_icount);
|
||||
@ -43,20 +57,502 @@ void nios2_device::device_start()
|
||||
state_add(NIOS2_PC, "PC", m_pc);
|
||||
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
|
||||
for (int i = 1; i < 32; i++)
|
||||
state_add(NIOS2_R1 + i - 1, util::string_format("r%d", i).c_str(), m_gpr[i]);
|
||||
state_add<u32>(NIOS2_ZERO, "zero", []() { return 0; }).noshow();
|
||||
state_add(NIOS2_AT, "at", m_gpr[1]);
|
||||
for (int i = 2; i < 24; i++)
|
||||
state_add(NIOS2_R2 + i - 2, util::string_format("r%d", i).c_str(), m_gpr[i]);
|
||||
state_add(NIOS2_ET, "et", m_gpr[24]);
|
||||
state_add(NIOS2_BT, "bt", m_gpr[25]);
|
||||
state_add(NIOS2_GP, "gp", m_gpr[26]);
|
||||
state_add(NIOS2_SP, "sp", m_gpr[27]);
|
||||
state_add(NIOS2_FP, "fp", m_gpr[28]);
|
||||
state_add(NIOS2_EA, "ea", m_gpr[29]);
|
||||
state_add(NIOS2_BA, "ba", m_gpr[30]);
|
||||
state_add(NIOS2_RA, "ra", m_gpr[31]);
|
||||
for (int n = 0; n < 16; n++)
|
||||
state_add(NIOS2_STATUS + n, s_ctl_names[n], m_ctl[n]);
|
||||
|
||||
save_item(NAME(m_gpr));
|
||||
save_item(NAME(m_ctl));
|
||||
save_item(NAME(m_pc));
|
||||
}
|
||||
|
||||
void nios2_device::device_reset()
|
||||
{
|
||||
m_pc = 0;
|
||||
m_ctl[0] = 0; // clear status
|
||||
}
|
||||
|
||||
u32 nios2_device::read_ctl(unsigned r) const
|
||||
{
|
||||
if (r < std::size(m_ctl))
|
||||
return m_ctl[r];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void nios2_device::write_ctl(unsigned r, u32 val)
|
||||
{
|
||||
if (r < std::size(m_ctl))
|
||||
m_ctl[r] = val;
|
||||
}
|
||||
|
||||
void nios2_device::execute_run()
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
m_icount = 0;
|
||||
do
|
||||
{
|
||||
debugger_instruction_hook(m_pc);
|
||||
u32 inst = m_cache.read_dword(m_pc);
|
||||
|
||||
switch (BIT(inst, 0, 6))
|
||||
{
|
||||
case 0x00: // call
|
||||
m_gpr[31] = m_pc + 4;
|
||||
m_pc = (m_pc & 0xf0000000) | (inst >> 4);
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x01: // jmpi
|
||||
m_pc = (m_pc & 0xf0000000) | (inst >> 4);
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x03: case 0x23: // ldbu(io)
|
||||
m_gpr[BIT(inst, 22, 5)] = m_space.read_byte(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x04: // addi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x05: case 0x25: // stbio
|
||||
m_space.write_byte(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)), get_reg(BIT(inst, 22, 5)) & 0xff);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x06: // br
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x07: case 0x27: // ldb(io)
|
||||
m_gpr[BIT(inst, 22, 5)] = s32(s8(m_space.read_byte(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)))));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x08: // cmpgei
|
||||
m_gpr[BIT(inst, 22, 5)] = s32(get_reg(BIT(inst, 27, 5))) >= s16(BIT(inst, 6, 16)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0b: case 0x2b: // ldhu(io)
|
||||
m_gpr[BIT(inst, 22, 5)] = m_space.read_word(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0c: // andi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) & BIT(inst, 6, 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0d: case 0x2d: // sth(io)
|
||||
m_space.write_word(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)), get_reg(BIT(inst, 22, 5)) & 0xffff);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0e: // bge
|
||||
if (s32(get_reg(BIT(inst, 27, 5))) >= s32(get_reg(BIT(inst, 22, 5))))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0f: case 0x2f: // ldh(io)
|
||||
m_gpr[BIT(inst, 22, 5)] = s32(s16(m_space.read_word(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)))));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x10: // cmplti
|
||||
m_gpr[BIT(inst, 22, 5)] = s32(get_reg(BIT(inst, 27, 5))) < s16(BIT(inst, 6, 16)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x14: // ori
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) | BIT(inst, 6, 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x15: case 0x35: // stw(io)
|
||||
m_space.write_dword(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)), get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x16: // blt
|
||||
if (s32(get_reg(BIT(inst, 27, 5))) < s32(get_reg(BIT(inst, 22, 5))))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x17: case 0x37: // ldw(io)
|
||||
m_gpr[BIT(inst, 22, 5)] = m_space.read_dword(get_reg(BIT(inst, 27, 5)) + s16(BIT(inst, 6, 16)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x18: // cmpnei
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) != s32(s16(BIT(inst, 6, 16))) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1c: // xori
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) ^ BIT(inst, 6, 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1e: // bne
|
||||
if (get_reg(BIT(inst, 27, 5)) != get_reg(BIT(inst, 22, 5)))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x20: // cmpeqi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) == s32(s16(BIT(inst, 6, 16))) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x24: // muli
|
||||
m_gpr[BIT(inst, 22, 5)] = s32(get_reg(BIT(inst, 27, 5))) * s16(BIT(inst, 6, 16));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x26: // beq
|
||||
if (get_reg(BIT(inst, 27, 5)) == get_reg(BIT(inst, 22, 5)))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x28: // cmpgeui
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) >= BIT(inst, 6, 16) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x2c: // andhi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) & (BIT(inst, 6, 16) << 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x2e: // bgeu
|
||||
if (get_reg(BIT(inst, 27, 5)) >= get_reg(BIT(inst, 22, 5)))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x30: // cmpltui
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) < BIT(inst, 6, 16) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x33: // initd
|
||||
logerror("initd 0x%08X\n", get_reg(BIT(inst, 27, 5) + s16(BIT(inst, 6, 16))));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x34: // orhi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) | (BIT(inst, 6, 16) << 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x36: // bltu
|
||||
if (get_reg(BIT(inst, 27, 5)) < get_reg(BIT(inst, 22, 5)))
|
||||
m_pc += 4 + s32(s16(BIT(inst, 6, 16)));
|
||||
else
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x3a:
|
||||
switch (BIT(inst, 11, 6))
|
||||
{
|
||||
case 0x01: // eret
|
||||
case 0x05: // ret
|
||||
case 0x09: // bret
|
||||
case 0x0d: // jmp
|
||||
m_pc = get_reg(BIT(inst, 27, 5));
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x02: // roli
|
||||
m_gpr[BIT(inst, 17, 5)] = rotl_32(get_reg(BIT(inst, 27, 5)), BIT(inst, 6, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x03: // rol
|
||||
m_gpr[BIT(inst, 17, 5)] = rotl_32(get_reg(BIT(inst, 27, 5)), get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x04: // flushp
|
||||
logerror("flushp instruction encountered (PC = 0x%08X)\n", m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x06: // nor
|
||||
m_gpr[BIT(inst, 17, 5)] = ~(get_reg(BIT(inst, 27, 5)) | get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x07: // mulxuu
|
||||
m_gpr[BIT(inst, 17, 5)] = mulu_32x32_hi(get_reg(BIT(inst, 27, 5)), get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x08: // cmpge
|
||||
m_gpr[BIT(inst, 17, 5)] = s32(get_reg(BIT(inst, 27, 5))) >= s32(get_reg(BIT(inst, 22, 5))) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0b: // ror
|
||||
m_gpr[BIT(inst, 17, 5)] = rotr_32(get_reg(BIT(inst, 27, 5)), get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0c: // flushi
|
||||
logerror("flushi 0x%08X (PC = 0x%08X)\n", get_reg(BIT(inst, 27, 5)), m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x0e: // and
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) & get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x10: // cmplt
|
||||
m_gpr[BIT(inst, 17, 5)] = s32(get_reg(BIT(inst, 27, 5))) < s32(get_reg(BIT(inst, 22, 5))) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x12: // slli
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) << BIT(inst, 6, 5);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x13: // sll
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) << (get_reg(BIT(inst, 22, 5)) & 0x1f);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x17: // mulxsu
|
||||
m_gpr[BIT(inst, 17, 5)] = (s64(s32(get_reg(BIT(inst, 27, 5)))) * u64(get_reg(BIT(inst, 22, 5)))) >> 32;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x18: // cmpne
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) != get_reg(BIT(inst, 22, 5)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x16: // or
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) & get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1a: // srli
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) >> BIT(inst, 6, 5);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1b: // srl
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) >> (get_reg(BIT(inst, 22, 5)) & 0x1f);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1c: // nextpc
|
||||
m_gpr[BIT(inst, 17, 5)] = m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1d: // callr
|
||||
m_gpr[BIT(inst, 17, 5)] = m_pc + 4;
|
||||
m_pc = get_reg(BIT(inst, 27, 5));
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1e: // xor
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) ^ get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x1f: // mulxss
|
||||
m_gpr[BIT(inst, 17, 5)] = mul_32x32_hi(get_reg(BIT(inst, 27, 5)), get_reg(BIT(inst, 22, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x20: // cmpeq
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) == get_reg(BIT(inst, 22, 5)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x24: // divu
|
||||
if (u32 divisor = get_reg(BIT(inst, 22, 5)); divisor != 0)
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) / divisor;
|
||||
else
|
||||
{
|
||||
logerror("Divide by 0 at PC = 0x%08X\n", m_pc);
|
||||
m_gpr[BIT(inst, 17, 5)] = 0xffffffff; // result is undefined
|
||||
}
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x25: // div
|
||||
if (s32 divisor = get_reg(BIT(inst, 22, 5)); divisor != 0)
|
||||
m_gpr[BIT(inst, 17, 5)] = s32(get_reg(BIT(inst, 27, 5)) / divisor);
|
||||
else
|
||||
{
|
||||
logerror("Divide by 0 at PC = 0x%08X\n", m_pc);
|
||||
m_gpr[BIT(inst, 17, 5)] = 0xffffffff; // result is undefined
|
||||
}
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x26: // rdctl
|
||||
m_gpr[BIT(inst, 17, 5)] = read_ctl(BIT(inst, 6, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x27: // mul
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) * get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x28: // cmpgeu
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) >= get_reg(BIT(inst, 22, 5)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x29: // initi
|
||||
logerror("initi 0x%08X (PC = 0x%08X)\n", get_reg(BIT(inst, 27, 5)), m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x2e: // wrctl
|
||||
write_ctl(BIT(inst, 6, 5), get_reg(BIT(inst, 27, 5)));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x30: // cmpltu
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) < get_reg(BIT(inst, 22, 5)) ? 1 : 0;
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x31: // add
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) + get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x36: // sync
|
||||
logerror("sync instruction encountered (PC = 0x%08X)\n", m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x39: // sub
|
||||
m_gpr[BIT(inst, 17, 5)] = get_reg(BIT(inst, 27, 5)) - get_reg(BIT(inst, 22, 5));
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x3a: // srai
|
||||
m_gpr[BIT(inst, 17, 5)] = s32(get_reg(BIT(inst, 27, 5))) >> BIT(inst, 6, 5);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
case 0x3b: // sra
|
||||
m_gpr[BIT(inst, 17, 5)] = s32(get_reg(BIT(inst, 27, 5))) >> (get_reg(BIT(inst, 22, 5)) & 0x1f);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unknown/invalid R-type instruction word encountered (OPX = 0x%02X, PC = 0x%08X)\n", BIT(inst, 11, 6), m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3c: // xorhi
|
||||
m_gpr[BIT(inst, 22, 5)] = get_reg(BIT(inst, 27, 5)) ^ (BIT(inst, 6, 16) << 16);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror("Unknown/invalid instruction word encountered (OP = 0x%02X, PC = 0x%08X)\n", BIT(inst, 0, 6), m_pc);
|
||||
m_pc += 4;
|
||||
m_icount--;
|
||||
break;
|
||||
}
|
||||
} while (m_icount > 0);
|
||||
}
|
||||
|
@ -10,11 +10,15 @@ class nios2_device : public cpu_device
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
NIOS2_R1 = 1, NIOS2_R2, NIOS2_R3, NIOS2_R4, NIOS2_R5, NIOS2_R6, NIOS2_R7,
|
||||
NIOS2_ZERO = 0, NIOS2_AT, NIOS2_R2, NIOS2_R3, NIOS2_R4, NIOS2_R5, NIOS2_R6, NIOS2_R7,
|
||||
NIOS2_R8, NIOS2_R9, NIOS2_R10, NIOS2_R11, NIOS2_R12, NIOS2_R13, NIOS2_R14, NIOS2_R15,
|
||||
NIOS2_R16, NIOS2_R17, NIOS2_R18, NIOS2_R19, NIOS2_R20, NIOS2_R21, NIOS2_R22, NIOS2_R23,
|
||||
NIOS2_R24, NIOS2_R25, NIOS2_R26, NIOS2_R27, NIOS2_R28, NIOS2_R29, NIOS2_R30, NIOS2_R31,
|
||||
NIOS2_ET, NIOS2_BT, NIOS2_GP, NIOS2_SP, NIOS2_FP, NIOS2_EA, NIOS2_BA, NIOS2_RA,
|
||||
NIOS2_PC,
|
||||
NIOS2_STATUS, NIOS2_BSTATUS, NIOS2_ESTATUS, NIOS2_IENABLE,
|
||||
NIOS2_IPENDING, NIOS2_CPUID, NIOS2_CTLID, NIOS2_EXCEPTION,
|
||||
NIOS2_PTEADDR, NIOS2_TLBACC, NIOS2_TLBMISC, NIOS2_ECCINJ,
|
||||
NIOS2_BADADDR, NIOS2_CONFIG, NIOS2_MPUBASE, NIOS2_MPUACC
|
||||
};
|
||||
|
||||
// construction/destruction
|
||||
@ -35,12 +39,19 @@ protected:
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
|
||||
private:
|
||||
u32 get_reg(unsigned r) const noexcept { return r == 0 ? 0 : m_gpr[r]; }
|
||||
|
||||
u32 read_ctl(unsigned r) const;
|
||||
void write_ctl(unsigned r, u32 val);
|
||||
|
||||
// address space
|
||||
address_space_config m_program_config;
|
||||
memory_access<32, 2, 0, ENDIANNESS_LITTLE>::specific m_space;
|
||||
memory_access<32, 2, 0, ENDIANNESS_LITTLE>::cache m_cache;
|
||||
|
||||
// internal registers
|
||||
u32 m_gpr[32];
|
||||
u32 m_ctl[16];
|
||||
u32 m_pc;
|
||||
s32 m_icount;
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ const char *const s_reg_names[32] =
|
||||
const char *const s_ctlreg_names[16] =
|
||||
{
|
||||
"status", "estatus", "bstatus", "ienable", "ipending", "cpuid", "ctl6", "exception",
|
||||
"pteaddr", "tlbacc", "tlbmisc", "ctl11", "badaddr", "config", "mpubase", "mpuacc"
|
||||
"pteaddr", "tlbacc", "tlbmisc", "eccinj", "badaddr", "config", "mpubase", "mpuacc"
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
|
@ -58,6 +58,11 @@ void truesys_state::main_map(address_map &map)
|
||||
map(0x00000000, 0x0000001f).rom().region("maincpu", 0);
|
||||
map(0x00000020, 0x007fffff).ram();
|
||||
map(0x00800000, 0x0087ffff).rom().region("maincpu", 0);
|
||||
map(0x00900000, 0x009003ff).ram(); // video RAM or debug RAM?
|
||||
map(0x009092f0, 0x009092f3).nopw(); // semaphore?
|
||||
map(0x00909300, 0x00909303).noprw(); // byte-wide peripheral (SPI?)
|
||||
map(0x00909304, 0x00909307).noprw();
|
||||
map(0x00909308, 0x0090930b).nopw(); // byte-wide peripheral control?
|
||||
}
|
||||
|
||||
|
||||
|
@ -407,6 +407,65 @@ static const gdb_register_map gdb_register_map_score7 =
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static const gdb_register_map gdb_register_map_nios2 =
|
||||
{
|
||||
"nios2",
|
||||
"org.gnu.gdb.nios2.cpu",
|
||||
{
|
||||
{ "zero", "zero", false, TYPE_INT },
|
||||
{ "at", "at", false, TYPE_INT },
|
||||
{ "r2", "r2", false, TYPE_INT },
|
||||
{ "r3", "r3", false, TYPE_INT },
|
||||
{ "r4", "r4", false, TYPE_INT },
|
||||
{ "r5", "r5", false, TYPE_INT },
|
||||
{ "r6", "r6", false, TYPE_INT },
|
||||
{ "r7", "r7", false, TYPE_INT },
|
||||
{ "r8", "r8", false, TYPE_INT },
|
||||
{ "r9", "r9", false, TYPE_INT },
|
||||
{ "r10", "r10", false, TYPE_INT },
|
||||
{ "r11", "r11", false, TYPE_INT },
|
||||
{ "r12", "r12", false, TYPE_INT },
|
||||
{ "r13", "r13", false, TYPE_INT },
|
||||
{ "r14", "r14", false, TYPE_INT },
|
||||
{ "r15", "r15", false, TYPE_INT },
|
||||
{ "r16", "r16", false, TYPE_INT },
|
||||
{ "r17", "r17", false, TYPE_INT },
|
||||
{ "r18", "r18", false, TYPE_INT },
|
||||
{ "r19", "r19", false, TYPE_INT },
|
||||
{ "r20", "r20", false, TYPE_INT },
|
||||
{ "r21", "r21", false, TYPE_INT },
|
||||
{ "r22", "r22", false, TYPE_INT },
|
||||
{ "r23", "r23", false, TYPE_INT },
|
||||
{ "et", "et", false, TYPE_INT },
|
||||
{ "bt", "bt", false, TYPE_INT },
|
||||
{ "gp", "gp", false, TYPE_DATA_POINTER },
|
||||
{ "sp", "sp", true, TYPE_DATA_POINTER },
|
||||
{ "fp", "fp", false, TYPE_DATA_POINTER },
|
||||
{ "ea", "ea", false, TYPE_CODE_POINTER },
|
||||
{ "ba", "sstatus", false, TYPE_INT }, // this is Altera's fault
|
||||
{ "ra", "ra", false, TYPE_CODE_POINTER },
|
||||
{ "status", "status", false, TYPE_INT },
|
||||
{ "estatus", "estatus", false, TYPE_INT },
|
||||
{ "bstatus", "bstatus", false, TYPE_INT },
|
||||
{ "ienable", "ienable", false, TYPE_INT },
|
||||
{ "ipending", "ipending", false, TYPE_INT },
|
||||
{ "cpuid", "cpuid", false, TYPE_INT },
|
||||
{ "ctl6", "ctl6", false, TYPE_INT },
|
||||
{ "exception","exception",false, TYPE_INT },
|
||||
{ "pteaddr", "pteaddr", false, TYPE_INT },
|
||||
{ "tlbacc", "tlbacc", false, TYPE_INT },
|
||||
{ "tlbmisc", "tlbmisc", false, TYPE_INT },
|
||||
{ "eccinj", "eccinj", false, TYPE_INT },
|
||||
{ "badaddr", "badaddr", false, TYPE_INT },
|
||||
{ "config", "config", false, TYPE_INT },
|
||||
{ "mpubase", "mpubase", false, TYPE_INT },
|
||||
{ "mpuacc", "mpuacc", false, TYPE_INT },
|
||||
{ "PC", "pc", true, TYPE_CODE_POINTER },
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static const std::map<std::string, const gdb_register_map &> gdb_register_maps = {
|
||||
{ "i486", gdb_register_map_i486 },
|
||||
@ -420,6 +479,7 @@ static const std::map<std::string, const gdb_register_map &> gdb_register_maps =
|
||||
{ "rp2a03", gdb_register_map_m6502 },
|
||||
{ "m6809", gdb_register_map_m6809 },
|
||||
{ "score7", gdb_register_map_score7 },
|
||||
{ "nios2", gdb_register_map_nios2 },
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user