mirror of
https://gitlab.com/kholdfuzion/goldeneye_src
synced 2026-06-09 12:06:07 -04:00
351 lines
7.5 KiB
C
351 lines
7.5 KiB
C
/*
|
|
* THIS FILE IS AN OS FILE (PR\libultra\rmon\rmonMain.c)
|
|
*/
|
|
#include <stdarg.h>
|
|
#include <ultra64.h>
|
|
#include <PR/os.h>
|
|
#include "libultra/libc/xstdio.h"
|
|
#include "crash.h"
|
|
#include "rmon.h" /*<PR/rmon.h>*/
|
|
|
|
#ifdef ENABLE_USB
|
|
|
|
#include <os_internal.h>
|
|
#include "libultra/os/osint.h"
|
|
#include "usb.h"
|
|
|
|
#define RMON_MESSAGE_QUEUE_SIZE 10
|
|
#define RMON_MESSAGE_PRINTF_BUFFER_LENGTH 56
|
|
|
|
enum RMON_MESG_TYPE {
|
|
RMON_MESG_TEST = 1,
|
|
RMON_MESG_PRINTF
|
|
};
|
|
|
|
struct RmonMesgBase {
|
|
int type;
|
|
};
|
|
|
|
struct RmonMesgPrintf {
|
|
int type;
|
|
int length;
|
|
char buffer[RMON_MESSAGE_PRINTF_BUFFER_LENGTH];
|
|
};
|
|
|
|
int rmonCurrentMesgStack;
|
|
struct RmonMesgBase rmonMesgStack[2];
|
|
int rmonCurrentMesgPrintfStack;
|
|
struct RmonMesgPrintf rmonMesgPrintfStack[2];
|
|
OSMesg rmonMesg[RMON_MESSAGE_QUEUE_SIZE];
|
|
OSMesgQueue rmonMessageQueue;
|
|
|
|
OSTimer rmonSleeptimer;
|
|
OSMesgQueue rmonSleepMq;
|
|
OSMesg rmonSleepMesg;
|
|
|
|
void rmonHandleTestMsg(struct RmonMesgBase *msg);
|
|
void rmonHandlePrintfMsg(struct RmonMesgPrintf *msg);
|
|
|
|
// sprintf internal function to unwrap paramaters
|
|
extern char *proutSprintf(char *dst, const char *src, size_t count);
|
|
|
|
void rmonInit(void) {
|
|
rmonCurrentMesgStack = 0;
|
|
rmonCurrentMesgPrintfStack = 0;
|
|
|
|
osCreateMesgQueue(&rmonMessageQueue, &rmonMesg, RMON_MESSAGE_QUEUE_SIZE);
|
|
osCreateMesgQueue(&rmonSleepMq, &rmonSleepMesg, 1);
|
|
}
|
|
#endif
|
|
/************************************************************************
|
|
Function: rmonMain
|
|
Args: none
|
|
Type: void
|
|
Purpose: This is the main loop of the rmon debugger. It is mostly a protocol
|
|
parser/dispatcher.
|
|
************************************************************************/
|
|
void rmonMain(void) {
|
|
#ifdef ENABLE_USB
|
|
rmonInit();
|
|
|
|
while (1)
|
|
{
|
|
OSMesg work;
|
|
struct RmonMesgBase *msg;
|
|
|
|
while (0 == osRecvMesg(&rmonMessageQueue, &work, OS_MESG_NOBLOCK))
|
|
{
|
|
msg = work;
|
|
|
|
switch (msg->type)
|
|
{
|
|
case RMON_MESG_TEST:
|
|
rmonHandleTestMsg((struct RmonMesgBase *)msg);
|
|
break;
|
|
|
|
case RMON_MESG_PRINTF:
|
|
rmonHandlePrintfMsg((struct RmonMesgPrintf *)msg);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
osSetTimer(&rmonSleeptimer, OS_USEC_TO_CYCLES(1000000), 0, &rmonSleepMq, rmonSleepMesg);
|
|
osRecvMesg(&rmonSleepMq, &rmonSleepMesg, OS_MESG_BLOCK);
|
|
}
|
|
# endif
|
|
}
|
|
|
|
/**
|
|
* rmonGetToken
|
|
* returns true if this if rmon is disabled
|
|
*/
|
|
s32 rmonGetToken(void) {
|
|
#if defined(DEBUG)
|
|
//flesh out sending a token from pc app
|
|
return FALSE;
|
|
#else
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* REMOVED
|
|
* rmonStatus
|
|
* returns the status of rmon
|
|
*/
|
|
s32 rmonStatus(void) {
|
|
#ifdef DEBUG
|
|
//removed
|
|
#else
|
|
return -1;
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Removed
|
|
* reimpliment osWriteHost
|
|
* target rmon and usb
|
|
*/
|
|
void osWriteHost(void * buffer, u32 size)
|
|
{
|
|
if (buffer);
|
|
if (size);
|
|
#ifdef ENABLE_USB
|
|
//flesh out a proper ge parser on pc app
|
|
usb_write(DATATYPE_RMONBINARY , buffer, size);
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* Removed
|
|
* reimpliment osReadHost
|
|
* target rmon and usb
|
|
*/
|
|
void osReadHost(void * buffer, u32 size)
|
|
{
|
|
#ifdef ENABLE_USB
|
|
char incoming_type = 0;
|
|
int incoming_size = 0;
|
|
#endif
|
|
if (buffer);
|
|
if (size);
|
|
#ifdef ENABLE_USB
|
|
//flesh out a proper pc side tool still
|
|
osSyncPrintf("USB: Waiting for data\n");
|
|
while(1)
|
|
{
|
|
// Check if there's data in USB
|
|
// Needs to be a while loop because we can't write to USB if there's data that needs to be read first
|
|
while (usb_poll() != 0)
|
|
{
|
|
int header = usb_poll();
|
|
// Store the size and type from the header
|
|
incoming_type = USBHEADER_GETTYPE(header);
|
|
incoming_size = USBHEADER_GETSIZE(header);
|
|
osSyncPrintf("USB: Received header %d\n", incoming_type);
|
|
osSyncPrintf("USB: Received size %d\n", incoming_size);
|
|
// Ensure we're receiving a text command
|
|
if (incoming_type != DATATYPE_RMONBINARY)
|
|
{
|
|
//errortype = 1;
|
|
usb_purge();
|
|
osSyncPrintf("USB: Received invalid type %d\n", incoming_type);
|
|
return;
|
|
}
|
|
osSyncPrintf("USB: Read data\n");
|
|
usb_read(buffer, size);
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* Removed
|
|
* rmon7000CEC8
|
|
* unknown function
|
|
*/
|
|
void rmon7000CEC8(void) {
|
|
#ifdef DEBUG
|
|
//removed
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Removed
|
|
* rmon7000CED0
|
|
* unknown function
|
|
*/
|
|
void rmon7000CED0(void) {
|
|
#ifdef DEBUG
|
|
//removed
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* Removed
|
|
* rmon7000CED8
|
|
* unknown function
|
|
*/
|
|
void rmon7000CED8(void) {
|
|
#ifdef DEBUG
|
|
//removed
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Removed
|
|
* rmonPrintf
|
|
*/
|
|
void rmonPrintf(void)
|
|
{
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------
|
|
* This is a new file (PR/libultra/libc/syncprintf.c)
|
|
*/
|
|
|
|
|
|
/**
|
|
* Send text to Remote Debugger, GE redirects to screen (crashAppendChar)
|
|
*/
|
|
#ifndef ENABLE_USB
|
|
void *proutSyncPrintf(void *str, const char *buf, size_t n)
|
|
{
|
|
u32 sent = 0;
|
|
|
|
#ifndef _FINALROM
|
|
while (sent < n)
|
|
{
|
|
# ifdef USERDB
|
|
sent += __osRdbSend((u8 *)&buf[sent], n - sent, RDB_TYPE_GtoH_PRINT);
|
|
# endif
|
|
crashAppendChar(buf[sent++]);
|
|
}
|
|
#endif
|
|
return ((void *)1); /* return a fake pointer so that it's not NULL */
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* Print formatted string to Debugger
|
|
*/
|
|
void osSyncPrintf(const char *fmt, ...)
|
|
{
|
|
|
|
#ifdef ENABLE_USB
|
|
u8 buffer[100];
|
|
#endif
|
|
int ans;
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
#ifdef ENABLE_USB
|
|
ans = _Printf(&proutSprintf, buffer, fmt, args);
|
|
#else
|
|
ans = _Printf(&proutSyncPrintf, NULL, fmt, args);
|
|
#endif
|
|
va_end(args);
|
|
#ifdef ENABLE_USB
|
|
if (ans >= 0) {
|
|
if (ans > 99)
|
|
{
|
|
ans = 99;
|
|
}
|
|
buffer[ans] = 0;
|
|
}
|
|
usb_write_text(buffer, ans);
|
|
#endif
|
|
|
|
}
|
|
|
|
#ifdef ENABLE_USB
|
|
/**
|
|
* Print formatted string to Debugger.
|
|
* This is a non blocking call. The printf message will be copied
|
|
* to the rmon printf queue. It is possible for the queue to overflow (wrap around).
|
|
* The printf message is copied to a local byte array, truncating the message if necessary.
|
|
*/
|
|
void osAsyncPrintf(const char *format, ...)
|
|
{
|
|
s32 written;
|
|
va_list args;
|
|
|
|
struct RmonMesgPrintf *dest = &rmonMesgPrintfStack[rmonCurrentMesgPrintfStack];
|
|
rmonCurrentMesgPrintfStack++;
|
|
if (rmonCurrentMesgPrintfStack > 1) {
|
|
rmonCurrentMesgPrintfStack = 0;
|
|
}
|
|
dest->type = RMON_MESG_PRINTF;
|
|
|
|
va_start(args, format);
|
|
written = _Printf(proutSprintf, dest->buffer, format, args);
|
|
va_end(args);
|
|
if (written >= 0) {
|
|
if (written > RMON_MESSAGE_PRINTF_BUFFER_LENGTH - 1)
|
|
{
|
|
written = RMON_MESSAGE_PRINTF_BUFFER_LENGTH - 1;
|
|
}
|
|
dest->buffer[written] = 0;
|
|
}
|
|
|
|
dest->length = written;
|
|
|
|
osSendMesg(&rmonMessageQueue, (OSMesg)dest, OS_MESG_NOBLOCK);
|
|
}
|
|
|
|
void osQueueTest(void)
|
|
{
|
|
struct RmonMesgBase *dest = &rmonMesgStack[rmonCurrentMesgStack];
|
|
rmonCurrentMesgStack++;
|
|
if (rmonCurrentMesgStack > 1) {
|
|
rmonCurrentMesgStack = 0;
|
|
}
|
|
dest->type = RMON_MESG_TEST;
|
|
osSendMesg(&rmonMessageQueue, (OSMesg)dest, OS_MESG_NOBLOCK);
|
|
}
|
|
|
|
void rmonHandleTestMsg(struct RmonMesgBase *msg)
|
|
{
|
|
usb_write_text("????\n", 6);
|
|
}
|
|
|
|
void rmonHandlePrintfMsg(struct RmonMesgPrintf *msg)
|
|
{
|
|
// pending read data will abort write, so clobber any incoming data.
|
|
//usb_purge();
|
|
usb_write_text(msg->buffer, msg->length);
|
|
}
|
|
#endif
|