Subversion Repositories Kolibri OS

Rev

Rev 444 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 444 Rev 453
1
$Revision: 431 $
1
$Revision: 448 $
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
3
;;                                                              ;;
3
;;                                                              ;;
4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
4
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
5
;; Distributed under terms of the GNU General Public License    ;;
5
;; Distributed under terms of the GNU General Public License    ;;
6
;;                                                              ;;
6
;;                                                              ;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8
 
8
 
9
align 4
9
align 4
10
proc alloc_page
10
proc alloc_page
11
 
11
 
12
           pushfd
12
           pushfd
13
           cli
13
           cli
14
           mov ebx, [page_start]
14
           mov ebx, [page_start]
15
           mov ecx, [page_end]
15
           mov ecx, [page_end]
16
.l1:
16
.l1:
17
           bsf eax,[ebx];
17
           bsf eax,[ebx];
18
           jnz .found
18
           jnz .found
19
           add ebx,4
19
           add ebx,4
20
           cmp ebx, ecx
20
           cmp ebx, ecx
21
           jb .l1
21
           jb .l1
22
           popfd
22
           popfd
23
           xor eax,eax
23
           xor eax,eax
24
           ret
24
           ret
25
.found:
25
.found:
26
           btr [ebx], eax
26
           btr [ebx], eax
27
           mov [page_start],ebx
27
           mov [page_start],ebx
28
           sub ebx, sys_pgmap
28
           sub ebx, sys_pgmap
29
           lea eax, [eax+ebx*8]
29
           lea eax, [eax+ebx*8]
30
           shl eax, 12
30
           shl eax, 12
31
           dec [pg_data.pages_free]
31
           dec [pg_data.pages_free]
32
           popfd
32
           popfd
33
           ret
33
           ret
34
endp
34
endp
35
 
35
 
36
align 4
36
align 4
37
proc alloc_pages stdcall, count:dword
37
proc alloc_pages stdcall, count:dword
38
           pushfd
38
           pushfd
39
           cli
39
           cli
40
           mov eax, [count]
40
           mov eax, [count]
41
           add eax, 7
41
           add eax, 7
42
           shr eax, 3
42
           shr eax, 3
43
           mov [count], eax
43
           mov [count], eax
44
           cmp eax, [pg_data.pages_free]
44
           cmp eax, [pg_data.pages_free]
45
           ja .fail
45
           ja .fail
46
 
46
 
47
           mov ecx, [page_start]
47
           mov ecx, [page_start]
48
           mov ebx, [page_end]
48
           mov ebx, [page_end]
49
.find:
49
.find:
50
           mov edx, [count]
50
           mov edx, [count]
51
           mov edi, ecx
51
           mov edi, ecx
52
.match:
52
.match:
53
           cmp byte [ecx], 0xFF
53
           cmp byte [ecx], 0xFF
54
           jne .next
54
           jne .next
55
           dec edx
55
           dec edx
56
           jz .ok
56
           jz .ok
57
           inc ecx
57
           inc ecx
58
           cmp ecx,ebx
58
           cmp ecx,ebx
59
           jb .match
59
           jb .match
60
.fail:     xor eax, eax
60
.fail:     xor eax, eax
61
           popfd
61
           popfd
62
           ret
62
           ret
63
.next:
63
.next:
64
           inc ecx
64
           inc ecx
65
           cmp ecx, ebx
65
           cmp ecx, ebx
66
           jb .find
66
           jb .find
67
           popfd
67
           popfd
68
           xor eax, eax
68
           xor eax, eax
69
           ret
69
           ret
70
.ok:
70
.ok:
71
           sub ecx, edi
71
           sub ecx, edi
72
           inc ecx
72
           inc ecx
73
           mov esi, edi
73
           mov esi, edi
74
           xor eax, eax
74
           xor eax, eax
75
           rep stosb
75
           rep stosb
76
           sub esi, sys_pgmap
76
           sub esi, sys_pgmap
77
           shl esi, 3+12
77
           shl esi, 3+12
78
           mov eax, esi
78
           mov eax, esi
79
           mov ebx, [count]
79
           mov ebx, [count]
80
           shl ebx, 3
80
           shl ebx, 3
81
           sub [pg_data.pages_free], ebx
81
           sub [pg_data.pages_free], ebx
82
           popfd
82
           popfd
83
           ret
83
           ret
84
endp
84
endp
85
 
85
 
86
align 4
86
align 4
87
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
87
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword
88
           push ebx
88
           push ebx
89
           mov eax, [phis_addr]
89
           mov eax, [phis_addr]
90
           and eax, not 0xFFF
90
           and eax, not 0xFFF
91
           or eax, [flags]
91
           or eax, [flags]
92
           mov ebx, [lin_addr]
92
           mov ebx, [lin_addr]
93
           shr ebx, 12
93
           shr ebx, 12
94
           mov [page_tabs+ebx*4], eax
94
           mov [page_tabs+ebx*4], eax
95
           mov eax, [lin_addr]
95
           mov eax, [lin_addr]
96
           invlpg [eax]
96
           invlpg [eax]
97
           pop ebx
97
           pop ebx
98
           ret
98
           ret
99
endp
99
endp
100
 
100
 
101
align 4
101
align 4
102
map_space:    ;not implemented
102
map_space:    ;not implemented
103
 
103
 
104
 
104
 
105
           ret
105
           ret
106
 
106
 
107
 
107
 
108
align 4
108
align 4
109
proc free_page
109
proc free_page
110
;arg:  eax  page address
110
;arg:  eax  page address
111
           pushfd
111
           pushfd
112
           cli
112
           cli
113
           shr eax, 12              ;page index
113
           shr eax, 12              ;page index
114
           mov ebx, sys_pgmap
-
 
115
           bts [ebx], eax           ;that's all!
114
           bts dword [sys_pgmap], eax           ;that's all!
116
           cmc
115
           cmc
117
           adc [pg_data.pages_free], 0
116
           adc [pg_data.pages_free], 0
118
           shr eax, 3
117
           shr eax, 3
119
           and eax, not 3           ;dword offset from page_map
118
           and eax, not 3           ;dword offset from page_map
120
           add eax, ebx
119
           add eax, sys_pgmap
121
           cmp [page_start], eax
120
           cmp [page_start], eax
122
           ja @f
121
           ja @f
123
           popfd
122
           popfd
124
           ret
123
           ret
125
@@:
124
@@:
126
           mov [page_start], eax
125
           mov [page_start], eax
127
           popfd
126
           popfd
128
           ret
127
           ret
129
endp
128
endp
130
 
129
 
131
; param
130
; param
132
;  eax= page base + page flags
131
;  eax= page base + page flags
133
;  ebx= liear address
132
;  ebx= liear address
134
;  ecx= count
133
;  ecx= count
135
 
134
 
136
align 4
135
align 4
137
commit_pages:
136
commit_pages:
138
 
137
 
139
           test ecx, ecx
138
           test ecx, ecx
140
           jz .fail
139
           jz .fail
141
 
140
 
142
           mov edi, ebx
141
           mov edi, ebx
143
           mov ebx, pg_data.pg_mutex
142
           mov ebx, pg_data.pg_mutex
144
           call wait_mutex      ;ebx
143
           call wait_mutex      ;ebx
145
 
144
 
146
           mov edx, 0x1000
145
           mov edx, 0x1000
147
           mov ebx, edi
146
           mov ebx, edi
148
           shr ebx, 12
147
           shr ebx, 12
149
@@:
148
@@:
150
           mov [page_tabs+ebx*4], eax
149
           mov [page_tabs+ebx*4], eax
151
           invlpg [edi]
150
           invlpg [edi]
152
           add edi, edx
151
           add edi, edx
153
           add eax, edx
152
           add eax, edx
154
           inc ebx
153
           inc ebx
155
           dec ecx
154
           dec ecx
156
           jnz @B
155
           jnz @B
157
           mov [pg_data.pg_mutex],ecx
156
           mov [pg_data.pg_mutex],ecx
158
.fail:
157
.fail:
159
           ret
158
           ret
160
 
159
 
161
 
160
 
162
; param
161
; param
163
;  eax= base
162
;  eax= base
164
;  ecx= count
163
;  ecx= count
165
 
164
 
166
align 4
165
align 4
167
release_pages:
166
release_pages:
168
 
167
 
169
           pushad
168
           pushad
170
           mov ebx, pg_data.pg_mutex
169
           mov ebx, pg_data.pg_mutex
171
           call wait_mutex      ;ebx
170
           call wait_mutex      ;ebx
172
 
171
 
173
           mov esi, eax
172
           mov esi, eax
174
           mov edi, eax
173
           mov edi, eax
175
 
174
 
176
           shr esi, 10
175
           shr esi, 10
177
           add esi, page_tabs
176
           add esi, page_tabs
178
 
177
 
179
           mov ebp, [pg_data.pages_free]
178
           mov ebp, [pg_data.pages_free]
180
           mov ebx, [page_start]
179
           mov ebx, [page_start]
181
           mov edx, sys_pgmap
180
           mov edx, sys_pgmap
182
@@:
181
@@:
183
           xor eax, eax
182
           xor eax, eax
184
           xchg eax, [esi]
