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:
Lywx
2024-02-14 09:24:31 -06:00
committed by GitHub
parent ff2627c1ca
commit 902dc0b829
138 changed files with 10087 additions and 1430 deletions
+87 -6
View File
@@ -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
View File
@@ -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);
}
+72 -5
View File
@@ -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);
}
+57 -3
View File
@@ -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
View File
@@ -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);
}
+35 -2
View File
@@ -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
+4 -5
View File
@@ -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
+98 -2
View File
@@ -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
+18 -2
View File
@@ -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;
}
+84 -3
View File
@@ -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;
}
+139 -4
View File
@@ -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;
}
+23 -3
View File
@@ -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);
}
+168 -3
View File
@@ -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
+174 -3
View File
@@ -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
+71 -4
View File
@@ -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;
}
+9 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
}
}
}
+8 -2
View File
@@ -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);
}
+60 -2
View File
@@ -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;
}
+52 -2
View File
@@ -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;
}
+28 -2
View File
@@ -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;
}
+21 -2
View File
@@ -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;
}
+37 -2
View File
@@ -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;
}
+192 -4
View File
@@ -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));
}
}
+4 -4
View File
@@ -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;
+27 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+9 -2
View File
@@ -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
View File
@@ -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;
+52 -2
View File
@@ -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;
}
+28 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+42 -2
View File
@@ -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;
}
+22 -2
View File
@@ -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;
}
+21 -2
View File
@@ -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
View File
@@ -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;
}
}
+8 -2
View File
@@ -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);
}
+32 -2
View File
@@ -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;
}
+23 -2
View File
@@ -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;
}
+22 -2
View File
@@ -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;
}
+14 -2
View File
@@ -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;
}
+8 -2
View File
@@ -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);
}
+79 -4
View File
@@ -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);
}
+5 -2
View File
@@ -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);
}
+17 -2
View File
@@ -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
View File
@@ -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();
}
+16 -2
View File
@@ -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);
}
+8 -2
View File
@@ -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
View File
@@ -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;
}
}
}
+16 -2
View File
@@ -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);
}
+26 -2
View File
@@ -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);
}
+26 -2
View File
@@ -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);
}
+71 -2
View File
@@ -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);
}
+30 -2
View File
@@ -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);
}
+79 -2
View File
@@ -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
View File
@@ -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;
}
}
}
+3 -31
View File
@@ -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
View File
@@ -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;
}
}
+53 -2
View File
@@ -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);
}
+9 -2
View File
@@ -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;
}
+24 -2
View File
@@ -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;
}
+223 -2
View File
@@ -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
+30 -2
View File
@@ -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
+36 -2
View File
@@ -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;
}
+72 -2
View File
@@ -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;
}
+39 -2
View File
@@ -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;
}
+8 -2
View File
@@ -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);
}
+37 -2
View File
@@ -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;
}
+38 -2
View File
@@ -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);
}
+8 -2
View File
@@ -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);
}
+35 -2
View File
@@ -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);
}
+15 -2
View File
@@ -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;
}
+55 -2
View File
@@ -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;
}
+38 -2
View File
@@ -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);
}
+27 -2
View File
@@ -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
View File
@@ -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;
}
+12 -2
View File
@@ -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);
}
}
+9 -2
View File
@@ -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
View File
@@ -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
+52 -3
View File
@@ -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
+134 -5
View File
@@ -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
View File
@@ -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
+59 -5
View File
@@ -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
View File
@@ -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
+85 -5
View File
@@ -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
+336 -9
View File
@@ -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
+37
View File
@@ -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
} },
};
+37
View File
@@ -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
} },
};
+37
View File
@@ -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
View File
@@ -1,3 +1,4 @@
#include "prevent_bss_reordering.h"
#include "global.h"
typedef struct {
+1
View File
@@ -1,3 +1,4 @@
#include "prevent_bss_reordering.h"
#include "sf64math.h"
// BSS section range:
+1 -1
View File
@@ -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++) {
+2 -2
View File
@@ -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;
+2
View File
@@ -1,3 +1,5 @@
#include "prevent_bss_reordering.h"
#include "prevent_bss_reordering2.h"
#include "global.h"
typedef struct UnkStruct_D_i4_801A03E0 {
+2 -1
View File
@@ -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"