[Scummvm-cvs-logs] SF.net SVN: scummvm:[50982] scummvm/trunk

Bluddy at users.sourceforge.net Bluddy at users.sourceforge.net
Sun Jul 18 09:03:15 CEST 2010


Revision: 50982
          http://scummvm.svn.sourceforge.net/scummvm/?rev=50982&view=rev
Author:   Bluddy
Date:     2010-07-18 07:03:14 +0000 (Sun, 18 Jul 2010)

Log Message:
-----------
PSP: switched to using my memcpy

Modified Paths:
--------------
    scummvm/trunk/backends/platform/psp/Makefile
    scummvm/trunk/backends/platform/psp/memory.cpp
    scummvm/trunk/backends/platform/psp/memory.h
    scummvm/trunk/backends/platform/psp/psp_main.cpp
    scummvm/trunk/backends/platform/psp/tests.cpp
    scummvm/trunk/backends/platform/psp/tests.h
    scummvm/trunk/backends/platform/psp/trace.h
    scummvm/trunk/configure

Modified: scummvm/trunk/backends/platform/psp/Makefile
===================================================================
--- scummvm/trunk/backends/platform/psp/Makefile	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/Makefile	2010-07-18 07:03:14 UTC (rev 50982)
@@ -148,7 +148,8 @@
 	audio.o \
 	thread.o \
 	rtc.o \
-	mp3.o
+	mp3.o \
+	tests.o
 
 # Include common Scummvm makefile
 include $(srcdir)/Makefile.common

