HatariWii/src/cpu/cpummu030.h
2018-05-25 20:45:09 +02:00

478 lines
13 KiB
C

#ifndef CPUMMU030_H
#define CPUMMU030_H
#include "mmu_common.h"
extern uae_u64 srp_030, crp_030;
extern uae_u32 tt0_030, tt1_030, tc_030;
extern uae_u16 mmusr_030;
#define MAX_MMU030_ACCESS 10
extern uae_u32 mm030_stageb_address;
extern int mmu030_idx;
extern bool mmu030_retry;
extern int mmu030_opcode, mmu030_opcode_stageb;
extern int mmu030_fake_prefetch;
extern uaecptr mmu030_fake_prefetch_addr;
extern uae_u16 mmu030_state[3];
extern uae_u32 mmu030_data_buffer;
extern uae_u32 mmu030_disp_store[2];
extern uae_u32 mmu030_fmovem_store[2];
#define MMU030_STATEFLAG1_FMOVEM 0x2000
#define MMU030_STATEFLAG1_MOVEM1 0x4000
#define MMU030_STATEFLAG1_MOVEM2 0x8000
#define MMU030_STATEFLAG1_DISP0 0x0001
#define MMU030_STATEFLAG1_DISP1 0x0002
struct mmu030_access
{
bool done;
uae_u32 val;
};
extern struct mmu030_access mmu030_ad[MAX_MMU030_ACCESS];
uae_u32 REGPARAM3 get_disp_ea_020_mmu030 (uae_u32 base, int idx) REGPARAM;
void mmu030_page_fault(uaecptr addr, bool read, int flags, uae_u32 fc);
bool mmu_op30_pmove (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
bool mmu_op30_ptest (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
bool mmu_op30_pload (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
bool mmu_op30_pflush (uaecptr pc, uae_u32 opcode, uae_u16 next, uaecptr extra);
uae_u32 mmu_op30_helper_get_fc(uae_u16 next);
void mmu030_ptest_atc_search(uaecptr logical_addr, uae_u32 fc, bool write);
uae_u32 mmu030_ptest_table_search(uaecptr extra, uae_u32 fc, bool write, int level);
uae_u32 mmu030_table_search(uaecptr addr, uae_u32 fc, bool write, int level);
typedef struct {
uae_u32 addr_base;
uae_u32 addr_mask;
uae_u32 fc_base;
uae_u32 fc_mask;
} TT_info;
TT_info mmu030_decode_tt(uae_u32 TT);
bool mmu030_decode_tc(uae_u32 TC);
bool mmu030_decode_rp(uae_u64 RP);
int mmu030_logical_is_in_atc(uaecptr addr, uae_u32 fc, bool write);
void mmu030_atc_handle_history_bit(int entry_num);
void mmu030_put_long_atc(uaecptr addr, uae_u32 val, int l, uae_u32 fc);
void mmu030_put_word_atc(uaecptr addr, uae_u16 val, int l, uae_u32 fc);
void mmu030_put_byte_atc(uaecptr addr, uae_u8 val, int l, uae_u32 fc);
uae_u32 mmu030_get_long_atc(uaecptr addr, int l, uae_u32 fc);
uae_u16 mmu030_get_word_atc(uaecptr addr, int l, uae_u32 fc);
uae_u8 mmu030_get_byte_atc(uaecptr addr, int l, uae_u32 fc);
#ifdef WINUAE_FOR_HATARI
uae_u32 mmu030_get_ilong_atc(uaecptr addr, int l, uae_u32 fc);
uae_u16 mmu030_get_iword_atc(uaecptr addr, int l, uae_u32 fc);
#endif
void mmu030_put_atc_generic(uaecptr addr, uae_u32 val, int l, uae_u32 fc, int size, int flags);
uae_u32 mmu030_get_atc_generic(uaecptr addr, int l, uae_u32 fc, int size, int flags, bool checkwrite);
void mmu030_flush_atc_fc(uae_u32 fc_base, uae_u32 fc_mask);
void mmu030_flush_atc_page(uaecptr logical_addr);
void mmu030_flush_atc_page_fc(uaecptr logical_addr, uae_u32 fc_base, uae_u32 fc_mask);
void mmu030_flush_atc_all(void);
void mmu030_reset(int hardreset);
void mmu030_set_funcs(void);
uaecptr mmu030_translate(uaecptr addr, bool super, bool data, bool write);
int mmu030_match_ttr(uaecptr addr, uae_u32 fc, bool write);
int mmu030_match_ttr_access(uaecptr addr, uae_u32 fc, bool write);
int mmu030_match_lrmw_ttr_access(uaecptr addr, uae_u32 fc);
int mmu030_do_match_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc, bool write);
int mmu030_do_match_lrmw_ttr(uae_u32 tt, TT_info masks, uaecptr addr, uae_u32 fc);
void mmu030_put_long(uaecptr addr, uae_u32 val, uae_u32 fc);
void mmu030_put_word(uaecptr addr, uae_u16 val, uae_u32 fc);
void mmu030_put_byte(uaecptr addr, uae_u8 val, uae_u32 fc);
uae_u32 mmu030_get_long(uaecptr addr, uae_u32 fc);
uae_u16 mmu030_get_word(uaecptr addr, uae_u32 fc);
uae_u8 mmu030_get_byte(uaecptr addr, uae_u32 fc);
uae_u32 mmu030_get_ilong(uaecptr addr, uae_u32 fc);
uae_u16 mmu030_get_iword(uaecptr addr, uae_u32 fc);
uae_u32 uae_mmu030_get_lrmw(uaecptr addr, int size);
void uae_mmu030_put_lrmw(uaecptr addr, uae_u32 val, int size);
void mmu030_put_generic(uaecptr addr, uae_u32 val, uae_u32 fc, int size, int accesssize, int flags);
uae_u32 mmu030_get_generic(uaecptr addr, uae_u32 fc, int size, int accesssize, int flags);
extern uae_u16 REGPARAM3 mmu030_get_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM;
extern uae_u32 REGPARAM3 mmu030_get_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM;
extern uae_u32 REGPARAM3 mmu030_get_ilong_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM;
extern uae_u16 REGPARAM3 mmu030_get_lrmw_word_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM;
extern uae_u32 REGPARAM3 mmu030_get_lrmw_long_unaligned(uaecptr addr, uae_u32 fc, int flags) REGPARAM;
extern void REGPARAM3 mmu030_put_word_unaligned(uaecptr addr, uae_u16 val, uae_u32 fc, int flags) REGPARAM;
extern void REGPARAM3 mmu030_put_long_unaligned(uaecptr addr, uae_u32 val, uae_u32 fc, int flags) REGPARAM;
static ALWAYS_INLINE uae_u32 uae_mmu030_get_ilong(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 2;
if (unlikely(is_unaligned(addr, 4)))
return mmu030_get_ilong_unaligned(addr, fc, 0);
return mmu030_get_ilong(addr, fc);
}
static ALWAYS_INLINE uae_u16 uae_mmu030_get_iword(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 2;
return mmu030_get_iword(addr, fc);
}
static ALWAYS_INLINE uae_u16 uae_mmu030_get_ibyte(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 2;
return mmu030_get_byte(addr, fc);
}
static ALWAYS_INLINE uae_u32 uae_mmu030_get_long(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
if (unlikely(is_unaligned(addr, 4)))
return mmu030_get_long_unaligned(addr, fc, 0);
return mmu030_get_long(addr, fc);
}
static ALWAYS_INLINE uae_u16 uae_mmu030_get_word(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
if (unlikely(is_unaligned(addr, 2)))
return mmu030_get_word_unaligned(addr, fc, 0);
return mmu030_get_word(addr, fc);
}
static ALWAYS_INLINE uae_u8 uae_mmu030_get_byte(uaecptr addr)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
return mmu030_get_byte(addr, fc);
}
static ALWAYS_INLINE void uae_mmu030_put_long(uaecptr addr, uae_u32 val)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
if (unlikely(is_unaligned(addr, 4)))
mmu030_put_long_unaligned(addr, val, fc, 0);
else
mmu030_put_long(addr, val, fc);
}
static ALWAYS_INLINE void uae_mmu030_put_word(uaecptr addr, uae_u16 val)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
if (unlikely(is_unaligned(addr, 2)))
mmu030_put_word_unaligned(addr, val, fc, 0);
else
mmu030_put_word(addr, val, fc);
}
static ALWAYS_INLINE void uae_mmu030_put_byte(uaecptr addr, uae_u8 val)
{
uae_u32 fc = (regs.s ? 4 : 0) | 1;
mmu030_put_byte(addr, val, fc);
}
static ALWAYS_INLINE uae_u32 sfc030_get_long(uaecptr addr)
{
uae_u32 fc = regs.sfc;
#if MMUDEBUG > 2
write_log(_T("sfc030_get_long: FC = %i\n"),fc);
#endif
if (unlikely(is_unaligned(addr, 4)))
return mmu030_get_long_unaligned(addr, fc, 0);
return mmu030_get_long(addr, fc);
}
static ALWAYS_INLINE uae_u16 sfc030_get_word(uaecptr addr)
{
uae_u32 fc = regs.sfc;
#if MMUDEBUG > 2
write_log(_T("sfc030_get_word: FC = %i\n"),fc);
#endif
if (unlikely(is_unaligned(addr, 2)))
return mmu030_get_word_unaligned(addr, fc, 0);
return mmu030_get_word(addr, fc);
}
static ALWAYS_INLINE uae_u8 sfc030_get_byte(uaecptr addr)
{
uae_u32 fc = regs.sfc;
#if MMUDEBUG > 2
write_log(_T("sfc030_get_byte: FC = %i\n"),fc);
#endif
return mmu030_get_byte(addr, fc);
}
static ALWAYS_INLINE void dfc030_put_long(uaecptr addr, uae_u32 val)
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
write_log(_T("dfc030_put_long: %08X = %08X FC = %i\n"), addr, val, fc);
#endif
if (unlikely(is_unaligned(addr, 4)))
mmu030_put_long_unaligned(addr, val, fc, 0);
else
mmu030_put_long(addr, val, fc);
}
static ALWAYS_INLINE void dfc030_put_word(uaecptr addr, uae_u16 val)
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
write_log(_T("dfc030_put_word: %08X = %04X FC = %i\n"), addr, val, fc);
#endif
if (unlikely(is_unaligned(addr, 2)))
mmu030_put_word_unaligned(addr, val, fc, 0);
else
mmu030_put_word(addr, val, fc);
}
static ALWAYS_INLINE void dfc030_put_byte(uaecptr addr, uae_u8 val)
{
uae_u32 fc = regs.dfc;
#if MMUDEBUG > 2
write_log(_T("dfc030_put_byte: %08X = %02X FC = %i\n"), addr, val, fc);
#endif
mmu030_put_byte(addr, val, fc);
}
#define ACCESS_CHECK_PUT \
if (!mmu030_ad[mmu030_idx].done) { \
mmu030_ad[mmu030_idx].val = v; \
} else if (mmu030_ad[mmu030_idx].done) { \
mmu030_idx++; \
return; \
}
#define ACCESS_CHECK_GET \
if (mmu030_ad[mmu030_idx].done) { \
v = mmu030_ad[mmu030_idx].val; \
mmu030_idx++; \
return v; \
}
#define ACCESS_CHECK_GET_PC(pc) \
if (mmu030_ad[mmu030_idx].done) { \
v = mmu030_ad[mmu030_idx].val; \
mmu030_idx++; \
m68k_incpci (pc); \
return v; \
}
#define ACCESS_EXIT_PUT \
mmu030_ad[mmu030_idx].done = true; \
mmu030_idx++; \
mmu030_ad[mmu030_idx].done = false;
#define ACCESS_EXIT_GET \
mmu030_ad[mmu030_idx].val = v; \
mmu030_ad[mmu030_idx].done = true; \
mmu030_idx++; \
mmu030_ad[mmu030_idx].done = false;
STATIC_INLINE void put_byte_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_byte (addr, v);
ACCESS_EXIT_PUT
}
STATIC_INLINE void put_lrmw_byte_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_lrmw (addr, v, sz_byte);
ACCESS_EXIT_PUT
}
STATIC_INLINE void put_word_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_word (addr, v);
ACCESS_EXIT_PUT
}
STATIC_INLINE void put_lrmw_word_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_lrmw (addr, v, sz_word);
ACCESS_EXIT_PUT
}
STATIC_INLINE void put_long_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_long (addr, v);
ACCESS_EXIT_PUT
}
STATIC_INLINE void put_lrmw_long_mmu030_state (uaecptr addr, uae_u32 v)
{
ACCESS_CHECK_PUT
uae_mmu030_put_lrmw (addr, v, sz_long);
ACCESS_EXIT_PUT
}
STATIC_INLINE uae_u32 get_byte_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_byte (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_lrmw_byte_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_lrmw (addr, sz_byte);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_word_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_word (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_lrmw_word_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_lrmw (addr, sz_word);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_long_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_long (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_lrmw_long_mmu030_state (uaecptr addr)
{
uae_u32 v;
ACCESS_CHECK_GET
v = uae_mmu030_get_lrmw (addr, sz_long);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_ibyte_mmu030_state (int o)
{
uae_u32 v;
uae_u32 addr = m68k_getpci () + o;
ACCESS_CHECK_GET
v = uae_mmu030_get_iword (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_iword_mmu030_state (int o)
{
uae_u32 v;
uae_u32 addr = m68k_getpci () + o;
ACCESS_CHECK_GET
v = uae_mmu030_get_iword (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_ilong_mmu030_state (int o)
{
uae_u32 v;
uae_u32 addr = m68k_getpci () + o;
ACCESS_CHECK_GET
v = uae_mmu030_get_ilong (addr);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 next_iword_mmu030_state (void)
{
uae_u32 v;
uae_u32 addr = m68k_getpci ();
ACCESS_CHECK_GET_PC(2);
v = uae_mmu030_get_iword (addr);
m68k_incpci (2);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 next_ilong_mmu030_state (void)
{
uae_u32 v;
uae_u32 addr = m68k_getpci ();
ACCESS_CHECK_GET_PC(4);
v = uae_mmu030_get_ilong (addr);
m68k_incpci (4);
ACCESS_EXIT_GET
return v;
}
STATIC_INLINE uae_u32 get_byte_mmu030 (uaecptr addr)
{
return uae_mmu030_get_byte (addr);
}
STATIC_INLINE uae_u32 get_word_mmu030 (uaecptr addr)
{
return uae_mmu030_get_word (addr);
}
STATIC_INLINE uae_u32 get_long_mmu030 (uaecptr addr)
{
return uae_mmu030_get_long (addr);
}
STATIC_INLINE void put_byte_mmu030 (uaecptr addr, uae_u32 v)
{
uae_mmu030_put_byte (addr, v);
}
STATIC_INLINE void put_word_mmu030 (uaecptr addr, uae_u32 v)
{
uae_mmu030_put_word (addr, v);
}
STATIC_INLINE void put_long_mmu030 (uaecptr addr, uae_u32 v)
{
uae_mmu030_put_long (addr, v);
}
STATIC_INLINE uae_u32 get_ibyte_mmu030 (int o)
{
uae_u32 pc = m68k_getpci () + o;
return uae_mmu030_get_iword (pc);
}
STATIC_INLINE uae_u32 get_iword_mmu030 (int o)
{
uae_u32 pc = m68k_getpci () + o;
return uae_mmu030_get_iword (pc);
}
STATIC_INLINE uae_u32 get_ilong_mmu030 (int o)
{
uae_u32 pc = m68k_getpci () + o;
return uae_mmu030_get_ilong (pc);
}
STATIC_INLINE uae_u32 next_iword_mmu030 (void)
{
uae_u32 v;
uae_u32 pc = m68k_getpci ();
v = uae_mmu030_get_iword (pc);
m68k_incpci (2);
return v;
}
STATIC_INLINE uae_u32 next_ilong_mmu030 (void)
{
uae_u32 v;
uae_u32 pc = m68k_getpci ();
v = uae_mmu030_get_ilong (pc);
m68k_incpci (4);
return v;
}
extern void m68k_do_rts_mmu030 (void);
extern void m68k_do_rte_mmu030 (uaecptr a7);
extern void flush_mmu030 (uaecptr, int);
extern void m68k_do_bsr_mmu030 (uaecptr oldpc, uae_s32 offset);
#endif