diff --git a/source/ngc/dvd.c b/source/ngc/dvd.c index c4ad891..3529fb8 100644 --- a/source/ngc/dvd.c +++ b/source/ngc/dvd.c @@ -14,6 +14,7 @@ #include #include #include +#include #ifdef WII_DVD #include @@ -33,16 +34,17 @@ bool isWii = false; volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000; #endif - /** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/ -unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); unsigned char dvdbuffer[2048]; /**************************************************************************** * dvd_read * - * The only DVD function we need - you gotta luv gc-linux self-boots! + * Main DVD function, everything else uses this! * returns: 1 - ok ; 0 - error ***************************************************************************/ +#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1)))) +#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1)))) + int dvd_read (void *dst, unsigned int len, u64 offset) { @@ -52,7 +54,9 @@ dvd_read (void *dst, unsigned int len, u64 offset) // don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD) if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL))) { - unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer; + u8 * buffer = (u8 *)memalign(32, 0x8000); + u32 off_size = 0; + DCInvalidateRange ((void *) buffer, len); #ifdef HW_DOL @@ -72,11 +76,16 @@ dvd_read (void *dst, unsigned int len, u64 offset) if (dvd[0] & 0x4) return 0; #else - if (DI_ReadDVD(buffer, len >> 11, (u32)(offset >> 11))) + off_size = (offset << 2) - ALIGN_BACKWARD((offset << 2),0x800); + if (DI_ReadDVD( + buffer, + (ALIGN_FORWARD((offset << 2) + len,0x800) - ALIGN_BACKWARD((offset << 2),0x800)) >> 11, + (u32)(ALIGN_BACKWARD(offset << 2, 0x800) >> 11) + )) return 0; #endif - memcpy (dst, buffer, len); + memcpy (dst, buffer+off_size, len); return 1; }