Updated lazyusf

CQTexperiment
Chris Moeller 2014-11-23 21:39:42 -08:00
parent 55d6e5050c
commit 339ba527c5
13 changed files with 1027 additions and 21 deletions

View File

@ -7,6 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
8319EF191A219846009DD5C4 /* cpu_hle.c in Sources */ = {isa = PBXBuildFile; fileRef = 8319EF171A219846009DD5C4 /* cpu_hle.c */; };
8319EF1A1A219846009DD5C4 /* cpu_hle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8319EF181A219846009DD5C4 /* cpu_hle.h */; };
8319EF1D1A2198B9009DD5C4 /* os.c in Sources */ = {isa = PBXBuildFile; fileRef = 8319EF1B1A2198B9009DD5C4 /* os.c */; };
8319EF1E1A2198B9009DD5C4 /* os.h in Headers */ = {isa = PBXBuildFile; fileRef = 8319EF1C1A2198B9009DD5C4 /* os.h */; };
8319EF211A219BE7009DD5C4 /* audiolib.c in Sources */ = {isa = PBXBuildFile; fileRef = 8319EF1F1A219BE7009DD5C4 /* audiolib.c */; };
8319EF221A219BE7009DD5C4 /* audiolib.h in Headers */ = {isa = PBXBuildFile; fileRef = 8319EF201A219BE7009DD5C4 /* audiolib.h */; };
8378416A18C6E56B002C4FE5 /* alist.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415418C6E56B002C4FE5 /* alist.c */; };
8378416B18C6E56B002C4FE5 /* alist.h in Headers */ = {isa = PBXBuildFile; fileRef = 8378415518C6E56B002C4FE5 /* alist.h */; };
8378416C18C6E56B002C4FE5 /* alist_audio.c in Sources */ = {isa = PBXBuildFile; fileRef = 8378415618C6E56B002C4FE5 /* alist_audio.c */; };
@ -110,6 +116,12 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
8319EF171A219846009DD5C4 /* cpu_hle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cpu_hle.c; sourceTree = "<group>"; };
8319EF181A219846009DD5C4 /* cpu_hle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cpu_hle.h; sourceTree = "<group>"; };
8319EF1B1A2198B9009DD5C4 /* os.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = os.c; sourceTree = "<group>"; };
8319EF1C1A2198B9009DD5C4 /* os.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = os.h; sourceTree = "<group>"; };
8319EF1F1A219BE7009DD5C4 /* audiolib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = audiolib.c; sourceTree = "<group>"; };
8319EF201A219BE7009DD5C4 /* audiolib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = audiolib.h; sourceTree = "<group>"; };
8378415418C6E56B002C4FE5 /* alist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist.c; sourceTree = "<group>"; };
8378415518C6E56B002C4FE5 /* alist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = alist.h; sourceTree = "<group>"; };
8378415618C6E56B002C4FE5 /* alist_audio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = alist_audio.c; sourceTree = "<group>"; };
@ -287,6 +299,12 @@
83C8B62B18AF57770071B040 /* lazyusf */ = {
isa = PBXGroup;
children = (
8319EF1F1A219BE7009DD5C4 /* audiolib.c */,
8319EF201A219BE7009DD5C4 /* audiolib.h */,
8319EF1B1A2198B9009DD5C4 /* os.c */,
8319EF1C1A2198B9009DD5C4 /* os.h */,
8319EF171A219846009DD5C4 /* cpu_hle.c */,
8319EF181A219846009DD5C4 /* cpu_hle.h */,
8378415318C6E56B002C4FE5 /* rsp_hle */,
83C8B6FD18AF59E70071B040 /* lazyusf-Info.plist */,
83C8B65A18AF58080071B040 /* audio.h */,
@ -415,11 +433,13 @@
83C8B6B918AF58080071B040 /* main.h in Headers */,
83C8B6F418AF58090071B040 /* rsp.h in Headers */,
8378417018C6E56B002C4FE5 /* arithmetics.h in Headers */,
8319EF221A219BE7009DD5C4 /* audiolib.h in Headers */,
83C8B6C018AF58080071B040 /* registers.h in Headers */,
83C8B6BE18AF58080071B040 /* pif.h in Headers */,
83C8B6F618AF58090071B040 /* tlb.h in Headers */,
83C8B6F718AF58090071B040 /* types.h in Headers */,
83C8B6BB18AF58080071B040 /* memory.h in Headers */,
8319EF1E1A2198B9009DD5C4 /* os.h in Headers */,
83C8B6BC18AF58080071B040 /* opcode.h in Headers */,
83C8B6B718AF58080071B040 /* interpreter_ops.h in Headers */,
83C8B6B318AF58080071B040 /* exception.h in Headers */,
@ -471,6 +491,7 @@
83C8B6E918AF58080071B040 /* vrcp.h in Headers */,
83C8B6D318AF58080071B040 /* vlt.h in Headers */,
83C8B6C118AF58080071B040 /* config.h in Headers */,
8319EF1A1A219846009DD5C4 /* cpu_hle.h in Headers */,
83C8B6DF18AF58080071B040 /* vmudm.h in Headers */,
83C8B6D818AF58080071B040 /* vmadl.h in Headers */,
83C8B6EB18AF58090071B040 /* vrcpl.h in Headers */,
@ -564,8 +585,11 @@
83C8B6AE18AF58080071B040 /* cpu.c in Sources */,
83C8B6AB18AF58080071B040 /* audio.c in Sources */,
83A2249418CAC28500FE4173 /* hle.c in Sources */,
8319EF191A219846009DD5C4 /* cpu_hle.c in Sources */,
8319EF1D1A2198B9009DD5C4 /* os.c in Sources */,
8378416E18C6E56B002C4FE5 /* alist_naudio.c in Sources */,
83C8B6B218AF58080071B040 /* exception.c in Sources */,
8319EF211A219BE7009DD5C4 /* audiolib.c in Sources */,
83C8B6BF18AF58080071B040 /* registers.c in Sources */,
83C8B6F918AF58090071B040 /* usf.c in Sources */,
83C8B6B818AF58080071B040 /* main.c in Sources */,

View File

@ -0,0 +1,273 @@
#include "usf.h"
#include "usf_internal.h"
#include "cpu_hle.h"
#include "audiolib.h"
#include "os.h"
#include "main.h"
#include "memory.h"
#define N64WORD(x) (*(uint32_t*)PageVRAM((x)))
#define N64HALF(x) (*(uint16_t*)PageVRAM((x)))
#define N64BYTE(x) (*(uint8_t*)PageVRAM((x)))
int alCopy(usf_state_t * state, int paddr) {
uint32_t source = (state->GPR[4].UW[0]);
uint32_t dest = (state->GPR[5].UW[0]);
uint32_t len = (state->GPR[6].UW[0]);
if(len&3)
DisplayError(state, "OMG!!!! - alCopy length & 3\n");
memcpyn642n64(state, dest, source, len);
return 1;
}
int alLink(usf_state_t * state, int paddr) {
ALLink *element = (ALLink*)PageVRAM(state->GPR[4].UW[0]);
ALLink *after = (ALLink*)PageVRAM(state->GPR[5].UW[0]);
ALLink *afterNext;
element->next = after->next;
element->prev = state->GPR[5].UW[0];
if (after->next) {
afterNext = (ALLink*)PageVRAM(after->next);
afterNext->prev = state->GPR[4].UW[0];
}
after->next = state->GPR[4].UW[0];
return 1;
}
int alUnLink(usf_state_t * state, int paddr) {
ALLink *element = (ALLink*)PageVRAM(state->GPR[4].UW[0]);
ALLink *elementNext = (ALLink*)PageVRAM(element->next);
ALLink *elementPrev = (ALLink*)PageVRAM(element->prev);
// _asm int 3
if (element->next)
elementNext->prev = element->prev;
if (element->prev)
elementPrev->next = element->next;
return 1;
}
int alEvtqPostEvent(usf_state_t * state, int paddr) {
ALEventQueue *evtq;
ALEvent *events;
uint32_t A0 = state->GPR[4].UW[0];
uint32_t A1 = state->GPR[5].UW[0];
uint32_t DeltaTime = state->GPR[6].UW[0];
uint32_t nodeNext = 0;
uint32_t nextItem = 0;
uint32_t node = 0;
uint32_t nextDelta = 0;
uint32_t item = 0;
uint32_t postWhere = 0;
uint32_t NEXT = 0;
uint32_t nextItemDelta = 0;
evtq = (ALEventQueue *)PageVRAM(A0);
events = (ALEvent *)PageVRAM(A1);
//_asm int 3
NEXT = evtq->freeList.next;
if(NEXT == 0)
return 1;
//DisplayError("%08x", N64WORD(0x800533E4));
//cprintf("%08x\t%08x\n", N64WORD(0x800533D4), N64WORD(0x800533D8));
item = NEXT;
state->GPR[4].UW[0] = NEXT;
alUnLink(state, 0);
state->GPR[4].UW[0] = A1; state->GPR[5].UW[0] = NEXT + 0xC; state->GPR[6].UW[0] = 0x10;
alCopy(state, 0);
postWhere = (DeltaTime==0x7FFFFFFF)?1:0;
nodeNext = A0;
node = nodeNext + 8;
while(nodeNext !=0 ) {
nodeNext = *(uint32_t*)PageVRAM(node);
if(nodeNext != 0) {
nextDelta = *(uint32_t*)PageVRAM(nodeNext + 8);
nextItem = nodeNext;
if(DeltaTime < nextDelta) {
*(uint32_t*)PageVRAM(item + 8) = DeltaTime;
nextItemDelta = *(uint32_t*)PageVRAM(nextItem + 8);
*(uint32_t*)PageVRAM(nextItem + 8) = nextItemDelta - DeltaTime;
state->GPR[4].UW[0] = item; state->GPR[5].UW[0] = node;
alLink(state, 0);
return 1;
} else {
node = nodeNext;
DeltaTime -= nextDelta;
if(node == 0)
return 1;
}
}
}
if(postWhere == 0)
*(uint32_t*)PageVRAM(item + 8) = DeltaTime;
else
*(uint32_t*)PageVRAM(item + 8) = 0;
state->GPR[4].UW[0] = item; state->GPR[5].UW[0] = node;
alLink(state, 0);
return 1;
}
int alEvtqPostEvent_Alt(usf_state_t * state, int paddr) {
return 0;
}
#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
#endif
int32_t __nextSampleTime(usf_state_t * state, int32_t driver, int32_t *client) {
uint32_t c = 0;
int32_t deltaTime = 0x7FFFFFFF;
*client = 0;
for(c = N64WORD(driver); c != 0; c = N64WORD(c)) {
int samplesLeft = N64WORD(c + 0x10);
int curSamples = N64WORD(driver + 0x20);
if((samplesLeft - curSamples) < deltaTime) {
*client = c;
deltaTime = samplesLeft - curSamples;
}
}
return N64WORD((*client)+0x10);
}
int32_t _timeToSamplesNoRound(usf_state_t * state, long synth, long micros)
{
uint32_t outputRate = N64WORD(synth+0x44);
float tmp = ((float)micros) * outputRate / 1000000.0 + 0.5;
//DisplayError("Smaple rate is %d", outputRate);
return (int32_t)tmp;
}
int32_t byteswap(char b[4] ) {
int32_t out = 0;
out += b[3];
out += b[2] << 8;
out += b[1] << 16;
out += b[0] << 24;
return out;
}
int alAudioFrame(usf_state_t * state, int paddr) {
ALPlayer *cl;
uint32_t alGlobals = 0;
uint32_t driver = 0, head = 0, deltaTime = 0, c = 0, *paramSamples, *curSamples, handler = 0, dl = 0;
int32_t client = 0;
uint32_t A0 = state->GPR[4].UW[0];
uint32_t A1 = state->GPR[5].UW[0];
uint32_t A2 = state->GPR[6].UW[0];
uint32_t outLen = state->GPR[7].UW[0];
uint32_t cmdlEnd = A0;
uint32_t lOutBuf = A2;
alGlobals = ((*(uint16_t*)PageRAM2(paddr + 0x8)) & 0xFFFF) << 16; //alGlobals->drvr
alGlobals += *(int16_t*)PageRAM2(paddr + 0xc);
//alGlobals = 0x80750C74;
driver = N64WORD(alGlobals);
paramSamples = (uint32_t*) PageVRAM(driver + 0x1c);
curSamples = (uint32_t*) PageVRAM(driver + 0x20);
if(N64WORD(driver) == 0) { // if(drvr->head == 0)
N64WORD(A1) = 0;
state->GPR[2].UW[0] = A0;
return 1;
}
for(*paramSamples = __nextSampleTime(state, driver, &client); (*paramSamples - *curSamples) < outLen; *paramSamples = __nextSampleTime(state, driver, &client)) {
int32_t *cSamplesLeft;
cSamplesLeft = (int32_t *) PageVRAM(client + 0x10);
*paramSamples &= ~0xf;
//run handler (not-HLE'd)
state->GPR[4].UW[0] = client;
RunFunction(state, N64WORD(client+0x8));
*cSamplesLeft += _timeToSamplesNoRound(state, driver, state->GPR[2].UW[0]);
}
*paramSamples &= ~0xf;
//give us some stack
state->GPR[0x1d].UW[0] -= 0x20;
N64WORD(state->GPR[0x1d].UW[0]+0x4) = 0; //tmp
while (outLen > 0) {
int32_t maxOutSamples = 0, nOut = 0, cmdPtr = 0, output = 0, setParam = 0, handler = 0, tmp = 0x700000;
maxOutSamples = N64WORD(driver + 0x48);
nOut = MIN(maxOutSamples, outLen);
cmdPtr = cmdlEnd;//+8;
output = N64WORD(driver + 0x38);
setParam = N64WORD(output+8); // alSaveParam
state->GPR[4].DW = output;
state->GPR[5].DW = 0x6; // AL_FILTER_SET_DRAM
state->GPR[6].DW = lOutBuf;
RunFunction(state, setParam);
handler = N64WORD(output+4); // alSavePull
state->GPR[4].DW = output;
state->GPR[5].DW = state->GPR[0x1d].UW[0]+0x12; //&tmp
state->GPR[6].DW = nOut;
state->GPR[7].DW = *curSamples;
N64WORD(state->GPR[0x1d].UW[0]+0x10) = cmdPtr;
RunFunction(state, handler);
curSamples = (uint32_t *) PageVRAM(driver + 0x20);
cmdlEnd = state->GPR[2].UW[0];
outLen -= nOut;
lOutBuf += (nOut<<2);
*curSamples += nOut;
}
state->GPR[0x1d].UW[0] += 0x20;
N64WORD(A1) = (int32_t) ((cmdlEnd - A0) >> 3);
state->GPR[4].UW[0] = driver;
while( (dl = N64WORD(driver+0x14)) ) {
state->GPR[4].UW[0] = dl;
alUnLink(state, 0);
state->GPR[4].UW[0] = dl;
state->GPR[5].UW[0] = driver + 4;
alLink(state, 0);
}
state->GPR[2].UW[0] = cmdlEnd;
return 1;
}

View File

@ -0,0 +1,60 @@
#ifndef _CPU_HLE_AUDIOLIB_
#define _CPU_HLE_AUDIOLIB_
#include "cpu_hle.h"
#include "os.h"
// a few of these structures/type were sequestered from SGI\Nindendo's code
typedef struct ALLink_s {
uint32_t next;
uint32_t prev;
} ALLink;
typedef struct {
ALLink freeList;
ALLink allocList;
int32_t eventCount;
} ALEventQueue;
typedef struct {
uint16_t type;
uint8_t msg[12];
} ALEvent;
typedef struct {
ALLink node;
int32_t delta; //microtime
ALEvent event;
} ALEventListItem;
int alCopy(usf_state_t *, int paddr);
int alLink(usf_state_t *, int paddr);
int alUnLink(usf_state_t *, int paddr);
int alEvtqPostEvent(usf_state_t *, int paddr) ;
int alEvtqPostEvent_Alt(usf_state_t *, int paddr);
int alAudioFrame(usf_state_t *, int paddr);
// need to remove these
typedef struct {
uint8_t *base;
uint8_t *cur;
int32_t len;
int32_t count;
} ALHeap;
typedef struct ALPlayer_s {
struct ALPlayer_s *next;
void *clientData;
void *handler;
int32_t callTime;
int32_t samplesLeft;
} ALPlayer;
#endif

View File

@ -33,6 +33,7 @@
#include "audio.h"
#include "registers.h"
#include "rsp.h"
#include "cpu_hle.h"
#include "usf_internal.h"
@ -478,12 +479,47 @@ void StartEmulationFromSave ( usf_state_t * state, void * savestate ) {
ChangeTimer(state,AiTimer,IntScheduled);
AI_STATUS_REG|=0x40000000;
}
state->OLD_VI_V_SYNC_REG = ~VI_V_SYNC_REG;
CPUHLE_Scan(state);
}
void RefreshScreen (usf_state_t * state){
ChangeTimer(state, ViTimer, 300000);
if (state->OLD_VI_V_SYNC_REG != VI_V_SYNC_REG)
{
if (VI_V_SYNC_REG == 0)
{
state->VI_INTR_TIME = 500000;
}
else
{
state->VI_INTR_TIME = (VI_V_SYNC_REG + 1) * 1500;
if ((VI_V_SYNC_REG % 1) != 0)
{
state->VI_INTR_TIME -= 38;
}
}
}
ChangeTimer(state,ViTimer,state->Timers->Timer + state->Timers->NextTimer[ViTimer] + state->VI_INTR_TIME);
if ((VI_STATUS_REG & 0x10) != 0)
{
if (state->ViFieldNumber == 0)
{
state->ViFieldNumber = 1;
}
else
{
state->ViFieldNumber = 0;
}
}
else
{
state->ViFieldNumber = 0;
}
}
void RunRsp (usf_state_t * state) {
@ -533,7 +569,7 @@ void TimerDone (usf_state_t * state) {
case CompareTimer:
if(state->enablecompare)
FAKE_CAUSE_REGISTER |= CAUSE_IP7;
//CheckInterrupts();
CheckInterrupts(state);
ChangeCompareTimer(state);
break;
case ViTimer:

View File

@ -0,0 +1,148 @@
#include <string.h>
#include "usf.h"
#include "usf_internal.h"
#include "cpu_hle.h"
#include "os.h"
#include "audiolib.h"
// Nintendo 64 Standard (and non standard) library functions, for HLE
int numEntries = 0;
_HLE_Entry entrys[] = {
{"__osEnqueueThread",0,20,{0x8C,0x98,0,0,0x8C,0xAF,0,4,0,0x80,0xC8,0x25,0x8F,0xE,0,4,1,0xCF,8,0x2A},0,0,__osEnqueueThread},
{"__osRestoreInt",0,28,{0x40,8,0x60,0 ,1,4,0x40,0x25,0x40,0x88,0x60,0,0,0,0,0,0,0,0,0,3,0xE0,0,8,0,0,0,0},0,0,__osRestoreInt},
{"__osDisableInt",0,32,{0x40,8,0x60,0,0x24,1,0xFF,0xFE,1,1,0x48,0x24,0x40,0x89,0x60,0,0x31,2,0,1,0,0,0,0,3,0xE0,0,8,0,0,0,0},0,0,__osDisableInt},
// {"osStartThread",0,32,{0x27,0xBD,0xFF,0xD8,0xAF,0xBF,0,0x1C,0xAF,0xA4,0,0x28,0xAF,0xB1,0,0x18,0xC,-1,-1,-1,0xAF,0xB0,0,0x14,0x8F,0xAE,0,0x28,0x24,1,0,1,0,0x40,0x80,0x25},0,0,osStartThread},
//{"osPiStartDma",0,52,{0x27,0xBD,0xFF,0xD8,0x3C,0xE,-1,-1,0x8D,0xCE,-1,-1,0xAF,0xBF,0,0x1C,0xAF,0xA4,0,0x28,0xAF,0xA5,0,0x2C,0xAF,0xA6,0,0x30,0xAF,0xA7,0,0x34,0xAF,0xB1,0,0x18,0x15,0xC0,0,3,0xAF,0xB0,0,0x14,0x10,0,0,0x32,0x24,2,0xFF,0xFF},0,0,osPiStartDma}
//{"osRecvMesg",0,60,{0x27,0xBD,0xFF,0xD8,0xAF,0xBF,0,0x1C,0xAF,0xA4,0,0x28,0xAF,0xA5,0,0x2C,0xAF,0xA6,0,0x30,0xAF,0xB1,0,0x18,0xC,-1,-1,-1,0xAF,0xB0,0,0x14,0x8F,0xAE,0,0x28,0,0x40,0x80,0x25,0x8D,0xCF,0,8,0x15,0xE0,0,0x12,0,0,0,0,0x8f,0xb8,0,0x30,0x17,0,0,5},0,0,osRecvMesg},
{"saveThreadContext",0,32,{0x3C,5,-1,-1,0x8C,0xA5,-1,-1,0x40,8,0x60,0,0x8C,0xBB,0,0x18,0x35,8,0,2,0xAC,0xA8,1,0x18,0xFC,0xB0,0,0x98,0xFC,0xB1,0,0xA0},0,0,saveThreadContext},
{"loadThreadContext",0,40,{0x3C,4,-1,-1,0xC,-1,-1,-1,0x24,0x84,-1,-1,0x3C,1,-1,-1,0xAC,0x22,-1,-1,0x24,8,0,4,0xA4,0x48,0,0x10,0,0x40,0xD0,0x25,0x3C,8,-1,-1,0x8F,0x5B,1,0x18},0,0,loadThreadContext},
{"osSetIntMask",0,44,{0x40,0xC,0x60,0,0x31,0x82,0xFF,1,0x3C,8,-1,-1,0x25,8,-1,-1,0x8D,0xB,0,0,0x24,1,0xFF,0xFF,1,0x61,0x40,0x26,0x31,8,0xFF,0,0,0x48,0x10,0x25,0x3C,0xA,0xA4,0x30,0x8D,0x4A,0,0xC},0,0,osSetIntMask},
{"osVirtualToPhysical",0,36,{0x27,0xBD,0xFF,0xE8,0xAF,0xA4,0,0x18,0x8F,0xAE,0,0x18,0x3C,1,0x80,0,0xAF,0xBF,0,0x14,1,0xC1,8,0x2B,0x14,0x20,0,7,0x3C,1,0xA0,0,1,0xC1,8,0x2B},0,0,osVirtualToPhysical},
{"alCopy",0,32,{0,0x80,0x10,0x25,0,0xA0,0x18,0x25,0x18,0xC0,0,0x18,0,0,0x38,0x25,0x30,0xC5,0,3,0x10,0xA0,0,9,0,0xA0,0x20,0x25,0x90,0x4E,0,0},0,0,alCopy},
{"alLink",0,28,{0x8C,0xAE,0,0,0xAC,0x85,0,4,0xAC,0x8E,0,0,0x8C,0xA2,0,0,0x10,0x40,0,2,0,0,0,0,0xAC,0x44,0,4},0,0,alLink},
{"alUnlink",0,28,{0x8C,0x82,0,0,0x50,0x40,0,4,0x8C,0x82,0,4,0x8C,0x8E,0,4,0xAC,0x4E,0,4,0x8C,0x82,0,4,0x10,0x40,0,3},0,0,alUnLink},
{"osAiSetNextBuffer",0,32,{0x27,0xBD,0xFF,0xE0,0x3C,0xF,-1,-1,0x91,0xEF,-1,-1,0xAF,0xA4,0,0x20,0x8F,0xAE,0,0x20,0xAF,0xBF,0,0x14,0xAF,0xA5,0,0x24,0x11,0xE0,0,3},0,0,osAiSetNextBuffer},
{"alLink (DK64)",0,20,{0x8C,0xAE,0,0,0xAC,0x8E,0,0,0xAC,0x85,0,4,0x8C,0xAF,0,0,0x11,0xE0,0,3},0,0,alLink},
{"alUnLink (DK64)",0,28,{0x8C,0x8E,0,0,0x11,0xC0,0,4,0,0,0,0,0x8C,0x8F,0,4,0x8C,0x98,0,0,0xAF,0xF,0,4,0x8C,0x99,0,4},0,0,alUnLink},
{"alEvtqPostEvent",0,64,{0x27,0xBD,0xFF,0xD0,0xAF,0xBF,0,0x14,0xAF,0xA4,0,0x30,0xAF,0xA5,0,0x34,0xAF,0xA0,0,0x20,0x24,4,0,1,0xC,-1,-1,-1,0xAF,0xA6,0,0x38,0x8F,0xAE,0,0x30,0x8F,0xA7,0,0x38,0,0x40,0x28,0x25,0x8D,0xC8,0,0,0x15,0,0,5,1,0,0x20,0x25,0xC,-1,-1,-1,0,0x40,0x20,0x25},0,0,alEvtqPostEvent},
{"alEvtqPostEvent (DK64)",0,64,{0x27,0xBD,0xFF,0xD0,0xAF,0xBF,0,0x14,0xAF,0xA4,0,0x30,0xAF,0xA5,0,0x34,0xAF,0xA6,0,0x38,0xAF,0xA0,0,0x20,0xC,-1,-1,-1,0x24,4,0,1,0xAF,0xA2,0,0x1C,0x8F,0xAE,0,0x30,0x8D,0xCF,0,0,0xAF,0xAF,0,0x2C,0x8F,0xB8,0,0x2C,0x17,0,0,5,0,0,0,0,0xC,-1,-1,-1,0x8F,0xA4,0,0x1C},0,0,alEvtqPostEvent},
{"alEvtqPostEvent (CBFD)",0,56,{0x27,0xBD,0xFF,0xC0,0xAF,0xBF,0,0x14,0xAF,0xA4,0,0x40,0xAF,0xA5,0,0x44,0xAF,0xA6,0,0x48,0xAF,0xA7,0,0x4C,0xAF,0xA0,0,0x30,0x8F,0xAE,0,0x4C,0x31,0xCF,0,2,0x11,0xE0,0,4,0,0,0,0,0xC,-1,-1,-1,0x24,4,0,1,0xAF,0xA2,0,0x2C},0,0,alEvtqPostEvent},
{"alEvtqPostEvent (BT)",0,60,{0x27,0xBD,0xFF,0xD0,0xAF,0xBF,0,0x14,0xAF,0xA4,0,0x30,0xAF,0xA5,0,0x34,0xAF,0xA6,0,0x38,0xAF,0xA7,0,0x3C,0xAF,0xA0,0,0x20,0xC,-1,-1,-1,0x24,4,0,1,0xAF,0xA2,0,0x1C,0x8F,0xAE,0,0x30,0x8D,0xCF,0,0,0xAF,0xAF,0,0x2C,0x8F,0xB8,0,0x2C,0x17,0,0,5},0,0,alEvtqPostEvent},
{"alAudioFrame",0,52,{0x27,0xBD,0xFF,0x48,0xAF,0xB1,0,0x30,0x3C,0x11,-1,-1,0x8E,0x31,0-1,-1,0xAF,0xBF,0,0x4C,0xAF,0xB7,0,0x48,0xAF,0xB6,0,0x44,0xAF,0xB5,0,0x40,0xAF,0xB4,0,0x3C,0xAF,0xB3,0,0x38,0xAF,0xB2,0,0x34,0xAF,0xB0,0,0x2C,0xF7,0xB6,0,0x20},0,0,alAudioFrame},
//{"alAudioFrame (DK64)",0,64,{0x27,0xBD,0xFF,0xC0,0xAF,0xBF,0,0x1C,0xAF,0xA4,0,0x40,0xAF,0xA5,0,0x44,0xAF,0xA6,0,0x48,0xAF,0xA7,0,0x4C,0xAF,0xB1,0,0x18,0xAF,0xB0,0,0x14,0xA7,0xA0,0,0x3A,0x8F,0xAE,0,0x40,0xAF,0xAE,0,0x34,0x8F,0xAF,0,0x48,0xAF,0xAF,0,0x28,0x3C,0x18,0x80,0x75,0x8F,0x18,0xC,0x74,0x8F,0x19,0,0},0,0,alAudioFrame},
};
//int 0xA4,0xA6,0,0x38
//char foundlist[2048];
int CPUHLE_Scan(usf_state_t * state)
{
int i = 0, j = 0;
unsigned char c = 0;
long d = 0;
int entrySize = 0;
int entry = 0;
void * address = 0;
int good = 1; //, needcomma = 0;
_HLE_Entry * entries;
numEntries = sizeof(entrys) / sizeof(_HLE_Entry);
entries = state->cpu_hle_entries = realloc( state->cpu_hle_entries, sizeof(entrys) );
memcpy( entries, entrys, sizeof(entrys) );
//for(i=0; i < numEntries; i++)
// entries[i].used = 0;
//memset(foundlist,0,2048);
for(i=0; i < (state->RdramSize - 64); i+=4) {
for(entry = 0; entry < numEntries; entry++) {
if(entries[entry].used)
continue;
good = 1;
entrySize = entries[entry].length;
for(j=0; j < entrySize; j++) {
address = state->N64MEM + i + j;
//address = i;
c = *(unsigned char *)(address);
d = entries[entry].bytes[j^3];
if((c != d) && (d!=-1)) {
good = 0;
break;
}
}
if(good == 1 && i< (state->RdramSize-64)) {
//char buf[256];
//if(needcomma) {
// sprintf(buf,", %s", entries[entry].name);
//} else {
// sprintf(buf,"%s", entries[entry].name);
//}
//needcomma = 1;
//strcat(foundlist,buf);
entries[entry].used = 1;
entries[entry].phys = i;
break;
}
}
}
//printf("<--------------HLE Functions Found--------------->\n%s<------------------------------------------------>\n", foundlist);
//printf("HLE Functions found: %s\n", foundlist);
return 0;
}
int DoCPUHLE(usf_state_t * state, unsigned long loc)
{
int i = 0;
uintptr_t real_addr = PageVRAM2(loc);
_HLE_Entry * entries = state->cpu_hle_entries;
for(i = 0; i < numEntries; i++) {
if(entries[i].used && (entries[i].phys == real_addr)) {
//printf("CPU HLEing using %d at %08x (phys: %08x) \"%s\"\n", entries[i].name, loc, entries[i].phys, entries[i].name);
if(entries[i].location(state, entries[i].phys)) {
// printf("done\n");
return 1;
}
else
return 0;
}
}
return 0;
}

View File

@ -0,0 +1,27 @@
#ifndef _CPU_HLE_
#define _CPU_HLE_
#include "usf.h"
#include "cpu.h"
#include "interpreter_ops.h"
#include "memory.h"
typedef struct {
char *name;
int num;
int length;
long bytes[80];
int used;
int phys;
int (*location)(usf_state_t *, int);
} _HLE_Entry;
int CPUHLE_Scan(usf_state_t *);
int DoCPUHLE(usf_state_t *, unsigned long loc);
////////////////////////////////////////////////////////////////////
// OS Thread Stuff
// found this stuff in daedalus
#endif

View File

@ -28,6 +28,7 @@
#include "cpu.h"
#include "usf.h"
#include "memory.h"
#include "cpu_hle.h"
#include "usf_internal.h"
@ -679,6 +680,29 @@ void BuildInterpreter (usf_state_t * state) {
}
void RunFunction(usf_state_t * state, uint32_t address) {
uint32_t oldPC = state->PROGRAM_COUNTER, oldRA = state->GPR[31].UW[0], la = state->NextInstruction;
int callStack = 0;
state->NextInstruction = NORMAL;
state->PROGRAM_COUNTER = address;
while( (state->PROGRAM_COUNTER != oldRA) || callStack) {
if(state->PROGRAM_COUNTER == address)
callStack++;
ExecuteInterpreterOpCode(state);
if(state->PROGRAM_COUNTER == oldRA)
callStack--;
}
state->PROGRAM_COUNTER = oldPC;
state->GPR[31].UW[0] = oldRA;
state->NextInstruction = la;
}
void ExecuteInterpreterOpCode (usf_state_t * state) {
@ -713,8 +737,13 @@ void ExecuteInterpreterOpCode (usf_state_t * state) {
state->PROGRAM_COUNTER += 4;
break;
case JUMP:
state->PROGRAM_COUNTER = state->JumpToLocation;
state->NextInstruction = NORMAL;
if(!DoCPUHLE(state, state->JumpToLocation)) {
state->PROGRAM_COUNTER = state->JumpToLocation;
state->NextInstruction = NORMAL;
} else {
state->PROGRAM_COUNTER = state->GPR[31].UW[0];
state->NextInstruction = NORMAL;
}
if ((int32_t)state->Timers->Timer < 0) { TimerDone(state); }
if (state->CPU_Action->DoSomething) { DoSomething(state); }

View File

@ -30,7 +30,7 @@ void ExecuteInterpreterOpCode ( usf_state_t * );
void StartInterpreterCPU ( usf_state_t * );
void TestInterpreterJump ( usf_state_t *, uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2 );
void RunFunction( usf_state_t *, uint32_t address );

View File

@ -157,6 +157,10 @@ void Release_Memory ( usf_state_t * state ) {
if (state->MemChunk != 0) { large_free( state->MemChunk, 0x100000 * sizeof(uintptr_t) + 0x1D000 + state->RdramSize ); state->MemChunk=0; }
if(state->cpu_hle_entries)
free(state->cpu_hle_entries);
state->cpu_hle_entries = NULL;
if(state->savestatespace)
free(state->savestatespace);
state->savestatespace = NULL;
@ -813,3 +817,23 @@ uint32_t r4300i_SW_VAddr ( usf_state_t * state, uint32_t VAddr, uint32_t Value )
*(uint32_t *)address = Value;
return 1;
}
void memcpyn642n64(usf_state_t * state, uint32_t dest, uint32_t src, uint32_t len)
{
uint32_t i;
uint32_t temp;
for (i = 0; i < len; i += 4)
{
uintptr_t dstAddr = state->TLB_Map[(dest + i) >> 12];
uintptr_t srcAddr = state->TLB_Map[(src + i) >> 12];
if (srcAddr)
temp = *(uint32_t*)(srcAddr + src + i);
else
temp = 0;
if (dstAddr)
*(uint32_t*)(dstAddr + dest + i) = temp;
}
}

View File

@ -31,6 +31,10 @@
#define ROM_IN_MAPSPACE
#define PageRAM2(x) (state->N64MEM+(x))
#define PageVRAM(x) (state->TLB_Map[((x)&0xFFFFFFFF)>>12]+(x))
#define PageVRAM2(x) (uint32_t)(PageVRAM(x)-(uintptr_t)state->N64MEM)
/* Memory Control */
int Allocate_Memory ( void * );
void Release_Memory ( usf_state_t * );
@ -56,3 +60,5 @@ int32_t r4300i_SW_NonMemory ( usf_state_t *, uint32_t PAddr, uint32_t V
uint32_t r4300i_SW_VAddr ( usf_state_t *, uint32_t VAddr, uint32_t Value );
uint8_t * PageROM(usf_state_t *, uint32_t addr);
void memcpyn642n64(usf_state_t *, uint32_t dest, uint32_t src, uint32_t len);

View File

@ -0,0 +1,285 @@
#include <string.h>
#include "usf.h"
#include "usf_internal.h"
#include "os.h"
#include "cpu_hle.h"
#include "audio.h"
#include "interpreter_cpu.h"
#include "main.h"
#include "memory.h"
#define N64WORD(x) (*(uint32_t*)PageVRAM((x)))
#define N64HALF(x) (*(uint16_t*)PageVRAM((x)))
#define N64BYTE(x) (*(uint8_t*)PageVRAM((x^3)))
#define N64DWORD(addr) (((long long)N64WORD((addr))) << 32) + N64WORD((addr)+4);
int __osRestoreInt(usf_state_t * state, int n)
{
STATUS_REGISTER |= state->GPR[0x4].UW[0];
return 1;
}
int __osDisableInt(usf_state_t * state, int n)
{
state->GPR[0x2].UW[0] = STATUS_REGISTER & 1;
STATUS_REGISTER &= 0xFFFFFFFE;
return 1;
}
void osEnqueueThread(usf_state_t * state, uint32_t osThreadQueueAddr, uint32_t threadVAddr)
{
OSThread *thread = (OSThread*) PageVRAM(threadVAddr);
OSThread *oldThread = (OSThread*) PageVRAM(osThreadQueueAddr);
OSThread *curThread = (OSThread*) PageVRAM(oldThread->next);
while((int32_t)curThread->priority >= (int32_t)thread->priority) {
oldThread = curThread;
curThread = (OSThread*) PageVRAM(curThread->next);
}
thread->next = oldThread->next;
oldThread->next = threadVAddr;
thread->queue = osThreadQueueAddr;
}
int __osEnqueueThread(usf_state_t * state, int n) {
osEnqueueThread(state, state->GPR[4].UW[0],state->GPR[5].UW[0]);
return 1;
}
int osStartThread(usf_state_t * state, int n)
{
OSMesgQueue *osThreadQueue = NULL;
uint32_t osThreadQueueAddr = 0;
uint32_t oldStatus = STATUS_REGISTER & 1;
uint32_t osActiveThreadAddr = 0;
uint32_t osActiveThread = 0;
OSThread *thread = (OSThread*)PageVRAM(state->GPR[4].UW[0]);
STATUS_REGISTER &= 0xFFFFFFFE;
osThreadQueueAddr = ((*(uint32_t*)PageRAM2(n + 0x40)) & 0xFFFF) << 16;
osThreadQueueAddr += *(int16_t*)PageRAM2(n + 0x50);
osThreadQueue = (OSMesgQueue*) PageVRAM(osThreadQueueAddr);
if(thread->state != 8 ) {
DisplayError(state, "OMG, thread state is not OS_STATE_WAITING!\n");
return 0;
}
thread->state = OS_STATE_RUNNABLE;
osEnqueueThread(state,osThreadQueueAddr,state->GPR[4].UW[0]);
osActiveThreadAddr = ((*(uint32_t*)PageRAM2(n + 0xDC)) & 0xFFFF) << 16;
osActiveThreadAddr += *(int16_t*)PageRAM2(n + 0xE0);
osActiveThread = *(uint32_t*)PageVRAM(osActiveThreadAddr);
if(osActiveThread==0) {
DisplayError(state,"OMG, active thread is NULL!\n");
return 0;
}
STATUS_REGISTER |= oldStatus;
// CheckInterrupts();
return 1;
}
int osRecvMesg(usf_state_t * state, int n)
{
//unsigned long devAddr = state->GPR[7].UW[0];
//unsigned long vAddr = state->GPR[0x11].UW[0];
//unsigned long nbytes = state->GPR[0x10].UW[0];
//unsigned long oldStatus = STATUS_REGISTER & 1;
RunFunction(state, n | (state->PROGRAM_COUNTER & 0xF0000000));
//DisplayError("%08x\n%08x\n%08x",devAddr, vAddr, nbytes);
return 1;
}
// doesnt even use?
int osSetIntMask(usf_state_t * state, int paddr) {
#if 0
uint32_t globalIntMask = 0;
uint32_t mask = STATUS_REGISTER & 0xFF01;
uint32_t interrupts = 0;
uint32_t intAddress = 0, newMask = 0, workMask = 0;
uint32_t baseAddress = 0;
globalIntMask = ((*(uint16_t*)PageRAM2(paddr + 0x8)) & 0xFFFF) << 16;
globalIntMask += *(uint16_t*)PageRAM2(paddr + 0xc);
globalIntMask = *(uint32_t*)PageVRAM(globalIntMask);
interrupts = (globalIntMask ^ 0xffffffff) & 0xff00;
mask |= interrupts;
newMask = MI_INTR_MASK_REG;
if(!newMask)
newMask = ((globalIntMask >> 16) ^ 0xFFFFFFFF) & 0x3F;
mask |= (newMask << 16);
baseAddress = ((*(uint16_t*)PageRAM2(paddr + 0x5C)) & 0xFFFF) << 16;
baseAddress += *(int16_t*)PageRAM2(paddr + 0x64);
baseAddress += ((state->GPR[4].UW[0] & 0x3F0000) & globalIntMask) >> 15;;
MI_INTR_MASK_REG = *(uint16_t*)PageVRAM(baseAddress);
state->STATUS_REGISTER = ((state->GPR[4].UW[0] & 0xff01) & (globalIntMask & 0xff00)) | (STATUS_REGISTER & 0xFFFF00FF);
#endif
return 1;
}
int osVirtualToPhysical(usf_state_t * state, int paddr) {
uintptr_t address = 0;
uintptr_t vaddr = state->GPR[4].UW[0];
address = (state->TLB_Map[vaddr >> 12] + vaddr) - (uintptr_t)state->N64MEM;
if(address < 0x800000) {
state->GPR[2].UW[0] = (uint32_t)address;
} else
state->GPR[2].UW[0] = 0xFFFFFFFF;
return 1;
}
int osAiSetNextBuffer(usf_state_t * state, int paddr) {
uint32_t var = 0, var2 = 0;
var = ((*(short*)PageRAM2(paddr + 0x4)) & 0xFFFF) << 16;
var += *(short*)PageRAM2(paddr + 0x8);
var2 = N64WORD(var);
if(AI_CONTROL_REG & 0x80000000)
state->GPR[2].UW[0] = -1;
AI_DRAM_ADDR_REG = state->GPR[4].UW[0];
AI_LEN_REG = state->GPR[5].UW[0]&0x3FFF;
AiLenChanged(state);
state->GPR[2].UW[0] = 0;
return 1;
}
int saveThreadContext(usf_state_t * state, int paddr) {
#if 0
uint32_t OSThreadContextAddr = 0;
OSThreadContextAddr = ((*(short*)PageRAM2(paddr)) & 0xFFFF) << 16;
OSThreadContextAddr += *(short*)PageRAM2(paddr + 0x4);
OSThreadContextAddr = N64WORD(OSThreadContextAddr);
if((PageVRAM2(OSThreadContextAddr) & 0xffff) > 0xFF00) {
DisplayError(state,"OMG! Too high!");
return 0;
}
#endif
return 0;
}
int loadThreadContext(usf_state_t * state, int paddr) {
#if 0
uint32_t i = 0, OSThreadContextAddr = 0, T9 = 0, osOSThread = 0, Addr2 = 0, GlobalBitMask = 0, Tmp = 0;
uint32_t K0 = 0, K1 = 0, T0 = 0, R1 = 0, RCP = 0, intrList = 0;
OSThread t;
OSThreadContextAddr = ((*(short*)PageRAM2(paddr)) & 0xFFFF) << 16;
OSThreadContextAddr += *(short*)PageRAM2(paddr + 0x8);
Addr2 = ((*(short*)PageRAM2(paddr + 0xC)) & 0xFFFF) << 16;
Addr2 += *(short*)PageRAM2(paddr + 0x10);
GlobalBitMask = ((*(short*)PageRAM2(paddr + 0x20)) & 0xFFFF) << 16;
GlobalBitMask += *(short*)PageRAM2(paddr + 0x28);
GlobalBitMask = N64WORD(GlobalBitMask);
intrList = ((*(short*)PageRAM2(paddr + 0x14C + 0x0)) & 0xFFFF) << 16;
intrList += *(short*)PageRAM2(paddr + 0x150 + 0x0);
return 0;
if((PageVRAM2(OSThreadContextAddr) & 0xffff) > 0xFE80) {
DisplayError(state, "OMG this number is too high!!!!\n");
}
osOSThread = N64WORD(OSThreadContextAddr);
T9 = N64WORD(osOSThread);
N64WORD(OSThreadContextAddr) = T9;
N64WORD(Addr2) = osOSThread;
N64WORD(osOSThread + 0x10) = OS_STATE_RUNNING; //T0 is globalbitmask
K1 = N64WORD(osOSThread + 0x118); //osOSThread.context.k0
STATUS_REGISTER = (K1 & 0xFFFF00FF) | (GlobalBitMask & 0xFF00);
for(i = 1; i <= 0x19; i++) {
state->GPR[i].DW = N64DWORD(osOSThread + 0x18 + (i * 8));
}
for(i = 0x1C; i <= 0x1F; i++) {
state->GPR[i].DW = N64DWORD(osOSThread + 0x8 + (i * 8));
}
state->LO.DW = N64DWORD(osOSThread + 0x108);
state->HI.DW = N64DWORD(osOSThread + 0x110);
EPC_REGISTER = (uint32_t) N64WORD(osOSThread + 0x11C);
state->FPCR[31] = (uint32_t) N64WORD(osOSThread + 0x12C);
if(N64WORD(osOSThread + 0x18)) {
for(i = 0; i <= 30; i+=2) {
(*(uint64_t *)state->FPRDoubleLocation[i]) = N64DWORD(osOSThread + 0x130 + (i * 4));
}
} else {
}
state->GPR[0x1A].UW[0] = (uint32_t) osOSThread;
RCP = N64WORD(osOSThread + 0x128);
K0 = (intrList + ((RCP & (GlobalBitMask >> 16)) << 1));
K1 = 0;
r4300i_LH_VAddr(state, K0, &K1);
// cheap hack?
//K1 = 0xAAA;
SW_Register(0x0430000C, K1);
NextInstruction = JUMP;
if ((STATUS_REGISTER & STATUS_ERL) != 0) {
JumpToLocation = ERROREPC_REGISTER;
STATUS_REGISTER &= ~STATUS_ERL;
} else {
JumpToLocation = EPC_REGISTER;
STATUS_REGISTER &= ~STATUS_EXL;
}
LLBit = 0;
CheckInterrupts();
#endif
return 0;
}

View File

@ -0,0 +1,89 @@
#ifndef _CPU_HLE_OS_
#define _CPU_HLE_OS_
#include "cpu_hle.h"
#pragma pack(1)
#define OS_STATE_STOPPED 1
#define OS_STATE_RUNNABLE 2
#define OS_STATE_RUNNING 4
#define OS_STATE_WAITING 8
typedef uint32_t OSPri;
typedef uint32_t OSId;
typedef
union
{
struct
{
float f_odd;
float f_even;
} f;
double d;
}
__OSfp;
typedef struct {
uint64_t at, v0, v1, a0, a1, a2, a3;
uint64_t t0, t1, t2, t3, t4, t5, t6, t7;
uint64_t s0, s1, s2, s3, s4, s5, s6, s7;
uint64_t t8, t9, gp, sp, s8, ra;
uint64_t lo, hi;
uint32_t sr, pc, cause, badvaddr, rcp;
uint32_t fpcsr;
__OSfp fp0, fp2, fp4, fp6, fp8, fp10, fp12, fp14;
__OSfp fp16, fp18, fp20, fp22, fp24, fp26, fp28, fp30;
} __OSThreadContext;
typedef struct OSThread_s
{
uint32_t next; // run/mesg queue link
OSPri priority; // run/mesg queue priority
uint32_t queue; // queue thread is on
uint32_t tlnext; // all threads queue link
#if 0
uint16_t state; // OS_STATE_*
uint16_t flags; // flags for rmon
#endif
//swap these because of byteswapping
uint16_t flags; // flags for rmon
uint16_t state; // OS_STATE_*
OSId id; // id for debugging
int fp; // thread has used fp unit
__OSThreadContext context; // register/interrupt mask
} OSThread;
typedef void * OSMesg;
//
// Structure for message queue
//
typedef struct OSMesgQueue_s
{
OSThread *mtqueue; // Queue to store threads blocked
// on empty mailboxes (receive)
OSThread *fullqueue; // Queue to store threads blocked
// on full mailboxes (send)
int32_t validCount; // Contains number of valid message
int32_t first; // Points to first valid message
int32_t msgCount; // Contains total # of messages
OSMesg *msg; // Points to message buffer array
} OSMesgQueue;
int __osRestoreInt(usf_state_t *, int n);
int __osDisableInt(usf_state_t *, int n);
int __osEnqueueThread(usf_state_t *, int n) ;
int osStartThread(usf_state_t *, int n);
int osRecvMesg(usf_state_t *, int n);
int osSetIntMask(usf_state_t *, int paddr) ;
int osVirtualToPhysical(usf_state_t *, int paddr);
int osAiSetNextBuffer(usf_state_t *, int paddr);
int saveThreadContext(usf_state_t *, int paddr);
int loadThreadContext(usf_state_t *, int paddr);
#endif

View File

@ -3,6 +3,7 @@
#include "cpu.h"
#include "rsp_hle/hle.h"
#include "cpu_hle.h"
struct usf_state_helper
{
@ -29,37 +30,37 @@ struct usf_state
// which is indicated for allocation accounts for this
// with two pages of padding.
short VR[32][8];
short VACC[3][8];
int16_t VR[32][8];
int16_t VACC[3][8];
// RSP virtual registers, also needs alignment
int SR[32];
int32_t SR[32];
// rsp/rsp.c, not necessarily in need of alignment
RCPREG* CR[16];
// rsp/vu/cf.h, all need alignment
short ne[8]; /* $vco: high byte "NOTEQUAL" */
short co[8]; /* $vco: low byte "carry/borrow in/out" */
short clip[8]; /* $vcc: high byte (clip tests: VCL, VCH, VCR) */
short comp[8]; /* $vcc: low byte (VEQ, VNE, VLT, VGE, VCL, VCH, VCR) */
short vce[8]; /* $vce: vector compare extension register */
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
int DivIn; /* buffered numerator of division read from vector file */
int DivOut; /* global division result set by VRCP/VRCPL/VRSQ/VRSQH */
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)
int MovIn; /* We do not emulate this register (obsolete, for VMOV). */
int32_t MovIn; /* We do not emulate this register (obsolete, for VMOV). */
#endif
int DPH;
int32_t DPH;
// rsp/rsp.h
int stage; // unused since EMULATE_STATIC_PC is defined by default in rsp/config.h
int temp_PC;
short MFC0_count[32];
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];
// rsp_hle
struct hle_t hle;
@ -134,6 +135,10 @@ struct usf_state
// tlb.c
FASTTLB FastTlb[64];
TLB tlb[32];
uint32_t OLD_VI_V_SYNC_REG/* = 0*/, VI_INTR_TIME/* = 500000*/;
_HLE_Entry * cpu_hle_entries;
};
#define USF_STATE_HELPER ((usf_state_helper_t *)(state))