183
           xchg eax, [esi]
185
           invlpg [edi]
184
           invlpg [edi]
186
 
185
 
187
           test eax, 1
186
           test eax, 1
188
           jz .next
187
           jz .next
189
 
188
 
190
           shr eax, 12
189
           shr eax, 12
191
           bts [edx], eax
190
           bts [edx], eax
192
           cmc
191
           cmc
193
           adc ebp, 0
192
           adc ebp, 0
194
           shr eax, 3
193
           shr eax, 3
195
           and eax, -4
194
           and eax, -4
196
           add eax, edx
195
           add eax, edx
197
           cmp eax, ebx
196
           cmp eax, ebx
198
           jae .next
197
           jae .next
199
 
198
 
200
           mov ebx, eax
199
           mov ebx, eax
201
.next:
200
.next:
202
           add edi, 0x1000
201
           add edi, 0x1000
203
           add esi, 4
202
           add esi, 4
204
           dec ecx
203
           dec ecx
205
           jnz @B
204
           jnz @B
206
           mov [pg_data.pages_free], ebp
205
           mov [pg_data.pages_free], ebp
207
           and [pg_data.pg_mutex],0
206
           and [pg_data.pg_mutex],0
208
           popad
207
           popad
209
           ret
208
           ret
210
 
209
 
211
align 4
210
align 4
212
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
211
proc map_page_table stdcall, lin_addr:dword, phis_addr:dword
213
           push ebx
212
           push ebx
214
           mov ebx, [lin_addr]
213
           mov ebx, [lin_addr]
215
           shr ebx, 22
214
           shr ebx, 22
216
           mov eax, [phis_addr]
215
           mov eax, [phis_addr]
217
           and eax, not 0xFFF
216
           and eax, not 0xFFF
218
           or eax, PG_UW          ;+PG_NOCACHE
217
           or eax, PG_UW          ;+PG_NOCACHE
219
           mov dword [master_tab+ebx*4], eax
218
           mov dword [master_tab+ebx*4], eax
220
           mov eax, [lin_addr]
219
           mov eax, [lin_addr]
221
           shr eax, 10
220
           shr eax, 10
222
           add eax, page_tabs
221
           add eax, page_tabs
223
           invlpg [eax]
222
           invlpg [eax]
224
           pop ebx
223
           pop ebx
225
           ret
224
           ret
226
endp
225
endp
227
 
226
 
228
align 4
227
align 4
229
proc init_LFB
228
proc init_LFB
230
           locals
229
           locals
231
             pg_count dd ?
230
             pg_count dd ?
232
           endl
231
           endl
233
 
232
 
234
           cmp dword [LFBAddress], -1
233
           cmp dword [LFBAddress], -1
235
           jne @f
234
           jne @f
236
           mov [BOOT_VAR+0x901c],byte 2
235
           mov [BOOT_VAR+0x901c],byte 2
237
           stdcall kernel_alloc, 0x280000
236
           stdcall kernel_alloc, 0x280000
238
           mov [LFBAddress], eax
237
           mov [LFBAddress], eax
239
           ret
238
           ret
240
@@:
239
@@:
241
           test [SCR_MODE],word 0100000000000000b
240
           test [SCR_MODE],word 0100000000000000b
242
           jnz @f
241
           jnz @f
243
           mov [BOOT_VAR+0x901c],byte 2
242
           mov [BOOT_VAR+0x901c],byte 2
244
           ret
243
           ret
245
@@:
244
@@:
246
           mov edx, LFB_BASE
245
           mov edx, LFB_BASE
247
           mov esi, [LFBAddress]
246
           mov esi, [LFBAddress]
248
           mov edi, 0x00800000
247
           mov edi, 0x00800000
249
           mov dword [exp_lfb+4], edx
248
           mov dword [exp_lfb+4], edx
250
 
249
 
251
           shr edi, 12
250
           shr edi, 12
252
           mov [pg_count], edi
251
           mov [pg_count], edi
253
           shr edi, 10
252
           shr edi, 10
254
 
253
 
255
           bt [cpu_caps], CAPS_PSE
254
           bt [cpu_caps], CAPS_PSE
256
           jnc .map_page_tables
255
           jnc .map_page_tables
257
           or esi, PG_LARGE+PG_UW
256
           or esi, PG_LARGE+PG_UW
258
           mov edx, sys_pgdir+(LFB_BASE shr 20)
257
           mov edx, sys_pgdir+(LFB_BASE shr 20)
259
@@:
258
@@:
260
           mov [edx], esi
259
           mov [edx], esi
261
           add edx, 4
260
           add edx, 4
262
           add esi, 0x00400000
261
           add esi, 0x00400000
263
           dec edi
262
           dec edi
264
           jnz @B
263
           jnz @B
265
 
264
 
266
           bt [cpu_caps], CAPS_PGE
265
           bt [cpu_caps], CAPS_PGE
267
           jnc @F
266
           jnc @F
268
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
267
           or dword [sys_pgdir+(LFB_BASE shr 20)], PG_GLOBAL
269
@@:
268
@@:
270
           mov dword [LFBAddress], LFB_BASE
269
           mov dword [LFBAddress], LFB_BASE
271
           mov eax, cr3       ;flush TLB
270
           mov eax, cr3       ;flush TLB
272
           mov cr3, eax
271
           mov cr3, eax
273
           ret
272
           ret
274
 
273
 
275
.map_page_tables:
274
.map_page_tables:
276
 
275
 
277
@@:
276
@@:
278
           call alloc_page
277
           call alloc_page
279
           stdcall map_page_table, edx, eax
278
           stdcall map_page_table, edx, eax
280
           add edx, 0x00400000
279
           add edx, 0x00400000
281
           dec edi
280
           dec edi
282
           jnz @B
281
           jnz @B
283
 
282
 
284
           mov eax, [LFBAddress]
283
           mov eax, [LFBAddress]
285
           mov edi, page_tabs + (LFB_BASE shr 10)
284
           mov edi, page_tabs + (LFB_BASE shr 10)
286
           or eax, PG_UW
285
           or eax, PG_UW
287
           mov ecx, [pg_count]
286
           mov ecx, [pg_count]
288
           cld
287
           cld
289
@@:
288
@@:
290
           stosd
289
           stosd
291
           add eax, 0x1000
290
           add eax, 0x1000
292
           dec ecx
291
           dec ecx
293
           jnz @B
292
           jnz @B
294
 
293
 
295
           mov dword [LFBAddress], LFB_BASE
294
           mov dword [LFBAddress], LFB_BASE
296
           mov eax, cr3       ;flush TLB
295
           mov eax, cr3       ;flush TLB
297
           mov cr3, eax
296
           mov cr3, eax
298
 
297
 
299
           ret
298
           ret
300
endp
299
endp
301
 
300
 
302
align 4
301
align 4
303
proc new_mem_resize stdcall, new_size:dword
302
proc new_mem_resize stdcall, new_size:dword
304
 
303
 
305
           mov ebx, pg_data.pg_mutex
304
           mov ebx, pg_data.pg_mutex
306
           call wait_mutex    ;ebx
305
           call wait_mutex    ;ebx
307
 
306
 
308
           mov edi, [new_size]
307
           mov edi, [new_size]
309
           add edi,4095
308
           add edi,4095
310
           and edi,not 4095
309
           and edi,not 4095
311
           mov [new_size], edi
310
           mov [new_size], edi
312
 
311
 
313
           mov edx,[current_slot]
312
           mov edx,[current_slot]
314
           cmp [edx+APPDATA.heap_base],0
313
           cmp [edx+APPDATA.heap_base],0
315
           jne .exit
314
           jne .exit
316
 
315
 
317
           mov esi, [edx+APPDATA.mem_size]
316
           mov esi, [edx+APPDATA.mem_size]
318
           add esi, 4095
317
           add esi, 4095
319
           and esi, not 4095
318
           and esi, not 4095
320
 
319
 
321
           cmp edi, esi
320
           cmp edi, esi
322
           jae .expand
321
           jae .expand
323
 
322
 
324
           shr edi, 12
323
           shr edi, 12
325
           shr esi, 12
324
           shr esi, 12
326
@@:
325
@@:
327
           mov eax, [app_page_tabs+edi*4]
326
           mov eax, [app_page_tabs+edi*4]
328
           test eax, 1
327
           test eax, 1
329
           jz .next
328
           jz .next
330
           mov dword [app_page_tabs+edi*4], 2
329
           mov dword [app_page_tabs+edi*4], 2
331
           mov ebx, edi
330
           mov ebx, edi
332
           shl ebx, 12
331
           shl ebx, 12
333
           invlpg [ebx+std_application_base_address]
332
           invlpg [ebx+std_application_base_address]
334
           call free_page
333
           call free_page
335
 
334
 
336
.next:     add edi, 1
335
.next:     add edi, 1
337
           cmp edi, esi
336
           cmp edi, esi
338
           jb @B
337
           jb @B
339
 
338
 
340
.update_size:
339
.update_size:
341
           mov     ebx, [new_size]
340
           mov     ebx, [new_size]
342
           call    update_mem_size
341
           call    update_mem_size
343
 
342
 
344
           xor eax, eax
343
           xor eax, eax
