Cog/Frameworks/lazyusf2/lazyusf2/usf/usf_internal.h

488 lines
12 KiB
C

#ifndef _USF_INTERNAL_H_
#define _USF_INTERNAL_H_
#include "osal/preproc.h"
#include "main/main.h"
#include "main/rom.h"
#include "ai/ai_controller.h"
#include "memory/memory.h"
#include "pi/pi_controller.h"
#include "r4300/r4300_core.h"
#include "r4300/ops.h"
#include "r4300/cp0.h"
#include "rdp/rdp_core.h"
#include "ri/ri_controller.h"
#include "rsp/rsp_core.h"
#include "si/si_controller.h"
#include "vi/vi_controller.h"
#include "rsp_hle/hle.h"
#include <stdio.h>
struct usf_state_helper
{
size_t offset_to_structure;
};
#ifdef DEBUG_INFO
#include <stdio.h>
#endif
#ifndef RCPREG_DEFINED
#define RCPREG_DEFINED
typedef uint32_t RCPREG;
#endif
#if defined(__x86_64__)
typedef struct _jump_table
{
unsigned int mi_addr;
unsigned int pc_addr;
unsigned int absolute64;
} jump_table;
typedef struct _riprelative_table
{
unsigned int pc_addr; /* index in bytes from start of x86_64 code block to the displacement value to write */
unsigned int extra_bytes; /* number of remaining instruction bytes (immediate data) after 4-byte displacement */
unsigned char *global_dst; /* 64-bit pointer to the data object */
} riprelative_table;
#else
typedef struct _jump_table
{
unsigned int mi_addr;
unsigned int pc_addr;
} jump_table;
#endif
#ifndef INTERUPT_STRUCTS
#define INTERUPT_STRUCTS
#define POOL_CAPACITY 16
struct interrupt_event
{
int type;
unsigned int count;
};
struct node
{
struct interrupt_event data;
struct node *next;
};
struct pool
{
struct node nodes[POOL_CAPACITY];
struct node* stack[POOL_CAPACITY];
size_t index;
};
struct interrupt_queue
{
struct pool pool;
struct node* first;
};
#endif
#ifndef TLB_STRUCTS
#define TLB_STRUCTS
typedef struct _tlb
{
short mask;
int vpn2;
char g;
unsigned char asid;
int pfn_even;
char c_even;
char d_even;
char v_even;
int pfn_odd;
char c_odd;
char d_odd;
char v_odd;
char r;
//int check_parity_mask;
unsigned int start_even;
unsigned int end_even;
unsigned int phys_even;
unsigned int start_odd;
unsigned int end_odd;
unsigned int phys_odd;
} tlb;
#endif
#ifndef PRECOMP_STRUCTS
#define PRECOMP_STRUCTS
#if defined(__x86_64__)
#include "r4300/x86_64/assemble_struct.h"
#else
#include "r4300/x86/assemble_struct.h"
#endif
typedef struct _precomp_instr
{
void (osal_fastcall *ops)(usf_state_t * state);
union
{
struct
{
long long int *rs;
long long int *rt;
short immediate;
} i;
struct
{
unsigned int inst_index;
} j;
struct
{
long long int *rs;
long long int *rt;
long long int *rd;
unsigned char sa;
unsigned char nrd;
} r;
struct
{
unsigned char base;
unsigned char ft;
short offset;
} lf;
struct
{
unsigned char ft;
unsigned char fs;
unsigned char fd;
} cf;
} f;
unsigned int addr; /* word-aligned instruction address in r4300 address space */
unsigned int local_addr; /* byte offset to start of corresponding x86_64 instructions, from start of code block */
#ifdef DYNAREC
reg_cache_struct reg_cache_infos;
#endif
} precomp_instr;
typedef struct _precomp_block
{
precomp_instr *block;
unsigned int start;
unsigned int end;
unsigned char *code;
unsigned int code_length;
unsigned int max_code_length;
void *jumps_table;
int jumps_number;
void *riprel_table;
int riprel_number;
//unsigned char md5[16];
unsigned int adler32;
} precomp_block;
#endif
struct usf_state
{
// main/main.c
uint32_t g_rdram[RDRAM_MAX_SIZE/4];
// RSP vector registers, need to be aligned to 16 bytes
// when SSE2 or SSSE3 is enabled, or for any hope of
// auto vectorization
// usf_clear takes care of aligning the structure within
// the memory block passed into it, treating the pointer
// as usf_state_helper, and storing an offset from the
// pointer to the actual usf_state structure. The size
// which is indicated for allocation accounts for this
// with two pages of padding.
int16_t VR[32][8];
int16_t VACC[3][8];
// RSP virtual registers, also needs alignment
int32_t SR[32];
// rsp/rsp.c, not necessarily in need of alignment
RCPREG* CR[16];
// rsp/vu/cf.h, all need alignment
int16_t ne[8]; /* $vco: high byte "NOTEQUAL" */
int16_t co[8]; /* $vco: low byte "carry/borrow in/out" */
int16_t clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */
int16_t comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
int16_t vce[8]; /* $vce: vector compare extension register */
// All further members of the structure need not be aligned
// rsp/vu/divrom.h
int32_t DivIn; /* buffered numerator of division read from vector file */
int32_t DivOut; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */
#if (0)
int32_t MovIn; /* We do not emulate this register (obsolete, for VMOV). */
#endif
int32_t DPH;
// rsp/rsp.h
int32_t stage; // unused since EMULATE_STATIC_PC is defined by default in rsp/config.h
int32_t temp_PC;
int16_t MFC0_count[32];
unsigned char * DMEM;
unsigned char * IMEM;
// rsp_hle
struct hle_t hle;
// options from file tags
uint32_t enablecompare, enableFIFOfull;
// options for decoding
uint32_t enable_hle_audio;
// trimming helper
uint32_t enable_trimming_mode;
void * barray_rom;
void * barray_ram_read;
void * barray_ram_written_first;
// save state
unsigned char * save_state;
unsigned int save_state_size;
// buffering for rendered sample data
size_t sample_buffer_count;
int16_t * sample_buffer;
// audio.c
// SampleRate is usually guaranteed to stay the same for the duration
// of a given track, and depends on the game.
int32_t SampleRate;
// Audio is rendered in whole Audio Interface DMA transfers, which are
// then copied directly to the caller's buffer. Any left over samples
// from the last DMA transfer that fills the caller's buffer will be
// stored here until the next call to usf_render()
int16_t samplebuf[16384];
size_t samples_in_buffer;
void * resampler;
int16_t samplebuf2[8192];
size_t samples_in_buffer_2;
// This buffer does not really need to be that large, as it is likely
// to only accumulate a handlful of error messages, at which point
// emulation is immediately halted and the messages are returned to
// the caller.
const char * last_error;
char error_message[16384];
uint32_t MemoryState;
// main/main.c
struct ai_controller g_ai;
struct pi_controller g_pi;
struct ri_controller g_ri;
struct si_controller g_si;
struct vi_controller g_vi;
struct r4300_core g_r4300;
struct rdp_core g_dp;
struct rsp_core g_sp;
// Compatibility with USF sets dictates that these all remain zero
int g_delay_si/* = 0*/;
int g_delay_ai/* = 0*/;
int g_delay_pi/* = 0*/;
int g_delay_sp/* = 0*/;
int g_delay_dp/* = 0*/;
// XXX enable this for some USF sets, safe to enable always
int g_disable_tlb_write_exception;
int g_gs_vi_counter/* = 0*/;
// memory/memory.c
unsigned int address, cpu_word;
unsigned char cpu_byte;
unsigned short cpu_hword;
unsigned long long cpu_dword, *rdword;
uint32_t EmptySpace[0x10000/4];
void (osal_fastcall *readmem[0x10000])(usf_state_t *);
void (osal_fastcall *readmemb[0x10000])(usf_state_t *);
void (osal_fastcall *readmemh[0x10000])(usf_state_t *);
void (osal_fastcall *readmemd[0x10000])(usf_state_t *);
void (osal_fastcall *writemem[0x10000])(usf_state_t *);
void (osal_fastcall *writememb[0x10000])(usf_state_t *);
void (osal_fastcall *writememh[0x10000])(usf_state_t *);
void (osal_fastcall *writememd[0x10000])(usf_state_t *);
// main/rom.c
unsigned char* g_rom/* = NULL*/;
int g_rom_size/* = 0*/;
m64p_rom_header ROM_HEADER;
rom_params ROM_PARAMS;
// r4300/pure_interp.c
precomp_instr interp_PC;
// r4300/r4300.c
unsigned int r4300emu/* = 0*/;
unsigned int count_per_op/* = COUNT_PER_OP_DEFAULT*/;
int llbit, rompause;
int stop;
long long int reg[32], hi, lo;
unsigned int next_interupt;
precomp_instr *PC;
long long int local_rs;
unsigned int delay_slot, skip_jump/* = 0*/, dyna_interp/* = 0*/, last_addr;
cpu_instruction_table current_instruction_table;
// r4300/reset.c
int reset_hard_job/* = 0*/;
// r4300/cp0.c
unsigned int g_cp0_regs[CP0_REGS_COUNT];
// r4300/cp1.c
float *reg_cop1_simple[32];
double *reg_cop1_double[32];
int FCR0, FCR31;
long long int reg_cop1_fgr_64[32];
int rounding_mode/* = 0x33F*/;
// These constants won't be written to, but they need to be located within the struct
int trunc_mode/* = 0xF3F*/, round_mode/* = 0x33F*/,
ceil_mode/* = 0xB3F*/, floor_mode/* = 0x73F*/;
// r4300/interupt.c
int interupt_unsafe_state/* = 0*/;
int SPECIAL_done/* = 0*/;
struct interrupt_queue q;
// r4300/tlb.c
tlb tlb_e[32];
unsigned int tlb_LUT_r[0x100000];
unsigned int tlb_LUT_w[0x100000];
// r4300/instr_counters.c
#ifdef COUNT_INSTR
unsigned int instr_count[132];
#endif
// r4300/cached_interp.c
char invalid_code[0x100000];
precomp_block *blocks[0x100000];
precomp_block *actual;
unsigned int jump_to_address;
// r4300/recomp.c
precomp_instr *dst; // destination structure for the recompiled instruction
int code_length; // current real recompiled code length
int max_code_length; // current recompiled code's buffer length
unsigned char **inst_pointer; // output buffer for recompiled code
precomp_block *dst_block; // the current block that we are recompiling
int src; // the current recompiled instruction
int fast_memory;
int no_compiled_jump /* = 0*/; /* use cached interpreter instead of recompiler for jumps */
void (*recomp_func)(usf_state_t *); // pointer to the dynarec's generator
// function for the latest decoded opcode
int *SRC; // currently recompiled instruction in the input stream
int check_nop; // next instruction is nop ?
int delay_slot_compiled/* = 0*/;
int init_length;
int cycle_count;
#ifdef DYNAREC
#ifdef _MSC_VER
#define __i386__
#endif
// r4300/(x86|x86_64)/assemble.c
unsigned int g_jump_start8/* = 0*/;
unsigned int g_jump_start32/* = 0*/;
jump_table *jumps_table/* = NULL*/;
int jumps_number/* = 0*/, max_jumps_number/* = 0*/;
// r4300/x86_64/assemble.c
#if defined(__x86_64__)
riprelative_table *riprel_table/* = NULL*/;
int riprel_number/* = 0*/, max_riprel_number/* = 0*/;
#endif
// r4300/(x86|x86_64)/gr4300.c
precomp_instr fake_instr;
int branch_taken/* = 0*/;
// r4300/(x86|x86_64)/gspecial.c
unsigned int precomp_instr_size/* = sizeof(precomp_instr)*/;
// r4300/x86/rjump.c
#if defined(__i386__)
long save_esp;
long save_eip;
unsigned long *return_address;
#endif
// r4300/x86_64/rjump.c
#if defined(__x86_64__)
unsigned long long *return_address;
long long save_rsp/* = 0*/;
long long save_rip/* = 0*/;
#endif
// r4300/x86/regcache.c
#if defined(__i386__)
unsigned int* reg_content[8];
precomp_instr* last_access[8];
precomp_instr* free_since[8];
int dirty[8];
int r64[8];
unsigned int* r0;
#endif
// r4300/x86_64/regcache.c
#if defined(__x86_64__)
unsigned long long * reg_content[8];
precomp_instr* last_access[8];
precomp_instr* free_since[8];
int dirty[8];
int is64bits[8];
unsigned long long *r0;
#endif
#endif
// logging
#ifdef DEBUG_INFO
FILE * debug_log;
#endif
};
void usf_set_audio_format(void *, unsigned int frequency, unsigned int bits);
void usf_push_audio_samples(void *, const void * buffer, size_t size);
#define USF_STATE_HELPER ((usf_state_helper_t *)(state))
#define USF_STATE ((usf_state_t *)(((uint8_t *)(state))+((usf_state_helper_t *)(state))->offset_to_structure))
#endif