copied new unf usb lib

This commit is contained in:
thecozies
2023-04-12 18:07:49 -05:00
parent d68233a1c0
commit 312496d769
4 changed files with 871 additions and 886 deletions

View File

@@ -18,7 +18,6 @@ https://github.com/buu342/N64-UNFLoader
#include <string.h>
#if DEBUG_MODE
/*********************************
@@ -39,39 +38,41 @@ https://github.com/buu342/N64-UNFLoader
#define COMMAND_TOKENS 10
#define BUFFER_SIZE 256
/*********************************
Libultra types (for libdragon)
Libultra types (for libdragon)
*********************************/
#ifdef LIBDRAGON
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef unsigned long long u64;
typedef signed char s8;
typedef short s16;
typedef long s32;
typedef long long s64;
typedef volatile unsigned char vu8;
typedef volatile unsigned short vu16;
typedef volatile unsigned long vu32;
typedef volatile unsigned long long vu64;
typedef volatile signed char vs8;
typedef volatile short vs16;
typedef volatile long vs32;
typedef volatile long long vs64;
typedef float f32;
typedef double f64;
#endif
/*********************************
Structs
*********************************/
// Register struct
typedef struct
{
@@ -109,7 +110,7 @@ https://github.com/buu342/N64-UNFLoader
static void debug_thread_fault(void *arg);
#endif
static void debug_thread_usb(void *arg);
// Other
#if OVERWRITE_OSPRINT
static void* debug_osSyncPrintf_implementation(void *unused, const char *str, size_t len);
@@ -117,12 +118,13 @@ https://github.com/buu342/N64-UNFLoader
#else
static void debug_thread_usb(void *arg);
#endif
static inline void debug_handle_64drivebutton();
/*********************************
Globals
*********************************/
// Function pointers
#ifndef LIBDRAGON
extern int _Printf(void *(*copyfunc)(void *, const char *, size_t), void*, const char*, va_list);
@@ -130,7 +132,7 @@ https://github.com/buu342/N64-UNFLoader
extern void* __printfunc;
#endif
#endif
// Debug globals
static char debug_initialized = 0;
static char debug_buffer[BUFFER_SIZE];
@@ -138,20 +140,25 @@ https://github.com/buu342/N64-UNFLoader
// Commands hashtable related
static debugCommand* debug_commands_hashtable[HASHTABLE_SIZE];
static debugCommand debug_commands_elements[MAX_COMMANDS];
static int debug_commands_count = 0;
static int debug_commands_count = 0;
// Command parsing related
static int debug_command_current = 0;
static int debug_command_totaltokens = 0;
static int debug_command_incoming_start[COMMAND_TOKENS];
static int debug_command_incoming_size[COMMAND_TOKENS];
static char* debug_command_error;
static int debug_command_current = 0;
static int debug_command_totaltokens = 0;
static int debug_command_incoming_start[COMMAND_TOKENS];
static int debug_command_incoming_size[COMMAND_TOKENS];
static char* debug_command_error = NULL;
// Assertion globals
static int assert_line = 0;
static int assert_line = 0;
static const char* assert_file = NULL;
static const char* assert_expr = NULL;
// 64Drive button functions
static void (*debug_64dbut_func)() = NULL;
static u64 debug_64dbut_debounce = 0;
static u64 debug_64dbut_hold = 0;
#ifndef LIBDRAGON
// Fault thread globals
#if USE_FAULTTHREAD
@@ -166,7 +173,7 @@ https://github.com/buu342/N64-UNFLoader
static OSMesg usbMessageBuf;
static OSThread usbThread;
static u64 usbThreadStack[USB_THREAD_STACK/sizeof(u64)];
// List of error causes
static regDesc causeDesc[] = {
{CAUSE_BD, CAUSE_BD, "BD"},
@@ -198,7 +205,7 @@ https://github.com/buu342/N64-UNFLoader
{CAUSE_EXCMASK, EXC_VCED, "Virtual coherency exception on data reference"},
{0, 0, ""}
};
// List of register descriptions
static regDesc srDesc[] = {
{SR_CU3, SR_CU3, "CU3"},
@@ -233,7 +240,7 @@ https://github.com/buu342/N64-UNFLoader
{SR_IE, SR_IE, "IE"},
{0, 0, ""}
};
// List of floating point registers descriptions
static regDesc fpcsrDesc[] = {
{FPCSR_FS, FPCSR_FS, "FS"},
@@ -261,7 +268,8 @@ https://github.com/buu342/N64-UNFLoader
{0, 0, ""}
};
#endif
/*********************************
Debug functions
*********************************/
@@ -276,7 +284,7 @@ https://github.com/buu342/N64-UNFLoader
// Initialize the USB functions
if (!usb_initialize())
return;
// Overwrite osSyncPrintf
#ifndef LIBDRAGON
#if OVERWRITE_OSPRINT
@@ -409,7 +417,7 @@ https://github.com/buu342/N64-UNFLoader
// Ensure debug mode is initialized
if (!debug_initialized)
return;
// Create the data header to send
data[0] = DATATYPE_SCREENSHOT;
data[1] = depth;
@@ -426,7 +434,7 @@ https://github.com/buu342/N64-UNFLoader
#else
debug_thread_usb(&msg);
#endif
// Send the framebuffer to the USB thread
msg.msgtype = MSG_WRITE;
msg.datatype = DATATYPE_SCREENSHOT;
@@ -438,8 +446,8 @@ https://github.com/buu342/N64-UNFLoader
debug_thread_usb(&msg);
#endif
}
/*==============================
_debug_assert
Halts the program (assumes expression failed)
@@ -447,11 +455,9 @@ https://github.com/buu342/N64-UNFLoader
@param The file where the exception ocurred
@param The line number where the exception ocurred
==============================*/
void _debug_assert(const char* expression, const char* file, int line)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
volatile char crash;
// Set the assert data
@@ -463,10 +469,25 @@ https://github.com/buu342/N64-UNFLoader
#ifdef LIBDRAGON
debug_printf("Assertion failed in file '%s', line %d.\n", assert_file, assert_line);
#endif
// Intentionally cause a TLB exception on load/instruction fetch
crash = *(volatile char *)1;
#pragma GCC diagnostic pop
(void)crash;
}
/*==============================
debug_64drivebutton
Assigns a function to be executed when the 64drive button is pressed.
@param The function pointer to execute
@param Whether or not to execute the function only on pressing (ignore holding the button down)
==============================*/
void debug_64drivebutton(void(*execute)(), char onpress)
{
debug_64dbut_func = execute;
debug_64dbut_debounce = 0;
debug_64dbut_hold = !onpress;
}
@@ -549,7 +570,10 @@ https://github.com/buu342/N64-UNFLoader
// Ensure debug mode is initialized
if (!debug_initialized)
return;
// Handle 64Drive button polling
debug_handle_64drivebutton();
// Send a read message to the USB thread
msg.msgtype = MSG_READ;
#ifndef LIBDRAGON
@@ -560,6 +584,56 @@ https://github.com/buu342/N64-UNFLoader
}
/*==============================
debug_handle_64drivebutton
Handles the 64Drive's button logic
==============================*/
static inline void debug_handle_64drivebutton()
{
static u32 held = 0;
// If we own a 64Drive
if (usb_getcart() == CART_64DRIVE && debug_64dbut_func != NULL)
{
u64 curtime;
#ifndef LIBDRAGON
curtime = osGetTime();
#else
curtime = timer_ticks();
#endif
// And the debounce time on the 64Drive's button has elapsed
if (debug_64dbut_debounce < curtime)
{
s32 bpoll;
#ifndef LIBDRAGON
osPiReadIo(0xB80002F8, (u32 *)&bpoll);
#else
bpoll = io_read(0xB80002F8);
#endif
bpoll = (bpoll&0xFFFF0000)>>16;
// If the 64Drive's button has been pressed, then execute the assigned function and set the debounce timer
if (bpoll == 0 && (debug_64dbut_hold || !held))
{
u64 nexttime;
#ifndef LIBDRAGON
nexttime = OS_USEC_TO_CYCLES(100000);
#else
nexttime = TIMER_TICKS(100000);
#endif
debug_64dbut_debounce = curtime + nexttime;
debug_64dbut_func();
held = 1;
}
else if (bpoll != 0 && held)
held = 0;
}
}
}
/*==============================
debug_sizecommand
Returns the size of the data from this part of the command
@@ -606,7 +680,7 @@ https://github.com/buu342/N64-UNFLoader
usb_rewind(debug_command_incoming_size[curr]+debug_command_incoming_start[curr]);
debug_command_current++;
}
/*==============================
debug_commands_setup
@@ -631,11 +705,11 @@ https://github.com/buu342/N64-UNFLoader
int readsize = BUFFER_SIZE;
if (readsize > dataleft)
readsize = dataleft;
// Read a block from USB
memset(debug_buffer, 0, BUFFER_SIZE);
usb_read(debug_buffer, readsize);
// Parse the block
for (i=0; i<readsize && dataleft > 0; i++)
{
@@ -707,12 +781,12 @@ https://github.com/buu342/N64-UNFLoader
Handles the USB thread
@param Arbitrary data that the thread can receive
==============================*/
static void debug_thread_usb(void *arg)
{
char errortype = USBERROR_NONE;
usbMesg* threadMsg;
#ifndef LIBDRAGON
// Create the message queue for the USB message
osCreateMesgQueue(&usbMessageQ, &usbMessageBuf, 1);
@@ -720,7 +794,7 @@ https://github.com/buu342/N64-UNFLoader
// Set the received thread message to the argument
threadMsg = (usbMesg*)arg;
#endif
// Thread loop
while (1)
{
@@ -813,10 +887,12 @@ https://github.com/buu342/N64-UNFLoader
switch (threadMsg->msgtype)
{
case MSG_WRITE:
if (usb_timedout())
usb_sendheartbeat();
usb_write(threadMsg->datatype, threadMsg->buff, threadMsg->size);
break;
}
// If we're in libdragon, break out of the loop as we don't need it
#ifdef LIBDRAGON
break;
@@ -835,7 +911,7 @@ https://github.com/buu342/N64-UNFLoader
@param The amount of characters to write
@returns The end of the buffer that was written to
==============================*/
static void* debug_osSyncPrintf_implementation(void *unused, const char *str, size_t len)
{
void* ret;
@@ -857,7 +933,7 @@ https://github.com/buu342/N64-UNFLoader
}
#endif
#if USE_FAULTTHREAD
/*==============================
@@ -867,7 +943,7 @@ https://github.com/buu342/N64-UNFLoader
@param The name of the register
@param The registry description to use
==============================*/
static void debug_printreg(u32 value, char *name, regDesc *desc)
{
char first = 1;
@@ -895,11 +971,11 @@ https://github.com/buu342/N64-UNFLoader
{
OSMesg msg;
OSThread *curr;
// Create the message queue for the fault message
osCreateMesgQueue(&faultMessageQ, &faultMessageBuf, 1);
osSetEventMesg(OS_EVENT_FAULT, &faultMessageQ, (OSMesg)MSG_FAULT);
// Thread loop
while (1)
{
@@ -911,7 +987,7 @@ https://github.com/buu342/N64-UNFLoader
if (curr != NULL)
{
__OSThreadContext* context = &curr->context;
// Print the basic info
debug_printf("Fault in thread: %d\n\n", curr->id);
debug_printf("pc\t\t0x%08x\n", context->pc);
@@ -933,7 +1009,7 @@ https://github.com/buu342/N64-UNFLoader
debug_printf("s6 0x%016llx s7 0x%016llx t8 0x%016llx\n", context->s6, context->s7, context->t8);
debug_printf("t9 0x%016llx gp 0x%016llx sp 0x%016llx\n", context->t9, context->gp, context->sp);
debug_printf("s8 0x%016llx ra 0x%016llx\n\n", context->s8, context->ra);
// Print the floating point registers
debug_printreg(context->fpcsr, "fpcsr", fpcsrDesc);
debug_printf("\n");
@@ -952,4 +1028,4 @@ https://github.com/buu342/N64-UNFLoader
#endif
#endif
#endif
#endif

View File

@@ -77,6 +77,16 @@
#define debug_assert(expr) (expr) ? ((void)0) : _debug_assert(#expr, __FILE__, __LINE__)
/*==============================
debug_64drivebutton
Assigns a function to be executed when the 64drive button is pressed.
@param The function pointer to execute
@param Whether or not to execute the function only on pressing (ignore holding the button down)
==============================*/
extern void debug_64drivebutton(void(*execute)(), char onpress);
/*==============================
debug_pollcommands
Check the USB for incoming commands.
@@ -90,7 +100,7 @@
Adds a command for the USB to read.
@param The command name
@param The command description
@param The function pointer to execute
@param The function pointer to execute
==============================*/
extern void debug_addcommand(char* command, char* description, char*(*execute)());
@@ -134,14 +144,15 @@
// Overwrite library functions with useless macros if debug mode is disabled
#define debug_initialize()
#define debug_printf(__VA_ARGS__)
#define debug_printf
#define debug_screenshot(a, b, c)
#define debug_assert(a)
#define debug_pollcommands()
#define debug_addcommand(a, b, c)
#define debug_parsecommand() NULL
#define debug_parsecommand(a) NULL
#define debug_sizecommand() 0
#define debug_printcommands()
#define debug_64drivebutton(a, b)
#define usb_initialize() 0
#define usb_getcart() 0
#define usb_write(a, b, c)

File diff suppressed because it is too large Load Diff

View File

@@ -1,43 +1,42 @@
#ifndef UNFL_USB_H
#define UNFL_USB_H
#include "types.h"
/*********************************
DataType macros
*********************************/
// UNCOMMENT THE #DEFINE IF USING LIBDRAGON
//#define LIBDRAGON
//#define LIBDRAGON
// Settings
#define USE_OSRAW 0 // Use if you're doing USB operations without the PI Manager (libultra only)
#define DEBUG_ADDRESS_SIZE 8*1024*1024 // Max size of USB I/O. The bigger this value, the more ROM you lose!
#define CHECK_EMULATOR 0 // Stops the USB library from working if it detects an emulator to prevent problems
// Cart definitions
#define CART_NONE 0
#define CART_64DRIVE 1
#define CART_EVERDRIVE 2
#define CART_SC64 3
// Data types defintions
#define DATATYPE_TEXT 0x01
#define DATATYPE_RAWBINARY 0x02
#define DATATYPE_HEADER 0x03
#define DATATYPE_SCREENSHOT 0x04
extern int usb_datatype;
extern int usb_datasize;
extern int usb_dataleft;
extern int usb_readblock;
#define DATATYPE_HEARTBEAT 0x05
/*********************************
Convenience macros
*********************************/
// Use these to conveniently read the header from usb_poll()
#define USBHEADER_GETTYPE(header) ((header & 0xFF000000) >> 24)
#define USBHEADER_GETSIZE(header) ((header & 0x00FFFFFF))
/*********************************
USB Functions
@@ -48,19 +47,19 @@
Initializes the USB buffers and pointers
@return 1 if the USB initialization was successful, 0 if not
==============================*/
extern char usb_initialize();
/*==============================
usb_getcart
Returns which flashcart is currently connected
@return The CART macro that corresponds to the identified flashcart
==============================*/
extern char usb_getcart();
/*==============================
usb_write
Writes data to the USB.
@@ -69,53 +68,74 @@
@param A buffer with the data to send
@param The size of the data being sent
==============================*/
extern void usb_write(int datatype, const void* data, int size);
/*==============================
usb_poll
Returns the header of data being received via USB
The first byte contains the data type, the next 3 the number of bytes left to read
@return The data header, or 0
==============================*/
extern unsigned long usb_poll();
extern u32 usb_poll();
/*==============================
usb_read
Reads bytes from USB into the provided buffer
@param The buffer to put the read data in
@param The number of bytes to read
==============================*/
extern void usb_read(void* buffer, int size);
/*==============================
usb_skip
Skips a USB read by the specified amount of bytes
@param The number of bytes to skip
==============================*/
extern void usb_skip(int nbytes);
/*==============================
usb_rewind
Rewinds a USB read by the specified amount of bytes
@param The number of bytes to rewind
==============================*/
extern void usb_rewind(int nbytes);
/*==============================
usb_purge
Purges the incoming USB data
==============================*/
extern void usb_purge();
#endif
/*==============================
usb_timedout
Checks if the USB timed out recently
@return 1 if the USB timed out, 0 if not
==============================*/
extern char usb_timedout();
/*==============================
usb_sendheartbeat
Sends a heartbeat packet to the PC
This is done once automatically at initialization,
but can be called manually to ensure that the
host side tool is aware of the current USB protocol
version.
==============================*/
extern void usb_sendheartbeat();
#endif