345
           dec [pg_data.pg_mutex]
344
           dec [pg_data.pg_mutex]
346
           ret
345
           ret
347
.expand:
346
.expand:
348
 
347
 
349
           push esi
348
           push esi
350
           push edi
349
           push edi
351
 
350
 
352
           add edi, 0x3FFFFF
351
           add edi, 0x3FFFFF
353
           and edi, not(0x3FFFFF)
352
           and edi, not(0x3FFFFF)
354
           add esi, 0x3FFFFF
353
           add esi, 0x3FFFFF
355
           and esi, not(0x3FFFFF)
354
           and esi, not(0x3FFFFF)
356
 
355
 
357
           cmp esi, edi
356
           cmp esi, edi
358
           jae .grow
357
           jae .grow
359
 
358
 
360
           xchg esi, edi
359
           xchg esi, edi
361
 
360
 
362
@@:
361
@@:
363
           call alloc_page
362
           call alloc_page
364
           test eax, eax
363
           test eax, eax
365
           jz .exit
364
           jz .exit
366
 
365
 
367
           stdcall map_page_table, edi, eax
366
           stdcall map_page_table, edi, eax
368
 
367
 
369
           push edi
368
           push edi
370
           shr edi, 10
369
           shr edi, 10
371
           add edi, page_tabs
370
           add edi, page_tabs
372
           mov ecx, 1024
371
           mov ecx, 1024
373
           xor eax, eax
372
           xor eax, eax
374
           cld
373
           cld
375
           rep stosd
374
           rep stosd
376
           pop edi
375
           pop edi
377
 
376
 
378
           add edi, 0x00400000
377
           add edi, 0x00400000
379
           cmp edi, esi
378
           cmp edi, esi
380
           jb @B
379
           jb @B
381
.grow:
380
.grow:
382
           pop edi
381
           pop edi
383
           pop esi
382
           pop esi
384
@@:
383
@@:
385
           call alloc_page
384
           call alloc_page
386
           test eax, eax
385
           test eax, eax
387
           jz .exit
386
           jz .exit
388
           stdcall map_page,esi,eax,dword PG_UW
387
           stdcall map_page,esi,eax,dword PG_UW
389
 
388
 
390
           push edi
389
           push edi
391
           mov edi, esi
390
           mov edi, esi
392
           xor eax, eax
391
           xor eax, eax
393
           mov ecx, 1024
392
           mov ecx, 1024
394
           cld
393
           cld
395
           rep stosd
394
           rep stosd
396
           pop edi
395
           pop edi
397
 
396
 
398
           add esi, 0x1000
397
           add esi, 0x1000
399
           cmp esi, edi
398
           cmp esi, edi
400
           jb  @B
399
           jb  @B
401
 
400
 
402
           jmp .update_size
401
           jmp .update_size
403
.exit:
402
.exit:
404
           xor eax, eax
403
           xor eax, eax
405
           inc eax
404
           inc eax
406
           dec [pg_data.pg_mutex]
405
           dec [pg_data.pg_mutex]
407
           ret
406
           ret
408
endp
407
endp
409
 
408
 
410
update_mem_size:
409
update_mem_size:
411
; in: edx = slot base
410
; in: edx = slot base
412
;     ebx = new memory size
411
;     ebx = new memory size
413
; destroys eax,ecx,edx
412
; destroys eax,ecx,edx
414
 
413
 
415
           mov    [APPDATA.mem_size+edx],ebx
414
           mov    [APPDATA.mem_size+edx],ebx
416
;search threads and update
415
;search threads and update
417
;application memory size infomation
416
;application memory size infomation
418
           mov    ecx,[APPDATA.dir_table+edx]
417
           mov    ecx,[APPDATA.dir_table+edx]
419
           mov    eax,2
418
           mov    eax,2
420
 
419
 
421
.search_threads:
420
.search_threads:
422
;eax = current slot
421
;eax = current slot
423
;ebx = new memory size
422
;ebx = new memory size
424
;ecx = page directory
423
;ecx = page directory
425
           cmp    eax,[TASK_COUNT]
424
           cmp    eax,[TASK_COUNT]
426
           jg     .search_threads_end
425
           jg     .search_threads_end
427
           mov    edx,eax
426
           mov    edx,eax
428
           shl    edx,5
427
           shl    edx,5
429
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
428
           cmp    word [CURRENT_TASK+edx+TASKDATA.state],9 ;if slot empty?
430
           jz     .search_threads_next
429
           jz     .search_threads_next
431
           shl    edx,3
430
           shl    edx,3
432
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
431
           cmp    [SLOT_BASE+edx+APPDATA.dir_table],ecx     ;if it is our thread?
433
           jnz    .search_threads_next
432
           jnz    .search_threads_next
434
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
433
           mov    [SLOT_BASE+edx+APPDATA.mem_size],ebx     ;update memory size
435
.search_threads_next:
434
.search_threads_next:
436
           inc    eax
435
           inc    eax
437
           jmp    .search_threads
436
           jmp    .search_threads
438
.search_threads_end:
437
.search_threads_end:
439
           ret
438
           ret
440
 
439
 
441
; param
440
; param
442
;  eax= linear address
441
;  eax= linear address
443
;
442
;
444
; retval
443
; retval
445
;  eax= phisical page address
444
;  eax= phisical page address
446
 
445
 
447
align 4
446
align 4
448
get_pg_addr:
447
get_pg_addr:
449
           shr eax, 12
448
           shr eax, 12
450
           mov eax, [page_tabs+eax*4]
449
           mov eax, [page_tabs+eax*4]
451
           and eax, 0xFFFFF000
450
           and eax, 0xFFFFF000
452
           ret
451
           ret
453
 
452
 
454
 
453
 
455
align 4
454
align 4
456
proc page_fault_handler
455
proc page_fault_handler
457
 
456
 
458
        .err_code equ ebp+32
457
        .err_code equ ebp+32
459
        .err_addr equ ebp-4
458
        .err_addr equ ebp-4
460
 
459
 
461
           pushad
460
           pushad
462
           mov ebp, esp
461
           mov ebp, esp
463
           mov eax, cr2
462
           mov eax, cr2
464
           push eax
463
           push eax
465
 
464
 
466
           mov ax, app_data
465
           mov ax, app_data
467
           mov ds, ax
466
           mov ds, ax
468
           mov es, ax
467
           mov es, ax
469
 
468
 
470
           inc [pg_data.pages_faults]
469
           inc [pg_data.pages_faults]
471
 
470
 
472
     push eax
471
     push eax
473
     push edx
472
     push edx
474
     mov edx, 0x400   ;bochs
473
     mov edx, 0x400   ;bochs
475
     mov al,0xff      ;bochs
474
     mov al,0xff      ;bochs
476
     out dx, al       ;bochs
475
     out dx, al       ;bochs
477
     pop edx
476
     pop edx
478
     pop eax
477
     pop eax
479
 
478
 
480
           mov ebx, [.err_addr]
479
           mov ebx, [.err_addr]
481
           mov eax, [.err_code]
480
           mov eax, [.err_code]
482
 
481
 
483
           cmp ebx, OS_BASE
482
           cmp ebx, OS_BASE
484
           jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
483
           jb .user_space      ;ñòðàíèöà â ïàìÿòè ïðèëîæåíèÿ ;
485
 
484
 
486
           cmp ebx, page_tabs
485
           cmp ebx, page_tabs
487
           jb .kernel_space    ;ñòðàíèöà â ïàìÿòè ÿäðà
486
           jb .kernel_space    ;ñòðàíèöà â ïàìÿòè ÿäðà
488
 
487
 
489
           cmp ebx, kernel_tabs
488
           cmp ebx, kernel_tabs
490
           jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
489
           jb .alloc;.app_tabs ;òàáëèöû ñòðàíèö ïðèëîæåíèÿ ;
491
                               ;ïðîñòî ñîçäàäèì îäíó
490
                               ;ïðîñòî ñîçäàäèì îäíó
492
 
491
 
493
           cmp ebx, LFB_BASE
492
           cmp ebx, LFB_BASE
494
           jb .core_tabs       ;òàáëèöû ñòðàíèö ÿäðà
493
           jb .core_tabs       ;òàáëèöû ñòðàíèö ÿäðà
495
                               ;Îøèáêà
494
                               ;Îøèáêà
496
.lfb:
495
.lfb:
497
                               ;îáëàñòü LFB
496
                               ;îáëàñòü LFB
498
                               ;Îøèáêà
497
                               ;Îøèáêà
499
           jmp .fail
498
           jmp .fail
500
 
499
 
501
align 4
500
align 4
502
.user_space:
501
.user_space:
503
           test eax, PG_MAP
502
           test eax, PG_MAP
504
           jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
503
           jnz .err_access     ;Ñòðàíèöà ïðèñóòñòâóåò
505
                               ;Îøèáêà äîñòóïà ?
504
                               ;Îøèáêà äîñòóïà ?
506
 
505
 
507
           shr ebx, 12
506
           shr ebx, 12
508
           mov ecx, ebx
507
           mov ecx, ebx
509
           shr ecx, 10
508
           shr ecx, 10
510
           mov edx, [master_tab+ecx*4]
