Import gx, PadClamp, rest of mtx, TRK 2.6 and MSL (#525)

* Match mtx and Padclamp.c

* Match the rest of GX

* Import TRK 2.6

* Import MSL headers and files

* Merge some MSL headers into ours
This commit is contained in:
dbalatoni13 2025-01-12 15:11:23 +01:00 committed by GitHub
parent a79294aac0
commit cdb1d1fc37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
113 changed files with 11219 additions and 394 deletions

View file

@ -0,0 +1,55 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/abort_exit.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/critical_regions.h"
#include "stddef.h"
#include "PowerPC_EABI_Support/Runtime/NMWException.h"
void _ExitProcess();
extern void (*_dtors[])(void);
int __aborting = 0;
static void (*atexit_funcs[64])(void);
static int atexit_curr_func = 0;
static void (*__atexit_funcs[64])(void);
static int __atexit_curr_func = 0;
void (*__stdio_exit)(void) = 0;
void (*__console_exit)(void) = 0;
void abort(void)
{
// TODO
}
void exit(int status)
{
int i;
void (**dtor)(void);
if (!__aborting) {
__destroy_global_chain();
dtor = _dtors;
while (*dtor != NULL) {
(*dtor)();
dtor++;
}
if (__stdio_exit != NULL) {
__stdio_exit();
__stdio_exit = NULL;
}
}
while (__atexit_curr_func > 0)
__atexit_funcs[--__atexit_curr_func]();
if (__console_exit != NULL) {
__console_exit();
__console_exit = NULL;
}
_ExitProcess();
}

View file

@ -0,0 +1,95 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/ansi_files.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/file_io.h"
extern files __files = {
{
0,
0,
1,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
{ 0, 0 },
{ 0, 0 },
0,
(unsigned char*)&__files._stdin.char_buffer,
1,
(unsigned char*)&__files._stdin.char_buffer,
0,
0,
0,
0,
NULL,
__read_console,
__write_console,
__close_console,
NULL,
},
{
0,
0,
2,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
{ 0, 0 },
{ 0, 0 },
0,
(unsigned char*)&__files._stdout.char_buffer,
1,
(unsigned char*)&__files._stdout.char_buffer,
0,
0,
0,
0,
NULL,
__read_console,
__write_console,
__close_console,
NULL,
},
{
0,
0,
2,
0,
2,
0,
0,
0,
0,
0,
0,
0,
0,
{ 0, 0 },
{ 0, 0 },
0,
(unsigned char*)&__files._stderr.char_buffer,
1,
(unsigned char*)&__files._stderr.char_buffer,
0,
0,
0,
0,
NULL,
__read_console,
__write_console,
__close_console,
NULL,
},
};

View file

@ -0,0 +1,41 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/ansi_files.h"
void __prep_buffer(FILE* file)
{
file->buffer_ptr = file->buffer;
file->buffer_length = file->buffer_size;
file->buffer_length -= file->position & file->buffer_alignment;
file->buffer_position = file->position;
}
void __convert_from_newlines(unsigned char* p, size_t* n) { }
int __flush_buffer(FILE* file, size_t* bytes_flushed)
{
size_t buffer_len;
int ioresult;
buffer_len = file->buffer_ptr - file->buffer;
if (buffer_len) {
file->buffer_length = buffer_len;
if (!file->file_mode.binary_io)
__convert_from_newlines(file->buffer, &file->buffer_length);
ioresult = (*file->write_fn)(file->handle, file->buffer,
&file->buffer_length, file->idle_fn);
if (bytes_flushed)
*bytes_flushed = file->buffer_length;
if (ioresult)
return ioresult;
file->position += file->buffer_length;
}
__prep_buffer(file);
return __no_io_error;
}

View file

@ -0,0 +1,85 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/ctype.h"
#define ctrl __control_char
#define motn __motion_char
#define spac __space_char
#define punc __punctuation
#define digi __digit
#define hexd __hex_digit
#define lowc __lower_case
#define uppc __upper_case
#define dhex (hexd | digi)
#define uhex (hexd | uppc)
#define lhex (hexd | lowc)
const unsigned char __ctype_map[256] = {
// clang-format off
ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, motn, motn, motn, motn, motn, ctrl, ctrl,
ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl, ctrl,
spac, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc, punc,
dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, dhex, punc, punc, punc, punc, punc, punc,
punc, uhex, uhex, uhex, uhex, uhex, uhex, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc,
uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, uppc, punc, punc, punc, punc, punc,
punc, lhex, lhex, lhex, lhex, lhex, lhex, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc,
lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, lowc, punc, punc, punc, punc, ctrl,
// clang-format on
};
const unsigned char __lower_map[256] = {
// clang-format off
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '[', '\\', ']', '^', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
// clang-format on
};
const unsigned char __upper_map[256] = {
// clang-format off
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '{', '|', '}', '~', 0x7F,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
// clang-format on
};
int tolower(int __c)
{
if (__c == -1)
return -1;
return __lower_map[__c & 0xff];
}
int toupper(int __c)
{
if (__c == -1)
return -1;
return __upper_map[__c & 0xff];
}

View file

@ -0,0 +1,114 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/direct_io.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/buffer_io.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/misc_io.h"
#include "string.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/wchar_io.h"
size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)
{
unsigned char* write_ptr;
size_t num_bytes, bytes_to_go, bytes_written;
int ioresult, always_buffer;
if (fwide(stream, 0) == 0)
fwide(stream, -1);
bytes_to_go = size * count;
if (!bytes_to_go || stream->file_state.error
|| stream->file_mode.file_kind == __closed_file)
return 0;
if ((int)stream->file_mode.file_kind == __console_file)
__stdio_atexit();
always_buffer = !stream->file_mode.binary_io
|| (int)stream->file_mode.file_kind == __string_file
|| stream->file_mode.buffer_mode == _IOFBF
|| stream->file_mode.buffer_mode == _IOLBF;
if (stream->file_state.io_state == __neutral) {
if (stream->file_mode.io_mode & __write) {
stream->file_state.io_state = __writing;
__prep_buffer(stream);
}
}
if (stream->file_state.io_state != __writing) {
set_error(stream);
return 0;
}
write_ptr = (unsigned char*)buffer;
bytes_written = 0;
if (bytes_to_go
&& (stream->buffer_ptr != stream->buffer || always_buffer)) {
stream->buffer_length
= stream->buffer_size - (stream->buffer_ptr - stream->buffer);
do {
unsigned char* newline = NULL;
num_bytes = stream->buffer_length;
if (num_bytes > bytes_to_go)
num_bytes = bytes_to_go;
if (num_bytes) {
memcpy(stream->buffer_ptr, write_ptr, num_bytes);
write_ptr += num_bytes;
bytes_written += num_bytes;
bytes_to_go -= num_bytes;
stream->buffer_ptr += num_bytes;
stream->buffer_length -= num_bytes;
}
if (!stream->buffer_length
&& (int)stream->file_mode.file_kind == __string_file) {
bytes_written += bytes_to_go;
break;
}
if (!stream->buffer_length || newline != NULL
|| (stream->file_mode.buffer_mode == _IONBF)) {
ioresult = __flush_buffer(stream, NULL);
if (ioresult) {
set_error(stream);
bytes_to_go = 0;
break;
}
}
} while (bytes_to_go && always_buffer);
}
if (bytes_to_go && !always_buffer) {
unsigned char* save_buffer = stream->buffer;
size_t save_size = stream->buffer_size;
stream->buffer = write_ptr;
stream->buffer_size = bytes_to_go;
stream->buffer_ptr = write_ptr + bytes_to_go;
if (__flush_buffer(stream, &num_bytes) != __no_io_error)
set_error(stream);
bytes_written += num_bytes;
stream->buffer = save_buffer;
stream->buffer_size = save_size;
__prep_buffer(stream);
stream->buffer_length = 0;
}
if (stream->file_mode.buffer_mode != _IOFBF)
stream->buffer_length = 0;
return ((bytes_written + size - 1) / size);
}

View file

@ -0,0 +1,3 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common_Embedded/Math/fdlibm.h"
double fabs__Fd(double v) { return __fabs(v); }

View file

@ -0,0 +1,145 @@
/* @(#)e_atan2.c 1.3 95/01/18 */
/**
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* __ieee754_atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
* ARG (x+iy) = arctan(y/x) ... if x > 0,
* ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
*
* Special cases:
*
* ATAN2((anything), NaN ) is NaN;
* ATAN2(NAN , (anything) ) is NaN;
* ATAN2(+-0, +(anything but NaN)) is +-0 ;
* ATAN2(+-0, -(anything but NaN)) is +-pi ;
* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
* ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
* ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
* ATAN2(+-INF,+INF ) is +-pi/4 ;
* ATAN2(+-INF,-INF ) is +-3pi/4;
* ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common_Embedded/Math/fdlibm.h"
#ifdef __STDC__
static const double
#else
static double
#endif
tiny
= 1.0e-300,
zero = 0.0, pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
#ifdef __STDC__
double __ieee754_atan2(double y, double x)
#else
double __ieee754_atan2(y, x)
double y, x;
#endif
{
double z;
int k, m, hx, hy, ix, iy;
unsigned lx, ly;
hx = __HI(x);
ix = hx & 0x7fffffff;
lx = __LO(x);
hy = __HI(y);
iy = hy & 0x7fffffff;
ly = __LO(y);
if (((ix | ((lx | -lx) >> 31)) > 0x7ff00000)
|| ((iy | ((ly | -ly) >> 31)) > 0x7ff00000)) /* x or y is NaN */
return x + y;
if ((hx - 0x3ff00000 | lx) == 0)
return atan(y); /* x=1.0 */
m = ((hy >> 31) & 1) | ((hx >> 30) & 2); /* 2*sign(x)+sign(y) */
/* when y = 0 */
if ((iy | ly) == 0) {
switch (m) {
case 0:
case 1:
return y; /* atan(+-0,+anything)=+-0 */
case 2:
return pi + tiny; /* atan(+0,-anything) = pi */
case 3:
return -pi - tiny; /* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if ((ix | lx) == 0)
return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
/* when x is INF */
if (ix == 0x7ff00000) {
if (iy == 0x7ff00000) {
switch (m) {
case 0:
return pi_o_4 + tiny; /* atan(+INF,+INF) */
case 1:
return -pi_o_4 - tiny; /* atan(-INF,+INF) */
case 2:
return 3.0 * pi_o_4 + tiny; /*atan(+INF,-INF)*/
case 3:
return -3.0 * pi_o_4 - tiny; /*atan(-INF,-INF)*/
}
} else {
switch (m) {
case 0:
return zero; /* atan(+...,+INF) */
case 1:
return -zero; /* atan(-...,+INF) */
case 2:
return pi + tiny; /* atan(+...,-INF) */
case 3:
return -pi - tiny; /* atan(-...,-INF) */
}
}
}
/* when y is INF */
if (iy == 0x7ff00000)
return (hy < 0) ? -pi_o_2 - tiny : pi_o_2 + tiny;
/* compute y/x */
k = (iy - ix) >> 20;
if (k > 60)
z = pi_o_2 + 0.5 * pi_lo; /* |y/x| > 2**60 */
else if (hx < 0 && k < -60)
z = 0.0; /* |y|/x < -2**60 */
else
z = atan(fabs__Fd(y / x)); /* safe to do y/x */
switch (m) {
case 0:
return z; /* atan(+,+) */
case 1:
__HI(z) ^= 0x80000000;
return z; /* atan(-,+) */
case 2:
return pi - (z - pi_lo); /* atan(+,-) */
default: /* case 3 */
return (z - pi_lo) - pi; /* atan(-,-) */
}
}

View file

@ -0,0 +1,3 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/errno.h"
int errno;

View file

@ -0,0 +1,5 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/float.h"
unsigned long __float_nan[] = { 0x7FFFFFFF };
unsigned long __float_huge[] = { 0x7F800000 };

View file

@ -0,0 +1,18 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/mbstring.h"
size_t wcstombs(char* s, const wchar_t* pwcs, size_t n)
{
wchar_t next;
size_t chars_written;
int i;
chars_written = 0;
for (i = 0; i < n; ++i) {
next = *pwcs++;
*s++ = (char)next;
if ((char)next == '\0')
break;
++chars_written;
}
return chars_written;
}

View file

@ -0,0 +1,75 @@
#include "string.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/mem_funcs.h"
void* memmove(void* dst, const void* src, size_t n)
{
unsigned char* csrc;
unsigned char* cdst;
int reverse = (unsigned int)src < (unsigned int)dst;
if (n >= 32) {
if (((unsigned int)dst ^ (unsigned int)src) & 3) {
if (!reverse) {
__copy_longs_unaligned(dst, src, n);
} else {
__copy_longs_rev_unaligned(dst, src, n);
}
} else {
if (!reverse) {
__copy_longs_aligned(dst, src, n);
} else {
__copy_longs_rev_aligned(dst, src, n);
}
}
return dst;
} else {
if (!reverse) {
csrc = ((unsigned char*)src) - 1;
cdst = ((unsigned char*)dst) - 1;
n++;
while (--n > 0) {
*++cdst = *++csrc;
}
} else {
csrc = (unsigned char*)src + n;
cdst = (unsigned char*)dst + n;
n++;
while (--n > 0) {
*--cdst = *--csrc;
}
}
}
return dst;
}
void* memchr(const void* ptr, int ch, size_t count)
{
const unsigned char* p;
unsigned long v = (ch & 0xff);
for (p = (unsigned char*)ptr - 1, count++; --count;)
if ((*++p & 0xff) == v)
return (void*)p;
return NULL;
}
int memcmp(const void* lhs, const void* rhs, size_t count)
{
const unsigned char* p1;
const unsigned char* p2;
for (p1 = (const unsigned char*)lhs - 1, p2 = (const unsigned char*)rhs - 1,
count++;
--count;)
if (*++p1 != *++p2)
return ((*p1 < *p2) ? -1 : +1);
return 0;
}

View file

@ -0,0 +1,221 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/mem_funcs.h"
#define cps ((unsigned char*)src)
#define cpd ((unsigned char*)dst)
#define lps ((unsigned long*)src)
#define lpd ((unsigned long*)dst)
#define deref_auto_inc(p) *++(p)
void __copy_longs_aligned(void* dst, const void* src, size_t n)
{
unsigned long i;
i = (-(unsigned long)dst) & 3;
cps = ((unsigned char*)src) - 1;
cpd = ((unsigned char*)dst) - 1;
if (i) {
n -= i;
do
deref_auto_inc(cpd) = deref_auto_inc(cps);
while (--i);
}
lps = ((unsigned long*)(cps + 1)) - 1;
lpd = ((unsigned long*)(cpd + 1)) - 1;
i = n >> 5;
if (i)
do {
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
deref_auto_inc(lpd) = deref_auto_inc(lps);
} while (--i);
i = (n & 31) >> 2;
if (i)
do
deref_auto_inc(lpd) = deref_auto_inc(lps);
while (--i);
cps = ((unsigned char*)(lps + 1)) - 1;
cpd = ((unsigned char*)(lpd + 1)) - 1;
n &= 3;
if (n)
do
deref_auto_inc(cpd) = deref_auto_inc(cps);
while (--n);
return;
}
void __copy_longs_rev_aligned(void* dst, const void* src, size_t n)
{
unsigned long i;
cps = ((unsigned char*)src) + n;
cpd = ((unsigned char*)dst) + n;
i = ((unsigned long)cpd) & 3;
if (i) {
n -= i;
do
*--cpd = *--cps;
while (--i);
}
i = n >> 5;
if (i)
do {
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
*--lpd = *--lps;
} while (--i);
i = (n & 31) >> 2;
if (i)
do
*--lpd = *--lps;
while (--i);
n &= 3;
if (n)
do
*--cpd = *--cps;
while (--n);
return;
}
void __copy_longs_unaligned(void* dst, const void* src, size_t n)
{
unsigned long i, v1, v2;
unsigned int src_offset, left_shift, right_shift;
i = (-(unsigned long)dst) & 3;
cps = ((unsigned char*)src) - 1;
cpd = ((unsigned char*)dst) - 1;
if (i) {
n -= i;
do
deref_auto_inc(cpd) = deref_auto_inc(cps);
while (--i);
}
src_offset = ((unsigned int)(cps + 1)) & 3;
left_shift = src_offset << 3;
right_shift = 32 - left_shift;
cps -= src_offset;
lps = ((unsigned long*)(cps + 1)) - 1;
lpd = ((unsigned long*)(cpd + 1)) - 1;
i = n >> 3;
v1 = deref_auto_inc(lps);
do {
v2 = deref_auto_inc(lps);
deref_auto_inc(lpd) = (v1 << left_shift) | (v2 >> right_shift);
v1 = deref_auto_inc(lps);
deref_auto_inc(lpd) = (v2 << left_shift) | (v1 >> right_shift);
} while (--i);
if (n & 4) {
v2 = deref_auto_inc(lps);
deref_auto_inc(lpd) = (v1 << left_shift) | (v2 >> right_shift);
}
cps = ((unsigned char*)(lps + 1)) - 1;
cpd = ((unsigned char*)(lpd + 1)) - 1;
n &= 3;
if (n) {
cps -= 4 - src_offset;
do
deref_auto_inc(cpd) = deref_auto_inc(cps);
while (--n);
}
return;
}
void __copy_longs_rev_unaligned(void* dst, const void* src, size_t n)
{
unsigned long i, v1, v2;
unsigned int src_offset, left_shift, right_shift;
cps = ((unsigned char*)src) + n;
cpd = ((unsigned char*)dst) + n;
i = ((unsigned long)cpd) & 3;
if (i) {
n -= i;
do
*--cpd = *--cps;
while (--i);
}
src_offset = ((unsigned int)cps) & 3;
left_shift = src_offset << 3;
right_shift = 32 - left_shift;
cps += 4 - src_offset;
i = n >> 3;
v1 = *--lps;
do {
v2 = *--lps;
*--lpd = (v2 << left_shift) | (v1 >> right_shift);
v1 = *--lps;
*--lpd = (v1 << left_shift) | (v2 >> right_shift);
} while (--i);
if (n & 4) {
v2 = *--lps;
*--lpd = (v2 << left_shift) | (v1 >> right_shift);
}
n &= 3;
if (n) {
cps += src_offset;
do
*--cpd = *--cps;
while (--n);
}
return;
}

View file

@ -0,0 +1 @@
void __stdio_atexit(void) { }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
#include "dolphin.h"
// rand.c from Runtime library
u32 next = 1;
u32 rand(void)
{
next = 0x41C64E6D * next + 12345;
return (next >> 16) & 0x7FFF;
}
void srand(u32 seed) { next = seed; }

View file

@ -0,0 +1,148 @@
/* @(#)s_atan.c 1.3 95/01/18 */
/**
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* atan(x)
* Method
* 1. Reduce x to positive by atan(x) = -atan(-x).
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument
* is further reduced to one of the following intervals and the
* arctangent of t is evaluated by the corresponding formula:
*
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common_Embedded/Math/fdlibm.h"
#ifdef __STDC__
static const double atanhi[] = {
#else
static double atanhi[] = {
#endif
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
};
#ifdef __STDC__
static const double atanlo[] = {
#else
static double atanlo[] = {
#endif
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
};
#ifdef __STDC__
static const double aT[] = {
#else
static double aT[] = {
#endif
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
};
#ifdef __STDC__
static const double
#else
static double
#endif
one
= 1.0,
huge = 1.0e300;
#ifdef __STDC__
double atan(double x)
#else
double atan(x)
double x;
#endif
{
double w, s1, s2, z;
int ix, hx, id;
hx = __HI(x);
ix = hx & 0x7fffffff;
if (ix >= 0x44100000) { /* if |x| >= 2^66 */
if (ix > 0x7ff00000 || (ix == 0x7ff00000 && (__LO(x) != 0)))
return x + x; /* NaN */
if (hx > 0)
return atanhi[3] + atanlo[3];
else
return -atanhi[3] - atanlo[3];
}
if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
if (ix < 0x3e200000) { /* |x| < 2^-29 */
if (huge + x > one)
return x; /* raise inexact */
}
id = -1;
} else {
x = fabs__Fd(x);
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
id = 0;
x = (2.0 * x - one) / (2.0 + x);
} else { /* 11/16<=|x|< 19/16 */
id = 1;
x = (x - one) / (x + one);
}
} else {
if (ix < 0x40038000) { /* |x| < 2.4375 */
id = 2;
x = (x - 1.5) / (one + 1.5 * x);
} else { /* 2.4375 <= |x| < 2^66 */
id = 3;
x = -1.0 / x;
}
}
}
/* end of argument reduction */
z = x * x;
w = z * z;
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
s1 = z
* (aT[0]
+ w
* (aT[2]
+ w * (aT[4] + w * (aT[6] + w * (aT[8] + w * aT[10])))));
s2 = w * (aT[1] + w * (aT[3] + w * (aT[5] + w * (aT[7] + w * aT[9]))));
if (id < 0)
return x - x * (s1 + s2);
else {
z = atanhi[id] - ((x * (s1 + s2) - atanlo[id]) - x);
return (hx < 0) ? -z : z;
}
}