Modified: scummvm/trunk/backends/platform/psp/memory.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/memory.cpp	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/memory.cpp	2010-07-18 07:03:14 UTC (rev 50982)
@@ -1,404 +1,499 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
- * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
- *
- */
-
-#include "common/scummsys.h"
-#include "common/singleton.h"
-#include "common/list.h"
-#include "backends/platform/psp/PSPPixelFormat.h"
-#include "backends/platform/psp/memory.h"
-
-// Class Copier --------------------------------------------------------------------------
-//#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
-//#define __PSP_DEBUG_PRINT__
-
-#include "backends/platform/psp/trace.h"
-
-//#define TEST_MEMORY_COPY
-
-// swapRB is used to swap red and blue in the display
-void PspMemory::copy(byte *dst, const byte *src, uint32 bytes) {
-	DEBUG_ENTER_FUNC();
-
-#ifdef TEST_MEMORY_COPY
-	uint32 debugBytes = bytes;
-	const byte *debugDst = dst, *debugSrc = src;
-#endif
-
-	PSP_DEBUG_PRINT("copy(): dst[%p], src[%p], bytes[%d]\n", dst, src, bytes);
-
-	// align the destination pointer first
-	uint32 prefixDst = (((uint32)dst) & 0x3);
-	
-	if (prefixDst) {
-		prefixDst = 4 - prefixDst;				// prefix only if we have address % 4 != 0	
-		PSP_DEBUG_PRINT("prefixDst[%d]\n", prefixDst);
-
-		bytes -= prefixDst;						// remember we assume bytes >= 4
-	
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) {	// check if it's worthwhile to continue
-			copy8(dst, src, bytes);
-#ifdef TEST_MEMORY_COPY
-			testCopy(debugDst, debugSrc, debugBytes);
-#endif		
-			return;
-		}
-		
-		while (prefixDst--) {
-			*dst++ = *src++;
-		}		
-	}
-	
-	// check the source pointer alignment now
-	uint32 alignSrc = (((uint32)src) & 0x3);
-	
-	if (alignSrc) {						// we'll need to realign our reads
-		copy32Misaligned((uint32 *)dst, src, bytes, alignSrc);
-	} else {
-		copy32Aligned((uint32 *)dst, (uint32 *)src, bytes);
-	}
-
-#ifdef TEST_MEMORY_COPY
-	testCopy(debugDst, debugSrc, debugBytes);
-#endif		
-}
-
-void PspMemory::testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes) {
-	
-	bool mismatch = false;
-	PSP_INFO_PRINT("testing memcpy...");
-
-	for (uint32 i = 0; i < debugBytes; i++) {
-		if (debugDst[i] != debugSrc[i]) {
-			if (mismatch == false) {
-				PSP_DEBUG_PRINT_SAMELN("**** mismatch in copy! ****\n");
-				PSP_DEBUG_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes);
-				mismatch = true;
-			}
-			PSP_DEBUG_PRINT_SAMELN("%x!=%x ", debugSrc[i], debugDst[i]);
-		}
-	}
-	if (mismatch) {
-		PSP_DEBUG_PRINT("\n");
-	} else {
-		PSP_INFO_PRINT("ok\n");
-	}	
-}
-
-// 
-// used to swap red and blue
-void PspMemory::swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-
-	// align the destination pointer first
-	uint32 prefixDst = (((uint32)dst16) & 0x3);	// for swap, we can only have 2 or 0 as our prefix
-	
-	if (prefixDst) {
-		bytes -= prefixDst;						// remember we assume bytes > 4
-		*dst16++ = *src16++;
-		
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY * 2) { // check if it's worthwhile to continue
-			swap16(dst16, src16, bytes, format);
-			return;
-		}
-	}
-	
-	// check the source pointer alignment now
-	uint32 alignSrc = (((uint32)src16) & 0x3);
-	
-	if (alignSrc) {						// we'll need to realign our reads
-		PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src16, dst16);
-		swap32Misaligned((uint32 *)dst16, (uint16 *)src16, bytes, format);
-	} else {
-		swap32Aligned((uint32 *)dst16, (uint32 *)src16, bytes, format);
-	}
-}
-
-void PspMemory::copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes) {
-	PSP_DEBUG_PRINT("copy32Aligned(): dst32[%p], src32[%p], bytes[%d]\n", dst32, src32, bytes);
-
-	int words8 = bytes >> 5;
-	
-	// try blocks of 8 words at a time
-	if (words8) {
-		while (words8--) {
-			dst32[0] = src32[0];
-			dst32[1] = src32[1];
-			dst32[2] = src32[2];
-			dst32[3] = src32[3];
-			dst32[4] = src32[4];
-			dst32[5] = src32[5];
-			dst32[6] = src32[6];
-			dst32[7] = src32[7];			
-			dst32 += 8;
-			src32 += 8;
-		}				
-	}
-	
-	int words4 = (bytes & 0x1F) >> 4;
-	
-	// try blocks of 4 words at a time
-	if (words4) {
-		dst32[0] = src32[0];
-		dst32[1] = src32[1];
-		dst32[2] = src32[2];
-		dst32[3] = src32[3];
-		dst32 += 4;
-		src32 += 4;
-	}
-	
-	int bytesLeft = (bytes & 0xF);	// only look at bytes left after we did the above
-	int wordsLeft = bytesLeft >> 2;
-	
-	// now just do single words
-	while (wordsLeft) {
-		*dst32++ = *src32++;
-		wordsLeft--;
-	}
-
-	bytesLeft = bytes & 0x3;	// get remaining bytes
-
-	PSP_DEBUG_PRINT("bytesLeft[%d]\n", bytesLeft);
-
-	byte *dst = (byte *)dst32;
-	byte *src = (byte *)src32;
-	
-	while (bytesLeft--) {
-		*dst++ = *src++;
-	}
-}
-
-void PspMemory::swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-	int words = bytes >> 2;
-	
-	// try blocks of 4 words at a time
-	for (; words - 4 >= 0; words -= 4) {
-		dst32[0] = format.swapRedBlue32(src32[0]);
-		dst32[1] = format.swapRedBlue32(src32[1]);
-		dst32[2] = format.swapRedBlue32(src32[2]);
-		dst32[3] = format.swapRedBlue32(src32[3]);
-		dst32 += 4;
-		src32 += 4;
-	}
-	
-	// now just do words
-	for (; words > 0; words--) {
-		*dst32++ = format.swapRedBlue32(*src32++);
-	}	
-
-	uint32 remainingBytes = bytes & 0x3;
-	
-	if (remainingBytes) {	// for swap, must be a 16 bit value
-		*((uint16 *)dst32) = format.swapRedBlue16(*((uint16 *)src32));	// only 1 short left
-	}
-}
-
-
-// More challenging -- need to shift
-// Assume dst is aligned
-void PspMemory::copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc) {
-	PSP_DEBUG_PRINT("copy32Misaligned: dst32[%p], src[%p], bytes[%d], alignSrc[%d]\n", dst32, src, bytes, alignSrc);
-	
-	uint32 *src32 = (uint32 *)(((uint32)src) & 0xFFFFFFFC);	// remove misalignment
-	uint32 offset;
-	
-	switch (alignSrc) {
-	case 1:
-		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 8, 24);
-		break;
-	case 2:
-		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 16, 16);
-		break;
-	case 3:
-		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 24, 8);
-		break;
-	}
-	
-	uint32 remainingBytes = bytes & 3;
-	
-	if (remainingBytes) {
-		byte *dst = (byte *)dst32;
-		src += offset;
-		dst += offset;
-		copy8(dst, src, remainingBytes);
-	}	
-}
-
-// returns offset in dst
-uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue) {
-	uint32 *origDst32 = dst32;
-	register uint32 dstWord, srcWord;
-	
-	PSP_DEBUG_PRINT("misaligned32Detail(): alignSrc[%d], dst32[%p], src32[%p], words[%d]\n", alignSrc, dst32, src32, words);
-	
-	// Try to do groups of 4 words
-	uint32 words4 = bytes >> 4;
-	
-	srcWord = src32[0];
-
-	while (words4--) {
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[1];
-		dstWord |= srcWord << lastShiftValue;
-		dst32[0] = dstWord;
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[2];
-		dstWord |= srcWord << lastShiftValue;
-		dst32[1] = dstWord;
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[3];
-		dstWord |= srcWord << lastShiftValue;
-		dst32[2] = dstWord;
-		dstWord = srcWord >> shiftValue;
-		srcWord = src32[4];
-		dstWord |= srcWord << lastShiftValue;
-		dst32[3] = dstWord;
-		src32 += 4;
-		dst32 += 4;
-	}
-	
-	uint32 words = (bytes & 0xF) >> 2;
-	
-	// we read one word ahead of what we write
-	// setup the first read
-	if (words) {
-		srcWord = *src32++;
-		
-		while (words--) {
-			dstWord = srcWord >> shiftValue;
-			srcWord = *src32++;
-			dstWord |= srcWord << lastShiftValue;
-			*dst32++ = dstWord;
-		}
-	}
-	
-	return (byte *)dst32 - (byte *)origDst32;
-}
-// More challenging -- need to shift
-// Assume dst is aligned
-void PspMemory::swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-	DEBUG_ENTER_FUNC();
-	if (bytes < MIN_AMOUNT_FOR_MISALIGNED_COPY) {	// less than a certain number of bytes it's just not worth it
-		swap16((uint16 *)dst32, src16, bytes, format);
-		return;
-	}
-	
-	int words = bytes >> 2;
-	uint32 remainingBytes = bytes & 3;
-	
-	uint32 *src32 = (uint32 *)(((uint32)src16) & 0xFFFFFFFC);	// remove misalignment
-
-	// we read one word ahead of what we write
-	// setup the first read
-	uint32 lastWord = ((*src32++) >> 16) & 0xFFFF;
-	
-	for (; words; words--) {
-		uint32 srcWord = *src32++;
-		uint32 curWord = (srcWord >> 16) & 0xFFFF;
-		lastWord |= (srcWord & 0xFFFF) << 16;	// take the part of the src that belongs to this word		
-		*dst32++ = format.swapRedBlue32(lastWord);
-		lastWord = curWord;
-	}
-	
-	if (remainingBytes) {	// add in the remaining stuff
-		*(uint16 *)dst32 = format.swapRedBlue16((uint16)lastWord);
-	}
-}
-
-inline void PspMemory::copy16(uint16 *dst16, const uint16 *src16, uint32 bytes) {
-	PSP_DEBUG_PRINT("copy16(): dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes);
-	
-	uint32 shorts = bytes >> 1;
-	uint32 remainingBytes = bytes & 1;
-
-	for (; shorts > 0 ; shorts--) {
-		*dst16++ = *src16++;
-	}
-	if (remainingBytes)
-		*(byte *)dst16 = *(byte *)src16;
-}
-
-// Class VramAllocator -----------------------------------
-
-DECLARE_SINGLETON(VramAllocator)
-
-//#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
-//#define __PSP_DEBUG_PRINT__
-
-#include "backends/platform/psp/trace.h"
-
-
-void *VramAllocator::allocate(int32 size, bool smallAllocation /* = false */) {
-	DEBUG_ENTER_FUNC();
-	assert(size > 0);
-
-	byte *lastAddress = smallAllocation ? (byte *)VRAM_SMALL_ADDRESS : (byte *)VRAM_START_ADDRESS;
-	Common::List<Allocation>::iterator i;
-
-	// Find a block that fits, starting from the beginning
-	for (i = _allocList.begin(); i != _allocList.end(); ++i) {
-		byte *currAddress = (*i).address;
-
-		if (currAddress - lastAddress >= size) // We found a match
-			break;
-
-		if ((*i).getEnd() > lastAddress)
-			lastAddress = (byte *)(*i).getEnd();
-	}
-
-	if (lastAddress + size > (byte *)VRAM_END_ADDRESS) {
-		PSP_DEBUG_PRINT("No space for allocation of %d bytes. %d bytes already allocated.\n",
-		                size, _bytesAllocated);
-		return NULL;
-	}
-
-	_allocList.insert(i, Allocation(lastAddress, size));
-	_bytesAllocated += size;
-
-	PSP_DEBUG_PRINT("Allocated in VRAM, size %u at %p.\n", size, lastAddress);
-	PSP_DEBUG_PRINT("Total allocated %u, remaining %u.\n", _bytesAllocated, (2 * 1024 * 1024) - _bytesAllocated);
-
-	return lastAddress;
-}
-
-// Deallocate a block from VRAM
-void VramAllocator::deallocate(void *address) {
-	DEBUG_ENTER_FUNC();
-	address = (byte *)CACHED(address);	// Make sure all addresses are the same
-
-	Common::List<Allocation>::iterator i;
-
-	// Find the Allocator to deallocate
-	for (i = _allocList.begin(); i != _allocList.end(); ++i) {
-		if ((*i).address == address) {
-			_bytesAllocated -= (*i).size;
-			_allocList.erase(i);
-			PSP_DEBUG_PRINT("Deallocated address[%p], size[%u]\n", (*i).address, (*i).size);
-			return;
-		}
-	}
-
-	PSP_DEBUG_PRINT("Address[%p] not allocated.\n", address);
-}
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/singleton.h"
+#include "common/list.h"
+#include "backends/platform/psp/PSPPixelFormat.h"
+#include "backends/platform/psp/memory.h"
+
+// Class Copier --------------------------------------------------------------------------
+//#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
+//#define __PSP_DEBUG_PRINT__
+
+#include "backends/platform/psp/trace.h"
+
+//#define TEST_MEMORY_COPY
+
+extern "C" {
+
+void *__wrap_memcpy(void *dst, void *src, size_t bytes) {
+	PspMemory::fastCopy((byte *)dst, (byte *)src, bytes);
+	return dst;
+}
+
+}
+
+void PspMemory::copy(byte *dst, const byte *src, uint32 bytes) {
+	DEBUG_ENTER_FUNC();
+
+#ifdef TEST_MEMORY_COPY
+	uint32 debugBytes = bytes;
+	const byte *debugDst = dst, *debugSrc = src;
+#endif
+
+	PSP_DEBUG_PRINT("copy(): dst[%p], src[%p], bytes[%d]\n", dst, src, bytes);
+
+	// align the destination pointer first
+	uint32 prefixDst = (((uint32)dst) & 0x3);
+	
+	if (prefixDst) {
+		prefixDst = 4 - prefixDst;				// prefix only if we have address % 4 != 0	
+		PSP_DEBUG_PRINT("prefixDst[%d]\n", prefixDst);
+
+		bytes -= prefixDst;						// remember we assume bytes >= 4
+		
+		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) {	// check if it's worthwhile to continue
+			copy8(dst, src, bytes + prefixDst);
+#ifdef TEST_MEMORY_COPY
+			testCopy(debugDst, debugSrc, debugBytes);
+#endif		
+			return;
+		}
+		
+		while (prefixDst--) {
+			*dst++ = *src++;
+		}		
+	}
+	
+	// check the source pointer alignment now
+	uint32 alignSrc = (((uint32)src) & 0x3);
+	
+	if (alignSrc) {						// we'll need to realign our reads
+		copy32Misaligned((uint32 *)dst, src, bytes, alignSrc);
+	} else {
+		copy32Aligned((uint32 *)dst, (uint32 *)src, bytes);
+	}
+
+#ifdef TEST_MEMORY_COPY
+	testCopy(debugDst, debugSrc, debugBytes);
+#endif		
+}
+
+void PspMemory::testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes) {
+	
+	bool mismatch = false;
+	PSP_INFO_PRINT("testing fastCopy...");
+
+	for (uint32 i = 0; i < debugBytes; i++) {
+		if (debugDst[i] != debugSrc[i]) {
+			if (!mismatch) {
+				PSP_INFO_PRINT("**** mismatch in copy! ****\n");
+				PSP_INFO_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes);
+				mismatch = true;
+			}
+			PSP_INFO_PRINT("[%d]%x!=%x ", i, debugSrc[i], debugDst[i]);
+		}
+	}
+	if (mismatch) {
+		PSP_INFO_PRINT("\n");
+	} else {
+		PSP_INFO_PRINT("ok\n");
+	}	
+}
+
+// 
+// used to swap red and blue
+void PspMemory::swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
+	DEBUG_ENTER_FUNC();
+
+#ifdef TEST_MEMORY_COPY
+	uint32 debugBytes = bytes;
+	const uint16 *debugDst = dst16, *debugSrc = src16;
+#endif
+	
+	// align the destination pointer first
+	uint32 prefixDst = (((uint32)dst16) & 0x3);	// for swap, we can only have 2 or 0 as our prefix
+	
+	if (prefixDst) {
+		bytes -= prefixDst;						// remember we assume bytes > 4
+		*dst16++ = format.swapRedBlue16(*src16++);
+		
+		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { // check if it's worthwhile to continue
+			swap16(dst16, src16, bytes, format);
+
+#ifdef TEST_MEMORY_COPY
+			testSwap(debugDst, debugSrc, debugBytes, format);
+#endif		
+			return;
+		}
+	}
+	
+	// check the source pointer alignment now
+	uint32 alignSrc = (((uint32)src16) & 0x3);
+	
+	if (alignSrc) {						// we'll need to realign our reads
+		PSP_DEBUG_PRINT("misaligned copy of %u bytes from %p to %p\n", bytes, src16, dst16);
+		swap32Misaligned((uint32 *)dst16, src16, bytes, format);
+	} else {
+		swap32Aligned((uint32 *)dst16, (const uint32 *)src16, bytes, format);
+	}
+	
+#ifdef TEST_MEMORY_COPY
+	testSwap(debugDst, debugSrc, debugBytes, format);
+#endif		
+	
+}
+
+void PspMemory::testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format) {
+	
+	bool mismatch = false;
+	PSP_INFO_PRINT("testing fastSwap...");
+	
+	uint32 shorts = debugBytes >> 1;
+
+	for (uint32 i = 0; i < shorts; i++) {
+		if (debugDst[i] != format.swapRedBlue16(debugSrc[i])) {
+			if (!mismatch) {
+				PSP_INFO_PRINT("**** mismatch in swap! ****\n");
+				PSP_INFO_PRINT("dst[%p], src[%p], bytes[%u]\n", debugDst, debugSrc, debugBytes);
+				mismatch = true;
+			}
+			PSP_INFO_PRINT("[%d]%x!=%x ", i<<1, format.swapRedBlue16(debugSrc[i]), debugDst[i]);
+		}
+	}
+	if (mismatch) {
+		PSP_INFO_PRINT("\n");
+	} else {
+		PSP_INFO_PRINT("ok\n");
+	}	
+}
+
+
+void PspMemory::copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes) {
+	PSP_DEBUG_PRINT("copy32Aligned(): dst32[%p], src32[%p], bytes[%d]\n", dst32, src32, bytes);
+
+	int words8 = bytes >> 5;
+	
+	// try blocks of 8 words at a time
+	if (words8) {
+		while (words8--) {
+			uint32 a, b, c, d;
+			a = src32[0];
+			b = src32[1];
+			c = src32[2];
+			d = src32[3];
+			dst32[0] = a;
+			dst32[1] = b;
+			dst32[2] = c;
+			dst32[3] = d;
+			a = src32[4];
+			b = src32[5];
+			c = src32[6];
+			d = src32[7];
+			dst32[4] = a;
+			dst32[5] = b;
+			dst32[6] = c;
+			dst32[7] = d;
+			dst32 += 8;
+			src32 += 8;
+		}				
+	}
+	
+	int words4 = (bytes & 0x1F) >> 4;
+	
+	// try blocks of 4 words at a time
+	if (words4) {
+		uint32 a, b, c, d;
+		a = src32[0];
+		b = src32[1];
+		c = src32[2];
+		d = src32[3];
+		dst32[0] = a;
+		dst32[1] = b;
+		dst32[2] = c;
+		dst32[3] = d;
+		dst32 += 4;
+		src32 += 4;
+	}
+	
+	int bytesLeft = (bytes & 0xF);	// only look at bytes left after we did the above
+	int wordsLeft = bytesLeft >> 2;
+	
+	// now just do single words
+	while (wordsLeft) {
+		*dst32++ = *src32++;
+		wordsLeft--;
+	}
+
+	bytesLeft = bytes & 0x3;	// get remaining bytes
+
+	PSP_DEBUG_PRINT("bytesLeft[%d]\n", bytesLeft);
+
+	byte *dst = (byte *)dst32;
+	byte *src = (byte *)src32;
+	
+	while (bytesLeft--) {
+		*dst++ = *src++;
+	}
+}
+
+void PspMemory::swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format) {
+	DEBUG_ENTER_FUNC();
+	int words4 = bytes >> 4;
+	
+	// try blocks of 4 words at a time
+	while (words4--) {
+		uint32 a, b, c, d;
+		a = format.swapRedBlue32(src32[0]);
+		b = format.swapRedBlue32(src32[1]);
+		c = format.swapRedBlue32(src32[2]);
+		d = format.swapRedBlue32(src32[3]);
+		dst32[0] = a;
+		dst32[1] = b;
+		dst32[2] = c;
+		dst32[3] = d;
+		dst32 += 4;
+		src32 += 4;
+	}
+
+	uint32 bytesLeft = bytes & 0xF;
+	uint32 words = bytesLeft >> 2;
+	
+	// now just do words
+	while (words--) {
+		*dst32++ = format.swapRedBlue32(*src32++);
+	}	
+
+	bytesLeft = bytes & 0x3;
+	
+	if (bytesLeft) {	// for swap, can only be 1 short left
+		*((uint16 *)dst32) = format.swapRedBlue16(*((uint16 *)src32));
+	}
+}
+
+
+// More challenging -- need to shift
+// Assume dst is aligned
+void PspMemory::copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc) {
+	PSP_DEBUG_PRINT("copy32Misaligned: dst32[%p], src[%p], bytes[%d], alignSrc[%d]\n", dst32, src, bytes, alignSrc);
+	
+	uint32 *src32 = (uint32 *)(((uint32)src) & 0xFFFFFFFC);	// remove misalignment
+	uint32 offset;
+	
+	switch (alignSrc) {
+	case 1:
+		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 8, 24);
+		break;
+	case 2:
+		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 16, 16);
+		break;
+	default: /* 3 */
+		offset = misaligned32Detail(dst32, src32, bytes, alignSrc, 24, 8);
+		break;
+	}
+	
+	uint32 remainingBytes = bytes & 3;
+	
+	if (remainingBytes) {
+		byte *dst = (byte *)dst32;
+		src += offset;
+		dst += offset;
+		copy8(dst, src, remainingBytes);
+	}	
+}
+
+// returns offset in dst
+uint32 PspMemory::misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue) {
+	uint32 *origDst32 = dst32;
+	register uint32 dstWord, srcWord;
+	
+	PSP_DEBUG_PRINT("misaligned32Detail(): alignSrc[%d], dst32[%p], src32[%p], bytes[%d]\n", alignSrc, dst32, src32, bytes);
+	
+	// Try to do groups of 4 words
+	uint32 words4 = bytes >> 4;
+	
+	srcWord = src32[0];
+
+	while (words4--) {
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[1];
+		dstWord |= srcWord << lastShiftValue;
+		dst32[0] = dstWord;
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[2];
+		dstWord |= srcWord << lastShiftValue;
+		dst32[1] = dstWord;
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[3];
+		dstWord |= srcWord << lastShiftValue;
+		dst32[2] = dstWord;
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[4];
+		dstWord |= srcWord << lastShiftValue;
+		dst32[3] = dstWord;
+		src32 += 4;
+		dst32 += 4;
+	}
+	
+	uint32 words = (bytes & 0xF) >> 2;
+	
+	// we read one word ahead of what we write
+	// setup the first read
+	if (words) {
+		src32++;	// we already loaded the value, so just increment
+		
+		while (words--) {
+			dstWord = srcWord >> shiftValue;
+			srcWord = *src32++;
+			dstWord |= srcWord << lastShiftValue;
+			*dst32++ = dstWord;
+		}
+	}
+	
+	return (byte *)dst32 - (byte *)origDst32;
+}
+
+// More challenging -- need to shift
+// We assume dst is aligned
+void PspMemory::swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
+	DEBUG_ENTER_FUNC();
+
+	const uint32 shiftValue = 16;
+	uint32 *src32 = (uint32 *)(((uint32)src16) & 0xFFFFFFFC);	// remove misalignment
+	
+	// Try to do groups of 4 words
+	uint32 words4 = bytes >> 4;
+	uint32 srcWord = src32[0];	// preload
+
+	while (words4--) {
+		uint32 dstWord = srcWord >> shiftValue;
+		srcWord = src32[1];
+		dstWord |= srcWord << shiftValue;
+		dst32[0] = format.swapRedBlue32(dstWord);
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[2];
+		dstWord |= srcWord << shiftValue;
+		dst32[1] = format.swapRedBlue32(dstWord);
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[3];
+		dstWord |= srcWord << shiftValue;
+		dst32[2] = format.swapRedBlue32(dstWord);
+		dstWord = srcWord >> shiftValue;
+		srcWord = src32[4];
+		dstWord |= srcWord << shiftValue;
+		dst32[3] = format.swapRedBlue32(dstWord);
+		src32 += 4;
+		dst32 += 4;
+	}
+	
+	uint32 words = (bytes & 0xF) >> 2;
+	
+	// we read one word ahead of what we write
+	// setup the first read
+	if (words) {
+		//srcWord = *src32++;	// don't need this. already loaded
+		src32++;	// we already have the value loaded in
+		
+		while (words--) {
+			uint32 dstWord = srcWord >> shiftValue;
+			srcWord = *src32++;
+			dstWord |= srcWord << shiftValue;
+			*dst32++ = format.swapRedBlue32(dstWord);
+		}
+	}
+	
+	uint32 bytesLeft = bytes & 3;
+	
+	if (bytesLeft) {	// for swap, can only be 1 short left
+		*((uint16 *)dst32) = format.swapRedBlue16((uint16)(srcWord >> shiftValue));
+	}
+}
+
+inline void PspMemory::copy16(uint16 *dst16, const uint16 *src16, uint32 bytes) {
+	PSP_DEBUG_PRINT("copy16(): dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes);
+	
+	uint32 shorts = bytes >> 1;
+	uint32 remainingBytes = bytes & 1;
+
+	for (; shorts > 0 ; shorts--) {
+		*dst16++ = *src16++;
+	}
+	if (remainingBytes)
+		*(byte *)dst16 = *(byte *)src16;
+}
+
+// Class VramAllocator -----------------------------------
+
+DECLARE_SINGLETON(VramAllocator)
+
+//#define __PSP_DEBUG_FUNCS__	/* For debugging the stack */
+//#define __PSP_DEBUG_PRINT__
+
+#include "backends/platform/psp/trace.h"
+
+
+void *VramAllocator::allocate(int32 size, bool smallAllocation /* = false */) {
+	DEBUG_ENTER_FUNC();
+	assert(size > 0);
+
+	byte *lastAddress = smallAllocation ? (byte *)VRAM_SMALL_ADDRESS : (byte *)VRAM_START_ADDRESS;
+	Common::List<Allocation>::iterator i;
+
+	// Find a block that fits, starting from the beginning
+	for (i = _allocList.begin(); i != _allocList.end(); ++i) {
+		byte *currAddress = (*i).address;
+
+		if (currAddress - lastAddress >= size) // We found a match
+			break;
+
+		if ((*i).getEnd() > lastAddress)
+			lastAddress = (byte *)(*i).getEnd();
+	}
+
+	if (lastAddress + size > (byte *)VRAM_END_ADDRESS) {
+		PSP_DEBUG_PRINT("No space for allocation of %d bytes. %d bytes already allocated.\n",
+		                size, _bytesAllocated);
+		return NULL;
+	}
+
+	_allocList.insert(i, Allocation(lastAddress, size));
+	_bytesAllocated += size;
+
+	PSP_DEBUG_PRINT("Allocated in VRAM, size %u at %p.\n", size, lastAddress);
+	PSP_DEBUG_PRINT("Total allocated %u, remaining %u.\n", _bytesAllocated, (2 * 1024 * 1024) - _bytesAllocated);
+
+	return lastAddress;
+}
+
+// Deallocate a block from VRAM
+void VramAllocator::deallocate(void *address) {
+	DEBUG_ENTER_FUNC();
+	address = (byte *)CACHED(address);	// Make sure all addresses are the same
+
+	Common::List<Allocation>::iterator i;
+
+	// Find the Allocator to deallocate
+	for (i = _allocList.begin(); i != _allocList.end(); ++i) {
+		if ((*i).address == address) {
+			_bytesAllocated -= (*i).size;
+			_allocList.erase(i);
+			PSP_DEBUG_PRINT("Deallocated address[%p], size[%u]\n", (*i).address, (*i).size);
+			return;
+		}
+	}
+
+	PSP_DEBUG_PRINT("Address[%p] not allocated.\n", address);
+}

Modified: scummvm/trunk/backends/platform/psp/memory.h
===================================================================
--- scummvm/trunk/backends/platform/psp/memory.h	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/memory.h	2010-07-18 07:03:14 UTC (rev 50982)
@@ -1,131 +1,132 @@
-
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
- * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
- *
- */
-
-#ifndef PSP_MEMORY_H
-#define PSP_MEMORY_H
-
-#include "backends/platform/psp/psppixelformat.h"
-#include "common/list.h"
-
-#define UNCACHED(x)		((byte *)(((uint32)(x)) | 0x40000000))	/* make an uncached access */
-#define CACHED(x)		((byte *)(((uint32)(x)) & 0xBFFFFFFF))	/* make an uncached access into a cached one */
-
-#define MIN_AMOUNT_FOR_COMPLEX_COPY  8
-#define MIN_AMOUNT_FOR_MISALIGNED_COPY 8
-
-//#define __PSP_DEBUG_PRINT__
-
-#include "backends/platform/psp/trace.h"
-
-/**
- *	Class that does memory copying and swapping if needed
- */
-class PspMemory {
-private:
-	static void testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes);
-	static void copy(byte *dst, const byte *src, uint32 bytes);
-	static void swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
-	static void copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes);
-	static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format);
-	static void copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc);
-	static uint32 misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue);
-	static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
-	static void copy16(uint16 *dst, const uint16 *src, uint32 bytes);
-
-	// For swapping, we know that we have multiples of 16 bits
-	static void swap16(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
-		PSP_DEBUG_PRINT("swap16 called with dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes);
-		uint32 shorts = bytes >> 1;
-
-		for (; shorts > 0 ; shorts--) {
-			*dst16++ = format.swapRedBlue16(*src16++);
-		}
-	}
-	
-	static void copy8(byte *dst, const byte *src, uint32 bytes) {
-		PSP_DEBUG_PRINT("copy8 called with dst[%p], src[%p], bytes[%d]\n", dst, src, bytes);
-		while (bytes--) {
-			*dst++ = *src++;
-		}
-	}
-
-public:	
-	// This is the interface to the outside world
-	static void fastCopy(byte *dst, const byte *src, uint32 bytes) {
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) {
-			copy8(dst, src, bytes);
-		} else {	// go to more powerful copy
-			copy(dst, src, bytes);
-		}
-	}
-
-	static void fastSwap(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat &format) {
-		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY * 2) {
-			swap16((uint16 *)dst, (uint16 *)src, bytes, format);
-		} else {	// go to more powerful copy
-			swap((uint16 *)dst, (uint16 *)src, bytes, format);
-		}
-	}
-};
-
-/**
- *	Class that allocates memory in the VRAM
- */
-class VramAllocator : public Common::Singleton<VramAllocator> {
-public:
-	VramAllocator() : _bytesAllocated(0) {}
-	void *allocate(int32 size, bool smallAllocation = false);	// smallAllocation e.g. palettes
-	void deallocate(void *pointer);
-
-	static inline bool isAddressInVram(void *address) {
-		if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
-			return true;
-		return false;
-	}
-
-
-private:
-	/**
-	 *	Used to allocate in VRAM
-	 */
-	struct Allocation {
-		byte *address;
-		uint32 size;
-		void *getEnd() { return address + size; }
-		Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
-		Allocation() : address(0), size(0) {}
-	};
-
-	enum {
-		VRAM_START_ADDRESS = 0x04000000,
-		VRAM_END_ADDRESS   = 0x04200000,
-		VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4 * 1024)	// 4K in the end for small allocations
-	};
-	Common::List <Allocation> _allocList;		// List of allocations
-	uint32 _bytesAllocated;
-};
-
-#endif /* PSP_MEMORY_H */
+
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/backends/platform/psp/osys_psp.cpp $
+ * $Id: osys_psp.cpp 46126 2009-11-24 14:18:46Z fingolfin $
+ *
+ */
+
+#ifndef PSP_MEMORY_H
+#define PSP_MEMORY_H
+
+#include "backends/platform/psp/psppixelformat.h"
+#include "common/list.h"
+
+#define UNCACHED(x)		((byte *)(((uint32)(x)) | 0x40000000))	/* make an uncached access */
+#define CACHED(x)		((byte *)(((uint32)(x)) & 0xBFFFFFFF))	/* make an uncached access into a cached one */
+
+#define MIN_AMOUNT_FOR_COMPLEX_COPY  8
+#define MIN_AMOUNT_FOR_MISALIGNED_COPY 8
+
+//#define __PSP_DEBUG_PRINT__
+
+#include "backends/platform/psp/trace.h"
+
+/**
+ *	Class that does memory copying and swapping if needed
+ */
+class PspMemory {
+private:
+	static void testCopy(const byte *debugDst, const byte *debugSrc, uint32 debugBytes);
+	static void testSwap(const uint16 *debugDst, const uint16 *debugSrc, uint32 debugBytes, PSPPixelFormat &format);
+	static void copy(byte *dst, const byte *src, uint32 bytes);
+	static void swap(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
+	static void copy32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes);
+	static void swap32Aligned(uint32 *dst32, const uint32 *src32, uint32 bytes, PSPPixelFormat &format);
+	static void copy32Misaligned(uint32 *dst32, const byte *src, uint32 bytes, uint32 alignSrc);
+	static uint32 misaligned32Detail(uint32 *dst32, uint32 *src32, uint32 bytes, uint32 alignSrc, const uint32 shiftValue, const uint32 lastShiftValue);
+	static void swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format);
+	static void copy16(uint16 *dst, const uint16 *src, uint32 bytes);
+
+	// For swapping, we know that we have multiples of 16 bits
+	static void swap16(uint16 *dst16, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) {
+		PSP_DEBUG_PRINT("swap16 called with dst16[%p], src16[%p], bytes[%d]\n", dst16, src16, bytes);
+		uint32 shorts = bytes >> 1;
+
+		while (shorts--) {
+			*dst16++ = format.swapRedBlue16(*src16++);
+		}
+	}
+	
+	static void copy8(byte *dst, const byte *src, uint32 bytes) {
+		PSP_DEBUG_PRINT("copy8 called with dst[%p], src[%p], bytes[%d]\n", dst, src, bytes);
+		while (bytes--) {
+			*dst++ = *src++;
+		}
+	}
+
+public:	
+	// This is the interface to the outside world
+	static void fastCopy(byte *dst, const byte *src, uint32 bytes) {
+		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) {
+			copy8(dst, src, bytes);
+		} else {	// go to more powerful copy
+			copy(dst, src, bytes);
+		}
+	}
+
+	static void fastSwap(byte *dst, const byte *src, uint32 bytes, PSPPixelFormat &format) {
+		if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY * 2) {
+			swap16((uint16 *)dst, (uint16 *)src, bytes, format);
+		} else {	// go to more powerful copy
+			swap((uint16 *)dst, (uint16 *)src, bytes, format);
+		}
+	}
+};
+
+/**
+ *	Class that allocates memory in the VRAM
+ */
+class VramAllocator : public Common::Singleton<VramAllocator> {
+public:
+	VramAllocator() : _bytesAllocated(0) {}
+	void *allocate(int32 size, bool smallAllocation = false);	// smallAllocation e.g. palettes
+	void deallocate(void *pointer);
+
+	static inline bool isAddressInVram(void *address) {
+		if ((uint32)(CACHED(address)) >= VRAM_START_ADDRESS && (uint32)(CACHED(address)) < VRAM_END_ADDRESS)
+			return true;
+		return false;
+	}
+
+
+private:
+	/**
+	 *	Used to allocate in VRAM
+	 */
+	struct Allocation {
+		byte *address;
+		uint32 size;
+		void *getEnd() { return address + size; }
+		Allocation(void *Address, uint32 Size) : address((byte *)Address), size(Size) {}
+		Allocation() : address(0), size(0) {}
+	};
+
+	enum {
+		VRAM_START_ADDRESS = 0x04000000,
+		VRAM_END_ADDRESS   = 0x04200000,
+		VRAM_SMALL_ADDRESS = VRAM_END_ADDRESS - (4 * 1024)	// 4K in the end for small allocations
+	};
+	Common::List <Allocation> _allocList;		// List of allocations
+	uint32 _bytesAllocated;
+};
+
+#endif /* PSP_MEMORY_H */