509
           mov edx, [master_tab+ecx*4]
511
           test edx, PG_MAP
510
           test edx, PG_MAP
512
           jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
511
           jz .fail            ;òàáëèöà ñòðàíèö íå ñîçäàíà
513
                               ;íåâåðíûé àäðåñ â ïðîãðàììå
512
                               ;íåâåðíûé àäðåñ â ïðîãðàììå
514
 
513
 
515
           mov eax, [page_tabs+ebx*4]
514
           mov eax, [page_tabs+ebx*4]
516
           test eax, 2
515
           test eax, 2
517
           jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
516
           jz .fail            ;àäðåñ íå çàðåçåðâèðîâàí äëÿ ;
518
                               ;èñïîëüçîâàíèÿ. Îøèáêà
517
                               ;èñïîëüçîâàíèÿ. Îøèáêà
519
.alloc:
518
.alloc:
520
           call alloc_page
519
           call alloc_page
521
           and eax, eax
520
           and eax, eax
522
           jz .fail
521
           jz .fail
523
 
522
 
524
           stdcall map_page,[ebp-4],eax,dword PG_UW
523
           stdcall map_page,[ebp-4],eax,dword PG_UW
525
 
524
 
526
           mov edi, [ebp-4]
525
           mov edi, [ebp-4]
527
           and edi, 0xFFFFF000
526
           and edi, 0xFFFFF000
528
           mov ecx, 1024
527
           mov ecx, 1024
529
           xor eax, eax
528
           xor eax, eax
530
           cld
529
           cld
531
           rep stosd
530
           rep stosd
532
.exit:
531
.exit:
533
           mov esp, ebp
532
           mov esp, ebp
534
           popad
533
           popad
535
           add esp, 4
534
           add esp, 4
536
           iretd
535
           iretd
537
 
536
 
538
.err_access:
537
.err_access:
539
;íèêîãäà íå ïðîèñõîäèò
538
;íèêîãäà íå ïðîèñõîäèò
540
           jmp .fail
539
           jmp .fail
541
 
540
 
542
.kernel_space:
541
.kernel_space:
543
           test eax, PG_MAP
542
           test eax, PG_MAP
544
           jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
543
           jz .fail        ;ñòðàíèöà íå ïðèñóòñòâóåò
545
 
544
 
546
           test eax, 4     ;U/S
545
           test eax, 4     ;U/S
547
           jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
546
           jnz .fail       ;ïðèëîæåíèå îáðàòèëîñü ê ïàìÿòè
548
                           ;ÿäðà
547
                           ;ÿäðà
549
           test eax, 8
548
           test eax, 8
550
           jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
549
           jnz .fail       ;óñòàíîâëåí çàðåçåðâèðîâàííûé áèò
551
                           ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
550
                           ;â òàáëèöàõ ñòðàíèö. äîáàâëåíî â P4/Xeon
552
 
551
 
553
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
552
;ïîïûòêà çàïèñè â çàùèù¸ííóþ ñòðàíèöó ÿäðà
554
 
553
 
555
           cmp ebx, tss._io_map_0
554
           cmp ebx, tss._io_map_0
556
           jb .fail
555
           jb .fail
557
 
556
 
558
           cmp ebx, tss._io_map_0+8192
557
           cmp ebx, tss._io_map_0+8192
559
           jae .fail
558
           jae .fail
560
 
559
 
561
; io permission map
560
; io permission map
562
; copy-on-write protection
561
; copy-on-write protection
563
 
562
 
564
           call alloc_page
563
           call alloc_page
565
           and eax, eax
564
           and eax, eax
566
           jz .fail
565
           jz .fail
567
 
566
 
568
           push eax
567
           push eax
569
           stdcall map_page,[ebp-4],eax,dword PG_SW
568
           stdcall map_page,[ebp-4],eax,dword PG_SW
570
           pop eax
569
           pop eax
571
           mov edi, [.err_addr]
570
           mov edi, [.err_addr]
572
           and edi, -4096
571
           and edi, -4096
573
           lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
572
           lea esi, [edi+(not tss._io_map_0)+1]; -tss._io_map_0
574
 
573
 
575
           mov ebx, esi
574
           mov ebx, esi
576
           shr ebx, 12
575
           shr ebx, 12
577
           mov edx, [current_slot]
576
           mov edx, [current_slot]
578
           or eax, PG_SW
577
           or eax, PG_SW
579
           mov [edx+APPDATA.io_map+ebx*4], eax
578
           mov [edx+APPDATA.io_map+ebx*4], eax
580
 
579
 
581
           add esi, [default_io_map]
580
           add esi, [default_io_map]
582
           mov ecx, 4096/4
581
           mov ecx, 4096/4
583
           cld
582
           cld
584
           rep movsd
583
           rep movsd
585
           jmp .exit
584
           jmp .exit
586
 
585
 
587
 
586
 
588
;íå îáðàáàòûâàåì. Îøèáêà
587
;íå îáðàáàòûâàåì. Îøèáêà
589
 
588
 
590
.core_tabs:
589
.core_tabs:
591
.fail:
590
.fail:
592
           mov esp, ebp
591
           mov esp, ebp
593
           popad
592
           popad
594
           add esp, 4
593
           add esp, 4
595
           iretd
594
           iretd
596
 
595
 
597
           save_ring3_context     ;debugger support
596
           save_ring3_context     ;debugger support
598
 
597
 
599
           mov bl, 14
598
           mov bl, 14
600
           jmp exc_c
599
           jmp exc_c
601
           iretd
600
           iretd
602
endp
601
endp
603
 
602
 
604
align 4
603
align 4
605
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
604
proc map_mem stdcall, lin_addr:dword,pdir:dword,\
606
                      ofs:dword,buf_size:dword
605
                      ofs:dword,buf_size:dword
607
           mov eax, [buf_size]
606
           mov eax, [buf_size]
608
           test eax, eax
607
           test eax, eax
609
           jz .exit
608
           jz .exit
610
 
609
 
611
           mov eax, [pdir]
610
           mov eax, [pdir]
612
           and eax, 0xFFFFF000
611
           and eax, 0xFFFFF000
613
 
612
 
614
           stdcall map_page,[ipc_pdir],eax,dword PG_UW
613
           stdcall map_page,[ipc_pdir],eax,dword PG_UW
615
           mov ebx, [ofs]
614
           mov ebx, [ofs]
616
           shr ebx, 22
615
           shr ebx, 22
617
           mov esi, [ipc_pdir]
616
           mov esi, [ipc_pdir]
618
           mov edi, [ipc_ptab]
617
           mov edi, [ipc_ptab]
619
           mov eax, [esi+ebx*4]
618
           mov eax, [esi+ebx*4]
620
           and eax, 0xFFFFF000
619
           and eax, 0xFFFFF000
621
           test eax, eax
620
           test eax, eax
622
           jz .exit
621
           jz .exit
623
           stdcall map_page,edi,eax,dword PG_UW
622
           stdcall map_page,edi,eax,dword PG_UW
624
;           inc ebx
623
;           inc ebx
625
;           add edi, 0x1000
624
;           add edi, 0x1000
626
;           mov eax, [esi+ebx*4]
625
;           mov eax, [esi+ebx*4]
627
;           test eax, eax
626
;           test eax, eax
628
;           jz @f
627
;           jz @f
629
;          and eax, 0xFFFFF000
628
;          and eax, 0xFFFFF000
630
;           stdcall map_page, edi, eax
629
;           stdcall map_page, edi, eax
631
 
630
 
632
@@:        mov edi, [lin_addr]
631
@@:        mov edi, [lin_addr]
633
           and edi, 0xFFFFF000
632
           and edi, 0xFFFFF000
634
           mov ecx, [buf_size]
633
           mov ecx, [buf_size]
635
           add ecx, 4095
634
           add ecx, 4095
636
           shr ecx, 12
635
           shr ecx, 12
637
           inc ecx
636
           inc ecx
638
 
637
 
639
           mov edx, [ofs]
638
           mov edx, [ofs]
640
           shr edx, 12
639
           shr edx, 12
641
           and edx, 0x3FF
640
           and edx, 0x3FF
642
           mov esi, [ipc_ptab]
641
           mov esi, [ipc_ptab]
643
 
642
 
644
.map:      mov eax, [esi+edx*4]
643
.map:      mov eax, [esi+edx*4]
645
           and eax, 0xFFFFF000
644
           and eax, 0xFFFFF000
646
           test eax, eax
645
           test eax, eax
647
           jz .exit
646
           jz .exit
648
           stdcall map_page,edi,eax,dword PG_UW
647
           stdcall map_page,edi,eax,dword PG_UW
649
           add edi, 0x1000
648
           add edi, 0x1000
650
           inc edx
649
           inc edx
651
           dec ecx
650
           dec ecx
652
           jnz .map
651
           jnz .map
653
 
652
 
654
.exit:
653
.exit:
655
           ret
654
           ret
656
endp
655
endp
657
 
656
 
658
align 4
657
align 4
659
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
658
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\
660
                        ofs:dword,buf_size:dword
659
                        ofs:dword,buf_size:dword
661
           mov eax, [buf_size]
660
           mov eax, [buf_size]
662
           test eax, eax
661
           test eax, eax
