mirror of
https://github.com/ApacheThunder/ezfo-disc_io.git
synced 2025-06-18 19:15:33 -04:00

* DMA code limited to GBA compile flag as it will not operate safely in DS mode due to arm9 cache system. * tonccpy used in place of dmaCopy for NDS mode. * Altered detection routine in startup function. Should be more reliable (for DS mode at least. Maybe it worked better for GBA homebrew but I found this to be unreliable for DS mode stuff) * setRomPage value for Kernel mode alrted to be 0x8002 as rerferenced in the EZFlash Kernel source code. 0x8000....not sure what the difference is with that one. Maybe 0x8000 is actually bootloader mode? * Disabling of SD and setting back to PSRam mode will no only occur if DLDI is compiled for GBA as the constant mode switching is not nessecery.
137 lines
3.2 KiB
C
137 lines
3.2 KiB
C
#include "tonccpy.h"
|
|
//# tonccpy.c
|
|
|
|
//! VRAM-safe cpy.
|
|
/*! This version mimics memcpy in functionality, with
|
|
the benefit of working for VRAM as well. It is also
|
|
slightly faster than the original memcpy, but faster
|
|
implementations can be made.
|
|
\param dst Destination pointer.
|
|
\param src Source pointer.
|
|
\param size Fill-length in bytes.
|
|
\note The pointers and size need not be word-aligned.
|
|
*/
|
|
void tonccpy(void *dst, const void *src, uint size)
|
|
{
|
|
if(size==0 || dst==0 || src==0)
|
|
return;
|
|
|
|
uint count;
|
|
u16 *dst16; // hword destination
|
|
u8 *src8; // byte source
|
|
|
|
// Ideal case: copy by 4x words. Leaves tail for later.
|
|
if( ((u32)src|(u32)dst)%4==0 && size>=4)
|
|
{
|
|
u32 *src32= (u32*)src, *dst32= (u32*)dst;
|
|
|
|
count= size/4;
|
|
uint tmp= count&3;
|
|
count /= 4;
|
|
|
|
// Duff's Device, good friend!
|
|
switch(tmp) {
|
|
do { *dst32++ = *src32++;
|
|
case 3: *dst32++ = *src32++;
|
|
case 2: *dst32++ = *src32++;
|
|
case 1: *dst32++ = *src32++;
|
|
case 0: ; } while(count--);
|
|
}
|
|
|
|
// Check for tail
|
|
size &= 3;
|
|
if(size == 0)
|
|
return;
|
|
|
|
src8= (u8*)src32;
|
|
dst16= (u16*)dst32;
|
|
}
|
|
else // Unaligned.
|
|
{
|
|
uint dstOfs= (u32)dst&1;
|
|
src8= (u8*)src;
|
|
dst16= (u16*)(dst-dstOfs);
|
|
|
|
// Head: 1 byte.
|
|
if(dstOfs != 0)
|
|
{
|
|
*dst16= (*dst16 & 0xFF) | *src8++<<8;
|
|
dst16++;
|
|
if(--size==0)
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Unaligned main: copy by 2x byte.
|
|
count= size/2;
|
|
while(count--)
|
|
{
|
|
*dst16++ = src8[0] | src8[1]<<8;
|
|
src8 += 2;
|
|
}
|
|
|
|
// Tail: 1 byte.
|
|
if(size&1)
|
|
*dst16= (*dst16 &~ 0xFF) | *src8;
|
|
}
|
|
//# toncset.c
|
|
|
|
//! VRAM-safe memset, internal routine.
|
|
/*! This version mimics memset in functionality, with
|
|
the benefit of working for VRAM as well. It is also
|
|
slightly faster than the original memset.
|
|
\param dst Destination pointer.
|
|
\param fill Word to fill with.
|
|
\param size Fill-length in bytes.
|
|
\note The \a dst pointer and \a size need not be
|
|
word-aligned. In the case of unaligned fills, \a fill
|
|
will be masked off to match the situation.
|
|
*/
|
|
void __toncset(void *dst, u32 fill, uint size)
|
|
{
|
|
if(size==0 || dst==0)
|
|
return;
|
|
|
|
uint left= (u32)dst&3;
|
|
u32 *dst32= (u32*)(dst-left);
|
|
u32 count, mask;
|
|
|
|
// Unaligned head.
|
|
if(left != 0)
|
|
{
|
|
// Adjust for very small stint.
|
|
if(left+size<4)
|
|
{
|
|
mask= BIT_MASK(size*8)<<(left*8);
|
|
*dst32= (*dst32 &~ mask) | (fill & mask);
|
|
return;
|
|
}
|
|
|
|
mask= BIT_MASK(left*8);
|
|
*dst32= (*dst32 & mask) | (fill&~mask);
|
|
dst32++;
|
|
size -= 4-left;
|
|
}
|
|
|
|
// Main stint.
|
|
count= size/4;
|
|
uint tmp= count&3;
|
|
count /= 4;
|
|
|
|
switch(tmp) {
|
|
do { *dst32++ = fill;
|
|
case 3: *dst32++ = fill;
|
|
case 2: *dst32++ = fill;
|
|
case 1: *dst32++ = fill;
|
|
case 0: ; } while(count--);
|
|
}
|
|
|
|
// Tail
|
|
size &= 3;
|
|
if(size)
|
|
{
|
|
mask= BIT_MASK(size*8);
|
|
*dst32= (*dst32 &~ mask) | (fill & mask);
|
|
}
|
|
}
|