View file

@ -0,0 +1,58 @@
/* @(#)s_frexp.c 1.4 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* for non-zero x
* x = frexp(arg,&exp);
* return a double fp quantity x such that 0.5 <= |x| <1.0
* and the corresponding binary exponent "exp". That is
* arg = x*2^exp.
* If arg is inf, 0.0, or NaN, then frexp(arg,&exp) returns arg
* with *exp=0.
*/
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common_Embedded/Math/fdlibm.h"
#ifdef __STDC__
static const double
#else
static double
#endif
two54
= 1.80143985094819840000e+16; /* 0x43500000, 0x00000000 */
#ifdef __STDC__
double frexp(double x, int* eptr)
#else
double frexp(x, eptr)
double x;
int* eptr;
#endif
{
int hx, ix, lx;
hx = __HI(x);
ix = 0x7fffffff & hx;
lx = __LO(x);
*eptr = 0;
if (ix >= 0x7ff00000 || ((ix | lx) == 0))
return x; /* 0,inf,nan */
if (ix < 0x00100000) { /* subnormal */
x *= two54;
hx = __HI(x);
ix = hx & 0x7fffffff;
*eptr = -54;
}
*eptr += (ix >> 20) - 1022;
hx = (hx & 0x800fffff) | 0x3fe00000;
__HI(x) = hx;
return x;
}

View file

@ -0,0 +1,34 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/scanf.h"
int __StringRead(void* pPtr, int ch, int act)
{
char ret;
__InStrCtrl* Iscp = (__InStrCtrl*)pPtr;
switch (act) {
case __GetAChar:
ret = *(Iscp->NextChar);
if (ret == '\0') {
Iscp->NullCharDetected = 1;
return -1;
} else {
Iscp->NextChar++;
return ret;
}
case __UngetAChar:
if (Iscp->NullCharDetected == 0) {
Iscp->NextChar--;
} else {
Iscp->NullCharDetected = 0;
}
return ch;
case __TestForError:
return Iscp->NullCharDetected;
}
return 0;
}

View file

@ -0,0 +1,257 @@
#include "string.h"
static int K1 = 0x80808080;
static int K2 = 0xFEFEFEFF;
size_t strlen(const char* str)
{
size_t len = -1;
unsigned char* p = (unsigned char*)str - 1;
do {
len++;
} while (*++p);
return len;
}
char* strcpy(char* dst, const char* src)
{
register unsigned char *destb, *fromb;
register unsigned long w, t, align;
register unsigned int k1;
register unsigned int k2;
fromb = (unsigned char*)src;
destb = (unsigned char*)dst;
if ((align = ((int)fromb & 3)) != ((int)destb & 3)) {
goto bytecopy;
}
if (align) {
if ((*destb = *fromb) == 0) {
return dst;
}
for (align = 3 - align; align; align--) {
if ((*(++destb) = *(++fromb)) == 0) {
return dst;
}
}
++destb;
++fromb;
}
k1 = K1;
k2 = K2;
w = *((int*)(fromb));
t = w + k2;
t &= k1;
if (t) {
goto bytecopy;
}
--((int*)(destb));
do {
*(++((int*)(destb))) = w;
w = *(++((int*)(fromb)));
t = w + k2;
t &= k1;
if (t) {
goto adjust;
}
} while (1);
adjust:
++((int*)(destb));
bytecopy:
if ((*destb = *fromb) == 0) {
return dst;
}
do {
if ((*(++destb) = *(++fromb)) == 0) {
return dst;
}
} while (1);
return dst;
}
char* strncpy(char* dst, const char* src, size_t n)
{
const unsigned char* p = (const unsigned char*)src - 1;
unsigned char* q = (unsigned char*)dst - 1;
n++;
while (--n) {
if (!(*++q = *++p)) {
while (--n) {
*++q = 0;
}
break;
}
}
return dst;
}
char* strcat(char* dst, const char* src)
{
const unsigned char* p = (unsigned char*)src - 1;
unsigned char* q = (unsigned char*)dst - 1;
while (*++q) { }
q--;
while (*++q = *++p) { }
return dst;
}
int strcmp(const char* str1, const char* str2)
{
register unsigned char* left = (unsigned char*)str1;
register unsigned char* right = (unsigned char*)str2;
unsigned long align, l1, r1, x;
l1 = *left;
r1 = *right;
if (l1 - r1) {
return l1 - r1;
}
if ((align = ((int)left & 3)) != ((int)right & 3)) {
goto bytecopy;
}
if (align) {
if (l1 == 0) {
return 0;
}
for (align = 3 - align; align; align--) {
l1 = *(++left);
r1 = *(++right);
if (l1 - r1) {
return l1 - r1;
}
if (l1 == 0) {
return 0;
}
}
left++;
right++;
}
l1 = *(int*)left;
r1 = *(int*)right;
x = l1 + K2;
if (x & K1) {
goto adjust;
}
while (l1 == r1) {
l1 = *(++((int*)(left)));
r1 = *(++((int*)(right)));
x = l1 + K2;
if (x & K1) {
goto adjust;
}
}
if (l1 > r1) {
return 1;
}
return -1;
adjust:
l1 = *left;
r1 = *right;
if (l1 - r1) {
return l1 - r1;
}
bytecopy:
if (l1 == 0) {
return 0;
}
do {
l1 = *(++left);
r1 = *(++right);
if (l1 - r1) {
return l1 - r1;
}
if (l1 == 0) {
return 0;
}
} while (1);
}
char* strchr(const char* str, int c)
{
const unsigned char* p = (unsigned char*)str - 1;
unsigned long chr = (c & 0xFF);
unsigned long ch;
while (ch = *++p) {
if (ch == chr) {
return (char*)p;
}
}
return chr ? NULL : (char*)p;
}
char* strrchr(const char* str, int c)
{
const unsigned char* p = (unsigned char*)str - 1;
const unsigned char* q = NULL;
unsigned long chr = (c & 0xFF);
unsigned long ch;
while (ch = *++p) {
if (ch == chr) {
q = p;
}
}
if (q != NULL) {
return (char*)q;
}
return chr ? NULL : (char*)p;
}
char* strstr(const char* str, const char* pat)
{
const unsigned char* s1 = (const unsigned char*)str - 1;
const unsigned char* p1 = (const unsigned char*)pat - 1;
unsigned long firstc, c1, c2;
if ((pat == 0) || (!(firstc = *++p1))) {
return (char*)str;
}
while (c1 = *++s1) {
if (c1 == firstc) {
const unsigned char* s2 = s1 - 1;
const unsigned char* p2 = p1 - 1;
while ((c1 = *++s2) == (c2 = *++p2) && c1)
;
if (!c2)
return (char*)s1;
}
}
return NULL;
}

View file

@ -0,0 +1,199 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/strtoul.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/ctype.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/errno.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/limits.h"
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/scanf.h"
enum scan_states {
start = 0x01,
check_for_zero = 0x02,
leading_zero = 0x04,
need_digit = 0x08,
digit_loop = 0x10,
finished = 0x20,
failure = 0x40
};
#define final_state(scan_state) (scan_state & (finished | failure))
#define success(scan_state) \
(scan_state & (leading_zero | digit_loop | finished))
#define fetch() (count++, (*ReadProc)(ReadProcArg, 0, __GetAChar))
#define unfetch(c) (*ReadProc)(ReadProcArg, c, __UngetAChar)
unsigned long __strtoul(int base, int max_width,
int (*ReadProc)(void*, int, int), void* ReadProcArg,
int* chars_scanned, int* negative, int* overflow)
{
int scan_state = start;
int count = 0;
unsigned long value = 0;
unsigned long value_max = 0;
int c;
*negative = *overflow = 0;
if (base < 0 || base == 1 || base > 36 || max_width < 1) {
scan_state = failure;
} else {
c = fetch();
}
if (base != 0)
value_max = ULONG_MAX / base;
while (count <= max_width && c != -1 && !final_state(scan_state)) {
switch (scan_state) {
case start:
if (isspace(c)) {
c = fetch();
break;
}
if (c == '+') {
c = fetch();
} else if (c == '-') {
c = fetch();
*negative = 1;
}
scan_state = check_for_zero;
break;
case check_for_zero:
if (base == 0 || base == 16) {
if (c == '0') {
scan_state = leading_zero;
c = fetch();
break;
}
}
scan_state = need_digit;
break;
case 4:
if (c == 'X' || c == 'x') {
base = 16;
scan_state = need_digit;
c = fetch();
break;
}
if (base == 0)
base = 8;
scan_state = digit_loop;
break;
case need_digit:
case digit_loop:
if (base == 0)
base = 10;
if (!value_max) {
value_max = ULONG_MAX / base;
}
if (isdigit(c)) {
if ((c -= '0') >= base) {
if (scan_state == digit_loop)
scan_state = finished;
else
scan_state = failure;
c += '0';
break;
}
} else if (!isalpha(c) || (toupper(c) - 'A' + 10) >= base) {
if (scan_state == digit_loop)
scan_state = finished;
else
scan_state = failure;
break;
} else {
c = toupper(c) - 'A' + 10;
}
if (value > value_max)
*overflow = 1;
value *= base;
if (c > (ULONG_MAX - value))
*overflow = 1;
value += c;
scan_state = digit_loop;
c = fetch();
break;
}
}
if (!success(scan_state)) {
value = 0;
count = 0;
} else {
count--;
}
*chars_scanned = count;
unfetch(c);
return value;
}
unsigned long strtoul(const char* str, char** end, int base)
{
unsigned long value;
int count, negative, overflow;
__InStrCtrl isc;
isc.NextChar = (char*)str;
isc.NullCharDetected = 0;
value = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count,
&negative, &overflow);
if (end) {
*end = (char*)str + count;
}
if (overflow) {
value = ULONG_MAX;
errno = 0x22;
} else if (negative) {
value = -value;
}
return value;
}
long strtol(const char* str, char** end, int base)
{
unsigned long uvalue;
long svalue;
int count, negative, overflow;
__InStrCtrl isc;
isc.NextChar = (char*)str;
isc.NullCharDetected = 0;
uvalue = __strtoul(base, 0x7FFFFFFF, &__StringRead, (void*)&isc, &count,
&negative, &overflow);
if (end) {
*end = (char*)str + count;
}
if (overflow || (!negative && uvalue > LONG_MAX)
|| (negative && uvalue > -LONG_MIN)) {
svalue = (negative ? -LONG_MIN : LONG_MAX);
errno = ERANGE;
} else {
svalue = (negative ? (long)-uvalue : (long)uvalue);
}
return svalue;
}

