mirror of
https://github.com/izzy2lost/Ghostship.git
synced 2026-06-19 01:17:03 -07:00
init2
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
typedef union {
|
||||
int i;
|
||||
float f;
|
||||
} fu;
|
||||
const fu NAN = { 0x7f810000 };
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "libultra_internal.h"
|
||||
#include "hardware.h"
|
||||
u32 __osSpGetStatus() {
|
||||
return HW_REG(SP_STATUS_REG, u32);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "libultra_internal.h"
|
||||
#include "hardware.h"
|
||||
void __osSpSetStatus(u32 status) {
|
||||
HW_REG(SP_STATUS_REG, u32) = status;
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user