/[pcsx2_0.9.7]/trunk/pcsx2/IPU/coroutine.cpp
ViewVC logotype

Annotation of /trunk/pcsx2/IPU/coroutine.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 31 - (hide annotations) (download)
Tue Sep 7 03:24:11 2010 UTC (10 years ago) by william
File size: 3782 byte(s)
committing r3113 initial commit again...
1 william 31 /* PCSX2 - PS2 Emulator for PCs
2     * Copyright (C) 2002-2010 PCSX2 Dev Team
3     *
4     * PCSX2 is free software: you can redistribute it and/or modify it under the terms
5     * of the GNU Lesser General Public License as published by the Free Software Found-
6     * ation, either version 3 of the License, or (at your option) any later version.
7     *
8     * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
9     * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10     * PURPOSE. See the GNU General Public License for more details.
11     *
12     * You should have received a copy of the GNU General Public License along with PCSX2.
13     * If not, see <http://www.gnu.org/licenses/>.
14     */
15    
16    
17     #include "PrecompiledHeader.h"
18    
19     #include "coroutine.h"
20    
21     struct coroutine {
22     void* pcalladdr;
23     void *pcurstack;
24    
25     uptr storeebx, storeesi, storeedi, storeebp;
26    
27     s32 restore; // if nonzero, restore the registers
28     s32 alloc;
29     //struct s_coroutine *caller;
30     //struct s_coroutine *restarget;
31    
32     };
33    
34     #define CO_STK_ALIGN 256
35     #define CO_STK_COROSIZE ((sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1))
36     #define CO_MIN_SIZE (4 * 1024)
37    
38     coroutine* g_pCurrentRoutine;
39    
40     coroutine_t so_create(void (*func)(void *), void *data, void *stack, int size)
41     {
42     void* endstack;
43     int alloc = 0; // r = CO_STK_COROSIZE;
44     coroutine *co;
45    
46     if ((size &= ~(sizeof(s32) - 1)) < CO_MIN_SIZE) return NULL;
47     if (!stack) {
48     size = (size + sizeof(coroutine) + CO_STK_ALIGN - 1) & ~(CO_STK_ALIGN - 1);
49     stack = malloc(size);
50     if (!stack) return NULL;
51     alloc = size;
52     }
53     endstack = (char*)stack + size - 64;
54     co = (coroutine*)stack;
55     stack = (char *) stack + CO_STK_COROSIZE;
56     *(void**)endstack = NULL;
57     *(void**)((char*)endstack+sizeof(void*)) = data;
58     co->alloc = alloc;
59     co->pcalladdr = (void*)func;
60     co->pcurstack = endstack;
61     return co;
62     }
63    
64     void so_delete(coroutine_t coro)
65     {
66     coroutine *co = (coroutine *) coro;
67     pxAssert( co != NULL );
68     if (co->alloc) free(co);
69     }
70    
71     // see acoroutines.S and acoroutines.asm for other asm implementations
72     #if defined(_MSC_VER)
73    
74     __declspec(naked) void so_call(coroutine_t coro)
75     {
76     __asm {
77     mov eax, dword ptr [esp+4]
78     test dword ptr [eax+24], 1
79     jnz RestoreRegs
80     mov [eax+8], ebx
81     mov [eax+12], esi
82     mov [eax+16], edi
83     mov [eax+20], ebp
84     mov dword ptr [eax+24], 1
85     jmp CallFn
86     RestoreRegs:
87     // have to load and save at the same time
88     mov ecx, [eax+8]
89     mov edx, [eax+12]
90     mov [eax+8], ebx
91     mov [eax+12], esi
92     mov ebx, ecx
93     mov esi, edx
94     mov ecx, [eax+16]
95     mov edx, [eax+20]
96     mov [eax+16], edi
97     mov [eax+20], ebp
98     mov edi, ecx
99     mov ebp, edx
100    
101     CallFn:
102     mov [g_pCurrentRoutine], eax
103     mov ecx, esp
104     mov esp, [eax+4]
105     mov [eax+4], ecx
106    
107     jmp dword ptr [eax]
108     }
109     }
110    
111     __declspec(naked) void so_resume(void)
112     {
113     __asm {
114     mov eax, [g_pCurrentRoutine]
115     mov ecx, [eax+8]
116     mov edx, [eax+12]
117     mov [eax+8], ebx
118     mov [eax+12], esi
119     mov ebx, ecx
120     mov esi, edx
121     mov ecx, [eax+16]
122     mov edx, [eax+20]
123     mov [eax+16], edi
124     mov [eax+20], ebp
125     mov edi, ecx
126     mov ebp, edx
127    
128     // put the return address in pcalladdr
129     mov ecx, [esp]
130     mov [eax], ecx
131     add esp, 4 // remove the return address
132    
133     // swap stack pointers
134     mov ecx, [eax+4]
135     mov [eax+4], esp
136     mov esp, ecx
137     ret
138     }
139     }
140    
141     __declspec(naked) void so_exit(void)
142     {
143     __asm {
144     mov eax, [g_pCurrentRoutine]
145     mov esp, [eax+4]
146     mov ebx, [eax+8]
147     mov esi, [eax+12]
148     mov edi, [eax+16]
149     mov ebp, [eax+20]
150     ret
151     }
152     }
153     #endif

  ViewVC Help
Powered by ViewVC 1.1.22