MIPS3: Add TODO, better internal counter register emulation (on

Interpreter and Recompiler), disable breakpoints by default.
This commit is contained in:
Marcos Medeiros 2015-05-12 03:18:31 +00:00
parent 65cfdea1dd
commit 4e4986527d
4 changed files with 46 additions and 8 deletions

View File

@ -41,6 +41,10 @@ void mips3::cop0_execute(uint32_t opcode)
// MFC
case 0x00:
if (RTNUM) {
if (RDNUM == COP0_Count) {
RT = (uint32_t) ((m_state.total_cycles - m_state.reset_cycle) / 2);
return;
}
RT = CR(RDNUM);
}
break;
@ -48,6 +52,9 @@ void mips3::cop0_execute(uint32_t opcode)
// MTC
case 0x04:
m_state.cpr[0][RDNUM] = RT;
if (RDNUM == COP0_Count) {
m_state.reset_cycle = m_state.total_cycles - ((uint64_t)(uint32_t)RT * 2);
}
break;
// TLBWI

View File

@ -3,6 +3,13 @@
* Copyright (c) 2015, Marcos Medeiros
* Licensed under BSD 3-clause.
*/
/*
* TODO:
* Fix TLB emulation
* COP1 FR0 opcodes
* Exceptions!!!
**/
//#include <QDebug>
#include <iostream>
#include <cstdint>
@ -90,6 +97,7 @@ uint32_t mips3::translate(addr_t addr, addr_t *out)
}
#if MIPS3_ENABLE_BREAKPOINTS
void mips3::bp_insert(addr_t address)
{
@ -106,25 +114,30 @@ inline bool mips3::check_breakpoint()
return (m_breakpoints.find(m_state.pc) != m_breakpoints.end());
}
#endif
bool mips3::run(int cycles, bool skip_bps)
{
m_counter = 0;
int last_icounter = 0;
// endereço efetivo
addr_t eaddr = 0;
#if MIPS3_ENABLE_BREAKPOINTS
if (!skip_bps && check_breakpoint())
return true;
#endif
while (m_counter < cycles) {
if (translate(m_state.pc, &eaddr)) {
/* ocorreu algum erro */
/* TODO: handle exceptions */
}
m_prev_pc = m_state.pc;
uint32_t opcode = mem::read_word(eaddr);
// A instrução que precede um branch/jump sempre é executada
// We always execute delay slot
if (m_delay_slot) {
m_state.pc = m_next_pc;
m_delay_slot = false;
@ -133,6 +146,8 @@ bool mips3::run(int cycles, bool skip_bps)
m_state.pc += 4;
}
last_icounter = m_counter;
switch (opcode >> 26) {
// SPECIAL
@ -418,13 +433,13 @@ bool mips3::run(int cycles, bool skip_bps)
break;
}
// Increment COP0 Count
m_state.cpr[0][COP0_Count] += 20;
m_counter++;
m_state.total_cycles += m_counter - last_icounter;
#if MIPS3_ENABLE_BREAKPOINTS
if (!skip_bps && check_breakpoint())
return true;
#endif
}
m_state.total_cycles += m_counter;
return false;
}

View File

@ -5,6 +5,8 @@
#ifndef MIPS3_H
#define MIPS3_H
#define MIPS3_ENABLE_BREAKPOINTS 0
#include "mips3_common.h"
#include <string>
@ -107,14 +109,18 @@ public:
uint32_t translate(addr_t addr, addr_t *out);
const int m_tlb_entries;
#if MIPS3_ENABLE_BREAKPOINTS
void bp_insert(addr_t address);
void bp_remove(addr_t address);
#endif
private:
int m_counter;
addr_t tlb_translate(addr_t address);
#if MIPS3_ENABLE_BREAKPOINTS
unordered_set<addr_t> m_breakpoints;
bool check_breakpoint();
#endif
void tlb_init();
void tlb_flush();
void cop0_reset();

View File

@ -24,19 +24,18 @@ bool mips3_x64::compile_cop0(uint32_t opcode)
case 0x00:
if (RTNUM) {
switch (RDNUM) {
// Hack: (total_cycles - reset_cycle) * 16
case COP0_Count:
m_block_icounter += 250;
//sub(r15, 250);
mov(rax, TOTAL_x);
sub(rax, RSTCYC_x);
shr(rax, 1);
and_(eax, ~0);
mov(RT_x, rax);
return false;
case COP0_Cause:
m_block_icounter += 250;
//sub(r15, 250);
break;
}
mov(rax, COP0_x(RDNUM));
@ -44,6 +43,17 @@ bool mips3_x64::compile_cop0(uint32_t opcode)
mov(RT_x, rax);
}
break;
// MTC0 rd, rt
case 0x04:
if (RDNUM == COP0_Count) {
mov(rax, RT_x);
mov(COP0_x(COP0_Count), rax);
mov(rcx, TOTAL_x);
shl(eax, 1);
sub(rcx, rax);
mov(RSTCYC_q, rax);
return false;
}
default:
fallback(opcode, &mips3::cop0_execute);
break;