663
           jz .exit
662
           jz .exit
664
 
663
 
665
           mov eax, [pdir]
664
           mov eax, [pdir]
666
           and eax, 0xFFFFF000
665
           and eax, 0xFFFFF000
667
 
666
 
668
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
667
           stdcall map_page,[proc_mem_pdir],eax,dword PG_UW
669
           mov ebx, [ofs]
668
           mov ebx, [ofs]
670
           shr ebx, 22
669
           shr ebx, 22
671
           mov esi, [proc_mem_pdir]
670
           mov esi, [proc_mem_pdir]
672
           mov edi, [proc_mem_tab]
671
           mov edi, [proc_mem_tab]
673
           mov eax, [esi+ebx*4]
672
           mov eax, [esi+ebx*4]
674
           and eax, 0xFFFFF000
673
           and eax, 0xFFFFF000
675
           test eax, eax
674
           test eax, eax
676
           jz .exit
675
           jz .exit
677
           stdcall map_page,edi,eax,dword PG_UW
676
           stdcall map_page,edi,eax,dword PG_UW
678
 
677
 
679
@@:        mov edi, [lin_addr]
678
@@:        mov edi, [lin_addr]
680
           and edi, 0xFFFFF000
679
           and edi, 0xFFFFF000
681
           mov ecx, [buf_size]
680
           mov ecx, [buf_size]
682
           add ecx, 4095
681
           add ecx, 4095
683
           shr ecx, 12
682
           shr ecx, 12
684
           inc ecx
683
           inc ecx
685
 
684
 
686
           mov edx, [ofs]
685
           mov edx, [ofs]
687
           shr edx, 12
686
           shr edx, 12
688
           and edx, 0x3FF
687
           and edx, 0x3FF
689
           mov esi, [proc_mem_tab]
688
           mov esi, [proc_mem_tab]
690
 
689
 
691
.map:      mov eax, [esi+edx*4]
690
.map:      mov eax, [esi+edx*4]
692
;           and eax, 0xFFFFF000
691
;           and eax, 0xFFFFF000
693
;           test eax, eax
692
;           test eax, eax
694
;           jz .exit
693
;           jz .exit
695
           stdcall map_page,edi,eax,dword PG_UW
694
           stdcall map_page,edi,eax,dword PG_UW
696
           add edi, 0x1000
695
           add edi, 0x1000
697
           inc edx
696
           inc edx
698
           dec ecx
697
           dec ecx
699
           jnz .map
698
           jnz .map
700
.exit:
699
.exit:
701
           ret
700
           ret
702
endp
701
endp
703
 
702
 
704
 
703
 
705
 
704
 
706
 
705
 
707
sys_IPC:
706
sys_IPC:
708
;input:
707
;input:
709
;  eax=1 - set ipc buffer area
708
;  eax=1 - set ipc buffer area
710
;    ebx=address of buffer
709
;    ebx=address of buffer
711
;    ecx=size of buffer
710
;    ecx=size of buffer
712
;  eax=2 - send message
711
;  eax=2 - send message
713
;    ebx=PID
712
;    ebx=PID
714
;    ecx=address of message
713
;    ecx=address of message
715
;    edx=size of message
714
;    edx=size of message
716
 
715
 
717
           cmp  eax,1
716
           cmp  eax,1
718
           jne @f
717
           jne @f
719
           call set_ipc_buff
718
           call set_ipc_buff
720
           mov [esp+36], eax
719
           mov [esp+36], eax
721
           ret
720
           ret
722
@@:
721
@@:
723
           cmp eax, 2
722
           cmp eax, 2
724
           jne @f
723
           jne @f
725
           stdcall sys_ipc_send, ebx, ecx, edx
724
           stdcall sys_ipc_send, ebx, ecx, edx
726
           mov [esp+36], eax
725
           mov [esp+36], eax
727
           ret
726
           ret
728
@@:
727
@@:
729
           xor eax, eax
728
           xor eax, eax
730
           not eax
729
           not eax
731
           mov [esp+36], eax
730
           mov [esp+36], eax
732
           ret
731
           ret
733
 
732
 
734
align 4
733
align 4
735
proc set_ipc_buff
734
proc set_ipc_buff
736
 
735
 
737
           mov  eax,[current_slot]
736
           mov  eax,[current_slot]
738
           pushf
737
           pushf
739
           cli
738
           cli
740
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
739
           mov  [eax+APPDATA.ipc_start],ebx     ;set fields in extended information area
741
           mov  [eax+APPDATA.ipc_size],ecx
740
           mov  [eax+APPDATA.ipc_size],ecx
742
 
741
 
743
           add ecx, ebx
742
           add ecx, ebx
744
           add ecx, 4095
743
           add ecx, 4095
745
           and ecx, not 4095
744
           and ecx, not 4095
746
 
745
 
747
.touch:    mov eax, [ebx]
746
.touch:    mov eax, [ebx]
748
           add ebx, 0x1000
747
           add ebx, 0x1000
749
           cmp ebx, ecx
748
           cmp ebx, ecx
750
           jna .touch
749
           jna .touch
751
 
750
 
752
           popf
751
           popf
753
           xor eax, eax
752
           xor eax, eax
754
           ret
753
           ret
755
endp
754
endp
756
 
755
 
757
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
756
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
758
           locals
757
           locals
759
             dst_slot   dd ?
758
             dst_slot   dd ?
760
             dst_offset dd ?
759
             dst_offset dd ?
761
             buf_size   dd ?
760
             buf_size   dd ?
762
           endl
761
           endl
763
 
762
 
764
           pushf
763
           pushf
765
           cli
764
           cli
766
 
765
 
767
           mov  eax, [PID]
766
           mov  eax, [PID]
768
           call pid_to_slot
767
           call pid_to_slot
769
           test eax,eax
768
           test eax,eax
770
           jz   .no_pid
769
           jz   .no_pid
771
 
770
 
772
           mov [dst_slot], eax
771
           mov [dst_slot], eax
773
           shl  eax,8
772
           shl  eax,8
774
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
773
           mov  edi,[eax+SLOT_BASE+0xa0]  ;is ipc area defined?
775
           test edi,edi
774
           test edi,edi
776
           jz   .no_ipc_area
775
           jz   .no_ipc_area
777
 
776
 
778
           mov ebx, edi
777
           mov ebx, edi
779
       ;    add edi, new_app_base
778
       ;    add edi, new_app_base
780
           and ebx, 0xFFF
779
           and ebx, 0xFFF
781
           mov [dst_offset], ebx
780
           mov [dst_offset], ebx
782
 
781
 
783
           mov esi, [eax+SLOT_BASE+0xa4]
782
           mov esi, [eax+SLOT_BASE+0xa4]
784
           mov [buf_size], esi
783
           mov [buf_size], esi
785
 
784
 
786
           stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\
785
           stdcall map_mem, [ipc_tmp], [SLOT_BASE+eax+0xB8],\
787
                             edi, esi
786
                             edi, esi
788
 
787
 
789
           mov edi, [dst_offset]
788
           mov edi, [dst_offset]
790
           add edi, [ipc_tmp]
789
           add edi, [ipc_tmp]
791
           cmp dword [edi], 0
790
           cmp dword [edi], 0
792
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
791
           jnz  .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
793
 
792
 
794
           mov ebx, dword [edi+4]
793
           mov ebx, dword [edi+4]
795
           mov edx, ebx
794
           mov edx, ebx
796
           add ebx, 8
795
           add ebx, 8
797
           add ebx, [msg_size]
796
           add ebx, [msg_size]
798
           cmp ebx, [buf_size]
797
           cmp ebx, [buf_size]
799
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
798
           ja .buffer_overflow         ;esi<0 - not enough memory in buffer
800
 
799
 
801
           mov dword [edi+4], ebx
800
           mov dword [edi+4], ebx
802
           mov eax,[TASK_BASE]
801
           mov eax,[TASK_BASE]
803
           mov eax, [eax+0x04]         ;eax - our PID
802
           mov eax, [eax+0x04]         ;eax - our PID
804
           mov edi, [dst_offset]
803
           mov edi, [dst_offset]
805
           add edi, [ipc_tmp]
804
           add edi, [ipc_tmp]
806
           add edi, edx
805
           add edi, edx
807
           mov [edi], eax
806
           mov [edi], eax
808
           mov ecx, [msg_size]
807
           mov ecx, [msg_size]
809
 
808
 
810
           mov [edi+4], ecx
809
           mov [edi+4], ecx
811
           add edi, 8
810
           add edi, 8
812
           mov esi, [msg_addr]
811
           mov esi, [msg_addr]
813
       ;    add esi, new_app_base
812
       ;    add esi, new_app_base
814
           cld
813
           cld
815
           rep movsb
814
           rep movsb
816
 
815
 
817
           mov ebx, [ipc_tmp]
816
           mov ebx, [ipc_tmp]
818
           mov edx, ebx
817
           mov edx, ebx
819
           shr ebx, 12
818
           shr ebx, 12
820
           xor eax, eax
819
           xor eax, eax
821
           mov [page_tabs+ebx*4], eax
820
           mov [page_tabs+ebx*4], eax
822
           invlpg [edx]
821
           invlpg [edx]