Modified: scummvm/trunk/backends/platform/psp/psp_main.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/psp_main.cpp	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/psp_main.cpp	2010-07-18 07:03:14 UTC (rev 50982)
@@ -44,15 +44,13 @@
 #include "backends/plugins/psp/psp-provider.h"
 #include "backends/platform/psp/psppixelformat.h"
 #include "backends/platform/psp/osys_psp.h"
-#include "backends/platform/psp/tests.h"
+#include "backends/platform/psp/tests.h"	/* for unit/speed tests */
 #include "backends/platform/psp/trace.h"
 
 #ifdef ENABLE_PROFILING
 	#include <pspprof.h>
 #endif
 
-#define ENABLE_TESTS	/* to enable tests of PSP architecture */
-
 /**
  * Define the module info section
  *
@@ -156,7 +154,7 @@
 #undef main
 int main(void) {
 	//change clock rate to 333mhz
-	scePowerSetClockFrequency(222, 222, 111);
+	scePowerSetClockFrequency(333, 333, 166);
 
 	PowerManager::instance();	// Setup power manager
 
@@ -172,10 +170,11 @@
 	PluginManager::instance().addPluginProvider(new PSPPluginProvider());
 #endif
 
-#ifdef ENABLE_TESTS
+/* unit/speed tests */
+#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS)	
 	PSP_INFO_PRINT("running tests\n");