View file

@ -0,0 +1,39 @@
/* @(#)w_atan2.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/*
* wrapper atan2(y,x)
*/
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common_Embedded/Math/fdlibm.h"
#ifdef __STDC__
double atan2(double y, double x) /* wrapper atan2 */
#else
double atan2(y, x) /* wrapper atan2 */
double y, x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_atan2(y, x);
#else
double z;
z = __ieee754_atan2(y, x);
if (_LIB_VERSION == _IEEE_ || isnan(x) || isnan(y))
return z;
if (x == 0.0 && y == 0.0) {
return __kernel_standard(y, x, 3); /* atan2(+-0,+-0) */
} else
return z;
#endif
}

View file

@ -0,0 +1,22 @@
#include "PowerPC_EABI_Support/Msl/MSL_C/MSL_Common/wchar_io.h"
int fwide(FILE* file, int mode)
{
if (file->file_mode.file_kind == __closed_file) {
return 0;
}
switch (file->file_mode.file_orientation) {
case UNORIENTED:
if (mode > 0) {
file->file_mode.file_orientation = WIDE_ORIENTED;
} else if (mode < 0) {
file->file_mode.file_orientation = CHAR_ORIENTED;
}
return mode;
case WIDE_ORIENTED:
return 1;
case CHAR_ORIENTED:
return -1;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,43 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/dispatch.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
u32 gTRKDispatchTableSize;
struct DispatchEntry {
int (*fn)(TRKBuffer*);
};
struct DispatchEntry gTRKDispatchTable[33] = {
{ &TRKDoUnsupported }, { &TRKDoConnect }, { &TRKDoDisconnect },
{ &TRKDoReset }, { &TRKDoVersions }, { &TRKDoSupportMask },
{ &TRKDoCPUType }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoReadMemory }, { &TRKDoWriteMemory },
{ &TRKDoReadRegisters }, { &TRKDoWriteRegisters }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoFlushCache }, { &TRKDoUnsupported },
{ &TRKDoContinue }, { &TRKDoStep }, { &TRKDoStop },
{ &TRKDoUnsupported }, { &TRKDoUnsupported }, { &TRKDoUnsupported },
{ &TRKDoUnsupported }, { &TRKDoUnsupported },
};
DSError TRKInitializeDispatcher()
{
gTRKDispatchTableSize = 32;
return DS_NoError;
}
DSError TRKDispatchMessage(TRKBuffer* buffer)
{
DSError error;
u8 command;
error = DS_DispatchError;
TRKSetBufferPosition(buffer, 0);
TRKReadBuffer1_ui8(buffer, &command);
if (command < gTRKDispatchTableSize) {
error = gTRKDispatchTable[command].fn(buffer);
}
return error;
}

View file

@ -0,0 +1,137 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/main_TRK.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.h"
#include "dolphin/ar.h"
#include "stddef.h"
#define EXCEPTIONMASK_ADDR 0x80000044
static u32 lc_base;
static u32 TRK_ISR_OFFSETS[15] = { PPC_SystemReset,
PPC_MachineCheck,
PPC_DataStorage,
PPC_InstructionStorage,
PPC_ExternalInterrupt,
PPC_Alignment,
PPC_Program,
PPC_FloatingPointUnavaiable,
PPC_Decrementer,
PPC_SystemCall,
PPC_Trace,
PPC_PerformanceMonitor,
PPC_InstructionAddressBreakpoint,
PPC_SystemManagementInterrupt,
PPC_ThermalManagementInterrupt };
__declspec(section ".init") void __TRK_reset(void) { __TRK_copy_vectors(); }
asm void InitMetroTRK()
{
#ifdef __MWERKS__ // clang-format off
nofralloc
addi r1, r1, -4
stw r3, 0(r1)
lis r3, gTRKCPUState@h
ori r3, r3, gTRKCPUState@l
stmw r0, ProcessorState_PPC.Default.GPR(r3) //Save the gprs
lwz r4, 0(r1)
addi r1, r1, 4
stw r1, ProcessorState_PPC.Default.GPR[1](r3)
stw r4, ProcessorState_PPC.Default.GPR[3](r3)
mflr r4
stw r4, ProcessorState_PPC.Default.LR(r3)
stw r4, ProcessorState_PPC.Default.PC(r3)
mfcr r4
stw r4, ProcessorState_PPC.Default.CR(r3)
//???
mfmsr r4
ori r3, r4, (1 << (31 - 16))
xori r3, r3, (1 << (31 - 16))
mtmsr r3
mtsrr1 r4 //Copy msr to srr1
//Save misc registers to gTRKCPUState
bl TRKSaveExtended1Block
lis r3, gTRKCPUState@h
ori r3, r3, gTRKCPUState@l
lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs
//Reset IABR and DABR
li r0, 0
mtspr 0x3f2, r0
mtspr 0x3f5, r0
//Restore stack pointer
lis r1, 0x80426008@h
ori r1, r1, 0x80426008@l
mr r3, r5
bl InitMetroTRKCommTable //Initialize comm table
/*
If InitMetroTRKCommTable returned 1 (failure), an invalid hardware
id or the id for GDEV was somehow passed. Since only BBA or NDEV
are supported, we return early. Otherwise, we proceed with
starting up TRK.
*/
cmpwi r3, 1
bne initCommTableSuccess
/*
BUG: The code probably orginally reloaded gTRKCPUState here, but
as is it will read the returned value of InitMetroTRKCommTable
as a TRKCPUState struct pointer, causing the CPU to return to
a garbage code address.
*/
lwz r4, ProcessorState_PPC.Default.LR(r3)
mtlr r4
lmw r0, ProcessorState_PPC.Default.GPR(r3) //Restore the gprs
blr
initCommTableSuccess:
b TRK_main //Jump to TRK_main
#endif // clang-format on
}
void EnableMetroTRKInterrupts(void) { EnableEXI2Interrupts(); }
u32 TRKTargetTranslate(u32 param_0)
{
if (param_0 >= lc_base) {
if ((param_0 < lc_base + 0x4000)
&& ((gTRKCPUState.Extended1.DBAT3U & 3) != 0)) {
return param_0;
}
}
return param_0 & 0x3FFFFFFF | 0x80000000;
}
extern u8 gTRKInterruptVectorTable[];
void TRK_copy_vector(u32 offset)
{
void* destPtr = (void*)TRKTargetTranslate(offset);
TRK_memcpy(destPtr, gTRKInterruptVectorTable + offset, 0x100);
TRK_flush_cache(destPtr, 0x100);
}
void __TRK_copy_vectors(void)
{
int i;
u32 mask;
mask = *(u32*)TRKTargetTranslate(0x44);
for (i = 0; i <= 14; ++i) {
if (mask & (1 << i)) {
TRK_copy_vector(TRK_ISR_OFFSETS[i]);
}
}
}
DSError TRKInitializeTarget()
{
gTRKState.isStopped = TRUE;
gTRKState.msr = __TRK_get_MSR();
lc_base = 0xE0000000;
return DS_NoError;
}

View file

@ -0,0 +1,116 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "OdemuExi2/odemuexi/DebuggerDriver.h"
#include "amcstubs/AmcExi2Stubs.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
DBCommTable gDBCommTable = {};
asm void TRKLoadContext(OSContext* ctx, u32)
{
#ifdef __MWERKS__ // clang-format off
nofralloc
lwz r0, OSContext.gpr[0](r3)
lwz r1, OSContext.gpr[1](r3)
lwz r2, OSContext.gpr[2](r3)
lhz r5, OSContext.state(r3)
rlwinm. r6, r5, 0, 0x1e, 0x1e
beq lbl_80371C1C
rlwinm r5, r5, 0, 0x1f, 0x1d
sth r5, OSContext.state(r3)
lmw r5, OSContext.gpr[5](r3)
b lbl_80371C20
lbl_80371C1C:
lmw r13, OSContext.gpr[13](r3)
lbl_80371C20:
mr r31, r3
mr r3, r4
lwz r4, OSContext.cr(r31)
mtcrf 0xff, r4
lwz r4, OSContext.lr(r31)
mtlr r4
lwz r4, OSContext.ctr(r31)
mtctr r4
lwz r4, OSContext.xer(r31)
mtxer r4
mfmsr r4
rlwinm r4, r4, 0, 0x11, 0xf //Turn off external exceptions
rlwinm r4, r4, 0, 0x1f, 0x1d //Turn off recoverable exception flag
mtmsr r4
mtsprg 1, r2
lwz r4, OSContext.gpr[3](r31)
mtsprg 2, r4
lwz r4, OSContext.gpr[4](r31)
mtsprg 3, r4
lwz r2, OSContext.srr0(r31)
lwz r4, OSContext.srr1(r31)
lwz r31, OSContext.gpr[31](r31)
b TRKInterruptHandler
#endif // clang-format on
}
void TRKEXICallBack(__OSInterrupt param_0, OSContext* ctx)
{
OSEnableScheduler();
TRKLoadContext(ctx, 0x500);
}
int InitMetroTRKCommTable(int hwId)
{
int result;
if (hwId == HARDWARE_GDEV) {
result = Hu_IsStub();
gDBCommTable.initialize_func = DBInitComm;
gDBCommTable.init_interrupts_func = DBInitInterrupts;
gDBCommTable.peek_func = DBQueryData;
gDBCommTable.read_func = DBRead;
gDBCommTable.write_func = DBWrite;
gDBCommTable.open_func = DBOpen;
gDBCommTable.close_func = DBClose;
} else {
result = AMC_IsStub();
gDBCommTable.initialize_func = EXI2_Init;
gDBCommTable.init_interrupts_func = EXI2_EnableInterrupts;
gDBCommTable.peek_func = EXI2_Poll;
gDBCommTable.read_func = EXI2_ReadN;
gDBCommTable.write_func = EXI2_WriteN;
gDBCommTable.open_func = EXI2_Reserve;
gDBCommTable.close_func = EXI2_Unreserve;
}
return result;
}
void TRKUARTInterruptHandler() { }
DSError TRKInitializeIntDrivenUART(u32 param_0, u32 param_1, u32 param_2,
volatile u8** param_3)
{
gDBCommTable.initialize_func(param_3, TRKEXICallBack);
return DS_NoError;
}
void EnableEXI2Interrupts(void) { gDBCommTable.init_interrupts_func(); }
int TRKPollUART(void) { return gDBCommTable.peek_func(); }
UARTError TRKReadUARTN(void* bytes, u32 length)
{
int readErr = gDBCommTable.read_func(bytes, length);
return readErr == 0 ? 0 : -1;
}
UARTError TRKWriteUARTN(const void* bytes, u32 length)
{
int writeErr = gDBCommTable.write_func(bytes, length);
return writeErr == 0 ? 0 : -1;
}
void ReserveEXI2Port(void) { gDBCommTable.open_func(); }
void UnreserveEXI2Port(void) { gDBCommTable.close_func(); }
void TRK_board_display(char* str) { OSReport(str); }

View file

@ -0,0 +1,26 @@
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/flush_cache.h"
asm void TRK_flush_cache(register void* param_1, register int param_2)
{
#ifdef __MWERKS__ // clang-format off
nofralloc
lis r5, 0xFFFF
ori r5, r5, 0xFFF1
and r5, r5, param_1
subf r3, r5, param_1
add r4, param_2, r3
loop:
dcbst 0, r5
dcbf 0, r5
sync
icbi 0, r5
addic r5, r5, 8
addic. r4, r4, -8
bge loop
isync
blr
#endif // clang-format on
}

View file

@ -0,0 +1,17 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/main_TRK.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubinit.h"
static DSError TRK_mainError;
DSError TRK_main(void)
{
TRK_mainError = TRKInitializeNub();
if (TRK_mainError == DS_NoError) {
TRKNubWelcome();
TRKNubMainLoop();
}
TRK_mainError = TRKTerminateNub();
return TRK_mainError;
}

View file

@ -0,0 +1,70 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/dispatch.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
void TRKHandleRequestEvent(TRKEvent* event)
{
TRKBuffer* buffer = TRKGetBuffer(event->msgBufID);
TRKDispatchMessage(buffer);
}
void TRKHandleSupportEvent(TRKEvent* event) { TRKTargetSupportRequest(); }
void TRKIdle()
{
if (TRKTargetStopped() == FALSE) {
TRKTargetContinue();
}
}
void TRKNubMainLoop(void)
{
void* msg;
TRKEvent event;
BOOL isShutdownRequested;
BOOL isNewInput;
isShutdownRequested = FALSE;
isNewInput = FALSE;
while (isShutdownRequested == FALSE) {
if (TRKGetNextEvent(&event) != FALSE) {
isNewInput = FALSE;
switch (event.eventType) {
case NUBEVENT_Null:
break;
case NUBEVENT_Request:
TRKHandleRequestEvent(&event);
break;
case NUBEVENT_Shutdown:
isShutdownRequested = TRUE;
break;
case NUBEVENT_Breakpoint:
case NUBEVENT_Exception:
TRKTargetInterrupt(&event);
break;
case NUBEVENT_Support:
TRKHandleSupportEvent(&event);
break;
}
TRKDestructEvent(&event);
continue;
}
if ((isNewInput == FALSE) || (*(u8*)gTRKInputPendingPtr != '\0')) {
isNewInput = TRUE;
TRKGetInput();
continue;
}
TRKIdle();
isNewInput = FALSE;
}
}

View file

@ -0,0 +1,83 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
#include "dolphin/types.h"
void TRK_fill_mem(void *dest, int value, unsigned long length)
{
#define cDest ((unsigned char *)dest)
#define lDest ((unsigned long *)dest)
unsigned long val = (unsigned char)value;
unsigned long i;
lDest = (unsigned long *)dest;
cDest = (unsigned char *)dest;
cDest--;
if (length >= 32) {
i = ~(unsigned long)dest & 3;
if (i) {
length -= i;
do {
*++cDest = val;
} while (--i);
}
if (val) {
val |= val << 24 | val << 16 | val << 8;
}
lDest = (unsigned long *)(cDest + 1) - 1;
i = length >> 5;
if (i) {
do {
*++lDest = val;
*++lDest = val;
*++lDest = val;
*++lDest = val;
*++lDest = val;
*++lDest = val;
*++lDest = val;
*++lDest = val;
} while (--i);
}
i = (length & 31) >> 2;
if (i) {
do {
*++lDest = val;
} while (--i);
}
cDest = (unsigned char *)(lDest + 1) - 1;
length &= 3;
}
if (length) {
do {
*++cDest = val;
} while (--length);
}
#undef cDest
#undef lDest
}
__declspec(section ".init") void *TRK_memcpy(void *dst, const void *src, size_t n)
{
const char *p;
char *q;
for (p = (const char *)src - 1, q = (char *)dst - 1, n++; --n;)
*++q = *++p;
return dst;
}
__declspec(section ".init") void *TRK_memset(void *dst, int val, size_t n)
{
TRK_fill_mem(dst, val, n);
return dst;
}

View file