823
 
822
 
824
           mov ebx, [ipc_pdir]
823
           mov ebx, [ipc_pdir]
825
           mov edx, ebx
824
           mov edx, ebx
826
           shr ebx, 12
825
           shr ebx, 12
827
           xor eax, eax
826
           xor eax, eax
828
           mov [page_tabs+ebx*4], eax
827
           mov [page_tabs+ebx*4], eax
829
           invlpg [edx]
828
           invlpg [edx]
830
 
829
 
831
           mov ebx, [ipc_ptab]
830
           mov ebx, [ipc_ptab]
832
           mov edx, ebx
831
           mov edx, ebx
833
           shr ebx, 12
832
           shr ebx, 12
834
           xor eax, eax
833
           xor eax, eax
835
           mov [page_tabs+ebx*4], eax
834
           mov [page_tabs+ebx*4], eax
836
           invlpg [edx]
835
           invlpg [edx]
837
 
836
 
838
           mov  eax, [dst_slot]
837
           mov  eax, [dst_slot]
839
           shl eax, 8
838
           shl eax, 8
840
           or   [eax+SLOT_BASE+0xA8],dword 0x40
839
           or   [eax+SLOT_BASE+0xA8],dword 0x40
841
           cmp  dword [check_idle_semaphore],20
840
           cmp  dword [check_idle_semaphore],20
842
           jge  .ipc_no_cis
841
           jge  .ipc_no_cis
843
 
842
 
844
           mov  dword [check_idle_semaphore],5
843
           mov  dword [check_idle_semaphore],5
845
.ipc_no_cis:
844
.ipc_no_cis:
846
           popf
845
           popf
847
           xor eax, eax
846
           xor eax, eax
848
           ret
847
           ret
849
.no_pid:
848
.no_pid:
850
           popf
849
           popf
851
           mov  eax, 4
850
           mov  eax, 4
852
           ret
851
           ret
853
.no_ipc_area:
852
.no_ipc_area:
854
           popf
853
           popf
855
           xor eax, eax
854
           xor eax, eax
856
           inc eax
855
           inc eax
857
           ret
856
           ret
858
.ipc_blocked:
857
.ipc_blocked:
859
           popf
858
           popf
860
           mov  eax, 2
859
           mov  eax, 2
861
           ret
860
           ret
862
.buffer_overflow:
861
.buffer_overflow:
863
           popf
862
           popf
864
           mov  eax, 3
863
           mov  eax, 3
865
           ret
864
           ret
866
endp
865
endp
867
 
866
 
868
align 4
867
align 4
869
sysfn_meminfo:
868
sysfn_meminfo:
870
 
869
 
871
        ;   add ebx, new_app_base
870
        ;   add ebx, new_app_base
872
           cmp ebx, OS_BASE
871
           cmp ebx, OS_BASE
873
           jae .fail
872
           jae .fail
874
 
873
 
875
           mov eax, [pg_data.pages_count]
874
           mov eax, [pg_data.pages_count]
876
           mov [ebx], eax
875
           mov [ebx], eax
877
           shl eax, 12
876
           shl eax, 12
878
           mov [esp+36], eax
877
           mov [esp+36], eax
879
           mov ecx, [pg_data.pages_free]
878
           mov ecx, [pg_data.pages_free]
880
           mov [ebx+4], ecx
879
           mov [ebx+4], ecx
881
           mov edx, [pg_data.pages_faults]
880
           mov edx, [pg_data.pages_faults]
882
           mov [ebx+8], edx
881
           mov [ebx+8], edx
883
           mov esi, [heap_size]
882
           mov esi, [heap_size]
884
           mov [ebx+12], esi
883
           mov [ebx+12], esi
885
           mov edi, [heap_free]
884
           mov edi, [heap_free]
886
           mov [ebx+16], edi
885
           mov [ebx+16], edi
887
           mov eax, [heap_blocks]
886
           mov eax, [heap_blocks]
888
           mov [ebx+20], eax
887
           mov [ebx+20], eax
889
           mov ecx, [free_blocks]
888
           mov ecx, [free_blocks]
890
           mov [ebx+24], ecx
889
           mov [ebx+24], ecx
891
           ret
890
           ret
892
.fail:
891
.fail:
893
           mov dword [esp+36], -1
892
           mov dword [esp+36], -1
894
           ret
893
           ret
895
 
894
 
896
align 4
895
align 4
897
new_services:
896
new_services:
898
 
897
 
899
           cmp  eax,4
898
           cmp  eax,4
900
           jle  sys_sheduler
899
           jle  sys_sheduler
901
 
900
 
902
           cmp eax, 11
901
           cmp eax, 11
903
           jb .fail
902
           jb .fail
904
           ja @f
903
           ja @f
905
 
904
 
906
           call init_heap
905
           call init_heap
907
           mov [esp+36], eax
906
           mov [esp+36], eax
908
           ret
907
           ret
909
@@:
908
@@:
910
           cmp eax, 12
909
           cmp eax, 12
911
           ja @f
910
           ja @f
912
 
911
 
913
           stdcall user_alloc, ebx
912
           stdcall user_alloc, ebx
914
           mov [esp+36], eax
913
           mov [esp+36], eax
915
           ret
914
           ret
916
@@:
915
@@:
917
           cmp eax, 13
916
           cmp eax, 13
918
           ja @f
917
           ja @f
919
           stdcall user_free, ebx
918
           stdcall user_free, ebx
920
           mov [esp+36], eax
919
           mov [esp+36], eax
921
           ret
920
           ret
922
@@:
921
@@:
923
           cmp eax, 14
922
           cmp eax, 14
924
           ja @f
923
           ja @f
925
           cmp ebx, OS_BASE
924
           cmp ebx, OS_BASE
926
           jae .fail
925
           jae .fail
927
           stdcall get_event_ex, ebx, ecx
926
           stdcall get_event_ex, ebx, ecx
928
           mov [esp+36], eax
927
           mov [esp+36], eax
929
           ret
928
           ret
930
@@:
929
@@:
931
           cmp eax, 15
930
           cmp eax, 15
932
           ja @f
931
           ja @f
933
           mov ecx, [current_slot]
932
           mov ecx, [current_slot]
934
           mov eax, [ecx+APPDATA.fpu_handler]
933
           mov eax, [ecx+APPDATA.fpu_handler]
935
           mov [ecx+APPDATA.fpu_handler], ebx
934
           mov [ecx+APPDATA.fpu_handler], ebx
936
           mov [esp+36], eax
935
           mov [esp+36], eax
937
           ret
936
           ret
938
@@:
937
@@:
939
           cmp eax, 16
938
           cmp eax, 16
940
           ja @f
939
           ja @f
941
 
940
 
942
           test ebx, ebx
941
           test ebx, ebx
943
           jz .fail
942
           jz .fail
944
           cmp ebx, OS_BASE
943
           cmp ebx, OS_BASE
945
           jae .fail
944
           jae .fail
946
           stdcall get_service, ebx
945
           stdcall get_service, ebx
947
           mov [esp+36], eax
946
           mov [esp+36], eax
948
           ret
947
           ret
949
@@:
948
@@:
950
           cmp eax, 17
949
           cmp eax, 17
951
           ja @f
950
           ja @f
952
           call srv_handlerEx   ;ebx
951
           call srv_handlerEx   ;ebx
953
           mov [esp+36], eax
952
           mov [esp+36], eax
954
           ret
953
           ret
955
@@:
954
@@:
956
           cmp eax, 18
955
           cmp eax, 18
957
           ja @f
956
           ja @f
958
           mov ecx, [current_slot]
957
           mov ecx, [current_slot]
959
           mov eax, [ecx+APPDATA.sse_handler]
958
           mov eax, [ecx+APPDATA.sse_handler]
960
           mov [ecx+APPDATA.sse_handler], ebx
959
           mov [ecx+APPDATA.sse_handler], ebx
961
           mov [esp+36], eax
960
           mov [esp+36], eax
962
           ret
961
           ret
963
@@:
962
@@:
964
           cmp eax, 19
963
           cmp eax, 19
965
           ja .fail
964
           ja @f
966
      ;     add ebx, new_app_base
-
 
967
           cmp ebx, OS_BASE
965
           cmp ebx, OS_BASE
968
           jae .fail
966
           jae .fail
969
           stdcall load_library, ebx
967
           stdcall load_library, ebx
970
           mov [esp+36], eax
968
           mov [esp+36], eax
971
           ret
969
           ret
-
 
970
 
-
 
971
@@:
-
 
972
        cmp     eax, 20
-
 
973
        ja      .fail
-
 
974
        mov     eax, ecx
-
 
975
        call    user_realloc
-
 
976
        mov     [esp+36], eax
-
 
977
        ret
972
 
978
 
973
.fail:
979
.fail:
974
           xor eax, eax
980
           xor eax, eax
975
           mov [esp+36], eax
981
           mov [esp+36], eax
976
           ret
982
           ret
977
 
983
 
978
align 4
984
align 4
979
proc init_mtrr
985
proc init_mtrr
980
 
986
 
981
           cmp [BOOT_VAR+0x901c],byte 2
987
           cmp [BOOT_VAR+0x901c],byte 2
