diff options
| author | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-05-28 07:29:36 +0000 |
|---|---|---|
| committer | SND\weimingzhi_cp <SND\weimingzhi_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2010-05-28 07:29:36 +0000 |
| commit | ee905e2a8af0e14650b63dc08d4541ff205c9e52 (patch) | |
| tree | 4355d0b0a1523ededb3e2f246624ff5fc7539873 | |
| parent | 1f046517cc2f060268282f01a5dae7a19603b9d3 (diff) | |
| download | pcsxr-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-- | ChangeLog | 2 | ||||
| -rw-r--r-- | libpcsxcore/psxbios.c | 290 |
2 files changed, 207 insertions, 85 deletions
@@ -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) { |