@ -0,0 +1,248 @@
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/mpc_7xx_603e.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
extern u8 gTRKRestoreFlags[9 + 3 /* padding */];
asm void TRKSaveExtended1Block()
{
#ifdef __MWERKS__ // clang-format off
nofralloc
lis r2, gTRKCPUState@h /* 0x8044F338@h */
ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */
mfsr r16, 0
mfsr r17, 1
mfsr r18, 2
mfsr r19, 3
mfsr r20, 4
mfsr r21, 5
mfsr r22, 6
mfsr r23, 7
mfsr r24, 8
mfsr r25, 9
mfsr r26, 0xa
mfsr r27, 0xb
mfsr r28, 0xc
mfsr r29, 0xd
mfsr r30, 0xe
mfsr r31, 0xf
stmw r16, 0x1a8(r2)
mftb r10, 0x10c
mftbu r11
mfspr r12, 0x3f0
mfspr r13, 0x3f1
mfspr r14, 0x1b
mfpvr r15
mfibatu r16, 0
mfibatl r17, 0
mfibatu r18, 1
mfibatl r19, 1
mfibatu r20, 2
mfibatl r21, 2
mfibatu r22, 3
mfibatl r23, 3
mfdbatu r24, 0
mfdbatl r25, 0
mfdbatu r26, 1
mfdbatl r27, 1
mfdbatu r28, 2
mfdbatl r29, 2
mfdbatu r30, 3
mfdbatl r31, 3
stmw r10, 0x1e8(r2)
mfspr r22, 0x19
mfdar r23
mfdsisr r24
mfspr r25, 0x110
mfspr r26, 0x111
mfspr r27, 0x112
mfspr r28, 0x113
li r29, 0
mfspr r30, 0x3f2
mfspr r31, 0x11a
stmw r22, 0x25c(r2)
mfspr r20, 0x390
mfspr r21, 0x391
mfspr r22, 0x392
mfspr r23, 0x393
mfspr r24, 0x394
mfspr r25, 0x395
mfspr r26, 0x396
mfspr r27, 0x397
mfspr r28, 0x398
mfspr r29, 0x399
mfspr r30, 0x39a
mfspr r31, 0x39b
stmw r20, 0x2fc(r2)
b lbl_80371340
mfspr r16, 0x3a0
mfspr r17, 0x3a7
mfspr r18, 0x3a8
mfspr r19, 0x3a9
mfspr r20, 0x3aa
mfspr r21, 0x3ab
mfspr r22, 0x3ac
mfspr r23, 0x3ad
mfspr r24, 0x3ae
mfspr r25, 0x3af
mfspr r26, 0x3b0
mfspr r27, 0x3b7
mfspr r28, 0x3bf
mfspr r29, 0x3f6
mfspr r30, 0x3f7
mfspr r31, 0x3ff
stmw r16, 0x2b8(r2)
lbl_80371340:
mfspr r19, 0x3f5
mfspr r20, 0x3b9
mfspr r21, 0x3ba
mfspr r22, 0x3bd
mfspr r23, 0x3be
mfspr r24, 0x3bb
mfspr r25, 0x3b8
mfspr r26, 0x3bc
mfspr r27, 0x3fc
mfspr r28, 0x3fd
mfspr r29, 0x3fe
mfspr r30, 0x3FB
mfspr r31, 0x3f9
stmw r19, 0x284(r2)
b end
mfspr r25, 0x3d0
mfspr r26, 0x3d1
mfspr r27, 0x3d2
mfspr r28, 0x3d3
mfspr r29, 0x3D4
mfspr r30, 0x3D5
mfspr r31, 0x3d6
stmw r25, 0x240(r2)
mfspr r31, 0x16
stw r31, 0x278(r2)
end:
blr
#endif // clang-format on
}
asm void TRKRestoreExtended1Block()
{
#ifdef __MWERKS__ // clang-format off
nofralloc
lis r2, gTRKCPUState@h /* 0x8044F338@h */
ori r2, r2, gTRKCPUState@l /* 0x8044F338@l */
lis r5, gTRKRestoreFlags@h /* 0x803D3238@h */
ori r5, r5, gTRKRestoreFlags@l /* 0x803D3238@l */
lbz r3, 0(r5)
lbz r6, 1(r5)
li r0, 0
stb r0, 0(r5)
stb r0, 1(r5)
cmpwi r3, 0
beq lbl_803713E4
lwz r24, 0x1e8(r2)
lwz r25, 0x1ec(r2)
mttbl r24
mttbu r25
lbl_803713E4:
lmw r20, 0x2fc(r2)
mtspr 0x390, r20
mtspr 0x391, r21
mtspr 0x392, r22
mtspr 0x393, r23
mtspr 0x394, r24
mtspr 0x395, r25
mtspr 0x396, r26
mtspr 0x397, r27
mtspr 0x398, r28
mtspr 0x39a, r30
mtspr 0x39b, r31
b lbl_80371430
lmw r26, 0x2e0(r2)
mtspr 0x3b0, r26
mtspr 0x3b7, r27
mtspr 0x3f6, r29
mtspr 0x3f7, r30
mtspr 0x3ff, r31
lbl_80371430:
lmw r19, 0x284(r2)
mtspr 0x3f5, r19
mtspr 0x3b9, r20
mtspr 0x3ba, r21
mtspr 0x3bd, r22
mtspr 0x3be, r23
mtspr 0x3bb, r24
mtspr 0x3b8, r25
mtspr 0x3bc, r26
mtspr 0x3fc, r27
mtspr 0x3fd, r28
mtspr 0x3fe, r29
mtspr 0x3FB, r30
mtspr 0x3f9, r31
b lbl_8037149C
cmpwi r6, 0
beq lbl_8037147C
lwz r26, 0x278(r2)
mtspr 0x16, r26
lbl_8037147C:
lmw r25, 0x240(r2)
mtspr 0x3d0, r25
mtspr 0x3d1, r26
mtspr 0x3d2, r27
mtspr 0x3d3, r28
mtspr 0x3D4, r29
mtspr 0x3D5, r30
mtspr 0x3d6, r31
lbl_8037149C:
lmw r16, 0x1a8(r2)
mtsr 0, r16
mtsr 1, r17
mtsr 2, r18
mtsr 3, r19
mtsr 4, r20
mtsr 5, r21
mtsr 6, r22
mtsr 7, r23
mtsr 8, r24
mtsr 9, r25
mtsr 0xa, r26
mtsr 0xb, r27
mtsr 0xc, r28
mtsr 0xd, r29
mtsr 0xe, r30
mtsr 0xf, r31
lmw r12, 0x1f0(r2)
mtspr 0x3f0, r12
mtspr 0x3f1, r13
mtspr 0x1b, r14
mtspr 0x11f, r15
mtibatu 0, r16
mtibatl 0, r17
mtibatu 1, r18
mtibatl 1, r19
mtibatu 2, r20
mtibatl 2, r21
mtibatu 3, r22
mtibatl 3, r23
mtdbatu 0, r24
mtdbatl 0, r25
mtdbatu 1, r26
mtdbatl 1, r27
mtdbatu 2, r28
mtdbatl 2, r29
mtdbatu 3, r30
mtdbatl 3, r31
lmw r22, 0x25c(r2)
mtspr 0x19, r22
mtdar r23
mtdsisr r24
mtspr 0x110, r25
mtspr 0x111, r26
mtspr 0x112, r27
mtspr 0x113, r28
mtspr 0x3f2, r30
mtspr 0x11a, r31
blr
#endif // clang-format on
}
u32 TRKTargetCPUMinorType(void) { return 0x54; }

View file

@ -0,0 +1,9 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
DSError TRKMessageSend(TRK_Msg* msg)
{
DSError write_err = TRKWriteUARTN(&msg->m_msg, msg->m_msgLength);
return DS_NoError;
}

View file

@ -0,0 +1,359 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubinit.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mutex_TRK.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
#include "stddef.h"
TRKBuffer gTRKMsgBufs[3];
void TRKSetBufferUsed(TRKBuffer* msg, BOOL state) { msg->isInUse = state; }
DSError TRKInitializeMessageBuffers(void)
{
int i;
for (i = 0; i < 3; i++) {
TRKInitializeMutex(&gTRKMsgBufs[i]);
TRKAcquireMutex(&gTRKMsgBufs[i]);
TRKSetBufferUsed(&gTRKMsgBufs[i], FALSE);
TRKReleaseMutex(&gTRKMsgBufs[i]);
}
return DS_NoError;
}
DSError TRKGetFreeBuffer(int* msgID, TRKBuffer** outMsg)
{
TRKBuffer* buf;
DSError error = DS_NoMessageBufferAvailable;
int i;
*outMsg = NULL;
for (i = 0; i < 3; i++) {
buf = TRKGetBuffer(i);
TRKAcquireMutex(buf);
if (!buf->isInUse) {
TRKResetBuffer(buf, TRUE);
TRKSetBufferUsed(buf, TRUE);
error = DS_NoError;
*outMsg = buf;
*msgID = i;
i = 3; // why not break? weird choice
}
TRKReleaseMutex(buf);
}
return error;
}
void* TRKGetBuffer(int idx)
{
TRKBuffer* buf = NULL;
if (idx >= 0 && idx < 3) {
buf = &gTRKMsgBufs[idx];
}
return buf;
}
void TRKReleaseBuffer(int idx)
{
TRKBuffer* msg;
if (idx != -1 && idx >= 0 && idx < 3) {
msg = &gTRKMsgBufs[idx];
TRKAcquireMutex(msg);
TRKSetBufferUsed(msg, FALSE);
TRKReleaseMutex(msg);
}
}
void TRKResetBuffer(TRKBuffer* msg, BOOL keepData)
{
msg->length = 0;
msg->position = 0;
if (!keepData) {
TRK_memset(msg->data, 0, TRKMSGBUF_SIZE);
}
}
DSError TRKSetBufferPosition(TRKBuffer* msg, u32 pos)
{
DSError error = DS_NoError;
if (pos > 0x880) {
error = DS_MessageBufferOverflow;
} else {
msg->position = pos;
// If the new position is past the current length,
// update the length
if (pos > msg->length) {
msg->length = pos;
}
}
return error;
}
DSError TRKAppendBuffer(TRKBuffer* msg, const void* data, size_t length)
{
DSError error = DS_NoError; // r31
u32 bytesLeft;
// Return if no bytes to append
if (length == 0) {
return DS_NoError;
}
bytesLeft = 0x880 - msg->position;
// If there isn't enough space left in the buffer, change the number
// of bytes to append to the remaning number of bytes
if (bytesLeft < length) {
error = DS_MessageBufferOverflow;
length = bytesLeft;
}
if (length == 1) {
// If the length of bytes to append is 1, just copy the byte over
msg->data[msg->position] = ((u8*)data)[0];
} else {
// Otherwise, use memcpy
TRK_memcpy(msg->data + msg->position, data, length);
}
// Update the position and length
msg->position += length;
msg->length = msg->position;
return error;
}
DSError TRKReadBuffer(TRKBuffer* msg, void* data, size_t length)
{
DSError error = DS_NoError;
unsigned int
bytesLeft; // this has to be unsigned int not u32 to match lmfao.
// Return if no bytes to read
if (length == 0) {
return DS_NoError;
}
bytesLeft = msg->length - msg->position;
// If the number of bytes to read exceeds the buffer length, change
// the length to the remaining number of bytes
if (length > bytesLeft) {
error = DS_MessageBufferReadError;
length = bytesLeft;
}
TRK_memcpy(data, msg->data + msg->position, length);
msg->position += length;
return error;
}
DSError TRKAppendBuffer1_ui16(TRKBuffer* buffer, const u16 data)
{
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[1];
bigEndianData[1] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer1_ui32(TRKBuffer* buffer, const u32 data)
{
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[3];
bigEndianData[1] = byteData[2];
bigEndianData[2] = byteData[1];
bigEndianData[3] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer1_ui64(TRKBuffer* buffer, const u64 data)
{
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)&data;
} else {
byteData = (u8*)&data;
bigEndianData = swapBuffer;
bigEndianData[0] = byteData[7];
bigEndianData[1] = byteData[6];
bigEndianData[2] = byteData[5];
bigEndianData[3] = byteData[4];
bigEndianData[4] = byteData[3];
bigEndianData[5] = byteData[2];
bigEndianData[6] = byteData[1];
bigEndianData[7] = byteData[0];
}
return TRKAppendBuffer(buffer, (const void*)bigEndianData, sizeof(data));
}
DSError TRKAppendBuffer_ui8(TRKBuffer* buffer, const u8* data, int count)
{
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKAppendBuffer1_ui8(buffer, data[i]);
}
return err;
}
DSError TRKAppendBuffer_ui32(TRKBuffer* buffer, const u32* data, int count)
{
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKAppendBuffer1_ui32(buffer, data[i]);
}
return err;
}
DSError TRKReadBuffer1_ui8(TRKBuffer* buffer, u8* data)
{
return TRKReadBuffer(buffer, (void*)data, 1);
}
DSError TRKReadBuffer1_ui16(TRKBuffer* buffer, u16* data)
{
DSError err;
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)data;
} else {
bigEndianData = swapBuffer;
}
err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data));
if (!gTRKBigEndian && err == DS_NoError) {
byteData = (u8*)data;
byteData[0] = bigEndianData[1];
byteData[1] = bigEndianData[0];
}
return err;
}
DSError TRKReadBuffer1_ui32(TRKBuffer* buffer, u32* data)
{
DSError err;
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)data;
} else {
bigEndianData = swapBuffer;
}
err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data));
if (!gTRKBigEndian && err == DS_NoError) {
byteData = (u8*)data;
byteData[0] = bigEndianData[3];
byteData[1] = bigEndianData[2];
byteData[2] = bigEndianData[1];
byteData[3] = bigEndianData[0];
}
return err;
}
DSError TRKReadBuffer1_ui64(TRKBuffer* buffer, u64* data)
{
DSError err;
u8* bigEndianData;
u8* byteData;
u8 swapBuffer[sizeof(data)];
if (gTRKBigEndian) {
bigEndianData = (u8*)data;
} else {
bigEndianData = swapBuffer;
}
err = TRKReadBuffer(buffer, (void*)bigEndianData, sizeof(*data));
if (!gTRKBigEndian && err == 0) {
byteData = (u8*)data;
byteData[0] = bigEndianData[7];
byteData[1] = bigEndianData[6];
byteData[2] = bigEndianData[5];
byteData[3] = bigEndianData[4];
byteData[4] = bigEndianData[3];
byteData[5] = bigEndianData[2];
byteData[6] = bigEndianData[1];
byteData[7] = bigEndianData[0];
}
return err;
}
DSError TRKReadBuffer_ui8(TRKBuffer* buffer, u8* data, int count)
{
DSError err;
int i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKReadBuffer1_ui8(buffer, &(data[i]));
}
return err;
}
DSError TRKReadBuffer_ui32(TRKBuffer* buffer, u32* data, int count)
{
DSError err;
s32 i;
for (i = 0, err = DS_NoError; err == DS_NoError && i < count; i++) {
err = TRKReadBuffer1_ui32(buffer, &(data[i]));
}
return err;
}

View file