-	tests();
-	sceKernelSleepThread();
+	psp_tests();
+	sceKernelSleepThread();	// that's it. That's all we're doing
 #endif
 	
 	int res = scummvm_main(argc, argv);

Modified: scummvm/trunk/backends/platform/psp/tests.cpp
===================================================================
--- scummvm/trunk/backends/platform/psp/tests.cpp	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/tests.cpp	2010-07-18 07:03:14 UTC (rev 50982)
@@ -23,6 +23,13 @@
  *
  */
 
+// PSP speed and unit tests. Activate in tests.h 
+// You may also want to build without any engines. 
+ 
+#include "backends/platform/psp/tests.h"
+
+#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS)	
+ 
 #include "common/scummsys.h"
 #include <pspiofilemgr_fcntl.h>
 #include <pspiofilemgr_stat.h>
@@ -51,7 +58,36 @@
   
 #include "backends/platform/psp/trace.h" 
 
-void test_ticks() {
+class PspSpeedTests {
+public:
+	void tickSpeed();
+	void getMicrosSpeed();
+	void seekSpeed();
+	void msReadSpeed();
+	void threadFunctionsSpeed();
+	void semaphoreSpeed(); 
+	static int threadFunc(SceSize args, void *argp);
+	void semaphoreManyThreadSpeed();
+	void fastCopySpeed();
+	
+private:
+	enum {
+		MEMCPY_BUFFER_SIZE = 8192
+	};
+	static PspSemaphore _sem;	// semaphore
+
+	void readAndTime(uint32 bytes, char *buffer, FILE *file);
+	void seekAndTime(int bytes, int origin, FILE *file);
+	void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes);
+	void fastCopyDifferentSizes(byte *dst, byte *src);
+	int getThreadIdSpeed();
+	void getPrioritySpeed();
+	void changePrioritySpeed(int id, int priority);
+};
+
+PspSemaphore PspSpeedTests::_sem(0);
+
+void PspSpeedTests::tickSpeed() {
 	uint32 ticksPerSecond = sceRtcGetTickResolution();
 	PSP_INFO_PRINT("ticksPerSecond[%d]\n", ticksPerSecond);
 
@@ -75,7 +111,7 @@
 	PSP_INFO_PRINT("time2, year[%d] month[%d] day[%d] hour[%d] minutes[%d] seconds[%d] us[%d]\n", time2.year, time2.month, time2.day, time2.hour, time2.minutes, time2.seconds, time2.microseconds);
 }
 
