mirror of
https://github.com/HarbourMasters/Starship
synced 2026-08-08 10:53:24 -04:00
Match Libultra (#120)
* Matched perspective, contquery, contreaddata, recvmesg and sendmesg * Fixed libultra compilation flags * Matched viblack * Matched virepeatline, visetmode, visetspecial and viswapbuf * Matched cartrominit, dpsetstat, sptask, sptaskyield, visetevent, createthread, gettime, setthreadpri, settime, settimer and starthread * Fixed bss bs * Matched even more libultra stuff * Matched even more * __osRdbSend * Decompiled most of the functions of libultra <3 * Matched last functions * Added a separation to libultra macros * Removed ARRLEN from controller.h * Fix libultra warnings --------- Co-authored-by: Alejandro Javier Asenjo Nitti <alejandro.asenjo88@gmail.com>
This commit is contained in:
@@ -1,11 +1,92 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/rdb.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/debug/kdebugserver/string_to_u32.s")
|
||||
// not included in final rom, but __osThreadSave is here for some reason
|
||||
OSThread __osThreadSave;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/debug/kdebugserver/send_packet.s")
|
||||
extern OSThread* __osRunningThread;
|
||||
extern u32 __osRdb_IP6_Empty;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/debug/kdebugserver/clear_IP6.s")
|
||||
static u8 buffer[12];
|
||||
static u32 numChars = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/debug/kdebugserver/send.s")
|
||||
static u32 string_to_u32(u8* s) {
|
||||
u32 k;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/debug/kdebugserver/kdebugserver.s")
|
||||
k = ((s[0] & 0xFF) << 0x18);
|
||||
k |= ((s[1] & 0xFF) << 0x10);
|
||||
k |= ((s[2] & 0xFF) << 0x8);
|
||||
k |= (s[3] & 0xFF);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
static void send_packet(u8* s, u32 n) {
|
||||
rdbPacket packet;
|
||||
u32 i;
|
||||
|
||||
packet.type = 0xC;
|
||||
packet.length = n;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
packet.buf[i] = s[i];
|
||||
}
|
||||
*(vu32*) RDB_BASE_REG = *(u32*) &packet;
|
||||
}
|
||||
|
||||
static void clear_IP6(void) {
|
||||
while (!(__osGetCause() & CAUSE_IP6)) {
|
||||
;
|
||||
}
|
||||
*(vu32*) RDB_READ_INTR_REG = 0;
|
||||
|
||||
while (__osGetCause() & CAUSE_IP6) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static void send(u8* s, u32 n) {
|
||||
u32 ct;
|
||||
u32 i = 0;
|
||||
u32 getLastIP6;
|
||||
|
||||
if (!__osRdb_IP6_Empty) {
|
||||
clear_IP6();
|
||||
getLastIP6 = FALSE;
|
||||
} else {
|
||||
getLastIP6 = TRUE;
|
||||
}
|
||||
while (n != 0) {
|
||||
ct = (n < 3) ? n : 3;
|
||||
send_packet(s + i, ct);
|
||||
n -= ct;
|
||||
i += ct;
|
||||
if (n != 0) {
|
||||
clear_IP6();
|
||||
}
|
||||
}
|
||||
if (getLastIP6) {
|
||||
clear_IP6();
|
||||
}
|
||||
}
|
||||
|
||||
void kdebugserver(rdbPacket packet) {
|
||||
u32 i;
|
||||
u32 length;
|
||||
u8* addr;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
buffer[numChars++] = packet.buf[i];
|
||||
}
|
||||
|
||||
if (buffer[0] == 2) {
|
||||
send((char*) &__osRunningThread->context, sizeof(__OSThreadContext));
|
||||
numChars = 0;
|
||||
} else if (numChars >= 9 && buffer[0] == 1) {
|
||||
addr = string_to_u32(&buffer[1]);
|
||||
length = string_to_u32(&buffer[5]);
|
||||
send(addr, length);
|
||||
numChars = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+123
-3
@@ -1,5 +1,125 @@
|
||||
#include "common.h"
|
||||
/**************************************************************************
|
||||
* *
|
||||
* Copyright (C) 1994, Silicon Graphics, Inc. *
|
||||
* *
|
||||
* These coded instructions, statements, and computer programs contain *
|
||||
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
||||
* are protected by Federal copyright law. They may not be disclosed *
|
||||
* to third parties or copied or duplicated in any form, in whole or *
|
||||
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/cosf/__cosf.s")
|
||||
#include "PR/ultratypes.h"
|
||||
#include "PR/guint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/cosf/D_800C9390.s")
|
||||
/* ====================================================================
|
||||
* ====================================================================
|
||||
*
|
||||
* Module: fcos.c
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 1998/10/09 06:10:53 $
|
||||
* $Author: has $
|
||||
* $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/libultra/monegi/gu/cosf.c,v $
|
||||
*
|
||||
* Revision history:
|
||||
* 09-Jun-93 - Original Version
|
||||
*
|
||||
* Description: source code for fcos function
|
||||
*
|
||||
* ====================================================================
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#pragma weak fcos = __cosf
|
||||
#pragma weak cosf = __cosf
|
||||
#define fcos __cosf
|
||||
|
||||
/* coefficients for polynomial approximation of cos on +/- pi/2 */
|
||||
|
||||
static const du P[] = {
|
||||
{ 0x3ff00000, 0x00000000 }, { 0xbfc55554, 0xbc83656d }, { 0x3f8110ed, 0x3804c2a0 },
|
||||
{ 0xbf29f6ff, 0xeea56814 }, { 0x3ec5dbdf, 0x0e314bfe },
|
||||
};
|
||||
|
||||
static const du rpi = { 0x3fd45f30, 0x6dc9c883 };
|
||||
|
||||
static const du pihi = { 0x400921fb, 0x50000000 };
|
||||
|
||||
static const du pilo = { 0x3e6110b4, 0x611a6263 };
|
||||
|
||||
static const fu zero = { 0x00000000 };
|
||||
|
||||
/* ====================================================================
|
||||
*
|
||||
* FunctionName fcos
|
||||
*
|
||||
* Description computes cosine of arg
|
||||
*
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
float fcos(float x) {
|
||||
float absx;
|
||||
double dx, xsq, poly;
|
||||
double dn;
|
||||
int n;
|
||||
double result;
|
||||
int ix, xpt;
|
||||
|
||||
ix = *(int*) &x;
|
||||
xpt = (ix >> 22);
|
||||
xpt &= 0x1ff;
|
||||
|
||||
/* xpt is exponent(x) + 1 bit of mantissa */
|
||||
|
||||
if (xpt < 0x136) {
|
||||
/* |x| < 2^28 */
|
||||
|
||||
/* use the standard algorithm from Cody and Waite, doing
|
||||
the computations in double precision
|
||||
*/
|
||||
|
||||
absx = ABS(x);
|
||||
|
||||
dx = absx;
|
||||
|
||||
dn = dx * rpi.d + 0.5;
|
||||
n = ROUND(dn);
|
||||
dn = n;
|
||||
|
||||
dn -= 0.5;
|
||||
|
||||
dx = dx - dn * pihi.d;
|
||||
dx = dx - dn * pilo.d; /* dx = x - (n - 0.5)*pi */
|
||||
|
||||
xsq = dx * dx;
|
||||
|
||||
poly = ((P[4].d * xsq + P[3].d) * xsq + P[2].d) * xsq + P[1].d;
|
||||
|
||||
result = dx + (dx * xsq) * poly;
|
||||
|
||||
/* negate result if n is odd */
|
||||
|
||||
if ((n & 1) == 0) {
|
||||
return ((float) result);
|
||||
}
|
||||
|
||||
return (-(float) result);
|
||||
}
|
||||
|
||||
if (x != x) {
|
||||
/* x is a NaN; return a quiet NaN */
|
||||
|
||||
#ifdef _IP_NAN_SETS_ERRNO
|
||||
|
||||
*__errnoaddr = EDOM;
|
||||
#endif
|
||||
|
||||
return (__libm_qnan_f);
|
||||
}
|
||||
|
||||
/* just give up and return 0.0 */
|
||||
|
||||
return (zero.f);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,76 @@
|
||||
#include "common.h"
|
||||
/**************************************************************************
|
||||
* *
|
||||
* Copyright (C) 1994, Silicon Graphics, Inc. *
|
||||
* *
|
||||
* These coded instructions, statements, and computer programs contain *
|
||||
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
||||
* are protected by Federal copyright law. They may not be disclosed *
|
||||
* to third parties or copied or duplicated in any form, in whole or *
|
||||
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/mtxutil/guMtxF2L.s")
|
||||
#include "PR/ultratypes.h"
|
||||
#include "PR/guint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/mtxutil/guMtxIdentF.s")
|
||||
void guMtxF2L(float mf[4][4], Mtx* m) {
|
||||
int i, j;
|
||||
int e1, e2;
|
||||
int *ai, *af;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/mtxutil/guMtxIdent.s")
|
||||
ai = (int*) &m->m[0][0];
|
||||
af = (int*) &m->m[2][0];
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/mtxutil/guMtxL2F.s")
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
e1 = FTOFIX32(mf[i][j * 2]);
|
||||
e2 = FTOFIX32(mf[i][j * 2 + 1]);
|
||||
*(ai++) = (e1 & 0xffff0000) | ((e2 >> 16) & 0xffff);
|
||||
*(af++) = ((e1 << 16) & 0xffff0000) | (e2 & 0xffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This function seems to use the SM64 version of the guMtxF2L function
|
||||
void guMtxL2F(float mf[4][4], Mtx* m) {
|
||||
int r, c;
|
||||
u32 tmp1;
|
||||
u32 tmp2;
|
||||
u32* m1;
|
||||
u32* m2;
|
||||
s32 stmp1, stmp2;
|
||||
m1 = (u32*) &m->m[0][0];
|
||||
m2 = (u32*) &m->m[2][0];
|
||||
for (r = 0; r < 4; r++) {
|
||||
for (c = 0; c < 2; c++) {
|
||||
tmp1 = (*m1 & 0xffff0000) | ((*m2 >> 0x10) & 0xffff);
|
||||
tmp2 = ((*m1++ << 0x10) & 0xffff0000) | (*m2++ & 0xffff);
|
||||
stmp1 = *(s32*) &tmp1;
|
||||
stmp2 = *(s32*) &tmp2;
|
||||
mf[r][c * 2 + 0] = stmp1 / 65536.0f;
|
||||
mf[r][c * 2 + 1] = stmp2 / 65536.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxIdentF(float mf[4][4]) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
if (i == j) {
|
||||
mf[i][j] = 1.0;
|
||||
} else {
|
||||
mf[i][j] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guMtxIdent(Mtx* m) {
|
||||
float mf[4][4];
|
||||
|
||||
guMtxIdentF(mf);
|
||||
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,59 @@
|
||||
#include "common.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/perspective/guPerspectiveF.s")
|
||||
/**************************************************************************
|
||||
* *
|
||||
* Copyright (C) 1994, Silicon Graphics, Inc. *
|
||||
* *
|
||||
* These coded instructions, statements, and computer programs contain *
|
||||
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
||||
* are protected by Federal copyright law. They may not be disclosed *
|
||||
* to third parties or copied or duplicated in any form, in whole or *
|
||||
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/perspective/guPerspective.s")
|
||||
#include "PR/ultratypes.h"
|
||||
#include "PR/guint.h"
|
||||
|
||||
extern f32 __cosf(f32);
|
||||
extern f32 __sinf(f32);
|
||||
|
||||
void guPerspectiveF(float mf[4][4], u16* perspNorm, float fovy, float aspect, float near, float far, float scale) {
|
||||
float cot;
|
||||
int i, j;
|
||||
|
||||
guMtxIdentF(mf);
|
||||
|
||||
fovy *= 3.1415926 / 180.0;
|
||||
cot = __cosf(fovy / 2) / __sinf(fovy / 2);
|
||||
|
||||
mf[0][0] = cot / aspect;
|
||||
mf[1][1] = cot;
|
||||
mf[2][2] = (near + far) / (near - far);
|
||||
mf[2][3] = -1;
|
||||
mf[3][2] = (2 * near * far) / (near - far);
|
||||
mf[3][3] = 0;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
mf[i][j] *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
if (perspNorm != (u16*) NULL) {
|
||||
if (near + far <= 2.0) {
|
||||
*perspNorm = (u16) 0xFFFF;
|
||||
} else {
|
||||
*perspNorm = (u16) ((2.0 * 65536.0) / (near + far));
|
||||
if (*perspNorm <= 0) {
|
||||
*perspNorm = (u16) 0x0001;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void guPerspective(Mtx* m, u16* perspNorm, float fovy, float aspect, float near, float far, float scale) {
|
||||
Matrix mf;
|
||||
|
||||
guPerspectiveF(mf, perspNorm, fovy, aspect, near, far, scale);
|
||||
guMtxF2L(mf, m);
|
||||
}
|
||||
|
||||
+140
-3
@@ -1,5 +1,142 @@
|
||||
#include "common.h"
|
||||
/**************************************************************************
|
||||
* *
|
||||
* Copyright (C) 1994, Silicon Graphics, Inc. *
|
||||
* *
|
||||
* These coded instructions, statements, and computer programs contain *
|
||||
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
||||
* are protected by Federal copyright law. They may not be disclosed *
|
||||
* to third parties or copied or duplicated in any form, in whole or *
|
||||
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
||||
* *
|
||||
**************************************************************************/
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/sinf/__sinf.s")
|
||||
#include "PR/ultratypes.h"
|
||||
#include "PR/guint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/gu/sinf/D_800C9340.s")
|
||||
/* ====================================================================
|
||||
* ====================================================================
|
||||
*
|
||||
* Module: fsin.c
|
||||
* $Revision: 1.3 $
|
||||
* $Date: 1998/10/09 06:14:51 $
|
||||
* $Author: has $
|
||||
* $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/libultra/monegi/gu/sinf.c,v $
|
||||
*
|
||||
* Revision history:
|
||||
* 09-Jun-93 - Original Version
|
||||
*
|
||||
* Description: source code for fsin function
|
||||
*
|
||||
* ====================================================================
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#pragma weak fsin = __sinf
|
||||
#pragma weak sinf = __sinf
|
||||
#define fsin __sinf
|
||||
|
||||
/* coefficients for polynomial approximation of sin on +/- pi/2 */
|
||||
|
||||
static const du P[] = {
|
||||
{ 0x3ff00000, 0x00000000 }, { 0xbfc55554, 0xbc83656d }, { 0x3f8110ed, 0x3804c2a0 },
|
||||
{ 0xbf29f6ff, 0xeea56814 }, { 0x3ec5dbdf, 0x0e314bfe },
|
||||
};
|
||||
|
||||
static const du rpi = { 0x3fd45f30, 0x6dc9c883 };
|
||||
|
||||
static const du pihi = { 0x400921fb, 0x50000000 };
|
||||
|
||||
static const du pilo = { 0x3e6110b4, 0x611a6263 };
|
||||
|
||||
static const fu zero = { 0x00000000 };
|
||||
|
||||
/* ====================================================================
|
||||
*
|
||||
* FunctionName fsin
|
||||
*
|
||||
* Description computes sine of arg
|
||||
*
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
float fsin(float x) {
|
||||
double dx, xsq, poly;
|
||||
double dn;
|
||||
int n;
|
||||
double result;
|
||||
int ix, xpt;
|
||||
|
||||
ix = *(int*) &x;
|
||||
xpt = (ix >> 22);
|
||||
xpt &= 0x1ff;
|
||||
|
||||
/* xpt is exponent(x) + 1 bit of mantissa */
|
||||
|
||||
if (xpt < 0xff) {
|
||||
/* |x| < 1.5 */
|
||||
|
||||
dx = x;
|
||||
|
||||
if (xpt >= 0xe6) {
|
||||
/* |x| >= 2^(-12) */
|
||||
|
||||
/* compute sin(x) with a standard polynomial approximation */
|
||||
|
||||
xsq = dx * dx;
|
||||
|
||||
poly = ((P[4].d * xsq + P[3].d) * xsq + P[2].d) * xsq + P[1].d;
|
||||
|
||||
result = dx + (dx * xsq) * poly;
|
||||
|
||||
return ((float) result);
|
||||
}
|
||||
|
||||
return (x);
|
||||
}
|
||||
|
||||
if (xpt < 0x136) {
|
||||
/* |x| < 2^28 */
|
||||
|
||||
dx = x;
|
||||
|
||||
/* reduce argument to +/- pi/2 */
|
||||
|
||||
dn = dx * rpi.d;
|
||||
|
||||
n = ROUND(dn);
|
||||
dn = n;
|
||||
|
||||
dx = dx - dn * pihi.d;
|
||||
dx = dx - dn * pilo.d; /* dx = x - n*pi */
|
||||
|
||||
/* compute sin(dx) as before, negating result if n is odd
|
||||
*/
|
||||
|
||||
xsq = dx * dx;
|
||||
|
||||
poly = ((P[4].d * xsq + P[3].d) * xsq + P[2].d) * xsq + P[1].d;
|
||||
|
||||
result = dx + (dx * xsq) * poly;
|
||||
|
||||
if ((n & 1) == 0) {
|
||||
return ((float) result);
|
||||
}
|
||||
|
||||
return (-(float) result);
|
||||
}
|
||||
|
||||
if (x != x) {
|
||||
/* x is a NaN; return a quiet NaN */
|
||||
|
||||
#ifdef _IP_NAN_SETS_ERRNO
|
||||
|
||||
*__errnoaddr = EDOM;
|
||||
#endif
|
||||
|
||||
return (__libm_qnan_f);
|
||||
}
|
||||
|
||||
/* just give up and return 0.0 */
|
||||
|
||||
return (zero.f);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,36 @@
|
||||
#include "common.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/host/readhost/osReadHost.s")
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rdb.h"
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
static int readHostInitialized = FALSE;
|
||||
static OSMesgQueue readHostMesgQueue ALIGNED(8);
|
||||
static OSMesg readHostMesgBuf[1];
|
||||
|
||||
u32 __osRdb_Read_Data_Buf;
|
||||
u32 __osRdb_Read_Data_Ct;
|
||||
|
||||
void osReadHost(void* dramAddr, u32 nbytes) {
|
||||
char tstr[4];
|
||||
u32 sent = 0;
|
||||
|
||||
if (!readHostInitialized) {
|
||||
osCreateMesgQueue(&readHostMesgQueue, readHostMesgBuf, ARRLEN(readHostMesgBuf));
|
||||
osSetEventMesg(OS_EVENT_RDB_READ_DONE, &readHostMesgQueue, NULL);
|
||||
readHostInitialized = TRUE;
|
||||
}
|
||||
|
||||
__osRdb_Read_Data_Buf = dramAddr;
|
||||
__osRdb_Read_Data_Ct = nbytes;
|
||||
|
||||
while (sent == 0) {
|
||||
sent += __osRdbSend(tstr, 1, RDB_TYPE_GtoH_READY_FOR_DATA);
|
||||
}
|
||||
|
||||
osRecvMesg(&readHostMesgQueue, NULL, OS_MESG_BLOCK);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "global.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "osint.h"
|
||||
|
||||
#ifdef IMPORT_DATA_PENDING
|
||||
s32 osAiSetNextBuffer(void* bufPtr, u32 size) {
|
||||
static u8 hdwrBugFlag = FALSE;
|
||||
char* bptr;
|
||||
@@ -45,6 +47,3 @@ s32 osAiSetNextBuffer(void* bufPtr, u32 size) {
|
||||
IO_WRITE(AI_LEN_REG, size);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/aisetnextbuf/osAiSetNextBuffer.s")
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,99 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_version.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/R4300.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "piint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/cartrominit/osCartRomInit.s")
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
OSPiHandle __CartRomHandle ALIGNED(8);
|
||||
OSPiHandle* osCartRomInit(void) {
|
||||
u32 value = 0;
|
||||
u32 saveMask;
|
||||
static int first = 1;
|
||||
register u32 stat;
|
||||
u32 latency;
|
||||
u32 pulse;
|
||||
u32 pageSize;
|
||||
u32 relDuration;
|
||||
|
||||
__osPiGetAccess();
|
||||
|
||||
if (!first) {
|
||||
__osPiRelAccess();
|
||||
return &__CartRomHandle;
|
||||
}
|
||||
|
||||
first = 0;
|
||||
__CartRomHandle.type = DEVICE_TYPE_CART;
|
||||
__CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2);
|
||||
__CartRomHandle.domain = PI_DOMAIN1;
|
||||
__CartRomHandle.speed = 0;
|
||||
|
||||
bzero(&__CartRomHandle.transferInfo, sizeof(__OSTranxInfo));
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
|
||||
latency = IO_READ(PI_BSD_DOM1_LAT_REG);
|
||||
pageSize = IO_READ(PI_BSD_DOM1_PGS_REG);
|
||||
relDuration = IO_READ(PI_BSD_DOM1_RLS_REG);
|
||||
pulse = IO_READ(PI_BSD_DOM1_PWD_REG);
|
||||
|
||||
IO_WRITE(PI_BSD_DOM1_LAT_REG, 0xFF);
|
||||
IO_WRITE(PI_BSD_DOM1_PGS_REG, 0);
|
||||
IO_WRITE(PI_BSD_DOM1_RLS_REG, 3);
|
||||
IO_WRITE(PI_BSD_DOM1_PWD_REG, 0xFF);
|
||||
|
||||
value = IO_READ(__CartRomHandle.baseAddress);
|
||||
__CartRomHandle.latency = value & 0xFF;
|
||||
__CartRomHandle.pageSize = (value >> 0x10) & 0xF;
|
||||
__CartRomHandle.relDuration = (value >> 0x14) & 0xF;
|
||||
__CartRomHandle.pulse = (value >> 8) & 0xFF;
|
||||
|
||||
IO_WRITE(PI_BSD_DOM1_LAT_REG, latency);
|
||||
IO_WRITE(PI_BSD_DOM1_PGS_REG, pageSize);
|
||||
IO_WRITE(PI_BSD_DOM1_RLS_REG, relDuration);
|
||||
IO_WRITE(PI_BSD_DOM1_PWD_REG, pulse);
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
__CartRomHandle.next = __osPiTable;
|
||||
__osPiTable = &__CartRomHandle;
|
||||
__osRestoreInt(saveMask);
|
||||
__osPiRelAccess();
|
||||
|
||||
return &__CartRomHandle;
|
||||
}
|
||||
#else
|
||||
|
||||
OSPiHandle CartRomHandle ALIGNED(8);
|
||||
OSPiHandle* osCartRomInit(void) {
|
||||
u32 domain = 0;
|
||||
u32 saveMask;
|
||||
|
||||
if (CartRomHandle.baseAddress == PHYS_TO_K1(PI_DOM1_ADDR2)) {
|
||||
return &CartRomHandle;
|
||||
}
|
||||
|
||||
CartRomHandle.type = DEVICE_TYPE_CART;
|
||||
CartRomHandle.baseAddress = PHYS_TO_K1(PI_DOM1_ADDR2);
|
||||
osPiRawReadIo(NULL, &domain);
|
||||
CartRomHandle.latency = domain & 0xff;
|
||||
CartRomHandle.pulse = (domain >> 8) & 0xff;
|
||||
CartRomHandle.pageSize = (domain >> 0x10) & 0xf;
|
||||
CartRomHandle.relDuration = (domain >> 0x14) & 0xf;
|
||||
CartRomHandle.domain = PI_DOMAIN1;
|
||||
|
||||
#if BUILD_VERSION > VERSION_I
|
||||
CartRomHandle.speed = 0;
|
||||
#endif
|
||||
|
||||
bzero(&CartRomHandle.transferInfo, sizeof(__OSTranxInfo));
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
CartRomHandle.next = __osPiTable;
|
||||
__osPiTable = &CartRomHandle;
|
||||
__osRestoreInt(saveMask);
|
||||
|
||||
return &CartRomHandle;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
#include "common.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepprobe/osEepromProbe.s")
|
||||
s32 osEepromProbe(OSMesgQueue* mq) {
|
||||
s32 status = 0;
|
||||
OSContStatus sdata;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
status = __osEepStatus(mq, &sdata);
|
||||
if (status == 0 && (sdata.type & 0x8000) != 0) {
|
||||
status = 1;
|
||||
} else {
|
||||
status = 0;
|
||||
}
|
||||
|
||||
__osSiRelAccess();
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,86 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepread/osEepromRead.s")
|
||||
OSPifRam __osEepPifRam ALIGNED(16);
|
||||
#if BUILD_VERSION >= VERSION_L
|
||||
s32 __osEepromRead16K;
|
||||
#endif
|
||||
void __osPackEepReadData(u8 address);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepread/__osPackEepReadData.s")
|
||||
s32 osEepromRead(OSMesgQueue* mq, u8 address, u8* buffer) {
|
||||
s32 ret = 0;
|
||||
int i = 0;
|
||||
u8* ptr = (u8*) &__osEepPifRam;
|
||||
OSContStatus sdata;
|
||||
__OSContEepromFormat eepromformat;
|
||||
|
||||
if (address > 0x40) {
|
||||
return -1;
|
||||
}
|
||||
__osSiGetAccess();
|
||||
ret = __osEepStatus(mq, &sdata);
|
||||
if (ret != 0 || sdata.type != 0x8000) {
|
||||
return 8;
|
||||
}
|
||||
while (sdata.status & 0x80) {
|
||||
__osEepStatus(mq, &sdata);
|
||||
}
|
||||
__osPackEepReadData(address);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
__osEepPifRam.ramarray[i] = 0xFF;
|
||||
}
|
||||
__osEepPifRam.pifstatus = 0;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
|
||||
__osContLastCmd = 4;
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
for (i = 0; i < 4; i++) {
|
||||
ptr++;
|
||||
}
|
||||
eepromformat = *(__OSContEepromFormat*) ptr;
|
||||
ret = CHNL_ERR(eepromformat);
|
||||
|
||||
if (ret == 0) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
*buffer++ = eepromformat.data[i];
|
||||
}
|
||||
}
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPackEepReadData(u8 address) {
|
||||
u8* ptr = (u8*) &__osEepPifRam.ramarray;
|
||||
__OSContEepromFormat eepromformat;
|
||||
int i;
|
||||
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
for (i = 0; i < ARRLEN(__osEepPifRam.ramarray) + 1; i++) {
|
||||
__osEepPifRam.ramarray[i] = CONT_CMD_NOP;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osEepPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
eepromformat.txsize = CONT_CMD_READ_EEPROM_TX;
|
||||
eepromformat.rxsize = CONT_CMD_READ_EEPROM_RX;
|
||||
eepromformat.cmd = CONT_CMD_READ_EEPROM;
|
||||
eepromformat.address = address;
|
||||
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
for (i = 0; i < ARRLEN(eepromformat.data); i++) {
|
||||
eepromformat.data[i] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < MAXCONTROLLERS; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
*(__OSContEepromFormat*) (ptr) = eepromformat;
|
||||
ptr += sizeof(__OSContEepromFormat);
|
||||
ptr[0] = CONT_CMD_END;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,142 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepwrite/osEepromWrite.s")
|
||||
void __osPackEepWriteData(u8 address, u8* buffer);
|
||||
s32 osEepromWrite(OSMesgQueue* mq, u8 address, u8* buffer) {
|
||||
s32 ret = 0;
|
||||
int i;
|
||||
u8* ptr = (u8*) &__osEepPifRam.ramarray;
|
||||
__OSContEepromFormat eepromformat;
|
||||
OSContStatus sdata;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepwrite/__osPackEepWriteData.s")
|
||||
if (address > 0x40) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/conteepwrite/__osEepStatus.s")
|
||||
__osSiGetAccess();
|
||||
ret = __osEepStatus(mq, &sdata);
|
||||
|
||||
if (ret != 0 || sdata.type != 0x8000) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
while (sdata.status & 0x80) {
|
||||
__osEepStatus(mq, &sdata);
|
||||
}
|
||||
|
||||
__osPackEepWriteData(address, buffer);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
__osEepPifRam.ramarray[i] = 255;
|
||||
}
|
||||
|
||||
__osEepPifRam.pifstatus = 0;
|
||||
ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
|
||||
__osContLastCmd = 5;
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
eepromformat = *(__OSContEepromFormat*) ptr;
|
||||
ret = CHNL_ERR(eepromformat);
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPackEepWriteData(u8 address, u8* buffer) {
|
||||
u8* ptr = (u8*) &__osEepPifRam.ramarray;
|
||||
__OSContEepromFormat eepromformat;
|
||||
int i;
|
||||
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
for (i = 0; i < ARRLEN(__osEepPifRam.ramarray) + 1; i++) {
|
||||
__osEepPifRam.ramarray[i] = CONT_CMD_NOP;
|
||||
}
|
||||
#endif
|
||||
__osEepPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
eepromformat.txsize = CONT_CMD_WRITE_EEPROM_TX;
|
||||
eepromformat.rxsize = CONT_CMD_WRITE_EEPROM_RX;
|
||||
eepromformat.cmd = CONT_CMD_WRITE_EEPROM;
|
||||
eepromformat.address = address;
|
||||
|
||||
for (i = 0; i < ARRLEN(eepromformat.data); i++) {
|
||||
eepromformat.data[i] = *buffer++;
|
||||
}
|
||||
|
||||
for (i = 0; i < MAXCONTROLLERS; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
*(__OSContEepromFormat*) (ptr) = eepromformat;
|
||||
ptr += sizeof(__OSContEepromFormat);
|
||||
ptr[0] = CONT_CMD_END;
|
||||
}
|
||||
|
||||
s32 __osEepStatus(OSMesgQueue* mq, OSContStatus* data) {
|
||||
s32 ret = 0;
|
||||
int i;
|
||||
u8* ptr = (u8*) __osEepPifRam.ramarray;
|
||||
__OSContRequesFormat requestformat;
|
||||
|
||||
for (i = 0; i < ARRLEN(__osEepPifRam.ramarray) + 1; i++) {
|
||||
__osEepPifRam.ramarray[i] = 0;
|
||||
}
|
||||
|
||||
__osEepPifRam.pifstatus = CONT_CMD_EXE;
|
||||
ptr = (u8*) __osEepPifRam.ramarray;
|
||||
|
||||
for (i = 0; i < MAXCONTROLLERS; i++) {
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS;
|
||||
}
|
||||
|
||||
requestformat.dummy = CONT_CMD_NOP;
|
||||
requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX;
|
||||
requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX;
|
||||
requestformat.cmd = CONT_CMD_REQUEST_STATUS;
|
||||
requestformat.typeh = CONT_CMD_NOP;
|
||||
requestformat.typel = CONT_CMD_NOP;
|
||||
requestformat.status = CONT_CMD_NOP;
|
||||
requestformat.dummy1 = CONT_CMD_NOP;
|
||||
*(__OSContRequesFormat*) ptr = requestformat;
|
||||
ptr += sizeof(__OSContRequesFormat);
|
||||
*ptr = CONT_CMD_END;
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osEepPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
__osContLastCmd = CONT_CMD_END;
|
||||
#else
|
||||
__osContLastCmd = CONT_CMD_WRITE_EEPROM; // seems to be 5 in 2.0H
|
||||
#endif
|
||||
ret = __osSiRawStartDma(OS_READ, &__osEepPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptr = (u8*) &__osEepPifRam;
|
||||
|
||||
for (i = 0; i < MAXCONTROLLERS; i++) {
|
||||
*ptr++ = 0;
|
||||
}
|
||||
|
||||
requestformat = *(__OSContRequesFormat*) ptr;
|
||||
data->errno = CHNL_ERR(requestformat);
|
||||
data->type = (requestformat.typel << 8) | requestformat.typeh;
|
||||
data->status = requestformat.status;
|
||||
|
||||
if (data->errno != 0) {
|
||||
return data->errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contquery/osContStartQuery.s")
|
||||
s32 osContStartQuery(OSMesgQueue* mq) {
|
||||
s32 ret = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contquery/osContGetQuery.s")
|
||||
__osSiGetAccess();
|
||||
|
||||
if (__osContLastCmd != CONT_CMD_REQUEST_STATUS) {
|
||||
__osPackRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray);
|
||||
__osContLastCmd = CONT_CMD_REQUEST_STATUS;
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osContGetQuery(OSContStatus* data) {
|
||||
u8 pattern;
|
||||
__osContGetInitData(&pattern, data);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,170 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contramread/__osContRamRead.s")
|
||||
#define READFORMAT(ptr) ((__OSContRamReadFormat*) (ptr))
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contramread/__osPackRamReadData.s")
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
s32 __osPfsLastChannel = -1;
|
||||
|
||||
s32 __osContRamRead(OSMesgQueue* mq, int channel, u16 address, u8* buffer) {
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
u8* ptr;
|
||||
s32 retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
ptr = (u8*) &__osPfsPifRam;
|
||||
|
||||
if (__osContLastCmd != CONT_CMD_READ_PAK || (u32) __osPfsLastChannel != channel) {
|
||||
__osContLastCmd = CONT_CMD_READ_PAK;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
READFORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
READFORMAT(ptr)->txsize = CONT_CMD_READ_PAK_TX;
|
||||
READFORMAT(ptr)->rxsize = CONT_CMD_READ_PAK_RX;
|
||||
READFORMAT(ptr)->cmd = CONT_CMD_READ_PAK;
|
||||
READFORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr += channel;
|
||||
}
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
READFORMAT(ptr)->addrh = address >> 3;
|
||||
READFORMAT(ptr)->addrl = (u8) ((address << 5) | __osContAddressCrc(address));
|
||||
#else
|
||||
READFORMAT(ptr)->address = (address << 0x5) | __osContAddressCrc(address);
|
||||
#endif
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = CHNL_ERR(*READFORMAT(ptr));
|
||||
|
||||
if (!ret) {
|
||||
if (__osContDataCrc(READFORMAT(ptr)->data) != READFORMAT(ptr)->datacrc) {
|
||||
ret = __osPfsGetStatus(mq, channel);
|
||||
|
||||
if (ret) {
|
||||
break;
|
||||
} else {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
bcopy(READFORMAT(ptr)->data, buffer, BLOCKSIZE);
|
||||
}
|
||||
} else {
|
||||
ret = PFS_ERR_NOPACK;
|
||||
}
|
||||
} while ((ret == PFS_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
||||
static void __osPackRamReadData(int channel, u16 address);
|
||||
|
||||
s32 __osContRamRead(OSMesgQueue* mq, int channel, u16 address, u8* buffer) {
|
||||
s32 ret = 0;
|
||||
int i;
|
||||
u8* ptr = (u8*) &__osPfsPifRam;
|
||||
__OSContRamReadFormat ramreadformat;
|
||||
int retry = 2;
|
||||
|
||||
__osSiGetAccess();
|
||||
__osContLastCmd = CONT_CMD_READ_PAK;
|
||||
__osPackRamReadData(channel, address);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
do {
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
ptr = (u8*) &__osPfsPifRam;
|
||||
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; i++) {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
ramreadformat = *READFORMAT(ptr);
|
||||
|
||||
ret = CHNL_ERR(ramreadformat);
|
||||
if (ret == 0) {
|
||||
u8 c = __osContDataCrc((u8*) &ramreadformat.data);
|
||||
if (c != ramreadformat.datacrc) {
|
||||
ret = __osPfsGetStatus(mq, channel);
|
||||
|
||||
if (ret != 0) {
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
} else {
|
||||
for (i = 0; i < ARRLEN(ramreadformat.data); i++) {
|
||||
*buffer++ = ramreadformat.data[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = PFS_ERR_NOPACK;
|
||||
}
|
||||
} while ((ret == PFS_ERR_CONTRFAIL) && retry-- >= 0);
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __osPackRamReadData(int channel, u16 address) {
|
||||
u8* ptr;
|
||||
__OSContRamReadFormat ramreadformat;
|
||||
int i;
|
||||
|
||||
ptr = (u8*) __osPfsPifRam.ramarray;
|
||||
|
||||
#if BUILD_VERSION < VERSION_I
|
||||
for (i = 0; i < 16; i++) {
|
||||
__osPfsPifRam.ramarray[i] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
ramreadformat.dummy = CONT_CMD_NOP;
|
||||
ramreadformat.txsize = CONT_CMD_READ_PAK_TX;
|
||||
ramreadformat.rxsize = CONT_CMD_READ_PAK_RX;
|
||||
ramreadformat.cmd = CONT_CMD_READ_PAK;
|
||||
ramreadformat.address = (address << 0x5) | __osContAddressCrc(address);
|
||||
ramreadformat.datacrc = CONT_CMD_NOP;
|
||||
|
||||
for (i = 0; i < ARRLEN(ramreadformat.data); i++) {
|
||||
ramreadformat.data[i] = CONT_CMD_NOP;
|
||||
}
|
||||
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
*(__OSContRamReadFormat*) ptr = ramreadformat;
|
||||
ptr += sizeof(__OSContRamReadFormat);
|
||||
ptr[0] = CONT_CMD_END;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,176 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contramwrite/__osContRamWrite.s")
|
||||
extern s32 __osPfsLastChannel;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contramwrite/__osPackRamWriteData.s")
|
||||
#define READFORMAT(ptr) ((__OSContRamReadFormat*) (ptr))
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
s32 __osContRamWrite(OSMesgQueue* mq, int channel, u16 address, u8* buffer, int force) {
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
u8* ptr;
|
||||
s32 retry = 2;
|
||||
u8 crc;
|
||||
|
||||
if ((force != TRUE) && (address < PFS_LABEL_AREA) && (address != 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
ptr = (u8*) __osPfsPifRam.ramarray;
|
||||
|
||||
if (__osContLastCmd != CONT_CMD_WRITE_PAK || (u32) __osPfsLastChannel != channel) {
|
||||
__osContLastCmd = CONT_CMD_WRITE_PAK;
|
||||
__osPfsLastChannel = channel;
|
||||
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS;
|
||||
}
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
|
||||
READFORMAT(ptr)->dummy = CONT_CMD_NOP;
|
||||
READFORMAT(ptr)->txsize = CONT_CMD_WRITE_PAK_TX;
|
||||
READFORMAT(ptr)->rxsize = CONT_CMD_WRITE_PAK_RX;
|
||||
READFORMAT(ptr)->cmd = CONT_CMD_WRITE_PAK;
|
||||
READFORMAT(ptr)->datacrc = 0xFF;
|
||||
|
||||
ptr[sizeof(__OSContRamReadFormat)] = CONT_CMD_END;
|
||||
} else {
|
||||
ptr += channel;
|
||||
}
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
READFORMAT(ptr)->addrh = address >> 3;
|
||||
READFORMAT(ptr)->addrl = ((address << 5) | __osContAddressCrc(address));
|
||||
#else
|
||||
READFORMAT(ptr)->address = (address << 0x5) | __osContAddressCrc(address);
|
||||
#endif
|
||||
|
||||
bcopy(buffer, READFORMAT(ptr)->data, BLOCKSIZE);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
crc = __osContDataCrc(buffer);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
ret = CHNL_ERR(*READFORMAT(ptr));
|
||||
|
||||
if (!ret) {
|
||||
if (crc != READFORMAT(ptr)->datacrc) {
|
||||
if ((ret = __osPfsGetStatus(mq, channel))) {
|
||||
break;
|
||||
} else {
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = PFS_ERR_NOPACK;
|
||||
}
|
||||
} while ((ret == PFS_ERR_CONTRFAIL) && (retry-- >= 0));
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
|
||||
static void __osPackRamWriteData(int channel, u16 address, u8* buffer);
|
||||
|
||||
s32 __osContRamWrite(OSMesgQueue* mq, int channel, u16 address, u8* buffer, int force) {
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
u8* ptr = (u8*) &__osPfsPifRam;
|
||||
__OSContRamReadFormat ramreadformat;
|
||||
s32 retry = 2;
|
||||
u8 crc;
|
||||
|
||||
if ((force != TRUE) && (address < PFS_LABEL_AREA) && (address != 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
__osSiGetAccess();
|
||||
__osContLastCmd = CONT_CMD_WRITE_PAK;
|
||||
__osPackRamWriteData(channel, address, buffer);
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
do {
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
ptr = (u8*) &__osPfsPifRam;
|
||||
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; i++) {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
ramreadformat = *READFORMAT(ptr);
|
||||
|
||||
ret = CHNL_ERR(ramreadformat);
|
||||
if (ret == 0) {
|
||||
if (__osContDataCrc(buffer) != ramreadformat.datacrc) {
|
||||
ret = __osPfsGetStatus(mq, channel);
|
||||
|
||||
if (ret != 0) {
|
||||
__osSiRelAccess();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = PFS_ERR_CONTRFAIL;
|
||||
}
|
||||
} else {
|
||||
ret = PFS_ERR_NOPACK;
|
||||
}
|
||||
} while ((ret == PFS_ERR_CONTRFAIL) && retry-- >= 0);
|
||||
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __osPackRamWriteData(int channel, u16 address, u8* buffer) {
|
||||
u8* ptr;
|
||||
__OSContRamReadFormat ramreadformat;
|
||||
int i;
|
||||
|
||||
ptr = (u8*) __osPfsPifRam.ramarray;
|
||||
|
||||
#if BUILD_VERSION < VERSION_I
|
||||
for (i = 0; i < 16; i++) {
|
||||
__osPfsPifRam.ramarray[i] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
ramreadformat.dummy = CONT_CMD_NOP;
|
||||
ramreadformat.txsize = CONT_CMD_WRITE_PAK_TX;
|
||||
ramreadformat.rxsize = CONT_CMD_WRITE_PAK_RX;
|
||||
ramreadformat.cmd = CONT_CMD_WRITE_PAK;
|
||||
ramreadformat.address = (address << 0x5) | __osContAddressCrc(address);
|
||||
ramreadformat.datacrc = CONT_CMD_NOP;
|
||||
|
||||
for (i = 0; i < ARRLEN(ramreadformat.data); i++) {
|
||||
ramreadformat.data[i] = *buffer++;
|
||||
}
|
||||
|
||||
if (channel != 0) {
|
||||
for (i = 0; i < channel; i++) {
|
||||
*ptr++ = CONT_CMD_REQUEST_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
*(__OSContRamReadFormat*) ptr = ramreadformat;
|
||||
ptr += sizeof(__OSContRamReadFormat);
|
||||
ptr[0] = CONT_CMD_END;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,74 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contreaddata/osContStartReadData.s")
|
||||
static void __osPackReadData(void);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contreaddata/osContGetReadData.s")
|
||||
s32 osContStartReadData(OSMesgQueue* mq) {
|
||||
s32 ret = 0;
|
||||
s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/contreaddata/__osPackReadData.s")
|
||||
__osSiGetAccess();
|
||||
|
||||
if (__osContLastCmd != CONT_CMD_READ_BUTTON) {
|
||||
__osPackReadData();
|
||||
ret = __osSiRawStartDma(OS_WRITE, __osContPifRam.ramarray);
|
||||
osRecvMesg(mq, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
for (i = 0; i <= ARRLEN(__osContPifRam.ramarray); i++) {
|
||||
__osContPifRam.ramarray[i] = 0xFF;
|
||||
}
|
||||
__osContPifRam.pifstatus = 0;
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, __osContPifRam.ramarray);
|
||||
__osContLastCmd = CONT_CMD_READ_BUTTON;
|
||||
__osSiRelAccess();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void osContGetReadData(OSContPad* data) {
|
||||
u8* ptr = (u8*) __osContPifRam.ramarray;
|
||||
__OSContReadFormat readformat;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(__OSContReadFormat), data++) {
|
||||
readformat = *(__OSContReadFormat*) ptr;
|
||||
data->errno = CHNL_ERR(readformat);
|
||||
|
||||
if (data->errno != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data->button = readformat.button;
|
||||
data->stick_x = readformat.stick_x;
|
||||
data->stick_y = readformat.stick_y;
|
||||
}
|
||||
}
|
||||
|
||||
static void __osPackReadData(void) {
|
||||
u8* ptr = (u8*) __osContPifRam.ramarray;
|
||||
__OSContReadFormat readformat;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= ARRLEN(__osContPifRam.ramarray); i++) {
|
||||
__osContPifRam.ramarray[i] = 0;
|
||||
}
|
||||
|
||||
__osContPifRam.pifstatus = CONT_CMD_EXE;
|
||||
readformat.dummy = CONT_CMD_NOP;
|
||||
readformat.txsize = CONT_CMD_READ_BUTTON_TX;
|
||||
readformat.rxsize = CONT_CMD_READ_BUTTON_RX;
|
||||
readformat.cmd = CONT_CMD_READ_BUTTON;
|
||||
readformat.button = 0xFFFF;
|
||||
readformat.stick_x = -1;
|
||||
readformat.stick_y = -1;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*(__OSContReadFormat*) ptr = readformat;
|
||||
ptr += sizeof(__OSContReadFormat);
|
||||
}
|
||||
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,15 @@
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
extern s32 __osContinitialized;
|
||||
OSPifRam __osContPifRam ALIGNED(16);
|
||||
u8 __osContLastCmd;
|
||||
u8 __osMaxControllers;
|
||||
|
||||
OSTimer __osEepromTimer;
|
||||
OSMesgQueue __osEepromTimerQ ALIGNED(8);
|
||||
OSMesg __osEepromTimerMsg;
|
||||
|
||||
s32 __osContinitialized = 0;
|
||||
|
||||
#define USEC_TO_CYCLES_OLD(n, clock) ((n) * (u64) (clock) / 1000000)
|
||||
|
||||
|
||||
+112
-3
@@ -1,5 +1,114 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/crc/__osContAddressCrc.s")
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/crc/__osContDataCrc.s")
|
||||
u8 __osContAddressCrc(u16 addr) {
|
||||
u32 temp = 0;
|
||||
u32 i = 0x400;
|
||||
|
||||
do {
|
||||
temp <<= 1;
|
||||
|
||||
if ((u32) addr & i) {
|
||||
if (temp & 0x20) {
|
||||
temp ^= 0x14;
|
||||
} else {
|
||||
++temp;
|
||||
}
|
||||
} else if (temp & 0x20) {
|
||||
temp ^= 0x15;
|
||||
}
|
||||
|
||||
i >>= 1;
|
||||
} while (i != 0);
|
||||
|
||||
i = 5;
|
||||
|
||||
do {
|
||||
temp <<= 1;
|
||||
if (temp & 0x20) {
|
||||
temp ^= 0x15;
|
||||
}
|
||||
} while (--i != 0);
|
||||
|
||||
return temp & 0x1F;
|
||||
}
|
||||
|
||||
u8 __osContDataCrc(u8* data) {
|
||||
u32 temp = 0;
|
||||
u32 i;
|
||||
u32 j;
|
||||
|
||||
for (i = 0x20; i; --i) {
|
||||
for (j = 0x80; j; j >>= 1) {
|
||||
temp <<= 1;
|
||||
|
||||
if ((*data & j) != 0) {
|
||||
if ((temp & 0x100) != 0) {
|
||||
temp ^= 0x84;
|
||||
} else {
|
||||
++temp;
|
||||
}
|
||||
} else if (temp & 0x100) {
|
||||
temp ^= 0x85;
|
||||
}
|
||||
}
|
||||
|
||||
data++;
|
||||
}
|
||||
do {
|
||||
temp <<= 1;
|
||||
|
||||
if (temp & 0x100) {
|
||||
temp ^= 0x85;
|
||||
}
|
||||
} while (++i < 8U);
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
u8 __osContAddressCrc(u16 addr) {
|
||||
u8 temp = 0;
|
||||
u8 temp2;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
temp2 = (temp & 0x10) ? 0x15 : 0;
|
||||
|
||||
temp <<= 1;
|
||||
temp |= (u8) ((addr & 0x400) ? 1 : 0);
|
||||
addr <<= 1;
|
||||
temp ^= temp2;
|
||||
}
|
||||
|
||||
return temp & 0x1f;
|
||||
}
|
||||
|
||||
u8 __osContDataCrc(u8* data) {
|
||||
u8 temp = 0;
|
||||
u8 temp2;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i <= 32; i++) {
|
||||
for (j = 7; j > -1; j--) {
|
||||
temp2 = (temp & 0x80) ? 0x85 : 0;
|
||||
|
||||
temp <<= 1;
|
||||
|
||||
if (i == 32) {
|
||||
temp &= -1;
|
||||
} else {
|
||||
temp |= ((*data & (1 << j)) ? 1 : 0);
|
||||
}
|
||||
|
||||
temp ^= temp2;
|
||||
}
|
||||
data++;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+107
-2
@@ -1,3 +1,108 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "piint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/devmgr/__osDevMgrMain.s")
|
||||
void __osDevMgrMain(void* args) {
|
||||
OSIoMesg* mb;
|
||||
OSMesg em;
|
||||
OSMesg dummy;
|
||||
s32 ret;
|
||||
OSDevMgr* dm;
|
||||
s32 messageSend = 0;
|
||||
|
||||
dm = (OSDevMgr*) args;
|
||||
mb = NULL;
|
||||
ret = 0;
|
||||
|
||||
while (TRUE) {
|
||||
osRecvMesg(dm->cmdQueue, (OSMesg) &mb, OS_MESG_BLOCK);
|
||||
|
||||
if (mb->piHandle != NULL && mb->piHandle->type == DEVICE_TYPE_64DD &&
|
||||
(mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_0 ||
|
||||
mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_1)) {
|
||||
__OSBlockInfo* blockInfo;
|
||||
__OSTranxInfo* info;
|
||||
info = &mb->piHandle->transferInfo;
|
||||
blockInfo = &info->block[info->blockNum];
|
||||
info->sectorNum = -1;
|
||||
|
||||
if (info->transferMode != LEO_SECTOR_MODE) {
|
||||
blockInfo->dramAddr = (void*) ((u32) blockInfo->dramAddr - blockInfo->sectorSize);
|
||||
}
|
||||
|
||||
if (info->transferMode == LEO_TRACK_MODE && mb->piHandle->transferInfo.cmdType == LEO_CMD_TYPE_0) {
|
||||
messageSend = 1;
|
||||
} else {
|
||||
messageSend = 0;
|
||||
}
|
||||
|
||||
osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
|
||||
__osResetGlobalIntMask(OS_IM_PI);
|
||||
__osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, (info->bmCtlShadow | 0x80000000));
|
||||
|
||||
readblock1:
|
||||
osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK);
|
||||
info = &mb->piHandle->transferInfo;
|
||||
blockInfo = &info->block[info->blockNum];
|
||||
|
||||
if (blockInfo->errStatus == LEO_ERROR_29) {
|
||||
u32 stat;
|
||||
__osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_RESET);
|
||||
__osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow);
|
||||
__osEPiRawReadIo(mb->piHandle, LEO_STATUS, &stat);
|
||||
|
||||
if (stat & LEO_STATUS_MECHANIC_INTERRUPT) {
|
||||
__osEPiRawWriteIo(mb->piHandle, LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_CLR_MECHANIC_INTR);
|
||||
}
|
||||
|
||||
blockInfo->errStatus = LEO_ERROR_4;
|
||||
IO_WRITE(PI_STATUS_REG, PI_CLR_INTR);
|
||||
__osSetGlobalIntMask(OS_IM_PI | SR_IBIT4);
|
||||
}
|
||||
|
||||
osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK);
|
||||
|
||||
if (messageSend == 1 && mb->piHandle->transferInfo.block[0].errStatus == LEO_ERROR_GOOD) {
|
||||
messageSend = 0;
|
||||
goto readblock1;
|
||||
}
|
||||
|
||||
osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK);
|
||||
if (mb->piHandle->transferInfo.blockNum == 1) {
|
||||
osYieldThread();
|
||||
}
|
||||
} else {
|
||||
switch (mb->hdr.type) {
|
||||
case OS_MESG_TYPE_DMAREAD:
|
||||
osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
|
||||
ret = dm->dma(OS_READ, mb->devAddr, mb->dramAddr, mb->size);
|
||||
break;
|
||||
case OS_MESG_TYPE_DMAWRITE:
|
||||
osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
|
||||
ret = dm->dma(OS_WRITE, mb->devAddr, mb->dramAddr, mb->size);
|
||||
break;
|
||||
case OS_MESG_TYPE_EDMAREAD:
|
||||
osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
|
||||
ret = dm->edma(mb->piHandle, OS_READ, mb->devAddr, mb->dramAddr, mb->size);
|
||||
break;
|
||||
case OS_MESG_TYPE_EDMAWRITE:
|
||||
osRecvMesg(dm->acsQueue, &dummy, OS_MESG_BLOCK);
|
||||
ret = dm->edma(mb->piHandle, OS_WRITE, mb->devAddr, mb->dramAddr, mb->size);
|
||||
break;
|
||||
case OS_MESG_TYPE_LOOPBACK:
|
||||
osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK);
|
||||
ret = -1;
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
osRecvMesg(dm->evtQueue, &em, OS_MESG_BLOCK);
|
||||
osSendMesg(mb->hdr.retQueue, mb, OS_MESG_NOBLOCK);
|
||||
osSendMesg(dm->acsQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/dpsetstat/osDpSetStatus.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osDpSetStatus(u32 data) {
|
||||
IO_WRITE(DPC_STATUS_REG, data);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,61 @@
|
||||
#include "common.h"
|
||||
#include "piint.h"
|
||||
#include "PR/ultraerror.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/epidma/osEPiStartDma.s")
|
||||
s32 osEPiStartDma(OSPiHandle* pihandle, OSIoMesg* mb, s32 direction) {
|
||||
register s32 ret;
|
||||
|
||||
if (!__osPiDevMgr.active) {
|
||||
#ifdef _DEBUG
|
||||
__osError(ERR_OSPISTARTDMA_PIMGR, 0);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((mb->hdr.pri != OS_MESG_PRI_NORMAL) && (mb->hdr.pri != OS_MESG_PRI_HIGH)) {
|
||||
__osError(ERR_OSPISTARTDMA_PRI, 1, mb->hdr.pri);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((direction != OS_READ) && (direction != OS_WRITE)) {
|
||||
__osError(ERR_OSPISTARTDMA_DIR, 1, direction);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mb->devAddr & 0x1) {
|
||||
__osError(ERR_OSPISTARTDMA_DEVADDR, 1, mb->devAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((u32) mb->dramAddr & 0x7) {
|
||||
__osError(ERR_OSPISTARTDMA_ADDR, 1, mb->dramAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mb->size & 0x1) {
|
||||
__osError(ERR_OSPISTARTDMA_SIZE, 1, mb->size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((mb->size == 0) || (mb->size > (16 * 1024 * 1024))) {
|
||||
__osError(ERR_OSPISTARTDMA_RANGE, 1, mb->size);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
mb->piHandle = pihandle;
|
||||
|
||||
if (direction == OS_READ) {
|
||||
mb->hdr.type = OS_MESG_TYPE_EDMAREAD;
|
||||
} else {
|
||||
mb->hdr.type = OS_MESG_TYPE_EDMAWRITE;
|
||||
}
|
||||
|
||||
if (mb->hdr.pri == OS_MESG_PRI_HIGH) {
|
||||
ret = osJamMesg(osPiGetCmdQueue(), (OSMesg) mb, OS_MESG_NOBLOCK);
|
||||
} else {
|
||||
ret = osSendMesg(osPiGetCmdQueue(), (OSMesg) mb, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
#include "common.h"
|
||||
#include "piint.h"
|
||||
#include "PR/ultraerror.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/epirawdma/osEPiRawStartDma.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osEPiRawStartDma(OSPiHandle* pihandle, s32 direction, u32 devAddr, void* dramAddr, u32 size) {
|
||||
u32 stat;
|
||||
u32 domain;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((direction != OS_READ) && (direction != OS_WRITE)) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_DIR, 1, direction);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (devAddr & 0x1) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_DEVADDR, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((u32) dramAddr & 0x7) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_ADDR, 1, dramAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size & 0x1) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_SIZE, 1, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size == 0) || (size > (16 * 1024 * 1024))) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_RANGE, 1, size);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
EPI_SYNC(pihandle, stat, domain);
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
|
||||
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS(pihandle->baseAddress | devAddr));
|
||||
|
||||
switch (direction) {
|
||||
case OS_READ:
|
||||
IO_WRITE(PI_WR_LEN_REG, size - 1);
|
||||
break;
|
||||
case OS_WRITE:
|
||||
IO_WRITE(PI_RD_LEN_REG, size - 1);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
#include "common.h"
|
||||
#include "piint.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/assert.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/epirawread/osEPiRawReadIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 28
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osEPiRawReadIo(OSPiHandle* pihandle, u32 devAddr, u32* data) {
|
||||
register u32 stat;
|
||||
register u32 domain;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (devAddr & 0x3) {
|
||||
__osError(ERR_OSPIRAWREADIO, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
assert(data != NULL);
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
*data = IO_READ(pihandle->baseAddress | devAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#include "common.h"
|
||||
#include "piint.h"
|
||||
#include "PR/ultraerror.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/epirawwrite/osEPiRawWriteIo.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osEPiRawWriteIo(OSPiHandle* pihandle, u32 devAddr, u32 data) {
|
||||
register u32 stat;
|
||||
register u32 domain;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (devAddr & 0x3) {
|
||||
__osError(ERR_OSPIRAWWRITEIO, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
IO_WRITE(pihandle->baseAddress | devAddr, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
#include "common.h"
|
||||
// This file was removed in 2.0J
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/os_libc.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "macros.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/leodiskinit/osLeoDiskInit.s")
|
||||
OSPiHandle LeoDiskHandle ALIGNED(8);
|
||||
OSPiHandle* __osDiskHandle;
|
||||
|
||||
OSPiHandle* osLeoDiskInit() {
|
||||
u32 saveMask;
|
||||
|
||||
LeoDiskHandle.type = DEVICE_TYPE_64DD;
|
||||
LeoDiskHandle.baseAddress = PHYS_TO_K1(PI_DOM2_ADDR1);
|
||||
LeoDiskHandle.latency = 3;
|
||||
LeoDiskHandle.pulse = 6;
|
||||
LeoDiskHandle.pageSize = 6;
|
||||
LeoDiskHandle.relDuration = 2;
|
||||
LeoDiskHandle.domain = PI_DOMAIN2;
|
||||
|
||||
IO_WRITE(PI_BSD_DOM2_LAT_REG, LeoDiskHandle.latency);
|
||||
IO_WRITE(PI_BSD_DOM2_PWD_REG, LeoDiskHandle.pulse);
|
||||
IO_WRITE(PI_BSD_DOM2_PGS_REG, LeoDiskHandle.pageSize);
|
||||
IO_WRITE(PI_BSD_DOM2_RLS_REG, LeoDiskHandle.relDuration);
|
||||
#if BUILD_VERSION >= VERSION_I
|
||||
LeoDiskHandle.speed = 0;
|
||||
#endif
|
||||
|
||||
bzero(&LeoDiskHandle.transferInfo, sizeof(__OSTranxInfo));
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
LeoDiskHandle.next = __osPiTable;
|
||||
__osPiTable = &LeoDiskHandle;
|
||||
__osDiskHandle = &LeoDiskHandle;
|
||||
__osRestoreInt(saveMask);
|
||||
|
||||
return &LeoDiskHandle;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,195 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "osint.h"
|
||||
#include "piint.h"
|
||||
#include "macros.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/leointerrupt/__osLeoInterrupt.s")
|
||||
extern OSPiHandle* __osDiskHandle;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/leointerrupt/__osLeoAbnormalResume.s")
|
||||
u8 leoDiskStack[OS_PIM_STACKSIZE] ALIGNED(16);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/leointerrupt/__osLeoResume.s")
|
||||
static void __osLeoAbnormalResume(void);
|
||||
static void __osLeoResume(void);
|
||||
|
||||
s32 __osLeoInterrupt() {
|
||||
u32 stat = 0;
|
||||
volatile u32 pi_stat;
|
||||
u32 bm_stat;
|
||||
__OSTranxInfo* info = &__osDiskHandle->transferInfo;
|
||||
__OSBlockInfo* blockInfo = &info->block[info->blockNum];
|
||||
|
||||
pi_stat = IO_READ(PI_STATUS_REG);
|
||||
if (pi_stat & PI_STATUS_DMA_BUSY) {
|
||||
__OSGlobalIntMask = __OSGlobalIntMask & ~SR_IBIT4; // cart interrupt
|
||||
blockInfo->errStatus = LEO_ERROR_29;
|
||||
__osLeoResume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
WAIT_ON_IOBUSY(pi_stat);
|
||||
stat = IO_READ(LEO_STATUS);
|
||||
if (stat & LEO_STATUS_MECHANIC_INTERRUPT) {
|
||||
WAIT_ON_IOBUSY(pi_stat);
|
||||
IO_WRITE(LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_CLR_MECHANIC_INTR);
|
||||
blockInfo->errStatus = LEO_ERROR_GOOD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info->cmdType == LEO_CMD_TYPE_2) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (stat & LEO_STATUS_BUFFER_MANAGER_ERROR) {
|
||||
WAIT_ON_IOBUSY(pi_stat);
|
||||
stat = IO_READ(LEO_STATUS);
|
||||
blockInfo->errStatus = LEO_ERROR_22;
|
||||
__osLeoResume();
|
||||
IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR);
|
||||
__OSGlobalIntMask |= OS_IM_PI;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->cmdType == LEO_CMD_TYPE_1) {
|
||||
if ((stat & LEO_STATUS_DATA_REQUEST) == 0) {
|
||||
if (info->sectorNum + 1 != info->transferMode * 85) {
|
||||
blockInfo->errStatus = LEO_ERROR_24;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR);
|
||||
__OSGlobalIntMask |= OS_IM_PI;
|
||||
blockInfo->errStatus = LEO_ERROR_GOOD;
|
||||
__osLeoResume();
|
||||
return 1;
|
||||
} else {
|
||||
blockInfo->dramAddr = (void*) ((u32) blockInfo->dramAddr + blockInfo->sectorSize);
|
||||
info->sectorNum++;
|
||||
osEPiRawStartDma(__osDiskHandle, OS_WRITE, LEO_SECTOR_BUFF, blockInfo->dramAddr, blockInfo->sectorSize);
|
||||
return 1;
|
||||
}
|
||||
} else if (info->cmdType == LEO_CMD_TYPE_0) {
|
||||
if (info->transferMode == LEO_SECTOR_MODE) {
|
||||
if (info->sectorNum > (s32) blockInfo->C1ErrNum + 17) {
|
||||
blockInfo->errStatus = LEO_ERROR_GOOD;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((stat & LEO_STATUS_DATA_REQUEST) == 0) {
|
||||
blockInfo->errStatus = LEO_ERROR_23;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
blockInfo->dramAddr = (void*) ((u32) blockInfo->dramAddr + blockInfo->sectorSize);
|
||||
}
|
||||
|
||||
bm_stat = IO_READ(LEO_BM_STATUS);
|
||||
if ((bm_stat & LEO_BM_STATUS_C1SINGLE && bm_stat & LEO_BM_STATUS_C1DOUBLE) || bm_stat & LEO_BM_STATUS_MICRO) {
|
||||
if (blockInfo->C1ErrNum > 3) {
|
||||
if (info->transferMode != LEO_SECTOR_MODE || info->sectorNum > 0x52) {
|
||||
blockInfo->errStatus = LEO_ERROR_23;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
int errNum = blockInfo->C1ErrNum;
|
||||
blockInfo->C1ErrSector[errNum] = info->sectorNum + 1;
|
||||
}
|
||||
|
||||
blockInfo->C1ErrNum++;
|
||||
}
|
||||
|
||||
if (stat & LEO_STATUS_C2_TRANSFER) {
|
||||
if (info->sectorNum + 1 != 88) {
|
||||
blockInfo->errStatus = LEO_ERROR_24;
|
||||
__osLeoAbnormalResume();
|
||||
}
|
||||
|
||||
if (info->transferMode == LEO_TRACK_MODE && info->blockNum == 0) {
|
||||
info->blockNum = 1;
|
||||
info->sectorNum = -1;
|
||||
info->block[1].dramAddr = (void*) ((u32) info->block[1].dramAddr - info->block[1].sectorSize);
|
||||
|
||||
blockInfo->errStatus = LEO_ERROR_22;
|
||||
} else {
|
||||
IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR);
|
||||
__OSGlobalIntMask |= OS_IM_PI;
|
||||
info->cmdType = LEO_CMD_TYPE_2;
|
||||
blockInfo->errStatus = LEO_ERROR_GOOD;
|
||||
}
|
||||
|
||||
osEPiRawStartDma(__osDiskHandle, OS_READ, LEO_C2_BUFF, blockInfo->C2Addr, blockInfo->sectorSize * 4);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (info->sectorNum == -1 && info->transferMode == LEO_TRACK_MODE && info->blockNum == 1) {
|
||||
__OSBlockInfo* bptr = &info->block[0];
|
||||
if (bptr->C1ErrNum == 0) {
|
||||
if (((u32*) bptr->C2Addr)[0] | ((u32*) bptr->C2Addr)[1] | ((u32*) bptr->C2Addr)[2] |
|
||||
((u32*) bptr->C2Addr)[3]) {
|
||||
bptr->errStatus = LEO_ERROR_24;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bptr->errStatus = 0;
|
||||
__osLeoResume();
|
||||
}
|
||||
info->sectorNum++;
|
||||
if (stat & LEO_STATUS_DATA_REQUEST) {
|
||||
if (info->sectorNum > 0x54) {
|
||||
blockInfo->errStatus = LEO_ERROR_24;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
osEPiRawStartDma(__osDiskHandle, 0, LEO_SECTOR_BUFF, blockInfo->dramAddr, blockInfo->sectorSize);
|
||||
blockInfo->errStatus = LEO_ERROR_GOOD;
|
||||
return 1;
|
||||
} else if (info->sectorNum <= 0x54) {
|
||||
blockInfo->errStatus = LEO_ERROR_24;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
blockInfo->errStatus = LEO_ERROR_4;
|
||||
__osLeoAbnormalResume();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void __osLeoAbnormalResume(void) {
|
||||
__OSTranxInfo* info = &__osDiskHandle->transferInfo;
|
||||
u32 pi_stat;
|
||||
|
||||
WAIT_ON_IOBUSY(pi_stat);
|
||||
IO_WRITE(LEO_BM_CTL, info->bmCtlShadow | LEO_BM_CTL_RESET);
|
||||
WAIT_ON_IOBUSY(pi_stat);
|
||||
IO_WRITE(LEO_BM_CTL, info->bmCtlShadow);
|
||||
__osLeoResume();
|
||||
IO_WRITE(PI_STATUS_REG, PI_STATUS_CLR_INTR);
|
||||
__OSGlobalIntMask |= OS_IM_PI;
|
||||
}
|
||||
|
||||
static void __osLeoResume(void) {
|
||||
__OSEventState* es = &__osEventStateTab[OS_EVENT_PI];
|
||||
OSMesgQueue* mq = es->messageQueue;
|
||||
s32 last;
|
||||
|
||||
if (mq == NULL || MQ_IS_FULL(mq)) {
|
||||
return;
|
||||
}
|
||||
|
||||
last = (mq->first + mq->validCount) % mq->msgCount;
|
||||
mq->msg[last] = es->message;
|
||||
mq->validCount++;
|
||||
|
||||
if (mq->mtqueue->next != NULL) {
|
||||
__osEnqueueThread(&__osRunQueue, __osPopThread(&mq->mtqueue));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "global.h"
|
||||
#include "siint.h"
|
||||
|
||||
extern OSPifRam _MotorStopData[MAXCONTROLLERS];
|
||||
extern OSPifRam _MotorStartData[MAXCONTROLLERS];
|
||||
extern u8 _motorstopbuf[0x20];
|
||||
extern u8 _motorstartbuf[0x20];
|
||||
OSPifRam _MotorStopData[MAXCONTROLLERS] ALIGNED(8);
|
||||
OSPifRam _MotorStartData[MAXCONTROLLERS] ALIGNED(8);
|
||||
u8 _motorstopbuf[32] ALIGNED(8);
|
||||
u8 _motorstartbuf[32] ALIGNED(8);
|
||||
|
||||
s32 osMotorStop(OSPfs* pfs) {
|
||||
s32 i;
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pfsgetstatus/__osPfsGetStatus.s")
|
||||
s32 __osPfsGetStatus(OSMesgQueue* queue, int channel) {
|
||||
s32 ret = 0;
|
||||
OSMesg dummy;
|
||||
u8 pattern;
|
||||
OSContStatus status[4];
|
||||
|
||||
__osPfsRequestData(0);
|
||||
ret = __osSiRawStartDma(1, &__osPfsPifRam);
|
||||
osRecvMesg(queue, &dummy, 1);
|
||||
ret = __osSiRawStartDma(0, &__osPfsPifRam);
|
||||
osRecvMesg(queue, &dummy, 1);
|
||||
__osPfsGetInitData(&pattern, status);
|
||||
|
||||
if (status[channel].status & CONT_CARD_ON && status[channel].status & CONT_CARD_PULL) {
|
||||
return 2;
|
||||
}
|
||||
if (status[channel].errno || !(status[channel].status & CONT_CARD_ON)) {
|
||||
return 1;
|
||||
}
|
||||
if (status[channel].status & CONT_ADDR_CRC_ER) {
|
||||
return 4;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
+102
-4
@@ -1,7 +1,105 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/controller.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pfsisplug/osPfsIsPlug.s")
|
||||
OSPifRam __osPfsPifRam ALIGNED(16);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pfsisplug/__osPfsRequestData.s")
|
||||
s32 osPfsIsPlug(OSMesgQueue* mq, u8* pattern) {
|
||||
s32 ret = 0;
|
||||
OSMesg msg;
|
||||
u8 bitpattern;
|
||||
OSContStatus contData[MAXCONTROLLERS];
|
||||
s32 channel;
|
||||
u8 bits = 0;
|
||||
s32 crcErrorCount = 3;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pfsisplug/__osPfsGetInitData.s")
|
||||
__osSiGetAccess();
|
||||
|
||||
do {
|
||||
__osPfsRequestData(CONT_CMD_REQUEST_STATUS);
|
||||
|
||||
ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam);
|
||||
osRecvMesg(mq, &msg, OS_MESG_BLOCK);
|
||||
|
||||
__osPfsGetInitData(&bitpattern, &contData[0]);
|
||||
|
||||
for (channel = 0; channel < __osMaxControllers; channel++) {
|
||||
if ((contData[channel].status & CONT_ADDR_CRC_ER) == 0) {
|
||||
crcErrorCount--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (channel == __osMaxControllers) {
|
||||
crcErrorCount = 0;
|
||||
}
|
||||
} while (crcErrorCount > 0);
|
||||
|
||||
for (channel = 0; channel < __osMaxControllers; channel++) {
|
||||
if ((contData[channel].errno == 0) && ((contData[channel].status & CONT_CARD_ON) != 0)) {
|
||||
bits |= (1 << channel);
|
||||
}
|
||||
}
|
||||
__osSiRelAccess();
|
||||
*pattern = bits;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __osPfsRequestData(u8 cmd) {
|
||||
u8* ptr;
|
||||
__OSContRequesFormat requestformat;
|
||||
int i;
|
||||
|
||||
__osContLastCmd = cmd;
|
||||
|
||||
#if BUILD_VERSION < VERSION_I
|
||||
for (i = 0; i < 16; i++) {
|
||||
__osPfsPifRam.ramarray[i] = 0;
|
||||
}
|
||||
__osPfsPifRam.pifstatus = CONT_CMD_EXE;
|
||||
#endif
|
||||
|
||||
ptr = (u8*) &__osPfsPifRam;
|
||||
requestformat.dummy = CONT_CMD_NOP;
|
||||
requestformat.txsize = CONT_CMD_REQUEST_STATUS_TX;
|
||||
requestformat.rxsize = CONT_CMD_REQUEST_STATUS_RX;
|
||||
requestformat.cmd = cmd;
|
||||
requestformat.typeh = CONT_CMD_NOP;
|
||||
requestformat.typel = CONT_CMD_NOP;
|
||||
requestformat.status = CONT_CMD_NOP;
|
||||
requestformat.dummy1 = CONT_CMD_NOP;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++) {
|
||||
*((__OSContRequesFormat*) ptr) = requestformat;
|
||||
ptr += sizeof(__OSContRequesFormat);
|
||||
}
|
||||
|
||||
*ptr = CONT_CMD_END;
|
||||
}
|
||||
|
||||
void __osPfsGetInitData(u8* pattern, OSContStatus* data) {
|
||||
u8* ptr;
|
||||
__OSContRequesFormat requestformat;
|
||||
int i;
|
||||
u8 bits = 0;
|
||||
|
||||
ptr = (u8*) &__osPfsPifRam;
|
||||
|
||||
for (i = 0; i < __osMaxControllers; i++, ptr += sizeof(requestformat), data++) {
|
||||
requestformat = *((__OSContRequesFormat*) ptr);
|
||||
data->errno = CHNL_ERR(requestformat);
|
||||
|
||||
if (data->errno != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
data->type = ((requestformat.typel << 8) | requestformat.typeh);
|
||||
data->status = requestformat.status;
|
||||
bits |= (1 << i);
|
||||
}
|
||||
*pattern = bits;
|
||||
}
|
||||
|
||||
+22
-4
@@ -1,7 +1,25 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/piacs/__osPiCreateAccessQueue.s")
|
||||
#define PI_Q_BUF_LEN 1
|
||||
u32 __osPiAccessQueueEnabled = 0;
|
||||
OSMesg piAccessBuf[PI_Q_BUF_LEN];
|
||||
OSMesgQueue __osPiAccessQueue ALIGNED(8);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/piacs/__osPiGetAccess.s")
|
||||
void __osPiCreateAccessQueue(void) {
|
||||
__osPiAccessQueueEnabled = 1;
|
||||
osCreateMesgQueue(&__osPiAccessQueue, piAccessBuf, PI_Q_BUF_LEN);
|
||||
osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/piacs/__osPiRelAccess.s")
|
||||
void __osPiGetAccess(void) {
|
||||
OSMesg dummyMesg;
|
||||
if (!__osPiAccessQueueEnabled) {
|
||||
__osPiCreateAccessQueue();
|
||||
}
|
||||
osRecvMesg(&__osPiAccessQueue, &dummyMesg, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
void __osPiRelAccess(void) {
|
||||
osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "piint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pigetcmdq/osPiGetCmdQueue.s")
|
||||
OSMesgQueue* osPiGetCmdQueue(void) {
|
||||
if (!__osPiDevMgr.active) {
|
||||
return NULL;
|
||||
} else {
|
||||
return __osPiDevMgr.cmdQueue;
|
||||
}
|
||||
}
|
||||
|
||||
+25
-11
@@ -2,16 +2,33 @@
|
||||
#include "piint.h"
|
||||
#include "PR/rdb.h"
|
||||
|
||||
void ramromMain(void* arg);
|
||||
extern OSMesg piEventBuf[];
|
||||
extern OSMesgQueue piEventQueue;
|
||||
extern OSThread piThread;
|
||||
extern char piThreadStack[];
|
||||
extern OSThread ramromThread;
|
||||
extern char ramromThreadStack[];
|
||||
OSThread piThread ALIGNED(8);
|
||||
char piThreadStack[OS_PIM_STACKSIZE] ALIGNED(16);
|
||||
|
||||
#ifndef _FINALROM
|
||||
static OSThread ramromThread ALIGNED(8);
|
||||
static char ramromThreadStack[1024] ALIGNED(16);
|
||||
static OSMesgQueue getRamromQ ALIGNED(8);
|
||||
static OSMesg getRamromBuf[1];
|
||||
static OSMesgQueue freeRamromQ ALIGNED(8);
|
||||
static OSMesg freeRamromBuf[1];
|
||||
static void ramromMain(void*);
|
||||
#endif
|
||||
|
||||
OSMesgQueue piEventQueue ALIGNED(8);
|
||||
OSMesg piEventBuf[1];
|
||||
|
||||
#ifdef IMPORT_DATA_PENDING
|
||||
OSDevMgr __osPiDevMgr = { 0 };
|
||||
OSPiHandle* __osPiTable = NULL;
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
OSPiHandle __Dom1SpeedParam ALIGNED(8);
|
||||
OSPiHandle __Dom2SpeedParam ALIGNED(8);
|
||||
OSPiHandle* __osCurrentHandle[2] ALIGNED(8) = { &__Dom1SpeedParam, &__Dom2SpeedParam };
|
||||
#else
|
||||
extern OSPiHandle CartRomHandle;
|
||||
extern OSPiHandle LeoDiskHandle;
|
||||
OSPiHandle* __osCurrentHandle[2] ALIGNED(8) = { &CartRomHandle, &LeoDiskHandle };
|
||||
#endif
|
||||
|
||||
void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQ, OSMesg* cmdBuf, s32 cmdMsgCnt) {
|
||||
u32 savedMask;
|
||||
@@ -56,9 +73,6 @@ void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQ, OSMesg* cmdBuf, s32 cmdMsgC
|
||||
osSetThreadPri(NULL, oldPri);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pimgr/osCreatePiManager.s")
|
||||
#endif
|
||||
|
||||
extern OSMesg freeRamromBuf[];
|
||||
extern OSMesgQueue freeRamromQ;
|
||||
|
||||
@@ -1,3 +1,53 @@
|
||||
#include "common.h"
|
||||
#include "piint.h"
|
||||
#include "PR/ultraerror.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pirawdma/osPiRawStartDma.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osPiRawStartDma(s32 direction, u32 devAddr, void* dramAddr, u32 size) {
|
||||
register u32 stat;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((direction != OS_READ) && (direction != OS_WRITE)) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_DIR, 1, direction);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (devAddr & 0x1) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_DEVADDR, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((u32) dramAddr & 0x7) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_ADDR, 1, dramAddr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (size & 0x1) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_SIZE, 1, size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size == 0) || (size > (16 * 1024 * 1024))) {
|
||||
__osError(ERR_OSPIRAWSTARTDMA_RANGE, 1, size);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
|
||||
IO_WRITE(PI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
|
||||
IO_WRITE(PI_CART_ADDR_REG, K1_TO_PHYS((u32) osRomBase | devAddr));
|
||||
|
||||
switch (direction) {
|
||||
case OS_READ:
|
||||
IO_WRITE(PI_WR_LEN_REG, size - 1);
|
||||
break;
|
||||
case OS_WRITE:
|
||||
IO_WRITE(PI_RD_LEN_REG, size - 1);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,29 @@
|
||||
#include "global.h"
|
||||
#include "PR/assert.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "piint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/pirawread/osPiRawReadIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 46
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osPiRawReadIo(u32 devAddr, u32* data) {
|
||||
register u32 stat;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (devAddr & 0x3) {
|
||||
__osError(ERR_OSPIRAWREADIO, 1, devAddr);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(data != NULL);
|
||||
|
||||
WAIT_ON_IOBUSY(stat);
|
||||
*data = IO_READ((u32) osRomBase | devAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+14
-2
@@ -1,3 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/si/__osSiDeviceBusy.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
int __osSiDeviceBusy() {
|
||||
register u32 stat = IO_READ(SI_STATUS_REG);
|
||||
|
||||
if (stat & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
+22
-4
@@ -1,7 +1,25 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/siacs/__osSiCreateAccessQueue.s")
|
||||
#define SI_Q_BUF_LEN 1
|
||||
OSMesg siAccessBuf[SI_Q_BUF_LEN] ALIGNED(8);
|
||||
OSMesgQueue __osSiAccessQueue ALIGNED(8);
|
||||
u32 __osSiAccessQueueEnabled = 0;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/siacs/__osSiGetAccess.s")
|
||||
void __osSiCreateAccessQueue(void) {
|
||||
__osSiAccessQueueEnabled = 1;
|
||||
osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, SI_Q_BUF_LEN);
|
||||
osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/siacs/__osSiRelAccess.s")
|
||||
void __osSiGetAccess(void) {
|
||||
OSMesg dummyMesg;
|
||||
if (!__osSiAccessQueueEnabled) {
|
||||
__osSiCreateAccessQueue();
|
||||
}
|
||||
osRecvMesg(&__osSiAccessQueue, &dummyMesg, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
void __osSiRelAccess(void) {
|
||||
osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/assert.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sirawdma/__osSiRawStartDma.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 49
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSiRawStartDma(s32 direction, void* dramAddr) {
|
||||
assert(((u32) dramAddr & 0x3) == 0);
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
if (IO_READ(SI_STATUS_REG) & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) {
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (__osSiDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (direction == OS_WRITE) {
|
||||
osWritebackDCache(dramAddr, 64);
|
||||
}
|
||||
|
||||
IO_WRITE(SI_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
|
||||
|
||||
if (direction == OS_READ) {
|
||||
IO_WRITE(SI_PIF_ADDR_RD64B_REG, PIF_RAM_START);
|
||||
} else {
|
||||
IO_WRITE(SI_PIF_ADDR_WR64B_REG, PIF_RAM_START);
|
||||
}
|
||||
|
||||
if (direction == OS_READ) {
|
||||
osInvalDCache(dramAddr, 64);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/assert.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sirawread/__osSiRawReadIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 45
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSiRawReadIo(u32 devAddr, u32* data) {
|
||||
assert((devAddr & 0x3) == 0);
|
||||
assert(data != NULL);
|
||||
|
||||
if (__osSiDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data = IO_READ(devAddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,22 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/assert.h"
|
||||
#include "siint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sirawwrite/__osSiRawWriteIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 46
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSiRawWriteIo(u32 devAddr, u32 data) {
|
||||
assert((devAddr & 0x3) == 0);
|
||||
|
||||
if (__osSiDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
IO_WRITE(devAddr, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+16
-2
@@ -1,3 +1,17 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sp/__osSpDeviceBusy.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
int __osSpDeviceBusy() {
|
||||
register u32 stat = IO_READ(SP_STATUS_REG);
|
||||
|
||||
if (stat & (SP_STATUS_DMA_BUSY | SP_STATUS_DMA_FULL | SP_STATUS_IO_FULL)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/spgetstat/__osSpGetStatus.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
u32 __osSpGetStatus() {
|
||||
return IO_READ(SP_STATUS_REG);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/assert.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sprawdma/__osSpRawStartDma.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 52
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSpRawStartDma(s32 direction, u32 devAddr, void* dramAddr, u32 size) {
|
||||
assert(((u32) devAddr & 0x7) == 0);
|
||||
assert(((u32) dramAddr & 0x7) == 0);
|
||||
assert(((u32) size & 0x7) == 0);
|
||||
|
||||
if (__osSpDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
IO_WRITE(SP_MEM_ADDR_REG, devAddr);
|
||||
IO_WRITE(SP_DRAM_ADDR_REG, osVirtualToPhysical(dramAddr));
|
||||
|
||||
if (direction == OS_READ) {
|
||||
IO_WRITE(SP_WR_LEN_REG, size - 1);
|
||||
} else {
|
||||
IO_WRITE(SP_RD_LEN_REG, size - 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/assert.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sprawread/__osSpRawReadIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 45
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSpRawReadIo(u32 devAddr, u32* data) {
|
||||
assert((devAddr & 0x3) == 0);
|
||||
assert(data != NULL);
|
||||
|
||||
if (__osSpDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data = IO_READ(devAddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/assert.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sprawwrite/__osSpRawWriteIo.s")
|
||||
// Adjust line numbers to match assert
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#line 45
|
||||
#endif
|
||||
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSpRawWriteIo(u32 devAddr, u32 data) {
|
||||
assert((devAddr & 0x3) == 0);
|
||||
|
||||
if (__osSpDeviceBusy()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
IO_WRITE(devAddr, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
#include "common.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/spsetpc/__osSpSetPc.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
s32 __osSpSetPc(u32 pc) {
|
||||
register u32 status = IO_READ(SP_STATUS_REG);
|
||||
|
||||
if (!(status & SP_STATUS_HALT)) {
|
||||
return -1;
|
||||
}
|
||||
IO_WRITE(SP_PC_REG, pc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/spsetstat/__osSpSetStatus.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void __osSpSetStatus(u32 data) {
|
||||
IO_WRITE(SP_STATUS_REG, data);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,82 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sptask/_VirtualToPhysicalTask.s")
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sptask/osSpTaskLoad.s")
|
||||
#define _osVirtualToPhysical(ptr) \
|
||||
if (ptr != NULL) { \
|
||||
ptr = (void*) osVirtualToPhysical(ptr); \
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sptask/osSpTaskStartGo.s")
|
||||
static OSTask tmp_task;
|
||||
|
||||
static OSTask* _VirtualToPhysicalTask(OSTask* intp) {
|
||||
OSTask* tp;
|
||||
tp = &tmp_task;
|
||||
bcopy(intp, tp, sizeof(OSTask));
|
||||
|
||||
_osVirtualToPhysical(tp->t.ucode);
|
||||
_osVirtualToPhysical(tp->t.ucode_data);
|
||||
_osVirtualToPhysical(tp->t.dram_stack);
|
||||
_osVirtualToPhysical(tp->t.output_buff);
|
||||
_osVirtualToPhysical(tp->t.output_buff_size);
|
||||
_osVirtualToPhysical(tp->t.data_ptr);
|
||||
_osVirtualToPhysical(tp->t.yield_data_ptr);
|
||||
return tp;
|
||||
}
|
||||
|
||||
void osSpTaskLoad(OSTask* intp) {
|
||||
OSTask* tp;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((intp->t.dram_stack != 0x0) && ((u32) intp->t.dram_stack & 0xf)) {
|
||||
__osError(ERR_OSSPTASKLOAD_DRAM, 1, intp->t.dram_stack);
|
||||
return;
|
||||
}
|
||||
if ((intp->t.output_buff != 0x0) && ((u32) intp->t.output_buff & 0xf)) {
|
||||
__osError(ERR_OSSPTASKLOAD_OUT, 1, intp->t.output_buff);
|
||||
return;
|
||||
}
|
||||
if ((intp->t.output_buff_size != 0x0) && ((u32) intp->t.output_buff_size & 0xf)) {
|
||||
__osError(ERR_OSSPTASKLOAD_OUTSIZE, 1, intp->t.output_buff_size);
|
||||
return;
|
||||
}
|
||||
if ((intp->t.yield_data_ptr != 0x0) && ((u32) intp->t.yield_data_ptr & 0xf)) {
|
||||
__osError(ERR_OSSPTASKLOAD_YIELD, 1, intp->t.yield_data_ptr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
tp = _VirtualToPhysicalTask(intp);
|
||||
|
||||
if (tp->t.flags & OS_TASK_YIELDED) {
|
||||
tp->t.ucode_data = tp->t.yield_data_ptr;
|
||||
tp->t.ucode_data_size = tp->t.yield_data_size;
|
||||
intp->t.flags &= ~OS_TASK_YIELDED;
|
||||
if (tp->t.flags & OS_TASK_LOADABLE) {
|
||||
tp->t.ucode = (u64*) IO_READ((u32) intp->t.yield_data_ptr + OS_YIELD_DATA_SIZE - 4);
|
||||
}
|
||||
}
|
||||
|
||||
osWritebackDCache(tp, sizeof(OSTask));
|
||||
__osSpSetStatus(SP_CLR_YIELD | SP_CLR_YIELDED | SP_CLR_TASKDONE | SP_SET_INTR_BREAK);
|
||||
|
||||
while (__osSpSetPc(SP_IMEM_START) == -1) {}
|
||||
|
||||
while (__osSpRawStartDma(1, (SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) {}
|
||||
|
||||
while (__osSpDeviceBusy()) {}
|
||||
|
||||
while (__osSpRawStartDma(1, SP_IMEM_START, tp->t.ucode_boot, tp->t.ucode_boot_size) == -1) {}
|
||||
}
|
||||
|
||||
void osSpTaskStartGo(OSTask* tp) {
|
||||
while (__osSpDeviceBusy()) {}
|
||||
|
||||
__osSpSetStatus(SP_SET_INTR_BREAK | SP_CLR_SSTEP | SP_CLR_BROKE | SP_CLR_HALT);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sptaskyield/osSpTaskYield.s")
|
||||
void osSpTaskYield(void) {
|
||||
__osSpSetStatus(SP_SET_YIELD);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "PR/rcp.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/sptaskyielded/osSpTaskYielded.s")
|
||||
OSYieldResult osSpTaskYielded(OSTask* tp) {
|
||||
u32 status;
|
||||
OSYieldResult result;
|
||||
|
||||
status = __osSpGetStatus();
|
||||
result = (status & SP_STATUS_YIELDED) ? OS_TASK_YIELDED : 0;
|
||||
|
||||
if (status & SP_STATUS_YIELD) {
|
||||
tp->t.flags |= result;
|
||||
tp->t.flags &= ~(OS_TASK_DP_WAIT);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+38
-2
@@ -1,3 +1,39 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/R4300.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/vi/__osViInit.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
static __OSViContext vi[2] ALIGNED(8) = { 0 };
|
||||
__OSViContext* __osViCurr = &vi[0];
|
||||
__OSViContext* __osViNext = &vi[1];
|
||||
|
||||
void __osViInit(void) {
|
||||
bzero(vi, sizeof(vi));
|
||||
__osViCurr = &vi[0];
|
||||
__osViNext = &vi[1];
|
||||
__osViNext->retraceCount = 1;
|
||||
__osViCurr->retraceCount = 1;
|
||||
__osViNext->framep = (void*) K0BASE;
|
||||
__osViCurr->framep = (void*) K0BASE;
|
||||
|
||||
if (osTvType == OS_TV_TYPE_PAL) {
|
||||
__osViNext->modep = &osViModePalLan1;
|
||||
} else if (osTvType == OS_TV_TYPE_MPAL) {
|
||||
__osViNext->modep = &osViModeMpalLan1;
|
||||
} else {
|
||||
__osViNext->modep = &osViModeNtscLan1;
|
||||
}
|
||||
|
||||
__osViNext->state = VI_STATE_BLACK;
|
||||
__osViNext->control = __osViNext->modep->comRegs.ctrl;
|
||||
|
||||
while (IO_READ(VI_CURRENT_REG) > 10) { // wait for vsync?
|
||||
}
|
||||
|
||||
IO_WRITE(VI_CONTROL_REG, 0); // pixel size blank (no data, no sync)
|
||||
__osViSwapContext();
|
||||
}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/viblack/osViBlack.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osViBlack(u8 active) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
if (active) {
|
||||
__osViNext->state |= VI_STATE_BLACK;
|
||||
} else {
|
||||
__osViNext->state &= ~VI_STATE_BLACK;
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/vigetcurrcontext/__osViGetCurrentContext.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
__OSViContext* __osViGetCurrentContext(void) {
|
||||
return __osViCurr;
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,5 +1,126 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/vimgr/osCreateViManager.s")
|
||||
OSDevMgr __osViDevMgr = { 0 };
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
u32 __additional_scanline = 0;
|
||||
#endif
|
||||
static OSThread viThread;
|
||||
static unsigned char viThreadStack[OS_VIM_STACKSIZE] ALIGNED(16);
|
||||
static OSMesgQueue viEventQueue ALIGNED(8);
|
||||
static OSMesg viEventBuf[5] ALIGNED(8);
|
||||
static OSIoMesg viRetraceMsg ALIGNED(8);
|
||||
static OSIoMesg viCounterMsg ALIGNED(8);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/vimgr/viMgrMain.s")
|
||||
static void viMgrMain(void* arg);
|
||||
void osCreateViManager(OSPri pri) {
|
||||
u32 savedMask;
|
||||
OSPri oldPri;
|
||||
OSPri myPri;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((pri < OS_PRIORITY_IDLE) || (pri > OS_PRIORITY_MAX)) {
|
||||
__osError(ERR_OSCREATEVIMANAGER, 1, pri);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (__osViDevMgr.active) {
|
||||
return;
|
||||
}
|
||||
__osTimerServicesInit();
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
__additional_scanline = 0;
|
||||
#endif
|
||||
osCreateMesgQueue(&viEventQueue, viEventBuf, ARRLEN(viEventBuf));
|
||||
viRetraceMsg.hdr.type = OS_MESG_TYPE_VRETRACE;
|
||||
viRetraceMsg.hdr.pri = OS_MESG_PRI_NORMAL;
|
||||
viRetraceMsg.hdr.retQueue = NULL;
|
||||
viCounterMsg.hdr.type = OS_MESG_TYPE_COUNTER;
|
||||
viCounterMsg.hdr.pri = OS_MESG_PRI_NORMAL;
|
||||
viCounterMsg.hdr.retQueue = NULL;
|
||||
osSetEventMesg(OS_EVENT_VI, &viEventQueue, &viRetraceMsg);
|
||||
osSetEventMesg(OS_EVENT_COUNTER, &viEventQueue, &viCounterMsg);
|
||||
oldPri = -1;
|
||||
myPri = osGetThreadPri(NULL);
|
||||
|
||||
if (myPri < pri) {
|
||||
oldPri = myPri;
|
||||
osSetThreadPri(NULL, pri);
|
||||
}
|
||||
|
||||
savedMask = __osDisableInt();
|
||||
__osViDevMgr.active = TRUE;
|
||||
__osViDevMgr.thread = &viThread;
|
||||
__osViDevMgr.cmdQueue = &viEventQueue;
|
||||
__osViDevMgr.evtQueue = &viEventQueue;
|
||||
__osViDevMgr.acsQueue = NULL;
|
||||
__osViDevMgr.dma = NULL;
|
||||
__osViDevMgr.edma = NULL;
|
||||
osCreateThread(&viThread, 0, viMgrMain, &__osViDevMgr, &viThreadStack[OS_VIM_STACKSIZE], pri);
|
||||
__osViInit();
|
||||
osStartThread(&viThread);
|
||||
__osRestoreInt(savedMask);
|
||||
|
||||
if (oldPri != -1) {
|
||||
osSetThreadPri(NULL, oldPri);
|
||||
}
|
||||
}
|
||||
|
||||
static void viMgrMain(void* arg) {
|
||||
__OSViContext* vc;
|
||||
OSDevMgr* dm;
|
||||
OSIoMesg* mb;
|
||||
static u16 retrace;
|
||||
s32 first;
|
||||
u32 count;
|
||||
|
||||
mb = NULL;
|
||||
first = 0;
|
||||
vc = __osViGetCurrentContext();
|
||||
retrace = vc->retraceCount;
|
||||
if (retrace == 0) {
|
||||
retrace = 1;
|
||||
}
|
||||
dm = (OSDevMgr*) arg;
|
||||
|
||||
while (TRUE) {
|
||||
osRecvMesg(dm->evtQueue, (OSMesg) &mb, OS_MESG_BLOCK);
|
||||
switch (mb->hdr.type) {
|
||||
case OS_MESG_TYPE_VRETRACE:
|
||||
__osViSwapContext();
|
||||
retrace--;
|
||||
|
||||
if (retrace == 0) {
|
||||
vc = __osViGetCurrentContext();
|
||||
if (vc->msgq != NULL) {
|
||||
osSendMesg(vc->msgq, vc->msg, OS_MESG_NOBLOCK);
|
||||
}
|
||||
retrace = vc->retraceCount;
|
||||
}
|
||||
|
||||
__osViIntrCount++;
|
||||
|
||||
if (first) {
|
||||
count = osGetCount();
|
||||
__osCurrentTime = count;
|
||||
first = 0;
|
||||
}
|
||||
|
||||
count = __osBaseCounter;
|
||||
__osBaseCounter = osGetCount();
|
||||
count = __osBaseCounter - count;
|
||||
__osCurrentTime = __osCurrentTime + count;
|
||||
break;
|
||||
case OS_MESG_TYPE_COUNTER:
|
||||
__osTimerInterrupt();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,17 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/virepeatline/osViRepeatLine.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osViRepeatLine(u8 active) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
if (active) {
|
||||
__osViNext->state |= VI_STATE_REPEATLINE;
|
||||
} else {
|
||||
__osViNext->state &= ~VI_STATE_REPEATLINE;
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/assert.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/visetevent/osViSetEvent.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osViSetEvent(OSMesgQueue* mq, OSMesg m, u32 retraceCount) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSVISETEVENT, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(mq != NULL);
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
__osViNext->msgq = mq;
|
||||
__osViNext->msg = m;
|
||||
__osViNext->retraceCount = retraceCount;
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/assert.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/visetmode/osViSetMode.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osViSetMode(OSViMode* modep) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSVISETMODE, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(modep != NULL);
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
__osViNext->modep = modep;
|
||||
__osViNext->state = VI_STATE_MODE_UPDATED;
|
||||
__osViNext->control = __osViNext->modep->comRegs.ctrl;
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,72 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/visetspecial/osViSetSpecialFeatures.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
// This value was incorrectly calculated until being fixed in 2.0J
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#define OS_VI_SPECIAL_MAX \
|
||||
(OS_VI_GAMMA_ON | OS_VI_GAMMA_OFF | OS_VI_GAMMA_DITHER_ON | OS_VI_GAMMA_DITHER_OFF | OS_VI_DIVOT_ON | \
|
||||
OS_VI_DIVOT_OFF | OS_VI_DITHER_FILTER_ON | OS_VI_DITHER_FILTER_OFF)
|
||||
#else
|
||||
#define OS_VI_SPECIAL_MAX OS_VI_DITHER_FILTER_OFF
|
||||
#endif
|
||||
|
||||
void osViSetSpecialFeatures(u32 func) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSVISETSPECIAL_VIMGR, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((func < OS_VI_GAMMA_ON) || (func > OS_VI_SPECIAL_MAX)) {
|
||||
__osError(ERR_OSVISETSPECIAL_VALUE, 1, func);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
if ((func & OS_VI_GAMMA_ON) != 0) {
|
||||
__osViNext->control |= VI_CTRL_GAMMA_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_GAMMA_OFF) != 0) {
|
||||
__osViNext->control &= ~VI_CTRL_GAMMA_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_GAMMA_DITHER_ON) != 0) {
|
||||
__osViNext->control |= VI_CTRL_GAMMA_DITHER_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_GAMMA_DITHER_OFF) != 0) {
|
||||
__osViNext->control &= ~VI_CTRL_GAMMA_DITHER_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_DIVOT_ON) != 0) {
|
||||
__osViNext->control |= VI_CTRL_DIVOT_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_DIVOT_OFF) != 0) {
|
||||
__osViNext->control &= ~VI_CTRL_DIVOT_ON;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_DITHER_FILTER_ON) != 0) {
|
||||
__osViNext->control |= VI_CTRL_DITHER_FILTER_ON;
|
||||
__osViNext->control &= ~VI_CTRL_ANTIALIAS_MASK;
|
||||
}
|
||||
|
||||
if ((func & OS_VI_DITHER_FILTER_OFF) != 0) {
|
||||
__osViNext->control &= ~VI_CTRL_DITHER_FILTER_ON;
|
||||
__osViNext->control |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK;
|
||||
}
|
||||
|
||||
__osViNext->state |= VI_STATE_CTRL_UPDATED;
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/assert.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/viswapbuf/osViSwapBuffer.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void osViSwapBuffer(void* frameBufPtr) {
|
||||
u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSVISWAPBUFFER_VIMGR, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(frameBufPtr != NULL);
|
||||
|
||||
if ((u32) frameBufPtr & 0x3f) {
|
||||
__osError(ERR_OSVISWAPBUFFER_ADDR, 1, frameBufPtr);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
__osViNext->framep = frameBufPtr;
|
||||
__osViNext->state |= VI_STATE_BUFFER_UPDATED;
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,80 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/io/viswapcontext/__osViSwapContext.s")
|
||||
// TODO: this comes from a header
|
||||
#ident "$Revision: 1.17 $"
|
||||
|
||||
void __osViSwapContext() {
|
||||
register OSViMode* vm;
|
||||
register __OSViContext* vc;
|
||||
u32 origin;
|
||||
u32 hStart;
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
u32 vStart;
|
||||
#endif
|
||||
u32 nomValue;
|
||||
u32 field;
|
||||
|
||||
field = 0;
|
||||
vc = __osViNext;
|
||||
vm = vc->modep;
|
||||
|
||||
field = IO_READ(VI_CURRENT_REG) & 1; // field num
|
||||
|
||||
origin = osVirtualToPhysical(vc->framep) + (vm->fldRegs[field].origin);
|
||||
if (vc->state & VI_STATE_XSCALE_UPDATED) {
|
||||
vc->x.scale |= (vm->comRegs.xScale & ~VI_SCALE_MASK);
|
||||
} else {
|
||||
vc->x.scale = vm->comRegs.xScale;
|
||||
}
|
||||
|
||||
if (vc->state & VI_STATE_YSCALE_UPDATED) {
|
||||
nomValue = vm->fldRegs[field].yScale & VI_SCALE_MASK;
|
||||
vc->y.scale = vc->y.factor * nomValue;
|
||||
vc->y.scale |= vm->fldRegs[field].yScale & ~VI_SCALE_MASK;
|
||||
} else {
|
||||
vc->y.scale = vm->fldRegs[field].yScale;
|
||||
}
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
vStart = (vm->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline;
|
||||
#endif
|
||||
hStart = vm->comRegs.hStart;
|
||||
|
||||
if (vc->state & VI_STATE_BLACK) {
|
||||
hStart = 0;
|
||||
}
|
||||
|
||||
if (vc->state & VI_STATE_REPEATLINE) {
|
||||
vc->y.scale = 0;
|
||||
origin = osVirtualToPhysical(vc->framep);
|
||||
}
|
||||
|
||||
if (vc->state & VI_STATE_FADE) {
|
||||
vc->y.scale = (vc->y.offset << VI_SUBPIXEL_SH) & (VI_2_10_FPART_MASK << VI_SUBPIXEL_SH);
|
||||
origin = osVirtualToPhysical(vc->framep);
|
||||
}
|
||||
|
||||
IO_WRITE(VI_ORIGIN_REG, origin);
|
||||
IO_WRITE(VI_WIDTH_REG, vm->comRegs.width);
|
||||
IO_WRITE(VI_BURST_REG, vm->comRegs.burst);
|
||||
IO_WRITE(VI_V_SYNC_REG, vm->comRegs.vSync);
|
||||
IO_WRITE(VI_H_SYNC_REG, vm->comRegs.hSync);
|
||||
IO_WRITE(VI_LEAP_REG, vm->comRegs.leap);
|
||||
IO_WRITE(VI_H_START_REG, hStart);
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
IO_WRITE(VI_V_START_REG, vStart);
|
||||
#else
|
||||
IO_WRITE(VI_V_START_REG, vm->fldRegs[field].vStart);
|
||||
#endif
|
||||
IO_WRITE(VI_V_BURST_REG, vm->fldRegs[field].vBurst);
|
||||
IO_WRITE(VI_INTR_REG, vm->fldRegs[field].vIntr);
|
||||
IO_WRITE(VI_X_SCALE_REG, vc->x.scale);
|
||||
IO_WRITE(VI_Y_SCALE_REG, vc->y.scale);
|
||||
IO_WRITE(VI_CONTROL_REG, vc->control);
|
||||
|
||||
__osViNext = __osViCurr;
|
||||
__osViCurr = vc;
|
||||
*__osViNext = *__osViCurr;
|
||||
}
|
||||
|
||||
+303
-5
@@ -1,9 +1,307 @@
|
||||
#include "common.h"
|
||||
#include "libc/stdlib.h"
|
||||
#include "libc/string.h"
|
||||
#include "PR/xstdio.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xldtob/_Genld.s")
|
||||
// TODO: these come from headers
|
||||
#ident "$Revision: 1.23 $"
|
||||
#ident "$Revision: 1.34 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xldtob/D_800C9580.s")
|
||||
#define BUFF_LEN 0x20
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xldtob/_Ldtob.s")
|
||||
static s16 _Ldunscale(s16* pex, _Pft* px);
|
||||
static void _Genld(_Pft* px, char code, u8* p, s16 nsig, s16 xexp);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xldtob/D_800C95D0.s")
|
||||
static const double pows[] = { 10e0L, 10e1L, 10e3L, 10e7L, 10e15L, 10e31L, 10e63L, 10e127L, 10e255L };
|
||||
|
||||
// float properties
|
||||
#define _D0 0
|
||||
#define _DBIAS 0x3ff
|
||||
#define _DLONG 1
|
||||
#define _DOFF 4
|
||||
#define _FBIAS 0x7e
|
||||
#define _FOFF 7
|
||||
#define _FRND 1
|
||||
#define _LBIAS 0x3ffe
|
||||
#define _LOFF 15
|
||||
// integer properties
|
||||
#define _C2 1
|
||||
#define _CSIGN 1
|
||||
#define _ILONG 0
|
||||
#define _MBMAX 8
|
||||
#define NAN 2
|
||||
#define INF 1
|
||||
#define FINITE -1
|
||||
#define _DFRAC ((1 << _DOFF) - 1)
|
||||
#define _DMASK (0x7fff & ~_DFRAC)
|
||||
#define _DMAX ((1 << (15 - _DOFF)) - 1)
|
||||
#define _DNAN (0x8000 | _DMAX << _DOFF | 1 << (_DOFF - 1))
|
||||
#define _DSIGN 0x8000
|
||||
#define _D1 1 // big-endian order
|
||||
#define _D2 2
|
||||
#define _D3 3
|
||||
|
||||
#define ALIGN(s, align) (((u32) (s) + ((align) -1)) & ~((align) -1))
|
||||
|
||||
void _Ldtob(_Pft* px, char code) {
|
||||
char buff[BUFF_LEN];
|
||||
char* p;
|
||||
f64 ldval;
|
||||
s16 err;
|
||||
s16 nsig;
|
||||
s16 xexp;
|
||||
|
||||
// char unused[0x4];
|
||||
p = buff;
|
||||
ldval = px->v.ld;
|
||||
|
||||
if (px->prec < 0) {
|
||||
px->prec = 6;
|
||||
} else if (px->prec == 0 && (code == 'g' || code == 'G')) {
|
||||
px->prec = 1;
|
||||
}
|
||||
|
||||
err = _Ldunscale(&xexp, px);
|
||||
if (err > 0) {
|
||||
memcpy(px->s, err == 2 ? "NaN" : "Inf", px->n1 = 3);
|
||||
return;
|
||||
} else if (err == 0) {
|
||||
nsig = 0;
|
||||
xexp = 0;
|
||||
} else {
|
||||
{
|
||||
int i;
|
||||
int n;
|
||||
|
||||
if (ldval < 0) {
|
||||
ldval = -ldval;
|
||||
}
|
||||
|
||||
// what
|
||||
if ((xexp = xexp * 30103 / 100000 - 4) < 0) {
|
||||
n = ALIGN(-xexp, 4), xexp = -n;
|
||||
|
||||
for (i = 0; n > 0; n >>= 1, i++) {
|
||||
if (n & 1) {
|
||||
ldval *= pows[i];
|
||||
}
|
||||
}
|
||||
} else if (xexp > 0) {
|
||||
f64 factor = 1;
|
||||
|
||||
xexp &= ~3;
|
||||
|
||||
for (n = xexp, i = 0; n > 0; n >>= 1, i++) {
|
||||
if (n & 1) {
|
||||
factor *= pows[i];
|
||||
}
|
||||
}
|
||||
|
||||
ldval /= factor;
|
||||
}
|
||||
}
|
||||
{
|
||||
int gen = px->prec + ((code == 'f') ? 10 + xexp : 6);
|
||||
|
||||
if (gen > 0x13) {
|
||||
gen = 0x13;
|
||||
}
|
||||
|
||||
for (*p++ = '0'; gen > 0 && 0 < ldval; p += 8) {
|
||||
int j;
|
||||
long lo = ldval;
|
||||
|
||||
if ((gen -= 8) > 0) {
|
||||
ldval = (ldval - lo) * 1e8;
|
||||
}
|
||||
|
||||
for (p += 8, j = 8; lo > 0 && --j >= 0;) {
|
||||
ldiv_t qr;
|
||||
qr = ldiv(lo, 10);
|
||||
*--p = qr.rem + '0', lo = qr.quot;
|
||||
}
|
||||
|
||||
while (--j >= 0) {
|
||||
*--p = '0';
|
||||
}
|
||||
}
|
||||
|
||||
gen = p - &buff[1];
|
||||
|
||||
for (p = &buff[1], xexp += 7; *p == '0'; p++) {
|
||||
--gen, --xexp;
|
||||
}
|
||||
|
||||
nsig = px->prec + ((code == 'f') ? xexp + 1 : ((code == 'e' || code == 'E') ? 1 : 0));
|
||||
|
||||
if (gen < nsig) {
|
||||
nsig = gen;
|
||||
}
|
||||
|
||||
if (nsig > 0) {
|
||||
const char drop = nsig < gen && '5' <= p[nsig] ? '9' : '0';
|
||||
int n;
|
||||
|
||||
for (n = nsig; p[--n] == drop;) {
|
||||
--nsig;
|
||||
}
|
||||
|
||||
if (drop == '9') {
|
||||
++p[n];
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
--p, ++nsig, ++xexp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_Genld(px, code, p, nsig, xexp);
|
||||
}
|
||||
|
||||
s16 _Ldunscale(s16* pex, _Pft* px) {
|
||||
u16* ps = (u16*) px;
|
||||
s16 xchar = (ps[_D0] & _DMASK) >> _DOFF;
|
||||
|
||||
if (xchar == _DMAX) {
|
||||
*pex = 0;
|
||||
|
||||
return (ps[_D0] & _DFRAC) || ps[_D1] || ps[_D2] || ps[_D3] ? 2 : 1;
|
||||
} else if (xchar > 0) {
|
||||
ps[_D0] = (ps[_D0] & ~_DMASK) | 0x3FF0;
|
||||
*pex = xchar - 0x3FE;
|
||||
return -1;
|
||||
} else if (xchar < 0) {
|
||||
return 2;
|
||||
} else {
|
||||
*pex = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void _Genld(_Pft* px, char code, u8* p, s16 nsig, s16 xexp) {
|
||||
const unsigned char point = '.';
|
||||
|
||||
if (nsig <= 0) {
|
||||
nsig = 1, p = "0";
|
||||
}
|
||||
|
||||
if (code == 'f' || (code == 'g' || code == 'G') && xexp >= -4 && xexp < px->prec) {
|
||||
xexp++;
|
||||
if (code != 'f') {
|
||||
if (((px->flags & 8) == 0) && nsig < px->prec) {
|
||||
px->prec = nsig;
|
||||
}
|
||||
|
||||
if ((px->prec -= xexp) < 0) {
|
||||
px->prec = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (xexp <= 0) {
|
||||
px->s[px->n1++] = '0';
|
||||
|
||||
if (px->prec > 0 || (px->flags & 8)) {
|
||||
px->s[px->n1++] = point;
|
||||
}
|
||||
|
||||
if (px->prec < -xexp) {
|
||||
xexp = -px->prec;
|
||||
}
|
||||
|
||||
px->nz1 = -xexp;
|
||||
px->prec += xexp;
|
||||
|
||||
if (px->prec < nsig) {
|
||||
nsig = px->prec;
|
||||
}
|
||||
|
||||
memcpy(&px->s[px->n1], p, px->n2 = nsig);
|
||||
px->nz2 = px->prec - nsig;
|
||||
} else if (nsig < xexp) {
|
||||
memcpy(&px->s[px->n1], p, nsig);
|
||||
px->n1 += nsig;
|
||||
px->nz1 = xexp - nsig;
|
||||
if (px->prec > 0 || (px->flags & 8)) {
|
||||
px->s[px->n1] = point;
|
||||
px->n2++;
|
||||
}
|
||||
|
||||
px->nz2 = px->prec;
|
||||
} else {
|
||||
memcpy(&px->s[px->n1], p, xexp);
|
||||
px->n1 += xexp;
|
||||
nsig -= xexp;
|
||||
|
||||
if (px->prec > 0 || (px->flags & 8)) {
|
||||
px->s[px->n1++] = point;
|
||||
}
|
||||
|
||||
if (px->prec < nsig) {
|
||||
nsig = px->prec;
|
||||
}
|
||||
|
||||
memcpy(&px->s[px->n1], &p[xexp], nsig);
|
||||
px->n1 += nsig;
|
||||
px->nz1 = px->prec - nsig;
|
||||
}
|
||||
} else {
|
||||
if (code == 'g' || code == 'G') {
|
||||
if (nsig < px->prec) {
|
||||
px->prec = nsig;
|
||||
}
|
||||
|
||||
if (--px->prec < 0) {
|
||||
px->prec = 0;
|
||||
}
|
||||
|
||||
code = (code == 'g') ? 'e' : 'E';
|
||||
}
|
||||
|
||||
px->s[px->n1++] = *p++;
|
||||
|
||||
if (px->prec > 0 || (px->flags & 8)) {
|
||||
px->s[px->n1++] = point;
|
||||
}
|
||||
|
||||
if (px->prec > 0) {
|
||||
if (px->prec < --nsig) {
|
||||
nsig = px->prec;
|
||||
}
|
||||
|
||||
memcpy(&px->s[px->n1], p, nsig);
|
||||
px->n1 += nsig;
|
||||
px->nz1 = px->prec - nsig;
|
||||
}
|
||||
|
||||
p = &px->s[px->n1];
|
||||
*p++ = code;
|
||||
|
||||
if (xexp >= 0) {
|
||||
*p++ = '+';
|
||||
} else {
|
||||
*p++ = '-';
|
||||
xexp = -xexp;
|
||||
}
|
||||
|
||||
if (xexp >= 100) {
|
||||
if (xexp >= 1000) {
|
||||
*p++ = (xexp / 1000) + '0', xexp %= 1000;
|
||||
}
|
||||
*p++ = (xexp / 100) + '0', xexp %= 100;
|
||||
}
|
||||
*p++ = (xexp / 10) + '0', xexp %= 10;
|
||||
|
||||
*p++ = xexp + '0';
|
||||
px->n2 = (size_t) p - ((size_t) px->s + px->n1);
|
||||
}
|
||||
|
||||
if ((px->flags & 0x14) == 0x10) {
|
||||
s32 n = px->n0 + px->n1 + px->nz1 + px->n2 + px->nz2;
|
||||
|
||||
if (n < px->width) {
|
||||
px->nz0 = px->width - n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,40 +2,12 @@
|
||||
#include "libc/string.h"
|
||||
#include "libc/stdlib.h"
|
||||
|
||||
// typedef struct {
|
||||
// /* 0x0 */ union {
|
||||
// /* 0x0 */ s64 ll;
|
||||
// /* 0x0 */ f64 ld;
|
||||
// } v;
|
||||
// /* 0x8 */ char* s;
|
||||
// /* 0xC */ s32 n0;
|
||||
// /* 0x10 */ s32 nz0;
|
||||
// /* 0x14 */ s32 n1;
|
||||
// /* 0x18 */ s32 nz1;
|
||||
// /* 0x1C */ s32 n2;
|
||||
// /* 0x20 */ s32 nz2;
|
||||
// /* 0x24 */ s32 prec;
|
||||
// /* 0x28 */ s32 width;
|
||||
// /* 0x2C */ size_t nchar;
|
||||
// /* 0x30 */ u32 flags;
|
||||
// /* 0x34 */ u8 qual;
|
||||
// } _Pft;
|
||||
|
||||
#define BUFF_LEN 0x18
|
||||
// #define FLAGS_SPACE 1
|
||||
// #define FLAGS_PLUS 2
|
||||
// #define FLAGS_MINUS 4
|
||||
// #define FLAGS_HASH 8
|
||||
// #define FLAGS_ZERO 16
|
||||
|
||||
// Pending Data for import:
|
||||
// u8 ldigs[] = "0123456789abcdef";
|
||||
// u8 udigs[] = "0123456789ABCDEF";
|
||||
static char ldigs[] = "0123456789abcdef";
|
||||
static char udigs[] = "0123456789ABCDEF";
|
||||
|
||||
extern u8 ldigs[];
|
||||
extern u8 udigs[];
|
||||
|
||||
void _Litob(_Pft* args, u8 type) {
|
||||
void _Litob(_Pft* args, char type) {
|
||||
u8 buff[BUFF_LEN];
|
||||
const u8* numMap;
|
||||
s32 base;
|
||||
|
||||
+249
-3
@@ -1,5 +1,251 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "libc/string.h"
|
||||
#include "libc/stdarg.h"
|
||||
#include "PR/xstdio.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xprintf/_Putfld.s")
|
||||
// TODO: these come from headers
|
||||
#ident "$Revision: 1.34 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.23 $"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/libc/xprintf/_Printf.s")
|
||||
#define isdigit(x) ((x >= '0' && x <= '9'))
|
||||
#define LDSIGN(x) (((unsigned short*) &(x))[0] & 0x8000)
|
||||
|
||||
#define ATOI(dst, src) \
|
||||
for (dst = 0; isdigit(*src); ++src) { \
|
||||
if (dst < 999) \
|
||||
dst = dst * 10 + *src - '0'; \
|
||||
}
|
||||
|
||||
#define MAX_PAD ((sizeof(spaces) - 1))
|
||||
#define PAD(s, n) \
|
||||
if (0 < (n)) { \
|
||||
int i, j = (n); \
|
||||
for (; 0 < j; j -= i) { \
|
||||
i = MAX_PAD < (unsigned int) j ? (int) MAX_PAD : j; \
|
||||
PUT(s, i); \
|
||||
} \
|
||||
}
|
||||
#define PUT(s, n) \
|
||||
if (0 < (n)) { \
|
||||
if ((arg = (*prout)(arg, s, n)) != NULL) \
|
||||
x.nchar += (n); \
|
||||
else \
|
||||
return x.nchar; \
|
||||
}
|
||||
static char spaces[] = " ";
|
||||
static char zeroes[] = "00000000000000000000000000000000";
|
||||
|
||||
static void _Putfld(_Pft* x, va_list* args, char type, char* buff);
|
||||
|
||||
int _Printf(outfun prout, char* arg, const char* fmt, va_list args) {
|
||||
_Pft x;
|
||||
|
||||
x.nchar = 0;
|
||||
|
||||
while (TRUE) {
|
||||
const char* s;
|
||||
char c;
|
||||
const char* t;
|
||||
static const char fchar[] = { ' ', '+', '-', '#', '0', '\0' };
|
||||
static const int fbit[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 };
|
||||
char ac[32];
|
||||
s = fmt;
|
||||
|
||||
for (c = *s; c != 0 && c != '%';) {
|
||||
c = *++s;
|
||||
}
|
||||
|
||||
PUT(fmt, s - fmt);
|
||||
|
||||
if (c == 0) {
|
||||
return x.nchar;
|
||||
}
|
||||
|
||||
fmt = ++s;
|
||||
|
||||
for (x.flags = 0; (t = strchr(fchar, *s)) != NULL; s++) {
|
||||
x.flags |= fbit[t - fchar];
|
||||
}
|
||||
|
||||
if (*s == '*') {
|
||||
x.width = va_arg(args, int);
|
||||
|
||||
if (x.width < 0) {
|
||||
x.width = -x.width;
|
||||
x.flags |= FLAGS_MINUS;
|
||||
}
|
||||
s++;
|
||||
} else
|
||||
ATOI(x.width, s);
|
||||
|
||||
if (*s != '.') {
|
||||
x.prec = -1;
|
||||
} else if (*++s == '*') {
|
||||
x.prec = va_arg(args, int);
|
||||
++s;
|
||||
} else {
|
||||
for (x.prec = 0; isdigit(*s); s++) {
|
||||
if (x.prec < 999) {
|
||||
x.prec = x.prec * 10 + *s - '0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x.qual = strchr("hlL", *s) ? *s++ : '\0';
|
||||
|
||||
if (x.qual == 'l' && *s == 'l') {
|
||||
x.qual = 'L';
|
||||
++s;
|
||||
}
|
||||
|
||||
_Putfld(&x, &args, *s, ac);
|
||||
x.width -= x.n0 + x.nz0 + x.n1 + x.nz1 + x.n2 + x.nz2;
|
||||
|
||||
{
|
||||
|
||||
if (!(x.flags & FLAGS_MINUS)) {
|
||||
int i, j;
|
||||
if (0 < (x.width)) {
|
||||
i, j = x.width;
|
||||
for (; 0 < j; j -= i) {
|
||||
i = MAX_PAD < (unsigned int) j ? (int) MAX_PAD : j;
|
||||
PUT(spaces, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PUT(ac, x.n0);
|
||||
PAD(zeroes, x.nz0)
|
||||
|
||||
PUT(x.s, x.n1);
|
||||
PAD(zeroes, x.nz1);
|
||||
|
||||
PUT(x.s + x.n1, x.n2);
|
||||
PAD(zeroes, x.nz2);
|
||||
|
||||
if (x.flags & FLAGS_MINUS) {
|
||||
PAD(spaces, x.width);
|
||||
}
|
||||
}
|
||||
fmt = s + 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _Putfld(_Pft* x, va_list* args, char type, char* buff) {
|
||||
x->n0 = x->nz0 = x->n1 = x->nz1 = x->n2 = x->nz2 = 0;
|
||||
|
||||
switch (type) {
|
||||
case 'c':
|
||||
buff[x->n0++] = va_arg(*args, int);
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
if (x->qual == 'l') {
|
||||
x->v.ll = va_arg(*args, int);
|
||||
} else if (x->qual == 'L') {
|
||||
x->v.ll = va_arg(*args, s64);
|
||||
} else {
|
||||
x->v.ll = va_arg(*args, int);
|
||||
}
|
||||
|
||||
if (x->qual == 'h') {
|
||||
x->v.ll = (s16) x->v.ll;
|
||||
}
|
||||
|
||||
if (x->v.ll < 0) {
|
||||
buff[x->n0++] = '-';
|
||||
} else if (x->flags & FLAGS_PLUS) {
|
||||
buff[x->n0++] = '+';
|
||||
} else if (x->flags & FLAGS_SPACE) {
|
||||
buff[x->n0++] = ' ';
|
||||
}
|
||||
|
||||
x->s = (char*) &buff[x->n0];
|
||||
|
||||
_Litob(x, type);
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'u':
|
||||
case 'o':
|
||||
if (x->qual == 'l') {
|
||||
x->v.ll = va_arg(*args, int);
|
||||
} else if (x->qual == 'L') {
|
||||
x->v.ll = va_arg(*args, s64);
|
||||
} else {
|
||||
x->v.ll = va_arg(*args, int);
|
||||
}
|
||||
|
||||
if (x->qual == 'h') {
|
||||
x->v.ll = (u16) x->v.ll;
|
||||
} else if (x->qual == 0) {
|
||||
x->v.ll = (unsigned int) x->v.ll;
|
||||
}
|
||||
|
||||
if (x->flags & FLAGS_HASH) {
|
||||
buff[x->n0++] = '0';
|
||||
|
||||
if (type == 'x' || type == 'X') {
|
||||
buff[x->n0++] = type;
|
||||
}
|
||||
}
|
||||
|
||||
x->s = (char*) &buff[x->n0];
|
||||
_Litob(x, type);
|
||||
break;
|
||||
case 'e':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'E':
|
||||
case 'G':
|
||||
//... okay?
|
||||
x->v.ld = x->qual == 'L' ? va_arg(*args, f64) : va_arg(*args, f64);
|
||||
|
||||
if (LDSIGN(x->v.ld)) {
|
||||
buff[x->n0++] = '-';
|
||||
} else if (x->flags & FLAGS_PLUS) {
|
||||
buff[x->n0++] = '+';
|
||||
} else if (x->flags & FLAGS_SPACE) {
|
||||
buff[x->n0++] = ' ';
|
||||
}
|
||||
|
||||
x->s = (char*) &buff[x->n0];
|
||||
_Ldtob(x, type);
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (x->qual == 'h') {
|
||||
*(va_arg(*args, u16*)) = x->nchar;
|
||||
} else if (x->qual == 'l') {
|
||||
*va_arg(*args, unsigned int*) = x->nchar;
|
||||
} else if (x->qual == 'L') {
|
||||
*va_arg(*args, u64*) = x->nchar;
|
||||
} else {
|
||||
*va_arg(*args, unsigned int*) = x->nchar;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'p':
|
||||
x->v.ll = (long) va_arg(*args, void*);
|
||||
x->s = (char*) &buff[x->n0];
|
||||
_Litob(x, 'x');
|
||||
break;
|
||||
case 's':
|
||||
x->s = va_arg(*args, char*);
|
||||
x->n1 = strlen(x->s);
|
||||
|
||||
if (x->prec >= 0 && x->prec < x->n1) {
|
||||
x->n1 = x->prec;
|
||||
}
|
||||
|
||||
break;
|
||||
case '%':
|
||||
buff[x->n0++] = '%';
|
||||
break;
|
||||
default:
|
||||
buff[x->n0++] = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,54 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/R4300.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/createthread/osCreateThread.s")
|
||||
extern __OSThreadprofile_s thprof[];
|
||||
|
||||
void osCreateThread(OSThread* t, OSId id, void (*entry)(void*), void* arg, void* sp, OSPri p) {
|
||||
register u32 saveMask;
|
||||
OSIntMask mask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((u32) sp & 0x7) {
|
||||
__osError(ERR_OSCREATETHREAD_SP, 1, sp);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p < OS_PRIORITY_IDLE) || (p > OS_PRIORITY_MAX)) {
|
||||
__osError(ERR_OSCREATETHREAD_PRI, 1, p);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
t->id = id;
|
||||
t->priority = p;
|
||||
t->next = NULL;
|
||||
t->queue = NULL;
|
||||
t->context.pc = (u32) entry;
|
||||
t->context.a0 = (s64) (s32) arg; // Double cast gets rid of compiler warning
|
||||
t->context.sp = (s64) (s32) sp - 16;
|
||||
t->context.ra = __osCleanupThread;
|
||||
mask = OS_IM_ALL;
|
||||
t->context.sr = (mask & (SR_IMASK | SR_IE)) | SR_EXL;
|
||||
t->context.rcp = (mask & RCP_IMASK) >> RCP_IMASKSHIFT;
|
||||
t->context.fpcsr = (u32) (FPCSR_FS | FPCSR_EV);
|
||||
t->fp = 0;
|
||||
t->state = OS_STATE_STOPPED;
|
||||
t->flags = 0;
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
#ifndef _FINALROM
|
||||
if (id < THPROF_IDMAX) {
|
||||
t->thprof = &thprof[id];
|
||||
} else {
|
||||
t->thprof = &thprof[THPROF_IDMAX - 1];
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
t->tlnext = __osActiveQueue;
|
||||
__osActiveQueue = t;
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/getthreadpri/osGetThreadPri.s")
|
||||
OSPri osGetThreadPri(OSThread* thread) {
|
||||
if (thread == NULL) {
|
||||
thread = __osRunningThread;
|
||||
}
|
||||
|
||||
return thread->priority;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/viint.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/gettime/osGetTime.s")
|
||||
OSTime osGetTime() {
|
||||
u32 tmptime;
|
||||
u32 elapseCount;
|
||||
OSTime currentCount;
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSGETTIME, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
tmptime = osGetCount();
|
||||
elapseCount = tmptime - __osBaseCounter;
|
||||
currentCount = __osCurrentTime;
|
||||
__osRestoreInt(saveMask);
|
||||
return currentCount + elapseCount;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,224 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/os_version.h"
|
||||
#include "piint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/initialize/osInitialize.s")
|
||||
typedef struct {
|
||||
/* 0x0 */ unsigned int inst1;
|
||||
/* 0x4 */ unsigned int inst2;
|
||||
/* 0x8 */ unsigned int inst3;
|
||||
/* 0xC */ unsigned int inst4;
|
||||
} __osExceptionVector;
|
||||
extern __osExceptionVector __osExceptionPreamble[];
|
||||
|
||||
extern OSPiHandle __Dom1SpeedParam;
|
||||
extern OSPiHandle __Dom2SpeedParam;
|
||||
|
||||
OSTime osClockRate = OS_CLOCK_RATE;
|
||||
s32 osViClock = VI_NTSC_CLOCK;
|
||||
u32 __osShutdown = 0;
|
||||
u32 __OSGlobalIntMask = OS_IM_ALL;
|
||||
#ifdef _FINALROM
|
||||
u32 __osFinalrom;
|
||||
#else
|
||||
u32 __kmc_pt_mode;
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
void* __printfunc = NULL;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
|
||||
#define INITIALIZE_FUNC __osInitialize_common
|
||||
#define SPEED_PARAM_FUNC __createSpeedParam
|
||||
#else
|
||||
|
||||
#define INITIALIZE_FUNC osInitialize
|
||||
#define SPEED_PARAM_FUNC createSpeedParam
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
static void ptstart(void);
|
||||
static void SPEED_PARAM_FUNC(void);
|
||||
#endif
|
||||
extern __osExceptionVector __ptExceptionPreamble[];
|
||||
|
||||
#endif
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
void SPEED_PARAM_FUNC(void) {
|
||||
__Dom1SpeedParam.type = DEVICE_TYPE_INIT;
|
||||
__Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG);
|
||||
__Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG);
|
||||
__Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG);
|
||||
__Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG);
|
||||
|
||||
__Dom2SpeedParam.type = DEVICE_TYPE_INIT;
|
||||
__Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG);
|
||||
__Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG);
|
||||
__Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG);
|
||||
__Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG);
|
||||
}
|
||||
#endif
|
||||
|
||||
void INITIALIZE_FUNC() {
|
||||
u32 pifdata;
|
||||
#if BUILD_VERSION < VERSION_K
|
||||
u32 clock = 0;
|
||||
#endif
|
||||
|
||||
#ifdef _FINALROM
|
||||
__osFinalrom = TRUE;
|
||||
#endif
|
||||
|
||||
__osSetSR(__osGetSR() | SR_CU1); // enable fpu
|
||||
__osSetFpcCsr(FPCSR_FS | FPCSR_EV); // flush denorm to zero, enable invalid operation
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
__osSetWatchLo(0x4900000);
|
||||
#endif
|
||||
|
||||
while (__osSiRawReadIo(PIF_RAM_END - 3, &pifdata)) { // last byte of joychannel ram
|
||||
;
|
||||
}
|
||||
while (__osSiRawWriteIo(PIF_RAM_END - 3, pifdata | 8)) {
|
||||
; // todo: magic contant
|
||||
}
|
||||
*(__osExceptionVector*) UT_VEC = *__osExceptionPreamble;
|
||||
*(__osExceptionVector*) XUT_VEC = *__osExceptionPreamble;
|
||||
*(__osExceptionVector*) ECC_VEC = *__osExceptionPreamble;
|
||||
*(__osExceptionVector*) E_VEC = *__osExceptionPreamble;
|
||||
osWritebackDCache((void*) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector));
|
||||
osInvalICache((void*) UT_VEC, E_VEC - UT_VEC + sizeof(__osExceptionVector));
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
SPEED_PARAM_FUNC();
|
||||
osUnmapTLBAll();
|
||||
osMapTLBRdb();
|
||||
#else
|
||||
osMapTLBRdb();
|
||||
osPiRawReadIo(4, &clock); // Read clock rate from the ROM header
|
||||
clock &= ~0xf;
|
||||
if (clock != 0) {
|
||||
osClockRate = clock;
|
||||
}
|
||||
#endif
|
||||
osClockRate = osClockRate * 3 / 4;
|
||||
|
||||
if (osResetType == 0) { // cold reset
|
||||
bzero(osAppNMIBuffer, OS_APP_NMI_BUFSIZE);
|
||||
}
|
||||
|
||||
if (osTvType == OS_TV_PAL) {
|
||||
osViClock = VI_PAL_CLOCK;
|
||||
} else if (osTvType == OS_TV_MPAL) {
|
||||
osViClock = VI_MPAL_CLOCK;
|
||||
} else {
|
||||
osViClock = VI_NTSC_CLOCK;
|
||||
}
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
// Wait until there are no RCP interrupts
|
||||
if (__osGetCause() & CAUSE_IP5) {
|
||||
while (TRUE) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
IO_WRITE(AI_CONTROL_REG, AI_CONTROL_DMA_ON);
|
||||
IO_WRITE(AI_DACRATE_REG, AI_MAX_DAC_RATE - 1);
|
||||
IO_WRITE(AI_BITRATE_REG, AI_MAX_BIT_RATE - 1);
|
||||
#endif
|
||||
|
||||
#if BUILD_VERSION < VERSION_K && !defined(_FINALROM)
|
||||
if (!__kmc_pt_mode) {
|
||||
int (*fnc)(s32, s32);
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
unsigned int c;
|
||||
unsigned int c1;
|
||||
#endif
|
||||
unsigned int* src;
|
||||
unsigned int* dst;
|
||||
unsigned int monadr;
|
||||
volatile unsigned int* mon;
|
||||
volatile unsigned int* stat;
|
||||
|
||||
stat = (unsigned*) 0xbff08004;
|
||||
mon = (unsigned*) 0xBFF00000;
|
||||
if (*mon != 0x4B4D4300) {
|
||||
return;
|
||||
}
|
||||
|
||||
src = (unsigned*) __ptExceptionPreamble;
|
||||
dst = (unsigned*) E_VEC;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
src += 2;
|
||||
dst += 2;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++;
|
||||
#if BUILD_VERSION >= VERSION_H
|
||||
*dst++ = *src++;
|
||||
#endif
|
||||
|
||||
osWritebackDCache(E_VEC, 0x24);
|
||||
osInvalICache(E_VEC, 0x24);
|
||||
|
||||
__kmc_pt_mode = TRUE;
|
||||
|
||||
if ((*stat & 0x10) == 0) {
|
||||
monadr = *(mon + 1);
|
||||
if (monadr != 0xBFF00000) {
|
||||
unsigned int* src;
|
||||
unsigned int* dst = monadr | 0x20000000;
|
||||
unsigned int ct = 0x2000 / 4;
|
||||
|
||||
src = 0xBFF00000;
|
||||
|
||||
while (ct != 0) {
|
||||
*dst++ = *src++;
|
||||
ct--;
|
||||
}
|
||||
}
|
||||
fnc = monadr + 8;
|
||||
fnc(0x4B4D4300, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(_FINALROM) && BUILD_VERSION < VERSION_J
|
||||
void ptstart() {
|
||||
}
|
||||
#elif !defined(_FINALROM) && BUILD_VERSION < VERSION_K
|
||||
static void ptstart() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
void __osInitialize_autodetect() {
|
||||
#ifndef _FINALROM
|
||||
if (__checkHardware_msp()) {
|
||||
__osInitialize_msp();
|
||||
} else if (__checkHardware_kmc()) {
|
||||
__osInitialize_kmc();
|
||||
} else if (__checkHardware_isv()) {
|
||||
__osInitialize_isv();
|
||||
} else {
|
||||
__osInitialize_emu();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#elif BUILD_VERSION == VERSION_J
|
||||
static void SPEED_PARAM_FUNC(void) {
|
||||
__Dom1SpeedParam.type = DEVICE_TYPE_INIT;
|
||||
__Dom1SpeedParam.latency = IO_READ(PI_BSD_DOM1_LAT_REG);
|
||||
__Dom1SpeedParam.pulse = IO_READ(PI_BSD_DOM1_PWD_REG);
|
||||
__Dom1SpeedParam.pageSize = IO_READ(PI_BSD_DOM1_PGS_REG);
|
||||
__Dom1SpeedParam.relDuration = IO_READ(PI_BSD_DOM1_RLS_REG);
|
||||
|
||||
__Dom2SpeedParam.type = DEVICE_TYPE_INIT;
|
||||
__Dom2SpeedParam.latency = IO_READ(PI_BSD_DOM2_LAT_REG);
|
||||
__Dom2SpeedParam.pulse = IO_READ(PI_BSD_DOM2_PWD_REG);
|
||||
__Dom2SpeedParam.pageSize = IO_READ(PI_BSD_DOM2_PGS_REG);
|
||||
__Dom2SpeedParam.relDuration = IO_READ(PI_BSD_DOM2_RLS_REG);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,31 @@
|
||||
#include "common.h"
|
||||
#ifndef _FINALROM
|
||||
#include "PR/rdb.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/initrdb/osInitRdb.s")
|
||||
rdbPacket* __osRdb_IP6_Data;
|
||||
u32 __osRdb_IP6_Size;
|
||||
u32 __osRdb_IP6_Ct;
|
||||
u32 __osRdb_IP6_CurWrite;
|
||||
u32 __osRdb_IP6_CurSend;
|
||||
|
||||
void osInitRdb(u8* sendBuf, u32 sendSize) {
|
||||
u32 mask;
|
||||
|
||||
sendSize /= 4;
|
||||
|
||||
if (((u32) sendBuf & 3) != 0) {
|
||||
sendBuf = ((u32) sendBuf & 3) + 4;
|
||||
sendSize--;
|
||||
}
|
||||
mask = __osDisableInt();
|
||||
|
||||
__osRdb_IP6_Data = (rdbPacket*) sendBuf;
|
||||
__osRdb_IP6_Size = sendSize;
|
||||
__osRdb_IP6_Ct = 0;
|
||||
__osRdb_IP6_CurWrite = 0;
|
||||
__osRdb_IP6_CurSend = 0;
|
||||
|
||||
__osRestoreInt(mask);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/jammesg/osJamMesg.s")
|
||||
s32 osJamMesg(OSMesgQueue* mq, OSMesg msg, s32 flag) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((flag != OS_MESG_NOBLOCK) && (flag != OS_MESG_BLOCK)) {
|
||||
__osError(ERR_OSJAMMESG, 1, flag);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
while (mq->validCount >= mq->msgCount) {
|
||||
if (flag == OS_MESG_BLOCK) {
|
||||
__osRunningThread->state = OS_STATE_WAITING;
|
||||
__osEnqueueAndYield(&mq->fullqueue);
|
||||
} else {
|
||||
__osRestoreInt(saveMask);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
mq->first = (mq->first + mq->msgCount - 1) % mq->msgCount;
|
||||
mq->msg[mq->first] = msg;
|
||||
mq->validCount++;
|
||||
|
||||
if (mq->mtqueue->next != NULL) {
|
||||
osStartThread(__osPopThread(&mq->mtqueue));
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,73 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rdb.h"
|
||||
#include "PR/R4300.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/rdbsend/__osRdbSend.s")
|
||||
extern rdbPacket* __osRdb_IP6_Data;
|
||||
extern u32 __osRdb_IP6_Size;
|
||||
extern u32 __osRdb_IP6_Ct;
|
||||
extern u32 __osRdb_IP6_CurWrite;
|
||||
|
||||
u32 __osRdb_IP6_Empty = 1;
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
u32 __osRdbSend(u8* buf, u32 size, u32 type) {
|
||||
rdbPacket* pPtr;
|
||||
rdbPacket pkt;
|
||||
u32 len;
|
||||
u32 c;
|
||||
u32 inCt = 0;
|
||||
u32 needFirst = 0;
|
||||
u32 mask;
|
||||
u32 sent = 0;
|
||||
|
||||
mask = __osDisableInt();
|
||||
|
||||
if (__osRdb_IP6_Empty != 0) {
|
||||
__osRdb_IP6_Empty = 0;
|
||||
pkt.type = type;
|
||||
|
||||
len = MIN(size, sizeof(pkt.buf));
|
||||
|
||||
pkt.length = len;
|
||||
|
||||
c = 0;
|
||||
while (c < len) {
|
||||
pkt.buf[c++] = buf[inCt++];
|
||||
}
|
||||
|
||||
size -= len;
|
||||
sent = len;
|
||||
needFirst = 1;
|
||||
}
|
||||
|
||||
while (size != 0 && __osRdb_IP6_Ct < __osRdb_IP6_Size) {
|
||||
len = MIN(size, sizeof(pPtr->buf));
|
||||
|
||||
pPtr = &__osRdb_IP6_Data[__osRdb_IP6_CurWrite];
|
||||
|
||||
pPtr->type = type;
|
||||
pPtr->length = len;
|
||||
|
||||
c = 0;
|
||||
while (c < len) {
|
||||
pPtr->buf[c++] = buf[inCt++];
|
||||
}
|
||||
|
||||
__osRdb_IP6_CurWrite++;
|
||||
if (__osRdb_IP6_CurWrite >= __osRdb_IP6_Size) {
|
||||
__osRdb_IP6_CurWrite = 0;
|
||||
}
|
||||
|
||||
__osRdb_IP6_Ct++;
|
||||
size -= len;
|
||||
sent += len;
|
||||
}
|
||||
|
||||
if (needFirst) {
|
||||
*(u32*) RDB_BASE_REG = *(u32*) &pkt;
|
||||
}
|
||||
__osRestoreInt(mask);
|
||||
|
||||
return sent;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,40 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/recvmesg/osRecvMesg.s")
|
||||
s32 osRecvMesg(OSMesgQueue* mq, OSMesg* msg, s32 flags) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((flags != OS_MESG_NOBLOCK) && (flags != OS_MESG_BLOCK)) {
|
||||
__osError(ERR_OSRECVMESG, 1, flags);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
while (MQ_IS_EMPTY(mq)) {
|
||||
if (flags == OS_MESG_NOBLOCK) {
|
||||
__osRestoreInt(saveMask);
|
||||
return -1;
|
||||
} else {
|
||||
__osRunningThread->state = OS_STATE_WAITING;
|
||||
__osEnqueueAndYield(&mq->mtqueue);
|
||||
}
|
||||
}
|
||||
|
||||
if (msg != NULL) {
|
||||
*msg = mq->msg[mq->first];
|
||||
}
|
||||
|
||||
mq->first = (mq->first + 1) % mq->msgCount;
|
||||
mq->validCount--;
|
||||
|
||||
if (mq->fullqueue->next != NULL) {
|
||||
osStartThread(__osPopThread(&mq->fullqueue));
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/resetglobalintmask/__osResetGlobalIntMask.s")
|
||||
void __osResetGlobalIntMask(OSHWIntr mask) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
__OSGlobalIntMask &= ~(mask & ~OS_IM_RCP);
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,38 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/sendmesg/osSendMesg.s")
|
||||
s32 osSendMesg(OSMesgQueue* mq, OSMesg msg, s32 flags) {
|
||||
register u32 saveMask;
|
||||
register s32 last;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((flags != OS_MESG_NOBLOCK) && (flags != OS_MESG_BLOCK)) {
|
||||
__osError(ERR_OSSENDMESG, 1, flags);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
while (MQ_IS_FULL(mq)) {
|
||||
if (flags == OS_MESG_BLOCK) {
|
||||
__osRunningThread->state = OS_STATE_WAITING;
|
||||
__osEnqueueAndYield(&mq->fullqueue);
|
||||
} else {
|
||||
__osRestoreInt(saveMask);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
last = (mq->first + mq->validCount) % mq->msgCount;
|
||||
mq->msg[last] = msg;
|
||||
mq->validCount++;
|
||||
|
||||
if (mq->mtqueue->next != NULL) {
|
||||
osStartThread(__osPopThread(&mq->mtqueue));
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/seteventmesg/osSetEventMesg.s")
|
||||
__OSEventState __osEventStateTab[OS_NUM_EVENTS] ALIGNED(8);
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
u32 __osPreNMI = FALSE;
|
||||
#endif
|
||||
|
||||
void osSetEventMesg(OSEvent event, OSMesgQueue* mq, OSMesg msg) {
|
||||
register u32 saveMask;
|
||||
__OSEventState* es;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (event >= OS_NUM_EVENTS) {
|
||||
__osError(ERR_OSSETEVENTMESG, 1, event);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
es = &__osEventStateTab[event];
|
||||
|
||||
es->messageQueue = mq;
|
||||
es->message = msg;
|
||||
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
if (event == OS_EVENT_PRENMI) {
|
||||
if (__osShutdown && !__osPreNMI) {
|
||||
osSendMesg(mq, msg, OS_MESG_NOBLOCK);
|
||||
}
|
||||
__osPreNMI = TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/setglobalintmask/__osSetGlobalIntMask.s")
|
||||
void __osSetGlobalIntMask(OSHWIntr mask) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
__OSGlobalIntMask |= mask;
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,36 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/setthreadpri/osSetThreadPri.s")
|
||||
void osSetThreadPri(OSThread* t, OSPri pri) {
|
||||
register u32 saveMask;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((pri < OS_PRIORITY_IDLE) || (pri > OS_PRIORITY_MAX)) {
|
||||
__osError(ERR_OSSETTHREADPRI, 1, pri);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
saveMask = __osDisableInt();
|
||||
|
||||
if (t == NULL) {
|
||||
t = __osRunningThread;
|
||||
}
|
||||
|
||||
if (t->priority != pri) {
|
||||
t->priority = pri;
|
||||
|
||||
if (t != __osRunningThread && t->state != OS_STATE_STOPPED) {
|
||||
__osDequeueThread(t->queue, t);
|
||||
__osEnqueueThread(t->queue, t);
|
||||
}
|
||||
|
||||
if (__osRunningThread->priority < __osRunQueue->priority) {
|
||||
__osRunningThread->state = OS_STATE_RUNNABLE;
|
||||
__osEnqueueAndYield(&__osRunQueue);
|
||||
}
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/settime/osSetTime.s")
|
||||
void osSetTime(OSTime time) {
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSSETTIME, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
__osCurrentTime = time;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,56 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/settimer/osSetTimer.s")
|
||||
int osSetTimer(OSTimer* t, OSTime countdown, OSTime interval, OSMesgQueue* mq, OSMesg msg) {
|
||||
OSTime time;
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
OSTimer* next;
|
||||
u32 count;
|
||||
u32 value;
|
||||
u32 saveMask;
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (!__osViDevMgr.active) {
|
||||
__osError(ERR_OSSETTIMER, 0);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
t->next = NULL;
|
||||
t->prev = NULL;
|
||||
t->interval = interval;
|
||||
t->value = (countdown != 0) ? countdown : interval;
|
||||
t->mq = mq;
|
||||
t->msg = msg;
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
saveMask = __osDisableInt();
|
||||
if (__osTimerList->next == __osTimerList) {
|
||||
|
||||
} else {
|
||||
next = __osTimerList->next;
|
||||
count = osGetCount();
|
||||
value = count - __osTimerCounter;
|
||||
|
||||
if (value < next->value) {
|
||||
next->value -= value;
|
||||
} else {
|
||||
next->value = 1;
|
||||
}
|
||||
}
|
||||
|
||||
time = __osInsertTimer(t);
|
||||
__osSetTimerIntr(__osTimerList->next->value);
|
||||
__osRestoreInt(saveMask);
|
||||
#else
|
||||
time = __osInsertTimer(t);
|
||||
if (__osTimerList->next == t) {
|
||||
__osSetTimerIntr(time);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,39 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/startthread/osStartThread.s")
|
||||
void osStartThread(OSThread* t) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
switch (t->state) {
|
||||
case OS_STATE_WAITING:
|
||||
t->state = OS_STATE_RUNNABLE;
|
||||
__osEnqueueThread(&__osRunQueue, t);
|
||||
break;
|
||||
case OS_STATE_STOPPED:
|
||||
if (t->queue == NULL || t->queue == &__osRunQueue) {
|
||||
t->state = OS_STATE_RUNNABLE;
|
||||
__osEnqueueThread(&__osRunQueue, t);
|
||||
} else {
|
||||
t->state = OS_STATE_WAITING;
|
||||
__osEnqueueThread(t->queue, t);
|
||||
__osEnqueueThread(&__osRunQueue, __osPopThread(t->queue));
|
||||
}
|
||||
break;
|
||||
#ifdef _DEBUG
|
||||
default:
|
||||
__osError(ERR_OSSTARTTHREAD, 0);
|
||||
__osRestoreInt(saveMask);
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (__osRunningThread == NULL) {
|
||||
__osDispatchThread();
|
||||
} else if (__osRunningThread->priority < __osRunQueue->priority) {
|
||||
__osRunningThread->state = OS_STATE_RUNNABLE;
|
||||
__osEnqueueAndYield(&__osRunQueue);
|
||||
}
|
||||
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/thread/__osDequeueThread.s")
|
||||
struct __osThreadTail __osThreadTail = { NULL, -1 };
|
||||
OSThread* __osRunQueue = (OSThread*) &__osThreadTail;
|
||||
OSThread* __osActiveQueue = (OSThread*) &__osThreadTail;
|
||||
OSThread* __osRunningThread = { 0 };
|
||||
OSThread* __osFaultedThread = { 0 };
|
||||
|
||||
void __osDequeueThread(register OSThread** queue, register OSThread* t) {
|
||||
register OSThread* pred;
|
||||
register OSThread* succ;
|
||||
|
||||
pred = (OSThread*) queue;
|
||||
succ = pred->next;
|
||||
|
||||
while (succ != NULL) {
|
||||
if (succ == t) {
|
||||
pred->next = t->next;
|
||||
#ifdef _DEBUG
|
||||
t->next = NULL;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
pred = succ;
|
||||
succ = pred->next;
|
||||
}
|
||||
}
|
||||
|
||||
+140
-5
@@ -1,9 +1,144 @@
|
||||
#include "common.h"
|
||||
#include "macros.h"
|
||||
#include "osint.h"
|
||||
#include "PR/os_internal.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/timerintr/__osTimerServicesInit.s")
|
||||
// this needs to be in bss, because __osTimerServicesInit wont match otherwise.
|
||||
// The rest cannot be declared here, as they will be put above this symbol, which
|
||||
// doesnt match.
|
||||
OSTime __osCurrentTime;
|
||||
u32 __osBaseCounter;
|
||||
u32 __osViIntrCount;
|
||||
u32 __osTimerCounter;
|
||||
OSTimer __osBaseTimer;
|
||||
OSTimer* __osTimerList = &__osBaseTimer;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/timerintr/__osTimerInterrupt.s")
|
||||
#ifndef _FINALROM
|
||||
OSMesgQueue __osProfTimerQ ALIGNED(8);
|
||||
OSProf* __osProfileList;
|
||||
OSProf* __osProfileListEnd;
|
||||
u32 __osProfileOverflowBin;
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/timerintr/__osSetTimerIntr.s")
|
||||
void __osTimerServicesInit(void) {
|
||||
__osCurrentTime = 0;
|
||||
__osBaseCounter = 0;
|
||||
__osViIntrCount = 0;
|
||||
__osTimerList->next = __osTimerList->prev = __osTimerList;
|
||||
__osTimerList->interval = __osTimerList->value = 0;
|
||||
__osTimerList->mq = NULL;
|
||||
__osTimerList->msg = 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/timerintr/__osInsertTimer.s")
|
||||
void __osTimerInterrupt(void) {
|
||||
OSTimer* t;
|
||||
u32 count;
|
||||
u32 elapsed_cycles;
|
||||
|
||||
#ifndef _FINALROM
|
||||
u32 pc;
|
||||
s32 offset;
|
||||
OSProf* prof = __osProfileList;
|
||||
#endif
|
||||
|
||||
if (__osTimerList->next == __osTimerList) {
|
||||
return;
|
||||
}
|
||||
for (;;) {
|
||||
t = __osTimerList->next;
|
||||
|
||||
if (t == __osTimerList) {
|
||||
__osSetCompare(0);
|
||||
__osTimerCounter = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
count = osGetCount();
|
||||
elapsed_cycles = count - __osTimerCounter;
|
||||
__osTimerCounter = count;
|
||||
|
||||
if (elapsed_cycles < t->value) {
|
||||
t->value -= elapsed_cycles;
|
||||
__osSetTimerIntr(t->value);
|
||||
break;
|
||||
}
|
||||
|
||||
t->prev->next = t->next;
|
||||
t->next->prev = t->prev;
|
||||
t->next = NULL;
|
||||
t->prev = NULL;
|
||||
|
||||
if (t->mq != NULL) {
|
||||
#ifdef _FINALROM
|
||||
osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK);
|
||||
}
|
||||
#else
|
||||
if (t->mq != &__osProfTimerQ) {
|
||||
osSendMesg(t->mq, t->msg, OS_MESG_NOBLOCK);
|
||||
} else {
|
||||
pc = __osRunQueue->context.pc;
|
||||
for (prof = __osProfileList; prof < __osProfileListEnd; prof++) {
|
||||
offset = pc - (u32) prof->text_start;
|
||||
|
||||
if (offset >= 0) {
|
||||
if ((s32) prof->text_end - (s32) pc > 0) {
|
||||
(*(u16*) (u32) ((offset >> 2) + prof->histo_base))++;
|
||||
goto __ProfDone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__osProfileOverflowBin++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
__ProfDone:
|
||||
|
||||
if (t->interval != 0) {
|
||||
t->value = t->interval;
|
||||
__osInsertTimer(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __osSetTimerIntr(OSTime tim) {
|
||||
OSTime NewTime;
|
||||
u32 savedMask;
|
||||
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
if (tim < 468) {
|
||||
tim = 468;
|
||||
}
|
||||
#endif
|
||||
|
||||
savedMask = __osDisableInt();
|
||||
__osTimerCounter = osGetCount();
|
||||
NewTime = __osTimerCounter + tim;
|
||||
__osSetCompare(NewTime);
|
||||
__osRestoreInt(savedMask);
|
||||
}
|
||||
|
||||
OSTime __osInsertTimer(OSTimer* t) {
|
||||
OSTimer* timep;
|
||||
OSTime tim;
|
||||
u32 savedMask = __osDisableInt();
|
||||
|
||||
timep = __osTimerList->next;
|
||||
tim = t->value;
|
||||
for (; timep != __osTimerList && tim > timep->value; timep = timep->next) {
|
||||
tim -= timep->value;
|
||||
}
|
||||
|
||||
t->value = tim;
|
||||
|
||||
if (timep != __osTimerList) {
|
||||
timep->value -= tim;
|
||||
}
|
||||
|
||||
t->next = timep;
|
||||
t->prev = timep->prev;
|
||||
timep->prev->next = t;
|
||||
timep->prev = t;
|
||||
__osRestoreInt(savedMask);
|
||||
return tim;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/R4300.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/virtualtophysical/osVirtualToPhysical.s")
|
||||
u32 osVirtualToPhysical(void* addr) {
|
||||
if (IS_KSEG0(addr)) {
|
||||
return K0_TO_PHYS(addr);
|
||||
} else if (IS_KSEG1(addr)) {
|
||||
return K1_TO_PHYS(addr);
|
||||
} else {
|
||||
return __osProbeTLB(addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "osint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/os/yieldthread/osYieldThread.s")
|
||||
void osYieldThread(void) {
|
||||
register u32 saveMask = __osDisableInt();
|
||||
|
||||
__osRunningThread->state = OS_STATE_RUNNABLE;
|
||||
__osEnqueueAndYield(&__osRunQueue);
|
||||
__osRestoreInt(saveMask);
|
||||
}
|
||||
|
||||
+417
-16
@@ -1,31 +1,432 @@
|
||||
#include "common.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/SetTempBreakpoint.s")
|
||||
#include "PR/os_internal.h"
|
||||
#include "dbgproto.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "rmonint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/ClearTempBreakpoint.s")
|
||||
#include "macros.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonSetBreak.s")
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#else
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonListBreak.s")
|
||||
#define TMP_BP 0
|
||||
#define NUM_BREAKPOINTS 16
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonClearBreak.s")
|
||||
typedef struct {
|
||||
TVushort type;
|
||||
TVushort response;
|
||||
TVid threadID;
|
||||
void* pc;
|
||||
} TVExceptionReplyMsg;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonGetBranchTarget.s")
|
||||
typedef struct {
|
||||
u32* breakAddress;
|
||||
u32 oldInstruction;
|
||||
} BREAKINFO;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonbrk_IsJump.s")
|
||||
/* first breakpoint is reserved for implementing single-stepping */
|
||||
static BREAKINFO breakpoints[NUM_BREAKPOINTS] ALIGNED(8);
|
||||
/* breakpoint for alternate branch target */
|
||||
static BREAKINFO altBreak;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonSetSingleStep.s")
|
||||
static BREAKINFO RCPbreakpoints[NUM_BREAKPOINTS] ALIGNED(8);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonGetExceptionStatus.s")
|
||||
u8 __rmonRcpAtBreak;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/rmonSendBreakMessage.s")
|
||||
static void rmonFindFaultedThreads(void);
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonHitBreak.s")
|
||||
void SetTempBreakpoint(u32* addr1, u32* addr2) {
|
||||
STUBBED_PRINTF(("Set temp BP at %08x", addr1));
|
||||
if (addr2 != NULL) {
|
||||
STUBBED_PRINTF((" and %08x", addr2));
|
||||
}
|
||||
STUBBED_PRINTF(("\n"));
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonHitSpBreak.s")
|
||||
/* Save the word at the target address to be restored later */
|
||||
breakpoints[TMP_BP].oldInstruction = *addr1;
|
||||
/* Install a break instruction at the target address */
|
||||
*addr1 = MIPS_BREAK(16);
|
||||
osWritebackDCache(addr1, sizeof(*addr1));
|
||||
osInvalICache(addr1, sizeof(*addr1));
|
||||
breakpoints[TMP_BP].breakAddress = addr1;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/__rmonHitCpuFault.s")
|
||||
/* Also do so for an alt address if required */
|
||||
if (addr2 != NULL) {
|
||||
altBreak.oldInstruction = *addr2;
|
||||
*addr2 = MIPS_BREAK(16);
|
||||
osWritebackDCache(addr2, sizeof(*addr2));
|
||||
osInvalICache(addr2, sizeof(*addr2));
|
||||
altBreak.breakAddress = addr2;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/rmonFindFaultedThreads.s")
|
||||
void ClearTempBreakpoint(void) {
|
||||
u32 inst;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonbrk/D_800C9880.s")
|
||||
if (breakpoints[TMP_BP].breakAddress != NULL) {
|
||||
inst = *breakpoints[TMP_BP].breakAddress;
|
||||
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
STUBBED_PRINTF(("ClearTempBreak @ %08x\n", breakpoints[TMP_BP].breakAddress));
|
||||
|
||||
/* After confirming that there is a break instruction with code at the target
|
||||
address, restore the original contents of the word at the target address */
|
||||
*breakpoints[TMP_BP].breakAddress = breakpoints[TMP_BP].oldInstruction;
|
||||
osWritebackDCache(breakpoints[TMP_BP].breakAddress, sizeof(*breakpoints[TMP_BP].breakAddress));
|
||||
osInvalICache(breakpoints[TMP_BP].breakAddress, sizeof(*breakpoints[TMP_BP].breakAddress));
|
||||
}
|
||||
breakpoints[TMP_BP].breakAddress = NULL;
|
||||
}
|
||||
|
||||
/* Same as above for the alt breakpoint */
|
||||
if (altBreak.breakAddress != NULL) {
|
||||
inst = *altBreak.breakAddress;
|
||||
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
STUBBED_PRINTF(("ClearTempBreak @ %08x\n", altBreak.breakAddress));
|
||||
|
||||
*altBreak.breakAddress = altBreak.oldInstruction;
|
||||
osWritebackDCache(altBreak.breakAddress, sizeof(*altBreak.breakAddress));
|
||||
osInvalICache(altBreak.breakAddress, sizeof(*altBreak.breakAddress));
|
||||
}
|
||||
altBreak.breakAddress = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int __rmonSetBreak(KKHeader* req) {
|
||||
register KKSetBkptRequest* request = (KKSetBkptRequest*) req;
|
||||
register BREAKINFO* breakBase;
|
||||
register BREAKINFO* whichBreak;
|
||||
register BREAKINFO* lastBreak;
|
||||
KKBkptEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("SetBreak at %08x, method %d\n", request->addr, req->method));
|
||||
|
||||
/* Select breakpoint list */
|
||||
if (req->method == RMON_RSP) {
|
||||
breakBase = RCPbreakpoints;
|
||||
whichBreak = &RCPbreakpoints[1];
|
||||
lastBreak = &RCPbreakpoints[NUM_BREAKPOINTS];
|
||||
} else {
|
||||
breakBase = breakpoints;
|
||||
whichBreak = &breakpoints[1];
|
||||
lastBreak = &breakpoints[NUM_BREAKPOINTS];
|
||||
}
|
||||
|
||||
/* Find breakpoint slot */
|
||||
for (; whichBreak < lastBreak; whichBreak++) {
|
||||
if (whichBreak->breakAddress != NULL) {
|
||||
if (whichBreak->breakAddress == (u32*) request->addr) {
|
||||
/* Breakpoint already set here */
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
/* Empty slot */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* No breakpoints available */
|
||||
if (whichBreak == lastBreak) {
|
||||
return TV_ERROR_NO_MORE_IDS;
|
||||
}
|
||||
|
||||
/* Set breakpoint if not already set */
|
||||
if (whichBreak->breakAddress == NULL) {
|
||||
if (req->method == RMON_RSP) {
|
||||
whichBreak->oldInstruction = __rmonReadWordAt((u32*) request->addr);
|
||||
__rmonWriteWordTo((u32*) request->addr, MIPS_BREAK((whichBreak - breakBase) + NUM_BREAKPOINTS));
|
||||
} else {
|
||||
whichBreak->oldInstruction = *(u32*) request->addr;
|
||||
*(u32*) request->addr = MIPS_BREAK((whichBreak - breakBase) + NUM_BREAKPOINTS);
|
||||
osWritebackDCache((void*) request->addr, sizeof(whichBreak->oldInstruction));
|
||||
osInvalICache((void*) request->addr, sizeof(whichBreak->oldInstruction));
|
||||
}
|
||||
whichBreak->breakAddress = (u32*) request->addr;
|
||||
STUBBED_PRINTF(("* (%08x) = %08x (was %08x)\n", whichBreak->breakAddress, *whichBreak->breakAddress,
|
||||
whichBreak->oldInstruction));
|
||||
}
|
||||
|
||||
/* Send reply */
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->object;
|
||||
reply.bp = whichBreak - breakBase;
|
||||
reply.instruction = whichBreak->oldInstruction;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonListBreak(KKHeader* request UNUSED) {
|
||||
STUBBED_PRINTF(("ListBreak\n"));
|
||||
|
||||
return TV_ERROR_ILLEGAL_CALL;
|
||||
}
|
||||
|
||||
int __rmonClearBreak(KKHeader* req) {
|
||||
register KKClrBkptRequest* request = (KKClrBkptRequest*) req;
|
||||
register BREAKINFO* whichBreak;
|
||||
KKBkptEvent reply;
|
||||
u32 inst;
|
||||
|
||||
STUBBED_PRINTF(("ClearBreak\n"));
|
||||
|
||||
/* Check valid breakpoint index */
|
||||
if (request->bp >= NUM_BREAKPOINTS) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
/* Clear the breakpoint, restore whatever was there before */
|
||||
if (req->method == RMON_RSP) {
|
||||
whichBreak = &RCPbreakpoints[request->bp];
|
||||
|
||||
if (whichBreak->breakAddress == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
inst = __rmonReadWordAt(whichBreak->breakAddress);
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
__rmonWriteWordTo(whichBreak->breakAddress, whichBreak->oldInstruction);
|
||||
}
|
||||
} else {
|
||||
whichBreak = &breakpoints[request->bp];
|
||||
|
||||
if (whichBreak->breakAddress == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
inst = *whichBreak->breakAddress;
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
*whichBreak->breakAddress = whichBreak->oldInstruction;
|
||||
osWritebackDCache(whichBreak->breakAddress, sizeof(*whichBreak->breakAddress));
|
||||
osInvalICache(whichBreak->breakAddress, sizeof(*whichBreak->breakAddress));
|
||||
}
|
||||
}
|
||||
whichBreak->breakAddress = NULL;
|
||||
|
||||
/* Send reply */
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->object;
|
||||
reply.bp = request->bp;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
u32 __rmonGetBranchTarget(int method, int thread, char* addr) {
|
||||
int inst;
|
||||
|
||||
if (method == RMON_RSP) {
|
||||
inst = __rmonReadWordAt((u32*) addr);
|
||||
} else {
|
||||
inst = *(u32*) addr;
|
||||
}
|
||||
|
||||
switch ((inst >> 26) & 0x3F) {
|
||||
case 0: /* SPECIAL */
|
||||
if (((inst >> 5) & 0x7FFF) == 0 && (inst & 0x3F) == 8) {
|
||||
/* JR */
|
||||
return __rmonGetRegisterContents(method, thread, (inst >> 21) & 0x1F);
|
||||
}
|
||||
if (((inst >> 16) & 0x1F) == 0 && (inst & 0x7FF) == 9) {
|
||||
/* JALR */
|
||||
return __rmonGetRegisterContents(method, thread, (inst >> 21) & 0x1F);
|
||||
}
|
||||
break;
|
||||
case 1: /* REGIMM */
|
||||
switch ((inst >> 16) & 0x1F) {
|
||||
case 0: /* BLTZ */
|
||||
case 1: /* BGEZ */
|
||||
case 2: /* BLTZL */
|
||||
case 3: /* BGEZL */
|
||||
case 16: /* BLTZAL */
|
||||
case 17: /* BGEZAL */
|
||||
case 18: /* BLTZALL */
|
||||
case 19: /* BGEZALL */
|
||||
return (((inst << 0x10) >> 0xE) + addr + 4);
|
||||
}
|
||||
break;
|
||||
case 2: /* J */
|
||||
case 3: /* JAL */
|
||||
return (((u32) inst << 6) >> 4) + (((s32) ((u32) addr + 4) >> 0x1C) << 0x1C);
|
||||
case 4: /* BEQ */
|
||||
case 5: /* BNE */
|
||||
case 20: /* BEQL */
|
||||
case 21: /* BNEL */
|
||||
return (((inst << 0x10) >> 0xE) + addr + 4);
|
||||
case 6: /* BLEZ */
|
||||
case 7: /* BGTZ */
|
||||
case 22: /* BLEZL */
|
||||
case 23: /* BGTZL */
|
||||
if (((inst >> 16) & 0x1F) == 0) {
|
||||
return (((inst << 0x10) >> 0xE) + addr + 4);
|
||||
}
|
||||
break;
|
||||
case 16: /* COP0 */
|
||||
case 17: /* COP1 */
|
||||
case 18: /* COP2 */
|
||||
case 19: /* COP3 */
|
||||
if (((inst >> 21) & 0x1F) == 8) {
|
||||
switch ((inst >> 16) & 0x1F) {
|
||||
case 0: /* BCzF */
|
||||
case 1: /* BCzT */
|
||||
case 2: /* BCzFL */
|
||||
case 3: /* BCzTL */
|
||||
return (((inst << 0x10) >> 0xE) + addr + 4);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int IsJump(u32 inst) {
|
||||
switch ((inst >> 26) & 0x3F) {
|
||||
case 0: /* SPECIAL */
|
||||
if (((inst >> 5) & 0x7FFF) == 0 && (inst & 0x3F) == 8) {
|
||||
/* JR */
|
||||
return TRUE;
|
||||
}
|
||||
if (((inst >> 16) & 0x1F) == 0 && (inst & 0x7FF) == 9) {
|
||||
/* JALR */
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case 2: /* J */
|
||||
case 3: /* JAL */
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
int __rmonSetSingleStep(int thread, u32* instptr) {
|
||||
u32 branchTarget = __rmonGetBranchTarget(RMON_CPU, thread, (void*) instptr);
|
||||
|
||||
STUBBED_PRINTF(("SingleStep\n"));
|
||||
|
||||
if ((branchTarget & 3) != 0) {
|
||||
/* no branch target, set breakpoint at next pc */
|
||||
SetTempBreakpoint(instptr + 1, NULL);
|
||||
} else if (branchTarget == (u32) instptr) {
|
||||
/* branch target is this instruction, can't single step here */
|
||||
return FALSE;
|
||||
} else if (IsJump(*instptr) || branchTarget == (u32) (instptr + 2)) {
|
||||
/* unconditional branch, set at branch target */
|
||||
SetTempBreakpoint((u32*) branchTarget, NULL);
|
||||
} else {
|
||||
/* set two breakpoints for handling conditional branches */
|
||||
SetTempBreakpoint((u32*) branchTarget, instptr + 2);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void __rmonGetExceptionStatus(KKStatusEvent* reply) {
|
||||
reply->status.flags = OS_STATE_STOPPED;
|
||||
reply->status.why = 2;
|
||||
reply->status.what = 0;
|
||||
reply->status.rv = 0;
|
||||
reply->status.info.major = 2;
|
||||
reply->status.info.minor = 4;
|
||||
reply->header.code = KK_CODE_THREAD_STATUS;
|
||||
reply->header.error = TV_ERROR_NO_ERROR;
|
||||
reply->header.length = sizeof(*reply);
|
||||
}
|
||||
|
||||
#define FAULT_BREAKNUM (NUM_BREAKPOINTS - 1)
|
||||
|
||||
void rmonSendBreakMessage(s32 whichThread, int breakNumber) {
|
||||
KKStatusEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("Break %d in thread %d\n", breakNumber, whichThread));
|
||||
|
||||
/* Build thread exception status */
|
||||
__rmonGetThreadStatus(RMON_CPU, (whichThread != 0) ? whichThread : RMON_TID_NOTHREAD, &reply);
|
||||
__rmonGetExceptionStatus(&reply);
|
||||
|
||||
if (breakNumber == FAULT_BREAKNUM) {
|
||||
/* Hit fault */
|
||||
reply.status.info.major = 1;
|
||||
reply.status.info.minor = 2;
|
||||
}
|
||||
if (breakNumber < NUM_BREAKPOINTS) {
|
||||
breakNumber = 0;
|
||||
} else {
|
||||
breakNumber -= NUM_BREAKPOINTS;
|
||||
}
|
||||
if (breakNumber != 0) {
|
||||
/* Break not set by debugger, or set during single-step */
|
||||
reply.status.instr = MIPS_BREAK_OPCODE;
|
||||
}
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_EXCEPTION);
|
||||
}
|
||||
|
||||
void __rmonHitBreak(void) {
|
||||
STUBBED_PRINTF(("HitBreak\n"));
|
||||
|
||||
/* Stop all user threads and report faulted threads */
|
||||
ClearTempBreakpoint();
|
||||
__rmonStopUserThreads(0);
|
||||
rmonFindFaultedThreads();
|
||||
}
|
||||
|
||||
void __rmonHitSpBreak(void) {
|
||||
KKStatusEvent exceptionReply;
|
||||
|
||||
STUBBED_PRINTF(("Hit SP Break\n"));
|
||||
|
||||
/* Rewind RSP PC by one instruction to return to the location of the break instruction */
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, __rmonReadWordAt((u32*) SP_PC_REG) - 4);
|
||||
|
||||
/* Report RSP break event */
|
||||
__rmonGetThreadStatus(RMON_RSP, RMON_TID_RSP, &exceptionReply);
|
||||
__rmonGetExceptionStatus(&exceptionReply);
|
||||
__rmonSendReply(&exceptionReply.header, sizeof(exceptionReply), KK_TYPE_EXCEPTION);
|
||||
__rmonRcpAtBreak = TRUE;
|
||||
}
|
||||
|
||||
void __rmonHitCpuFault(void) {
|
||||
STUBBED_PRINTF(("HitCpuFault\n"));
|
||||
|
||||
/* Stop all user threads and report faulted threads */
|
||||
__rmonMaskIdleThreadInts();
|
||||
__rmonStopUserThreads(0);
|
||||
rmonFindFaultedThreads();
|
||||
}
|
||||
|
||||
void rmonFindFaultedThreads(void) {
|
||||
register OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->priority > OS_PRIORITY_IDLE && tptr->priority <= OS_PRIORITY_APPMAX) {
|
||||
if (tptr->flags & OS_FLAG_CPU_BREAK) {
|
||||
int inst = *(u32*) tptr->context.pc;
|
||||
|
||||
STUBBED_PRINTF(("Brk in thread %d @ %08x, inst %08x\r\n", tptr->id, tptr->context.pc, inst));
|
||||
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
rmonSendBreakMessage(tptr->id, inst >> 6);
|
||||
} else {
|
||||
rmonSendBreakMessage(tptr->id, 0);
|
||||
}
|
||||
}
|
||||
if (tptr->flags & OS_FLAG_FAULT) {
|
||||
__rmonSendFault(tptr);
|
||||
rmonSendBreakMessage(tptr->id, FAULT_BREAKNUM);
|
||||
}
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,54 @@
|
||||
#include "common.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmoncmds/__rmoncmd_NotImplemented.s")
|
||||
#include "dbgproto.h"
|
||||
#include "rmonint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmoncmds/__rmonExecute.s")
|
||||
#include "macros.h"
|
||||
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#else
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
static int NotImplemented(KKHeader* dummy UNUSED) {
|
||||
return TV_ERROR_ILLEGAL_CALL;
|
||||
}
|
||||
|
||||
static FUNPTR dispatchTable[] = {
|
||||
__rmonLoadProgram, __rmonListProcesses, __rmonGetExeName, __rmonListThreads, __rmonThreadStatus,
|
||||
NotImplemented, __rmonStopThread, __rmonRunThread, NotImplemented, NotImplemented,
|
||||
__rmonSetFault, NotImplemented, __rmonGetRegionCount, __rmonGetRegions, __rmonGetGRegisters,
|
||||
__rmonSetGRegisters, __rmonGetFRegisters, __rmonSetFRegisters, __rmonReadMem, __rmonWriteMem,
|
||||
__rmonSetBreak, __rmonClearBreak, __rmonListBreak, NotImplemented, NotImplemented,
|
||||
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
|
||||
__rmonSetComm, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
|
||||
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
|
||||
NotImplemented, NotImplemented, NotImplemented, NotImplemented, NotImplemented,
|
||||
NotImplemented, NotImplemented, NotImplemented, NotImplemented, __rmonGetSRegs,
|
||||
__rmonSetSRegs, __rmonGetVRegs, __rmonSetVRegs, NotImplemented,
|
||||
};
|
||||
|
||||
int __rmonExecute(KKHeader* request) {
|
||||
int retval;
|
||||
KKHeader reply;
|
||||
|
||||
if (request->code >= ARRLEN(dispatchTable) - 1) {
|
||||
return TV_ERROR_ILLEGAL_CALL;
|
||||
}
|
||||
|
||||
retval = dispatchTable[(int) request->code](request);
|
||||
if (retval < TV_ERROR_NO_ERROR) {
|
||||
reply.code = request->code;
|
||||
reply.error = retval;
|
||||
__rmonSendReply(&reply, sizeof(reply), KK_TYPE_REPLY);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,138 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_version.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmain/__rmonSendHeader.s")
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmain/__rmonSendReply.s")
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmain/__rmonSendData.s")
|
||||
#include "dbgproto.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "rmonint.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "PR/rdb.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmain/rmonMain.s")
|
||||
#include "macros.h"
|
||||
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#endif
|
||||
|
||||
int __rmonActive = FALSE;
|
||||
|
||||
static vu32 somethingToDo;
|
||||
static u32 inbuffer[280] ALIGNED(0x10);
|
||||
static u8 cmdinptr;
|
||||
static u8 cmdoutptr;
|
||||
static int state;
|
||||
static char* inPointer;
|
||||
|
||||
void __rmonSendHeader(KKHeader* const block, u32 blockSize, u32 type) {
|
||||
int sent;
|
||||
char* cPtr = (char*) block;
|
||||
|
||||
block->rev = KK_REV;
|
||||
block->type = type;
|
||||
|
||||
sent = 0;
|
||||
while (sent < blockSize) {
|
||||
sent += __osRdbSend(cPtr + sent, blockSize - sent, RDB_TYPE_GtoH_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
void __rmonSendReply(KKHeader* const block, u32 blockSize, u32 replyType) {
|
||||
char* cPtr;
|
||||
int sent = 0;
|
||||
|
||||
block->length = blockSize;
|
||||
cPtr = (char*) &blockSize;
|
||||
|
||||
/* send size */
|
||||
while (sent < (signed) sizeof(blockSize)) {
|
||||
sent += __osRdbSend(cPtr + sent, sizeof(blockSize) - sent, RDB_TYPE_GtoH_DEBUG);
|
||||
}
|
||||
|
||||
/* send data */
|
||||
__rmonSendHeader(block, blockSize, replyType);
|
||||
__rmonIOflush();
|
||||
}
|
||||
|
||||
void __rmonSendData(char* const block, unsigned int blockSize) {
|
||||
int* blockPointer = (int*) block;
|
||||
unsigned int wordCount = (u32) (blockSize + 3) / 4;
|
||||
u32 data;
|
||||
union {
|
||||
char bufBytes[4];
|
||||
u32 bufWord;
|
||||
} buffer;
|
||||
|
||||
if (((u32) block & 3) == 0) {
|
||||
while (wordCount--) {
|
||||
if ((u32) blockPointer >= SP_DMEM_START && (u32) blockPointer < 0x05000000) {
|
||||
__osSpRawReadIo((u32) blockPointer++, &data);
|
||||
__rmonIOputw(data);
|
||||
} else {
|
||||
__rmonIOputw(*(blockPointer++));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (wordCount--) {
|
||||
__rmonMemcpy((u8*) buffer.bufBytes, (u8*) blockPointer, sizeof(buffer));
|
||||
__rmonIOputw(buffer.bufWord);
|
||||
blockPointer++;
|
||||
}
|
||||
}
|
||||
__rmonIOflush();
|
||||
}
|
||||
|
||||
void rmonMain(void) {
|
||||
register int newChars UNUSED;
|
||||
|
||||
STUBBED_PRINTF(("rmon: Thread %d created\n"));
|
||||
STUBBED_PRINTF(("rmon: Thread %d destroyed\n"));
|
||||
|
||||
somethingToDo = 0;
|
||||
cmdoutptr = 0;
|
||||
cmdinptr = 0;
|
||||
|
||||
__rmonInit();
|
||||
__rmonActive = TRUE;
|
||||
|
||||
state = 0, newChars = 0, inPointer = (void*) &inbuffer;
|
||||
for (;;) {
|
||||
OSMesg work;
|
||||
|
||||
osRecvMesg(&__rmonMQ, &work, OS_MESG_BLOCK);
|
||||
|
||||
somethingToDo |= (u32) work;
|
||||
|
||||
if (somethingToDo & RMON_MESG_CPU_BREAK) {
|
||||
somethingToDo &= ~RMON_MESG_CPU_BREAK;
|
||||
__rmonHitBreak();
|
||||
}
|
||||
if (somethingToDo & RMON_MESG_SP_BREAK) {
|
||||
somethingToDo &= ~RMON_MESG_SP_BREAK;
|
||||
__rmonHitSpBreak();
|
||||
}
|
||||
if (somethingToDo & RMON_MESG_FAULT) {
|
||||
somethingToDo &= ~RMON_MESG_FAULT;
|
||||
__rmonHitCpuFault();
|
||||
}
|
||||
if (somethingToDo & 0x10) {
|
||||
somethingToDo;
|
||||
somethingToDo &= (u8) ~0x10;
|
||||
}
|
||||
if (somethingToDo & 0x20) {
|
||||
somethingToDo;
|
||||
somethingToDo &= (u8) ~0x20;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+270
-16
@@ -1,31 +1,285 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_version.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonWriteWordTo.s")
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonReadWordAt.s")
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonMemcpy.s")
|
||||
#include "dbgproto.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "rmonint.h"
|
||||
#include "PR/rdb.h"
|
||||
|
||||
void __rmonCopyWords(s32* arg0, s32* arg1, s32 arg2) {
|
||||
while (arg2--) {
|
||||
*arg0++ = *arg1++;
|
||||
#include "macros.h"
|
||||
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#endif
|
||||
|
||||
u8 __rmonUtilityBuffer[256] ALIGNED(8);
|
||||
|
||||
void __rmonWriteWordTo(u32* addr, u32 val) {
|
||||
while (__osSpRawWriteIo((u32) addr, val) != 0) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonmem_strcopy.s")
|
||||
u32 __rmonReadWordAt(u32* addr) {
|
||||
u32 data;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonReadMem.s")
|
||||
if ((u32) addr >= SP_DMEM_START && (u32) addr < 0x05000000) {
|
||||
__osSpRawReadIo((u32) addr, &data);
|
||||
return data;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonWriteMem.s")
|
||||
void __rmonMemcpy(u8* dest, u8* srce, u32 count) {
|
||||
while (count--) {
|
||||
*dest++ = *srce++;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonListProcesses.s")
|
||||
void __rmonCopyWords(u32* dest, u32* srce, u32 count) {
|
||||
while (count--) {
|
||||
*dest++ = *srce++;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonLoadProgram.s")
|
||||
static void strcpy(char* dest, char* srce) {
|
||||
while ((*dest++ = *srce++)) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/D_800C9660.s")
|
||||
int __rmonReadMem(KKHeader* req) {
|
||||
char* cPtr;
|
||||
int sent;
|
||||
int dataSize;
|
||||
KKReadRequest* request = (KKReadRequest*) req;
|
||||
KKBufferEvent* reply = (KKBufferEvent*) __rmonUtilityBuffer;
|
||||
u8* blockStart;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonGetExeName.s")
|
||||
STUBBED_PRINTF(("ReadMem @ %08x for %d\n", request->addr, request->nbytes));
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonGetRegionCount.s")
|
||||
reply->header.code = request->header.code;
|
||||
reply->object = request->object;
|
||||
reply->header.error = TV_ERROR_NO_ERROR;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmem/__rmonGetRegions.s")
|
||||
if (request->addr == (u32) -1) {
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
if (request->nbytes > RMON_MAX_XFER_SIZE) {
|
||||
return TV_ERROR_INVALID_CAPABILITY;
|
||||
}
|
||||
|
||||
if (req->method == RMON_RSP) {
|
||||
if (!((request->addr < SP_IMEM_START || (request->addr + request->nbytes) > SP_IMEM_END) ? FALSE : TRUE) &&
|
||||
!((request->addr < SP_DMEM_START || (request->addr + request->nbytes) > SP_DMEM_END) ? FALSE : TRUE)) {
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
} else if (osVirtualToPhysical((void*) request->addr) == (u32) -1) {
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
blockStart = (u8*) request->addr;
|
||||
reply->header.length = request->nbytes + sizeof(reply->header) + sizeof(reply->object);
|
||||
dataSize = request->nbytes + sizeof(reply->header) + sizeof(reply->object);
|
||||
|
||||
cPtr = (char*) &dataSize;
|
||||
sent = 0;
|
||||
while (sent < (signed) sizeof(dataSize)) {
|
||||
sent += __osRdbSend(cPtr + sent, sizeof(dataSize) - sent, RDB_TYPE_GtoH_DEBUG);
|
||||
}
|
||||
|
||||
__rmonSendHeader(&reply->header, sizeof(reply->header) + sizeof(reply->object), KK_TYPE_REPLY);
|
||||
__rmonSendData(blockStart, request->nbytes);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonWriteMem(KKHeader* req) {
|
||||
register KKWriteRequest* request = (KKWriteRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("WriteMem\n"));
|
||||
|
||||
/* Bad virtual address, abort */
|
||||
if (req->method == RMON_CPU && osVirtualToPhysical((u32*) request->writeHeader.addr) == (u32) -1) {
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
/* Transfer size too large, abort */
|
||||
if (request->writeHeader.nbytes > RMON_MAX_XFER_SIZE) {
|
||||
return TV_ERROR_INVALID_CAPABILITY;
|
||||
}
|
||||
|
||||
if (((request->writeHeader.addr < SP_DMEM_START ||
|
||||
(request->writeHeader.addr + request->writeHeader.nbytes) > 0x04FFFFFF)
|
||||
? FALSE
|
||||
: TRUE)) {
|
||||
int align;
|
||||
u32 word;
|
||||
|
||||
if ((align = request->writeHeader.addr & 3) != 0) {
|
||||
STUBBED_PRINTF(("Long unaligned write...\n"));
|
||||
|
||||
if (request->writeHeader.nbytes != 1) {
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
/* Unaligned write; read the word, substitute in the written byte, write it back */
|
||||
word = __rmonReadWordAt((u32*) (request->writeHeader.addr & ~3));
|
||||
if (align == 1) {
|
||||
word = (word & ~0xFF0000) | (request->buffer[0] << 0x10);
|
||||
} else if (align == 2) {
|
||||
word = (word & ~0xFF00) | (request->buffer[0] << 8);
|
||||
} else {
|
||||
word = (word & ~0xFF) | (request->buffer[0] << 0);
|
||||
}
|
||||
__rmonWriteWordTo((u32*) (request->writeHeader.addr & ~3), word);
|
||||
} else {
|
||||
int wordCount = request->writeHeader.nbytes / sizeof(u32);
|
||||
u32* wordPointer = (u32*) request->buffer;
|
||||
|
||||
if (request->writeHeader.nbytes % sizeof(u32) != 0) {
|
||||
STUBBED_PRINTF(("RCP write not an integral number of words\n"));
|
||||
return TV_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
while (wordCount--) {
|
||||
__rmonWriteWordTo((u32*) request->writeHeader.addr, *(wordPointer++));
|
||||
request->writeHeader.addr += sizeof(*wordPointer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
__rmonMemcpy((u8*) request->writeHeader.addr, (u8*) request->buffer, request->writeHeader.nbytes);
|
||||
}
|
||||
|
||||
reply.header.code = request->writeHeader.header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->writeHeader.object;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonListProcesses(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKObjsEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("ListProcesses\n"));
|
||||
|
||||
reply.object = 0;
|
||||
reply.objs.number = 1;
|
||||
reply.objs.objects[0] = (req->method == RMON_RSP) ? RMON_PID_RSP : RMON_PID_CPU;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonLoadProgram(KKHeader* request UNUSED) {
|
||||
STUBBED_PRINTF(("LoadProgram\n"));
|
||||
|
||||
return TV_ERROR_ILLEGAL_CALL;
|
||||
}
|
||||
|
||||
int __rmonGetExeName(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKBufferEvent* reply = (KKBufferEvent*) __rmonUtilityBuffer;
|
||||
|
||||
STUBBED_PRINTF(("GetExeName\n"));
|
||||
|
||||
reply->header.code = request->header.code;
|
||||
reply->header.error = TV_ERROR_NO_ERROR;
|
||||
reply->object = request->object;
|
||||
|
||||
if (req->method == RMON_RSP) {
|
||||
strcpy(reply->buffer, "imem");
|
||||
} else {
|
||||
strcpy(reply->buffer, "rmon");
|
||||
}
|
||||
__rmonSendReply(&reply->header, sizeof(reply->header) + sizeof(reply->object) + 8, KK_TYPE_REPLY);
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonGetRegionCount(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKNumberEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("GetRegionCount\n"));
|
||||
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->object;
|
||||
|
||||
reply.number = (req->method == RMON_RSP) ? 2 : 5;
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonGetRegions(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKRegionEvent* reply = (KKRegionEvent*) __rmonUtilityBuffer;
|
||||
int numRegions;
|
||||
|
||||
STUBBED_PRINTF(("GetRegions\n"));
|
||||
|
||||
numRegions = (req->method == RMON_RSP) ? 2 : 6;
|
||||
|
||||
reply->header.length = numRegions * sizeof(reply->regions[0]) + sizeof(*reply);
|
||||
reply->header.code = request->header.code;
|
||||
reply->header.error = TV_ERROR_NO_ERROR;
|
||||
reply->object = request->object;
|
||||
reply->number = numRegions;
|
||||
|
||||
reply->regions[1].vaddr = SP_IMEM_START;
|
||||
reply->regions[1].size = SP_IMEM_END + 1 - SP_IMEM_START;
|
||||
reply->regions[1].flags = 1 | 2 | 4;
|
||||
reply->regions[1].paddr = SP_IMEM_START;
|
||||
|
||||
reply->regions[0].vaddr = SP_DMEM_START;
|
||||
reply->regions[0].size = SP_DMEM_END + 1 - SP_DMEM_START;
|
||||
reply->regions[0].flags = 1 | 2;
|
||||
reply->regions[0].paddr = SP_DMEM_START;
|
||||
|
||||
if (numRegions > 2) {
|
||||
reply->regions[2].vaddr = 0x88200000;
|
||||
reply->regions[2].size = 0x6130;
|
||||
reply->regions[2].flags = 1 | 4;
|
||||
reply->regions[2].paddr = 0;
|
||||
|
||||
reply->regions[3].vaddr = 4;
|
||||
reply->regions[3].size = 0x200000;
|
||||
reply->regions[3].flags = 1 | 2;
|
||||
reply->regions[3].paddr = 0;
|
||||
|
||||
reply->regions[4].vaddr = 0x4002000;
|
||||
reply->regions[4].size = 0x800000;
|
||||
reply->regions[4].flags = 1 | 2;
|
||||
reply->regions[4].paddr = 0;
|
||||
|
||||
reply->regions[5].vaddr = 0x88206130;
|
||||
reply->regions[5].size = 0x9000;
|
||||
reply->regions[5].flags = 1 | 2;
|
||||
reply->regions[5].paddr = 0;
|
||||
}
|
||||
|
||||
__rmonSendReply(&reply->header, reply->header.length, KK_TYPE_REPLY);
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,15 +1,69 @@
|
||||
#include "global.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#include "dbgproto.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "rmonint.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmisc/__rmonSetFault.s")
|
||||
#include "macros.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmisc/__rmonInit.s")
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#else
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmisc/__rmonPanic.s")
|
||||
int __rmonSetFault(KKHeader* req) {
|
||||
KKFaultRequest* request = (KKFaultRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("SetFault\n"));
|
||||
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->tid;
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
OSMesgQueue __rmonMQ ALIGNED(8);
|
||||
static OSThread rmonIOThread ALIGNED(8);
|
||||
static OSMesg rmonMsgs[8] ALIGNED(8);
|
||||
static u64 rmonIOStack[2048] ALIGNED(16);
|
||||
static OSMesg rmonPiMsgs[8] ALIGNED(8);
|
||||
static OSMesgQueue rmonPiMQ ALIGNED(8);
|
||||
|
||||
void __rmonInit(void) {
|
||||
osCreateMesgQueue(&__rmonMQ, rmonMsgs, ARRLEN(rmonMsgs));
|
||||
osSetEventMesg(OS_EVENT_CPU_BREAK, &__rmonMQ, (OSMesg) RMON_MESG_CPU_BREAK);
|
||||
osSetEventMesg(OS_EVENT_SP_BREAK, &__rmonMQ, (OSMesg) RMON_MESG_SP_BREAK);
|
||||
osSetEventMesg(OS_EVENT_FAULT, &__rmonMQ, (OSMesg) RMON_MESG_FAULT);
|
||||
osSetEventMesg(OS_EVENT_THREADSTATUS, &__rmonMQ, NULL);
|
||||
osCreateThread(&rmonIOThread, 0, (void (*)(void*)) __rmonIOhandler, NULL, rmonIOStack + ARRLEN(rmonIOStack),
|
||||
OS_PRIORITY_MAX);
|
||||
osCreatePiManager(OS_PRIORITY_PIMGR, &rmonPiMQ, rmonPiMsgs, ARRLEN(rmonPiMsgs));
|
||||
osStartThread(&rmonIOThread);
|
||||
}
|
||||
|
||||
void __rmonPanic(void) {
|
||||
STUBBED_PRINTF(("PANIC!!\n"));
|
||||
|
||||
for (;;) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
int __rmonSetComm(KKHeader* req) {
|
||||
KKObjectEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("SetComm\n"));
|
||||
|
||||
reply.header.code = req->code;
|
||||
reply.object = 0;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
@@ -19,4 +73,4 @@ int __rmonSetComm(KKHeader* req) {
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonmisc/D_800C97D0.s")
|
||||
#endif
|
||||
|
||||
+399
-30
@@ -1,48 +1,417 @@
|
||||
#include "global.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#include "dbgproto.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "rmonint.h"
|
||||
#include "PR/rdb.h"
|
||||
#include "PR/os_version.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonregs_LoadStoreSU.s")
|
||||
#include "macros.h"
|
||||
|
||||
void __rmonregs_LoadStoreSU(int opcode, int regno);
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/LoadStoreVU.s")
|
||||
// TODO: these come from headers
|
||||
#if BUILD_VERSION >= VERSION_K
|
||||
#ident "$Revision: 1.4 $"
|
||||
// This revision was bumped down at K for some reason
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#elif BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 3.71 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#else
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
void SetUpForRCPop(int isVector);
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/SetUpForRCPop.s")
|
||||
static u32 RCPpc;
|
||||
static u32 oldIMEMvalue;
|
||||
static u32 DMEMbuffer[4] ALIGNED(8);
|
||||
|
||||
void CleanupFromRCPop(int isVector);
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/CleanupFromRCPop.s")
|
||||
typedef union {
|
||||
u32 everything;
|
||||
struct {
|
||||
int opcode : 6;
|
||||
int base : 5;
|
||||
int rt : 5;
|
||||
int offset : 16;
|
||||
} scalarop;
|
||||
struct {
|
||||
int opcode : 6;
|
||||
int base : 5;
|
||||
int rt : 5;
|
||||
int size : 5;
|
||||
int element : 4;
|
||||
int offset : 7;
|
||||
} vectorop;
|
||||
} INSTRUCTION;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonGetGRegisters.s")
|
||||
void LoadStoreSU(int opcode, int regno) {
|
||||
INSTRUCTION inst;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonSetGRegisters.s")
|
||||
/* Prepare a scalar load or store instruction at DMEM address 0 */
|
||||
inst.everything = 0;
|
||||
inst.scalarop.opcode = opcode;
|
||||
inst.scalarop.rt = regno;
|
||||
__rmonWriteWordTo((u32*) SP_IMEM_START, inst.everything);
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, 0);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonGetFRegisters.s")
|
||||
void LoadStoreVU(int opcode, int regno) {
|
||||
INSTRUCTION inst;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonSetFRegisters.s")
|
||||
/* Prepare a vector 128-bit load or store instruction at DMEM address 0 */
|
||||
inst.everything = 0;
|
||||
inst.vectorop.opcode = opcode;
|
||||
inst.vectorop.rt = regno;
|
||||
inst.vectorop.size = 4; /* LQV / SQV */
|
||||
__rmonWriteWordTo((u32*) SP_IMEM_START, inst.everything);
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, 0);
|
||||
}
|
||||
|
||||
s32 rmonGetRcpRegister(s32 arg0) {
|
||||
s32 ret;
|
||||
|
||||
if (__rmonRCPrunning() != 0) {
|
||||
return 0;
|
||||
} else {
|
||||
SetUpForRCPop(0);
|
||||
__rmonregs_LoadStoreSU(0x2B, arg0);
|
||||
__rmonStepRCP();
|
||||
ret = __rmonReadWordAt((u32*) SP_DMEM_START);
|
||||
CleanupFromRCPop(0);
|
||||
return ret;
|
||||
void SetUpForRCPop(int isVector) {
|
||||
/* Save RSP data that would be overwritten when reading or writing registers */
|
||||
RCPpc = __rmonReadWordAt((u32*) SP_PC_REG);
|
||||
oldIMEMvalue = __rmonReadWordAt((u32*) SP_IMEM_START);
|
||||
DMEMbuffer[0] = __rmonReadWordAt((u32*) SP_DMEM_START);
|
||||
if (isVector) {
|
||||
DMEMbuffer[1] = __rmonReadWordAt((u32*) (SP_DMEM_START + 0x4));
|
||||
DMEMbuffer[2] = __rmonReadWordAt((u32*) (SP_DMEM_START + 0x8));
|
||||
DMEMbuffer[3] = __rmonReadWordAt((u32*) (SP_DMEM_START + 0xC));
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonGetSRegs.s")
|
||||
void CleanupFromRCPop(int isVector) {
|
||||
/* Restore RSP data that was saved to read or write registers */
|
||||
__rmonWriteWordTo((u32*) SP_DMEM_START, DMEMbuffer[0]);
|
||||
if (isVector) {
|
||||
__rmonWriteWordTo((u32*) (SP_DMEM_START + 0x4), DMEMbuffer[1]);
|
||||
__rmonWriteWordTo((u32*) (SP_DMEM_START + 0x8), DMEMbuffer[2]);
|
||||
/* BUG: the last word is not restored properly */
|
||||
__rmonWriteWordTo((u32*) (SP_DMEM_START + 0xC), DMEMbuffer[2]);
|
||||
}
|
||||
__rmonWriteWordTo((u32*) SP_IMEM_START, oldIMEMvalue);
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, RCPpc);
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonSetSRegs.s")
|
||||
int __rmonGetGRegisters(KKHeader* req) {
|
||||
register KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKGregEvent reply;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonGetVRegs.s")
|
||||
STUBBED_PRINTF(("GetGRegisters\n"));
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonSetVRegs.s")
|
||||
reply.tid = request->object;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/__rmonGetRegisterContents.s")
|
||||
if (request->header.method == RMON_CPU) {
|
||||
OSThread* tptr = __rmonGetTCB(request->object);
|
||||
u64* tcbregptr;
|
||||
register s32 i;
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonregs/D_800C9800.s")
|
||||
if (tptr == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
for (i = GREG_IDX_AT, tcbregptr = &tptr->context.at; i < GREG_IDX_K0; i++, tcbregptr++) {
|
||||
reply.registers.gregs[i] = *tcbregptr;
|
||||
}
|
||||
for (i = GREG_IDX_GP, tcbregptr = &tptr->context.gp; i < GREG_IDX_CAUSE; i++, tcbregptr++) {
|
||||
reply.registers.gregs[i] = *tcbregptr;
|
||||
}
|
||||
|
||||
reply.registers.gregs[GREG_IDX_CAUSE] = tptr->context.cause;
|
||||
reply.registers.gregs[GREG_IDX_PC] = tptr->context.pc;
|
||||
reply.registers.gregs[GREG_IDX_SR] = tptr->context.sr;
|
||||
reply.registers.gregs[GREG_IDX_ZERO] = 0;
|
||||
} else {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonSetGRegisters(KKHeader* req) {
|
||||
register KKGRegsetRequest* request = (KKGRegsetRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
|
||||
STUBBED_PRINTF(("SetGRegisters\n"));
|
||||
|
||||
if (request->header.method == RMON_CPU) {
|
||||
OSThread* tptr = __rmonGetTCB(request->tid);
|
||||
u64* tcbregptr;
|
||||
register int i;
|
||||
|
||||
if (tptr == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
for (i = GREG_IDX_AT, tcbregptr = &tptr->context.at; i < GREG_IDX_K0; i++, tcbregptr++) {
|
||||
*tcbregptr = (s32) request->registers.gregs[i];
|
||||
}
|
||||
|
||||
for (i = GREG_IDX_GP, tcbregptr = &tptr->context.gp; i < GREG_IDX_CAUSE; i++, tcbregptr++) {
|
||||
*tcbregptr = (s32) request->registers.gregs[i];
|
||||
}
|
||||
|
||||
tptr->context.cause = request->registers.gregs[GREG_IDX_CAUSE];
|
||||
tptr->context.pc = request->registers.gregs[GREG_IDX_PC];
|
||||
tptr->context.sr = request->registers.gregs[GREG_IDX_SR];
|
||||
} else {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
reply.object = request->tid;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonGetFRegisters(KKHeader* req) {
|
||||
register KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKFPregEvent reply;
|
||||
OSThread* tptr;
|
||||
volatile float f UNUSED;
|
||||
|
||||
STUBBED_PRINTF(("GetFRegisters\n"));
|
||||
|
||||
if (req->method != RMON_CPU) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
/* touch fpu to ensure registers are saved to the context structure */
|
||||
f = 0.0f;
|
||||
|
||||
tptr = __rmonGetTCB(request->object);
|
||||
if (tptr == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
__rmonCopyWords((u32*) reply.registers.fpregs.regs, (u32*) &tptr->context.fp0, ARRLEN(reply.registers.fpregs.regs));
|
||||
|
||||
reply.registers.fpcsr = tptr->context.fpcsr;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.tid = request->object;
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonSetFRegisters(KKHeader* req) {
|
||||
register KKFPRegsetRequest* request = (KKFPRegsetRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
OSThread* tptr;
|
||||
volatile float f UNUSED;
|
||||
|
||||
STUBBED_PRINTF(("SetFRegisters\n"));
|
||||
|
||||
if (req->method != RMON_CPU) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
/* touch fpu to ensure registers are saved to the context structure */
|
||||
f = 0.0f;
|
||||
|
||||
tptr = __rmonGetTCB(request->tid);
|
||||
if (tptr == NULL) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
__rmonCopyWords((u32*) &tptr->context.fp0, (u32*) request->registers.fpregs.regs,
|
||||
ARRLEN(request->registers.fpregs.regs));
|
||||
tptr->context.fpcsr = request->registers.fpcsr;
|
||||
|
||||
reply.object = request->tid;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
u32 rmonGetRcpRegister(int regNumber) {
|
||||
u32 contents;
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
SetUpForRCPop(FALSE);
|
||||
LoadStoreSU(MIPS_SW_OPCODE, regNumber);
|
||||
__rmonStepRCP();
|
||||
contents = __rmonReadWordAt((u32*) SP_DMEM_START);
|
||||
CleanupFromRCPop(FALSE);
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
int __rmonGetSRegs(KKHeader* req) {
|
||||
register KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKCpSregEvent reply;
|
||||
register int i;
|
||||
|
||||
STUBBED_PRINTF(("GetSRegisters\n"));
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
reply.tid = request->object;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
|
||||
SetUpForRCPop(FALSE);
|
||||
for (i = SREG_IDX_ZERO; i <= SREG_IDX_RA; i++) {
|
||||
LoadStoreSU(MIPS_SW_OPCODE, i);
|
||||
__rmonStepRCP();
|
||||
reply.registers.sregs[i] = __rmonReadWordAt((u32*) SP_DMEM_START);
|
||||
}
|
||||
CleanupFromRCPop(FALSE);
|
||||
|
||||
reply.registers.sregs[SREG_IDX_DRAM_ADDR] = __rmonReadWordAt((u32*) SP_DRAM_ADDR_REG);
|
||||
reply.registers.sregs[SREG_IDX_MEM_ADDR] = __rmonReadWordAt((u32*) SP_MEM_ADDR_REG);
|
||||
reply.registers.sregs[SREG_IDX_RD_LEN] = __rmonReadWordAt((u32*) SP_RD_LEN_REG);
|
||||
reply.registers.sregs[SREG_IDX_PC] = __rmonReadWordAt((u32*) SP_PC_REG) + SP_IMEM_START;
|
||||
reply.registers.sregs[SREG_IDX_WR_LEN] = __rmonReadWordAt((u32*) SP_WR_LEN_REG);
|
||||
reply.registers.sregs[SREG_IDX_STATUS] = __rmonReadWordAt((u32*) SP_STATUS_REG);
|
||||
reply.registers.sregs[SREG_IDX_DMA_FULL] = __rmonReadWordAt((u32*) SP_DMA_FULL_REG);
|
||||
reply.registers.sregs[SREG_IDX_DMA_BUSY] = __rmonReadWordAt((u32*) SP_DMA_BUSY_REG);
|
||||
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonSetSRegs(KKHeader* req) {
|
||||
register KKCpScalarRegsetRequest* request = (KKCpScalarRegsetRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
register int i;
|
||||
|
||||
STUBBED_PRINTF(("SetSRegisters\n"));
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
SetUpForRCPop(FALSE);
|
||||
for (i = SREG_IDX_ZERO; i <= SREG_IDX_RA; i++) {
|
||||
__rmonWriteWordTo((u32*) SP_DMEM_START, request->registers.sregs[i]);
|
||||
LoadStoreSU(MIPS_LW_OPCODE, i);
|
||||
__rmonStepRCP();
|
||||
}
|
||||
CleanupFromRCPop(FALSE);
|
||||
|
||||
__rmonWriteWordTo((u32*) SP_DRAM_ADDR_REG, request->registers.sregs[SREG_IDX_DRAM_ADDR]);
|
||||
__rmonWriteWordTo((u32*) SP_MEM_ADDR_REG, request->registers.sregs[SREG_IDX_MEM_ADDR]);
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, request->registers.sregs[SREG_IDX_PC] & 0xFFF);
|
||||
__rmonWriteWordTo((u32*) SP_WR_LEN_REG, request->registers.sregs[SREG_IDX_WR_LEN]);
|
||||
__rmonWriteWordTo((u32*) SP_STATUS_REG, request->registers.sregs[SREG_IDX_STATUS]);
|
||||
|
||||
reply.object = request->tid;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonGetVRegs(KKHeader* req) {
|
||||
char* cPtr;
|
||||
int sent;
|
||||
int dataSize;
|
||||
register KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKCpVregEvent reply;
|
||||
register int i;
|
||||
|
||||
STUBBED_PRINTF(("GetVRegisters\n"));
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
reply.tid = request->object;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.header.length = sizeof(reply);
|
||||
|
||||
dataSize = sizeof(reply);
|
||||
cPtr = (char*) &dataSize;
|
||||
sent = 0;
|
||||
while (sent < (signed) sizeof(dataSize)) {
|
||||
sent += __osRdbSend(cPtr + sent, sizeof(dataSize) - sent, RDB_TYPE_GtoH_DEBUG);
|
||||
}
|
||||
|
||||
__rmonSendHeader(&reply.header, VREG_SIZE, KK_TYPE_REPLY);
|
||||
|
||||
SetUpForRCPop(TRUE);
|
||||
for (i = 0; i < VREG_NUM; i++) {
|
||||
LoadStoreVU(MIPS_SWC2_OPCODE, i);
|
||||
__rmonStepRCP();
|
||||
__rmonSendData((void*) SP_DMEM_START, VREG_SIZE);
|
||||
}
|
||||
CleanupFromRCPop(TRUE);
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonSetVRegs(KKHeader* req) {
|
||||
register KKCpVectorRegsetRequest* request = (KKCpVectorRegsetRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
register int i;
|
||||
|
||||
STUBBED_PRINTF(("SetVRegs\n"));
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
SetUpForRCPop(TRUE);
|
||||
for (i = 0; i < VREG_NUM; i++) {
|
||||
__rmonCopyWords((u32*) SP_DMEM_START, (u32*) &request->registers.vregs[i], VREG_SIZE / sizeof(u32));
|
||||
LoadStoreVU(MIPS_LWC2_OPCODE, i);
|
||||
__rmonStepRCP();
|
||||
}
|
||||
CleanupFromRCPop(TRUE);
|
||||
|
||||
reply.object = request->tid;
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
u32 __rmonGetRegisterContents(int method, int threadNumber, int regNumber) {
|
||||
if (method == RMON_CPU) {
|
||||
/* CPU register */
|
||||
u32* regPointer;
|
||||
OSThread* tptr;
|
||||
|
||||
if (regNumber >= GREG_IDX_AT && regNumber < GREG_IDX_K0) {
|
||||
regNumber -= GREG_IDX_AT - GREG_IDX_ZERO;
|
||||
} else if (regNumber >= GREG_IDX_GP && regNumber < GREG_IDX_LO) {
|
||||
regNumber -= GREG_IDX_GP - GREG_IDX_T9;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
tptr = __rmonGetTCB(threadNumber);
|
||||
if (tptr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
regPointer = (u32*) &tptr->context;
|
||||
regPointer += regNumber;
|
||||
return *regPointer;
|
||||
} else {
|
||||
/* RSP register */
|
||||
return rmonGetRcpRegister(regNumber);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,9 +1,89 @@
|
||||
#include "common.h"
|
||||
#include "PR/os_version.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonsio/__rmonSendFault.s")
|
||||
#if BUILD_VERSION < VERSION_J
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonsio/__rmonIOflush.s")
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonsio/__rmonIOputw.s")
|
||||
#include "PR/os_internal.h"
|
||||
#include "PR/ultraerror.h"
|
||||
#include "PR/ultralog.h"
|
||||
#include "PR/sptask.h"
|
||||
#include "dbgproto.h"
|
||||
#include "rmonint.h"
|
||||
#include "PR/ramrom.h"
|
||||
#include "PR/rdb.h"
|
||||
#include "PR/rmon.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmonsio/__rmonIOhandler.s")
|
||||
#include "macros.h"
|
||||
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#endif
|
||||
|
||||
static OSMesgQueue IOmq ALIGNED(8);
|
||||
static OSMesg IOmsgs;
|
||||
|
||||
void* __osRdb_DbgRead_Buf;
|
||||
u8 rmonRdbReadBuf[RMON_DBG_BUF_SIZE] ALIGNED(0x10);
|
||||
|
||||
void __rmonSendFault(OSThread* thread) {
|
||||
volatile float f UNUSED;
|
||||
u8* tPtr;
|
||||
u32 sent = 0;
|
||||
|
||||
/* touch fpu to ensure registers are saved to the context structure */
|
||||
f = 0.0f;
|
||||
|
||||
tPtr = (u8*) thread;
|
||||
while (sent < sizeof(OSThread)) {
|
||||
sent += __osRdbSend(tPtr + sent, sizeof(OSThread) - sent, RDB_TYPE_GtoH_FAULT);
|
||||
}
|
||||
}
|
||||
|
||||
void __rmonIOflush(void) {
|
||||
int sent = 0;
|
||||
char tstr[4];
|
||||
|
||||
while (sent <= 0) {
|
||||
sent += __osRdbSend(tstr, 1, RDB_TYPE_GtoH_DEBUG_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
void __rmonIOputw(u32 word) {
|
||||
int sent = 0;
|
||||
char* cPtr = (char*) &word;
|
||||
|
||||
while (sent < 4) {
|
||||
sent += __osRdbSend(cPtr + sent, sizeof(word) - sent, RDB_TYPE_GtoH_DEBUG);
|
||||
}
|
||||
}
|
||||
|
||||
void __rmonIOhandler(void) {
|
||||
int sent;
|
||||
char tstr[4];
|
||||
|
||||
osCreateMesgQueue(&IOmq, &IOmsgs, 1);
|
||||
osSetEventMesg(OS_EVENT_RDB_DBG_DONE, &IOmq, NULL);
|
||||
__osRdb_DbgRead_Buf = rmonRdbReadBuf;
|
||||
|
||||
while (TRUE) {
|
||||
osRecvMesg(&IOmq, NULL, OS_MESG_BLOCK);
|
||||
|
||||
__rmonExecute((KKHeader*) &rmonRdbReadBuf);
|
||||
__osRdb_DbgRead_Buf = rmonRdbReadBuf;
|
||||
|
||||
sent = 0;
|
||||
while (sent <= 0) {
|
||||
sent += __osRdbSend(tstr, 1, RDB_TYPE_GtoH_DEBUG_READY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,17 +1,344 @@
|
||||
#include "common.h"
|
||||
#ifndef _FINALROM
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonMaskIdleThreadInts.s")
|
||||
#include "dbgproto.h"
|
||||
#include "PR/os_internal.h"
|
||||
#include "rmonint.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/sptask.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonGetTCB.s")
|
||||
#include "macros.h"
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonStopUserThreads.s")
|
||||
// TODO: this comes from a header
|
||||
#if BUILD_VERSION >= VERSION_J
|
||||
#ident "$Revision: 1.4 $"
|
||||
#else
|
||||
#ident "$Revision: 3.70 $"
|
||||
#ident "$Revision: 1.5 $"
|
||||
#ident "$Revision: 1.2 $"
|
||||
#ident "$Revision: 1.4 $"
|
||||
#ident "$Revision: 1.3 $"
|
||||
#endif
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonListThreads.s")
|
||||
void __rmonMaskIdleThreadInts(void) {
|
||||
register OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonGetThreadStatus.s")
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->priority == OS_PRIORITY_IDLE) {
|
||||
tptr->context.sr &= ~OS_IM_CPU;
|
||||
tptr->context.sr |= (OS_IM_RDBREAD | OS_IM_RDBWRITE | OS_IM_CART);
|
||||
break;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonThreadStatus.s")
|
||||
OSThread* __rmonGetTCB(int threadNumber) {
|
||||
register OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonStopThread.s")
|
||||
if (threadNumber < 1) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#pragma GLOBAL_ASM("asm/us/nonmatchings/libultra/rmon/rmontask/__rmonRunThread.s")
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->id == threadNumber) {
|
||||
return tptr;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int __rmonStopUserThreads(int whichThread) {
|
||||
register int whichOne = 0;
|
||||
register OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
STUBBED_PRINTF(("StopThreads %d\n", whichThread));
|
||||
|
||||
if (whichThread != 0) {
|
||||
/* Stop specified thread */
|
||||
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->id == whichThread) {
|
||||
break;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
|
||||
if (tptr->priority == -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (tptr->priority > OS_PRIORITY_IDLE && tptr->priority <= OS_PRIORITY_APPMAX) {
|
||||
osStopThread(tptr);
|
||||
if (tptr->state != OS_STATE_STOPPED) {
|
||||
STUBBED_PRINTF(("Couldn't stop thread %d\n", tptr->id));
|
||||
}
|
||||
whichOne = whichThread;
|
||||
}
|
||||
} else {
|
||||
/* Stop all threads */
|
||||
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->priority > OS_PRIORITY_IDLE && tptr->priority <= OS_PRIORITY_APPMAX) {
|
||||
osStopThread(tptr);
|
||||
if (tptr->state != OS_STATE_STOPPED) {
|
||||
STUBBED_PRINTF(("Couldn\'t stop thread %d\n", tptr->id));
|
||||
}
|
||||
whichOne = -1;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
}
|
||||
return whichOne;
|
||||
}
|
||||
|
||||
int __rmonListThreads(KKHeader* req) {
|
||||
register KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKObjsEvent* reply = (KKObjsEvent*) __rmonUtilityBuffer;
|
||||
|
||||
STUBBED_PRINTF(("ListThreads\n"));
|
||||
|
||||
reply->object = (request->object == -1) ? RMON_PID_CPU : request->object;
|
||||
|
||||
if (req->method == RMON_RSP) {
|
||||
reply->objs.number = 1;
|
||||
reply->objs.objects[0] = RMON_TID_RSP;
|
||||
} else {
|
||||
register OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
reply->objs.number = 0;
|
||||
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->id != 0) {
|
||||
reply->objs.objects[reply->objs.number] = tptr->id;
|
||||
reply->objs.number++;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
}
|
||||
reply->header.code = request->header.code;
|
||||
reply->header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply->header, sizeof(*reply) + sizeof(reply->objs.objects[0]) * (reply->objs.number - 1),
|
||||
KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonGetThreadStatus(int method, int id, KKStatusEvent* reply) {
|
||||
u32 inst;
|
||||
|
||||
STUBBED_PRINTF(("ThreadStatus %d method %d\n", id, method));
|
||||
|
||||
reply->status.tid = id;
|
||||
reply->status.pid = (method == RMON_RSP) ? RMON_PID_RSP : RMON_PID_CPU;
|
||||
reply->status.why = 1;
|
||||
reply->status.what = 0;
|
||||
reply->status.info.major = 0;
|
||||
reply->status.info.minor = 0;
|
||||
reply->status.rv = 0;
|
||||
|
||||
if (method == RMON_RSP) {
|
||||
reply->status.start = SP_IMEM_START;
|
||||
reply->status.priority = RMON_PRI_RSP;
|
||||
|
||||
if (__rmonRCPrunning()) {
|
||||
reply->status.flags = OS_STATE_RUNNING;
|
||||
/* Cannot read RSP PC or current instruction while the RSP is running */
|
||||
reply->status.info.addr = 0;
|
||||
reply->status.instr = 0;
|
||||
} else {
|
||||
reply->status.flags = OS_STATE_STOPPED;
|
||||
reply->status.info.addr = __rmonReadWordAt((u32*) SP_PC_REG) + SP_IMEM_START;
|
||||
inst = __rmonReadWordAt((u32*) reply->status.info.addr);
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
inst = MIPS_BREAK_OPCODE;
|
||||
}
|
||||
if (__rmonRcpAtBreak) {
|
||||
/* Report RSP break */
|
||||
reply->status.why = 2;
|
||||
reply->status.info.major = 2;
|
||||
reply->status.info.minor = 4;
|
||||
}
|
||||
reply->status.instr = inst;
|
||||
}
|
||||
} else {
|
||||
OSThread* tptr = __osGetActiveQueue();
|
||||
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->id == id) {
|
||||
break;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
if (tptr->priority == -1) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
reply->status.priority = tptr->priority;
|
||||
reply->status.flags = (tptr->state != 0) ? tptr->state : OS_STATE_STOPPED;
|
||||
reply->status.info.addr = tptr->context.pc;
|
||||
|
||||
inst = *(u32*) (tptr->context.pc);
|
||||
if ((inst & MIPS_BREAK_MASK) == MIPS_BREAK_OPCODE) {
|
||||
inst = MIPS_BREAK_OPCODE;
|
||||
}
|
||||
|
||||
reply->status.instr = inst;
|
||||
reply->status.start = (int) tptr;
|
||||
|
||||
if (tptr->flags & OS_FLAG_CPU_BREAK) {
|
||||
/* Report break */
|
||||
reply->status.why = 2;
|
||||
reply->status.info.major = 2;
|
||||
reply->status.info.minor = 4;
|
||||
} else if (tptr->flags & OS_FLAG_FAULT) {
|
||||
/* Report fault */
|
||||
reply->status.why = 2;
|
||||
reply->status.info.major = 1;
|
||||
reply->status.info.minor = 2;
|
||||
}
|
||||
}
|
||||
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonThreadStatus(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKStatusEvent reply;
|
||||
|
||||
if (__rmonGetThreadStatus(req->method, request->object, &reply) != TV_ERROR_NO_ERROR) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonStopThread(KKHeader* req) {
|
||||
KKObjectRequest* request = (KKObjectRequest*) req;
|
||||
KKStatusEvent reply;
|
||||
u32* pc;
|
||||
|
||||
STUBBED_PRINTF(("StopThread %d\n", request->object));
|
||||
|
||||
switch (req->method) {
|
||||
case RMON_CPU:
|
||||
__rmonStopUserThreads(request->object);
|
||||
break;
|
||||
case RMON_RSP:
|
||||
if (__rmonRCPrunning()) {
|
||||
/* Stop the rsp */
|
||||
__rmonIdleRCP();
|
||||
pc = (u32*) __rmonReadWordAt((u32*) SP_PC_REG);
|
||||
if (pc == NULL) {
|
||||
break;
|
||||
}
|
||||
pc--;
|
||||
/* Check if the RSP is stopped in a branch delay slot, if it is step out of it. The RSP would otherwise
|
||||
lose information about whether the branch should or should not be taken when reading registers. */
|
||||
if (__rmonGetBranchTarget(RMON_RSP, RMON_TID_RSP, (void*) ((u32) pc + SP_IMEM_START)) % 4 == 0) {
|
||||
__rmonStepRCP();
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
if (__rmonGetThreadStatus(req->method, request->object, &reply) != TV_ERROR_NO_ERROR) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
if (reply.status.flags == OS_STATE_STOPPED) {
|
||||
reply.header.code = KK_CODE_THREAD_STATUS;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_EXCEPTION);
|
||||
}
|
||||
return TV_ERROR_NO_ERROR;
|
||||
}
|
||||
|
||||
int __rmonRunThread(KKHeader* req) {
|
||||
KKRunThreadRequest* request = (KKRunThreadRequest*) req;
|
||||
KKObjectEvent reply;
|
||||
KKStatusEvent exceptionReply;
|
||||
register OSThread* tptr;
|
||||
register int runNeeded = FALSE;
|
||||
|
||||
STUBBED_PRINTF(("RunThread %d\n", request->tid));
|
||||
|
||||
switch (req->method) {
|
||||
case RMON_CPU:
|
||||
tptr = __osGetActiveQueue();
|
||||
while (tptr->priority != -1) {
|
||||
if (tptr->id == request->tid) {
|
||||
break;
|
||||
}
|
||||
tptr = tptr->tlnext;
|
||||
}
|
||||
|
||||
if (tptr->priority == -1) {
|
||||
return TV_ERROR_INVALID_ID;
|
||||
}
|
||||
if (tptr->state != OS_STATE_STOPPED) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
tptr->flags &= ~(OS_FLAG_CPU_BREAK | OS_FLAG_FAULT);
|
||||
if (request->actions.flags & KK_RUN_SETPC) {
|
||||
tptr->context.pc = request->actions.vaddr;
|
||||
}
|
||||
if ((request->actions.flags & KK_RUN_SSTEP) &&
|
||||
!__rmonSetSingleStep(request->tid, (u32*) tptr->context.pc)) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
runNeeded = TRUE;
|
||||
break;
|
||||
case RMON_RSP:
|
||||
if (__rmonRCPrunning()) {
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
if (request->actions.flags & KK_RUN_SETPC) {
|
||||
__rmonWriteWordTo((u32*) SP_PC_REG, request->actions.vaddr - SP_IMEM_START);
|
||||
}
|
||||
if (request->actions.flags & KK_RUN_SSTEP) {
|
||||
/* If the RSP is stopped at a branch step twice so as to not stop in a branch delay slot. */
|
||||
if (__rmonGetBranchTarget(RMON_RSP, RMON_TID_RSP,
|
||||
(void*) (__rmonReadWordAt((u32*) SP_PC_REG) + SP_IMEM_START)) %
|
||||
4 ==
|
||||
0) {
|
||||
__rmonStepRCP();
|
||||
}
|
||||
__rmonStepRCP();
|
||||
__rmonRcpAtBreak = TRUE;
|
||||
} else {
|
||||
__rmonRcpAtBreak = FALSE;
|
||||
__rmonRunRCP();
|
||||
}
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->tid;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
if (request->actions.flags & KK_RUN_SSTEP) {
|
||||
__rmonGetThreadStatus(RMON_RSP, RMON_TID_RSP, &exceptionReply);
|
||||
__rmonGetExceptionStatus(&exceptionReply);
|
||||
__rmonSendReply(&exceptionReply.header, sizeof(exceptionReply), KK_TYPE_EXCEPTION);
|
||||
}
|
||||
return TV_ERROR_NO_ERROR;
|
||||
default:
|
||||
return TV_ERROR_OPERATIONS_PROTECTED;
|
||||
}
|
||||
|
||||
reply.header.code = request->header.code;
|
||||
reply.header.error = TV_ERROR_NO_ERROR;
|
||||
reply.object = request->tid;
|
||||
__rmonSendReply(&reply.header, sizeof(reply), KK_TYPE_REPLY);
|
||||
|
||||
if (runNeeded) {
|
||||
osStartThread(tptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "PR/os.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
OSViMode osViModeMpalLan1 = {
|
||||
OS_VI_MPAL_LAN1, // type
|
||||
{
|
||||
// comRegs
|
||||
VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
|
||||
VI_CTRL_PIXEL_ADV_3, // ctrl
|
||||
WIDTH(320), // width
|
||||
BURST(57, 30, 5, 70), // burst
|
||||
VSYNC(525), // vSync
|
||||
HSYNC(3089, 4), // hSync
|
||||
LEAP(3097, 3098), // leap
|
||||
HSTART(108, 748), // hStart
|
||||
SCALE(2, 0), // xScale
|
||||
VCURRENT(0), // vCurrent
|
||||
},
|
||||
{ // fldRegs
|
||||
{
|
||||
// [0]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(37, 511), // vStart
|
||||
BURST(4, 2, 14, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
},
|
||||
{
|
||||
// [1]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(37, 511), // vStart
|
||||
BURST(4, 2, 14, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
} },
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "PR/os.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
OSViMode osViModeNtscLan1 = {
|
||||
OS_VI_NTSC_LAN1, // type
|
||||
{
|
||||
// comRegs
|
||||
VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
|
||||
VI_CTRL_PIXEL_ADV_3, // ctrl
|
||||
WIDTH(320), // width
|
||||
BURST(57, 34, 5, 62), // burst
|
||||
VSYNC(525), // vSync
|
||||
HSYNC(3093, 0), // hSync
|
||||
LEAP(3093, 3093), // leap
|
||||
HSTART(108, 748), // hStart
|
||||
SCALE(2, 0), // xScale
|
||||
VCURRENT(0), // vCurrent
|
||||
},
|
||||
{ // fldRegs
|
||||
{
|
||||
// [0]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(37, 511), // vStart
|
||||
BURST(4, 2, 14, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
},
|
||||
{
|
||||
// [1]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(37, 511), // vStart
|
||||
BURST(4, 2, 14, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
} },
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "PR/os.h"
|
||||
#include "PR/rcp.h"
|
||||
#include "PR/viint.h"
|
||||
|
||||
OSViMode osViModePalLan1 = {
|
||||
OS_VI_PAL_LAN1, // type
|
||||
{
|
||||
// comRegs
|
||||
VI_CTRL_TYPE_16 | VI_CTRL_GAMMA_DITHER_ON | VI_CTRL_GAMMA_ON | VI_CTRL_DIVOT_ON | VI_CTRL_ANTIALIAS_MODE_1 |
|
||||
VI_CTRL_PIXEL_ADV_3, // ctrl
|
||||
WIDTH(320), // width
|
||||
BURST(58, 30, 4, 69), // burst
|
||||
VSYNC(625), // vSync
|
||||
HSYNC(3177, 23), // hSync
|
||||
LEAP(3183, 3181), // leap
|
||||
HSTART(128, 768), // hStart
|
||||
SCALE(2, 0), // xScale
|
||||
VCURRENT(0), // vCurrent
|
||||
},
|
||||
{ // fldRegs
|
||||
{
|
||||
// [0]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(95, 569), // vStart
|
||||
BURST(107, 2, 9, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
},
|
||||
{
|
||||
// [1]
|
||||
ORIGIN(640), // origin
|
||||
SCALE(1, 0), // yScale
|
||||
HSTART(95, 569), // vStart
|
||||
BURST(107, 2, 9, 0), // vBurst
|
||||
VINTR(2), // vIntr
|
||||
} },
|
||||
};
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "prevent_bss_reordering.h"
|
||||
#include "global.h"
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "prevent_bss_reordering.h"
|
||||
#include "sf64math.h"
|
||||
|
||||
// BSS section range:
|
||||
|
||||
@@ -104,7 +104,7 @@ void func_8000762C(s32 arg0, s32 arg1, const char* fmt, ...) {
|
||||
sp40[i] = 0;
|
||||
}
|
||||
|
||||
if (_Printf(func_80007604, sp40, fmt, args) <= 0) {
|
||||
if (_Printf((outfun*) func_80007604, sp40, fmt, args) <= 0) {
|
||||
return;
|
||||
}
|
||||
for (var_s0 = sp40; *var_s0 != 0; var_s0++) {
|
||||
|
||||
@@ -7,7 +7,7 @@ void* proutSprintf(void* dst, const char* fmt, size_t size) {
|
||||
}
|
||||
|
||||
s32 vsprintf(char* dst, const char* fmt, va_list args) {
|
||||
s32 ret = _Printf(proutSprintf, dst, fmt, args);
|
||||
s32 ret = _Printf((outfun*) proutSprintf, dst, fmt, args);
|
||||
|
||||
if (ret > -1) {
|
||||
dst[ret] = 0;
|
||||
@@ -20,7 +20,7 @@ int sprintf(char* s, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
||||
ret = _Printf(proutSprintf, s, fmt, args);
|
||||
ret = _Printf((outfun*) proutSprintf, s, fmt, args);
|
||||
|
||||
if (ret >= 0) {
|
||||
s[ret] = 0;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include "prevent_bss_reordering.h"
|
||||
#include "prevent_bss_reordering2.h"
|
||||
#include "global.h"
|
||||
|
||||
typedef struct UnkStruct_D_i4_801A03E0 {
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
#include "mods.h"
|
||||
// #include "prevent_bss_reordering.h"
|
||||
#include "prevent_bss_reordering.h"
|
||||
#include "prevent_bss_reordering2.h"
|
||||
#include "global.h"
|
||||
#include "fox_map.h"
|
||||
#include "fox_option.h"
|
||||
|
||||
Reference in New Issue
Block a user