982
           je  .exit
988
           je  .exit
983
 
989
 
984
           bt [cpu_caps], CAPS_MTRR
990
           bt [cpu_caps], CAPS_MTRR
985
           jnc .exit
991
           jnc .exit
986
 
992
 
987
           mov eax, cr0
993
           mov eax, cr0
988
           or eax, 0x60000000   ;disable caching
994
           or eax, 0x60000000   ;disable caching
989
           mov cr0, eax
995
           mov cr0, eax
990
           wbinvd               ;invalidate cache
996
           wbinvd               ;invalidate cache
991
 
997
 
992
           mov ecx, 0x2FF
998
           mov ecx, 0x2FF
993
           rdmsr                ;
999
           rdmsr                ;
994
           push eax
1000
           push eax
995
 
1001
 
996
           xor edx, edx
1002
           xor edx, edx
997
           xor eax, eax
1003
           xor eax, eax
998
           mov ecx, 0x2FF
1004
           mov ecx, 0x2FF
999
           wrmsr                ;disable all MTRR
1005
           wrmsr                ;disable all MTRR
1000
 
1006
 
1001
           stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
1007
           stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB
1002
           stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
1008
           stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC
1003
           xor edx, edx
1009
           xor edx, edx
1004
           xor eax, eax
1010
           xor eax, eax
1005
           mov ecx, 0x204
1011
           mov ecx, 0x204
1006
           mov ebx, 6
1012
           mov ebx, 6
1007
@@:
1013
@@:
1008
           wrmsr                ;disable unused MTRR
1014
           wrmsr                ;disable unused MTRR
1009
           inc ecx
1015
           inc ecx
1010
           wrmsr
1016
           wrmsr
1011
           inc ecx
1017
           inc ecx
1012
           dec ebx
1018
           dec ebx
1013
           jnz @b
1019
           jnz @b
1014
 
1020
 
1015
           wbinvd               ;again invalidate
1021
           wbinvd               ;again invalidate
1016
 
1022
 
1017
           pop eax
1023
           pop eax
1018
           or eax, 0x800        ;set default memtype to UC
1024
           or eax, 0x800        ;set default memtype to UC
1019
           and al, 0xF0
1025
           and al, 0xF0
1020
           mov ecx, 0x2FF
1026
           mov ecx, 0x2FF
1021
           wrmsr                ;and enable MTRR
1027
           wrmsr                ;and enable MTRR
1022
 
1028
 
1023
           mov eax, cr0
1029
           mov eax, cr0
1024
           and eax, not 0x60000000
1030
           and eax, not 0x60000000
1025
           mov cr0, eax         ; enable caching
1031
           mov cr0, eax         ; enable caching
1026
.exit:
1032
.exit:
1027
           ret
1033
           ret
1028
endp
1034
endp
1029
 
1035
 
1030
align 4
1036
align 4
1031
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1037
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword
1032
 
1038
 
1033
           xor edx, edx
1039
           xor edx, edx
1034
           mov eax, [base]
1040
           mov eax, [base]
1035
           or eax, [mem_type]
1041
           or eax, [mem_type]
1036
           mov ecx, [reg]
1042
           mov ecx, [reg]
1037
           lea ecx, [0x200+ecx*2]
1043
           lea ecx, [0x200+ecx*2]
1038
           wrmsr
1044
           wrmsr
1039
 
1045
 
1040
           mov ebx, [size]
1046
           mov ebx, [size]
1041
           dec ebx
1047
           dec ebx
1042
           mov eax, 0xFFFFFFFF
1048
           mov eax, 0xFFFFFFFF
1043
           mov edx, 0x0000000F
1049
           mov edx, 0x0000000F
1044
           sub eax, ebx
1050
           sub eax, ebx
1045
           sbb edx, 0
1051
           sbb edx, 0
1046
           or eax, 0x800
1052
           or eax, 0x800
1047
           inc ecx
1053
           inc ecx
1048
           wrmsr
1054
           wrmsr
1049
           ret
1055
           ret
1050
endp
1056
endp
1051
 
1057
 
1052
 
1058
 
1053
align 4
1059
align 4
1054
proc strncmp stdcall, str1:dword, str2:dword, count:dword
1060
proc strncmp stdcall, str1:dword, str2:dword, count:dword
1055
 
1061
 
1056
          mov ecx,[count]
1062
          mov ecx,[count]
1057
          jecxz .end
1063
          jecxz .end
1058
 
1064
 
1059
          mov ebx,ecx
1065
          mov ebx,ecx
1060
 
1066
 
1061
          mov edi,[str1]
1067
          mov edi,[str1]
1062
          mov esi,edi
1068
          mov esi,edi
1063
          xor eax,eax
1069
          xor eax,eax
1064
          repne scasb
1070
          repne scasb
1065
          neg ecx             ; cx = count - strlen
1071
          neg ecx             ; cx = count - strlen
1066
          add ecx,ebx         ; strlen + count - strlen
1072
          add ecx,ebx         ; strlen + count - strlen
1067
 
1073
 
1068
.okay:
1074
.okay:
1069
          mov edi,esi
1075
          mov edi,esi
1070
          mov esi,[str2]
1076
          mov esi,[str2]
1071
          repe cmpsb
1077
          repe cmpsb
1072
          mov al,[esi-1]
1078
          mov al,[esi-1]
1073
          xor ecx,ecx
1079
          xor ecx,ecx
1074
 
1080
 
1075
          cmp al,[edi-1]
1081
          cmp al,[edi-1]
1076
          ja .str2_big
1082
          ja .str2_big
1077
          je .end
1083
          je .end
1078
 
1084
 
1079
.str1_big:
1085
.str1_big:
1080
          sub ecx,2
1086
          sub ecx,2
1081
 
1087
 
1082
.str2_big:
1088
.str2_big:
1083
          not ecx
1089
          not ecx
1084
.end:
1090
.end:
1085
          mov eax,ecx
1091
          mov eax,ecx
1086
          ret
1092
          ret
1087
endp
1093
endp
1088
 
1094
 
1089
align 4
1095
align 4
1090
proc stall stdcall, delay:dword
1096
proc stall stdcall, delay:dword
1091
           push ecx
1097
           push ecx
1092
           push edx
1098
           push edx
1093
           push ebx
1099
           push ebx
1094
           push eax
1100
           push eax
1095
 
1101
 
1096
           mov eax, [delay]
1102
           mov eax, [delay]
1097
           mul [stall_mcs]
1103
           mul [stall_mcs]
1098
           mov ebx, eax       ;low
1104
           mov ebx, eax       ;low
1099
           mov ecx, edx       ;high
1105
           mov ecx, edx       ;high
1100
           rdtsc
1106
           rdtsc
1101
           add ebx, eax
1107
           add ebx, eax
1102
           adc ecx,edx
1108
           adc ecx,edx
1103
@@:
1109
@@:
1104
           rdtsc
1110
           rdtsc
1105
           sub eax, ebx
1111
           sub eax, ebx
1106
           sbb edx, ecx
1112
           sbb edx, ecx
1107
           jb @B
1113
           jb @B
1108
 
1114
 
1109
           pop eax
1115
           pop eax
1110
           pop ebx
1116
           pop ebx
1111
           pop edx
1117
           pop edx
1112
           pop ecx
1118
           pop ecx
1113
           ret
1119
           ret
1114
endp
1120
endp
1115
 
1121
 
1116
align 4
1122
align 4
1117
k_strrchr:
1123
k_strrchr:
1118
        push eax
1124
        push eax
1119
        xor eax,eax
1125
        xor eax,eax
1120
        or  ecx,-1
1126
        or  ecx,-1
1121
        repne scasb
1127
        repne scasb
1122
        add ecx,1
1128
        add ecx,1
1123
        neg ecx
1129
        neg ecx
1124
        sub edi,1
1130
        sub edi,1
1125
        pop eax
1131
        pop eax
1126
        std
1132
        std
1127
        repne scasb
1133
        repne scasb
1128
        cld
1134
        cld
1129
        add edi,1
1135
        add edi,1
1130
 
1136
 
1131
        cmp [edi],al
1137
        cmp [edi],al
1132
        jne @F
1138
        jne @F
1133
        mov eax,edi
1139
        mov eax,edi
1134
        ret
1140
        ret
1135
@@:
1141
@@:
1136
        xor eax,eax
1142
        xor eax,eax
1137
        ret
1143
        ret
1138
 
1144
 
1139
align 4
1145
align 4
1140
proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
1146
proc k_strncpy stdcall, dest:dword, src:dword, maxlen:dword
1141
        mov eax, [dest]
1147
        mov eax, [dest]
1142
        mov esi, [src]
1148
        mov esi, [src]
1143
        mov ecx, [maxlen]
1149
        mov ecx, [maxlen]
1144
        test eax, eax
1150
        test eax, eax
1145
        jz .L9
1151
        jz .L9
1146
        test esi, esi
1152
        test esi, esi
1147
        jz .L9
1153
        jz .L9
1148
        test ecx, ecx
1154
        test ecx, ecx
1149
        jz .L9
1155
        jz .L9
1150
 
1156
 
1151
        sub  esi, eax
1157
        sub  esi, eax
1152
        jmp .L1