-void test_getMicros() {
+void PspSpeedTests::getMicrosSpeed() {
 	uint32 time1, time2, time3, time4;
 	time1 = PspRtc::instance().getMicros();
 	time2 = PspRtc::instance().getMicros();
@@ -85,7 +121,7 @@
 	PSP_INFO_PRINT("getMicros() times: %d, %d, %d\n", time4-time3, time3-time2, time2-time1);
 }
 
-void read_and_time(uint32 bytes, char *buffer, FILE *file) {
+void PspSpeedTests::readAndTime(uint32 bytes, char *buffer, FILE *file) {
 	uint32 time1 = PspRtc::instance().getMicros();
 	// test minimal read
 	fread(buffer, bytes, 1, file);
@@ -101,18 +137,8 @@
 	Reading 50 byte takes 8us / 11
 	Reading 100 byte takes 8us / 11
 	Reading 1000 byte takes 915us / 1131
-	Reading 1000 byte takes 911us
-	Reading 1000 byte takes 914us
-	Reading 1000 byte takes 943us
-	Reading 1000 byte takes 915us
-	Reading 1000 byte takes 923us
-	Reading 1000 byte takes 22us
-	Reading 1000 byte takes 916us 
-	Reading 1000 byte takes 913us / 1,120
-	Reading 1000 byte takes 909us / 1,122
 	Reading 2000 byte takes 1806us / 2,284
 	Reading 3000 byte takes 2697us / 3,374
-	Reading 4000 byte takes 3652us / 4,592
 	Reading 5000 byte takes 4551us / 5,544
 	Reading 6000 byte takes 5356us / 6,676
 	Reading 7000 byte takes 6800us / 8,358
@@ -120,47 +146,40 @@
 	Reading 9000 byte takes 6782us / 8,563
 	Reading 10000 byte takes 8497us / 10,631
 	Reading 30000 byte takes 25995us / 32,473
-	Reading 50000 byte takes 42467us / 52,893
 	Reading 80000 byte takes 68457us / 85,291
 	Reading 100000 byte takes 85103us / 106,163
-	Reading 500000 byte takes 427337us / 531,679
-	Reading 1000000 byte takes 854831us / 1,063,107
 */
 // Function to test the impact of MS reads
 // These tests can't be done from shell - the cache screws them up
-void test_ms_reads() {
+void PspSpeedTests::msReadSpeed() {
 	FILE *file;
 	file = fopen("ms0:/psp/music/track1.mp3", "r");
 
 	char *buffer = (char *)malloc(2 * 1024 * 1024);
 	
-	read_and_time(1, buffer, file);
-	read_and_time(10, buffer, file);
-	read_and_time(50, buffer, file);
-	read_and_time(100, buffer, file);
-	for (int i = 0; i< 10; i++)
-		read_and_time(1000, buffer, file);
-	read_and_time(2000, buffer, file);
-	read_and_time(3000, buffer, file);
-	read_and_time(4000, buffer, file);
-	read_and_time(5000, buffer, file);
-	read_and_time(6000, buffer, file);
-	read_and_time(7000, buffer, file);
-	read_and_time(8000, buffer, file);
-	read_and_time(9000, buffer, file);	
-	read_and_time(10000, buffer, file);
-	read_and_time(30000, buffer, file);
-	read_and_time(50000, buffer, file);
-	read_and_time(80000, buffer, file);
-	read_and_time(100000, buffer, file);
-	read_and_time(500000, buffer, file);
-	read_and_time(1000000, buffer, file);	
+	readAndTime(1, buffer, file);
+	readAndTime(10, buffer, file);
+	readAndTime(50, buffer, file);
+	readAndTime(100, buffer, file);
+	readAndTime(1000, buffer, file);
+	readAndTime(2000, buffer, file);
+	readAndTime(3000, buffer, file);
+	readAndTime(5000, buffer, file);
+	readAndTime(6000, buffer, file);
+	readAndTime(7000, buffer, file);
+	readAndTime(8000, buffer, file);
+	readAndTime(9000, buffer, file);	
+	readAndTime(10000, buffer, file);
+	readAndTime(30000, buffer, file);
+	readAndTime(50000, buffer, file);
+	readAndTime(80000, buffer, file);
+	readAndTime(100000, buffer, file);
 	
 	fclose(file);
 	free(buffer);	
 }
  
-void seek_and_time(int bytes, int origin, FILE *file) {
+void PspSpeedTests::seekAndTime(int bytes, int origin, FILE *file) {
 	char buffer[1000];
 	
 	uint32 time1 = PspRtc::instance().getMicros();
@@ -202,26 +221,26 @@
 Reading 1000 bytes took 110us
 */
 
-void test_seeks() {
+void PspSpeedTests::seekSpeed() {
 	FILE *file;
 	file = fopen("ms0:/psp/music/track1.mp3", "r");
 
-	seek_and_time(0, SEEK_SET, file);
-	seek_and_time(5, SEEK_SET, file);
-	seek_and_time(1000, SEEK_SET, file);
-	seek_and_time(100, SEEK_SET, file);
-	seek_and_time(10000, SEEK_SET, file);
-	seek_and_time(-5, SEEK_CUR, file);
-	seek_and_time(-100, SEEK_CUR, file);
-	seek_and_time(100, SEEK_CUR, file);
-	seek_and_time(0, SEEK_END, file);
-	seek_and_time(-10000, SEEK_END, file);
+	seekAndTime(0, SEEK_SET, file);
+	seekAndTime(5, SEEK_SET, file);
+	seekAndTime(1000, SEEK_SET, file);
+	seekAndTime(100, SEEK_SET, file);
+	seekAndTime(10000, SEEK_SET, file);
+	seekAndTime(-5, SEEK_CUR, file);
+	seekAndTime(-100, SEEK_CUR, file);
+	seekAndTime(100, SEEK_CUR, file);
+	seekAndTime(0, SEEK_END, file);
+	seekAndTime(-10000, SEEK_END, file);
 
 	fclose(file);
 }
 
 // 222: 5-7us
-int testGetThreadId() {
+int PspSpeedTests::getThreadIdSpeed() {
 	uint32 time1 = PspRtc::instance().getMicros();
 	int threadId = sceKernelGetThreadId();
 	uint32 time2 = PspRtc::instance().getMicros();
@@ -232,7 +251,7 @@
 }
 
 // 222: 4-5us
-void testGetPriority() {
+void PspSpeedTests::getPrioritySpeed() {
 	uint32 time1 = PspRtc::instance().getMicros();
 	int priority = sceKernelGetThreadCurrentPriority();
 	uint32 time2 = PspRtc::instance().getMicros();
@@ -241,7 +260,7 @@
 }
 
 // 222: 9-10us
-void testChangePriority(int id, int priority) {
+void PspSpeedTests::changePrioritySpeed(int id, int priority) {
 	uint32 time1 = PspRtc::instance().getMicros();
 	sceKernelChangeThreadPriority(id, priority);
 	uint32 time2 = PspRtc::instance().getMicros();
@@ -249,15 +268,16 @@
 	PSP_INFO_PRINT("Changing thread priority to %d for id %d took %dus\n", priority, id, time2-time1);
 }
 
-void test_thread() {
+void PspSpeedTests::threadFunctionsSpeed() {
+	// very unscientific -- just ballpark
 	int id;
-	id = testGetThreadId();
-	testGetThreadId();
-	testGetPriority();
-	testGetPriority();
-	testChangePriority(id, 30);
-	testChangePriority(id, 35);
-	testChangePriority(id, 25);
+	id = getThreadIdSpeed();
+	getThreadIdSpeed();
+	getPrioritySpeed();
+	getPrioritySpeed();
+	changePrioritySpeed(id, 30);
+	changePrioritySpeed(id, 35);
+	changePrioritySpeed(id, 25);
 	
 	// test context switch time
 	for (int i=0; i<10; i++) {
@@ -268,260 +288,111 @@
 	}	
 }
  
-int test_mem_read(uint32 words) {
-	uint32 __attribute__((aligned(64))) buffer[1024];
-	register uint32 r = 0;
+void PspSpeedTests::semaphoreSpeed() { 
+	PspSemaphore sem(1);
 	
-	// uncached
-	uint32 *pBuffer = (uint32 *)UNCACHED(buffer);
-
 	uint32 time1 = PspRtc::instance().getMicros();
 	
-	for (int i=0; i<words; i++) {
-		r += *pBuffer;
-		pBuffer++;
-	}
-	uint32 time2 = PspRtc::instance().getMicros();
+	sem.take();
 	
-	PSP_INFO_PRINT("read of %d words from uncached took %dus\n", words, time2-time1);
-	
-	// flush cache
-	sceKernelDcacheWritebackInvalidateAll();
-	
-	// cached
-	pBuffer = buffer;
-
-	time1 = PspRtc::instance().getMicros();
-	
-	for (int i=0; i<words; i++) {
-		r += *pBuffer;
-		pBuffer++;
-	}
-	time2 = PspRtc::instance().getMicros();
-	
-	PSP_INFO_PRINT("read of %d words from cached took %dus\n", words, time2-time1);
-
-	return r;
-} 
-
-void test_mem_write(uint32 words) {
-	uint32 __attribute__((aligned(64))) buffer[1024];
-	register uint32 r = 0;
-	
-	// uncached
-	uint32 *pBuffer = (uint32 *)UNCACHED(buffer);
-
-	uint32 time1 = PspRtc::instance().getMicros();
-	
-	for (int i=0; i<words; i++) {
-		*pBuffer = r;
-		pBuffer++;
-	}
 	uint32 time2 = PspRtc::instance().getMicros();
 	
-	PSP_INFO_PRINT("write of %d words to uncached took %dus\n", words, time2-time1);
-	
-	// flush cache
-	sceKernelDcacheWritebackInvalidateAll();
-
-	// cached
-	pBuffer = buffer;
-	
-	time1 = PspRtc::instance().getMicros();
-	
-	for (int i=0; i<words; i++) {
-		*pBuffer = r;
-		pBuffer++;
-	}
-	time2 = PspRtc::instance().getMicros();
-	
-	PSP_INFO_PRINT("writeof %d words to cached took %dus\n", words, time2-time1);	
-}
-
-/*
-read of 1 words from uncached took 2us
-read of 1 words from cached took 3us
-read of 64 words from uncached took 12us
-read of 64 words from cached took 6us
-read of 65 words from uncached took 12us
-read of 65 words from cached took 6us
-read of 128 words from uncached took 24us
-read of 128 words from cached took 8us
-read of 1024 words from uncached took 168us
-read of 1024 words from cached took 50us
-write of 1 words to uncached took 2us
-writeof 1 words to cached took 2us
-write of 64 words to uncached took 4us
-writeof 64 words to cached took 5us
-write of 65 words to uncached took 5us
-writeof 65 words to cached took 5us
-write of 128 words to uncached took 5us
-writeof 128 words to cached took 8us
-write of 1024 words to uncached took 32us
-writeof 1024 words to cached took 45us
-*/ 
-void test_memory() {
-	test_mem_read(1);
-	test_mem_read(64);
-	test_mem_read(65);
-	test_mem_read(128);
-	test_mem_read(1024);
-	test_mem_write(1);
-	test_mem_write(64);
-	test_mem_write(65);
-	test_mem_write(128);
-	test_mem_write(1024);	
-}
-
-void test_semaphore() { 
-	// create semaphore
-	int sem = sceKernelCreateSema("testSemaphore", 0, 1, 1, 0);
-	
-	uint32 time1 = PspRtc::instance().getMicros();
-	
-	sceKernelWaitSema(sem, 1, 0);
-	
-	uint32 time2 = PspRtc::instance().getMicros();
-	
 	PSP_INFO_PRINT("taking semaphore took %d us\n", time2-time1);	// 10us
 	
 	uint32 time3 = PspRtc::instance().getMicros();
 	
-	sceKernelSignalSema(sem, 1);
+	sem.give();
 	
 	uint32 time4 = PspRtc::instance().getMicros();
 	PSP_INFO_PRINT("releasing semaphore took %d us\n", time4-time3);	//10us-55us
 }
 
-int globalSem = 0;	// semaphore
-
-int threadFunc(SceSize args, void *argp) {
+int PspSpeedTests::threadFunc(SceSize args, void *argp) {
 	PSP_INFO_PRINT("thread %x created.\n", sceKernelGetThreadId());
 	
-	sceKernelWaitSema(globalSem, 1, 0);	// grab semaphore
+	_sem.take();
+	
 	PSP_INFO_PRINT("grabbed semaphore. Quitting thread\n");
 	
 	return 0;
 }
 
-void test_semaphore_many_threads() {	
-	globalSem = sceKernelCreateSema("testSemaphore2", 0, 0, 255, 0);
-
+void PspSpeedTests::semaphoreManyThreadSpeed() {	
+	
 	// create 4 threads
 	for (int i=0; i<4; i++) {
-		int thid = sceKernelCreateThread("my_thread", threadFunc, 0x18, 0x10000, THREAD_ATTR_USER, NULL);
+		int thid = sceKernelCreateThread("my_thread", PspSpeedTests::threadFunc, 0x18, 0x10000, THREAD_ATTR_USER, NULL);
 		sceKernelStartThread(thid, 0, 0);
 	}
 		
 	PSP_INFO_PRINT("main thread. created threads\n");
 
-	SceKernelSemaInfo info;
-	int waitingThreads = 0;
-	while (waitingThreads < 4) {
-		sceKernelReferSemaStatus(globalSem, &info);
-		waitingThreads = info.numWaitThreads;
-		PSP_INFO_PRINT("main thread: waiting threads[%d]\n", waitingThreads);
+	uint32 threads = _sem.numOfWaitingThreads();
+	while (threads < 4) {
+		threads = _sem.numOfWaitingThreads();
+		PSP_INFO_PRINT("main thread: waiting threads[%d]\n", threads);
 	}
 	
-	PSP_INFO_PRINT("main: semaphore value[%d]\n", info.currentCount);
-	PSP_INFO_PRINT("main thread: waiting threads[%d]\n", info.numWaitThreads);
+	PSP_INFO_PRINT("main: semaphore value[%d]\n", _sem.getValue());
+	PSP_INFO_PRINT("main thread: waiting threads[%d]\n", _sem.numOfWaitingThreads());
 	
-	sceKernelSignalSema(globalSem, 4);
+	_sem.give(4);
 }
 
-void test_sce_ms_reads() { 
-	SceUID file;
-	char *buffer = (char *)malloc(2 * 1024 * 1024);
-	{
-		// get file size
-		SceIoStat stat;
-		
-		uint32 time1 = PspRtc::instance().getMicros();
-		
-		sceIoGetstat("ms0:/psp/music/track1.mp3", &stat);
-		
-		uint32 time2 = PspRtc::instance().getMicros();
-		
-		PSP_INFO_PRINT("getting size of %lld took %d us\n", stat.st_size, time2-time1); // 3180 us before an open
-	}
-	{
-		// open file
-		uint32 time1 = PspRtc::instance().getMicros();
-
-		file = sceIoOpen("ms0:/psp/music/track1.mp3", PSP_O_RDONLY, 0777);
-		
-		uint32 time2 = PspRtc::instance().getMicros();
-		
-		PSP_INFO_PRINT("opening scefile took %d us\n", time2-time1);	// 3355us (or 1223us if already got size)
-	}
-	{
-		// get file size
-		SceIoStat stat;
-		
-		uint32 time1 = PspRtc::instance().getMicros();
-		
-		sceIoGetstat("ms0:/psp/music/track1.mp3", &stat);
-		
-		uint32 time2 = PspRtc::instance().getMicros();
-		
-		PSP_INFO_PRINT("getting size of %lld took %d us\n", stat.st_size, time2-time1); // 1223us after an open
-	}
-	{
-		uint32 time1 = PspRtc::instance().getMicros();
+void PspSpeedTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes) {
+	uint32 time1, time2;
+	uint32 fastcopyTime, memcpyTime;
+	const int iterations = 2000;
+	int intc;
 	
-		// asynchronous read
-		sceIoReadAsync(file, buffer, 100000);
-		
-		uint32 time2 = PspRtc::instance().getMicros();
-		
-		PSP_INFO_PRINT("async read of 100000 took %d us\n", time2-time1);  // 146us
-		
-		// poll for completion
-		SceInt64 result;
-		for (int i=0; i<10; i++) {
-			sceIoPollAsync(file, &result);
-			uint time3 = PspRtc::instance().getMicros();
-			PSP_INFO_PRINT("poll %d. result = %lld. Time = %d us.\n", i, result, time3-time1);
-			PspThread::delayMicros(100);
-		}	
+	intc = pspSdkDisableInterrupts();
 	
-	}
-	{
-		uint32 time1 = PspRtc::instance().getMicros();
-		sceIoClose(file);
-		uint32 time2 = PspRtc::instance().getMicros();
-		PSP_INFO_PRINT("file close took %d us\n", time2-time1);	// 230us
-	}
-	free(buffer);
+	time1 = PspRtc::instance().getMicros();
+	for (int i=0; i<iterations; i++) {
+		PspMemory::fastCopy(dst, src, bytes);
+	}	
+	time2 = PspRtc::instance().getMicros();
+	
+	pspSdkEnableInterrupts(intc);
+	
+	fastcopyTime = time2-time1;
+	
+	intc = pspSdkDisableInterrupts();
+	
+	time1 = PspRtc::instance().getMicros();
+	for (int i=0; i<iterations; i++) {
+		memcpy(dst, src, bytes);
+	}	
+	time2 = PspRtc::instance().getMicros();
+	
+	pspSdkEnableInterrupts(intc);
+	
+	memcpyTime = time2-time1;
+	
+	PSP_INFO_PRINT("%d bytes. memcpy[%d], fastcopy[%d]\n", bytes, memcpyTime, fastcopyTime);
 }
 
-#define MEMCPY_BUFFER_SIZE 4096
-
-void test_fastCopy_specific(byte *dst, byte *src, uint32 bytes) {
-	memset(dst, 0, bytes);
-	PspMemory::fastCopy(dst, src, bytes);
-	PSP_INFO_PRINT("\n");
+void PspSpeedTests::fastCopyDifferentSizes(byte *dst, byte *src) {
+	PSP_INFO_PRINT("\nsrc[%p], dst[%p]\n", src, dst);
+	fastCopySpecificSize(dst, src, 1);
+	fastCopySpecificSize(dst, src, 2);
+	fastCopySpecificSize(dst, src, 3);
+	fastCopySpecificSize(dst, src, 4);
+	fastCopySpecificSize(dst, src, 5);
+	fastCopySpecificSize(dst, src, 8);
+	fastCopySpecificSize(dst, src, 10);
+	fastCopySpecificSize(dst, src, 16);
+	fastCopySpecificSize(dst, src, 32);
+	fastCopySpecificSize(dst, src, 50);
+	fastCopySpecificSize(dst, src, 100);
+	fastCopySpecificSize(dst, src, 500);
+	fastCopySpecificSize(dst, src, 1024);
+	fastCopySpecificSize(dst, src, 2048);
 }
 
-void test_fastCopy_different_sizes(byte *dst, byte *src) {
-	test_fastCopy_specific(dst, src, 1);
-	test_fastCopy_specific(dst, src, 2);
-	test_fastCopy_specific(dst, src, 4);
-	test_fastCopy_specific(dst, src, 6);
-	test_fastCopy_specific(dst, src, 8);
-	test_fastCopy_specific(dst, src, 9);
-	test_fastCopy_specific(dst, src, 16);
-	test_fastCopy_specific(dst, src, 17);
-	test_fastCopy_specific(dst, src, 32);
-	test_fastCopy_specific(dst, src, 33);
-	test_fastCopy_specific(dst, src, 34);
-	test_fastCopy_specific(dst, src, 35);
-	test_fastCopy_specific(dst, src, 36);
-}
+void PspSpeedTests::fastCopySpeed() {
+	PSP_INFO_PRINT("running fastCopy speed test\n");
 
-void test_fastcopy() {
-	PSP_INFO_PRINT("running fastcopy test\n");
-
 	uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
 	uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
 	
@@ -536,84 +407,57 @@
 	
 	byte *bufferSrc = ((byte *)bufferSrc32);
 	byte *bufferDst = ((byte *)bufferDst32);
+
+	PSP_INFO_PRINT("\n\ndst and src cached: -----------------\n");
+	fastCopyDifferentSizes(bufferDst, bufferSrc);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc);
 	
-	//test_fastCopy_different_sizes(bufferDst, bufferSrc);
-	//test_fastCopy_different_sizes(bufferDst+1, bufferSrc+1);
-	//test_fastCopy_different_sizes(bufferDst+2, bufferSrc+2);
-	//test_fastCopy_different_sizes(bufferDst+3, bufferSrc+3);
-	//test_fastCopy_different_sizes(bufferDst, bufferSrc+1);
-	//test_fastCopy_different_sizes(bufferDst, bufferSrc+2);
-	//test_fastCopy_different_sizes(bufferDst, bufferSrc+3);
-	test_fastCopy_different_sizes(bufferDst+1, bufferSrc+2);
-	test_fastCopy_different_sizes(bufferDst+1, bufferSrc+3);
-	test_fastCopy_different_sizes(bufferDst+2, bufferSrc+1);
-	test_fastCopy_different_sizes(bufferDst+2, bufferSrc+3);
-	test_fastCopy_different_sizes(bufferDst+3, bufferSrc+1);
-	test_fastCopy_different_sizes(bufferDst+3, bufferSrc+2);	
+	PSP_INFO_PRINT("\n\ndst cached, src uncached: -----------------\n");
+	bufferSrc = UNCACHED(bufferSrc);
+	fastCopyDifferentSizes(bufferDst, bufferSrc);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc);
+
+	PSP_INFO_PRINT("\n\ndst uncached, src uncached: --------------\n");
+	bufferDst = UNCACHED(bufferDst);
+	fastCopyDifferentSizes(bufferDst, bufferSrc);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc);
 	
+	PSP_INFO_PRINT("\n\ndst uncached, src cached: -------------------\n");
+	bufferSrc = CACHED(bufferSrc);
+	fastCopyDifferentSizes(bufferDst, bufferSrc);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc);
+
+	
 	free(bufferSrc32);
 	free(bufferDst32);
 }
 
-void test_fastcopy_speed_specific(byte *dst, byte *src, uint32 bytes) {
-	byte *dstUncached = UNCACHED(dst);
-	byte *srcUncached = UNCACHED(src);
-//	byte *dstUncached = dst;
-//	byte *srcUncached = src;
-	
-	uint32 time1, time2;
-	const int iterations = 2000;
-	int intc;
-	
-	intc = pspSdkDisableInterrupts();
-	
-	time1 = PspRtc::instance().getMicros();
-	for (int i=0; i<iterations; i++) {
-		PspMemory::fastCopy(dstUncached, srcUncached, bytes);
-	}	
-	time2 = PspRtc::instance().getMicros();
-	
-	pspSdkEnableInterrupts(intc);
-	
-	PSP_INFO_PRINT("fastcppy() results: bytes[%d], iters[%d], time[%d]us\n",
-		bytes, iterations, time2-time1);
-	
-	intc = pspSdkDisableInterrupts();
-	
-	time1 = PspRtc::instance().getMicros();
-	for (int i=0; i<iterations; i++) {
-		memcpy(dstUncached, srcUncached, bytes);
-	}	
-	time2 = PspRtc::instance().getMicros();
-	
-	pspSdkEnableInterrupts(intc);
-	
-	PSP_INFO_PRINT("memcpy() results: bytes[%d], iters[%d], time[%d]us\n\n",
-		bytes, iterations, time2-time1);
+//-------Unit Tests -------------------------------
 
-}
+class PspUnitTests {
+public:
+	void testFastCopy();
 
-void test_fastcopy_speed_bunch(byte *dst, byte *src) {
-	PSP_INFO_PRINT("new test bunch ******************\n");
-	PSP_INFO_PRINT("src[%p], dst[%p]\n", src, dst);
-	test_fastcopy_speed_specific(dst, src, 1);
-	test_fastcopy_speed_specific(dst, src, 2);
-	test_fastcopy_speed_specific(dst, src, 3);
-	test_fastcopy_speed_specific(dst, src, 4);
-	test_fastcopy_speed_specific(dst, src, 5);
-	test_fastcopy_speed_specific(dst, src, 8);
-	test_fastcopy_speed_specific(dst, src, 10);
-	test_fastcopy_speed_specific(dst, src, 16);
-	test_fastcopy_speed_specific(dst, src, 32);
-	test_fastcopy_speed_specific(dst, src, 50);
-	test_fastcopy_speed_specific(dst, src, 100);
-	test_fastcopy_speed_specific(dst, src, 500);
-	test_fastcopy_speed_specific(dst, src, 1024);
-	test_fastcopy_speed_specific(dst, src, 2048);
-}
+private:
+	enum {
+		MEMCPY_BUFFER_SIZE = 8192
+	};
+	
+	void fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap = false);
+	void fastCopyDifferentSizes(byte *dst, byte *src, bool swap = false);
+};	
 
-void test_fastcopy_speed() {
-	PSP_INFO_PRINT("running fastcopy speed test\n");
+void PspUnitTests::testFastCopy() {
+	PSP_INFO_PRINT("running fastcopy unit test ***********\n");
+	PSP_INFO_PRINT("this test requires the test flag to be on in fastCopy\n\n");
 
 	uint32 *bufferSrc32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
 	uint32 *bufferDst32 = (uint32 *)memalign(16, MEMCPY_BUFFER_SIZE);
@@ -630,27 +474,92 @@
 	byte *bufferSrc = ((byte *)bufferSrc32);
 	byte *bufferDst = ((byte *)bufferDst32);
 	
-	test_fastcopy_speed_bunch(bufferDst, bufferSrc);
-	test_fastcopy_speed_bunch(bufferDst+1, bufferSrc+1);
-	test_fastcopy_speed_bunch(bufferDst, bufferSrc+1);
-	test_fastcopy_speed_bunch(bufferDst+1, bufferSrc);
+	fastCopyDifferentSizes(bufferDst, bufferSrc, true);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc+2, true);
+	fastCopyDifferentSizes(bufferDst+3, bufferSrc+3);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+2, true);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc, true);
+	fastCopyDifferentSizes(bufferDst, bufferSrc+3);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+2);
+	fastCopyDifferentSizes(bufferDst+1, bufferSrc+3);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+2, bufferSrc+3);
+	fastCopyDifferentSizes(bufferDst+3, bufferSrc+1);
+	fastCopyDifferentSizes(bufferDst+3, bufferSrc+2);	
 	
 	free(bufferSrc32);
 	free(bufferDst32);
 }
+	
+void PspUnitTests::fastCopyDifferentSizes(byte *dst, byte *src, bool swap) {
+	fastCopySpecificSize(dst, src, 1);
+	fastCopySpecificSize(dst, src, 2, swap);
+	fastCopySpecificSize(dst, src, 4, swap);
+	fastCopySpecificSize(dst, src, 6, swap);
+	fastCopySpecificSize(dst, src, 8, swap);
+	fastCopySpecificSize(dst, src, 9);
+	fastCopySpecificSize(dst, src, 10, swap);
+	fastCopySpecificSize(dst, src, 11);
+	fastCopySpecificSize(dst, src, 12, swap);
+	fastCopySpecificSize(dst, src, 13);
+	fastCopySpecificSize(dst, src, 14, swap);
+	fastCopySpecificSize(dst, src, 15);	
+	fastCopySpecificSize(dst, src, 16, swap);
+	fastCopySpecificSize(dst, src, 17);
+	fastCopySpecificSize(dst, src, 18, swap);
+	fastCopySpecificSize(dst, src, 19);
+	fastCopySpecificSize(dst, src, 20, swap);
+	fastCopySpecificSize(dst, src, 32, swap);
+	fastCopySpecificSize(dst, src, 33);
+	fastCopySpecificSize(dst, src, 34, swap);
+	fastCopySpecificSize(dst, src, 35);
+	fastCopySpecificSize(dst, src, 36, swap);
+	fastCopySpecificSize(dst, src, 50, swap);
+	fastCopySpecificSize(dst, src, 100, swap);
+	fastCopySpecificSize(dst, src, 500, swap);
+	fastCopySpecificSize(dst, src, 1000, swap);
+}
 
+void PspUnitTests::fastCopySpecificSize(byte *dst, byte *src, uint32 bytes, bool swap) {
+	memset(dst, 0, bytes);
+	PspMemory::fastCopy(dst, src, bytes);
+	
+	if (swap) {	// test swap also
+		memset(dst, 0, bytes);
+		
+		// pixelformat for swap
+		PSPPixelFormat format;
+		format.set(PSPPixelFormat::Type_4444, true);
+	
+		PspMemory::fastSwap(dst, src, bytes, format);
+	}	
+}
 
- void tests() {
+void psp_tests() {
 	PSP_INFO_PRINT("in tests\n");
-	//test_ticks();
-	//test_getMicros();
-	//test_ms_reads();
-	//test_seeks();
-	//test_thread();
-	//test_memory();
-	//test_sce_ms_reads();
-	//test_semaphore();	
-	//test_semaphore_many_threads();
-	//test_fastcopy();
-	test_fastcopy_speed();
+	
+#ifdef PSP_ENABLE_SPEED_TESTS
+	// Speed tests
+	PspSpeedTests speedTests;
+	speedTests.tickSpeed();
+	speedTests.getMicrosSpeed();
+	speedTests.msReadSpeed();
+	speedTests.seekSpeed();
+	speedTests.msReadSpeed();
+	speedTests.threadFunctionsSpeed();
+	speedTests.semaphoreSpeed();	
+	speedTests.semaphoreManyThreadSpeed();
+	speedTests.fastCopySpeed();
+#endif	
+	
+#ifdef PSP_ENABLE_UNIT_TESTS
+	// Unit tests
+	PspUnitTests unitTests;
+	
+	unitTests.testFastCopy();
+#endif	
 }	
+
+#endif /* (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS) */
\ No newline at end of file

Modified: scummvm/trunk/backends/platform/psp/tests.h
===================================================================
--- scummvm/trunk/backends/platform/psp/tests.h	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/tests.h	2010-07-18 07:03:14 UTC (rev 50982)
@@ -23,4 +23,14 @@
  *
  */
 
-extern void tests();
\ No newline at end of file
+#ifndef _PSP_TESTS_H_ 
+#define _PSP_TESTS_H_
+
+//#define PSP_ENABLE_UNIT_TESTS		// run unit tests
+//#define PSP_ENABLE_SPEED_TESTS		// run speed tests
+
+#if defined (PSP_ENABLE_UNIT_TESTS) || defined (PSP_ENABLE_SPEED_TESTS)	
+void psp_tests();
+#endif
+
+#endif /* _PSP_TESTS_H_ */
\ No newline at end of file

Modified: scummvm/trunk/backends/platform/psp/trace.h
===================================================================
--- scummvm/trunk/backends/platform/psp/trace.h	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/backends/platform/psp/trace.h	2010-07-18 07:03:14 UTC (rev 50982)
@@ -30,6 +30,8 @@
 
 #include "common/str.h"
 
+#define __PSP_PRINT_TO_FILE_AND_SCREEN__
+
 /* Choose to print to file/screen/both */
 #ifdef __PSP_PRINT_TO_FILE__
 	#define __PSP_PRINT__(format,...)			PspDebugTrace(false, format, ## __VA_ARGS__)

Modified: scummvm/trunk/configure
===================================================================
--- scummvm/trunk/configure	2010-07-18 06:59:25 UTC (rev 50981)
+++ scummvm/trunk/configure	2010-07-18 07:03:14 UTC (rev 50982)
@@ -1916,7 +1916,7 @@
 PLUGIN_EXTRA_DEPS	= $(EXECUTABLE)
 CXXFLAGS		+= -DDYNAMIC_MODULES
 LDFLAGS			+= -Wl,-T$(srcdir)/backends/platform/psp/main_prog.ld
-PLUGIN_LDFLAGS		= -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm
+PLUGIN_LDFLAGS		= -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm -Wl,--wrap,memcpy
 PRE_OBJS_FLAGS		:= -Wl,--whole-archive
 POST_OBJS_FLAGS		:= -Wl,--no-whole-archive
 '
@@ -2468,6 +2468,7 @@
 	psp)
 		DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL"
 		LIBS="$LIBS -lpng -Wl,-Map,mapfile.txt"
+		LDFLAGS="$LDFLAGS -Wl,--wrap,memcpy"
 		;;
 	samsungtv)
 		find_sdlconfig


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list