470 lines
11 KiB
C
470 lines
11 KiB
C
/* Copyright 2003-2005 Guillaume Duhamel
|
|
Copyright 2004-2006 Theo Berkau
|
|
|
|
This file is part of Yabause.
|
|
|
|
Yabause is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Yabause is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Yabause; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#ifndef SH2CORE_H
|
|
#define SH2CORE_H
|
|
|
|
#include "core.h"
|
|
#include "memory.h"
|
|
|
|
#define SH2CORE_DEFAULT -1
|
|
#define MAX_INTERRUPTS 50
|
|
|
|
#ifdef MACH
|
|
#undef MACH
|
|
#endif
|
|
|
|
// UBC Flags
|
|
#define BBR_CPA_NONE (0 << 6)
|
|
#define BBR_CPA_CPU (1 << 6)
|
|
#define BBR_CPA_PER (2 << 6)
|
|
|
|
#define BBR_IDA_NONE (0 << 4)
|
|
#define BBR_IDA_INST (1 << 4)
|
|
#define BBR_IDA_DATA (2 << 4)
|
|
|
|
#define BBR_RWA_NONE (0 << 2)
|
|
#define BBR_RWA_READ (1 << 2)
|
|
#define BBR_RWA_WRITE (2 << 2)
|
|
|
|
#define BBR_SZA_NONE (0 << 0)
|
|
#define BBR_SZA_BYTE (1 << 0)
|
|
#define BBR_SZA_WORD (2 << 0)
|
|
#define BBR_SZA_LONGWORD (3 << 0)
|
|
|
|
#define BRCR_CMFCA (1 << 15)
|
|
#define BRCR_CMFPA (1 << 14)
|
|
#define BRCR_EBBA (1 << 13)
|
|
#define BRCR_UMD (1 << 12)
|
|
#define BRCR_PCBA (1 << 10)
|
|
|
|
#define BRCR_CMFCB (1 << 7)
|
|
#define BRCR_CMFPB (1 << 6)
|
|
#define BRCR_SEQ (1 << 4)
|
|
#define BRCR_DBEB (1 << 3)
|
|
#define BRCR_PCBB (1 << 2)
|
|
|
|
typedef struct
|
|
{
|
|
u32 R[16];
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
union {
|
|
struct {
|
|
u32 reserved1:22;
|
|
u32 M:1;
|
|
u32 Q:1;
|
|
u32 I:4;
|
|
u32 reserved0:2;
|
|
u32 S:1;
|
|
u32 T:1;
|
|
} part;
|
|
u32 all;
|
|
} SR;
|
|
#else
|
|
union {
|
|
struct {
|
|
u32 T:1;
|
|
u32 S:1;
|
|
u32 reserved0:2;
|
|
u32 I:4;
|
|
u32 Q:1;
|
|
u32 M:1;
|
|
u32 reserved1:22;
|
|
} part;
|
|
u32 all;
|
|
} SR;
|
|
#endif
|
|
|
|
u32 GBR;
|
|
u32 VBR;
|
|
u32 MACH;
|
|
u32 MACL;
|
|
u32 PR;
|
|
u32 PC;
|
|
} sh2regs_struct;
|
|
|
|
typedef struct
|
|
{
|
|
u8 SMR; // 0xFFFFFE00
|
|
u8 BRR; // 0xFFFFFE01
|
|
u8 SCR; // 0xFFFFFE02
|
|
u8 TDR; // 0xFFFFFE03
|
|
u8 SSR; // 0xFFFFFE04
|
|
u8 RDR; // 0xFFFFFE05
|
|
u8 TIER; // 0xFFFFFE10
|
|
u8 FTCSR; // 0xFFFFFE11
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
union {
|
|
struct {
|
|
u16 H:8; // 0xFFFFFE12
|
|
u16 L:8; // 0xFFFFFE13
|
|
} part;
|
|
u16 all;
|
|
} FRC;
|
|
#else
|
|
union {
|
|
struct {
|
|
u16 L:8; // 0xFFFFFE13
|
|
u16 H:8; // 0xFFFFFE12
|
|
} part;
|
|
u16 all;
|
|
} FRC;
|
|
#endif
|
|
u16 OCRA; // 0xFFFFFE14/0xFFFFFE15
|
|
u16 OCRB; // 0xFFFFFE14/0xFFFFFE15
|
|
u8 TCR; // 0xFFFFFE16
|
|
u8 TOCR; // 0xFFFFFE17
|
|
u16 FICR; // 0xFFFFFE18
|
|
// 0xFFFFFE19
|
|
u16 IPRB; // 0xFFFFFE60
|
|
u16 VCRA; // 0xFFFFFE62
|
|
u16 VCRB; // 0xFFFFFE64
|
|
u16 VCRC; // 0xFFFFFE66
|
|
u16 VCRD; // 0xFFFFFE68
|
|
u8 DRCR0; // 0xFFFFFE71
|
|
u8 DRCR1; // 0xFFFFFE72
|
|
u8 WTCSR; // 0xFFFFFE80
|
|
u8 WTCNT; // 0xFFFFFE81
|
|
u8 RSTCSR; // 0xFFFFFE83
|
|
u8 SBYCR; // 0xFFFFFE91
|
|
u8 CCR; // 0xFFFFFE92
|
|
u16 ICR; // 0xFFFFFEE0
|
|
u16 IPRA; // 0xFFFFFEE2
|
|
u16 VCRWDT; // 0xFFFFFEE4
|
|
u32 DVSR; // 0xFFFFFF00
|
|
u32 DVDNT; // 0xFFFFFF04
|
|
u32 DVCR; // 0xFFFFFF08
|
|
u32 VCRDIV; // 0xFFFFFF0C
|
|
u32 DVDNTH; // 0xFFFFFF10
|
|
u32 DVDNTL; // 0xFFFFFF14
|
|
u32 DVDNTUH; // 0xFFFFFF18
|
|
u32 DVDNTUL; // 0xFFFFFF1C
|
|
#ifdef WORDS_BIGENDIAN
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF40
|
|
u32 L:16; // 0xFFFFFF42
|
|
} part;
|
|
u16 all;
|
|
} BARA;
|
|
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF44
|
|
u32 L:16; // 0xFFFFFF46
|
|
} part;
|
|
u16 all;
|
|
} BAMRA;
|
|
#else
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF42
|
|
u32 H:16; // 0xFFFFFF40
|
|
} part;
|
|
u16 all;
|
|
} BARA;
|
|
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF46
|
|
u32 H:16; // 0xFFFFFF44
|
|
} part;
|
|
u16 all;
|
|
} BAMRA;
|
|
#endif
|
|
u32 BBRA; // 0xFFFFFF48
|
|
#ifdef WORDS_BIGENDIAN
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF60
|
|
u32 L:16; // 0xFFFFFF62
|
|
} part;
|
|
u16 all;
|
|
} BARB;
|
|
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF64
|
|
u32 L:16; // 0xFFFFFF66
|
|
} part;
|
|
u16 all;
|
|
} BAMRB;
|
|
#else
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF62
|
|
u32 H:16; // 0xFFFFFF60
|
|
} part;
|
|
u16 all;
|
|
} BARB;
|
|
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF66
|
|
u32 H:16; // 0xFFFFFF64
|
|
} part;
|
|
u16 all;
|
|
} BAMRB;
|
|
#endif
|
|
u32 BBRB; // 0xFFFFFF68
|
|
#ifdef WORDS_BIGENDIAN
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF70
|
|
u32 L:16; // 0xFFFFFF72
|
|
} part;
|
|
u16 all;
|
|
} BDRB;
|
|
|
|
union {
|
|
struct {
|
|
u32 H:16; // 0xFFFFFF74
|
|
u32 L:16; // 0xFFFFFF76
|
|
} part;
|
|
u16 all;
|
|
} BDMRB;
|
|
#else
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF72
|
|
u32 H:16; // 0xFFFFFF70
|
|
} part;
|
|
u16 all;
|
|
} BDRB;
|
|
|
|
union {
|
|
struct {
|
|
u32 L:16; // 0xFFFFFF76
|
|
u32 H:16; // 0xFFFFFF74
|
|
} part;
|
|
u16 all;
|
|
} BDMRB;
|
|
#endif
|
|
u32 BRCR; // 0xFFFFFF78
|
|
u32 SAR0; // 0xFFFFFF80
|
|
u32 DAR0; // 0xFFFFFF84
|
|
u32 TCR0; // 0xFFFFFF88
|
|
u32 CHCR0; // 0xFFFFFF8C
|
|
u32 SAR1; // 0xFFFFFF90
|
|
u32 DAR1; // 0xFFFFFF94
|
|
u32 TCR1; // 0xFFFFFF98
|
|
u32 CHCR1; // 0xFFFFFF9C
|
|
u32 VCRDMA0;// 0xFFFFFFA0
|
|
u32 VCRDMA1;// 0xFFFFFFA8
|
|
u32 DMAOR; // 0xFFFFFFB0
|
|
u16 BCR1; // 0xFFFFFFE0
|
|
u16 BCR2; // 0xFFFFFFE4
|
|
u16 WCR; // 0xFFFFFFE8
|
|
u16 MCR; // 0xFFFFFFEC
|
|
u16 RTCSR; // 0xFFFFFFF0
|
|
u16 RTCNT; // 0xFFFFFFF4
|
|
u16 RTCOR; // 0xFFFFFFF8
|
|
} Onchip_struct;
|
|
|
|
typedef struct
|
|
{
|
|
u8 vector;
|
|
u8 level;
|
|
} interrupt_struct;
|
|
|
|
typedef struct
|
|
{
|
|
u32 addr;
|
|
} codebreakpoint_struct;
|
|
|
|
typedef struct
|
|
{
|
|
u32 addr;
|
|
u32 flags;
|
|
readbytefunc oldreadbyte;
|
|
readwordfunc oldreadword;
|
|
readlongfunc oldreadlong;
|
|
writebytefunc oldwritebyte;
|
|
writewordfunc oldwriteword;
|
|
writelongfunc oldwritelong;
|
|
} memorybreakpoint_struct;
|
|
|
|
#define MAX_BREAKPOINTS 10
|
|
|
|
typedef struct
|
|
{
|
|
codebreakpoint_struct codebreakpoint[MAX_BREAKPOINTS];
|
|
int numcodebreakpoints;
|
|
memorybreakpoint_struct memorybreakpoint[MAX_BREAKPOINTS];
|
|
int nummemorybreakpoints;
|
|
void (*BreakpointCallBack)(void *, u32);
|
|
int inbreakpoint;
|
|
} breakpoint_struct;
|
|
|
|
#define BREAK_BYTEREAD 0x1
|
|
#define BREAK_WORDREAD 0x2
|
|
#define BREAK_LONGREAD 0x4
|
|
#define BREAK_BYTEWRITE 0x8
|
|
#define BREAK_WORDWRITE 0x10
|
|
#define BREAK_LONGWRITE 0x20
|
|
|
|
typedef struct
|
|
{
|
|
sh2regs_struct regs;
|
|
Onchip_struct onchip;
|
|
|
|
struct
|
|
{
|
|
u32 leftover;
|
|
u32 shift;
|
|
} frc;
|
|
|
|
struct
|
|
{
|
|
int isenable;
|
|
int isinterval;
|
|
u32 leftover;
|
|
u32 shift;
|
|
} wdt;
|
|
|
|
interrupt_struct interrupts[MAX_INTERRUPTS];
|
|
u32 NumberOfInterrupts;
|
|
u32 AddressArray[0x100];
|
|
u8 DataArray[0x1000];
|
|
u32 delay;
|
|
u32 cycles;
|
|
u8 isslave;
|
|
u8 isIdle;
|
|
u8 isSleeping;
|
|
u16 instruction;
|
|
u8 breakpointEnabled;
|
|
breakpoint_struct bp;
|
|
|
|
} SH2_struct;
|
|
|
|
typedef struct
|
|
{
|
|
int id;
|
|
const char *Name;
|
|
|
|
int (*Init)(void);
|
|
void (*DeInit)(void);
|
|
void (*Reset)(SH2_struct *context);
|
|
void FASTCALL (*Exec)(SH2_struct *context, u32 cycles);
|
|
|
|
void (*GetRegisters)(SH2_struct *context, sh2regs_struct *regs);
|
|
u32 (*GetGPR)(SH2_struct *context, int num);
|
|
u32 (*GetSR)(SH2_struct *context);
|
|
u32 (*GetGBR)(SH2_struct *context);
|
|
u32 (*GetVBR)(SH2_struct *context);
|
|
u32 (*GetMACH)(SH2_struct *context);
|
|
u32 (*GetMACL)(SH2_struct *context);
|
|
u32 (*GetPR)(SH2_struct *context);
|
|
u32 (*GetPC)(SH2_struct *context);
|
|
|
|
void (*SetRegisters)(SH2_struct *context, const sh2regs_struct *regs);
|
|
void (*SetGPR)(SH2_struct *context, int num, u32 value);
|
|
void (*SetSR)(SH2_struct *context, u32 value);
|
|
void (*SetGBR)(SH2_struct *context, u32 value);
|
|
void (*SetVBR)(SH2_struct *context, u32 value);
|
|
void (*SetMACH)(SH2_struct *context, u32 value);
|
|
void (*SetMACL)(SH2_struct *context, u32 value);
|
|
void (*SetPR)(SH2_struct *context, u32 value);
|
|
void (*SetPC)(SH2_struct *context, u32 value);
|
|
|
|
void (*SendInterrupt)(SH2_struct *context, u8 vector, u8 level);
|
|
int (*GetInterrupts)(SH2_struct *context,
|
|
interrupt_struct interrupts[MAX_INTERRUPTS]);
|
|
void (*SetInterrupts)(SH2_struct *context, int num_interrupts,
|
|
const interrupt_struct interrupts[MAX_INTERRUPTS]);
|
|
|
|
void (*WriteNotify)(u32 start, u32 length);
|
|
} SH2Interface_struct;
|
|
|
|
extern SH2_struct *MSH2;
|
|
extern SH2_struct *SSH2;
|
|
extern SH2Interface_struct *SH2Core;
|
|
|
|
int SH2Init(int coreid);
|
|
void SH2DeInit(void);
|
|
void SH2Reset(SH2_struct *context);
|
|
void SH2PowerOn(SH2_struct *context);
|
|
void FASTCALL SH2Exec(SH2_struct *context, u32 cycles);
|
|
void SH2SendInterrupt(SH2_struct *context, u8 vector, u8 level);
|
|
void SH2NMI(SH2_struct *context);
|
|
void SH2Step(SH2_struct *context);
|
|
void SH2GetRegisters(SH2_struct *context, sh2regs_struct * r);
|
|
void SH2SetRegisters(SH2_struct *context, sh2regs_struct * r);
|
|
void SH2WriteNotify(u32 start, u32 length);
|
|
|
|
void SH2SetBreakpointCallBack(SH2_struct *context, void (*func)(void *, u32));
|
|
int SH2AddCodeBreakpoint(SH2_struct *context, u32 addr);
|
|
int SH2DelCodeBreakpoint(SH2_struct *context, u32 addr);
|
|
codebreakpoint_struct *SH2GetBreakpointList(SH2_struct *context);
|
|
void SH2ClearCodeBreakpoints(SH2_struct *context);
|
|
|
|
static INLINE void SH2HandleBreakpoints(SH2_struct *context)
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i < context->bp.numcodebreakpoints; i++) {
|
|
if ((context->regs.PC == context->bp.codebreakpoint[i].addr) && context->bp.inbreakpoint == 0) {
|
|
context->bp.inbreakpoint = 1;
|
|
if (context->bp.BreakpointCallBack)
|
|
context->bp.BreakpointCallBack(context, context->bp.codebreakpoint[i].addr);
|
|
context->bp.inbreakpoint = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int SH2AddMemoryBreakpoint(SH2_struct *context, u32 addr, u32 flags);
|
|
int SH2DelMemoryBreakpoint(SH2_struct *context, u32 addr);
|
|
memorybreakpoint_struct *SH2GetMemoryBreakpointList(SH2_struct *context);
|
|
void SH2ClearMemoryBreakpoints(SH2_struct *context);
|
|
|
|
void DMAExec(void);
|
|
void DMATransfer(u32 *CHCR, u32 *SAR, u32 *DAR, u32 *TCR, u32 *VCRDMA);
|
|
|
|
u8 FASTCALL OnchipReadByte(u32 addr);
|
|
u16 FASTCALL OnchipReadWord(u32 addr);
|
|
u32 FASTCALL OnchipReadLong(u32 addr);
|
|
void FASTCALL OnchipWriteByte(u32 addr, u8 val);
|
|
void FASTCALL OnchipWriteWord(u32 addr, u16 val);
|
|
void FASTCALL OnchipWriteLong(u32 addr, u32 val);
|
|
|
|
u32 FASTCALL AddressArrayReadLong(u32 addr);
|
|
void FASTCALL AddressArrayWriteLong(u32 addr, u32 val);
|
|
|
|
u8 FASTCALL DataArrayReadByte(u32 addr);
|
|
u16 FASTCALL DataArrayReadWord(u32 addr);
|
|
u32 FASTCALL DataArrayReadLong(u32 addr);
|
|
void FASTCALL DataArrayWriteByte(u32 addr, u8 val);
|
|
void FASTCALL DataArrayWriteWord(u32 addr, u16 val);
|
|
void FASTCALL DataArrayWriteLong(u32 addr, u32 val);
|
|
|
|
void FASTCALL MSH2InputCaptureWriteWord(u32 addr, u16 data);
|
|
void FASTCALL SSH2InputCaptureWriteWord(u32 addr, u16 data);
|
|
|
|
int SH2SaveState(SH2_struct *context, FILE *fp);
|
|
int SH2LoadState(SH2_struct *context, FILE *fp, int version, int size);
|
|
|
|
#if defined(SH2_DYNAREC)
|
|
extern SH2Interface_struct SH2Dynarec;
|
|
#endif
|
|
|
|
#endif
|