@ -0,0 +1,689 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
BOOL IsTRKConnected;
BOOL GetTRKConnected()
{
return IsTRKConnected;
}
void SetTRKConnected(BOOL connected)
{
IsTRKConnected = connected;
}
static void TRKMessageIntoReply(TRKBuffer* buffer, u8 ackCmd,
DSReplyError errSentInAck)
{
TRKResetBuffer(buffer, 1);
TRKAppendBuffer1_ui8(buffer, ackCmd);
TRKAppendBuffer1_ui8(buffer, errSentInAck);
}
DSError TRKSendACK(TRKBuffer* buffer)
{
DSError err;
int ackTries;
ackTries = 3;
do {
err = TRKMessageSend((TRK_Msg*)buffer);
--ackTries;
} while (err != DS_NoError && ackTries > 0);
return err;
}
DSError TRKStandardACK(TRKBuffer* buffer, MessageCommandID commandID,
DSReplyError replyError)
{
TRKMessageIntoReply(buffer, commandID, replyError);
TRKSendACK(buffer);
return;
}
DSError TRKDoUnsupported(TRKBuffer* buffer)
{
return TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_UnsupportedCommandError);
}
DSError TRKDoConnect(TRKBuffer* buffer)
{
SetTRKConnected(TRUE);
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
}
DSError TRKDoDisconnect(TRKBuffer* buffer)
{
DSError error = DS_NoError;
TRKEvent event;
SetTRKConnected(FALSE);
if ((error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError))
== DS_NoError) {
TRKConstructEvent(&event, 1);
TRKPostEvent(&event);
}
return error;
}
DSError TRKDoReset(TRKBuffer* buffer)
{
TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
__TRK_reset();
return DS_NoError;
}
DSError TRKDoVersions(TRKBuffer* buffer)
{
DSError error;
DSVersions versions;
if (buffer->length != 1) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
} else {
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
error = TRKTargetVersions(&versions);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, versions.kernelMajor);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, versions.kernelMinor);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, versions.protocolMajor);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, versions.protocolMinor);
if (error != DS_NoError)
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError);
else
error = TRKSendACK(buffer);
}
return error;
}
DSError TRKDoSupportMask(TRKBuffer* buffer)
{
DSError error;
u8 mask[32];
if (buffer->length != 1) {
TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
} else {
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
error = TRKTargetSupportMask(mask);
if (error == DS_NoError)
error = TRKAppendBuffer(buffer, mask, 32);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, 2);
if (error != DS_NoError)
TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError);
else
TRKSendACK(buffer);
}
}
DSError TRKDoCPUType(TRKBuffer* buffer)
{
DSError error;
DSCPUType cputype;
if (buffer->length != 1) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
error = TRKTargetCPUType(&cputype);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.cpuMajor);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.cpuMinor);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.bigEndian);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.defaultTypeSize);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.fpTypeSize);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.extended1TypeSize);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, cputype.extended2TypeSize);
if (error != DS_NoError)
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_CWDSError);
else
error = TRKSendACK(buffer);
return error;
}
DSError TRKDoReadMemory(TRKBuffer* buffer)
{
DSError error;
DSReplyError replyError;
u8 tempBuf[0x800];
u32 length;
u32 msg_start;
u16 msg_length;
u8 msg_options;
u8 msg_command;
if (buffer->length != 8) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_length);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_start);
if (msg_options & 2) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_UnsupportedOptionError);
return error;
}
if (msg_length > 0x800) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
return error;
}
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error == DS_NoError) {
length = (u32)msg_length;
error = TRKTargetAccessMemory(
tempBuf, msg_start, &length,
(msg_options & 8) ? MEMACCESS_UserMemory : MEMACCESS_DebuggerMemory,
1);
msg_length = (u16)length;
if (error == DS_NoError)
error = TRKAppendBuffer1_ui16(buffer, msg_length);
if (error == DS_NoError)
error = TRKAppendBuffer(buffer, tempBuf, length);
}
if (error != DS_NoError) {
switch (error) {
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidMemory:
replyError = DSREPLY_InvalidMemoryRange;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
break;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError);
} else {
error = TRKSendACK(buffer);
}
return error;
}
DSError TRKDoWriteMemory(TRKBuffer* buffer)
{
DSError error;
DSReplyError replyError;
u8 tmpBuffer[0x800];
u32 length;
u32 msg_start;
u16 msg_length;
u8 msg_options;
u8 msg_command;
if (buffer->length <= 8) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_length);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_start);
if (msg_options & 2) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_UnsupportedOptionError);
return error;
}
if ((buffer->length != msg_length + 8) || (msg_length > 0x800)) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
} else {
if (error == DS_NoError) {
length = (u32)msg_length;
error = TRKReadBuffer(buffer, tmpBuffer, length);
if (error == DS_NoError) {
error = TRKTargetAccessMemory(tmpBuffer, msg_start, &length,
(msg_options & 8)
? MEMACCESS_UserMemory
: MEMACCESS_DebuggerMemory,
FALSE);
}
msg_length = (u16)length;
}
if (error == DS_NoError)
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui16(buffer, msg_length);
if (error != DS_NoError) {
switch (error) {
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidMemory:
replyError = DSREPLY_InvalidMemoryRange;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
break;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError);
} else {
error = TRKSendACK(buffer);
}
}
return error;
}
DSError TRKDoReadRegisters(TRKBuffer* buffer)
{
DSError error;
DSReplyError replyError;
DSMessageRegisterOptions options;
u32 registerDataLength;
u16 msg_lastRegister;
u16 msg_firstRegister;
u8 msg_options;
u8 msg_command;
if (buffer->length != 6) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_firstRegister);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_lastRegister);
if (msg_firstRegister > msg_lastRegister) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidRegisterRange);
return error;
}
if (error == DS_NoError)
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
options = (DSMessageRegisterOptions)msg_options;
switch (options) {
case DSREG_Default:
error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, TRUE);
break;
case DSREG_FP:
error = TRKTargetAccessFP(msg_firstRegister, msg_lastRegister, buffer,
&registerDataLength, TRUE);
break;
case DSREG_Extended1:
error = TRKTargetAccessExtended1(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, TRUE);
break;
case DSREG_Extended2:
error = TRKTargetAccessExtended2(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, TRUE);
break;
default:
error = DS_UnsupportedError;
break;
}
if (error != DS_NoError) {
switch (error) {
case DS_UnsupportedError:
replyError = DSREPLY_UnsupportedOptionError;
break;
case DS_InvalidRegister:
replyError = DSREPLY_InvalidRegisterRange;
break;
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError);
} else {
error = TRKSendACK(buffer);
}
return error;
}
DSError TRKDoWriteRegisters(TRKBuffer* buffer)
{
DSError error;
DSReplyError replyError;
DSMessageRegisterOptions options;
u32 registerDataLength;
u16 msg_lastRegister;
u16 msg_firstRegister;
u8 msg_options;
u8 msg_command;
if (buffer->length <= 6) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_firstRegister);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(buffer, &msg_lastRegister);
if (msg_firstRegister > msg_lastRegister) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidRegisterRange);
return error;
}
options = (DSMessageRegisterOptions)msg_options;
switch (options) {
case DSREG_Default:
error = TRKTargetAccessDefault(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, FALSE);
break;
case DSREG_FP:
error = TRKTargetAccessFP(msg_firstRegister, msg_lastRegister, buffer,
&registerDataLength, FALSE);
break;
case DSREG_Extended1:
error = TRKTargetAccessExtended1(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, FALSE);
break;
case DSREG_Extended2:
error = TRKTargetAccessExtended2(msg_firstRegister, msg_lastRegister,
buffer, &registerDataLength, FALSE);
break;
default:
error = DS_UnsupportedError;
break;
}
if (error == DS_NoError)
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error != DS_NoError) {
switch (error) {
case DS_UnsupportedError:
replyError = DSREPLY_UnsupportedOptionError;
break;
case DS_InvalidRegister:
replyError = DSREPLY_InvalidRegisterRange;
break;
case DS_MessageBufferReadError:
replyError = DSREPLY_PacketSizeError;
break;
case DS_CWDSException:
replyError = DSREPLY_CWDSException;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_CWDSError;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyError);
} else {
error = TRKSendACK(buffer);
}
return error;
}
DSError TRKDoFlushCache(TRKBuffer* buffer)
{
DSError error;
DSReplyError replyErr;
u32 msg_end;
u32 msg_start;
u8 msg_options;
u8 msg_command;
if (buffer->length != 10) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
return error;
}
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_start);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_end);
if (msg_start > msg_end) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_InvalidMemoryRange);
return error;
}
if (error == DS_NoError)
error = TRKTargetFlushCache(msg_options, (void*)msg_start,
(void*)msg_end);
if (error == DS_NoError)
TRKMessageIntoReply(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error != DS_NoError) {
switch (error) {
case DS_UnsupportedError:
replyErr = DSREPLY_UnsupportedOptionError;
break;
default:
replyErr = DSREPLY_CWDSError;
break;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, replyErr);
} else {
error = TRKSendACK(buffer);
}
return error;
}
DSError TRKDoContinue(TRKBuffer* buffer)
{
DSError error;
error = TRKTargetStopped();
if (error == DS_NoError) {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped);
return error;
}
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error == DS_NoError)
error = TRKTargetContinue();
return error;
}
DSError TRKDoStep(TRKBuffer* buffer)
{
DSError error;
u8 msg_command;
u8 msg_options;
u8 msg_count;
u32 msg_rangeStart;
u32 msg_rangeEnd;
u32 pc;
if (buffer->length < 3)
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_PacketSizeError);
TRKSetBufferPosition(buffer, DSREPLY_NoError);
error = TRKReadBuffer1_ui8(buffer, &msg_command);
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(buffer, &msg_options);
switch (msg_options) {
case DSSTEP_IntoCount:
case DSSTEP_OverCount:
if (error == DS_NoError)
TRKReadBuffer1_ui8(buffer, &msg_count);
if (msg_count >= 1) {
break;
}
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
case DSSTEP_IntoRange:
case DSSTEP_OverRange:
if (buffer->length != 10)
return TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_PacketSizeError);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_rangeStart);
if (error == DS_NoError)
error = TRKReadBuffer1_ui32(buffer, &msg_rangeEnd);
pc = TRKTargetGetPC();
if (pc >= msg_rangeStart && pc <= msg_rangeEnd) {
break;
}
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_ParameterError);
default:
return TRKStandardACK(buffer, DSMSG_ReplyACK,
DSREPLY_UnsupportedOptionError);
}
if (!TRKTargetStopped()) {
return TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NotStopped);
} else {
error = TRKStandardACK(buffer, DSMSG_ReplyACK, DSREPLY_NoError);
if (error == DS_NoError)
switch (msg_options) {
case DSSTEP_IntoCount:
case DSSTEP_OverCount:
error = TRKTargetSingleStep(msg_count,
(msg_options == DSSTEP_OverCount));
break;
case DSSTEP_IntoRange:
case DSSTEP_OverRange:
error = TRKTargetStepOutOfRange(
msg_rangeStart, msg_rangeEnd,
(msg_options == DSSTEP_OverRange));
break;
}
return error;
}
}
DSError TRKDoStop(TRKBuffer* b)
{
DSReplyError replyError;
switch (TRKTargetStop()) {
case DS_NoError:
replyError = DSREPLY_NoError;
break;
case DS_InvalidProcessID:
replyError = DSREPLY_InvalidProcessID;
break;
case DS_InvalidThreadID:
replyError = DSREPLY_InvalidThreadID;
break;
case DS_OSError:
replyError = DSREPLY_OSError;
break;
default:
replyError = DSREPLY_Error;
break;
}
return TRKStandardACK(b, DSMSG_ReplyACK, replyError);
}

View file

@ -0,0 +1,7 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mutex_TRK.h"
DSError TRKInitializeMutex(void*) { return DS_NoError; }
DSError TRKAcquireMutex(void*) { return DS_NoError; }
DSError TRKReleaseMutex(void*) { return DS_NoError; }

View file

@ -0,0 +1,40 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/notify.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
DSError TRKDoNotifyStopped(MessageCommandID cmd)
{
DSError err;
int reqIdx;
int bufIdx;
TRKBuffer* msg;
err = TRKGetFreeBuffer(&bufIdx, &msg);
if (err == DS_NoError) {
if (msg->position >= 0x880) {
err = DS_MessageBufferOverflow;
} else {
msg->data[msg->position++] = cmd;
++msg->length;
err = 0;
}
if (err == DS_NoError) {
if (cmd == DSMSG_NotifyStopped) {
TRKTargetAddStopInfo(msg);
} else {
TRKTargetAddExceptionInfo(msg);
}
}
err = TRKRequestSend(msg, &reqIdx, 2, 3, 1);
if (err == DS_NoError) {
TRKReleaseBuffer(reqIdx);
}
TRKReleaseBuffer(bufIdx);
}
return err;
}

View file

@ -0,0 +1,72 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mutex_TRK.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/mem_TRK.h"
TRKEventQueue gTRKEventQueue;
DSError TRKInitializeEventQueue()
{
TRKInitializeMutex(&gTRKEventQueue);
TRKAcquireMutex(&gTRKEventQueue);
gTRKEventQueue.count = 0;
gTRKEventQueue.next = 0;
gTRKEventQueue.eventID = 0x100;
TRKReleaseMutex(&gTRKEventQueue);
return DS_NoError;
}
void TRKCopyEvent(TRKEvent* dstEvent, const TRKEvent* srcEvent)
{
TRK_memcpy(dstEvent, srcEvent, sizeof(TRKEvent));
}
BOOL TRKGetNextEvent(TRKEvent* event)
{
BOOL status = 0;
TRKAcquireMutex(&gTRKEventQueue);
if (0 < gTRKEventQueue.count) {
TRKCopyEvent(event, &gTRKEventQueue.events[gTRKEventQueue.next]);
gTRKEventQueue.count--;
gTRKEventQueue.next++;
if (gTRKEventQueue.next == 2)
gTRKEventQueue.next = 0;
status = 1;
}
TRKReleaseMutex(&gTRKEventQueue);
return status;
}
DSError TRKPostEvent(TRKEvent* event)
{
DSError ret = DS_NoError;
int nextEventID;
TRKAcquireMutex(&gTRKEventQueue);
if (gTRKEventQueue.count == 2) {
ret = DS_EventQueueFull;
} else {
nextEventID = (gTRKEventQueue.next + gTRKEventQueue.count) % 2;
TRKCopyEvent(&gTRKEventQueue.events[nextEventID], event);
gTRKEventQueue.events[nextEventID].eventID = gTRKEventQueue.eventID;
gTRKEventQueue.eventID++;
if (gTRKEventQueue.eventID < 0x100)
gTRKEventQueue.eventID = 0x100;
gTRKEventQueue.count++;
}
TRKReleaseMutex(&gTRKEventQueue);
return ret;
}
void TRKConstructEvent(TRKEvent* event, NubEventType eventType)
{
event->eventType = eventType;
event->eventID = 0;
event->msgBufID = -1;
}
void TRKDestructEvent(TRKEvent* event) { TRKReleaseBuffer(event->msgBufID); }

View file

@ -0,0 +1,80 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubinit.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/dispatch.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/usr_put.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
BOOL gTRKBigEndian;
BOOL TRKInitializeEndian(void);
DSError TRKInitializeNub(void)
{
DSError ret;
DSError uartErr;
ret = TRKInitializeEndian();
if (ret == DS_NoError)
usr_put_initialize();
if (ret == DS_NoError)
ret = TRKInitializeEventQueue();
if (ret == DS_NoError)
ret = TRKInitializeMessageBuffers();
if (ret == DS_NoError)
ret = TRKInitializeDispatcher();
if (ret == DS_NoError) {
uartErr = TRKInitializeIntDrivenUART(0x0000e100, 1, 0,
(volatile u8**)&gTRKInputPendingPtr);
TRKTargetSetInputPendingPtr(gTRKInputPendingPtr);
if (uartErr != DS_NoError) {
ret = uartErr;
}
}
if (ret == DS_NoError)
ret = TRKInitializeSerialHandler();
if (ret == DS_NoError)
ret = TRKInitializeTarget();
return ret;
}
DSError TRKTerminateNub(void)
{
TRKTerminateSerialHandler();
return DS_NoError;
}
void TRKNubWelcome(void)
{
TRK_board_display("MetroTRK for GAMECUBE v0.10");
return;
}
BOOL TRKInitializeEndian(void)
{
u8 bendian[4];
BOOL result = FALSE;
gTRKBigEndian = TRUE;
bendian[0] = 0x12;
bendian[1] = 0x34;
bendian[2] = 0x56;
bendian[3] = 0x78;
if (*(u32*)bendian == 0x12345678) {
gTRKBigEndian = TRUE;
} else if (*(u32*)bendian == 0x78563412) {
gTRKBigEndian = FALSE;
} else {
result = TRUE;
}
return result;
}

