diff --git a/Makefile b/Makefile index 0579c99..1043325 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,8 @@ AS := tools/kmc-gcc-wrapper/as CC := tools/kmc-gcc-wrapper/gcc AR_OLD := tools/ar -CFLAGS := -D_LANGUAGE_C -D_MIPS_SZLONG=32 -D_FINALROM -w -nostdinc -c -G 0 -mgp32 -mfp32 -mips3 +CFLAGS := -w -nostdinc -c -G 0 -mgp32 -mfp32 -mips3 +CPPFLAGS := -D_LANGUAGE_C -D_MIPS_SZLONG=32 -D_FINALROM -D__USE_ISOC99 -DNDEBUG -DF3DEX_GBI_2 -I $(WORKING_DIR)/include -I $(WORKING_DIR)/include/gcc OPTFLAGS := -O3 SRC_DIRS := $(shell find src -type d) @@ -93,7 +94,7 @@ $(BUILD_DIR)/src/os/exit.marker: OPTFLAGS := -O0 $(BUILD_DIR)/src/os/seterrorhandler.marker: OPTFLAGS := -O0 $(BUILD_DIR)/%.marker: %.c - cd $( + + +/*************************************** + * + * Global defines + * + */ + /* Alignment sizes */ +#define ALIGNSZ (sizeof(long long)) /* 8 bytes */ +#define ALIGNOFFST (ALIGNSZ-1) + + /* size for storing index to free buffer */ +#define BUF_CTRL_SIZE ALIGNSZ + + /* Max bufcount = 32K */ +#define MAX_BUFCOUNT 0x8000 + /* code for last free buffer */ +#define BUF_FREE_WO_NEXT 0x8000 + +/* + * Global defines for alignment size (default is 8-byte alignment) + */ +#define OS_RG_ALIGN_2B 2 /* 2 bytes = 16-bit alignment */ +#define OS_RG_ALIGN_4B 4 /* 4 bytes = 32-bit alignment */ +#define OS_RG_ALIGN_8B 8 /* 8 bytes = 64-bit alignment */ +#define OS_RG_ALIGN_16B 16 /* 16 bytes = 128-bit alignment */ + +#define OS_RG_ALIGN_DEFAULT OS_RG_ALIGN_8B + + +/*************************************** + * + * Macro definitions + * + */ + +/* Perform alignment on input 's' */ +#define ALIGN(s, align) (((u32)(s) + ((align)-1)) & ~((align)-1)) + + +/*************************************** + * + * Typedefs & structure definitions + * + */ +/* + * Structure for region header/control area + */ +typedef struct _Region_s { + u8 *r_startBufferAddress; /* start address to data buffer */ + u8 *r_endAddress; /* end address of region */ + s32 r_bufferSize; /* size of buffers for this region */ + s32 r_bufferCount; /* up to 32K entries; MSB is used for + setting end-of-list/used */ + u16 r_freeList; /* point to array index of first + available memory buffer */ + u16 r_alignSize; /* alignment size (# of bytes) */ +} OSRegion; + +/* + * Macro to simplify accessing region header structure + */ +#define RP(x) rp->r_##x + + +/*************************************** + * + * Function prototypes + * + */ +extern void *osCreateRegion(void *, u32, u32, u32); +extern void *osMalloc(void *); +extern void osFree(void *, void *); +extern s32 osGetRegionBufCount(void *); +extern s32 osGetRegionBufSize(void *); + + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + + +#endif /* _REGION_H_ */ + + diff --git a/include/PR/sptask.h b/include/PR/sptask.h new file mode 100644 index 0000000..caa7604 --- /dev/null +++ b/include/PR/sptask.h @@ -0,0 +1,189 @@ +/************************************************************************** + * + * $Revision: 1.9 $ + * $Date: 1998/03/05 06:40:29 $ + * $Source: /exdisk2/cvs/N64OS/Master/cvsmdev2/PR/include/sptask.h,v $ + * + **************************************************************************/ + +#ifndef _SPTASK_H_ +#define _SPTASK_H_ + +#ifdef _LANGUAGE_C_PLUS_PLUS +extern "C" { +#endif + +#include + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Type definitions + * + */ + +/* + * Task List Structure. + * + * Things an app might pass to the SP via the task list. + * Not every task ucode would need/use every field, but + * + * - type (audio, gfx, video, ...) + * - flags + * - wait for DP to drain before running new task + * - SEE BIT DEFINITIONS UNDER "Task Flags field" + * - pointer to boot ucode + * - size of boot ucode + * - pointer to ucode + * - size of ucode + * - pointer to initial DMEM data + * - size of initial DMEM data + * - pointer to DRAM stack + * - size of DRAM stack (max) + * - pointer to output buffer + * - pointer to store output buffer length + * - generic data pointer (for display list, etc.) + * - generic data length (for display list, etc.) + * - pointer to buffer where to store saved DMEM (in yield case) + * - size of buffer to store saved DMEM. + * + * IMPORTANT!!! Watch alignment issues. + * + * IMPORTANT!!! Watch data cache issues. The RCP may write data into the + * dram_stack, output_buff, output_buff_size, and the yield_data_ptr areas. + * These buffers should be cache aligned and use the entire line (16 bytes) to + * avoid corruption by writebacks by the CPU (cache tearing). + * + * IMPORTANT!!! all addresses are virtual addresses. Library does + * any necessary translation. + * + */ +typedef struct { + u32 type; + u32 flags; + + u64 *ucode_boot; + u32 ucode_boot_size; + + u64 *ucode; + u32 ucode_size; + + u64 *ucode_data; + u32 ucode_data_size; + + u64 *dram_stack; + u32 dram_stack_size; + + u64 *output_buff; + u64 *output_buff_size; + + u64 *data_ptr; + u32 data_size; + + u64 *yield_data_ptr; + u32 yield_data_size; + +} OSTask_t; + +typedef union { + OSTask_t t; + long long int force_structure_alignment; +} OSTask; + +typedef u32 OSYieldResult; + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_ASSEMBLY + +/* + * For the RSP ucode: + * offsets into the task structure + */ + +#include + +#endif + +/* + * Task Flags field + */ +#define OS_TASK_YIELDED 0x0001 +#define OS_TASK_DP_WAIT 0x0002 +#define OS_TASK_LOADABLE 0x0004 +#define OS_TASK_SP_ONLY 0x0008 +#define OS_TASK_USR0 0x0010 +#define OS_TASK_USR1 0x0020 +#define OS_TASK_USR2 0x0040 +#define OS_TASK_USR3 0x0080 + +/* + * Size of Yield buffer. The taskHdrPtr->t.yield_data_ptr must point to a + * buffer of this size. (The size is in bytes). ONLY If the task will NEVER + * yield it may be a null pointer. The buffer must be aligned to a 64 bit + * boundary. The taskHdrPtr->t.yield_data_ptr must be set to point to the + * buffer BEFORE the task is started. + */ +#if (defined(F3DEX_GBI)||defined(F3DLP_GBI)||defined(F3DEX_GBI_2)) +#define OS_YIELD_DATA_SIZE 0xc00 +#else +#define OS_YIELD_DATA_SIZE 0x900 +#endif +#define OS_YIELD_AUDIO_SIZE 0x400 + +/************************************************************************** + * + * Global definitions + * + */ + + + +#if defined(_LANGUAGE_C) || defined(_LANGUAGE_C_PLUS_PLUS) + +/************************************************************************** + * + * Macro definitions + * + */ + +/* + * this macro simulates atomic action. + */ +#define osSpTaskStart(tp) \ + { \ + osSpTaskLoad((tp)); \ + osSpTaskStartGo((tp)); \ + } + + +/************************************************************************** + * + * Extern variables + * + */ + + +/************************************************************************** + * + * Function prototypes + * + */ + +/* + * break this up into two steps for debugging. + */ +extern void osSpTaskLoad(OSTask *tp); +extern void osSpTaskStartGo(OSTask *tp); + +extern void osSpTaskYield(void); +extern OSYieldResult osSpTaskYielded(OSTask *tp); + +#endif /* _LANGUAGE_C */ + +#ifdef _LANGUAGE_C_PLUS_PLUS +} +#endif + +#endif /* !_SPTASK_H */ diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..7f1989a --- /dev/null +++ b/include/assert.h @@ -0,0 +1,12 @@ +#ifndef __ASSERT_H__ +#define __ASSERT_H__ + +#ifdef NDEBUG +#undef assert +#define assert(EX) ((void)0) +#else +extern void __assert(const char *, const char *, int); +#define assert(EX) ((EX)?((void)0):__assert( # EX , __FILE__, __LINE__)) +#endif /* NDEBUG */ + +#endif /* !__ASSERT_H__ */ diff --git a/include/gcc/memory.h b/include/gcc/memory.h new file mode 100644 index 0000000..edfff5e --- /dev/null +++ b/include/gcc/memory.h @@ -0,0 +1,23 @@ +#ifndef _MEMORY_H +#define _MEMORY_H +/* + memory.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +void *memccpy(void *,void *,int,size_t); +void *memchr(void *,int,size_t); +int memcmp(const void *,const void *,size_t); +void *memcpy(void *,const void *,size_t); +int memicmp(void *,void *,size_t); +void *memmove(void *,void *,size_t); +void *memset(void *,int,size_t); + +void movmem(void *,void *,unsigned); +void setmem(void *,unsigned,int); + +#endif diff --git a/include/gcc/stdarg.h b/include/gcc/stdarg.h new file mode 100755 index 0000000..af337f6 --- /dev/null +++ b/include/gcc/stdarg.h @@ -0,0 +1,121 @@ +#ifndef _STDARG_H +#define _STDARG_H +/* ---------------------------------------- */ +/* VARARGS for MIPS/GNU CC */ +/* */ +/* */ +/* */ +/* */ +/* ---------------------------------------- */ + +/* These macros implement varargs for GNU C--either traditional or ANSU. */ + +/* Define __gnuc_va_list. */ + +#ifndef __GNUC_VA_LIST +#define __GNUC_VA_LIST +typedef char * __gnuc_va_list; +#endif /* not __GNUC_VA_LIST */ + +/* If this is for internal libc use, don't define anything but + __gnuc_va_list. */ +#if defined (_STDARG_H) || defined (_VARARGS_H) + +/* In GCC version 2, we want an ellipsis at the end of the declaration + of the argument list. GCC version 1 can't parse it. */ + +#if __GNUC__ > 1 +#define __va_ellipsis ... +#else +#define __va_ellipsis +#endif + +#if __mips>=3 +#define __va_rounded_size(__TYPE) \ + (((sizeof (__TYPE) + 8 - 1) / 8) * 8) +#else +#define __va_rounded_size(__TYPE) \ + (((sizeof (__TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) +#endif + +/* Get definitions for _MIPS_SIM_ABI64 etc. */ +#ifdef _MIPS_SIM +#include +#endif + +#ifdef _STDARG_H +#if defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64) +#define va_start(__AP, __LASTARG) \ + (__AP = __builtin_next_arg (__LASTARG) - 64 \ + + (__builtin_args_info (2) > 8 ? 64 : __builtin_args_info(2) * 8)) +#else +#define va_start(__AP, __LASTARG) \ + (__AP = (__gnuc_va_list) __builtin_next_arg (__LASTARG)) +#endif + +#else +#define va_alist __builtin_va_alist +#if __mips>=3 +/* This assumes that `long long int' is always a 64 bit type. */ +#define va_dcl long long int __builtin_va_alist; __va_ellipsis +#else +#define va_dcl int __builtin_va_alist; __va_ellipsis +#endif +/* Need alternate code for _MIPS_SIM_ABI64, but don't use that symbol + because it may not be defined. */ +#if defined(_MIPS_SIM) && (_MIPS_SIM == _MIPS_SIM_ABI64) +#define va_start(__AP) \ + (__AP = __builtin_next_arg () - 64 \ + + (__builtin_args_info (2) > 8 ? 64 : __builtin_args_info(2) * 8)) +#else +#define va_start(__AP) __AP = (char *) &__builtin_va_alist +#endif +#endif + +#ifndef va_end +void va_end (__gnuc_va_list); /* Defined in libgcc.a */ +#endif +#define va_end(__AP) ((void)0) + +/* We cast to void * and then to TYPE * because this avoids + a warning about increasing the alignment requirement. */ +/* The __mips>=3 cases are reversed from the 32 bit cases, because the standard + 32 bit calling convention left-aligns all parameters smaller than a word, + whereas the __mips>=3 calling convention does not (and hence they are + right aligned). */ +#if __mips>=3 +#ifdef __MIPSEB__ +#define va_arg(__AP, __type) \ + ((__type *) (void *) (__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ + + __va_rounded_size (__type))))[-1] +#else +#define va_arg(__AP, __type) \ + ((__AP = (char *) ((((__PTRDIFF_TYPE__)__AP + 8 - 1) & -8) \ + + __va_rounded_size (__type))), \ + *(__type *) (void *) (__AP - __va_rounded_size (__type))) +#endif + +#else /* not __mips>=3 */ + +#ifdef __MIPSEB__ +/* For big-endian machines. */ +#define va_arg(__AP, __type) \ + ((__AP = (char *) ((__alignof__ (__type) > 4 \ + ? ((int)__AP + 8 - 1) & -8 \ + : ((int)__AP + 4 - 1) & -4) \ + + __va_rounded_size (__type))), \ + *(__type *) (void *) (__AP - __va_rounded_size (__type))) +#else +/* For little-endian machines. */ +#define va_arg(__AP, __type) \ + ((__type *) (void *) (__AP = (char *) ((__alignof__(__type) > 4 \ + ? ((int)__AP + 8 - 1) & -8 \ + : ((int)__AP + 4 - 1) & -4) \ + + __va_rounded_size(__type))))[-1] +#endif +#endif + +typedef __gnuc_va_list va_list; + +#endif /* defined (_STDARG_H) || defined (_VARARGS_H) */ +#endif diff --git a/include/gcc/stdlib.h b/include/gcc/stdlib.h new file mode 100644 index 0000000..98f8a2e --- /dev/null +++ b/include/gcc/stdlib.h @@ -0,0 +1,81 @@ +#ifndef _STDLIB_H +#define _STDLIB_H +/* + stdlib.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +#ifndef _DIV_T_DEF +#define _DIV_T_DEF +typedef struct DIV_T { + int quot; + int rem; +} div_t; +#endif + +#ifndef _LDIV_T_DEF +#define _LDIV_T_DEF +typedef struct LDIV_T { + long quot; + long rem; +} ldiv_t; +#endif + +#ifndef _LLDIV_T_DEF +#define _LLDIV_T_DEF +typedef struct lldiv_t +{ + long long quot; + long long rem; +} lldiv_t; +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define _max(a,b) (((a) > (b)) ? (a) : (b)) +#define _min(a,b) (((a) < (b)) ? (a) : (b)) + +#define RAND_MAX 32767 + +int rand(void); +void srand(unsigned); + +int abs(int); +long labs(long); + +div_t div(int,int); +ldiv_t ldiv(long,long); +lldiv_t lldiv(long long, long long); + +int atoi(const char *); +long atol(const char *); + +long strtol(const char *,char **,int); +unsigned long strtoul(const char *,char **,int); + +char *itoa(int,char *,int); +char *ltoa(long,char *,int); +char *ultoa(unsigned long,char *,int); + +double atof(const char *); +double strtod(const char *,char **); + +void qsort(void *,size_t,size_t,int (*)(const void *,const void *)); +void *bsearch(const void *,const void *,size_t,size_t,int (*)(const void *,const void *)); + +void *malloc(size_t); +void *calloc(size_t,size_t); +void *realloc(void *,size_t); +void free(void *); + +void exit(int); + +void abort(void); + +#endif diff --git a/include/gcc/string.h b/include/gcc/string.h new file mode 100755 index 0000000..d82e1f1 --- /dev/null +++ b/include/gcc/string.h @@ -0,0 +1,42 @@ +#ifndef _STRING_H +#define _STRING_H +/* + string.h +*/ + +#ifndef _SIZE_T_DEF +#define _SIZE_T_DEF +typedef unsigned size_t; +#endif + +#include "memory.h" + +char *stpcpy(char *,const char *); +char *strcat(char *,const char *); +char *strchr(const char *,int); +int strcmp(const char *,const char *); +char *strcpy(char *,const char *); +size_t strcspn(const char *,const char *); +char *strdup(const char *); +char *strerror(int); +int stricmp(const char *,const char *); +size_t strlen(const char *); +char *strlwr(char *); +char *strncat(char *,const char *,size_t); +int strncmp(const char *,const char *,size_t); +char *strncpy(char *,const char *,size_t); +int strnicmp(const char *,const char *,size_t); +char *strnset(char *,int,size_t); +char *strpbrk(const char *,const char *); +char *strrchr(const char *,int); +char *strrev(char *); +char *strset(char *,int); +size_t strspn(const char *,const char *); +char *strstr(const char *,const char *); +char *strtok(char *,const char *); +char *strupr(char *); + +#define strcmpi(s1,s2) stricmp(s1,s2) +#define strncmpi(s1,s2,n) strnicmp(s1,s2,n) + +#endif diff --git a/src/io/sp.c b/src/io/sp.c new file mode 100755 index 0000000..95d5b20 --- /dev/null +++ b/src/io/sp.c @@ -0,0 +1,17 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "PR/sptask.h" +#include "../os/osint.h" + +// 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; + } + + return FALSE; +} diff --git a/src/io/spgetstat.c b/src/io/spgetstat.c new file mode 100755 index 0000000..0cdfda6 --- /dev/null +++ b/src/io/spgetstat.c @@ -0,0 +1,9 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +u32 __osSpGetStatus() { + return IO_READ(SP_STATUS_REG); +} diff --git a/src/io/sprawdma.c b/src/io/sprawdma.c new file mode 100755 index 0000000..41239b1 --- /dev/null +++ b/src/io/sprawdma.c @@ -0,0 +1,30 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "../os/osint.h" +#include "assert.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +s32 __osSpRawStartDma(s32 direction, u32 devAddr, void *dramAddr, u32 size) { + // These asserts are present in debug builds, but the line numbers won't match as-is + // TODO Add an assert spoofing macro that lets you specify a line number + 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; +} diff --git a/src/io/sprawread.c b/src/io/sprawread.c new file mode 100755 index 0000000..affc78b --- /dev/null +++ b/src/io/sprawread.c @@ -0,0 +1,16 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "../os/osint.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +s32 __osSpRawReadIo(u32 devAddr, u32 *data) { + if (__osSpDeviceBusy()) { + return -1; + } + + *data = IO_READ(devAddr); + return 0; +} + diff --git a/src/io/sprawwrite.c b/src/io/sprawwrite.c new file mode 100755 index 0000000..f6451ae --- /dev/null +++ b/src/io/sprawwrite.c @@ -0,0 +1,15 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" +#include "../os/osint.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +s32 __osSpRawWriteIo(u32 devAddr, u32 data) { + if (__osSpDeviceBusy()) { + return -1; + } + + IO_WRITE(devAddr, data); + return 0; +} diff --git a/src/io/spsetstat.c b/src/io/spsetstat.c new file mode 100755 index 0000000..2ab47e0 --- /dev/null +++ b/src/io/spsetstat.c @@ -0,0 +1,9 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +void __osSpSetStatus(u32 data) { + IO_WRITE(SP_STATUS_REG, data); +} diff --git a/src/io/sptask.c b/src/io/sptask.c new file mode 100755 index 0000000..13d6f00 --- /dev/null +++ b/src/io/sptask.c @@ -0,0 +1,63 @@ +#include "PR/os_internal.h" +#include "PR/sptask.h" +#include "PR/rcp.h" +#include "../os/osint.h" + +#define _osVirtualToPhysical(ptr) \ + if (ptr != NULL) \ + { \ + ptr = (void *)osVirtualToPhysical(ptr); \ + } + +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; + + 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); +} diff --git a/src/io/sptaskyield.c b/src/io/sptaskyield.c new file mode 100755 index 0000000..78bacae --- /dev/null +++ b/src/io/sptaskyield.c @@ -0,0 +1,6 @@ +#include "PR/os_internal.h" +#include "PR/rcp.h" + +void osSpTaskYield(void) { + __osSpSetStatus(SP_SET_YIELD); +} diff --git a/src/io/sptaskyielded.c b/src/io/sptaskyielded.c new file mode 100755 index 0000000..6c18c21 --- /dev/null +++ b/src/io/sptaskyielded.c @@ -0,0 +1,18 @@ +#include "PR/os_internal.h" +#include "PR/sptask.h" +#include "PR/rcp.h" + +OSYieldResult osSpTaskYielded(OSTask *tp) { + u32 status; + OSYieldResult result; + + status = __osSpGetStatus(); + result = status >> 8; + result &= 1; + + if (status & SP_STATUS_YIELD) { + tp->t.flags = ~(OS_TASK_DP_WAIT) & (tp->t.flags | result); + } + + return result; +} diff --git a/src/io/visetmode.c b/src/io/visetmode.c index d9a1d81..655cba6 100644 --- a/src/io/visetmode.c +++ b/src/io/visetmode.c @@ -8,7 +8,7 @@ void osViSetMode(OSViMode *modep) { register u32 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/io/visetspecial.c b/src/io/visetspecial.c index 00ce7f3..e8f90b8 100644 --- a/src/io/visetspecial.c +++ b/src/io/visetspecial.c @@ -42,7 +42,7 @@ void osViSetSpecialFeatures(u32 func) { __osViNext->control |= __osViNext->modep->comRegs.ctrl & VI_CTRL_ANTIALIAS_MASK; } - __osViNext->state |= VI_STATE_08; + __osViNext->state |= VI_STATE_CTRL_UPDATED; __osRestoreInt(saveMask); } diff --git a/src/io/viswapbuf.c b/src/io/viswapbuf.c index 5a2280c..327ed60 100644 --- a/src/io/viswapbuf.c +++ b/src/io/viswapbuf.c @@ -8,6 +8,6 @@ void osViSwapBuffer(void* frameBufPtr) { u32 saveMask = __osDisableInt(); __osViNext->framep = frameBufPtr; - __osViNext->state |= VI_STATE_10; + __osViNext->state |= VI_STATE_BUFFER_UPDATED; __osRestoreInt(saveMask); } diff --git a/src/libc/ldiv.c b/src/libc/ldiv.c new file mode 100755 index 0000000..59644e9 --- /dev/null +++ b/src/libc/ldiv.c @@ -0,0 +1,33 @@ +#include "stdlib.h" + +// TODO: these come from headers +#ident "$Revision: 1.34 $" +#ident "$Revision: 1.5 $" + +ldiv_t ldiv(long num, long denom) { + ldiv_t ret; + + ret.quot = num / denom; + ret.rem = num - denom * ret.quot; + + if (ret.quot < 0 && ret.rem > 0) { + ret.quot++; + ret.rem -= denom; + } + + return ret; +} + +lldiv_t lldiv(long long num, long long denom) { + lldiv_t ret; + + ret.quot = num / denom; + ret.rem = num - denom * ret.quot; + + if (ret.quot < 0 && ret.rem > 0) { + ret.quot++; + ret.rem -= denom; + } + + return ret; +} diff --git a/src/libc/ll.c b/src/libc/ll.c new file mode 100755 index 0000000..71582bf --- /dev/null +++ b/src/libc/ll.c @@ -0,0 +1,46 @@ +unsigned long long __ull_rshift(unsigned long long a0, unsigned long long a1) { + return a0 >> a1; +} + +unsigned long long __ull_rem(unsigned long long a0, unsigned long long a1) { + return a0 % a1; +} + +unsigned long long __ull_div(unsigned long long a0, unsigned long long a1) { + return a0 / a1; +} + +unsigned long long __ll_lshift(unsigned long long a0, unsigned long long a1) { + return a0 << a1; +} + +long long __ll_rem(unsigned long long a0, long long a1) { + return a0 % a1; +} + +long long __ll_div(long long a0, long long a1) { + return a0 / a1; +} + +unsigned long long __ll_mul(unsigned long long a0, unsigned long long a1) { + return a0 * a1; +} + +void __ull_divremi(unsigned long long *div, unsigned long long *rem, unsigned long long a2, unsigned short a3) { + *div = a2 / a3; + *rem = a2 % a3; +} + +long long __ll_mod(long long a0, long long a1) { + long long tmp = a0 % a1; + + if ((tmp < 0 && a1 > 0) || (tmp > 0 && a1 < 0)) { + tmp += a1; + } + + return tmp; +} + +long long __ll_rshift(long long a0, long long a1) { + return a0 >> a1; +} diff --git a/src/libc/llbit.c b/src/libc/llbit.c new file mode 100755 index 0000000..73d6056 --- /dev/null +++ b/src/libc/llbit.c @@ -0,0 +1,50 @@ +#include "PR/ultratypes.h" + +s64 __ll_bit_extract(u64 *addr, unsigned int start_bit, unsigned int length) { + unsigned int words; + unsigned int lbits; + unsigned int rbits; + u64 mask; + + words = start_bit >> 6; + lbits = start_bit & ((1 << 6) - 1); + rbits = 64 - (lbits + length); + addr += words; + mask = ((u64)1 << length) - 1; + mask = mask << rbits; + return (s64)((*addr & mask) >> rbits); +} + +u64 __ull_bit_extract(u64 *addr, unsigned int start_bit, unsigned int length) { + unsigned int words; + unsigned int lbits; + unsigned int rbits; + u64 mask; + + words = start_bit >> 6; + lbits = start_bit & ((1 << 6) - 1); + rbits = 64 - (lbits + length); + addr += words; + mask = ((u64)1 << length) - 1; + mask = mask << rbits; + return (u64)((*addr & mask) >> rbits); +} + +u64 __ll_bit_insert(u64 *addr, unsigned int start_bit, unsigned int length, u64 val) { + unsigned int words; + unsigned int lbits; + unsigned int rbits; + unsigned long long llval; + unsigned long long mask; + + words = start_bit >> 6; + lbits = start_bit & 0x3f; + rbits = 64 - (lbits + length); + addr += words; + mask = ((u64)1 << length) - 1; + mask <<= rbits; + llval = (val << (64 - length)) >> lbits; + *addr = (*addr & ~mask) | llval; + llval = llval >> rbits; + return llval; +} diff --git a/src/libc/llcvt.c b/src/libc/llcvt.c new file mode 100755 index 0000000..2c423dd --- /dev/null +++ b/src/libc/llcvt.c @@ -0,0 +1,31 @@ +long long __d_to_ll(double d) { + return d; +} + +long long __f_to_ll(float f) { + return f; +} + +unsigned long long __d_to_ull(double d) { + return d; +} + +unsigned long long __f_to_ull(float f) { + return f; +} + +double __ll_to_d(long long s) { + return s; +} + +float __ll_to_f(long long s) { + return s; +} + +double __ull_to_d(unsigned long long u) { + return u; +} + +float __ull_to_f(unsigned long long u) { + return u; +} diff --git a/src/libc/sprintf.c b/src/libc/sprintf.c new file mode 100755 index 0000000..8d619f5 --- /dev/null +++ b/src/libc/sprintf.c @@ -0,0 +1,24 @@ +#include "xstdio.h" +#include "string.h" + +// TODO: this comes from a header +#ident "$Revision: 1.23 $" + +static char *proutSprintf(char *dst, const char *src, size_t count); + +int sprintf(char *dst, const char *fmt, ...) +{ + s32 ans; + va_list ap; + va_start(ap, fmt); + ans = _Printf(proutSprintf, dst, fmt, ap); + if (ans >= 0) + { + dst[ans] = 0; + } + return ans; +} +static char *proutSprintf(char *dst, const char *src, size_t count) +{ + return (char *)memcpy((u8 *)dst, (u8 *)src, count) + count; +} diff --git a/src/libc/string.c b/src/libc/string.c new file mode 100755 index 0000000..c9a2b97 --- /dev/null +++ b/src/libc/string.c @@ -0,0 +1,34 @@ +#include "PR/ultratypes.h" +#include "string.h" + +// TODO: this comes from a header +#ident "$Revision: 1.23 $" + +char *strchr(const char *s, int c) { + const char ch = c; + while (*s != ch) + { + if (*s == 0) + return NULL; + s++; + } + return (char *)s; +} + +size_t strlen(const char *s) { + const char *sc = s; + while (*sc) + sc++; + return sc - s; +} + +void *memcpy(void *s1, const void *s2, size_t n) { + char *su1 = (char *)s1; + const char *su2 = (const char *)s2; + while (n > 0) + { + *su1++ = *su2++; + n--; + } + return (void *)s1; +} diff --git a/src/libc/syncprintf.c b/src/libc/syncprintf.c new file mode 100755 index 0000000..f2e758c --- /dev/null +++ b/src/libc/syncprintf.c @@ -0,0 +1,17 @@ +#include "stdarg.h" +#include "PR/os.h" + +void __osSyncVPrintf(const char *fmt, va_list args) { + // these functions intentionally left blank. ifdeffed out in rom release +} + +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/libc/xldtob.c_ b/src/libc/xldtob.c_ new file mode 100755 index 0000000..6e69492 --- /dev/null +++ b/src/libc/xldtob.c_ @@ -0,0 +1,179 @@ +#include "stdlib.h" +#include "string.h" +#include "xstdio.h" + +// TODO: these come from headers +#ident "$Revision: 1.23 $" +#ident "$Revision: 1.34 $" +#ident "$Revision: 1.5 $" + +#define BUFF_LEN 0x20 + +static short _Ldunscale(short *, printf_struct *); +static void _Genld(printf_struct *, char, char *, short, short); + +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 + +void _Ldtob(printf_struct *args, char type) { + char buff[BUFF_LEN]; + char *p; + f64 ldval; + short err; + short nsig; + short exp; + + // char unused[0x4]; + p = buff; + ldval = args->value.f64; + + if (args->precision < 0) { + args->precision = 6; + } else { + if (args->precision == 0 && (type == 'g' || type == 'G')) { + args->precision = 1; + } + } + + err = _Ldunscale(&exp, args); + + if (err > 0) { + memcpy(args->buff, err == 2 ? "NaN" : "Inf", args->part2_len = 3); + return; + } + + if (err == 0) { + nsig = 0; + exp = 0; + } else { + int i; + int n; + + if (ldval < 0) { + ldval = -ldval; + } + + exp = exp * 30103 / 100000 - 4; + + if (exp < 0) { + n = ((-exp + 3) & ~3); + exp = -n; + + for (i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + ldval *= pows[i]; + } + } + } else if (exp > 0) { + f64 factor = 1; + + exp &= ~3; + + for (n = exp, i = 0; n > 0; n >>= 1, i++) { + if ((n & 1) != 0) { + factor *= pows[i]; + } + } + + ldval /= factor; + } + { + int gen = args->precision + ((type == 'f') ? 10 + exp : 6); + + if (gen > 0x13) { + gen = 0x13; + } + + *p++ = '0'; + + while (gen > 0 && 0 < ldval) { + int j; + int lo = ldval; + + if ((gen -= 8) > 0) { + ldval = (ldval - lo) * 1.0e8; + } + + p = p + 8; + + for (j = 8; lo > 0 && --j >= 0;) { + ldiv_t qr = ldiv(lo, 10); + *--p = qr.rem + '0'; + lo = qr.quot; + } + + while (--j >= 0) { + p--; + *p = '0'; + } + p += 8; + } + + gen = p - &buff[1]; + + for (p = &buff[1], exp += 7; *p == '0'; p++) { + --gen, --exp; + } + + nsig = args->precision + ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)); + + if (gen < nsig) { + nsig = gen; + } + + if (nsig > 0) { + char drop; + int n; + + if (nsig < gen && p[nsig] > '4') + { + drop = '9'; + } else { + drop = '0'; + } + + for (n = nsig; p[--n] == drop;) { + nsig--; + } + + if (drop == '9') { + p[n]++; + } + + if (n < 0) { + --p, ++nsig, ++exp; + } + } + } + } + _Genld(args, type, p, nsig, exp); +} + +// _Ldunscale +// _Genld \ No newline at end of file diff --git a/src/libc/xlitob.c b/src/libc/xlitob.c new file mode 100755 index 0000000..b339d2f --- /dev/null +++ b/src/libc/xlitob.c @@ -0,0 +1,64 @@ +#include "stdlib.h" +#include "string.h" +#include "xstdio.h" + +// TODO: these come from headers +#ident "$Revision: 1.34 $" +#ident "$Revision: 1.5 $" +#ident "$Revision: 1.23 $" + +#define BUFF_LEN 0x18 + +static char ldigs[] = "0123456789abcdef"; +static char udigs[] = "0123456789ABCDEF"; + +void _Litob(printf_struct *args, char type) { + char buff[BUFF_LEN]; + const char *digs; + s32 base; + s32 i; + unsigned long long ullval; + + if (type == 'X') { + digs = udigs; + } else { + digs = ldigs; + } + + base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16); + i = BUFF_LEN; + ullval = args->value.s64; + + if ((type == 'd' || type == 'i') && args->value.s64 < 0) { + ullval = -ullval; + } + + if (ullval != 0 || args->precision != 0) { + buff[--i] = digs[ullval % base]; + } + + args->value.s64 = ullval / base; + + while (args->value.s64 > 0 && i > 0) { + lldiv_t qr = lldiv(args->value.s64, base); + + args->value.s64 = qr.quot; + buff[--i] = digs[qr.rem]; + } + + args->part2_len = BUFF_LEN - i; + + memcpy(args->buff, buff + i, args->part2_len); + + if (args->part2_len < args->precision) { + args->num_leading_zeros = args->precision - args->part2_len; + } + + if (args->precision < 0 && (args->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { + i = args->width - args->n0 - args->num_leading_zeros - args->part2_len; + + if (i > 0) { + args->num_leading_zeros += i; + } + } +} diff --git a/src/libc/xprintf.c b/src/libc/xprintf.c new file mode 100755 index 0000000..75c613c --- /dev/null +++ b/src/libc/xprintf.c @@ -0,0 +1,241 @@ +#include "macros.h" +#include "string.h" +#include "stdarg.h" +#include "xstdio.h" + +// TODO: these come from headers +#ident "$Revision: 1.34 $" +#ident "$Revision: 1.5 $" +#ident "$Revision: 1.23 $" + +#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[] = {' ', '+', '-', '#', '0', '\0'}; + static const int fbit[] = {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 '%': + buff[x->n0++] = '%'; + break; + default: + buff[x->n0++] = type; + break; + } +} diff --git a/src/libc/xstdio.h b/src/libc/xstdio.h new file mode 100755 index 0000000..5d6cf82 --- /dev/null +++ b/src/libc/xstdio.h @@ -0,0 +1,38 @@ +#ifndef _XSTDIO_H +#define _XSTDIO_H +#include "PR/ultratypes.h" +#include "stdlib.h" +#include "stdarg.h" + +typedef struct +{ + union { + /* 00 */ long long s64; + double f64; + } value; + /* 08 */ char *buff; + /* 0c */ int n0; + /* 10 */ int num_leading_zeros; + /* 14 */ int part2_len; + /* 18 */ int num_mid_zeros; + /* 1c */ int part3_len; + /* 20 */ int num_trailing_zeros; + /* 24 */ int precision; + /* 28 */ int width; + /* 2c */ unsigned int size; + /* 30 */ unsigned int flags; + /* 34 */ char length; +} printf_struct; + +#define FLAGS_SPACE 1 +#define FLAGS_PLUS 2 +#define FLAGS_MINUS 4 +#define FLAGS_HASH 8 +#define FLAGS_ZERO 16 +typedef char *outfun(char*,const char*,size_t); + +int _Printf(outfun prout, char *arg, const char *fmt, va_list args); +void _Litob(printf_struct *args, char type); +void _Ldtob(printf_struct *args, char type); + +#endif diff --git a/src/rg/free.c b/src/rg/free.c new file mode 100755 index 0000000..0229b2c --- /dev/null +++ b/src/rg/free.c @@ -0,0 +1,15 @@ +#include "PR/region.h" +#include "PR/R4300.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +void osFree(void *region, void *addr) { + register OSRegion *rp = region; + int i; + + rp = region; + i = ((u8 *)addr - rp->r_startBufferAddress) / rp->r_bufferSize; + *(u16 *)(&rp->r_startBufferAddress[i * rp->r_bufferSize]) = rp->r_freeList; + rp->r_freeList = i; +} diff --git a/src/rg/getbufcount.c b/src/rg/getbufcount.c new file mode 100755 index 0000000..4f61521 --- /dev/null +++ b/src/rg/getbufcount.c @@ -0,0 +1,10 @@ +#include "PR/region.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +s32 osGetRegionBufCount(void *region) { + register OSRegion *rp = region; + return rp->r_bufferCount; +} + diff --git a/src/rg/getsize.c b/src/rg/getsize.c new file mode 100755 index 0000000..6bd4b2a --- /dev/null +++ b/src/rg/getsize.c @@ -0,0 +1,9 @@ +#include "PR/region.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +s32 osGetRegionBufSize(void *region) { + register OSRegion *rp = region; + return rp->r_bufferSize; +} diff --git a/src/rg/malloc.c b/src/rg/malloc.c new file mode 100755 index 0000000..4b26431 --- /dev/null +++ b/src/rg/malloc.c @@ -0,0 +1,17 @@ +#include "PR/region.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +void *osMalloc(void *region) { + register OSRegion *rp = region; + unsigned char *addr; + + if (rp->r_freeList == MAX_BUFCOUNT) { + return NULL; + } + + addr = &rp->r_startBufferAddress[rp->r_freeList * rp->r_bufferSize]; + rp->r_freeList = *(u16 *)addr; + return addr; +} diff --git a/src/rg/region.c b/src/rg/region.c new file mode 100755 index 0000000..181f52f --- /dev/null +++ b/src/rg/region.c @@ -0,0 +1,36 @@ +#include "PR/region.h" + +// TODO: this comes from a header +#ident "$Revision: 1.17 $" + +void *osCreateRegion(void *startAddress, u32 length, u32 bufferSize, u32 alignSize) { + register OSRegion *rp; + register int i; + register unsigned char *addr; + + if (alignSize == 0) { + alignSize = OS_RG_ALIGN_DEFAULT; + } + + rp = (OSRegion*)ALIGN(startAddress, alignSize); + length = length - ((s32)rp - (s32)startAddress); + rp->r_bufferSize = ALIGN(bufferSize, alignSize); + rp->r_bufferCount = (s32)(length - ALIGN(sizeof(OSRegion), alignSize)) / rp->r_bufferSize; + + if (rp->r_bufferCount > MAX_BUFCOUNT) { + rp->r_bufferCount = MAX_BUFCOUNT; + } + + rp->r_startBufferAddress = (u8*)rp + ALIGN(sizeof(OSRegion), alignSize); + rp->r_endAddress = (u8*)rp + length; + addr = rp->r_startBufferAddress; + + for (i = 0; i < rp->r_bufferCount - 1; i++) { + *((s16 *)(&addr[i * rp->r_bufferSize])) = i + 1; + } + + *((u16 *)(&addr[i * rp->r_bufferSize])) = BUF_FREE_WO_NEXT; + rp->r_alignSize = alignSize; + rp->r_freeList = 0; + return rp; +} diff --git a/tools/disassemble_elf.py b/tools/disassemble_elf.py old mode 100644 new mode 100755 diff --git a/tools/fix_objfile.py b/tools/fix_objfile.py old mode 100644 new mode 100755 diff --git a/tools/patch_ar_meta.py b/tools/patch_ar_meta.py old mode 100644 new mode 100755