1 #include "types.h"
2 #include "common.h"
3
4 #include "vm.h"
5 #include "gefile.h"
6 #include "bytecode.h"
7
8
9
10 /*-----------------------------------------------------------------------------
11 * Summary: Append a string to resource
12 -----------------------------------------------------------------------------*/
13
14 uint STDCALL vmres_addstr( pvmEngine pThis, pubyte ptr )
15 {
16 collect_addptr( pThis, &pThis->_vm.resource, ptr );
17
18 return collect_count( pThis, &pThis->_vm.resource ) - 1;
19 }
20
21 /*-----------------------------------------------------------------------------
22 * Summary: Get a string from resource
23 -----------------------------------------------------------------------------*/
24
25 pstr STDCALL vmres_getstr( pvmEngine pThis, uint index )
26 {
27 return *( pstr* )collect_index( pThis, &pThis->_vm.resource, index );
28 }
29
30
31
32
33
34 /*-----------------------------------------------------------------------------
35 * Summary: Initialize the virtual machine.
36 -----------------------------------------------------------------------------*/
37
38 void STDCALL vm_deinit( pvmEngine pThis )// pvm _pvm )
39 {
40 // Destroy all objects
41 vmmng_destroy(pThis);
42 arr_delete( pThis, &pThis->_vm.objtbl );
43 hash_delete( pThis, &pThis->_vm.objname );
44 collect_delete( pThis, &pThis->_vm.resource );
45 buf_delete( pThis, &pThis->_vm.resource.data );
46
47 }
48
49 /*-----------------------------------------------------------------------------
50 * Summary: Initialize the virtual machine.
51 -----------------------------------------------------------------------------*/
52
53 void STDCALL vm_init( pvmEngine pThis )
54 {
55 uint i, id, k, len;
56 int topshift, cmdshift;
57 pubyte emb, ptr = ( pubyte )&embtypes;
58 ubyte input[64];
59 pvmfunc pfunc;
60
61 mem_zero( pThis, &pThis->_vm, sizeof( vm ));
62 pThis->_vm.loadmode = 1;
63 // Initialize the array of objects
64 arr_init( pThis, &pThis->_vm.objtbl, sizeof( uint ));
65 arr_step( pThis, &pThis->_vm.objtbl, 1024 );
66 buf_init( pThis, &pThis->_vm.resource.data );
67
68 // Initialize the hash of object names
69 hash_init( pThis, &pThis->_vm.objname, sizeof( uint ));
70 vmmng_new(pThis);
71
72 // Add zero command
73 load_stack( pThis, 0, 0, NULL )->type = OVM_NONE;
74
75 // Loading kernel objects into VM
76 for ( i = TInt; i <= TFordata; i++ )
77 {
78 load_type( pThis, &ptr );
79 }
80 // Loading kernel objects into VM
81 for ( i = 0; i < STACK_COUNT; i++ )
82 {
83 topshift = 0;
84 cmdshift = 0;
85 switch ( shifts[i] )
86 {
87 case SHN3_1: topshift--;
88 case SHN2_1: topshift--;
89 case SHN1_1: topshift--;
90 cmdshift = 1;
91 break;
92 case SHN1_2: topshift--;
93 cmdshift = 2;
94 break;
95 case SH0_2: cmdshift++;
96 case SH0_1: cmdshift++;
97 break;
98 case SH1_3: cmdshift++;
99 case SH1_2: cmdshift++;
100 case SH1_1: cmdshift++;
101 topshift = 1;
102 break;
103 case SH2_1:
104 topshift = 2;
105 cmdshift = 1;
106 break;
107 case SH2_3:
108 topshift = 2;
109 cmdshift = 3;
110 break;
111 }
112 id = pThis->_vm.count;
113 load_stack( pThis, topshift, cmdshift, NULL );
114 }
115 emb = ( pubyte )&embfuncs;
116 for ( i = 0; i < FUNCCOUNT; i++ )
117 {
118 ptr = ( pubyte )&input;
119 *ptr++ = OVM_EXFUNC;
120 *(( puint )ptr)++ = GHCOM_NAME | GHCOM_PACK;
121 *ptr++ = 0;
122 len = mem_copyuntilzero( pThis, ptr, emb );
123 ptr += len;
124 emb += len;
125 id = *emb++;
126 *ptr++ = ( id & 0x80 ? *emb++ : 0 );
127 *ptr++ = 0;
128 id &= 0x7f;
129 *ptr++ = ( ubyte )id;
130 for ( k = 0; k < id; k++ )
131 {
132 *ptr++ = *emb++;
133 *ptr++ = 0;
134 }
135 input[ 5 ] = ( ubyte )( ptr - ( pubyte )&input );
136 ptr = ( pubyte )&input;
137
138 pfunc = ( pvmfunc )load_exfunc( pThis, &ptr, 0 );
139 pfunc->func = NULL;
140 }
141 // Loading reserved empty commands
142 while ( pThis->_vm.count < KERNEL_COUNT )
143 load_stack( pThis, 0, 0, NULL )->type = OVM_NONE;
144
145 pThis->_vm.countinit = 0;//KERNEL_COUNT;
146
147 }
148
149
150
151
152
153 /*-----------------------------------------------------------------------------
154 * Summary: Create a new vmmanager
155 -----------------------------------------------------------------------------*/
156
157 pvmmanager STDCALL vmmng_new( pvmEngine pThis )
158 {
159 pvmmanager pmng = mem_alloc( pThis, sizeof( vmmanager ));
160 mem_zero(pThis, pmng, sizeof( vmmanager ));
161 pmng->next = pThis->_vm.pmng;
162 pThis->_vm.pmng = pmng;
163 pmng->ptr = mem_alloc( pThis, 0x100000 );
164 pmng->top = pmng->ptr;
165 pmng->end = ( pubyte )pmng->ptr + 0xFFF00;
166
167 return pmng;
168 }
169
170 /*-----------------------------------------------------------------------------
171 * Summary: Destroy all vm managers
172 -----------------------------------------------------------------------------*/
173
174 void STDCALL vmmng_destroy( pvmEngine pThis )
175 {
176 pvmmanager pmng;
177
178 while ( pThis->_vm.pmng )
179 {
180 pmng = pThis->_vm.pmng;
181
182 mem_free( pThis, pmng->ptr );
183 pThis->_vm.pmng = pmng->next;
184 mem_free( pThis, pmng );
185 }
186 }
187
188 /*-----------------------------------------------------------------------------
189 * Summary: Get a pointer for object
190 -----------------------------------------------------------------------------*/
191
192 pubyte STDCALL vmmng_begin( pvmEngine pThis, uint size )
193 {
194 pvmmanager pmng = pThis->_vm.pmng;
195
196 if ( ( pmng->top + 2 * size ) > pmng->end )
197 {
198 pmng = vmmng_new(pThis);
199 if ( size + 0xFFFF > 0x100000 )
200 {
201 mem_free( pThis, pmng->ptr );
202 pmng->ptr = mem_alloc( pThis, size + 0xFFFF );
203 pmng->top = pmng->ptr;
204 pmng->end = ( pubyte )pmng->ptr + size + 0xFF00;
205 }
206 }
207 return pmng->top;
208 }
209
210 /*-----------------------------------------------------------------------------
211 * Summary: The end of the object
212 -----------------------------------------------------------------------------*/
213
214 uint STDCALL vmmng_end( pvmEngine pThis, pubyte end )
215 {
216 uint ret = end - pThis->_vm.pmng->top;
217
218 (( pvmobj )pThis->_vm.pmng->top)->size = ret;
219
220 pThis->_vm.pmng->top = end;
221 return ret;
222 }
223