View file

@ -0,0 +1,82 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/nubevent.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
static TRKFramingState gTRKFramingState;
void* gTRKInputPendingPtr;
MessageBufferID TRKTestForPacket()
{
int bytes;
int batch;
int err;
TRKBuffer* b;
int id;
bytes = TRKPollUART();
if (bytes > 0) {
TRKGetFreeBuffer(&id, &b);
if (bytes > TRKMSGBUF_SIZE) {
for (; bytes > 0; bytes -= batch) {
batch = bytes > TRKMSGBUF_SIZE ? TRKMSGBUF_SIZE : bytes;
TRKReadUARTN(b->data, batch);
}
TRKStandardACK(b, 0xff, 6);
} else {
err = TRKReadUARTN(b->data, bytes);
if (err == 0) {
b->length = bytes;
return id;
}
}
}
if (id != -1) {
TRKReleaseBuffer(id);
}
return -1;
}
void TRKGetInput(void)
{
MessageBufferID id;
TRKBuffer* msgBuffer;
u8 command;
id = TRKTestForPacket();
if (id == -1)
return;
msgBuffer = TRKGetBuffer(id);
TRKSetBufferPosition(msgBuffer, 0);
TRKReadBuffer1_ui8(msgBuffer, &command);
if (command < DSMSG_ReplyACK) {
TRKProcessInput(id);
} else {
TRKReleaseBuffer(id);
}
}
void TRKProcessInput(int bufferIdx)
{
TRKEvent event;
TRKConstructEvent(&event, NUBEVENT_Request);
gTRKFramingState.msgBufID = -1;
event.msgBufID = bufferIdx;
TRKPostEvent(&event);
}
DSError TRKInitializeSerialHandler(void)
{
gTRKFramingState.msgBufID = -1;
gTRKFramingState.receiveState = DSRECV_Wait;
gTRKFramingState.isEscape = FALSE;
return DS_NoError;
}
DSError TRKTerminateSerialHandler(void) { return DS_NoError; }

View file

@ -0,0 +1,177 @@
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/support.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msgbuf.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msg.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/serpoll.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "stddef.h"
#include "string.h"
DSError TRKSuppAccessFile(u32 file_handle, u8* data, size_t* count,
DSIOResult* io_result, BOOL need_reply, BOOL read)
{
DSError error;
int replyBufferId;
TRKBuffer* replyBuffer;
int bufferId;
TRKBuffer* buffer;
u32 length;
u32 done;
u8 replyIOResult;
u16 replyLength;
BOOL exit;
if (data == NULL || *count == 0) {
return DS_ParameterError;
}
exit = FALSE;
*io_result = DS_IONoError;
done = 0;
error = DS_NoError;
while (!exit && done < *count && error == DS_NoError && *io_result == 0) {
if (*count - done > 0x800) {
length = 0x800;
} else {
length = *count - done;
}
error = TRKGetFreeBuffer(&bufferId, &buffer);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui8(buffer, read ? DSMSG_ReadFile
: DSMSG_WriteFile);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui32(buffer, file_handle);
if (error == DS_NoError)
error = TRKAppendBuffer1_ui16(buffer, length);
if (!read && error == DS_NoError)
error = TRKAppendBuffer_ui8(buffer, data + done, length);
if (error == DS_NoError) {
if (need_reply) {
replyLength = 0;
replyIOResult = 0;
error = TRKRequestSend(buffer, &replyBufferId, read ? 5 : 5, 3,
!(read && file_handle == 0));
if (error == DS_NoError) {
replyBuffer = (TRKBuffer*)TRKGetBuffer(replyBufferId);
TRKSetBufferPosition(replyBuffer, 2);
}
if (error == DS_NoError)
error = TRKReadBuffer1_ui8(replyBuffer, &replyIOResult);
if (error == DS_NoError)
error = TRKReadBuffer1_ui16(replyBuffer, &replyLength);
if (read && error == DS_NoError) {
if (replyBuffer->length != replyLength + 5) {
replyLength = replyBuffer->length - 5;
if (replyIOResult == 0)
replyIOResult = 1;
}
if (replyLength <= length)
error = TRKReadBuffer_ui8(replyBuffer, data + done,
replyLength);
}
if (replyLength != length) {
if ((!read || replyLength >= length) && replyIOResult == 0)
replyIOResult = 1;
length = replyLength;
exit = TRUE;
}
*io_result = (DSIOResult)replyIOResult;
TRKReleaseBuffer(replyBufferId);
} else {
error = TRKMessageSend((TRK_Msg*)buffer);
}
}
TRKReleaseBuffer(bufferId);
done += length;
}
*count = done;
return error;
}
DSError TRKRequestSend(TRKBuffer* msgBuf, int* bufferId, u32 p1, u32 p2, int p3)
{
int error = DS_NoError;
TRKBuffer* buffer;
u32 timer;
int tries;
u8 msg_command;
u8 msg_error;
BOOL badReply = TRUE;
*bufferId = -1;
for (tries = p2 + 1; tries != 0 && *bufferId == -1 && error == DS_NoError;
tries--) {
error = TRKMessageSend((TRK_Msg*)msgBuf);
if (error == DS_NoError) {
if (p3) {
timer = 0;
}
while (TRUE) {
do {
*bufferId = TRKTestForPacket();
if (*bufferId != -1)
break;
} while (!p3 || ++timer < 79999980);
if (*bufferId == -1)
break;
badReply = FALSE;
buffer = TRKGetBuffer(*bufferId);
TRKSetBufferPosition(buffer, 0);
if ((error = TRKReadBuffer1_ui8(buffer, &msg_command))
!= DS_NoError)
break;
if (msg_command >= DSMSG_ReplyACK)
break;
TRKProcessInput(*bufferId);
*bufferId = -1;
}
if (*bufferId != -1) {
if (buffer->length < p1) {
badReply = TRUE;
}
if (error == DS_NoError && !badReply) {
error = TRKReadBuffer1_ui8(buffer, &msg_error);
}
if (error == DS_NoError && !badReply) {
if (msg_command != DSMSG_ReplyACK
|| msg_error != DSREPLY_NoError) {
badReply = TRUE;
}
}
if (error != DS_NoError || badReply) {
TRKReleaseBuffer(*bufferId);
*bufferId = -1;
}
}
}
}
if (*bufferId == -1) {
error = DS_Error800;
}
return error;
}

View file

