mirror of
https://github.com/zeldaret/oot.git
synced 2024-11-25 09:45:02 +00:00
Match retail z_std_dma.c (#1665)
* Match z_std_dma.c * Fix DmaMgr_Error doc comment * Unindent
This commit is contained in:
parent
17da5e7bf9
commit
8ea4cb87e5
2 changed files with 58 additions and 25 deletions
|
@ -46,9 +46,11 @@ extern size_t gDmaMgrDmaBuffSize;
|
|||
s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
|
||||
OSMesg msg);
|
||||
s32 DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size);
|
||||
#if OOT_DEBUG
|
||||
s32 DmaMgr_RequestAsyncDebug(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
|
||||
OSMesg msg, const char* file, s32 line);
|
||||
s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char* file, s32 line);
|
||||
#endif
|
||||
|
||||
// Special-purpose DMA Requests
|
||||
|
||||
|
|
|
@ -36,12 +36,15 @@ u32 sDmaMgrIsRomCompressed = false;
|
|||
// dmadata filenames
|
||||
#define DEFINE_DMA_ENTRY(_0, nameString) nameString,
|
||||
|
||||
#if OOT_DEBUG
|
||||
const char* sDmaMgrFileNames[] = {
|
||||
#include "tables/dmadata_table.h"
|
||||
};
|
||||
#endif
|
||||
|
||||
#undef DEFINE_DMA_ENTRY
|
||||
|
||||
#if OOT_DEBUG
|
||||
/**
|
||||
* Compares `str1` and `str2`.
|
||||
*
|
||||
|
@ -67,6 +70,7 @@ s32 DmaMgr_StrCmp(const char* str1, const char* str2) {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Transfer `size` bytes from physical ROM address `rom` to `ram`.
|
||||
|
@ -86,7 +90,6 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
|
|||
OSMesg msg;
|
||||
s32 ret;
|
||||
size_t buffSize = gDmaMgrDmaBuffSize;
|
||||
s32 pad[2];
|
||||
|
||||
if (buffSize == 0) {
|
||||
buffSize = DMAMGR_DEFAULT_BUFSIZE;
|
||||
|
@ -132,7 +135,9 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
|
|||
ram = (u8*)ram + buffSize;
|
||||
}
|
||||
|
||||
if (1) {} // Also necessary to match
|
||||
if (1) { // Also necessary to match
|
||||
s32 pad[2];
|
||||
}
|
||||
|
||||
ioMsg.hdr.pri = OS_MESG_PRI_NORMAL;
|
||||
ioMsg.hdr.retQueue = &queue;
|
||||
|
@ -219,17 +224,18 @@ void DmaMgr_DmaFromDriveRom(void* ram, uintptr_t rom, size_t size) {
|
|||
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
/**
|
||||
* DMA error encountered, print error messages and bring up the crash screen.
|
||||
*
|
||||
* @param req DMA Request causing the error.
|
||||
* @param file DMA data filename associated with the operation that errored.
|
||||
* @param filename DMA data filename associated with the operation that errored.
|
||||
* @param errorName Error name string.
|
||||
* @param errorDesc Error description string.
|
||||
*
|
||||
* This function does not return.
|
||||
*/
|
||||
NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, const char* errorDesc) {
|
||||
NORETURN void DmaMgr_Error(DmaRequest* req, const char* filename, const char* errorName, const char* errorDesc) {
|
||||
uintptr_t vrom = req->vromAddr;
|
||||
void* ram = req->dramAddr;
|
||||
size_t size = req->size;
|
||||
|
@ -241,7 +247,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
|
|||
// "DMA Fatal Error"
|
||||
PRINTF("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n",
|
||||
errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size,
|
||||
file != NULL ? file : "???");
|
||||
filename != NULL ? filename : "???");
|
||||
|
||||
if (req->filename != NULL) { // Source file name that issued the DMA request
|
||||
PRINTF("DMA ERROR: %s %d", req->filename, req->line);
|
||||
|
@ -259,10 +265,15 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
|
|||
sprintf(buff1, "DMA ERROR: %s", errorName != NULL ? errorName : "???");
|
||||
}
|
||||
|
||||
sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, file != NULL ? file : "???");
|
||||
sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, filename != NULL ? filename : "???");
|
||||
Fault_AddHungupAndCrashImpl(buff1, buff2);
|
||||
}
|
||||
|
||||
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) DmaMgr_Error(req, filename, errorName, errorDesc)
|
||||
#else
|
||||
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) Fault_AddHungupAndCrash(file, line)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Searches the filesystem for the entry containing the address `vrom`. Retrieves the name of this entry from
|
||||
* the array of file names.
|
||||
|
@ -271,6 +282,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
|
|||
* @return Pointer to associated filename
|
||||
*/
|
||||
const char* DmaMgr_FindFileName(uintptr_t vrom) {
|
||||
#if OOT_DEBUG
|
||||
DmaEntry* iter = gDmaDataTable;
|
||||
const char** name = sDmaMgrFileNames;
|
||||
|
||||
|
@ -287,9 +299,13 @@ const char* DmaMgr_FindFileName(uintptr_t vrom) {
|
|||
#ifdef AVOID_UB
|
||||
return "";
|
||||
#endif
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* DmaMgr_GetFileName(uintptr_t vrom) {
|
||||
#if OOT_DEBUG
|
||||
const char* ret = DmaMgr_FindFileName(vrom);
|
||||
|
||||
if (ret == NULL) {
|
||||
|
@ -302,6 +318,9 @@ const char* DmaMgr_GetFileName(uintptr_t vrom) {
|
|||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
void DmaMgr_ProcessRequest(DmaRequest* req) {
|
||||
|
@ -314,15 +333,13 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
|
|||
DmaEntry* iter;
|
||||
const char* filename;
|
||||
|
||||
if (0) {
|
||||
// The string is defined in .rodata but not used, suggesting a debug print is here but was optimized out in
|
||||
// some way. The last arg of this print looks like it may be filename, but filename above this block does not
|
||||
// match.
|
||||
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n");
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
// Get the filename (for debugging)
|
||||
filename = DmaMgr_GetFileName(vrom);
|
||||
#else
|
||||
// An unused empty string is defined in .rodata of retail builds, suggesting it was used near here.
|
||||
filename = "";
|
||||
#endif
|
||||
|
||||
// Iterate through the DMA data table until the region containing the vrom address for this request is found
|
||||
iter = gDmaDataTable;
|
||||
|
@ -330,7 +347,11 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
|
|||
if (vrom >= iter->vromStart && vrom < iter->vromEnd) {
|
||||
// Found the region this request falls into
|
||||
|
||||
if (1) {} // Necessary to match
|
||||
if (0) {
|
||||
// The string is defined in .rodata of debug builds but not used, suggesting a debug print is here
|
||||
// but was optimized out in some way.
|
||||
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n", vrom, ram, size, filename);
|
||||
}
|
||||
|
||||
if (iter->romEnd == 0) {
|
||||
// romEnd of 0 indicates that the file is uncompressed. Files that are stored uncompressed can have
|
||||
|
@ -340,8 +361,8 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
|
|||
// Error, vrom + size ends up in a different file than it started in
|
||||
|
||||
// "DMA transfers cannot cross segment boundaries"
|
||||
DmaMgr_Error(req, filename, "Segment Alignment Error",
|
||||
"セグメント境界をまたがってDMA転送することはできません");
|
||||
DMA_ERROR(req, filename, "Segment Alignment Error",
|
||||
"セグメント境界をまたがってDMA転送することはできません", "../z_std_dma.c", 726);
|
||||
}
|
||||
|
||||
DmaMgr_DmaRomToRam(iter->romStart + (vrom - iter->vromStart), ram, size);
|
||||
|
@ -360,16 +381,16 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
|
|||
// Error, requested vrom is not the start of a file
|
||||
|
||||
// "DMA transfer cannot be performed from the middle of a compressed segment"
|
||||
DmaMgr_Error(req, filename, "Can't Transfer Segment",
|
||||
"圧縮されたセグメントの途中からはDMA転送することはできません");
|
||||
DMA_ERROR(req, filename, "Can't Transfer Segment",
|
||||
"圧縮されたセグメントの途中からはDMA転送することはできません", "../z_std_dma.c", 746);
|
||||
}
|
||||
|
||||
if (size != iter->vromEnd - iter->vromStart) {
|
||||
// Error, only part of the file was requested
|
||||
|
||||
// "It is not possible to DMA only part of a compressed segment"
|
||||
DmaMgr_Error(req, filename, "Can't Transfer Segment",
|
||||
"圧縮されたセグメントの一部だけをDMA転送することはできません");
|
||||
DMA_ERROR(req, filename, "Can't Transfer Segment",
|
||||
"圧縮されたセグメントの一部だけをDMA転送することはできません", "../z_std_dma.c", 752);
|
||||
}
|
||||
|
||||
// Reduce the thread priority and decompress the file, the decompression routine handles the DMA
|
||||
|
@ -395,7 +416,7 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
|
|||
// Error, rom is compressed so DMA may only be requested within the filesystem bounds
|
||||
|
||||
// "Corresponding data does not exist"
|
||||
DmaMgr_Error(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません");
|
||||
DMA_ERROR(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません", "../z_std_dma.c", 771);
|
||||
return;
|
||||
} else {
|
||||
// ROM is uncompressed, allow arbitrary DMA even if the region is not marked in the filesystem
|
||||
|
@ -460,11 +481,15 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
|
|||
OSMesg msg) {
|
||||
static s32 sDmaMgrQueueFullLogged = 0;
|
||||
|
||||
if ((1 && (ram == NULL)) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) ||
|
||||
#if OOT_DEBUG
|
||||
if ((ram == NULL) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) ||
|
||||
(size == 0) || (size & 1)) {
|
||||
//! @bug `req` is passed to `DmaMgr_Error` without rom, ram and size being set
|
||||
DmaMgr_Error(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です");
|
||||
// The line numbers for `DMA_ERROR` are only used in retail builds, but this usage was removed so
|
||||
// its line number is unknown.
|
||||
//! @bug `req` is passed to `DMA_ERROR` without rom, ram and size being set
|
||||
DMA_ERROR(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です", "../z_std_dma.c", 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
req->vromAddr = vrom;
|
||||
req->dramAddr = ram;
|
||||
|
@ -473,6 +498,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
|
|||
req->notifyQueue = queue;
|
||||
req->notifyMsg = msg;
|
||||
|
||||
#if OOT_DEBUG
|
||||
if (1 && (sDmaMgrQueueFullLogged == 0) && MQ_IS_FULL(&sDmaMgrMsgQueue)) {
|
||||
sDmaMgrQueueFullLogged++;
|
||||
PRINTF("%c", BEL);
|
||||
|
@ -483,6 +509,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
|
|||
952);
|
||||
PRINTF(VT_RST);
|
||||
}
|
||||
#endif
|
||||
|
||||
osSendMesg(&sDmaMgrMsgQueue, (OSMesg)req, OS_MESG_BLOCK);
|
||||
return 0;
|
||||
|
@ -523,12 +550,13 @@ void DmaMgr_Init(void) {
|
|||
(u32)(_dmadataSegmentRomEnd - _dmadataSegmentRomStart));
|
||||
PRINTF("dma_rom_ad[]\n");
|
||||
|
||||
sDmaMgrIsRomCompressed = false;
|
||||
#if OOT_DEBUG
|
||||
name = sDmaMgrFileNames;
|
||||
iter = gDmaDataTable;
|
||||
idx = 0;
|
||||
|
||||
// Check if the ROM is compressed (romEnd not 0)
|
||||
sDmaMgrIsRomCompressed = false;
|
||||
while (iter->vromEnd != 0) {
|
||||
if (iter->romEnd != 0) {
|
||||
sDmaMgrIsRomCompressed = true;
|
||||
|
@ -545,6 +573,7 @@ void DmaMgr_Init(void) {
|
|||
name++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensure that the boot segment always follows after the makerom segment.
|
||||
if ((uintptr_t)_bootSegmentRomStart != gDmaDataTable[0].vromEnd) {
|
||||
|
@ -562,6 +591,7 @@ void DmaMgr_Init(void) {
|
|||
osStartThread(&sDmaMgrThread);
|
||||
}
|
||||
|
||||
#if OOT_DEBUG
|
||||
/**
|
||||
* Asynchronous DMA Request with source file and line info for debugging.
|
||||
*
|
||||
|
@ -597,3 +627,4 @@ s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char*
|
|||
osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue