diff --git a/Makefile b/Makefile index a9acd75..37c0868 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,10 @@ build/src/libultra/os/virtualtophysical.c.o: OPTFLAGS := -O1 build/src/libultra/os/initialize.c.o: OPTFLAGS := -O1 build/src/libultra/os/epilinkhandle.c.o: OPTFLAGS := -O1 build/src/libultra/os/getmemsize.c.o: OPTFLAGS := -O1 +build/src/libultra/os/seteventmesg.c.o: OPTFLAGS := -O1 +build/src/libultra/os/createmesgqueue.c.o: OPTFLAGS := -O1 +build/src/libultra/os/jammesg.c.o: OPTFLAGS := -O1 +build/src/libultra/os/setthreadpri.c.o: OPTFLAGS := -O1 build/src/libultra/io/pigetcmdq.c.o: OPTFLAGS := -O1 build/src/libultra/io/sptask.c.o: OPTFLAGS := -O1 build/src/libultra/io/controller.c.o: OPTFLAGS := -O1 @@ -71,6 +75,12 @@ build/src/libultra/io/viblack.c.o: OPTFLAGS := -O1 build/src/libultra/io/visetmode.c.o: OPTFLAGS := -O1 build/src/libultra/io/virepeatline.c.o: OPTFLAGS := -O1 build/src/libultra/io/pfsisplug.c.o: OPTFLAGS := -O1 +build/src/libultra/io/epidma.c.o: OPTFLAGS := -O1 +build/src/libultra/io/conteeplongwrite.c.o: OPTFLAGS := -O1 +build/src/libultra/io/si.c.o: OPTFLAGS := -O1 +build/src/libultra/io/sp.c.o: OPTFLAGS := -O1 +build/src/libultra/io/viswapbuf.c.o: OPTFLAGS := -O1 +build/src/libultra/io/sptaskyielded.c.o: OPTFLAGS := -O1 build/src/libultra/libc/ll.c.o: OPTFLAGS := -O1 build/src/libultra/libc/ll.c.o: MIPS_VERSION := -mips3 -32 @@ -81,7 +91,22 @@ build/src/libultra/io/gbpakinit.c.o: OPTFLAGS += -Wo,-loopunroll,0 # Libultra misc build/src/libultra/gu/scale.c.o: CC := $(CC_OLD) build/src/libultra/gu/scale.c.o: OPTFLAGS := -O3 +build/src/libultra/gu/translate.c.o: CC := $(CC_OLD) +build/src/libultra/gu/translate.c.o: OPTFLAGS := -O3 +build/src/libultra/gu/mtxcatf.c.o: CC := $(CC_OLD) +build/src/libultra/gu/mtxcatf.c.o: OPTFLAGS := -O3 +build/src/libultra/gu/mtxcatl.c.o: CC := $(CC_OLD) +build/src/libultra/gu/mtxcatl.c.o: OPTFLAGS := -O3 +build/src/libultra/gu/rotateRPY.c.o: CC := $(CC_OLD) +build/src/libultra/gu/rotateRPY.c.o: OPTFLAGS := -O3 +build/src/libultra/gu/rotate.c.o: CC := $(CC_OLD) +build/src/libultra/gu/rotate.c.o: OPTFLAGS := -O3 build/src/libultra/gu/sinf.c.o: CC := $(CC_OLD) +build/src/libultra/gu/random.c.o: CC := $(CC_OLD) +build/src/libultra/libc/xprintf.c.o: CC := $(CC_OLD) +build/src/libultra/libc/xprintf.c.o: OPTFLAGS := -O3 +build/src/libultra/libc/string.c.o: CC := $(CC_OLD) +build/src/libultra/libc/string.c.o: OPTFLAGS := -O3 build/src/libultra/io/controller.c.o: CC := $(CC_OLD) build/src/libultra/io/contreaddata.c.o: CC := $(CC_OLD) build/src/libultra/io/devmgr.c.o: CC := $(CC_OLD) diff --git a/include/macros.h b/include/macros.h index 75ee873..cfc6183 100644 --- a/include/macros.h +++ b/include/macros.h @@ -1,6 +1,9 @@ #ifndef _MACROS_H_ #define _MACROS_H_ +#define true 1 +#define false 0 + #ifndef __sgi #define GLOBAL_ASM(...) #endif diff --git a/include/string.h b/include/string.h index 9c809db..9bc66c9 100644 --- a/include/string.h +++ b/include/string.h @@ -46,7 +46,7 @@ typedef unsigned long size_t; #endif extern void *memcpy(void *, const void *, size_t); -extern char *strchr(const char *, int); +extern const char *strchr(const char *, int); extern size_t strlen(const char *); #ifdef __cplusplus diff --git a/include/ultra64.h b/include/ultra64.h index cf93c86..bd4f939 100644 --- a/include/ultra64.h +++ b/include/ultra64.h @@ -40,6 +40,8 @@ #include "ultra64/thread.h" +#include "functions.h" #include "macros.h" +#include "variables.h" #endif diff --git a/include/ultra64/internal.h b/include/ultra64/internal.h new file mode 100644 index 0000000..a15df6a --- /dev/null +++ b/include/ultra64/internal.h @@ -0,0 +1,22 @@ +#ifndef ULTRA64_INTERNAL_H +#define ULTRA64_INTERNAL_H + +typedef struct { + /* 0x00 */ u32 initialized; + /* 0x04 */ OSThread* mgrThread; + /* 0x08 */ OSMesgQueue* cmdQueue; + /* 0x0C */ OSMesgQueue* eventQueue; + /* 0x10 */ OSMesgQueue* acccessQueue; + /* 0x14 */ s32 (*piDmaCallback)(s32, u32, void*, size_t); + /* 0x18 */ s32 (*epiDmaCallback)(OSPiHandle*, s32, u32, void*, size_t); +} OSMgrArgs; // size = 0x1C + +typedef struct { + /* 0x00 */ OSMesgQueue* queue; + /* 0x04 */ OSMesg msg; +} __OSEventState; // size = 0x08 + +extern OSMgrArgs __osPiDevMgr; +extern __OSEventState __osEventStateTab[]; + +#endif diff --git a/splat.yaml b/splat.yaml index ece55e7..d23fdde 100644 --- a/splat.yaml +++ b/splat.yaml @@ -211,36 +211,36 @@ segments: - [0x5C980, c, libultra/io/conteepwrite] - [0x5CD50, c, libultra/os/getmemsize] - [0x5CE70, c, libultra/io/contpfs] - - [0x5D9F0, asm, libultra/os/seteventmesg] - - [0x5DAB0, asm, libultra/gu/sqrtf] - - [0x5DAC0, asm, libultra/os/afterprenmi] - - [0x5DAE0, asm, libultra/gu/mtxcatf] - - [0x5DCF0, asm, libultra/gu/mtxcatl] - - [0x5DDB0, asm, libultra/gu/random] - - [0x5DDE0, asm, libultra/libc/xprintf] - - [0x5EAA0, asm, libultra/io/gbpakgetstatus] - - [0x5EC20, asm, libultra/libc/sprintf] - - [0x5ECA0, asm, libultra/os/unmaptlball] - - [0x5ECF0, asm, libultra/io/epidma] - - [0x5EDD0, asm, libultra/al/heapinit] - - [0x5EE10, asm, libultra/os/syncprintf] - - [0x5EE50, asm, libultra/libc/string] - - [0x5EEF0, asm, libultra/os/invalidcache] - - [0x5EFA0, asm, libultra/os/createmesgqueue] - - [0x5EFD0, asm, libultra/os/invalicache] - - [0x5F050, asm, libultra/io/conteeplongwrite] - - [0x5F140, asm, libultra/io/sp] - - [0x5F170, asm, libultra/io/si] - - [0x5F1A0, asm, libultra/gu/translate] - - [0x5F240, asm, libultra/os/jammesg] - - [0x5F390, asm, libultra/os/setthreadpri] - - [0x5F470, asm, libultra/os/getthreadpri] - - [0x5F490, asm, libultra/io/epirawread] - - [0x5F5F0, asm, libultra/io/viswapbuf] - - [0x5F640, asm, libultra/io/epirawdma] - - [0x5F820, asm, libultra/io/sptaskyielded] - - [0x5F8A0, asm, libultra/gu/rotateRPY] - - [0x5FA40, asm, libultra/libc/bcmp] + - [0x5D9F0, c, libultra/os/seteventmesg] + - [0x5DAB0, c, libultra/gu/sqrtf] + - [0x5DAC0, c, libultra/os/afterprenmi] + - [0x5DAE0, c, libultra/gu/mtxcatf] + - [0x5DCF0, c, libultra/gu/mtxcatl] + - [0x5DDB0, c, libultra/gu/random] + - [0x5DDE0, c, libultra/libc/xprintf] + - [0x5EAA0, c, libultra/io/gbpakgetstatus] + - [0x5EC20, c, libultra/libc/sprintf] + - [0x5ECA0, hasm, libultra/os/unmaptlball] + - [0x5ECF0, c, libultra/io/epidma] + - [0x5EDD0, c, libultra/al/heapinit] + - [0x5EE10, c, libultra/libc/syncprintf] + - [0x5EE50, c, libultra/libc/string] + - [0x5EEF0, hasm, libultra/os/invalidcache] + - [0x5EFA0, c, libultra/os/createmesgqueue] + - [0x5EFD0, hasm, libultra/os/invalicache] + - [0x5F050, c, libultra/io/conteeplongwrite] + - [0x5F140, c, libultra/io/sp] + - [0x5F170, c, libultra/io/si] + - [0x5F1A0, c, libultra/gu/translate] + - [0x5F240, c, libultra/os/jammesg] + - [0x5F390, c, libultra/os/setthreadpri] + - [0x5F470, c, libultra/os/getthreadpri] + - [0x5F490, c, libultra/io/epirawread] + - [0x5F5F0, c, libultra/io/viswapbuf] + - [0x5F640, c, libultra/io/epirawdma] + - [0x5F820, c, libultra/io/sptaskyielded] + - [0x5F8A0, c, libultra/gu/rotateRPY] + - [0x5FA40, hasm, libultra/libc/bcmp] - [0x5FB60, asm, libultra/gu/rotate] - [0x5FD50, asm, libultra/os/gettime] - [0x5FDE0, asm, libultra/os/timerintr] @@ -319,6 +319,9 @@ segments: - [0x7A2A0, .data, libultra/os/initialize] - [0x7A2C0, .data, libultra/al/reverb] - [0x7A2E0, bin, rom_data_7A2E0] + - [0x7B550, .data, libultra/gu/random] + - [0x7B560, .data, libultra/libc/xprintf] + - [0x7B5B0, bin, rom_data_7B5B0] # Start of .rodata - [0x7BAC0, .rodata, rsp] # rsp.c rodata @@ -328,6 +331,9 @@ segments: - [0x7EF30, .rodata, libultra/al/reverb] - [0x7EF60, .rodata, libultra/gu/perspective] - [0x7EF70, .rodata, libultra/io/devmgr] - - [0x7EF90, bin, rom_rodata_7EF90] + - [0x7EF90, .rodata, libultra/libc/xprintf] + - [0x7F090, .rodata, libultra/gu/rotateRPY] + - [0x7F0A0, bin, rom_rodata_7F0A0] # this is libultra/gu/rotate, but cant migrate due to bss splat issues + - [0x7F0B0, bin, rom_rodata_7F0B0] - [0x7F980, bin] # rest of rom part 2 - [0x2000000] diff --git a/src/libultra/al/heapinit.c b/src/libultra/al/heapinit.c new file mode 100644 index 0000000..9053375 --- /dev/null +++ b/src/libultra/al/heapinit.c @@ -0,0 +1,37 @@ +/*==================================================================== + * heapinit.c + * + * Copyright 1995, Silicon Graphics, Inc. + * All Rights Reserved. + * + * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, + * Inc.; the contents of this file may not be disclosed to third + * parties, copied or duplicated in any form, in whole or in part, + * without the prior written permission of Silicon Graphics, Inc. + * + * RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to + * restrictions as set forth in subdivision (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS + * 252.227-7013, and/or in similar or successor clauses in the FAR, + * DOD or NASA FAR Supplement. Unpublished - rights reserved under the + * Copyright Laws of the United States. + *====================================================================*/ + +#include "synthInternals.h" +#include + +void alHeapInit(ALHeap *hp, u8 *base, s32 len) +{ + s32 extraAlign = (AL_CACHE_ALIGN+1) - ((s32) base & AL_CACHE_ALIGN); + + if (extraAlign != AL_CACHE_ALIGN+1) + hp->base = base + extraAlign; + else + hp->base = base; + + hp->len = len; + hp->cur = hp->base; + hp->count = 0; +} + diff --git a/src/libultra/gu/mtxcatf.c b/src/libultra/gu/mtxcatf.c new file mode 100644 index 0000000..af2ae96 --- /dev/null +++ b/src/libultra/gu/mtxcatf.c @@ -0,0 +1,63 @@ + +/* + * Copyright 1995, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * + * UNPUBLISHED -- Rights reserved under the copyright laws of the United + * States. Use of a copyright notice is precautionary only and does not + * imply publication or disclosure. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to restrictions + * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or + * in similar or successor clauses in the FAR, or the DOD or NASA FAR + * Supplement. Contractor/manufacturer is Silicon Graphics, Inc., + * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. + * + * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY + * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY + * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON + * GRAPHICS, INC. + * + */ + +/* + * File: mtxcatf.c + * Creator: hsa@sgi.com + * Create Date: Thu Nov 2 13:03:02 PST 1995 + * + */ + +#include "guint.h" + +void guMtxCatF(float mf[4][4], float nf[4][4], float res[4][4]) +{ + int i, j, k; + float temp[4][4]; + + for (i=0; i<4; i++) { + for (j=0; j<4; j++) { + temp[i][j] = 0.0; + for (k=0; k<4; k++) { + temp[i][j] += mf[i][k] * nf[k][j]; + } + } + } + + /* make sure we handle case where result is an input */ + for (i=0; i<4; i++) { + for (j=0; j<4; j++) { + res[i][j] = temp[i][j]; + } + } +} + +void guMtxXFMF(float mf[4][4], float x, float y, float z, float *ox, float *oy, float *oz) +{ + *ox = mf[0][0]*x + mf[1][0]*y + mf[2][0]*z + mf[3][0]; + *oy = mf[0][1]*x + mf[1][1]*y + mf[2][1]*z + mf[3][1]; + *oz = mf[0][2]*x + mf[1][2]*y + mf[2][2]*z + mf[3][2]; +} + diff --git a/src/libultra/gu/mtxcatl.c b/src/libultra/gu/mtxcatl.c new file mode 100644 index 0000000..36e3312 --- /dev/null +++ b/src/libultra/gu/mtxcatl.c @@ -0,0 +1,54 @@ + +/* + * Copyright 1995, Silicon Graphics, Inc. + * ALL RIGHTS RESERVED + * + * UNPUBLISHED -- Rights reserved under the copyright laws of the United + * States. Use of a copyright notice is precautionary only and does not + * imply publication or disclosure. + * + * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND: + * Use, duplication or disclosure by the Government is subject to restrictions + * as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights + * in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or + * in similar or successor clauses in the FAR, or the DOD or NASA FAR + * Supplement. Contractor/manufacturer is Silicon Graphics, Inc., + * 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311. + * + * THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY + * INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION, + * DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY + * PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON + * GRAPHICS, INC. + * + */ + +/* + * File: mtxcatl.c + * Creator: hsa@sgi.com + * Create Date: Thu Nov 2 13:03:02 PST 1995 + * + */ + +#include "guint.h" + +void guMtxCatL(Mtx *m, Mtx *n, Mtx *res) +{ + float mf[4][4], nf[4][4], resf[4][4]; + + guMtxL2F(mf, m); + guMtxL2F(nf, n); + + guMtxCatF(mf, nf, resf); + + guMtxF2L(resf, res); +} + +void guMtxXFML(Mtx *m, float x, float y, float z, float *ox, float *oy, float *oz) +{ + float mf[4][4]; + + guMtxL2F(mf, m); + + guMtxXFMF(mf, x, y, z, ox, oy, oz); +} diff --git a/src/libultra/gu/random.c b/src/libultra/gu/random.c new file mode 100644 index 0000000..32cfde3 --- /dev/null +++ b/src/libultra/gu/random.c @@ -0,0 +1,33 @@ +/************************************************************************** + * * + * Copyright (C) 1995, 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. * + * * + **************************************************************************/ + +#include "guint.h" + +/* + * Return a pseudorandom 32 bit number + * try the RAND macro too + * + */ +int guRandom(void) +{ + static unsigned int xseed = 174823885; + unsigned int x; + + x = (xseed<<2) + 2; + + x *= (x+1); + x = x >> 2; + + xseed = x; + + return( x ); +} diff --git a/src/libultra/gu/rotate.c b/src/libultra/gu/rotate.c new file mode 100644 index 0000000..7612729 --- /dev/null +++ b/src/libultra/gu/rotate.c @@ -0,0 +1,60 @@ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ + +#include "guint.h" + +extern f32 __cosf(f32); + +void guRotateF(float mf[4][4], float a, float x, float y, float z) +{ + static float dtor = 3.1415926f / 180.0f; + float sine; + float cosine; + float ab, bc, ca, t; + + guNormalize(&x, &y, &z); + + a *= dtor; + + sine = sinf(a); + cosine = __cosf(a); + t = 1 - cosine; + ab = x * y * t; + bc = y * z * t; + ca = z * x * t; + + guMtxIdentF(mf); + + t = x * x; + mf[0][0] = t + cosine * (1 - t); + mf[2][1] = bc - x * sine; + mf[1][2] = bc + x * sine; + + t = y * y; + mf[1][1] = t + cosine * (1 - t); + mf[2][0] = ca + y * sine; + mf[0][2] = ca - y * sine; + + t = z * z; + mf[2][2] = t + cosine * (1 - t); + mf[1][0] = ab - z * sine; + mf[0][1] = ab + z * sine; +} + +void guRotate(Mtx *m, float a, float x, float y, float z) +{ + f32 mf[4][4]; + + guRotateF(mf, a, x, y, z); + + guMtxF2L(mf, m); +} \ No newline at end of file diff --git a/src/libultra/gu/rotateRPY.c b/src/libultra/gu/rotateRPY.c new file mode 100644 index 0000000..7c8e2db --- /dev/null +++ b/src/libultra/gu/rotateRPY.c @@ -0,0 +1,68 @@ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ + +#include "guint.h" + +// conflict with gu.h +#define M_DTOR_2 (3.1415926f / 180.0f) + +extern float D_80103870; + +extern float __cosf(float angle); + +/* + * Return rotation matrix given roll, pitch, and yaw in degrees + * + */ + +void guRotateRPYF(float mf[4][4], float r, float p, float h) +{ + // float dtor = ; + float sinr, sinp, sinh; + float cosr, cosp, cosh; + + r *= M_DTOR_2; + p *= M_DTOR_2; + h *= M_DTOR_2; + + D_80103870 = M_DTOR_2; + + sinr = sinf(r); + cosr = __cosf(r); + sinp = sinf(p); + cosp = __cosf(p); + sinh = sinf(h); + cosh = __cosf(h); + + guMtxIdentF(mf); + + mf[0][0] = cosp*cosh; + mf[0][1] = cosp*sinh; + mf[0][2] = -sinp; + + mf[1][0] = sinr*sinp*cosh - cosr*sinh; + mf[1][1] = sinr*sinp*sinh + cosr*cosh; + mf[1][2] = sinr*cosp; + + mf[2][0] = cosr*sinp*cosh + sinr*sinh; + mf[2][1] = cosr*sinp*sinh - sinr*cosh; + mf[2][2] = cosr*cosp; +} + +void guRotateRPY(Mtx *m, float r, float p, float h) +{ + Matrix mf; + + guRotateRPYF(mf, r, p, h); + + guMtxF2L(mf, m); +} diff --git a/src/libultra/gu/sqrtf.c b/src/libultra/gu/sqrtf.c new file mode 100644 index 0000000..7cfab9c --- /dev/null +++ b/src/libultra/gu/sqrtf.c @@ -0,0 +1,11 @@ +#include + +#pragma intrinsic(sqrtf) + +#ifndef __GNUC__ +#define __builtin_sqrtf sqrtf +#endif + +f32 sqrtf(f32 f) { + return __builtin_sqrtf(f); +} diff --git a/src/libultra/gu/translate.c b/src/libultra/gu/translate.c new file mode 100644 index 0000000..8e46be0 --- /dev/null +++ b/src/libultra/gu/translate.c @@ -0,0 +1,31 @@ +/************************************************************************** + * * + * 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. * + * * + **************************************************************************/ + +#include "guint.h" + +void guTranslateF(float mf[4][4], float x, float y, float z) +{ + guMtxIdentF(mf); + + mf[3][0] = x; + mf[3][1] = y; + mf[3][2] = z; +} + +void guTranslate(Mtx *m, float x, float y, float z) +{ + Matrix mf; + + guTranslateF(mf, x, y, z); + + guMtxF2L(mf, m); +} diff --git a/src/libultra/io/conteeplongwrite.c b/src/libultra/io/conteeplongwrite.c new file mode 100644 index 0000000..0124860 --- /dev/null +++ b/src/libultra/io/conteeplongwrite.c @@ -0,0 +1,18 @@ +#include +#include "ultra64/controller.h" + +s32 osEepromLongWrite(OSMesgQueue *mq, u8 address, u8 *buffer, int length) +{ + s32 ret; + ret = 0; + while (length > 0) + { + ERRCK(osEepromWrite(mq, address, buffer)); + length -= EEPROM_BLOCK_SIZE; + address++; + buffer += EEPROM_BLOCK_SIZE; + osSetTimer(&__osEepromTimer, 562500, 0, &__osEepromTimerQ, &__osEepromTimerMsg); + osRecvMesg(&__osEepromTimerQ, NULL, OS_MESG_BLOCK); + } + return ret; +} diff --git a/src/libultra/io/epidma.c b/src/libultra/io/epidma.c new file mode 100644 index 0000000..6009385 --- /dev/null +++ b/src/libultra/io/epidma.c @@ -0,0 +1,28 @@ +#include +#include "piint.h" + +s32 osEPiStartDma(OSPiHandle *pihandle, OSIoMesg *mb, s32 direction) +{ + register s32 ret; + + if (!__osPiDevMgr.active) + return -1; + 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(), mb, OS_MESG_NOBLOCK); + } + else + { + ret = osSendMesg(osPiGetCmdQueue(), mb, OS_MESG_NOBLOCK); + } + return ret; +} diff --git a/src/libultra/io/epirawdma.c b/src/libultra/io/epirawdma.c new file mode 100644 index 0000000..0dc889f --- /dev/null +++ b/src/libultra/io/epirawdma.c @@ -0,0 +1,24 @@ +#include "piint.h" + +s32 osEPiRawStartDma(OSPiHandle *pihandle, s32 direction, u32 devAddr, void *dramAddr, u32 size) +{ + u32 stat; + u32 domain; + + 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; +} diff --git a/src/libultra/io/epirawread.c b/src/libultra/io/epirawread.c new file mode 100644 index 0000000..44be711 --- /dev/null +++ b/src/libultra/io/epirawread.c @@ -0,0 +1,11 @@ +#include "piint.h" + +s32 osEPiRawReadIo(OSPiHandle* pihandle, u32 devAddr, u32* data) { + u32 stat; + u32 domain; + + EPI_SYNC(pihandle, stat, domain); + *data = IO_READ(pihandle->baseAddress | devAddr); + + return 0; +} diff --git a/src/libultra/io/gbpakgetstatus.c b/src/libultra/io/gbpakgetstatus.c new file mode 100644 index 0000000..2d45bb3 --- /dev/null +++ b/src/libultra/io/gbpakgetstatus.c @@ -0,0 +1,49 @@ +#include +#include "ultra64/controller.h" +#include "siint.h" + +s32 osGbpakGetStatus(OSPfs *pfs, u8 *status) +{ + s32 ret; + s32 i; + u8 buffer[32]; + + ret = __osContRamRead(pfs->queue, pfs->channel, 0x400, buffer); + + if (ret == PFS_ERR_NEW_PACK || buffer[31] != (OS_GBPAK_RSTB_DETECTION | OS_GBPAK_GBCART_ON)) { + ret = osGbpakInit(pfs->queue, pfs, pfs->channel); + + if (ret != 0) { + return ret; + } + } + + ret = __osContRamRead(pfs->queue, pfs->channel, 0x580, buffer); + + if (ret == 0) { + ret = __osPfsGetStatus(pfs->queue, pfs->channel); + + if (ret != 0) { + return ret; + } + + *status = buffer[0]; + + for (i = 1; i < 32; i++) { + *status |= ((u8 *)buffer)[i]; + } + + *status &= (OS_GBPAK_RSTB_DETECTION | OS_GBPAK_GBCART_PULL); + *status |= buffer[31]; + + if ((*status & OS_GBPAK_GBCART_ON) == 0) { + ret = PFS_ERR_NO_GBCART; + } else if (*status & OS_GBPAK_GBCART_PULL) { + ret = PFS_ERR_NEW_GBCART; + } + } else if (ret == PFS_ERR_NEW_PACK) { + ret = PFS_ERR_CONTRFAIL; + } + + return ret; +} diff --git a/src/libultra/io/piint.h b/src/libultra/io/piint.h index b618cd3..734fdde 100644 --- a/src/libultra/io/piint.h +++ b/src/libultra/io/piint.h @@ -1,7 +1,8 @@ -#ifndef _PIINT_H -#define _PIINT_H -#include -#include +#ifndef _PIINT_H_ +#define _PIINT_H_ + +#include "PR/os_internal.h" +#include "PR/rcp.h" //https://github.com/LuigiBlood/64dd/wiki/Memory-Map @@ -104,42 +105,50 @@ void __osDevMgrMain(void *); void __osPiCreateAccessQueue(void); void __osPiRelAccess(void); void __osPiGetAccess(void); +s32 __osPiRawStartDma(s32, u32 , void *, u32 ); +s32 __osPiRawWriteIo(u32, u32); +s32 __osPiRawReadIo(u32, u32 *); +s32 __osEPiRawWriteIo(OSPiHandle *, u32 , u32); +s32 __osEPiRawReadIo(OSPiHandle *, u32 , u32 *); +s32 __osEPiRawStartDma(OSPiHandle *, s32 , u32 , void *, u32 ); OSMesgQueue *osPiGetCmdQueue(void); -#define OS_RAMROM_STACKSIZE 1024 +#define WAIT_ON_IOBUSY(stat) \ + while (stat = IO_READ(PI_STATUS_REG), stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) \ + ; \ + (void)0 -#define WAIT_ON_IOBUSY(stat) \ - stat = IO_READ(PI_STATUS_REG); \ - while (stat & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) \ - stat = IO_READ(PI_STATUS_REG); - -#define UPDATE_REG(reg, var) \ +#define UPDATE_REG(pihandle, reg, var) \ if (cHandle->var != pihandle->var) \ - IO_WRITE(reg, pihandle->var); + IO_WRITE(reg, pihandle->var) -#define EPI_SYNC(pihandle, stat, domain) \ - \ - WAIT_ON_IOBUSY(stat) \ - \ - domain = pihandle->domain; \ - if (__osCurrentHandle[domain] != pihandle) \ - { \ - OSPiHandle *cHandle = __osCurrentHandle[domain]; \ - if (domain == PI_DOMAIN1) \ - { \ - UPDATE_REG(PI_BSD_DOM1_LAT_REG, latency); \ - UPDATE_REG(PI_BSD_DOM1_PGS_REG, pageSize); \ - UPDATE_REG(PI_BSD_DOM1_RLS_REG, relDuration); \ - UPDATE_REG(PI_BSD_DOM1_PWD_REG, pulse); \ - } \ - else \ - { \ - UPDATE_REG(PI_BSD_DOM2_LAT_REG, latency); \ - UPDATE_REG(PI_BSD_DOM2_PGS_REG, pageSize); \ - UPDATE_REG(PI_BSD_DOM2_RLS_REG, relDuration); \ - UPDATE_REG(PI_BSD_DOM2_PWD_REG, pulse); \ - } \ - __osCurrentHandle[domain] = pihandle; \ - } +#define EPI_SYNC(pihandle, stat, domain) \ + \ + WAIT_ON_IOBUSY(stat); \ + \ + domain = pihandle->domain; \ + if (__osCurrentHandle[domain]->type != pihandle->type) \ + { \ + OSPiHandle *cHandle = __osCurrentHandle[domain]; \ + if (domain == PI_DOMAIN1) \ + { \ + UPDATE_REG(pihandle, PI_BSD_DOM1_LAT_REG, latency); \ + UPDATE_REG(pihandle, PI_BSD_DOM1_PGS_REG, pageSize); \ + UPDATE_REG(pihandle, PI_BSD_DOM1_RLS_REG, relDuration); \ + UPDATE_REG(pihandle, PI_BSD_DOM1_PWD_REG, pulse); \ + } \ + else \ + { \ + UPDATE_REG(pihandle, PI_BSD_DOM2_LAT_REG, latency); \ + UPDATE_REG(pihandle, PI_BSD_DOM2_PGS_REG, pageSize); \ + UPDATE_REG(pihandle, PI_BSD_DOM2_RLS_REG, relDuration); \ + UPDATE_REG(pihandle, PI_BSD_DOM2_PWD_REG, pulse); \ + } \ + cHandle->type = pihandle->type; \ + cHandle->latency = pihandle->latency; \ + cHandle->pageSize = pihandle->pageSize; \ + cHandle->relDuration = pihandle->relDuration; \ + cHandle->pulse = pihandle->pulse; \ + }(void)0 #endif diff --git a/src/libultra/io/si.c b/src/libultra/io/si.c new file mode 100644 index 0000000..c20c71b --- /dev/null +++ b/src/libultra/io/si.c @@ -0,0 +1,10 @@ +#include +#include "siint.h" + +int __osSiDeviceBusy() +{ + register u32 stat = IO_READ(SI_STATUS_REG); + if (stat & (SI_STATUS_DMA_BUSY | SI_STATUS_RD_BUSY)) + return 1; + return 0; +} diff --git a/src/libultra/io/sp.c b/src/libultra/io/sp.c new file mode 100644 index 0000000..9517083 --- /dev/null +++ b/src/libultra/io/sp.c @@ -0,0 +1,11 @@ +#include +#include +#include + +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 1; + return 0; +} diff --git a/src/libultra/io/sptaskyielded.c b/src/libultra/io/sptaskyielded.c new file mode 100644 index 0000000..030f46e --- /dev/null +++ b/src/libultra/io/sptaskyielded.c @@ -0,0 +1,23 @@ +#include "PR/os_internal.h" +#include "PR/sptask.h" +#include "PR/rcp.h" + +OSYieldResult osSpTaskYielded(OSTask *tp) { + u32 status; + OSYieldResult result; + + status = __osSpGetStatus(); + + if (status & SP_STATUS_YIELDED) { + result = OS_TASK_YIELDED; + } else { + result = 0; + } + + if (status & SP_STATUS_YIELD) { + tp->t.flags |= result; + tp->t.flags &= ~(OS_TASK_DP_WAIT); + } + + return result; +} diff --git a/src/libultra/io/viint.h b/src/libultra/io/viint.h index f80e754..3ae94c8 100644 --- a/src/libultra/io/viint.h +++ b/src/libultra/io/viint.h @@ -1,20 +1,19 @@ #ifndef _VIINT_H #define _VIINT_H -#include +#include "PR/os_internal.h" #define OS_TV_TYPE_PAL 0 #define OS_TV_TYPE_NTSC 1 #define OS_TV_TYPE_MPAL 2 -//TODO: figure out what this is -#define VI_STATE_01 0x01 +#define VI_STATE_MODE_UPDATED 0x01 #define VI_STATE_XSCALE_UPDATED 0x02 #define VI_STATE_YSCALE_UPDATED 0x04 -#define VI_STATE_08 0x08 //related to control regs changing -#define VI_STATE_10 0x10 //swap buffer -#define VI_STATE_BLACK 0x20 //probably related to a black screen -#define VI_STATE_REPEATLINE 0x40 //repeat line? -#define VI_STATE_FADE 0x80 //fade +#define VI_STATE_CTRL_UPDATED 0x08 // related to control regs changing +#define VI_STATE_BUFFER_UPDATED 0x10 // swap buffer +#define VI_STATE_BLACK 0x20 // probably related to a black screen +#define VI_STATE_REPEATLINE 0x40 // repeat line? +#define VI_STATE_FADE 0x80 // fade #define VI_CTRL_ANTIALIAS_MODE_3 0x00300 /* Bit [9:8] anti-alias mode */ #define VI_CTRL_ANTIALIAS_MODE_2 0x00200 /* Bit [9:8] anti-alias mode */ @@ -25,7 +24,7 @@ #define VI_SUBPIXEL_SH 0x10 #define BURST(hsync_width, color_width, vsync_width, color_start) \ - (hsync_width | (color_width << 8) | (vsync_width << 16) | (color_start << 20)) + (hsync_width | (color_width << 8) | (vsync_width << 16) | (color_start << 20)) #define WIDTH(v) v #define VSYNC(v) v #define HSYNC(duration, leap) (duration | (leap << 16)) @@ -44,27 +43,28 @@ typedef struct { - /* 0x0 */ f32 factor; - /* 0x4 */ u16 offset; - /* 0x8 */ u32 scale; + /* 0x0 */ f32 factor; + /* 0x4 */ u16 offset; + /* 0x8 */ u32 scale; } __OSViScale; typedef struct { - /* 0x0 */ u16 state; - /* 0x2 */ u16 retraceCount; - /* 0x4 */ void *framep; - /* 0x8 */ OSViMode *modep; - /* 0xC */ u32 control; - /* 0x10 */ OSMesgQueue *msgq; - /* 0x14 */ OSMesg msg; - /* 0x18 */ __OSViScale x; - /* 0x24 */ __OSViScale y; -} __OSViContext; + /* 0x0 */ u16 state; + /* 0x2 */ u16 retraceCount; + /* 0x4 */ void *framep; + /* 0x8 */ OSViMode *modep; + /* 0xC */ u32 control; + /* 0x10 */ OSMesgQueue *msgq; + /* 0x14 */ OSMesg msg; + /* 0x18 */ __OSViScale x; + /* 0x24 */ __OSViScale y; +} __OSViContext; // 0x30 bytes void __osViSwapContext(void); extern __OSViContext *__osViCurr; extern __OSViContext *__osViNext; +extern u32 __additional_scanline; __OSViContext *__osViGetCurrentContext(void); void __osViInit(void); #endif diff --git a/src/libultra/io/visetmode.c b/src/libultra/io/visetmode.c index 7c1d43a..03ddae7 100644 --- a/src/libultra/io/visetmode.c +++ b/src/libultra/io/visetmode.c @@ -6,7 +6,7 @@ void osViSetMode(OSViMode *modep) register u32 saveMask; saveMask = __osDisableInt(); __osViNext->modep = modep; - __osViNext->state = VI_STATE_01; + __osViNext->state = VI_STATE_MODE_UPDATED; __osViNext->control = __osViNext->modep->comRegs.ctrl; __osRestoreInt(saveMask); } diff --git a/src/libultra/io/viswapbuf.c b/src/libultra/io/viswapbuf.c new file mode 100644 index 0000000..ee58f17 --- /dev/null +++ b/src/libultra/io/viswapbuf.c @@ -0,0 +1,10 @@ +#include +#include "viint.h" + +void osViSwapBuffer(void* frameBufPtr) { + u32 saveMask = __osDisableInt(); + + __osViNext->framep = frameBufPtr; + __osViNext->state |= VI_STATE_BUFFER_UPDATED; + __osRestoreInt(saveMask); +} diff --git a/src/libultra/libc/sprintf.c b/src/libultra/libc/sprintf.c new file mode 100644 index 0000000..fb0eb6e --- /dev/null +++ b/src/libultra/libc/sprintf.c @@ -0,0 +1,25 @@ +#include +#include "stdarg.h" + +typedef unsigned long uintptr_t; + +int _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args); + +void* proutSprintf(void* dst, const char* fmt, size_t size) { + return (void*)((uintptr_t)memcpy(dst, fmt, size) + size); +} + +int sprintf(char* dst, char* fmt, ...) { + int ans; + va_list args; + va_start(args, fmt); + + ans = _Printf((void*)&proutSprintf, dst, fmt, args); + if (ans > -1) { + dst[ans] = 0; + } + + va_end(args); + + return ans; +} diff --git a/src/libultra/libc/string.c b/src/libultra/libc/string.c new file mode 100644 index 0000000..5f085f6 --- /dev/null +++ b/src/libultra/libc/string.c @@ -0,0 +1,38 @@ +#include "string.h" + +const char* strchr(const char* s, int c) { + const unsigned char ch = c; + + while (*s != ch) { + if (*s == '\0') { + return NULL; + } + s++; + } + + return s; +} + +size_t strlen(const char* s) { + const char* sc = s; + + while (*sc != '\0') { + sc++; + } + + return (size_t)(sc - s); +} + +void* memcpy(void* s1, const void* s2, size_t n) { + unsigned char* su1 = (unsigned char*)s1; + const unsigned char* su2 = (const unsigned char*)s2; + + while (n > 0) { + *su1 = *su2; + su1++; + su2++; + n--; + } + + return s1; +} diff --git a/src/libultra/libc/syncprintf.c b/src/libultra/libc/syncprintf.c new file mode 100644 index 0000000..0dc0ce9 --- /dev/null +++ b/src/libultra/libc/syncprintf.c @@ -0,0 +1,13 @@ +#include + +void osSyncPrintf(const char *fmt, ...) +{ + int ans; + va_list ap; + // these functions intentionally left blank. ifdeffed out in rom release +} +void rmonPrintf(const char *fmt, ...) +{ + int ans; + va_list ap; +} diff --git a/src/libultra/libc/xprintf.c b/src/libultra/libc/xprintf.c new file mode 100644 index 0000000..893ca31 --- /dev/null +++ b/src/libultra/libc/xprintf.c @@ -0,0 +1,244 @@ +#include +#include +#include "xstdio.h" + +#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.size += (n); \ + else \ + return x.size; \ + } +static char spaces[] = " "; +static char zeroes[] = "00000000000000000000000000000000"; + +static void _Putfld(printf_struct *pf, va_list *pap, char code, char *ac); +int _Printf(outfun prout, char *arg, const char *fmt, va_list args) +{ + printf_struct x; + const char *s; + char c; + const char *t; + static const char fchar[6] = " +-#0"; + static const int fbit[6] = {FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0}; + char ac[32]; + x.size = 0; + for (;;) + { + s = fmt; + for (c = *s; c != 0 && c != '%';) + { + + c = *++s; + } + PUT(fmt, s - fmt); + if (c == 0) + return x.size; + 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.precision = -1; + else if (*++s == '*') + { + x.precision = va_arg(args, int); + ++s; + } + else + { + ATOI(x.precision, s); + } + x.length = strchr("hlL", *s) ? *s++ : '\0'; + if (x.length == 'l' && *s == 'l') + { + x.length = 'L'; + ++s; + } + _Putfld(&x, &args, *s, ac); + x.width -= x.n0 + x.num_leading_zeros + x.part2_len + x.num_mid_zeros + x.part3_len + x.num_trailing_zeros; + if (!(x.flags & FLAGS_MINUS)) + PAD(spaces, x.width); + PUT(ac, x.n0); + PAD(zeroes, x.num_leading_zeros); + PUT(x.buff, x.part2_len); + PAD(zeroes, x.num_mid_zeros); + PUT(x.buff + x.part2_len, x.part3_len); + PAD(zeroes, x.num_trailing_zeros); + if (x.flags & FLAGS_MINUS) + PAD(spaces, x.width); + fmt = s + 1; + } + return 0; +} + +static void _Putfld(printf_struct *x, va_list *args, char type, char *buff) +{ + x->n0 = x->num_leading_zeros = x->part2_len = x->num_mid_zeros = x->part3_len = + x->num_trailing_zeros = 0; + + switch (type) + { + case 'c': + buff[x->n0++] = va_arg(*args, int); + break; + + case 'd': + case 'i': + if (x->length == 'l') + x->value.s64 = va_arg(*args, int); + else if (x->length == 'L') + x->value.s64 = va_arg(*args, s64); + else + x->value.s64 = va_arg(*args, int); + + if (x->length == 'h') + { + x->value.s64 = (s16)x->value.s64; + } + + if (x->value.s64 < 0) + { + buff[x->n0++] = '-'; + } + else if (x->flags & FLAGS_PLUS) + { + buff[x->n0++] = '+'; + } + else if (x->flags & FLAGS_SPACE) + { + buff[x->n0++] = ' '; + } + + x->buff = (char *)&buff[x->n0]; + + _Litob(x, type); + break; + + case 'x': + case 'X': + case 'u': + case 'o': + if (x->length == 'l') + { + x->value.s64 = va_arg(*args, int); + } + else if (x->length == 'L') + { + x->value.s64 = va_arg(*args, s64); + } + else + { + x->value.s64 = va_arg(*args, int); + } + + if (x->length == 'h') + { + x->value.s64 = (u16)x->value.s64; + } + else if (x->length == 0) + { + x->value.s64 = (unsigned int)x->value.s64; + } + + if (x->flags & FLAGS_HASH) + { + buff[x->n0++] = '0'; + if (type == 'x' || type == 'X') + { + + buff[x->n0++] = type; + } + } + x->buff = (char *)&buff[x->n0]; + _Litob(x, type); + break; + + case 'e': + case 'f': + case 'g': + case 'E': + case 'G': + //... okay? + x->value.f64 = x->length == 'L' ? va_arg(*args, f64) : va_arg(*args, f64); + + if (LDSIGN(x->value.f64)) + buff[x->n0++] = '-'; + else if (x->flags & FLAGS_PLUS) + buff[x->n0++] = '+'; + else if (x->flags & FLAGS_SPACE) + buff[x->n0++] = ' '; + + x->buff = (char *)&buff[x->n0]; + _Ldtob(x, type); + break; + + case 'n': + if (x->length == 'h') + *(va_arg(*args, u16 *)) = x->size; + else if (x->length == 'l') + *va_arg(*args, unsigned int *) = x->size; + else if (x->length == 'L') + *va_arg(*args, u64 *) = x->size; + else + *va_arg(*args, unsigned int *) = x->size; + break; + + case 'p': + x->value.s64 = (long)va_arg(*args, void *); + x->buff = (char *)&buff[x->n0]; + _Litob(x, 'x'); + break; + + case 's': + x->buff = va_arg(*args, char *); + x->part2_len = strlen(x->buff); + if (x->precision >= 0 && x->part2_len > x->precision) + x->part2_len = x->precision; + break; + case '%': + //this doesn't match in -g because of regalloc issues?? + buff[x->n0++] = '%'; + break; + default: + buff[x->n0++] = type; + break; + } +} diff --git a/src/libultra/os/afterprenmi.c b/src/libultra/os/afterprenmi.c new file mode 100644 index 0000000..234d4b7 --- /dev/null +++ b/src/libultra/os/afterprenmi.c @@ -0,0 +1,5 @@ +#include + +s32 osAfterPreNMI(void) { + return __osSpSetPc(0); +} diff --git a/src/libultra/os/createmesgqueue.c b/src/libultra/os/createmesgqueue.c new file mode 100644 index 0000000..2649739 --- /dev/null +++ b/src/libultra/os/createmesgqueue.c @@ -0,0 +1,13 @@ +#include + +extern void *__osThreadTail; + +void osCreateMesgQueue(OSMesgQueue *mq, OSMesg *msg, s32 msgCount) +{ + mq->mtqueue = (OSThread *)&__osThreadTail; + mq->fullqueue = (OSThread *)&__osThreadTail; + mq->validCount = 0; + mq->first = 0; + mq->msgCount = msgCount; + mq->msg = msg; +} diff --git a/src/libultra/os/getthreadpri.c b/src/libultra/os/getthreadpri.c new file mode 100644 index 0000000..21a6dda --- /dev/null +++ b/src/libultra/os/getthreadpri.c @@ -0,0 +1,9 @@ +#include + +extern OSThread *__osRunningThread; +OSPri osGetThreadPri(OSThread *thread) +{ + if (thread == NULL) + thread = __osRunningThread; + return thread->priority; +} diff --git a/src/libultra/os/initialize.c b/src/libultra/os/initialize.c index f87df23..a1cf36e 100644 --- a/src/libultra/os/initialize.c +++ b/src/libultra/os/initialize.c @@ -19,7 +19,7 @@ OSTime osClockRate = 62500000; s32 osViClock = VI_NTSC_CLOCK; -u32 _osShutdown = 0; +u32 __osShutdown = 0; u32 __osGlobalIntMask = OS_IM_ALL; u32 var8005cf74 = 0; diff --git a/src/libultra/os/jammesg.c b/src/libultra/os/jammesg.c new file mode 100644 index 0000000..894c15c --- /dev/null +++ b/src/libultra/os/jammesg.c @@ -0,0 +1,31 @@ +#include + +extern OSThread *__osRunningThread; + +s32 osJamMesg(OSMesgQueue *mq, OSMesg msg, s32 flag) +{ + register u32 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; +} diff --git a/src/libultra/os/seteventmesg.c b/src/libultra/os/seteventmesg.c new file mode 100644 index 0000000..701eea2 --- /dev/null +++ b/src/libultra/os/seteventmesg.c @@ -0,0 +1,23 @@ +#include +#include "ultra64/internal.h" + +extern __OSEventState __osEventStateTab[OS_NUM_EVENTS]; + +extern u32 __osPreNMI; +extern u32 __osShutdown; + +void osSetEventMesg(OSEvent e, OSMesgQueue* mq, OSMesg msg) { + register u32 prevInt = __osDisableInt(); + __OSEventState* msgs = &__osEventStateTab[e]; + + msgs->queue = mq; + msgs->msg = msg; + + if (e == OS_EVENT_PRENMI) { + if (__osShutdown && !__osPreNMI) { + osSendMesg(mq, msg, OS_MESG_NOBLOCK); + } + __osPreNMI = true; + } + __osRestoreInt(prevInt); +} diff --git a/src/libultra/os/setthreadpri.c b/src/libultra/os/setthreadpri.c new file mode 100644 index 0000000..870c1b3 --- /dev/null +++ b/src/libultra/os/setthreadpri.c @@ -0,0 +1,26 @@ +#include + +extern OSThread* __osRunningThread; +extern OSThread* __osRunQueue; + +void osSetThreadPri(OSThread *t, OSPri pri) +{ + register u32 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); +} diff --git a/tools/symbol_addrs.txt b/tools/symbol_addrs.txt index e8407fc..1675cf4 100644 --- a/tools/symbol_addrs.txt +++ b/tools/symbol_addrs.txt @@ -315,7 +315,7 @@ __osGetCause = 0x80063E00; CartRomHandle = 0x80102430; LeoDiskHandle = 0x801024A8; __osGlobalIntMask = 0x800796B0; -_osShutdown = 0x800796AC; +__osShutdown = 0x800796AC; osViClock = 0x800796A8; __osPfsInodeCacheBank = 0x8007A934; __osPfsPifRam = 0x801023F0; @@ -350,4 +350,11 @@ osRomBase = 0x80000308; __osEepPifRam = 0x80104B70; osGetCount = 0x8005BD00; __osPfsInodeCacheChannel = 0x8007A930; -__osPfsInodeCache = 0x801036F0; \ No newline at end of file +__osPfsInodeCache = 0x801036F0; +__osPreNMI = 0x8007A940; +__osEventStateTab = 0x801037F0; +osAfterPreNMI = 0x8005CEC0; +__osThreadTail = 0x80079620; +__osRunQueue = 0x80079628; +__osEnqueueThread = 0x80057DEC; +__osCurrentHandle = 0x8007A880; \ No newline at end of file