This commit is contained in:
n64
2019-08-25 00:46:40 -04:00
commit 89e8690857
2846 changed files with 625030 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
typedef union {
int i;
float f;
} fu;
const fu NAN = { 0x7f810000 };
+270
View File
@@ -0,0 +1,270 @@
#include "libultra_internal.h"
#include <macros.h>
#include <stdlib.h>
#include <string.h>
#include "printf.h"
#define BUFF_LEN 0x20
static s16 _Ldunscale(s16 *, printf_struct *);
static void _Genld(printf_struct *, u8, u8 *, s16, s16);
const double D_80338670[] = { 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
#if _D0 == 3
#define _D1 2 /* little-endian order */
#define _D2 1
#define _D3 0
#else
#define _D1 1 /* big-endian order */
#define _D2 2
#define _D3 3
#endif
void _Ldtob(printf_struct *args, u8 type) {
u8 buff[BUFF_LEN];
u8 *ptr;
UNUSED u32 sp70;
f64 val;
/* maybe struct? */
s16 err;
s16 nsig;
s16 exp;
s32 i;
s32 n;
f64 factor;
s32 gen;
s32 j;
s32 lo;
ldiv_t qr;
u8 drop;
s32 n2;
/* */
UNUSED u8 unused[0x4];
ptr = buff;
val = 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 {
if (val < 0)
val = -val;
exp = exp * 30103 / 0x000186A0 - 4;
if (exp < 0) {
n = (3 - exp) & ~3;
exp = -n;
for (i = 0; n > 0; n >>= 1, i++) {
if ((n & 1) != 0) {
val *= D_80338670[i];
}
}
} else {
if (exp > 0) {
factor = 1;
exp &= ~3;
n = exp;
for (i = 0; n > 0; n >>= 1, i++) {
if ((n & 1) != 0) {
factor *= D_80338670[i];
}
}
val /= factor;
}
}
gen = ((type == 'f') ? exp + 10 : 6) + args->precision;
if (gen > 0x13)
gen = 0x13;
*ptr++ = '0';
while (gen > 0 && 0 < val) {
lo = val;
if ((gen -= 8) > 0) {
val = (val - lo) * 1.0e8;
}
ptr = ptr + 8;
for (j = 8; lo > 0 && --j >= 0;) {
qr = ldiv(lo, 10);
*--ptr = qr.rem + '0';
lo = qr.quot;
}
while (--j >= 0) {
ptr--;
*ptr = '0';
}
ptr += 8;
}
gen = ptr - &buff[1];
for (ptr = &buff[1], exp += 7; *ptr == '0'; ptr++) {
--gen, --exp;
}
nsig = ((type == 'f') ? exp + 1 : ((type == 'e' || type == 'E') ? 1 : 0)) + args->precision;
if (gen < nsig)
nsig = gen;
if (nsig > 0) {
if (nsig < gen && ptr[nsig] > '4')
drop = '9';
else
drop = '0';
for (n2 = nsig; ptr[--n2] == drop;) {
nsig--;
}
if (drop == '9') {
ptr[n2]++;
}
if (n2 < 0) {
--ptr, ++nsig, ++exp;
}
}
}
_Genld(args, type, ptr, nsig, exp);
}
static s16 _Ldunscale(s16 *pex, printf_struct *px) {
unsigned short *ps = (unsigned short *) px;
short xchar = (ps[_D0] & _DMASK) >> _DOFF;
if (xchar == _DMAX) { /* NaN or INF */
*pex = 0;
return (s16)(ps[_D0] & _DFRAC || ps[_D1] || ps[_D2] || ps[_D3] ? NAN : INF);
} else if (0 < xchar) {
ps[_D0] = (ps[_D0] & ~_DMASK) | (_DBIAS << _DOFF);
*pex = xchar - (_DBIAS - 1);
return (FINITE);
}
if (0 > xchar)
return NAN;
else {
*pex = 0;
return (0);
}
}
static void _Genld(printf_struct *px, u8 code, u8 *p, s16 nsig, s16 xexp) {
u8 point = '.';
if (nsig <= 0)
nsig = 1,
p = (u8 *) "0";
if (code == 'f'
|| ((code == 'g' || code == 'G') && (-4 <= xexp) && (xexp < px->precision))) { /* 'f' format */
++xexp; /* change to leading digit count */
if (code != 'f') { /* fixup for 'g' */
if (!(px->flags & FLAGS_HASH) && nsig < px->precision)
px->precision = nsig;
if ((px->precision -= xexp) < 0)
px->precision = 0;
}
if (xexp <= 0) { /* digits only to right of point */
px->buff[px->part2_len++] = '0';
if (0 < px->precision || px->flags & FLAGS_HASH)
px->buff[px->part2_len++] = point;
if (px->precision < -xexp)
xexp = -px->precision;
px->num_mid_zeros = -xexp;
px->precision += xexp;
if (px->precision < nsig)
nsig = px->precision;
memcpy(&px->buff[px->part2_len], p, px->part3_len = nsig);
px->num_trailing_zeros = px->precision - nsig;
} else if (nsig < xexp) { /* zeros before point */
memcpy(&px->buff[px->part2_len], p, nsig);
px->part2_len += nsig;
px->num_mid_zeros = xexp - nsig;
if (0 < px->precision || px->flags & FLAGS_HASH)
px->buff[px->part2_len] = point, ++px->part3_len;
px->num_trailing_zeros = px->precision;
} else { /* enough digits before point */
memcpy(&px->buff[px->part2_len], p, xexp);
px->part2_len += xexp;
nsig -= xexp;
if (0 < px->precision || px->flags & FLAGS_HASH)
px->buff[px->part2_len++] = point;
if (px->precision < nsig)
nsig = px->precision;
memcpy(&px->buff[px->part2_len], p + xexp, nsig);
px->part2_len += nsig;
px->num_mid_zeros = px->precision - nsig;
}
} else { /* 'e' format */
if (code == 'g' || code == 'G') { /* fixup for 'g' */
if (nsig < px->precision)
px->precision = nsig;
if (--px->precision < 0)
px->precision = 0;
code = code == 'g' ? 'e' : 'E';
}
px->buff[px->part2_len++] = *p++;
if (0 < px->precision || px->flags & FLAGS_HASH)
px->buff[px->part2_len++] = point;
if (0 < px->precision) { /* put fraction digits */
if (px->precision < --nsig)
nsig = px->precision;
memcpy(&px->buff[px->part2_len], p, nsig);
px->part2_len += nsig;
px->num_mid_zeros = px->precision - nsig;
}
p = (u8 *) &px->buff[px->part2_len]; /* put exponent */
*p++ = code;
if (0 <= xexp)
*p++ = '+';
else { /* negative exponent */
*p++ = '-';
xexp = -xexp;
}
if (100 <= xexp) { /* put oversize exponent */
if (1000 <= xexp)
*p++ = xexp / 1000 + '0', xexp %= 1000;
*p++ = xexp / 100 + '0', xexp %= 100;
}
*p++ = xexp / 10 + '0', xexp %= 10;
*p++ = xexp + '0';
px->part3_len = (u32) p - (u32) &px->buff[px->part2_len];
}
if ((px->flags & (FLAGS_ZERO | FLAGS_MINUS)) == FLAGS_ZERO) { /* pad with leading zeros */
int n =
px->part1_len + px->part2_len + px->num_mid_zeros + px->part3_len + px->num_trailing_zeros;
if (n < px->width)
px->num_leading_zeros = px->width - n;
}
}
+54
View File
@@ -0,0 +1,54 @@
#include "libultra_internal.h"
#include <stdlib.h>
#include <string.h>
#include "printf.h"
#define BUFF_LEN 0x18
static u8 D_80334960[] = "0123456789abcdef";
static u8 D_80334974[] = "0123456789ABCDEF";
void _Litob(printf_struct *args, u8 type) {
u8 buff[BUFF_LEN];
const u8 *num_map;
s32 base;
s32 buff_ind;
u64 num;
lldiv_t quotrem;
if (type == 'X')
num_map = D_80334974;
else
num_map = D_80334960;
base = (type == 'o') ? 8 : ((type != 'x' && type != 'X') ? 10 : 16);
buff_ind = BUFF_LEN;
num = args->value.s64;
if ((type == 'd' || type == 'i') && args->value.s64 < 0)
num = -num;
if (num != 0 || args->precision != 0)
buff[--buff_ind] = num_map[num % base];
args->value.s64 = num / base;
while (args->value.s64 > 0 && buff_ind > 0) {
quotrem = lldiv(args->value.s64, base);
args->value.s64 = quotrem.quot;
buff[--buff_ind] = num_map[quotrem.rem];
}
args->part2_len = BUFF_LEN - buff_ind;
memcpy(args->buff, buff + buff_ind, 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) {
buff_ind = args->width - args->part1_len - args->num_leading_zeros - args->part2_len;
if (buff_ind > 0)
args->num_leading_zeros += buff_ind;
}
}
+218
View File
@@ -0,0 +1,218 @@
#include "libultra_internal.h"
#include <stdarg.h>
#include <string.h>
#include "printf.h"
#define ATOI(i, a) \
for (i = 0; *a >= '0' && *a <= '9'; a++) \
if (i < 999) \
i = *a + i * 10 - '0';
#define _PROUT(dst, fmt, _size) \
if (_size > 0) { \
dst = prout(dst, fmt, _size); \
if (dst != 0) \
sp78.size += _size; \
else \
return sp78.size; \
}
#define _PAD(i, m, c, src, extracond) \
if (extracond && m > 0) \
for (i = m; i > 0; i -= c) { \
if ((u32) i > 32) \
c = 32; \
else \
c = i; \
_PROUT(dst, src, c); \
}
const u8 length_str[] = "hlL";
const u8 flags_str[] = " +-#0";
const u32 flags_arr[] = { FLAGS_SPACE, FLAGS_PLUS, FLAGS_MINUS, FLAGS_HASH, FLAGS_ZERO, 0 };
char _spaces[] = " ";
char _zeroes[] = "00000000000000000000000000000000";
static void _Putfld(printf_struct *, va_list *, u8, u8 *);
s32 _Printf(char *(*prout)(char *, const char *, size_t), char *dst, const char *fmt, va_list args) {
printf_struct sp78;
const u8 *fmt_ptr;
u8 c;
const u8 *flag_index;
u8 sp4c[0x20]; // probably a buffer?
s32 sp48, sp44, sp40, sp3c, sp38, sp34, sp30, sp2c, sp28, sp24;
sp78.size = 0;
while (1) {
fmt_ptr = (u8 *) fmt;
while ((c = *fmt_ptr++) > 0) {
if (c == '%') {
fmt_ptr--;
break;
}
}
_PROUT(dst, fmt, fmt_ptr - (u8 *) fmt);
if (c == 0)
return sp78.size;
fmt = (char *) ++fmt_ptr;
sp78.flags = 0;
for (; (flag_index = strchr(flags_str, *fmt_ptr)) != NULL; fmt_ptr++) {
sp78.flags |= flags_arr[flag_index - flags_str];
}
if (*fmt_ptr == '*') {
sp78.width = va_arg(args, s32);
if (sp78.width < 0) {
sp78.width = -sp78.width;
sp78.flags |= FLAGS_MINUS;
}
fmt_ptr++;
} else {
ATOI(sp78.width, fmt_ptr);
}
if (*fmt_ptr != '.') {
sp78.precision = -1;
} else {
fmt_ptr++;
if (*fmt_ptr == '*') {
sp78.precision = va_arg(args, s32);
fmt_ptr++;
} else {
ATOI(sp78.precision, fmt_ptr);
}
}
if (strchr(length_str, *fmt_ptr) != NULL)
sp78.length = *fmt_ptr++;
else
sp78.length = 0;
if (sp78.length == 'l' && *fmt_ptr == 'l') {
sp78.length = 'L';
fmt_ptr++;
}
_Putfld(&sp78, &args, *fmt_ptr, sp4c);
sp78.width -= sp78.part1_len + sp78.num_leading_zeros + sp78.part2_len + sp78.num_mid_zeros
+ sp78.part3_len + sp78.num_trailing_zeros;
_PAD(sp44, sp78.width, sp48, _spaces, !(sp78.flags & FLAGS_MINUS));
_PROUT(dst, (char *) sp4c, sp78.part1_len);
_PAD(sp3c, sp78.num_leading_zeros, sp40, _zeroes, 1);
_PROUT(dst, sp78.buff, sp78.part2_len);
_PAD(sp34, sp78.num_mid_zeros, sp38, _zeroes, 1);
_PROUT(dst, (char *) (&sp78.buff[sp78.part2_len]), sp78.part3_len)
_PAD(sp2c, sp78.num_trailing_zeros, sp30, _zeroes, 1);
_PAD(sp24, sp78.width, sp28, _spaces, sp78.flags & FLAGS_MINUS);
fmt = (char *) fmt_ptr + 1;
}
}
static void _Putfld(printf_struct *a0, va_list *args, u8 type, u8 *buff) {
a0->part1_len = a0->num_leading_zeros = a0->part2_len = a0->num_mid_zeros = a0->part3_len =
a0->num_trailing_zeros = 0;
switch (type) {
case 'c':
buff[a0->part1_len++] = va_arg(*args, u32);
break;
case 'd':
case 'i':
if (a0->length == 'l')
a0->value.s64 = va_arg(*args, s32);
else if (a0->length == 'L')
a0->value.s64 = va_arg(*args, s64);
else
a0->value.s64 = va_arg(*args, s32);
if (a0->length == 'h')
a0->value.s64 = (s16) a0->value.s64;
if (a0->value.s64 < 0)
buff[a0->part1_len++] = '-';
else if (a0->flags & FLAGS_PLUS)
buff[a0->part1_len++] = '+';
else if (a0->flags & FLAGS_SPACE)
buff[a0->part1_len++] = ' ';
a0->buff = (char *) &buff[a0->part1_len];
_Litob(a0, type);
break;
case 'x':
case 'X':
case 'u':
case 'o':
if (a0->length == 'l')
a0->value.s64 = va_arg(*args, s32);
else if (a0->length == 'L')
a0->value.s64 = va_arg(*args, s64);
else
a0->value.s64 = va_arg(*args, s32);
if (a0->length == 'h')
a0->value.s64 = (u16) a0->value.s64;
else if (a0->length == 0)
a0->value.s64 = (u32) a0->value.s64;
if (a0->flags & FLAGS_HASH) {
buff[a0->part1_len++] = '0';
if (type == 'x' || type == 'X')
buff[a0->part1_len++] = type;
}
a0->buff = (char *) &buff[a0->part1_len];
_Litob(a0, type);
break;
case 'e':
case 'f':
case 'g':
case 'E':
case 'G':
//... okay?
a0->value.f64 = a0->length == 'L' ? va_arg(*args, f64) : va_arg(*args, f64);
if (a0->value.u16 & 0x8000) {
buff[a0->part1_len++] = '-';
} else {
if (a0->flags & FLAGS_PLUS)
buff[a0->part1_len++] = '+';
else if (a0->flags & FLAGS_SPACE)
buff[a0->part1_len++] = ' ';
}
a0->buff = (char *) &buff[a0->part1_len];
_Ldtob(a0, type);
break;
case 'n':
if (a0->length == 'h')
*(va_arg(*args, u16 *)) = a0->size;
else if (a0->length == 'l')
*va_arg(*args, u32 *) = a0->size;
else if (a0->length == 'L')
*va_arg(*args, u64 *) = a0->size;
else
*va_arg(*args, u32 *) = a0->size;
break;
case 'p':
a0->value.s64 = (long) va_arg(*args, void *); // void*
a0->buff = (char *) &buff[a0->part1_len];
_Litob(a0, 'x');
break;
case 's':
a0->buff = va_arg(*args, char *);
a0->part2_len = strlen((u8 *) a0->buff);
if (a0->precision >= 0 && a0->part2_len > a0->precision)
a0->part2_len = a0->precision;
break;
case '%':
buff[a0->part1_len++] = '%';
break;
default:
buff[a0->part1_len++] = type;
break;
}
}
+10
View File
@@ -0,0 +1,10 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osAiDeviceBusy(void) {
register s32 status = HW_REG(AI_STATUS_REG, u32);
if ((status & AI_STATUS_AI_FULL) != 0)
return 1;
else
return 0;
}
+17
View File
@@ -0,0 +1,17 @@
#include "libultra_internal.h"
s32 __osAtomicDec(u32 *a0) {
s32 sp1c;
s32 sp18;
sp1c = __osDisableInt();
if (*a0 != 0) {
(*a0)--;
sp18 = 1;
} else {
sp18 = 0;
}
__osRestoreInt(sp1c);
return sp18;
}
+25
View File
@@ -0,0 +1,25 @@
#include "libultra_internal.h"
// these don't feel like they belong here
// but it makes the most logical since there was printf data before
OSThread *D_80334890 = NULL;
u32 unknown = -1;
OSThread *D_80334898 = (OSThread *) &D_80334890;
OSThread *D_8033489C = (OSThread *) &D_80334890;
OSThread *D_803348A0 = NULL;
u32 D_803348A4 = 0; // UNKNOWN
void __osDequeueThread(OSThread **queue, OSThread *thread) {
register OSThread **a2;
register OSThread *a3;
a2 = queue;
a3 = *a2;
while (a3 != NULL) {
if (a3 == thread) {
*a2 = thread->next;
return;
}
a2 = &a3->next;
a3 = *a2;
}
}
+37
View File
@@ -0,0 +1,37 @@
#include "libultra_internal.h"
void __osDevMgrMain(void *args) {
OSIoMesg *sp34;
OSMesg sp30;
OSMesg sp2c;
s32 sp28;
OSMgrArgs *sp24;
sp34 = NULL;
sp28 = 0;
sp24 = (OSMgrArgs *) args;
while (1) {
osRecvMesg(sp24->unk08, (OSMesg) &sp34, OS_MESG_BLOCK);
switch (sp34->hdr.type) {
case 11:
osRecvMesg(sp24->unk10, &sp2c, OS_MESG_BLOCK);
sp28 = sp24->dma_func(OS_READ, sp34->devAddr, sp34->dramAddr, sp34->size);
break;
case 12:
osRecvMesg(sp24->unk10, &sp2c, OS_MESG_BLOCK);
sp28 = sp24->dma_func(OS_WRITE, sp34->devAddr, sp34->dramAddr, sp34->size);
break;
case 10:
osSendMesg(sp34->hdr.retQueue, sp34, OS_MESG_NOBLOCK);
sp28 = -1;
break;
default:
sp28 = -1;
break;
}
if (sp28 == 0) {
osRecvMesg(sp24->unk0c, &sp30, OS_MESG_BLOCK);
osSendMesg(sp34->hdr.retQueue, sp34, OS_MESG_NOBLOCK);
osSendMesg(sp24->unk10, NULL, OS_MESG_NOBLOCK);
}
}
}
+24
View File
@@ -0,0 +1,24 @@
#include "libultra_internal.h"
#define PIAccessQueueSize 2
OSMesg osPiMesgBuff[PIAccessQueueSize];
OSMesgQueue gOsPiMessageQueue;
u32 gOsPiAccessQueueCreated = 0;
void __osPiCreateAccessQueue() {
gOsPiAccessQueueCreated = 1;
osCreateMesgQueue(&gOsPiMessageQueue, &osPiMesgBuff[0], PIAccessQueueSize - 1);
osSendMesg(&gOsPiMessageQueue, NULL, OS_MESG_NOBLOCK);
}
void __osPiGetAccess() {
OSMesg sp1c;
if (!gOsPiAccessQueueCreated)
__osPiCreateAccessQueue();
osRecvMesg(&gOsPiMessageQueue, &sp1c, OS_MESG_BLOCK);
}
void __osPiRelAccess() {
osSendMesg(&gOsPiMessageQueue, NULL, OS_MESG_NOBLOCK);
}
+22
View File
@@ -0,0 +1,22 @@
#include "libultra_internal.h"
#define SIAccessQueueSize 2
OSMesg osSiMesgBuff[SIAccessQueueSize];
OSMesgQueue gOsSiMessageQueue;
u32 gOsSiAccessQueueCreated = 0;
void __osSiCreateAccessQueue() {
gOsSiAccessQueueCreated = 1;
osCreateMesgQueue(&gOsSiMessageQueue, &osSiMesgBuff[0], SIAccessQueueSize - 1);
osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK);
}
void __osSiGetAccess(void) {
OSMesg sp1c;
if (!gOsSiAccessQueueCreated)
__osSiCreateAccessQueue();
osRecvMesg(&gOsSiMessageQueue, &sp1c, OS_MESG_BLOCK);
}
void __osSiRelAccess(void) {
osSendMesg(&gOsSiMessageQueue, NULL, OS_MESG_NOBLOCK);
}
+12
View File
@@ -0,0 +1,12 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSiDeviceBusy() {
register u32 status;
status = HW_REG(SI_STATUS_REG, u32);
if (status & (SI_STATUS_DMA_BUSY | SI_STATUS_IO_READ_BUSY)) {
return 1;
} else {
return 0;
}
}
+8
View File
@@ -0,0 +1,8 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSiRawReadIo(void *a0, u32 *a1) {
if (__osSiDeviceBusy())
return -1;
*a1 = HW_REG((u32) a0, u32);
return 0;
}
+25
View File
@@ -0,0 +1,25 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSiRawStartDma(s32 dir, void *addr) {
if (__osSiDeviceBusy()) {
return -1;
}
if (dir == OS_WRITE) {
osWritebackDCache(addr, 64);
}
HW_REG(SI_DRAM_ADDR_REG, void *) = (void *) osVirtualToPhysical(addr);
if (dir == OS_READ) {
HW_REG(SI_PIF_ADDR_RD64B_REG, u32) = 0x1FC007C0;
} else {
HW_REG(SI_PIF_ADDR_WR64B_REG, u32) = 0x1FC007C0;
}
if (dir == OS_READ) {
osInvalDCache(addr, 64);
}
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSiRawWriteIo(void *a0, u32 a1) {
if (__osSiDeviceBusy())
return -1;
HW_REG((u32) a0, u32) = a1;
return 0;
}
+9
View File
@@ -0,0 +1,9 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSpDeviceBusy() {
register u32 status = HW_REG(SP_STATUS_REG, u32);
if (status & (SPSTATUS_IO_FULL | SPSTATUS_DMA_FULL | SPSTATUS_DMA_BUSY))
return 1;
return 0;
}
+5
View File
@@ -0,0 +1,5 @@
#include "libultra_internal.h"
#include "hardware.h"
u32 __osSpGetStatus() {
return HW_REG(SP_STATUS_REG, u32);
}
+14
View File
@@ -0,0 +1,14 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSpRawStartDma(u32 dir, void *sp_ptr, void *dram_ptr, size_t size) {
if (__osSpDeviceBusy())
return -1;
HW_REG(SP_MEM_ADDR_REG, void *) = sp_ptr;
HW_REG(SP_DRAM_ADDR_REG, void *) = (void *) osVirtualToPhysical(dram_ptr);
if (dir == 0)
HW_REG(SP_WR_LEN_REG, u32) = size - 1;
else
HW_REG(SP_RD_LEN_REG, u32) = size - 1;
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
#include "libultra_internal.h"
#include "hardware.h"
s32 __osSpSetPc(void *pc) {
register u32 status = HW_REG(SP_STATUS_REG, u32);
if (!(status & SPSTATUS_HALT)) {
return -1;
} else {
HW_REG(SP_PC_REG, void *) = pc;
return 0;
}
}
+5
View File
@@ -0,0 +1,5 @@
#include "libultra_internal.h"
#include "hardware.h"
void __osSpSetStatus(u32 status) {
HW_REG(SP_STATUS_REG, u32) = status;
}
+35
View File
@@ -0,0 +1,35 @@
#include "libultra_internal.h"
typedef struct {
u8 unk00 : 2;
u8 pad : 4;
u8 unk01 : 2;
u8 unk2[3];
} unkStruct;
u32 D_80334A40 = 0;
u32 D_80334A44 = 1;
void __osSyncPutChars(s32 a0, s32 a1, u8 *a2) {
unkStruct sp24;
s32 sp20;
u32 sp1c;
sp24.unk00 = a0;
sp24.unk01 = a1;
for (sp20 = 0; sp20 < a1; sp20++) {
sp24.unk2[sp20] = a2[sp20];
}
while (!__osAtomicDec(&D_80334A44))
;
sp1c = __osDisableInt();
*(u32 *) 0xC0000000 = *(u32 *) &sp24;
while (!(__osGetCause() & 0x2000))
;
*(u32 *) 0xC000000C = 0;
D_80334A44++;
__osRestoreInt(sp1c);
}

Some files were not shown because too many files have changed in this diff Show More