1158
        jmp .L1
1153
 
1159
 
1154
align 4
1160
align 4
1155
.L2:
1161
.L2:
1156
        mov edx, [esi+eax]
1162
        mov edx, [esi+eax]
1157
        mov [eax], dl
1163
        mov [eax], dl
1158
        test dl, dl
1164
        test dl, dl
1159
        jz .L7
1165
        jz .L7
1160
 
1166
 
1161
        mov [eax+1], dh
1167
        mov [eax+1], dh
1162
        test dh, dh
1168
        test dh, dh
1163
        jz .L6
1169
        jz .L6
1164
 
1170
 
1165
        shr edx, 16
1171
        shr edx, 16
1166
        mov [eax+2],dl
1172
        mov [eax+2],dl
1167
        test dl, dl
1173
        test dl, dl
1168
        jz .L5
1174
        jz .L5
1169
 
1175
 
1170
        mov [eax+3], dh
1176
        mov [eax+3], dh
1171
        test dh, dh
1177
        test dh, dh
1172
        jz .L4
1178
        jz .L4
1173
        add eax, 4
1179
        add eax, 4
1174
.L1:
1180
.L1:
1175
        sub ecx, 4
1181
        sub ecx, 4
1176
        jae .L2
1182
        jae .L2
1177
 
1183
 
1178
        add ecx, 4
1184
        add ecx, 4
1179
        jz .L9
1185
        jz .L9
1180
 
1186
 
1181
        mov dl, [eax+esi]
1187
        mov dl, [eax+esi]
1182
        mov [eax], dl
1188
        mov [eax], dl
1183
        test dl, dl
1189
        test dl, dl
1184
        jz .L3
1190
        jz .L3
1185
 
1191
 
1186
        inc eax
1192
        inc eax
1187
        dec ecx
1193
        dec ecx
1188
        jz .L9
1194
        jz .L9
1189
 
1195
 
1190
        mov dl, [eax+esi]
1196
        mov dl, [eax+esi]
1191
        mov [eax], dl
1197
        mov [eax], dl
1192
        test dl, dl
1198
        test dl, dl
1193
        jz .L3
1199
        jz .L3
1194
 
1200
 
1195
        inc eax
1201
        inc eax
1196
        dec ecx
1202
        dec ecx
1197
        jz .L9
1203
        jz .L9
1198
 
1204
 
1199
        mov dl, [eax+esi]
1205
        mov dl, [eax+esi]
1200
        mov [eax], dl
1206
        mov [eax], dl
1201
        test dl, dl
1207
        test dl, dl
1202
        jz .L3
1208
        jz .L3
1203
 
1209
 
1204
        inc eax
1210
        inc eax
1205
        jmp .L9
1211
        jmp .L9
1206
 
1212
 
1207
.L4:    dec ecx
1213
.L4:    dec ecx
1208
        inc eax
1214
        inc eax
1209
 
1215
 
1210
.L5:    dec ecx
1216
.L5:    dec ecx
1211
        inc eax
1217
        inc eax
1212
 
1218
 
1213
.L6:    dec ecx
1219
.L6:    dec ecx
1214
        inc eax
1220
        inc eax
1215
.L7:
1221
.L7:
1216
        add ecx,3
1222
        add ecx,3
1217
        jz .L9
1223
        jz .L9
1218
.L8:
1224
.L8:
1219
        mov byte [ecx+eax], 0
1225
        mov byte [ecx+eax], 0
1220
.L3:
1226
.L3:
1221
        dec ecx
1227
        dec ecx
1222
        jnz .L8
1228
        jnz .L8
1223
.L9:
1229
.L9:
1224
	ret
1230
	ret
1225
endp
1231
endp
1226
 
1232
 
1227
if 0
1233
if 0
1228
 
1234
 
1229
magic equ 0xfefefeff
1235
magic equ 0xfefefeff
1230
 
1236
 
1231
k_strlen:
1237
k_strlen:
1232
        mov eax,[esp+4]
1238
        mov eax,[esp+4]
1233
        mov edx, 3
1239
        mov edx, 3
1234
 
1240
 
1235
        and edx, eax
1241
        and edx, eax
1236
        jz .L1
1242
        jz .L1
1237
        jp .L0
1243
        jp .L0
1238
 
1244
 
1239
        cmp dh, byte [eax]
1245
        cmp dh, byte [eax]
1240
        je .L2
1246
        je .L2
1241
 
1247
 
1242
        inc eax
1248
        inc eax
1243
        cmp dh, byte [eax]
1249
        cmp dh, byte [eax]
1244
 
1250
 
1245
        je .L2
1251
        je .L2
1246
 
1252
 
1247
        inc eax
1253
        inc eax
1248
        xor edx, 2
1254
        xor edx, 2
1249
 
1255
 
1250
        jz .L1
1256
        jz .L1
1251
.L0:
1257
.L0:
1252
        cmp dh, [eax]
1258
        cmp dh, [eax]
1253
        je .L2
1259
        je .L2
1254
 
1260
 
1255
        inc eax
1261
        inc eax
1256
        xor edx, edx
1262
        xor edx, edx
1257
 
1263
 
1258
.L1:
1264
.L1:
1259
        mov ecx, [eax]
1265
        mov ecx, [eax]
1260
        add eax, 4
1266
        add eax, 4
1261
 
1267
 
1262
        sub edx, ecx
1268
        sub edx, ecx
1263
        add ecx, magic
1269
        add ecx, magic
1264
 
1270
 
1265
        dec edx
1271
        dec edx
1266
        jnc .L3
1272
        jnc .L3
1267
 
1273
 
1268
        xor edx, ecx
1274
        xor edx, ecx
1269
        and edx, not magic
1275
        and edx, not magic
1270
        jne .L3
1276
        jne .L3
1271
 
1277
 
1272
        mov ecx, [eax]
1278
        mov ecx, [eax]
1273
        add eax, 4
1279
        add eax, 4
1274
 
1280
 
1275
        sub edx, ecx
1281
        sub edx, ecx
1276
        add ecx, magic
1282
        add ecx, magic
1277
        dec edx
1283
        dec edx
1278
        jnc .L3
1284
        jnc .L3
1279
 
1285
 
1280
        xor edx, ecx
1286
        xor edx, ecx
1281
        and edx, not magic
1287
        and edx, not magic
1282
        jne .L3
1288
        jne .L3
1283
 
1289
 
1284
        mov ecx, [eax]
1290
        mov ecx, [eax]
1285
        add eax, 4
1291
        add eax, 4
1286
 
1292
 
1287
        sub edx, ecx
1293
        sub edx, ecx
1288
        add ecx, magic
1294
        add ecx, magic
1289
 
1295
 
1290
        dec edx
1296
        dec edx
1291
        jnc .L3
1297
        jnc .L3
1292
 
1298
 
1293
        xor edx, ecx
1299
        xor edx, ecx
1294
 
1300
 
1295
        and edx, not magic
1301
        and edx, not magic
1296
        jne .L3
1302
        jne .L3
1297
 
1303
 
1298
        mov ecx, [eax]
1304
        mov ecx, [eax]
1299
        add eax, 4
1305
        add eax, 4
1300
 
1306
 
1301
        sub edx, ecx
1307
        sub edx, ecx
1302
        add ecx, magic
1308
        add ecx, magic
1303
 
1309
 
1304
        dec edx
1310
        dec edx
1305
        jnc .L3
1311
        jnc .L3
1306
 
1312
 
1307
        xor edx, ecx
1313
        xor edx, ecx
1308
 
1314
 
1309
        and edx, not magic
1315
        and edx, not magic
1310
        je .L1
1316
        je .L1
1311
 
1317
 
1312
.L3:    sub eax ,4
1318
.L3:    sub eax ,4
1313
        sub ecx, magic
1319
        sub ecx, magic
1314
 
1320
 
1315
        cmp cl, 0
1321
        cmp cl, 0
1316
        jz .L2
1322
        jz .L2
1317
 
1323
 
1318
        inc eax
1324
        inc eax
1319
        test ch, ch
1325
        test ch, ch
1320
        jz .L2
1326
        jz .L2
1321
 
1327
 
1322
        shr ecx, 16
1328
        shr ecx, 16
1323
        inc eax
1329
        inc eax
1324
 
1330
 
1325
        cmp cl,0
1331
        cmp cl,0
1326
        jz .L2
1332
        jz .L2
1327
 
1333
 
1328
        inc eax
1334
        inc eax
1329
 
1335
 
1330
.L2:
1336
.L2:
1331
        sub eax, [esp+4]
1337
        sub eax, [esp+4]
1332
	ret
1338
	ret
1333
 
1339
 
1334
end if
1340
end if
1335
 
1341
 
1336
if 0
1342
if 0
1337
     push eax
1343
     push eax
1338
     push edx
1344
     push edx
1339
     mov edx, 0x400   ;bochs
1345
     mov edx, 0x400   ;bochs
1340
     mov al,0xff      ;bochs
1346
     mov al,0xff      ;bochs
1341
     out dx, al       ;bochs
1347
     out dx, al       ;bochs
1342
     pop edx
1348
     pop edx
1343
     pop eax
1349
     pop eax
1344
end if
1350
end if