@ -0,0 +1,12 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/targcont.h"
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/dolphin_trk_glue.h"
#include "TRK_MINNOW_DOLPHIN/ppc/Generic/targimpl.h"
DSError TRKTargetContinue(void)
{
TRKTargetSetStopped(0);
UnreserveEXI2Port();
TRKSwapAndGo();
ReserveEXI2Port();
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#include "TRK_MINNOW_DOLPHIN/Os/dolphin/usr_put.h"
#include "TRK_MINNOW_DOLPHIN/MetroTRK/Portable/msghndlr.h"
#include "PowerPC_EABI_Support/MetroTRK/trk.h"
void usr_put_initialize(void) { }

View file

@ -6,15 +6,15 @@
#include <dolphin/gx/GXPriv.h>
static OSThread *__GXCurrentThread;
static struct __GXFifoObj* CPUFifo;
static struct __GXFifoObj* GPFifo;
static OSThread* __GXCurrentThread;
static GXBool CPGPLinked;
static BOOL GXOverflowSuspendInProgress;
static GXBreakPtCallback BreakPointCB;
static u32 __GXOverflowCount;
struct __GXFifoObj *CPUFifo;
struct __GXFifoObj *GPFifo;
void *__GXCurrentBP;
void* __GXCurrentBP;
static void __GXFifoReadEnable(void);
static void __GXFifoReadDisable(void);
@ -38,10 +38,10 @@ static void GXUnderflowHandler(s16 interrupt, OSContext *context)
{
ASSERTLINE(0x1A3, GXOverflowSuspendInProgress);
OSResumeThread(__GXCurrentThread);
GXOverflowSuspendInProgress = FALSE;
__GXWriteFifoIntReset(1U, 1U);
__GXWriteFifoIntEnable(1U, 0U);
OSResumeThread(__GXCurrentThread);
GXOverflowSuspendInProgress = FALSE;
__GXWriteFifoIntReset(1U, 1U);
__GXWriteFifoIntEnable(1U, 0U);
}
#define SOME_SET_REG_MACRO(reg, size, shift, val) \
@ -51,17 +51,17 @@ static void GXUnderflowHandler(s16 interrupt, OSContext *context)
static void GXBreakPointHandler(s16 interrupt, OSContext *context)
{
OSContext exceptionContext;
OSContext exceptionContext;
SOME_SET_REG_MACRO(gx->cpEnable, 1, 5, 0);
GX_SET_CP_REG(1, gx->cpEnable);
if (BreakPointCB != NULL) {
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
BreakPointCB();
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
gx->cpEnable = gx->cpEnable & 0xFFFFFFDF;
__cpReg[1] = gx->cpEnable;
if (BreakPointCB != NULL) {
OSClearContext(&exceptionContext);
OSSetCurrentContext(&exceptionContext);
BreakPointCB();
OSClearContext(&exceptionContext);
OSSetCurrentContext(context);
}
}
static void GXCPInterruptHandler(s16 interrupt, OSContext *context)

View file

@ -291,26 +291,25 @@ f32 GXGetYScaleFactor(u16 efbHeight, u16 xfbHeight)
u32 GXSetDispCopyYScale(f32 vscale)
{
u8 enable;
u32 iScale;
u32 ht;
u32 reg;
u32 scale;
GXBool check;
u32 height;
u32 reg;
CHECK_GXBEGIN(0x615, "GXSetDispCopyYScale");
scale = (u32)(256.0f / vscale) & 0x1FF;
check = (scale != 0x100);
ASSERTMSGLINE(0x617, vscale >= 1.0f, "GXSetDispCopyYScale: Vertical scale must be >= 1.0");
reg = 0;
SET_REG_FIELD(0, reg, 9, 0, scale);
SET_REG_FIELD(0, reg, 8, 24, 0x4E);
GX_WRITE_RAS_REG(reg);
gx->bpSentNot = GX_FALSE;
iScale = (u32)(256.0f / vscale) & 0x1FF;
enable = (iScale != 256);
SET_REG_FIELD(0, gx->cpDisp, 1, 10, check);
reg = 0;
SET_REG_FIELD(0x61E, reg, 9, 0, iScale);
SET_REG_FIELD(0x61E, reg, 8, 24, 0x4E);
GX_WRITE_RAS_REG(reg);
gx->bpSentNot = 0;
SET_REG_FIELD(0x623, gx->cpDisp, 1, 10, enable);
ht = GET_REG_FIELD(gx->cpDispSize, 10, 10) + 1;
return __GXGetNumXfbLines(ht, iScale);
height = (gx->cpDispSize >> 10 & 0x3FF) + 1;
return __GXGetNumXfbLines(height, scale);
}
void GXSetCopyClear(GXColor clear_clr, u32 clear_z)

View file

@ -65,150 +65,134 @@ static GXTlutRegion *__GXDefaultTlutRegionCallback(u32 idx)
GXFifoObj FifoObj;
GXFifoObj *GXInit(void *base, u32 size)
GXFifoObj* GXInit(void* base, u32 size)
{
u32 i;
u32 reg;
u32 freqBase;
u32 i;
u32 reg;
u32 freqBase;
char stack_padding[8];
// OSRegisterVersion(__GXVersion);
gx->inDispList = FALSE;
gx->dlSaveContext = TRUE;
gx->inDispList = FALSE;
gx->dlSaveContext = TRUE;
// gx->abtWaitPECopy = 1;
#if DEBUG
__GXinBegin = FALSE;
#endif
gx->tcsManEnab = FALSE;
gx->tevTcEnab = FALSE;
GXSetMisc(GX_MT_XF_FLUSH, 0);
gx->tcsManEnab = FALSE;
gx->tevTcEnab = 0;
GXSetMisc(GX_MT_XF_FLUSH, 0);
__piReg = OSPhysicalToUncached(0xC003000);
__cpReg = OSPhysicalToUncached(0xC000000);
__peReg = OSPhysicalToUncached(0xC001000);
__memReg = OSPhysicalToUncached(0xC004000);
__GXFifoInit();
GXInitFifoBase(&FifoObj, base, size);
GXSetCPUFifo(&FifoObj);
GXSetGPFifo(&FifoObj);
__GXPEInit();
EnableWriteGatherPipe();
__piReg = OSPhysicalToUncached(0xC003000);
__cpReg = OSPhysicalToUncached(0xC000000);
__peReg = OSPhysicalToUncached(0xC001000);
__memReg = OSPhysicalToUncached(0xC004000);
// __GXFifoInit();
// GXInitFifoBase(&FifoObj, base, size);
// GXSetCPUFifo(&FifoObj);
// GXSetGPFifo(&FifoObj);
gx->genMode = 0;
SET_REG_FIELD(0, gx->genMode, 8, 24, 0);
gx->bpMask = 255;
SET_REG_FIELD(0, gx->bpMask, 8, 24, 0x0F);
gx->lpSize = 0;
SET_REG_FIELD(0, gx->lpSize, 8, 24, 0x22);
for (i = 0; i < 16; ++i) {
gx->tevc[i] = 0;
gx->teva[i] = 0;
gx->tref[i / 2] = 0;
gx->texmapId[i] = GX_TEXMAP_NULL;
SET_REG_FIELD(0x2F2, gx->tevc[i], 8, 24, 0xC0 + i * 2);
SET_REG_FIELD(0x2F3, gx->teva[i], 8, 24, 0xC1 + i * 2);
SET_REG_FIELD(0x2F5, gx->tevKsel[i / 2], 8, 24, 0xF6 + i / 2);
SET_REG_FIELD(0x2F7, gx->tref[i / 2], 8, 24, 0x28 + i / 2);
}
gx->iref = 0;
SET_REG_FIELD(0, gx->iref, 8, 24, 0x27);
for (i = 0; i < 8; ++i) {
gx->suTs0[i] = 0;
gx->suTs1[i] = 0;
SET_REG_FIELD(0x300, gx->suTs0[i], 8, 24, 0x30 + i * 2);
SET_REG_FIELD(0x301, gx->suTs1[i], 8, 24, 0x31 + i * 2);
}
SET_REG_FIELD(0, gx->suScis0, 8, 24, 0x20);
SET_REG_FIELD(0, gx->suScis1, 8, 24, 0x21);
SET_REG_FIELD(0, gx->cmode0, 8, 24, 0x41);
SET_REG_FIELD(0, gx->cmode1, 8, 24, 0x42);
SET_REG_FIELD(0, gx->zmode, 8, 24, 0x40);
SET_REG_FIELD(0, gx->peCtrl, 8, 24, 0x43);
SET_REG_FIELD(0, gx->cpTex, 2, 7, 0);
gx->dirtyState = 0;
gx->dirtyVAT = FALSE;
// if (!resetFuncRegistered) {
// OSRegisterResetFunction(&GXResetFuncInfo);
// resetFuncRegistered = 1;
// }
freqBase = __OSBusClock / 500;
__GXFlushTextureState();
reg = (freqBase >> 11) | 0x400 | 0x69000000;
GX_WRITE_RAS_REG(reg);
// __GXPEInit();
// EnableWriteGatherPipe();
__GXFlushTextureState();
reg = (freqBase / 0x1080) | 0x200 | 0x46000000;
GX_WRITE_RAS_REG(reg);
gx->genMode = 0;
SET_REG_FIELD(0, gx->genMode, 8, 24, 0);
gx->bpMask = 255;
SET_REG_FIELD(0, gx->bpMask, 8, 24, 0x0F);
gx->lpSize = 0;
SET_REG_FIELD(0, gx->lpSize, 8, 24, 0x22);
for (i = 0; i < 16; ++i) {
gx->tevc[i] = 0;
gx->teva[i] = 0;
gx->tref[i / 2] = 0;
gx->texmapId[i] = GX_TEXMAP_NULL;
SET_REG_FIELD(0x46A, gx->tevc[i], 8, 24, 0xC0 + i * 2);
SET_REG_FIELD(0x46B, gx->teva[i], 8, 24, 0xC1 + i * 2);
SET_REG_FIELD(0x46D, gx->tevKsel[i / 2], 8, 24, 0xF6 + i / 2);
SET_REG_FIELD(0x46F, gx->tref[i / 2], 8, 24, 0x28 + i / 2);
}
gx->iref = 0;
SET_REG_FIELD(0, gx->iref, 8, 24, 0x27);
for (i = 0; i < 8; ++i) {
gx->suTs0[i] = 0;
gx->suTs1[i] = 0;
SET_REG_FIELD(0x478, gx->suTs0[i], 8, 24, 0x30 + i * 2);
SET_REG_FIELD(0x479, gx->suTs1[i], 8, 24, 0x31 + i * 2);
}
SET_REG_FIELD(0, gx->suScis0, 8, 24, 0x20);
SET_REG_FIELD(0, gx->suScis1, 8, 24, 0x21);
SET_REG_FIELD(0, gx->cmode0, 8, 24, 0x41);
SET_REG_FIELD(0, gx->cmode1, 8, 24, 0x42);
SET_REG_FIELD(0, gx->zmode, 8, 24, 0x40);
SET_REG_FIELD(0, gx->peCtrl, 8, 24, 0x43);
SET_REG_FIELD(0, gx->cpTex, 2, 7, 0);
for (i = GX_VTXFMT0; i < GX_MAX_VTXFMT; i++) {
SET_REG_FIELD(0, gx->vatA[i], 1, 30, 1);
SET_REG_FIELD(0, gx->vatB[i], 1, 31, 1);
do {
s32 regAddr;
GX_WRITE_U8(GX_LOAD_CP_REG);
GX_WRITE_U8(i | 0x80);
GX_WRITE_U32(gx->vatB[i]);
regAddr = i - 12;
} while (0);
}
{
u32 reg1 = 0;
u32 reg2 = 0;
SET_REG_FIELD(0, reg1, 1, 0, 1);
SET_REG_FIELD(0, reg1, 1, 1, 1);
SET_REG_FIELD(0, reg1, 1, 2, 1);
SET_REG_FIELD(0, reg1, 1, 3, 1);
SET_REG_FIELD(0, reg1, 1, 4, 1);
SET_REG_FIELD(0, reg1, 1, 5, 1);
GX_WRITE_XF_REG(0, reg1);
SET_REG_FIELD(0, reg2, 1, 0, 1);
GX_WRITE_XF_REG(0x12, reg2);
}
{
u32 reg = 0;
SET_REG_FIELD(0, reg, 1, 0, 1);
SET_REG_FIELD(0, reg, 1, 1, 1);
SET_REG_FIELD(0, reg, 1, 2, 1);
SET_REG_FIELD(0, reg, 1, 3, 1);
SET_REG_FIELD(0, reg, 8, 24, 0x58);
GX_WRITE_RAS_REG(reg);
}
for (i = 0; i < 8; i++)
GXInitTexCacheRegion(&gx->TexRegions[i], 0, i * 0x8000, 0,
0x80000 + i * 0x8000, 0);
for (i = 0; i < 4; i++)
GXInitTexCacheRegion(&gx->TexRegionsCI[i], 0, (i * 2 + 8) * 0x8000, 0,
(i * 2 + 9) * 0x8000, 0);
for (i = 0; i < 16; i++)
GXInitTlutRegion(&gx->TlutRegions[i], 0xC0000 + i * 0x2000, 16);
for (i = 0; i < 4; i++)
GXInitTlutRegion(&gx->TlutRegions[i + 16], 0xE0000 + i * 0x8000, 64);
__cpReg[3] = 0;
// gx->zScale = 1.6777216E7f;
// gx->zOffset = 0.0f;
gx->dirtyState = 0;
gx->dirtyVAT = FALSE;
#if DEBUG
__gxVerif->verifyLevel = GX_WARN_NONE;
GXSetVerifyCallback((GXVerifyCallback)__GXDefaultVerifyCallback);
for (i = 0; i < 256; i++) {
SET_REG_FIELD(0, __gxVerif->rasRegs[i], 8, 24, 0xFF);
}
memset(__gxVerif->xfRegsDirty, 0, 0x50);
memset(__gxVerif->xfMtxDirty, 0, 0x100);
memset(__gxVerif->xfNrmDirty, 0, 0x60);
memset(__gxVerif->xfLightDirty, 0, 0x80);
#endif
freqBase = __OSBusClock / 500;
// __GXFlushTextureState();
reg = (freqBase >> 11) | 0x400 | 0x69000000;
GX_WRITE_RAS_REG(reg);
{
SET_REG_FIELD(0, gx->perfSel, 4, 4, 0);
GX_WRITE_U8(GX_LOAD_CP_REG);
GX_WRITE_U8(0x20);
GX_WRITE_U32(gx->perfSel);
GX_WRITE_U8(GX_LOAD_XF_REG);
GX_WRITE_U32(0x1006);
GX_WRITE_U32(0);
GX_WRITE_RAS_REG(0x23000000);
GX_WRITE_RAS_REG(0x24000000);
GX_WRITE_RAS_REG(0x67000000);
}
// __GXFlushTextureState();
reg = (freqBase / 0x1080) | 0x200 | 0x46000000;
GX_WRITE_RAS_REG(reg);
// __GXInitRevisionBits();
// for (i = 0; i < 8; i++) {
// GXInitTexCacheRegion(&gx->TexRegions0[i], GX_FALSE, GXTexRegionAddrTable[i],
// GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 8], GX_TEXCACHE_32K);
// GXInitTexCacheRegion(&gx->TexRegions1[i], GX_FALSE, GXTexRegionAddrTable[i + 16],
// GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 24], GX_TEXCACHE_32K);
// GXInitTexCacheRegion(&gx->TexRegions2[i], GX_TRUE, GXTexRegionAddrTable[i + 32],
// GX_TEXCACHE_32K, GXTexRegionAddrTable[i + 40], GX_TEXCACHE_32K);
// }
// for (i = 0; i < 16; i++) {
// GXInitTlutRegion(&gx->TlutRegions[i], 0xC0000 + 0x2000 * i, GX_TLUT_256);
// }
// for (i = 0; i < 4; i++) {
// GXInitTlutRegion(&gx->TlutRegions[i + 16], 0xE0000 + 0x8000 * i, GX_TLUT_1K);
// }
{
u32 reg = 0;
#if DEBUG
s32 regAddr;
#endif
GX_SET_CP_REG(3, reg);
SET_REG_FIELD(0, gx->perfSel, 4, 4, 0);
GX_WRITE_U8(0x8);
GX_WRITE_U8(0x20);
GX_WRITE_U32(gx->perfSel);
#if DEBUG
regAddr = -12;
#endif
reg = 0;
GX_WRITE_XF_REG(6, reg);
reg = 0x23000000;
GX_WRITE_RAS_REG(reg);
reg = 0x24000000;
GX_WRITE_RAS_REG(reg);
reg = 0x67000000;
GX_WRITE_RAS_REG(reg);
}
__GXSetIndirectMask(0);
__GXSetTmemConfig(2);
__GXInitGX();
return &FifoObj;
__GXSetTmemConfig(0);
__GXInitGX();
return &FifoObj;
}
void __GXInitGX()

View file

@ -3,6 +3,8 @@
static f32 Unit01[] = { 0.0f, 1.0f };
extern f32 sinf(f32);
extern f32 cosf(f32);
extern f32 tanf(f32);
void C_MTXIdentity(Mtx mtx)
{
@ -648,12 +650,12 @@ void C_MTXRotRad(Mtx m, char axis, f32 rad)
#ifdef GEKKO
void PSMTXRotRad(Mtx m, char axis, f32 rad)
{
// f32 sinA, cosA;
f32 sinA, cosA;
// sinA = sinf(rad);
// cosA = cosf(rad);
sinA = sinf(rad);
cosA = cosf(rad);
// PSMTXRotTrig(m, axis, sinA, cosA);
PSMTXRotTrig(m, axis, sinA, cosA);
}
#endif
@ -717,68 +719,63 @@ void C_MTXRotTrig(Mtx m, char axis, f32 sinA, f32 cosA)
#ifdef GEKKO
void PSMTXRotTrig(register Mtx m, register char axis, register f32 sinA, register f32 cosA)
{
// register f32 fc0, fc1, nsinA;
// register f32 fw0, fw1, fw2, fw3;
// // clang-format off
// asm
// {
// frsp sinA, sinA
// frsp cosA, cosA
// }
register f32 fc0, fc1, nsinA;
register f32 fw0, fw1, fw2, fw3;
// clang-format off
// fc0 = 0.0F;
// fc1 = 1.0F;
// asm
// {
// ori axis, axis, 0x20
// ps_neg nsinA, sinA
// cmplwi axis, 'x'
// beq _case_x
// cmplwi axis, 'y'
// beq _case_y
// cmplwi axis, 'z'
// beq _case_z
// b _end
fc0 = 0.0F;
fc1 = 1.0F;
asm
{
ori axis, axis, 0x20
ps_neg nsinA, sinA
cmplwi axis, 'x'
beq _case_x
cmplwi axis, 'y'
beq _case_y
cmplwi axis, 'z'
beq _case_z
b _end
// _case_x:
// psq_st fc1, 0(m), 1, 0
// psq_st fc0, 4(m), 0, 0
// ps_merge00 fw0, sinA, cosA
// psq_st fc0, 12(m), 0, 0
// ps_merge00 fw1, cosA, nsinA
// psq_st fc0, 28(m), 0, 0
// psq_st fc0, 44(m), 1, 0
// psq_st fw0, 36(m), 0, 0
// psq_st fw1, 20(m), 0, 0
// b _end;
_case_x:
psq_st fc1, 0(m), 1, 0
psq_st fc0, 4(m), 0, 0
ps_merge00 fw0, sinA, cosA
psq_st fc0, 12(m), 0, 0
ps_merge00 fw1, cosA, nsinA
psq_st fc0, 28(m), 0, 0
psq_st fc0, 44(m), 1, 0
psq_st fw0, 36(m), 0, 0
psq_st fw1, 20(m), 0, 0
b _end;
// _case_y:
// ps_merge00 fw0, cosA, fc0
// ps_merge00 fw1, fc0, fc1
// psq_st fc0, 24(m), 0, 0
// psq_st fw0, 0(m), 0, 0
// ps_merge00 fw2, nsinA, fc0
// ps_merge00 fw3, sinA, fc0
// psq_st fw0, 40(m), 0, 0;
// psq_st fw1, 16(m), 0, 0;
// psq_st fw3, 8(m), 0, 0;
// psq_st fw2, 32(m), 0, 0;
// b _end;
_case_y:
ps_merge00 fw0, cosA, fc0
ps_merge00 fw1, fc0, fc1
psq_st fc0, 24(m), 0, 0
psq_st fw0, 0(m), 0, 0
ps_merge00 fw2, nsinA, fc0
ps_merge00 fw3, sinA, fc0
psq_st fw0, 40(m), 0, 0;
psq_st fw1, 16(m), 0, 0;
psq_st fw3, 8(m), 0, 0;
psq_st fw2, 32(m), 0, 0;
b _end;
// _case_z:
// psq_st fc0, 8(m), 0, 0
// ps_merge00 fw0, sinA, cosA
// ps_merge00 fw2, cosA, nsinA
// psq_st fc0, 24(m), 0, 0
// psq_st fc0, 32(m), 0, 0
// ps_merge00 fw1, fc1, fc0
// psq_st fw0, 16(m), 0, 0
// psq_st fw2, 0(m), 0, 0
// psq_st fw1, 40(m), 0, 0
_case_z:
psq_st fc0, 8(m), 0, 0
ps_merge00 fw0, sinA, cosA
ps_merge00 fw2, cosA, nsinA
psq_st fc0, 24(m), 0, 0
psq_st fc0, 32(m), 0, 0
ps_merge00 fw1, fc1, fc0
psq_st fw0, 16(m), 0, 0
psq_st fw2, 0(m), 0, 0
psq_st fw1, 40(m), 0, 0
// _end:
// }
// // clang-format on
_end:
}
// clang-format on
}
#endif
@ -822,70 +819,58 @@ void C_MTXRotAxisRad(Mtx m, const Vec *axis, f32 rad)
}
#ifdef GEKKO
static void __PSMTXRotAxisRadInternal(register Mtx m, const register Vec *axis, register f32 sT, register f32 cT)
#define qr0 0
void PSMTXRotAxisRad(register Mtx m, const Vec *axis, register f32 rad)
{
register f32 tT, fc0;
register f32 tmp0, tmp1, tmp2, tmp3, tmp4;
register f32 tmp5, tmp6, tmp7, tmp8, tmp9;
tmp9 = 0.5F;
tmp8 = 3.0F;
// clang-format off
asm
{
frsp cT, cT
psq_l tmp0, 0(axis), 0, 0
frsp sT, sT
lfs tmp1, 8(axis)
ps_mul tmp2, tmp0, tmp0
fadds tmp7, tmp9, tmp9
ps_madd tmp3, tmp1, tmp1, tmp2
fsubs fc0, tmp9, tmp9
ps_sum0 tmp4, tmp3, tmp1, tmp2
fsubs tT, tmp7, cT
frsqrte tmp5, tmp4
fmuls tmp2, tmp5, tmp5
fmuls tmp3, tmp5, tmp9
fnmsubs tmp2, tmp2, tmp4, tmp8
fmuls tmp5, tmp2, tmp3
ps_merge00 cT, cT, cT
ps_muls0 tmp0, tmp0, tmp5
ps_muls0 tmp1, tmp1, tmp5
ps_muls0 tmp4, tmp0, tT
ps_muls0 tmp9, tmp0, sT
ps_muls0 tmp5, tmp1, tT
ps_muls1 tmp3, tmp4, tmp0
ps_muls0 tmp2, tmp4, tmp0
ps_muls0 tmp4, tmp4, tmp1
fnmsubs tmp6, tmp1, sT, tmp3
fmadds tmp7, tmp1, sT, tmp3
ps_neg tmp0, tmp9
ps_sum0 tmp8, tmp4, fc0, tmp9
ps_sum0 tmp2, tmp2, tmp6, cT
ps_sum1 tmp3, cT, tmp7, tmp3
ps_sum0 tmp6, tmp0, fc0 ,tmp4
psq_st tmp8, 8(m), 0, 0
ps_sum0 tmp0, tmp4, tmp4, tmp0
psq_st tmp2, 0(m), 0, 0
ps_muls0 tmp5, tmp5, tmp1
psq_st tmp3, 16(m), 0, 0
ps_sum1 tmp4, tmp9, tmp0, tmp4
psq_st tmp6, 24(m), 0, 0
ps_sum0 tmp5, tmp5, fc0, cT
psq_st tmp4, 32(m), 0, 0
psq_st tmp5, 40(m), 0, 0
register f32 sT;
register f32 cT;
register f32 oneMinusCosT;
register f32 zero;
Vec axisNormalized;
register Vec *axisNormalizedPtr;
zero = 0.0f;
axisNormalizedPtr = &axisNormalized;
sT = sinf(rad);
cT = cosf(rad);
oneMinusCosT = 1.0f - cT;
PSVECNormalize(axis, axisNormalizedPtr);
#ifdef __MWERKS__ // clang-format off
asm {
psq_l rad, 0x0(axisNormalizedPtr), 0, qr0
lfs tmp1, 0x8(axisNormalizedPtr)
ps_merge00 tmp0, cT, cT
ps_muls0 tmp4, rad, oneMinusCosT
ps_muls0 tmp5, tmp1, oneMinusCosT
ps_muls1 tmp3, tmp4, rad
ps_muls0 tmp2, tmp4, rad
ps_muls0 rad, rad, sT
ps_muls0 tmp4, tmp4, tmp1
fnmsubs tmp6, tmp1, sT, tmp3
fmadds tmp7, tmp1, sT, tmp3
ps_neg tmp9, rad
ps_sum0 tmp8, tmp4, zero, rad
ps_sum0 tmp2, tmp2, tmp6, tmp0
ps_sum1 tmp3, tmp0, tmp7, tmp3
ps_sum0 tmp6, tmp9, zero, tmp4
ps_sum0 tmp9, tmp4, tmp4, tmp9
psq_st tmp8, 0x8(m), 0, qr0
ps_muls0 tmp5, tmp5, tmp1
psq_st tmp2, 0x0(m), 0, qr0
ps_sum1 tmp4, rad, tmp9, tmp4
psq_st tmp3, 0x10(m), 0, qr0
ps_sum0 tmp5, tmp5, zero, tmp0
psq_st tmp6, 0x18(m), 0, qr0
psq_st tmp4, 0x20(m), 0, qr0
psq_st tmp5, 0x28(m), 0, qr0
}
// clang-format on
}
void PSMTXRotAxisRad(Mtx m, const Vec *axis, f32 rad)
{
// f32 sinT, cosT;
// sinT = sinf(rad);
// cosT = cosf(rad);
// __PSMTXRotAxisRadInternal(m, axis, sinT, cosT);
#endif // clang-format on
}
#endif
@ -1219,30 +1204,30 @@ void PSMTXReflect(register Mtx m, const register Vec *p, const register Vec *n)
void C_MTXLookAt(Mtx m, const Point3d *camPos, const Vec *camUp, const Point3d *target)
{
// Vec vLook, vRight, vUp;
Vec vLook, vRight, vUp;
// vLook.x = camPos->x - target->x;
// vLook.y = camPos->y - target->y;
// vLook.z = camPos->z - target->z;
// VECNormalize(&vLook, &vLook);
// VECCrossProduct(camUp, &vLook, &vRight);
// VECNormalize(&vRight, &vRight);
// VECCrossProduct(&vLook, &vRight, &vUp);
vLook.x = camPos->x - target->x;
vLook.y = camPos->y - target->y;
vLook.z = camPos->z - target->z;
VECNormalize(&vLook, &vLook);
VECCrossProduct(camUp, &vLook, &vRight);
VECNormalize(&vRight, &vRight);
VECCrossProduct(&vLook, &vRight, &vUp);
// m[0][0] = vRight.x;
// m[0][1] = vRight.y;
// m[0][2] = vRight.z;
// m[0][3] = -(camPos->x * vRight.x + camPos->y * vRight.y + camPos->z * vRight.z);
m[0][0] = vRight.x;
m[0][1] = vRight.y;
m[0][2] = vRight.z;
m[0][3] = -(camPos->x * vRight.x + camPos->y * vRight.y + camPos->z * vRight.z);
// m[1][0] = vUp.x;
// m[1][1] = vUp.y;
// m[1][2] = vUp.z;
// m[1][3] = -(camPos->x * vUp.x + camPos->y * vUp.y + camPos->z * vUp.z);
m[1][0] = vUp.x;
m[1][1] = vUp.y;
m[1][2] = vUp.z;
m[1][3] = -(camPos->x * vUp.x + camPos->y * vUp.y + camPos->z * vUp.z);
// m[2][0] = vLook.x;
// m[2][1] = vLook.y;
// m[2][2] = vLook.z;
// m[2][3] = -(camPos->x * vLook.x + camPos->y * vLook.y + camPos->z * vLook.z);
m[2][0] = vLook.x;
m[2][1] = vLook.y;
m[2][2] = vLook.z;
m[2][3] = -(camPos->x * vLook.x + camPos->y * vLook.y + camPos->z * vLook.z);
}
void C_MTXLightFrustum(Mtx m, float t, float b, float l, float r, float n, float scaleS, float scaleT, float transS, float transT)
@ -1269,28 +1254,28 @@ void C_MTXLightFrustum(Mtx m, float t, float b, float l, float r, float n, float
void C_MTXLightPerspective(Mtx m, f32 fovY, f32 aspect, float scaleS, float scaleT, float transS, float transT)
{
// f32 angle;
// f32 cot;
f32 angle;
f32 cot;
// angle = fovY * 0.5f;
// angle = MTXDegToRad(angle);
angle = fovY * 0.5f;
angle = MTXDegToRad(angle);
// cot = 1.0f / tanf(angle);
cot = 1.0f / tanf(angle);
// m[0][0] = (cot / aspect) * scaleS;
// m[0][1] = 0.0f;
// m[0][2] = -transS;
// m[0][3] = 0.0f;
m[0][0] = (cot / aspect) * scaleS;
m[0][1] = 0.0f;
m[0][2] = -transS;
m[0][3] = 0.0f;
// m[1][0] = 0.0f;
// m[1][1] = cot * scaleT;
// m[1][2] = -transT;
// m[1][3] = 0.0f;
m[1][0] = 0.0f;
m[1][1] = cot * scaleT;
m[1][2] = -transT;
m[1][3] = 0.0f;
// m[2][0] = 0.0f;
// m[2][1] = 0.0f;
// m[2][2] = -1.0f;
// m[2][3] = 0.0f;
m[2][0] = 0.0f;
m[2][1] = 0.0f;
m[2][2] = -1.0f;
m[2][3] = 0.0f;
}
void C_MTXLightOrtho(Mtx m, f32 t, f32 b, f32 l, f32 r, float scaleS, float scaleT, float transS, float transT)

View file

@ -1,3 +1,4 @@
#include "dolphin/math.h"
#include "dolphin/mtx.h"
float acosf(float x);
@ -5,6 +6,28 @@ float acosf(float x);
float sinf(float x);
float cosf(float x);
void C_QUATAdd(const Quaternion *p, const Quaternion *q, Qtrn *r)
{
r->x = p->x + q->x;
r->y = p->y + q->y;
r->z = p->z + q->z;
r->w = p->w + q->w;
}
void PSQUATAdd(register const Quaternion *p, register const Quaternion *q, register Quaternion *r)
{
asm {
psq_l f0, 0x0(r3), 0, 0
psq_l f1, 0x0(r4), 0, 0
ps_add f0, f0, f1
psq_st f0, 0x0(r5), 0, 0
psq_l f0, 0x8(r3), 0, 0
psq_l f1, 0x8(r4), 0, 0
ps_add f0, f0, f1
psq_st f0, 0x8(r5), 0, 0
}
}
void PSQUATMultiply(register const Quaternion *a, register const Quaternion *b, register Quaternion *ab)
{
asm {
@ -33,6 +56,77 @@ void PSQUATMultiply(register const Quaternion *a, register const Quaternion *b,
}
}
void PSQUATNormalize(const register Quaternion *src, register Quaternion *unit)
{
// sdata2
(void)0.00001f;
(void)0.0f;
(void)0.5;
(void)3.0;
(void)1.0f;
(void)0.5f;
(void)3.0f;
{
register f32 vv1, vv2, vv3;
register f32 vv4, vv5, vv6;
register f32 vv7, vv8;
register f32 vv9 = 0.00001f;
register f32 vvA = 0.5F;
register f32 vvB = 3.0F;
asm
{
psq_l vv1, 0(src), 0, 0;
ps_mul vv3, vv1, vv1;
psq_l vv2, 8(src), 0, 0;
ps_sub vv6, vv9, vv9;
ps_madd vv3, vv2, vv2, vv3;
ps_sum0 vv3, vv3, vv3, vv3;
frsqrte vv4, vv3;
ps_sub vv5, vv3, vv9;
fmul vv7, vv4, vv4;
fmul vv8, vv4, vvA;
fnmsub vv7, vv7, vv3, vvB;
fmul vv4, vv7, vv8;
ps_sel vv4, vv5, vv4, vv6;
ps_muls0 vv1, vv1, vv4;
ps_muls0 vv2, vv2, vv4;
psq_st vv1, 0(unit), 0, 0;
psq_st vv2, 8(unit), 0, 0;
}
}
}
void PSQUATInverse(const register Quaternion *src, register Quaternion *inv)
{
register f32 vv1, vv2, vv3, vv4;
register f32 vv5, vv6, vv7, vv8, vv9, vvA, vvB;
register f32 vvC = 1.0F;
asm {
psq_l vv1, 0(src), 0, 0;
ps_mul vv5, vv1, vv1;
psq_l vv2, 8(src), 0, 0;
ps_madd vv5, vv2, vv2, vv5;
ps_add vvA, vvC, vvC;
ps_sum0 vv5, vv5, vv5, vv5;
fres vv7, vv5;
ps_neg vv6, vv5;
ps_nmsub vv9, vv5, vv7, vvA;
ps_mul vv7, vv7, vv9;
ps_sel vv7, vv6, vvC, vv7
b loc1;
loc0:
fmr vv7, vvC;
loc1:
ps_neg vv8, vv7;
ps_muls1 vv4, vv7, vv2;
ps_muls0 vv1, vv1, vv8;
psq_st vv4, 12(inv), 1, 0;
ps_muls0 vv3, vv2, vv8;
psq_st vv1, 0(inv), 0, 0;
psq_st vv3, 8(inv), 1, 0;
}
}
void C_QUATRotAxisRad(Quaternion *q, const Vec *axis, f32 rad)
{
f32 tmp, tmp2, tmp3;
@ -52,6 +146,42 @@ void C_QUATRotAxisRad(Quaternion *q, const Vec *axis, f32 rad)
q->w = tmp3;
}
void C_QUATMtx(Quaternion *r, const Mtx m)
{
f32 vv0, vv1;
s32 i, j, k;
s32 idx[3] = { 1, 2, 0 };
f32 vec[3];
vv0 = m[0][0] + m[1][1] + m[2][2];
if (vv0 > 0.0f) {
vv1 = (f32)sqrtf(vv0 + 1.0f);
r->w = vv1 * 0.5f;
vv1 = 0.5f / vv1;
r->x = (m[2][1] - m[1][2]) * vv1;
r->y = (m[0][2] - m[2][0]) * vv1;
r->z = (m[1][0] - m[0][1]) * vv1;
}
else {
i = 0;
if (m[1][1] > m[0][0])
i = 1;
if (m[2][2] > m[i][i])
i = 2;
j = idx[i];
k = idx[j];
vv1 = (f32)sqrtf((m[i][i] - (m[j][j] + m[k][k])) + 1.0f);
vec[i] = vv1 * 0.5f;
if (vv1 != 0.0f)
vv1 = 0.5f / vv1;
r->w = (m[k][j] - m[j][k]) * vv1;
vec[j] = (m[i][j] + m[j][i]) * vv1;
vec[k] = (m[i][k] + m[k][i]) * vv1;
r->x = vec[0];
r->y = vec[1];
r->z = vec[2];
}
}
void C_QUATSlerp(const Quaternion *p, const Quaternion *q, Quaternion *r, f32 t)
{
f32 ratioA, ratioB;

View file

@ -210,23 +210,23 @@ void C_VECHalfAngle(const Vec *a, const Vec *b, Vec *half)
void C_VECReflect(const Vec *src, const Vec *normal, Vec *dst)
{
// Vec a0;
// Vec b0;
// f32 dot;
Vec a0;
Vec b0;
f32 dot;
// a0.x = -src->x;
// a0.y = -src->y;
// a0.z = -src->z;
a0.x = -src->x;
a0.y = -src->y;
a0.z = -src->z;
// VECNormalize(&a0, &a0);
// VECNormalize(normal, &b0);
VECNormalize(&a0, &a0);
VECNormalize(normal, &b0);
// dot = VECDotProduct(&a0, &b0);
// dst->x = b0.x * 2.0f * dot - a0.x;
// dst->y = b0.y * 2.0f * dot - a0.y;
// dst->z = b0.z * 2.0f * dot - a0.z;
dot = VECDotProduct(&a0, &b0);
dst->x = b0.x * 2.0f * dot - a0.x;
dst->y = b0.y * 2.0f * dot - a0.y;
dst->z = b0.z * 2.0f * dot - a0.z;
// VECNormalize(dst, dst);
VECNormalize(dst, dst);
}
asm f32 PSVECSquareDistance(register const Vec *a, register const Vec *b) {

View file

@ -103,17 +103,34 @@ static void ClampTrigger(u8 *trigger, u8 min, u8 max)
}
}
void PADClamp(PADStatus *status)
void PADClamp(PADStatus* status)
{
// int i;
// for (i = 0; i < PAD_CHANMAX; i++, status++) {
// if (status->err != PAD_ERR_NONE) {
// continue;
// }
int i;
for (i = 0; i < PAD_CHANMAX; i++, status++) {
if (status->err != PAD_ERR_NONE) {
continue;
}
// ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick, ClampRegion.xyStick, ClampRegion.minStick);
// ClampStick(&status->substickX, &status->substickY, ClampRegion.maxSubstick, ClampRegion.xySubstick, ClampRegion.minSubstick);
// ClampTrigger(&status->triggerL, ClampRegion.minTrigger, ClampRegion.maxTrigger);
// ClampTrigger(&status->triggerR, ClampRegion.minTrigger, ClampRegion.maxTrigger);
// }
ClampStick(&status->stickX, &status->stickY, ClampRegion.maxStick,
ClampRegion.xyStick, ClampRegion.minStick);
ClampStick(&status->substickX, &status->substickY,
ClampRegion.maxSubstick, ClampRegion.xySubstick,
ClampRegion.minSubstick);
if (status->triggerL <= ClampRegion.minTrigger) {
status->triggerL = 0;
} else {
if (ClampRegion.maxTrigger < status->triggerL) {
status->triggerL = ClampRegion.maxTrigger;
}
status->triggerL -= ClampRegion.minTrigger;
}
if (status->triggerR <= ClampRegion.minTrigger) {
status->triggerR = 0;
} else {
if (ClampRegion.maxTrigger < status->triggerR) {
status->triggerR = ClampRegion.maxTrigger;
}
status->triggerR -= ClampRegion.minTrigger;
}
}
}