296 lines
9.2 KiB
C
296 lines
9.2 KiB
C
#ifndef __VUE_H__
|
|
#define __VUE_H__
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* API management */
|
|
#ifndef VUEAPI
|
|
#define VUEAPI extern
|
|
#endif
|
|
|
|
/* Header includes */
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* Constants *
|
|
*****************************************************************************/
|
|
|
|
/* Boolean values */
|
|
#define VUE_FALSE 0
|
|
#define VUE_TRUE 1
|
|
|
|
/* Memory access types */
|
|
#define VUE_S8 0
|
|
#define VUE_U8 1
|
|
#define VUE_S16 2
|
|
#define VUE_U16 3
|
|
#define VUE_S32 4
|
|
#define VUE_CANCEL 5
|
|
|
|
/* System register indexes */
|
|
#define VUE_ADTRE 25
|
|
#define VUE_CHCW 24
|
|
#define VUE_ECR 4
|
|
#define VUE_EIPC 0
|
|
#define VUE_EIPSW 1
|
|
#define VUE_FEPC 2
|
|
#define VUE_FEPSW 3
|
|
#define VUE_PIR 6
|
|
#define VUE_PSW 5
|
|
#define VUE_TKCW 7
|
|
|
|
/* Non-standard register indexes */
|
|
#define VUE_PC -1
|
|
#define VUE_JUMP_FROM -2
|
|
#define VUE_JUMP_TO -3
|
|
|
|
/* Program register indexes */
|
|
#define VUE_GP 4
|
|
#define VUE_HP 2
|
|
#define VUE_LP 31
|
|
#define VUE_SP 3
|
|
#define VUE_TP 5
|
|
|
|
/* Instruction IDs */
|
|
#define VUE_ILLEGAL -1
|
|
#define VUE_ADD_IMM 0
|
|
#define VUE_ADD_REG 1
|
|
#define VUE_ADDF_S 2
|
|
#define VUE_ADDI 3
|
|
#define VUE_AND 4
|
|
#define VUE_ANDBSU 5
|
|
#define VUE_ANDI 6
|
|
#define VUE_ANDNBSU 7
|
|
#define VUE_BCOND 8
|
|
#define VUE_CAXI 9
|
|
#define VUE_CLI 10
|
|
#define VUE_CMP_IMM 11
|
|
#define VUE_CMP_REG 12
|
|
#define VUE_CMPF_S 13
|
|
#define VUE_CVT_SW 14
|
|
#define VUE_CVT_WS 15
|
|
#define VUE_DIV 16
|
|
#define VUE_DIVF_S 17
|
|
#define VUE_DIVU 18
|
|
#define VUE_HALT 19
|
|
#define VUE_IN_B 20
|
|
#define VUE_IN_H 21
|
|
#define VUE_IN_W 22
|
|
#define VUE_JAL 23
|
|
#define VUE_JMP 24
|
|
#define VUE_JR 25
|
|
#define VUE_LD_B 26
|
|
#define VUE_LD_H 27
|
|
#define VUE_LD_W 28
|
|
#define VUE_LDSR 29
|
|
#define VUE_MOV_IMM 30
|
|
#define VUE_MOV_REG 31
|
|
#define VUE_MOVBSU 32
|
|
#define VUE_MOVEA 33
|
|
#define VUE_MOVHI 34
|
|
#define VUE_MPYHW 35
|
|
#define VUE_MUL 36
|
|
#define VUE_MULF_S 37
|
|
#define VUE_MULU 38
|
|
#define VUE_NOT 39
|
|
#define VUE_NOTBSU 40
|
|
#define VUE_OR 41
|
|
#define VUE_ORBSU 42
|
|
#define VUE_ORI 43
|
|
#define VUE_ORNBSU 44
|
|
#define VUE_OUT_B 45
|
|
#define VUE_OUT_H 46
|
|
#define VUE_OUT_W 47
|
|
#define VUE_RETI 48
|
|
#define VUE_REV 49
|
|
#define VUE_SAR_IMM 50
|
|
#define VUE_SAR_REG 51
|
|
#define VUE_SCH0BSD 52
|
|
#define VUE_SCH0BSU 53
|
|
#define VUE_SCH1BSD 54
|
|
#define VUE_SCH1BSU 55
|
|
#define VUE_SEI 56
|
|
#define VUE_SETF 57
|
|
#define VUE_SHL_IMM 58
|
|
#define VUE_SHL_REG 59
|
|
#define VUE_SHR_IMM 60
|
|
#define VUE_SHR_REG 61
|
|
#define VUE_ST_B 62
|
|
#define VUE_ST_H 63
|
|
#define VUE_ST_W 64
|
|
#define VUE_STSR 65
|
|
#define VUE_SUB 66
|
|
#define VUE_SUBF_S 67
|
|
#define VUE_TRAP 68
|
|
#define VUE_TRNC_SW 69
|
|
#define VUE_XB 70
|
|
#define VUE_XH 71
|
|
#define VUE_XOR 72
|
|
#define VUE_XORBSU 73
|
|
#define VUE_XORI 74
|
|
#define VUE_XORNBSU 75
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* Types *
|
|
*****************************************************************************/
|
|
|
|
/* Forward references */
|
|
typedef struct Vue Vue;
|
|
|
|
/* Boolean */
|
|
typedef int vbool;
|
|
|
|
/* Access state */
|
|
typedef struct {
|
|
uint32_t address; /* CPU bus address */
|
|
int32_t value; /* Value read/to write */
|
|
int8_t fetch; /* Index of machine code unit */
|
|
int8_t type; /* Data type */
|
|
} VueAccess;
|
|
|
|
/* Instruction state */
|
|
typedef struct {
|
|
int32_t bits; /* Binary encoding */
|
|
int32_t disp; /* Displacement for jumps and branches */
|
|
int32_t imm; /* Immediate operand */
|
|
uint8_t cond; /* Condition for Bcond */
|
|
int8_t format; /* Binary format */
|
|
int8_t id; /* Library-specific identifier */
|
|
uint8_t opcode; /* Instruction opcode */
|
|
uint8_t reg1; /* Source/right register */
|
|
uint8_t reg2; /* Destination/left register */
|
|
uint8_t size; /* Number of bytes in encoding */
|
|
uint8_t subopcode; /* Instruction subopcode */
|
|
} VueInstruction;
|
|
|
|
/* Breakpoint handler callbacks */
|
|
typedef int32_t (*VueOnAccess )(Vue *, VueAccess *);
|
|
typedef int32_t (*VueOnException)(Vue *, uint16_t );
|
|
typedef int32_t (*VueOnExecute )(Vue *, VueInstruction *);
|
|
typedef int32_t (*VueOnFrame )(Vue * );
|
|
|
|
/* Emulation state */
|
|
struct Vue {
|
|
void *tag; /* Application reference */
|
|
int32_t breakCode; /* Application break code */
|
|
uint8_t wram[0x10000]; /* System memory */
|
|
|
|
/* Breakpoint handlers */
|
|
VueOnException onException;
|
|
VueOnExecute onExecute;
|
|
VueOnFrame onFrame;
|
|
VueOnAccess onRead;
|
|
VueOnAccess onWrite;
|
|
|
|
/* CPU state */
|
|
struct {
|
|
VueAccess access; /* Access state */
|
|
VueInstruction inst; /* Instruction state */
|
|
uint32_t cycles; /* Cycles until next stage */
|
|
int32_t jumpFrom[3]; /* Source PCs of most recent jumps */
|
|
int32_t jumpTo [3]; /* Destination PCs of most recent jumps */
|
|
uint16_t exception; /* Exception code */
|
|
uint16_t irq; /* Interrupt lines */
|
|
int fetch; /* Fetch unit index */
|
|
int stage; /* Current processing stage */
|
|
|
|
/* Program registers */
|
|
int32_t program[32];
|
|
|
|
/* System registers */
|
|
int32_t adtre; /* Address Trap Register for Execution */
|
|
int32_t eipc; /* Exception/interrupt PC */
|
|
int32_t eipsw; /* Exception/interrupt PSW */
|
|
int32_t fepc; /* Duplexed exception PC */
|
|
int32_t fepsw; /* Duplexed exception PSW */
|
|
int32_t pc; /* Program Counter */
|
|
int32_t sr29; /* System register 29 */
|
|
int32_t sr31; /* System register 31 */
|
|
|
|
/* Program Status Word */
|
|
int8_t psw_ae; /* Address Trap Enable */
|
|
int8_t psw_ep; /* Exception Pending */
|
|
int8_t psw_id; /* Interrupt Disable */
|
|
int8_t psw_cy; /* Carry */
|
|
int8_t psw_fiv; /* Floating Reserved Operand */
|
|
int8_t psw_fov; /* Floating Overflow */
|
|
int8_t psw_fpr; /* Floating Precision */
|
|
int8_t psw_fro; /* Floating Reserved Operand */
|
|
int8_t psw_fud; /* Floating Underflow */
|
|
int8_t psw_fzd; /* Floating Zero Divide */
|
|
int8_t psw_i; /* Interrupt Level */
|
|
int8_t psw_np; /* NMI Pending */
|
|
int8_t psw_ov; /* Overflow */
|
|
int8_t psw_s; /* Sign */
|
|
int8_t psw_z; /* Zero */
|
|
|
|
/* Cache Control Word */
|
|
uint16_t chcw_cec; /* Clear Entry Count */
|
|
uint16_t chcw_cen; /* Clear Entry Number */
|
|
int8_t chcw_icc; /* Instruction Cache Clear */
|
|
int8_t chcw_icd; /* Instruction Cache Dump */
|
|
int8_t chcw_ice; /* Instruction Cache Enable */
|
|
int8_t chcw_icr; /* Instruction Cache Restore */
|
|
int32_t chcw_sa; /* Spill-Out Base Address */
|
|
|
|
/* Exception Cause Register */
|
|
uint16_t ecr_eicc; /* Exception/Interrupt Cause Code */
|
|
uint16_t ecr_fecc; /* Fatal Error Cause Code */
|
|
} cpu;
|
|
|
|
/* Game pak state */
|
|
struct {
|
|
uint8_t *ram; /* Cartridge SRAM */
|
|
uint32_t ramSize; /* Number of bytes in cartridge SRAM */
|
|
uint8_t *rom; /* Cartridge ROM */
|
|
uint32_t romSize; /* Number of bytes in cartridge ROM */
|
|
int8_t wcr_exp1w; /* Expansion one-wait mode */
|
|
int8_t wcr_rom1w; /* ROM one-wait mode */
|
|
} pak;
|
|
|
|
/* VIP state */
|
|
struct {
|
|
uint8_t vram[0x40000]; /* Video memory */
|
|
} vip;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function Prototypes *
|
|
*****************************************************************************/
|
|
|
|
VUEAPI uint32_t vueEmulate (Vue *vue, uint32_t maxCycles);
|
|
VUEAPI int32_t vueGetBreakCode (Vue *vue);
|
|
VUEAPI uint16_t vueGetExceptionCode (Vue *vue);
|
|
VUEAPI int32_t vueGetRegister (Vue *vue, int32_t index, vbool system);
|
|
VUEAPI void* vueGetTag (Vue *vue);
|
|
VUEAPI void vueInitialize (Vue *vue);
|
|
VUEAPI VueOnException vueOnException (Vue *vue, VueOnException callback);
|
|
VUEAPI VueOnExecute vueOnExecute (Vue *vue, VueOnExecute callback);
|
|
VUEAPI VueOnFrame vueOnFrame (Vue *vue, VueOnFrame callback);
|
|
VUEAPI VueOnAccess vueOnRead (Vue *vue, VueOnAccess callback);
|
|
VUEAPI VueOnAccess vueOnWrite (Vue *vue, VueOnAccess callback);
|
|
VUEAPI int32_t vueRead (Vue *vue, uint32_t address, int32_t type);
|
|
VUEAPI vbool vueReadBytes (Vue *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
|
VUEAPI void vueReset (Vue *vue);
|
|
VUEAPI int32_t vueSetRegister (Vue *vue, int32_t index, vbool system, int32_t value);
|
|
VUEAPI vbool vueSetROM (Vue *vue, uint8_t *rom, uint32_t size);
|
|
VUEAPI void* vueSetTag (Vue *vue, void *tag);
|
|
VUEAPI void vueWrite (Vue *vue, uint32_t address, int32_t type, int32_t value);
|
|
VUEAPI vbool vueWriteBytes (Vue *vue, uint32_t address, uint8_t *src, uint32_t length);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* __VUE_H__ */
|