summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-05-28 07:29:36 +0000
committerSND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2010-05-28 07:29:36 +0000
commitee905e2a8af0e14650b63dc08d4541ff205c9e52 (patch)
tree4355d0b0a1523ededb3e2f246624ff5fc7539873
parent1f046517cc2f060268282f01a5dae7a19603b9d3 (diff)
downloadpcsxr-ee905e2a8af0e14650b63dc08d4541ff205c9e52.tar.gz
implemented more functions by hand (qsort() is not tested).
git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@49477 e17a0e51-4ae3-4d35-97c3-1a29b211df97
-rw-r--r--ChangeLog2
-rw-r--r--libpcsxcore/psxbios.c290
2 files changed, 207 insertions, 85 deletions
diff --git a/ChangeLog b/ChangeLog
index cfa44e00..e9fa8bf7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,8 @@ May 28, 2010 Wei Mingzhi <whistler_wmz@users.sf.net>
* macosx/Pcsx.xcodeproj/project.pbxproj: Fixed Xcode Project.
* macosx/English.lproj/InfoPlist.strings: Updated info.
* autogen.sh: Removed autoreconf.
+ * libpcsxcore/psxbios.c: Implemented more functions by hand (qsort() is not
+ tested).
May 25, 2010 Wei Mingzhi <whistler_wmz@users.sf.net>
diff --git a/libpcsxcore/psxbios.c b/libpcsxcore/psxbios.c
index 774b5d8a..f0d01738 100644
--- a/libpcsxcore/psxbios.c
+++ b/libpcsxcore/psxbios.c
@@ -20,10 +20,10 @@
/*
* Internal simulated HLE BIOS.
*/
-
-// TODO:
-// Get rid of standard C functions, implement all system calls,
-// count the exact CPU cycles of system calls.
+
+// TODO:
+// Get rid of standard C functions, implement all system calls,
+// count the exact CPU cycles of system calls.
#include "psxbios.h"
#include "psxhw.h"
@@ -465,34 +465,34 @@ void psxBios_strlen() { // 0x1b
pc0 = ra;
}
-void psxBios_index() { // 0x1c
- char *p = (char *)Ra0;
-
- do {
- if (*p == a1) {
- v0 = a0 + (p - (char *)Ra0);
- pc0 = ra;
- return;
- }
- } while (*p++ != '\0');
-
- v0 = 0; pc0 = ra;
-}
-
-void psxBios_rindex() { // 0x1d
- char *p = (char *)Ra0;
-
- v0 = 0;
-
- do {
- if (*p == a1)
- v0 = a0 + (p - (char *)Ra0);
- } while (*p++ != '\0');
-
- pc0 = ra;
-}
-
-void psxBios_strchr() { // 0x1e
+void psxBios_index() { // 0x1c
+ char *p = (char *)Ra0;
+
+ do {
+ if (*p == a1) {
+ v0 = a0 + (p - (char *)Ra0);
+ pc0 = ra;
+ return;
+ }
+ } while (*p++ != '\0');
+
+ v0 = 0; pc0 = ra;
+}
+
+void psxBios_rindex() { // 0x1d
+ char *p = (char *)Ra0;
+
+ v0 = 0;
+
+ do {
+ if (*p == a1)
+ v0 = a0 + (p - (char *)Ra0);
+ } while (*p++ != '\0');
+
+ pc0 = ra;
+}
+
+void psxBios_strchr() { // 0x1e
psxBios_index();
}
@@ -500,35 +500,49 @@ void psxBios_strrchr() { // 0x1f
psxBios_rindex();
}
-void psxBios_strpbrk() { // 0x20
- char *p1 = (char *)Ra0, *p2 = (char *)Ra1, *scanp, c, sc;
-
- while ((c = *p1++) != '\0') {
- for (scanp = p2; (sc = *scanp++) != '\0';) {
- if (sc == c) {
- v0 = a0 + (p1 - 1 - (char *)Ra0);
- pc0 = ra;
- return;
- }
- }
- }
-
- // should return a0 instead of NULL if not found (???)
- v0 = a0; pc0 = ra;
+void psxBios_strpbrk() { // 0x20
+ char *p1 = (char *)Ra0, *p2 = (char *)Ra1, *scanp, c, sc;
+
+ while ((c = *p1++) != '\0') {
+ for (scanp = p2; (sc = *scanp++) != '\0';) {
+ if (sc == c) {
+ v0 = a0 + (p1 - 1 - (char *)Ra0);
+ pc0 = ra;
+ return;
+ }
+ }
+ }
+
+ // should return a0 instead of NULL if not found (???)
+ v0 = a0; pc0 = ra;
+}
+
+void psxBios_strspn() { // 0x21
+ char *p1, *p2;
+
+ for (p1 = (char *)Ra0; *p1 != '\0'; p1++) {
+ for (p2 = (char *)Ra1; *p2 != '\0' && *p2 != *p1; p2++);
+ if (*p2 == '\0') break;
+ }
+
+ v0 = p1 - (char *)Ra0; pc0 = ra;
}
-void psxBios_strspn() { // 0x21
- v0 = strspn ((char *)Ra0, (char *)Ra1); pc0 = ra;
-}
+void psxBios_strcspn() { // 0x22
+ char *p1, *p2;
-void psxBios_strcspn() { // 0x22
- v0 = strcspn((char *)Ra0, (char *)Ra1); pc0 = ra;
+ for (p1 = (char *)Ra0; *p1 != '\0'; p1++) {
+ for (p2 = (char *)Ra1; *p2 != '\0' && *p2 != *p1; p2++);
+ if (*p2 != '\0') break;
+ }
+
+ v0 = p1 - (char *)Ra0; pc0 = ra;
}
void psxBios_strtok() { // 0x23
char *pcA0 = (char *)Ra0;
char *pcRet = strtok(pcA0, (char *)Ra1);
- if(pcRet)
+ if (pcRet)
v0 = a0 + pcRet - pcA0;
else
v0 = 0;
@@ -538,32 +552,34 @@ void psxBios_strtok() { // 0x23
void psxBios_strstr() { // 0x24
char *pcA0 = (char *)Ra0;
char *pcRet = strstr(pcA0, (char *)Ra1);
- if(pcRet)
+ if (pcRet)
v0 = a0 + pcRet - pcA0;
else
v0 = 0;
pc0 = ra;
}
-void psxBios_toupper() { // 0x25
- v0 = toupper(a0);
- pc0 = ra;
-}
+void psxBios_toupper() { // 0x25
+ v0 = (s8)(a0 & 0xff);
+ if (v0 >= 'a' && v0 <= 'z') v0 -= 'a' - 'A';
+ pc0 = ra;
+}
-void psxBios_tolower() { // 0x26
- v0 = tolower(a0);
- pc0 = ra;
-}
+void psxBios_tolower() { // 0x26
+ v0 = (s8)(a0 & 0xff);
+ if (v0 >= 'A' && v0 <= 'Z') v0 += 'a' - 'A';
+ pc0 = ra;
+}
-void psxBios_bcopy() { // 0x27
- memcpy(Ra1,Ra0,a2);
- pc0 = ra;
-}
+void psxBios_bcopy() { // 0x27
+ memcpy(Ra1, Ra0, a2);
+ pc0 = ra;
+}
-void psxBios_bzero() { // 0x28
- memset(Ra0,0,a1);
- pc0 = ra;
-}
+void psxBios_bzero() { // 0x28
+ memset(Ra0,0,a1);
+ pc0 = ra;
+}
/*0x29*/void psxBios_bcmp() {v0 = memcmp(Ra0,Ra1,a2); pc0=ra; }
/*0x2a*/void psxBios_memcpy() {memcpy(Ra0, Ra1, a2); v0 = a0; pc0 = ra;}
@@ -578,15 +594,119 @@ void psxBios_memchr() { // 2e
pc0 = ra;
}
-void psxBios_rand() { // 2f
- u32 s = psxMu32(0x9010) * 1103515245 + 12345;
- v0 = (s >> 16) & 0x7fff;
- psxMu32ref(0x9010) = SWAPu32(s);
+void psxBios_rand() { // 2f
+ u32 s = psxMu32(0x9010) * 1103515245 + 12345;
+ v0 = (s >> 16) & 0x7fff;
+ psxMu32ref(0x9010) = SWAPu32(s);
pc0 = ra;
}
void psxBios_srand() { // 30
- psxMu32ref(0x9010) = SWAPu32(a0);
+ psxMu32ref(0x9010) = SWAPu32(a0);
+ pc0 = ra;
+}
+
+static u32 qscmp_addr, qses;
+
+static inline int qscmp(char *a, char *b) {
+ a0 = (u32)(a - (char *)PSXM(0));
+ a1 = (u32)(b - (char *)PSXM(0));
+
+ softCall2(qscmp_addr);
+ return (s32)v0;
+}
+
+static inline void qexchange(char *i, char *j) {
+ char t;
+ int n = qses;
+
+ do {
+ t = *i;
+ *i++ = *j;
+ *j++ = t;
+ } while (--n);
+}
+
+static inline void q3exchange(char *i, char *j, char *k) {
+ char t;
+ int n = qses;
+
+ do {
+ t = *i;
+ *i++ = *k;
+ *k++ = *j;
+ *j++ = t;
+ } while (--n);
+}
+
+static void qsort_main(char *a, char *l) {
+ char *i, *j, *lp, *hp;
+ int es, c;
+ unsigned int n;
+
+ es = qses;
+
+start:
+ if ((n = l - a) <= es)
+ return;
+ n = es * (n / (2 * es));
+ hp = lp = a + n;
+ i = a;
+ j = l - es;
+ while (TRUE) {
+ if (i < lp) {
+ if ((c = qscmp(i, lp)) == 0) {
+ qexchange(i, lp -= es);
+ continue;
+ }
+ if (c < 0) {
+ i += es;
+ continue;
+ }
+ }
+
+loop:
+ if (j > hp) {
+ if ((c = qscmp(hp, j)) == 0) {
+ qexchange(hp += es, j);
+ goto loop;
+ }
+ if (c > 0) {
+ if (i == lp) {
+ q3exchange(i, hp += es, j);
+ i = lp += es;
+ goto loop;
+ }
+ qexchange(i, j);
+ j -= es;
+ i += es;
+ continue;
+ }
+ j -= es;
+ goto loop;
+ }
+
+ if (i == lp) {
+ if (lp - a >= l - hp) {
+ qsort_main(hp + es, l);
+ l = lp;
+ } else {
+ qsort_main(a, lp);
+ a = hp + es;
+ }
+ goto start;
+ }
+
+ q3exchange(j, lp -= es, i);
+ j = hp -= es;
+ }
+}
+
+void psxBios_qsort() { // 31
+ qscmp_addr = a3;
+ qses = a2;
+ qsort_main((char *)Ra0, (char *)Ra0 + a1 * a2);
+
pc0 = ra;
}
@@ -597,7 +717,7 @@ void psxBios_malloc() { // 33
#ifdef PSXBIOS_LOG
PSXBIOS_LOG("psxBios_%s\n", biosA0n[0x33]);
#endif
-
+
// scan through heap and combine free chunks of space
chunk = heap_addr;
colflag = 0;
@@ -644,7 +764,7 @@ void psxBios_malloc() { // 33
}
// search an unused chunk that is big enough until the end of the heap
- while ((dsize > csize || cstat==0) && chunk < heap_end ) {
+ while ((dsize > csize || cstat == 0) && chunk < heap_end ) {
chunk = (u32*)((uptr)chunk + csize + 4);
csize = ((u32)*chunk) & 0xfffffffc;
cstat = ((u32)*chunk) & 1;
@@ -2012,7 +2132,7 @@ void psxBiosInit() {
biosA0[0x2e] = psxBios_memchr;
biosA0[0x2f] = psxBios_rand;
biosA0[0x30] = psxBios_srand;
- //biosA0[0x31] = psxBios_qsort;
+ biosA0[0x31] = psxBios_qsort;
//biosA0[0x32] = psxBios_strtod;
biosA0[0x33] = psxBios_malloc;
biosA0[0x34] = psxBios_free;
@@ -2308,13 +2428,13 @@ void psxBiosInit() {
psxMu32ref(0x8000) = SWAPu32((0x3b << 26) | 5);
psxMu32ref(0x07a0) = SWAPu32((0x3b << 26) | 0);
psxMu32ref(0x0884) = SWAPu32((0x3b << 26) | 0);
- psxMu32ref(0x0894) = SWAPu32((0x3b << 26) | 0);
-
+ psxMu32ref(0x0894) = SWAPu32((0x3b << 26) | 0);
+
// memory size 2 MB
psxHu32ref(0x1060) = SWAPu32(0x00000b88);
-
- // initial RNG seed
- psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
+
+ // initial RNG seed
+ psxMu32ref(0x9010) = SWAPu32(0xac20cc00);
}
void psxBiosShutdown() {
@@ -2527,7 +2647,7 @@ v0=1; // HDHOSHY experimental patch: Spongebob, Coldblood, fearEffect, Medievil2
#define bfreeze(ptr, size) { \
if (Mode == 1) memcpy(&psxR[base], ptr, size); \
if (Mode == 0) memcpy(ptr, &psxR[base], size); \
- base += size; \
+ base += size; \
}
#define bfreezes(ptr) bfreeze(ptr, sizeof(ptr))
@@ -2541,7 +2661,7 @@ v0=1; // HDHOSHY experimental patch: Spongebob, Coldblood, fearEffect, Medievil2
if (psxRu32(base)) *(u8**)&ptr = (u8*)(psxM + psxRu32(base)); \
else ptr = NULL; \
} \
- base += sizeof(uintptr_t); \
+ base += sizeof(uintptr_t); \
}
void psxBiosFreeze(int Mode) {