mirror of
https://github.com/holub/mame
synced 2025-05-21 21:29:15 +03:00
SH4: cleanup and better common/interpreter separation [R. Belmont]
This commit is contained in:
parent
74bbf1d033
commit
b85af379a8
@ -28,14 +28,9 @@
|
||||
#include "sh4regs.h"
|
||||
#include "sh4comn.h"
|
||||
|
||||
CPU_DISASSEMBLE( sh4 );
|
||||
#ifndef USE_SH4DRC
|
||||
|
||||
INLINE sh4_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SH4);
|
||||
return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
CPU_DISASSEMBLE( sh4 );
|
||||
|
||||
/* Called for unimplemented opcodes */
|
||||
static void TODO(sh4_state *sh4)
|
||||
@ -2079,27 +2074,6 @@ INLINE void LDCSPC(sh4_state *sh4, UINT32 m)
|
||||
sh4->spc = sh4->r[m];
|
||||
}
|
||||
|
||||
static UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address)
|
||||
{
|
||||
if (!sh4->sh4_mmu_enabled)
|
||||
return address;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
UINT32 topaddr = address&0xfff00000;
|
||||
|
||||
for (i=0;i<64;i++)
|
||||
{
|
||||
UINT32 topcmp = sh4->sh4_tlb_address[i]&0xfff00000;
|
||||
if (topcmp==topaddr)
|
||||
return (address&0x000fffff) | ((sh4->sh4_tlb_data[i])&0xfff00000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
/* PREF @Rn */
|
||||
INLINE void PREFM(sh4_state *sh4, UINT32 n)
|
||||
{
|
||||
@ -3622,43 +3596,6 @@ static ADDRESS_MAP_START( sh4_internal_map, ADDRESS_SPACE_PROGRAM, 64 )
|
||||
ADDRESS_MAP_END
|
||||
#endif
|
||||
|
||||
|
||||
static READ64_HANDLER( sh4_tlb_r )
|
||||
{
|
||||
sh4_state *sh4 = get_safe_token(space->cpu);
|
||||
|
||||
int offs = offset*8;
|
||||
|
||||
if (offs >= 0x01000000)
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
return sh4->sh4_tlb_data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
return sh4->sh4_tlb_address[i];
|
||||
}
|
||||
}
|
||||
|
||||
static WRITE64_HANDLER( sh4_tlb_w )
|
||||
{
|
||||
sh4_state *sh4 = get_safe_token(space->cpu);
|
||||
|
||||
int offs = offset*8;
|
||||
|
||||
if (offs >= 0x01000000)
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
sh4->sh4_tlb_data[i] = data&0xffffffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
sh4->sh4_tlb_address[i] = data&0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
/*When OC index mode is on (CCR.OIX = 1)*/
|
||||
static ADDRESS_MAP_START( sh4_internal_map, ADDRESS_SPACE_PROGRAM, 64 )
|
||||
AM_RANGE(0x1C000000, 0x1C000FFF) AM_RAM AM_MIRROR(0x01FFF000)
|
||||
@ -3884,3 +3821,5 @@ CPU_GET_INFO( sh4 )
|
||||
}
|
||||
|
||||
DEFINE_LEGACY_CPU_DEVICE(SH4, sh4);
|
||||
|
||||
#endif // USE_SH4DRC
|
||||
|
@ -100,5 +100,19 @@ void sh4_set_irln_input(device_t *device, int value);
|
||||
void sh4_set_ftcsr_callback(device_t *device, sh4_ftcsr_callback callback);
|
||||
void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s);
|
||||
|
||||
/***************************************************************************
|
||||
COMPILER-SPECIFIC OPTIONS
|
||||
***************************************************************************/
|
||||
|
||||
#define SH4DRC_STRICT_VERIFY 0x0001 /* verify all instructions */
|
||||
#define SH4DRC_FLUSH_PC 0x0002 /* flush the PC value before each memory access */
|
||||
#define SH4DRC_STRICT_PCREL 0x0004 /* do actual loads on MOVLI/MOVWI instead of collapsing to immediates */
|
||||
|
||||
#define SH4DRC_COMPATIBLE_OPTIONS (SH4DRC_STRICT_VERIFY | SH4DRC_FLUSH_PC | SH4DRC_STRICT_PCREL)
|
||||
#define SH4DRC_FASTEST_OPTIONS (0)
|
||||
|
||||
void sh4drc_set_options(device_t *device, UINT32 options);
|
||||
void sh4drc_add_pcflush(device_t *device, offs_t address);
|
||||
|
||||
#endif /* __SH4_H__ */
|
||||
|
||||
|
@ -30,13 +30,6 @@ static const UINT16 tcnt[] = { TCNT0, TCNT1, TCNT2 };
|
||||
static const UINT16 tcor[] = { TCOR0, TCOR1, TCOR2 };
|
||||
static const UINT16 tcr[] = { TCR0, TCR1, TCR2 };
|
||||
|
||||
INLINE sh4_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SH4);
|
||||
return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
|
||||
void sh4_change_register_bank(sh4_state *sh4, int to)
|
||||
{
|
||||
int s;
|
||||
@ -1314,3 +1307,60 @@ void sh4_dma_ddt(device_t *device, struct sh4_ddt_dma *s)
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address)
|
||||
{
|
||||
if (!sh4->sh4_mmu_enabled)
|
||||
return address;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
UINT32 topaddr = address&0xfff00000;
|
||||
|
||||
for (i=0;i<64;i++)
|
||||
{
|
||||
UINT32 topcmp = sh4->sh4_tlb_address[i]&0xfff00000;
|
||||
if (topcmp==topaddr)
|
||||
return (address&0x000fffff) | ((sh4->sh4_tlb_data[i])&0xfff00000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return address;
|
||||
}
|
||||
|
||||
READ64_HANDLER( sh4_tlb_r )
|
||||
{
|
||||
sh4_state *sh4 = get_safe_token(space->cpu);
|
||||
|
||||
int offs = offset*8;
|
||||
|
||||
if (offs >= 0x01000000)
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
return sh4->sh4_tlb_data[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
return sh4->sh4_tlb_address[i];
|
||||
}
|
||||
}
|
||||
|
||||
WRITE64_HANDLER( sh4_tlb_w )
|
||||
{
|
||||
sh4_state *sh4 = get_safe_token(space->cpu);
|
||||
|
||||
int offs = offset*8;
|
||||
|
||||
if (offs >= 0x01000000)
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
sh4->sh4_tlb_data[i] = data&0xffffffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 i = (offs>>8)&63;
|
||||
sh4->sh4_tlb_address[i] = data&0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,17 @@
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#ifdef USE_SH4DRC
|
||||
#include "cpu/drcfe.h"
|
||||
#include "cpu/drcuml.h"
|
||||
#include "cpu/drcumlsh.h"
|
||||
|
||||
class sh4_frontend;
|
||||
#endif
|
||||
|
||||
#define CPU_TYPE_SH3 (2)
|
||||
#define CPU_TYPE_SH4 (3)
|
||||
|
||||
#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
#define EXPPRI(pl,po,p,n) (((4-(pl)) << 24) | ((15-(po)) << 16) | ((p) << 8) | (255-(n)))
|
||||
@ -99,8 +110,88 @@ typedef struct
|
||||
UINT32 sh4_tlb_data[64];
|
||||
UINT8 sh4_mmu_enabled;
|
||||
|
||||
#ifdef USE_SH4DRC
|
||||
int icount;
|
||||
int cpu_type;
|
||||
|
||||
int pcfsel; // last pcflush entry set
|
||||
int maxpcfsel; // highest valid pcflush entry
|
||||
UINT32 pcflushes[16]; // pcflush entries
|
||||
|
||||
drc_cache * cache; /* pointer to the DRC code cache */
|
||||
drcuml_state * drcuml; /* DRC UML generator state */
|
||||
sh4_frontend * drcfe; /* pointer to the DRC front-end class */
|
||||
UINT32 drcoptions; /* configurable DRC options */
|
||||
|
||||
/* internal stuff */
|
||||
UINT8 cache_dirty; /* true if we need to flush the cache */
|
||||
|
||||
/* parameters for subroutines */
|
||||
UINT64 numcycles; /* return value from gettotalcycles */
|
||||
UINT32 arg0; /* print_debug argument 1 */
|
||||
UINT32 arg1; /* print_debug argument 2 */
|
||||
UINT32 irq; /* irq we're taking */
|
||||
|
||||
/* register mappings */
|
||||
drcuml_parameter regmap[16]; /* parameter to register mappings for all 16 integer registers */
|
||||
|
||||
drcuml_codehandle * entry; /* entry point */
|
||||
drcuml_codehandle * read8; /* read byte */
|
||||
drcuml_codehandle * write8; /* write byte */
|
||||
drcuml_codehandle * read16; /* read half */
|
||||
drcuml_codehandle * write16; /* write half */
|
||||
drcuml_codehandle * read32; /* read word */
|
||||
drcuml_codehandle * write32; /* write word */
|
||||
|
||||
drcuml_codehandle * interrupt; /* interrupt */
|
||||
drcuml_codehandle * nocode; /* nocode */
|
||||
drcuml_codehandle * out_of_cycles; /* out of cycles exception handler */
|
||||
|
||||
UINT32 prefadr;
|
||||
UINT32 target;
|
||||
#endif
|
||||
} sh4_state;
|
||||
|
||||
#ifdef USE_SH4DRC
|
||||
class sh4_frontend : public drc_frontend
|
||||
{
|
||||
public:
|
||||
sh4_frontend(sh4_state &state, UINT32 window_start, UINT32 window_end, UINT32 max_sequence);
|
||||
|
||||
protected:
|
||||
virtual bool describe(opcode_desc &desc, const opcode_desc *prev);
|
||||
|
||||
private:
|
||||
bool describe_group_0(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_2(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_3(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_4(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_6(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_8(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_12(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
bool describe_group_15(opcode_desc &desc, const opcode_desc *prev, UINT16 opcode);
|
||||
|
||||
sh4_state &m_context;
|
||||
};
|
||||
|
||||
INLINE sh4_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SH3 ||
|
||||
device->type() == SH4);
|
||||
return *(sh4_state **)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
#else
|
||||
INLINE sh4_state *get_safe_token(device_t *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == SH3 ||
|
||||
device->type() == SH4);
|
||||
return (sh4_state *)downcast<legacy_cpu_device *>(device)->token();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ICF = 0x00800000,
|
||||
@ -135,6 +226,24 @@ enum
|
||||
#define Rn ((opcode>>8)&15)
|
||||
#define Rm ((opcode>>4)&15)
|
||||
|
||||
#define REGFLAG_R(n) (1 << (n))
|
||||
#define REGFLAG_FR(n) (1 << (n))
|
||||
#define REGFLAG_XR(n) (1 << (n))
|
||||
|
||||
/* register flags 1 */
|
||||
#define REGFLAG_PR (1 << 0)
|
||||
#define REGFLAG_MACL (1 << 1)
|
||||
#define REGFLAG_MACH (1 << 2)
|
||||
#define REGFLAG_GBR (1 << 3)
|
||||
#define REGFLAG_VBR (1 << 4)
|
||||
#define REGFLAG_SR (1 << 5)
|
||||
#define REGFLAG_SGR (1 << 6)
|
||||
#define REGFLAG_FPUL (1 << 7)
|
||||
#define REGFLAG_FPSCR (1 << 8)
|
||||
#define REGFLAG_DBR (1 << 9)
|
||||
#define REGFLAG_SSR (1 << 10)
|
||||
#define REGFLAG_SPC (1 << 11)
|
||||
|
||||
void sh4_exception_recompute(sh4_state *sh4); // checks if there is any interrupt with high enough priority
|
||||
void sh4_exception_request(sh4_state *sh4, int exception); // start requesting an exception
|
||||
void sh4_exception_unrequest(sh4_state *sh4, int exception); // stop requesting an exception
|
||||
@ -150,6 +259,10 @@ void sh4_set_irq_line(sh4_state *sh4, int irqline, int state); // set state of e
|
||||
void sh4_swap_fp_couples(sh4_state *sh4);
|
||||
#endif
|
||||
void sh4_common_init(device_t *device);
|
||||
UINT32 sh4_getsqremap(sh4_state *sh4, UINT32 address);
|
||||
|
||||
READ64_HANDLER( sh4_tlb_r );
|
||||
WRITE64_HANDLER( sh4_tlb_w );
|
||||
|
||||
INLINE void sh4_check_pending_irq(sh4_state *sh4, const char *message) // look for highest priority active exception and handle it
|
||||
{
|
||||
|
@ -783,7 +783,7 @@ static UINT32 op1111(char *buffer, UINT32 pc, UINT16 opcode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned DasmSH4(char *buffer, unsigned pc, UINT16 opcode)
|
||||
unsigned DasmSH4(char *buffer, unsigned pc, UINT16 opcode)
|
||||
{
|
||||
UINT32 flags;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user