Subversion Repositories Kolibri OS

Rev

Rev 133 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ha 1
if ~defined newprocess_inc
2
newprocess_inc_fix:
3
newprocess_inc fix newprocess_inc_fix
4
include "mem.inc"
5
include "memmanag.inc"
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
;;Working with new types of processes.
8
;;Author: Khalyavin Andrey halyavin@land.ru
9
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
10
iglobal
11
    new_process_loading db 'K : New Process - loading',13,10,0
12
    new_process_running db 'K : New Process - done',13,10,0
13
    start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
14
endg
15
;-----------------------------------------------------------------------------
16
 
17
find_new_process_place:
18
;input:
19
;  none
20
;result:
21
;  eax=[new_process_place]<>0 - ok
22
;      0 - failed.
23
;This function find least empty slot.
24
;It doesn't increase [0x3004]!
25
    mov    eax,0x3000+second_base_address
26
    push   ebx
27
    mov    ebx,[0x3004]
28
    inc    ebx
29
    shl    ebx,5
30
    add    ebx,eax               ;ebx - address of process information for (last+1) slot
31
.newprocessplace:
32
;eax = address of process information for current slot
33
    cmp    eax,ebx
34
    jz     .endnewprocessplace   ;empty slot after high boundary
35
    add    eax,0x20
115 poddubny 36
    cmp    word [eax+TASKDATA.state],9      ;check process state, 9 means that process slot is empty
1 ha 37
    jnz    .newprocessplace
38
.endnewprocessplace:
39
    mov    ebx,eax
40
    sub    eax,0x3000+second_base_address
41
    shr    eax,5                 ;calculate slot index
42
    cmp    eax,256
43
    jge    .failed               ;it should be <256
115 poddubny 44
    mov    word [ebx+TASKDATA.state],9      ;set process state to 9 (for slot after hight boundary)
1 ha 45
    mov    [new_process_place],eax ;save process slot
46
    pop    ebx
47
    ret
48
.failed:
49
    xor    eax,eax
50
    pop    ebx
51
    ret
52
;-----------------------------------------------------------------------------
4 poddubny 53
safe_sti:
54
    cmp    byte [0xe000], 1
55
    jne    @f
56
    sti
57
 @@:ret
58
 
1 ha 59
new_start_application_floppy:
60
;input:
61
;  eax - pointer to filename
62
;  ebx - parameters to pass
40 halyavin 63
;  edx - flags
1 ha 64
;result:
65
;  eax - pid of new process
66
;        or 0 if call fails.
5 halyavin 67
    mov    [appl_path],edi
1 ha 68
    pushad
69
    mov    esi,new_process_loading
70
    call   sys_msg_board_str     ;write to debug board
71
 
72
;wait application_table_status mutex
73
.table_status:
74
    cli
75
    cmp    [application_table_status],0
76
    jz     .stf
77
    sti
78
    call   change_task
79
    jmp    .table_status
80
.stf:
81
    call   set_application_table_status
82
;we can change system tables now
83
    push   edi
84
    push   ebx
85
    push   eax
86
    call   find_new_process_place ;find empty process slot
87
    sti
88
    test   eax,eax
61 halyavin 89
	mov	ecx, -0x20	; too many processes
1 ha 90
    jz     .failed
91
 
92
    mov    edi,eax
93
    shl    edi,8
94
    add    edi,0x80000
95
    mov    ecx,256/4
96
    xor    eax,eax
97
    cld
98
    rep    stosd                 ;clean extended information about process
99
 
100
;set new process name
5 halyavin 101
    mov    [appl_path_size],eax
61 halyavin 102
    pop    eax
103
    push   eax
1 ha 104
.find_last_byte:
105
    cmp    byte [eax],0
106
    jz     .find_last_byte_end
107
    inc    eax
5 halyavin 108
    inc    [appl_path_size]
1 ha 109
    jmp    .find_last_byte
5 halyavin 110
.find_last_byte_end:
111
    add    [appl_path_size],24
1 ha 112
    sub    eax,11                ;last 11 bytes = application name
113
;    mov    eax,[esp]             ;eax - pointer to file name
114
    mov    ebx,[new_process_place]
115
    shl    ebx,8
115 poddubny 116
    add    ebx,0x80000 + APPDATA.app_name
1 ha 117
    mov    ecx,11
118
    call   memmove
119
 
120
;read header of file
121
    mov    eax,[esp]
122
    mov    ebx,1                 ;index of first block
123
    mov    ecx,2                 ;number of blocks
124
    mov    edx,0x90000           ;temp area
125
    mov    esi,12                ;file name length
126
    mov    edi,[esp+8]
127
;    cli
128
    call   floppy_fileread       ;read file from FD
129
;    sti
61 halyavin 130
	mov	ecx, eax
131
	neg	ecx
132
	jnz	.cleanfailed
133
;check MENUET signature
134
	mov	ecx, -0x1F	; not Menuet/Kolibri executable
1 ha 135
    cmp    [0x90000],dword 'MENU'
136
    jnz    .cleanfailed
137
    cmp    [0x90004],word 'ET'
138
    jnz    .cleanfailed
139
 
140
    call   get_app_params        ;parse header fields
133 diamond 141
    jc     .cleanfailed
1 ha 142
 
143
    mov    eax,[new_process_place]
61 halyavin 144
    	inc	ecx		; -0x1E = no memory
1 ha 145
    call   create_app_cr3_table   ;create page directory for new process
146
    test   eax,eax
147
    jz     .cleanfailed_mem
148
 
149
    call   MEM_Get_Linear_Address ;calculate linear address of it
150
 
151
    mov    ebx,std_application_base_address
152
    mov    ecx,[app_mem]
153
    add    ecx,4095
154
    shr    ecx,12
155
    mov    edx,eax
156
    call   mem_alloc_specified_region ;allocate memory for application
157
    test   eax,eax
61 halyavin 158
	mov	ecx, -0x1E
9 halyavin 159
    jz     .cleanfailed_mem1
1 ha 160
 
161
    mov    eax,[edx+(std_application_base_address shr 20)]
162
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
163
    call   MEM_Get_Linear_Address
164
    mov    edx,eax
165
 
166
;read file
167
    mov    ebx,1
168
    mov    esi,12                ;length of file name
169
.loop1:
170
;edx = linear address of current page table entry
171
;ebx = index of current block in file
172
    push   edx
173
    mov    eax,[edx]
174
    and    eax,not (4096-1)
175
    call   MEM_Get_Linear_Address
176
    mov    edx,eax               ;read file block to current page
177
    mov    eax,[esp+4]           ;restore pointer to file name
178
    mov    ecx,8                 ;number of blocks read
130 halyavin 179
    mov    ebp,edx               ;save buffer address for .endofimage
1 ha 180
    push   ebx
181
    mov    edi,[esp+16]
182
;    cli
183
    call   floppy_fileread
184
;ebx=file size
185
;    sti
186
    pop    ecx
130 halyavin 187
    add    ecx,8
188
    test   eax,eax
189
    jnz    .endloop1             ;check io errors
190
    mov    eax,[app_i_end]
191
    add    eax,511
192
    shr    eax,9
193
    cmp    ecx,eax
194
    jg     .endofimage           ;we have loaded whole program
195
    add    ebx,511
1 ha 196
    shr    ebx,9
197
    cmp    ecx,ebx
198
    jg     .endloop1             ;if end of file?
199
    mov    ebx,ecx
200
    pop    edx
201
    add    edx,4
202
    jmp    .loop1
203
 
130 halyavin 204
.endofimage:                     ;set to zero memory at end of page
205
    mov    ecx,[app_i_end]
206
    and    ecx,4096-1
207
    jz     .endloop1
208
    lea    edi,[ebp+ecx]
209
    neg    ecx
210
    add    ecx,4096
211
    xor    eax,eax
212
    cld
213
    rep    stosb
1 ha 214
.endloop1:
215
    add    esp,8+4                 ;pop linear address of page table entry and pointer to file name
216
    call   new_start_application_fl.add_app_parameters
217
    mov    [esp+28],eax
218
    popad
219
    ret
9 halyavin 220
 
221
.cleanfailed_mem1:
222
;there is mem for directory entry, but there is no mem for pages
223
;so free directory entry
224
    mov    eax,[new_process_place]
225
    shl    eax,8
115 poddubny 226
    mov    eax,[0x80000+eax+APPDATA.dir_table]
9 halyavin 227
    call   MEM_Free_Page
1 ha 228
.cleanfailed_mem:
9 halyavin 229
;there is no mem for directory entry, display message.
1 ha 230
    mov    esi,start_not_enough_memory
231
    call   sys_msg_board_str
232
.cleanfailed:                    ;clean process name
61 halyavin 233
	push	ecx	; save error code
9 halyavin 234
;can't read file, clean process name.
235
;this avoid problems with panel application.
1 ha 236
    mov    edi,[new_process_place]
237
    shl    edi,8
115 poddubny 238
    add    edi,0x80000 + APPDATA.app_name
1 ha 239
    mov    ecx,11
240
    mov    eax,' '
241
    cld
242
    rep    stosb
61 halyavin 243
	pop	eax
1 ha 244
.failed:
9 halyavin 245
;no more slots
1 ha 246
    add    esp,8+4
247
    mov    [application_table_status],0
61 halyavin 248
    mov    [esp+1Ch], eax
1 ha 249
    popad
250
    sti
251
    ret
252
 
253
;-----------------------------------------------------------------------------
254
new_start_application_fl:
255
;input:
256
;  eax - pointer to filename
257
;  ebx - parameters to pass
40 halyavin 258
;  edx - flags
1 ha 259
;result:
260
;  eax - pid of new process
261
;        or 0 if call fails.
5 halyavin 262
    mov    [appl_path],edi
263
    mov    [appl_path_size],36
1 ha 264
    pushad
265
    mov    esi,new_process_loading
266
    call   sys_msg_board_str     ;write to debug board
267
 
268
;wait application_table_status mutex
269
.table_status:
270
    cli
271
    cmp    [application_table_status],0
272
    jz     .stf
273
    sti
274
    call   change_task
275
    jmp    .table_status
276
.stf:
277
    call   set_application_table_status
278
;we can change system tables now
279
    push   ebx
280
    push   eax
281
    call   find_new_process_place ;find empty process slot
4 poddubny 282
    call   safe_sti
1 ha 283
    test   eax,eax
61 halyavin 284
	mov	ecx, -0x20	; too many processes
1 ha 285
    jz     .failed
286
 
287
    mov    edi,eax
288
    shl    edi,8
289
    add    edi,0x80000
290
    mov    ecx,256/4
291
    xor    eax,eax
292
    cld
293
    rep    stosd                 ;clean extended information about process
294
 
295
;set new process name
296
    mov    eax,[esp]             ;eax - pointer to file name
297
    mov    ebx,[new_process_place]
298
    shl    ebx,8
115 poddubny 299
    add    ebx,0x80000 + APPDATA.app_name
1 ha 300
    mov    ecx,11
301
    call   memmove
302
 
303
;read header of file
304
    mov    ebx,1                 ;index of first block
305
    mov    ecx,2                 ;number of blocks
306
    mov    edx,0x90000           ;temp area
307
    mov    esi,12                ;file name length
308
    cli
309
    call   fileread              ;read file from RD
4 poddubny 310
    call   safe_sti
61 halyavin 311
	mov	ecx, eax
312
	neg	ecx
313
	jnz	.cleanfailed
314
;check MENUET signature
315
	mov	ecx, -0x1F	; not Menuet/Kolibri executable
1 ha 316
    cmp    [0x90000],dword 'MENU'
317
    jnz    .cleanfailed
318
    cmp    [0x90004],word 'ET'
319
    jnz    .cleanfailed
320
 
321
    call   get_app_params        ;parse header fields
133 diamond 322
    jc     .cleanfailed
1 ha 323
 
324
    mov    eax,[new_process_place]
91 diamond 325
    inc    ecx		; -0x1E = no memory
1 ha 326
    call   create_app_cr3_table   ;create page directory for new process
327
    test   eax,eax
328
    jz     .cleanfailed_mem
329
 
330
    call   MEM_Get_Linear_Address ;calculate linear address of it
331
 
332
    mov    ebx,std_application_base_address
333
    mov    ecx,[app_mem]
334
    add    ecx,4095
335
    shr    ecx,12
336
    mov    edx,eax
337
    call   mem_alloc_specified_region ;allocate memory for application
338
    test   eax,eax
61 halyavin 339
	mov	ecx, -0x1E
9 halyavin 340
    jz     .cleanfailed_mem1
1 ha 341
 
342
    mov    eax,[edx+(std_application_base_address shr 20)]
343
    and    eax,not (4096-1)      ;eax - physical address of first (for application memory) page table
344
    call   MEM_Get_Linear_Address
345
    mov    edx,eax
346
 
347
;read file
348
    mov    ebx,1
349
    mov    esi,12                ;length of file name
350
.loop1:
351
;edx = linear address of current page table entry
352
;ebx = index of current block in file
353
    push   edx
354
    mov    eax,[edx]
355
    and    eax,not (4096-1)
356
    call   MEM_Get_Linear_Address
357
    mov    edx,eax               ;read file block to current page
358
    mov    eax,[esp+4]           ;restore pointer to file name
359
    mov    ecx,8                 ;number of blocks read
130 halyavin 360
    mov    ebp,edx               ;save buffer address for .endofimage
1 ha 361
    push   ebx
362
    cli
363
    call   fileread
364
;ebx=file size
4 poddubny 365
    call   safe_sti
1 ha 366
    pop    ecx
130 halyavin 367
    add    ecx,8
368
    test   eax,eax
369
    jnz    .endloop1             ;check io errors
370
    mov    eax,[app_i_end]
371
    add    eax,511
372
    shr    eax,9
373
    cmp    ecx,eax
374
    jg     .endofimage           ;we have loaded whole program
375
    add    ebx,511
1 ha 376
    shr    ebx,9
377
    cmp    ecx,ebx
378
    jg     .endloop1             ;if end of file?
379
    mov    ebx,ecx
380
    pop    edx
381
    add    edx,4
382
    jmp    .loop1
383
 
130 halyavin 384
.endofimage:                     ;set to zero memory at end of page
385
    mov    ecx,[app_i_end]
386
    and    ecx,4096-1
387
    jz     .endloop1
388
    lea    edi,[ebp+ecx]
389
    neg    ecx
390
    add    ecx,4096
391
    xor    eax,eax
392
    cld
393
    rep    stosb
1 ha 394
.endloop1:
395
    add    esp,8                 ;pop linear address of page table entry and pointer to file name
396
    call   .add_app_parameters
397
    mov    [esp+28],eax
398
    popad
399
    ret
400
 
9 halyavin 401
.cleanfailed_mem1:
402
;there is mem for directory entry, but there is no mem for pages
403
;so free directory entry
404
    mov    eax,[new_process_place]
405
    shl    eax,8
115 poddubny 406
    mov    eax,[0x80000+eax+APPDATA.dir_table]
9 halyavin 407
    call   MEM_Free_Page
1 ha 408
.cleanfailed_mem:
9 halyavin 409
;there is no mem for directory entry, display message.
1 ha 410
    mov    esi,start_not_enough_memory
411
    call   sys_msg_board_str
412
.cleanfailed:                    ;clean process name
61 halyavin 413
	push	ecx	; save error code
9 halyavin 414
;can't read file, clean process name.
415
;this avoid problems with panel application.
1 ha 416
    mov    edi,[new_process_place]
417
    shl    edi,8
115 poddubny 418
    add    edi,0x80000+APPDATA.app_name
1 ha 419
    mov    ecx,11
420
    mov    eax,' '
421
    cld
422
    rep    stosb
61 halyavin 423
	pop	eax
1 ha 424
.failed:
9 halyavin 425
;no more slots
1 ha 426
    add    esp,8
427
    mov    [application_table_status],0
61 halyavin 428
    mov    [esp+1Ch], eax
1 ha 429
    popad
4 poddubny 430
    call   safe_sti
1 ha 431
    ret
432
 
433
.add_app_parameters:
434
;input:
435
;  [esp] - pointer to parameters
436
;  [esp+4]-[esp+36] pushad registers.
437
;result
438
;  eax - pid of new process
439
;        or zero if failed
440
    cli
441
    mov    ebx,[new_process_place]
442
    cmp    ebx,[0x3004]
443
    jle    .noinc
444
    inc    dword [0x3004]        ;update number of processes
445
.noinc:
446
 
447
;   mov    ebx,[new_process_place]
448
;set 0x8c field of extended information about process
449
;(size of application memory)
450
    shl    ebx,8
451
    mov    eax,[app_mem]
115 poddubny 452
    mov    [second_base_address+0x80000+APPDATA.mem_size+ebx],eax
1 ha 453
;set 0x10 field of information about process
454
;(application base address)
455
;    mov    ebx,[new_process_place]
456
;    shl    ebx,5
457
    shr    ebx,3
115 poddubny 458
    mov    dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
1 ha 459
 
460
;add command line parameters
461
.add_command_line:
462
    mov    edx,[app_i_param]
463
    test   edx,edx
464
    jz     .no_command_line      ;application don't need parameters
465
    mov    eax,[esp+4]
466
    test   eax,eax
467
    jz     .no_command_line      ;no parameters specified
468
;calculate parameter length
469
    mov    esi,eax
470
    xor    ecx,ecx
139 diamond 471
    inc    ecx          ; include terminating null
1 ha 472
.command_line_len:
473
    cmp    byte [esi],0
474
    jz     .command_line_len_end
475
    inc    esi
476
    inc    ecx
477
    cmp    ecx,256
478
    jl     .command_line_len
479
 
480
.command_line_len_end:
481
;ecx - parameter length
482
;edx - address of parameters in new process address space
483
    mov    ebx,eax               ;ebx - address of parameters in our address space
484
    mov    eax,[new_process_place]
485
    call   write_process_memory  ;copy parameters to new process address space
486
 
487
.no_command_line:
5 halyavin 488
;******************************************************************
489
    mov    edx,[app_i_icon]
490
    test   edx,edx
491
    jz     .no_command_line_1      ;application don't need path of file
492
    mov    ebx,[appl_path]
493
    mov    ecx,[appl_path_size]
494
    mov    eax,[new_process_place]
495
    call   write_process_memory  ;copy path of file to new process address space
496
.no_command_line_1:
497
;******************************************************************
1 ha 498
    mov    ebx,[new_process_place]
499
    mov    eax,ebx
500
    shl    ebx,5
501
    add    ebx,0x3000            ;ebx - pointer to information about process
115 poddubny 502
    mov    [ebx+TASKDATA.wnd_number],al  ;set window number on screen = process slot
1 ha 503
 
115 poddubny 504
    mov    [ebx+TASKDATA.event_mask],dword 1+2+4     ;set default event flags (see 40 function)
1 ha 505
 
506
    inc    dword [process_number]
507
    mov    eax,[process_number]
115 poddubny 508
    mov    [ebx+TASKDATA.pid],eax           ;set PID
1 ha 509
 
510
    mov    ecx,ebx
511
    add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
512
;set draw data to full screen
115 poddubny 513
    mov    [ecx+RECT.left],dword 0
514
    mov    [ecx+RECT.top],dword 0
1 ha 515
    mov    eax,[0xfe00]
115 poddubny 516
    mov    [ecx+RECT.right],eax
1 ha 517
    mov    eax,[0xfe04]
115 poddubny 518
    mov    [ecx+RECT.bottom],eax
41 mikedld 519
;set window state to 'normal' (non-minimized/maximized/rolled-up) state
520
    mov    [ecx+WDATA.fl_wstate],WSTATE_NORMAL
1 ha 521
;set cr3 register in TSS of application
522
    mov    ecx,[new_process_place]
523
    shl    ecx,8
115 poddubny 524
    mov    eax,[0x80000+APPDATA.dir_table+ecx]
1 ha 525
    add    eax,8+16              ;add flags
526
    mov    [l.cr3],eax
527
 
528
    mov    eax,[app_start]
529
    mov    [l.eip],eax           ;set eip in TSS
530
    mov    eax,[app_esp]
531
    mov    [l.esp],eax           ;set stack in TSS
532
 
533
;gdt
4 poddubny 534
    ;mov    ebx,[new_process_place]
535
    ;shl    ebx,3
1 ha 536
    mov    ax,app_code           ;ax - selector of code segment
4 poddubny 537
    ;add    ax,bx
1 ha 538
    mov    [l.cs],ax
539
    mov    ax,app_data
4 poddubny 540
    ;add    ax,bx                 ;ax - selector of data segment
1 ha 541
    mov    [l.ss],ax
542
    mov    [l.ds],ax
543
    mov    [l.es],ax
544
    mov    [l.fs],ax
545
    mov    ax,graph_data         ;ax - selector of graphic segment
546
    mov    [l.gs],ax
547
    mov    [l.io],word 128
548
    mov    [l.eflags],dword 0x11202
549
    mov    [l.ss0],os_data
4 poddubny 550
    mov    ebx,[new_process_place]
551
    shl    ebx,12
14 poddubny 552
    add    ebx,sysint_stack_data+4096
3 halyavin 553
    mov    [l.esp0],ebx
1 ha 554
 
555
;copy tss to it place
556
    mov    eax,tss_sceleton
557
    mov    ebx,[new_process_place]
558
    imul   ebx,tss_step
559
    add    ebx,tss_data          ;ebx - address of application TSS
560
    mov    ecx,120
561
    call   memmove
562
 
563
;Add IO access table - bit array of permitted ports
564
    or     eax,-1
565
    mov    edi,[new_process_place]
566
    imul   edi,tss_step
567
    add    edi,tss_data+128
568
    mov    ecx,2048
569
    cld
570
    rep    stosd                 ;full access to 2048*8=16384 ports
571
 
572
    mov    ecx,ebx               ;ecx - address of application TSS
573
    mov    edi,[new_process_place]
574
    shl    edi,3
575
;set TSS descriptor
576
    mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
577
    mov    [edi+gdts+tss0+2],cx  ;part of offset
578
    mov    eax,ecx
579
    shr    eax,16
580
    mov    [edi+gdts+tss0+4],al  ;part of offset
581
    mov    [edi+gdts+tss0+7],ah  ;part of offset
582
    mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
583
 
584
 
585
;flush keyboard and buttons queue
586
    mov    [0xf400],byte 0
587
    mov    [0xf500],byte 0
588
 
589
    mov    edi,[new_process_place]
590
    shl    edi,5
591
    add    edi,window_data
592
    mov    ebx,[new_process_place]
593
    movzx  esi,word [0xC000+ebx*2]
594
    lea    esi,[0xC400+esi*2]
595
    call   windowactivate        ;gui initialization
596
 
597
    mov    ebx,[new_process_place]
598
    shl    ebx,5
40 halyavin 599
; set if debuggee
91 diamond 600
        test    byte [esp+28], 1
601
        jz      .no_debug
115 poddubny 602
        mov     [0x3000+ebx+TASKDATA.state], 1        ; set process state - suspended
91 diamond 603
        mov     eax, [0x3000]
115 poddubny 604
        mov     [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
91 diamond 605
        jmp     .debug
40 halyavin 606
.no_debug:
115 poddubny 607
        mov     [0x3000+ebx+TASKDATA.state], 0        ; set process state - running
91 diamond 608
.debug:
1 ha 609
 
610
    mov    esi,new_process_running
611
    call   sys_msg_board_str     ;output information about succefull startup
612
 
613
;    add    esp,4                 ;pop pointer to parameters
614
;    popad
615
    mov    eax,[process_number]  ;set result
616
    mov    [application_table_status],0 ;unlock application_table_status mutex
4 poddubny 617
    call   safe_sti
1 ha 618
    ret    4
619
;-----------------------------------------------------------------------------
620
new_sys_threads:
621
;eax=1 - create thread
622
;   ebx=thread start
623
;   ecx=thread stack value
624
;result:
625
;   eax=pid
40 halyavin 626
    xor    edx,edx	; flags=0
1 ha 627
    pushad
628
 
629
    cmp    eax,1
630
    jnz    .ret                  ;other subfunctions
631
    mov    esi,new_process_loading
632
    call   sys_msg_board_str
633
;lock application_table_status mutex
634
.table_status:
635
    cli
636
    cmp    [application_table_status],0
637
    je     .stf
638
    sti
639
    call   change_task
640
    jmp    .table_status
641
.stf:
642
    call   set_application_table_status
643
;find free process slot
644
 
645
    call   find_new_process_place
646
    test   eax,eax
647
    jz     .failed
648
 
649
;set parameters for thread
650
    xor    eax,eax
651
    mov    [app_i_param],eax
652
    mov    [app_i_icon],eax
653
    mov    [app_start],ebx
654
    mov    [app_esp],ecx
655
 
656
    mov    esi,[0x3000]
657
    shl    esi,8
115 poddubny 658
    add    esi,0x80000+APPDATA.app_name
1 ha 659
    mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
660
 
661
    mov    edi,[new_process_place]
662
    shl    edi,8
663
    add    edi,0x80000
115 poddubny 664
    lea    edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
1 ha 665
    mov    ecx,256/4
666
    rep    stosd                 ;clean extended information about new thread
667
    mov    edi,edx
668
    mov    ecx,11
669
    rep    movsb                 ;copy process name
115 poddubny 670
    mov    eax,[ebx+APPDATA.mem_size]
1 ha 671
    mov    [app_mem],eax         ;set memory size
115 poddubny 672
    mov    eax,[ebx+APPDATA.dir_table]
673
    mov    dword [edx-APPDATA.app_name+APPDATA.dir_table],eax        ;copy page directory
1 ha 674
;    mov    eax,[new_process_place]
675
;    mov    ebx,[0x3000]
676
;    call   addreference_app_cr3_table
677
 
678
    push   0                     ;no parameters
679
    call    new_start_application_fl.add_app_parameters ;start thread
680
    mov    [esp+28],eax
681
    popad
682
    ret
683
 
684
.failed:
685
    sti
686
    popad
687
    mov    eax,-1
688
    ret
689
.ret:
690
    popad
691
    ret
692
;-----------------------------------------------------------------------------
693
new_mem_resize:
694
;input:
695
;  ebx - new size
696
;result:
697
;  [esp+36]:=0 - normal
698
;  [esp+36]:=1 - error
699
;This function set new application memory size.
700
    mov    esi,ebx               ;save new size
701
    add    ebx,4095
702
    and    ebx,not (4096-1)      ;round up size
703
    mov    ecx,[0x3000]
704
    shl    ecx,8
115 poddubny 705
    mov    edx,[0x80000 + APPDATA.mem_size +ecx]
1 ha 706
    add    edx,4095
707
    and    edx,not (4096-1)      ;old size
115 poddubny 708
    mov    eax,[0x80000 + APPDATA.dir_table+ecx]
1 ha 709
    call   MEM_Get_Linear_Address
710
;eax - linear address of page directory
711
    call   MEM_Heap_Lock         ;guarantee that two threads willn't
712
                                 ;change memory size simultaneously
713
    cmp    ebx,edx
714
;    mov    esi,ebx               ;save new size
715
    jg     .expand
716
 
717
.free:
718
    sub    edx,ebx
719
    jz     .unlock               ;do nothing
720
    mov    ecx,edx
721
    shr    ecx,12
722
    add    ebx,std_application_base_address
723
    call   mem_free_specified_region  ;free unnecessary pages
724
    jmp    .unlock
725
 
726
.expand:
727
    sub    ebx,edx
728
    mov    ecx,ebx
729
    shr    ecx,12
730
    mov    ebx,edx
731
    add    ebx,std_application_base_address
732
    call   mem_alloc_specified_region ;alloc necessary pages
733
    test   eax,eax
734
    jz     .failed               ;not enough memory
735
 
736
.unlock:
737
    mov    ebx,esi
738
    mov    eax,[0x3000]
739
    shl    eax,8
115 poddubny 740
    mov    [eax+0x80000 + APPDATA.mem_size],ebx     ;write new memory size
1 ha 741
;search threads and update
742
;application memory size infomation
115 poddubny 743
    mov    ecx,[eax+0x80000 + APPDATA.dir_table]
1 ha 744
    mov    eax,2
745
 
746
.search_threads:
747
;eax = current slot
748
;ebx = new memory size
749
;ecx = page directory
750
    cmp    eax,[0x3004]
751
    jg     .search_threads_end
752
    mov    edx,eax
753
    shl    edx,5
115 poddubny 754
    cmp    word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
1 ha 755
    jz     .search_threads_next
756
    shl    edx,3
115 poddubny 757
    cmp    [edx+0x80000+APPDATA.dir_table],ecx     ;if it is our thread?
1 ha 758
    jnz    .search_threads_next
115 poddubny 759
    mov    [edx+0x80000+APPDATA.mem_size],ebx     ;update memory size
1 ha 760
.search_threads_next:
761
    inc    eax
762
    jmp    .search_threads
763
.search_threads_end:
764
 
765
    call   MEM_Heap_UnLock
766
    mov    dword [esp+36],0
767
    ret
768
 
769
.failed:
770
    call   MEM_Heap_UnLock
771
    mov    dword [esp+36],1
772
    ret
773
;-----------------------------------------------------------------------------
774
pid_to_slot:
775
;Input:
776
;  eax - pid of process
777
;Output:
778
;  eax - slot of process or 0 if process don't exists
779
;Search process by PID.
780
    push   ebx
781
    push   ecx
782
    mov    ebx,[0x3004]
783
    shl    ebx,5
784
    mov    ecx,2*32
785
 
786
.loop:
787
;ecx=offset of current process info entry
788
;ebx=maximum permitted offset
115 poddubny 789
    cmp    byte [second_base_address+0x3000+ecx+TASKDATA.state],9
1 ha 790
    jz     .endloop              ;skip empty slots
115 poddubny 791
    cmp    [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID
1 ha 792
    jz     .pid_found
793
.endloop:
794
    add    ecx,32
795
    cmp    ecx,ebx
796
    jle    .loop
797
 
798
    pop    ecx
799
    pop    ebx
800
    xor    eax,eax
801
    ret
802
 
803
.pid_found:
804
    shr    ecx,5
805
    mov    eax,ecx               ;convert offset to index of slot
806
    pop    ecx
807
    pop    ebx
808
    ret
809
;-----------------------------------------------------------------------------
810
is_new_process:
811
;Input:
812
;  eax - process slot
813
;Output:
814
;  eax=1 - it is new process
815
;  eax=0 - it is old process
816
;    shl   eax,5
817
;    mov   eax,[second_base_address+0x3000+eax+0x10]
818
;    cmp   eax,std_application_base_address  ;check base address of application
819
;    jz    .new_process
820
;    xor   eax,eax
821
;    ret
822
 
823
;.new_process:
824
    mov   eax,1
825
    ret
826
;-----------------------------------------------------------------------------
827
write_process_memory:
828
;Input:
829
;  eax - process slot
830
;  ebx - buffer address
831
;  ecx - buffer size
832
;  edx - start address in other process
833
;Output:
834
;  eax - number of bytes written
835
    pushad
836
    shl  eax,8
115 poddubny 837
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 838
    call MEM_Get_Linear_Address
839
    mov  ebp,eax
840
;ebp=linear address of page directory of other process.
841
    add  edx,std_application_base_address  ;convert to linear address
842
    test ecx,ecx
843
    jle  .ret
844
 
845
.write_loop:
846
;ebx = current buffer address
847
;ecx>0 = current size
848
;edx = current address in other process
849
;ebp = linear address of page directory
850
 
851
    call MEM_Heap_Lock           ;cli
852
    mov  esi,edx
853
    shr  esi,22
854
    mov  eax,[ebp+4*esi]         ;find page directory entry
855
    and  eax,not (4096-1)        ;clear flags
856
    test eax,eax
857
    jz   .page_not_found
858
    call MEM_Get_Linear_Address  ;calculate linear address of page table
859
    test eax,eax
860
    jz   .page_not_found
861
    mov  esi,edx
862
    shr  esi,12
863
    and  esi,1023
864
    mov  eax,[eax+4*esi]         ;find page table entry
865
    and  eax,not (4096-1)
866
    test eax,eax
867
    jz   .page_not_found
868
    call MEM_Get_Linear_Address  ;calculate linear address of page
869
    test eax,eax
870
    jz   .page_not_found
871
    mov  edi,eax
872
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
873
    call MEM_Heap_UnLock         ;sti
874
 
875
    mov  esi,edx
876
    and  esi,4095
877
    add  edi,esi                 ;add offset in page
878
;edi = linear address corresponding edx in other process
879
    sub  esi,4096
880
    neg  esi                     ;esi - number of remaining bytes in page
881
    cmp  esi,ecx
882
    jl   .min_ecx
883
    mov  esi,ecx
884
.min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
885
    sub  ecx,esi
886
    push ecx
887
    mov  ecx,esi                 ;ecx - number of bytes to write
888
    mov  esi,ebx                 ;esi - source, edi - destination
889
    add  edx,ecx                 ;move pointer in address space of other process
890
    push edi
891
 
892
;move ecx bytes
893
    test ecx,3
894
    jnz  .not_aligned
895
    shr  ecx,2
896
    rep  movsd
897
    jmp  .next_iter
898
.not_aligned:
899
    rep  movsb
900
.next_iter:
901
 
902
    pop  eax
903
    and  eax,not (4096-1)        ;eax - linear address of current page
904
    call MEM_Free_Page_Linear    ;free reference
905
    mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
906
    pop  ecx                     ;restore number of remaining bytes
907
    test ecx,ecx
908
    jnz  .write_loop
909
.ret:
910
    popad
911
    mov  eax,ecx
912
    ret
913
 
914
.page_not_found:
915
    call MEM_Heap_UnLock         ;error has appeared in critical region
916
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
917
    neg  ecx                     ;ecx=number_of_written_bytes
918
    mov  [esp+28],ecx            ;[esp+28]<-->eax
919
    popad
920
    ret
921
;-----------------------------------------------------------------------------
922
syscall_test:
923
;for testing memory manager from applications.
924
    mov  edx,ecx
925
    mov  ecx,ebx
926
    call trans_address
927
    mov  ebx,eax
928
    mov  eax,[0x3000]
929
    call read_process_memory
930
    ret
931
;-----------------------------------------------------------------------------
932
read_process_memory:
933
;Input:
934
;  eax - process slot
935
;  ebx - buffer address
936
;  ecx - buffer size
937
;  edx - start address in other process
938
;Output:
939
;  eax - number of bytes read.
940
    pushad
941
    shl  eax,8
115 poddubny 942
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 943
    call MEM_Get_Linear_Address
944
    mov  ebp,eax
945
    add  edx,std_application_base_address
946
.read_loop:
947
;ebx = current buffer address
948
;ecx>0 = current size
949
;edx = current address in other process
950
;ebp = linear address of page directory
951
 
952
    call MEM_Heap_Lock           ;cli
953
    mov  esi,edx
954
    shr  esi,22
955
    mov  eax,[ebp+4*esi]         ;find page directory entry
956
    and  eax,not (4096-1)
957
    test eax,eax
958
    jz   .page_not_found
959
    call MEM_Get_Linear_Address
960
    test eax,eax
961
    jz   .page_not_found
962
    mov  esi,edx
963
    shr  esi,12
964
    and  esi,1023
965
    mov  eax,[eax+4*esi]         ;find page table entry
966
    and  eax,not (4096-1)
967
    test eax,eax
968
    jz   .page_not_found
969
    call MEM_Get_Linear_Address  ;calculate linear address of page
970
    test eax,eax
971
    jz   .page_not_found
972
    mov  esi,eax
973
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
974
    call MEM_Heap_UnLock         ;sti
975
 
976
    mov  edi,edx
977
    and  edi,4095
978
    add  esi,edi                 ;add offset in page
979
;esi = linear address corresponding edx in other process
980
    sub  edi,4096
981
    neg  edi
982
 
983
;edi=min(edi,ecx) - number of bytes to copy
984
    cmp  edi,ecx
985
    jl   .min_ecx
986
    mov  edi,ecx
987
.min_ecx:
988
 
989
    sub  ecx,edi                 ;update size of remaining bytes
990
    add  edx,edi                 ;update current pointer in other address space.
991
    push ecx
992
    mov  ecx,edi                 ;ecx - number of bytes to read
993
    mov  edi,ebx                 ;esi - source, edi - destination
994
    push esi
995
;move ecx bytes
996
    test ecx,3
997
    jnz  .not_aligned
998
    shr  ecx,2
999
    rep  movsd
1000
    jmp  .next_iter
1001
.not_aligned:
1002
    rep  movsb
1003
.next_iter:
1004
    pop  eax
1005
    and  eax,not (4096-1)        ;eax - linear address of current page
1006
    call MEM_Free_Page_Linear    ;free reference
1007
    mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
1008
    pop  ecx                     ;restore number of remaining bytes
1009
    test ecx,ecx
1010
    jnz  .read_loop
1011
 
1012
    popad
1013
    mov  eax,ecx
1014
    ret
1015
 
1016
.page_not_found:
1017
    call MEM_Heap_UnLock         ;error has appeared in critical region
1018
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
1019
    neg  ecx                     ;ecx=number_of_read_bytes
1020
    mov  [esp+28],ecx            ;[esp+28]<-->eax
1021
    popad
1022
    ret
1023
;-----------------------------------------------------------------------------
1024
check_region:
1025
;input:
1026
;  ebx - start of buffer
1027
;  ecx - size of buffer
1028
;result:
1029
;  eax = 1 region lays in app memory
1030
;  eax = 0 region don't lays in app memory
1031
    mov  eax,[0x3000]
1032
    jmp  check_process_region
1033
;-----------------------------------------------------------------------------
1034
check_process_region:
1035
;input:
1036
;  eax - slot
1037
;  ebx - start of buffer
1038
;  ecx - size of buffer
1039
;result:
1040
;  eax = 1 region lays in app memory
1041
;  eax = 0 region don't lays in app memory
1042
    test ecx,ecx
1043
    jle  .ok
1044
    shl  eax,5
115 poddubny 1045
    cmp  word [0x3000+eax+TASKDATA.state],0
1 ha 1046
    jnz  .failed
1047
    shl  eax,3
115 poddubny 1048
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 1049
    test eax,eax
1050
    jz   .failed
1051
    call MEM_Get_Linear_Address
1052
    push ebx
1053
    push ecx
1054
    push edx
1055
    mov  edx,ebx
1056
    and  edx,not (4096-1)
1057
    sub  ebx,edx
1058
    add  ecx,ebx
1059
    mov  ebx,edx
1060
    add  ecx,(4096-1)
1061
    and  ecx,not (4096-1)
1062
.loop:
1063
;eax - linear address of page directory
1064
;ebx - current page
1065
;ecx - current size
1066
    mov  edx,ebx
1067
    shr  edx,22
1068
    mov  edx,[eax+4*edx]
1069
    and  edx,not (4096-1)
1070
    test edx,edx
1071
    jz   .failed1
1072
    push eax
1073
    mov  eax,edx
1074
    call MEM_Get_Linear_Address
1075
    mov  edx,ebx
1076
    shr  edx,12
1077
    and  edx,(1024-1)
1078
    mov  eax,[eax+4*edx]
1079
    and  eax,not (4096-1)
1080
    test eax,eax
1081
    pop  eax
1082
    jz   .failed1
1083
    add  ebx,4096
1084
    sub  ecx,4096
1085
    jg   .loop
1086
    pop  edx
1087
    pop  ecx
1088
    pop  ebx
1089
.ok:
1090
    mov  eax,1
1091
    ret
1092
 
1093
.failed1:
1094
    pop  edx
1095
    pop  ecx
1096
    pop  ebx
1097
.failed:
1098
    xor  eax,eax
1099
    ret
1100
;-----------------------------------------------------------------------------
1101
new_sys_ipc:
1102
;input:
1103
;  eax=1 - set ipc buffer area
1104
;    ebx=address of buffer
1105
;    ecx=size of buffer
1106
;  eax=2 - send message
1107
;    ebx=PID
1108
;    ecx=address of message
1109
;    edx=size of message
1110
    cmp  eax,1
1111
    jnz  .no_ipc_def
1112
;set ipc buffer area
1113
    mov  edi,[0x3000]
1114
    shl  edi,8
1115
    add  edi,0x80000
1116
    cli
115 poddubny 1117
    mov  [edi+APPDATA.ipc_start],ebx          ;set fields in extended information area
1118
    mov  [edi+APPDATA.ipc_size],ecx
1 ha 1119
    sti
1120
    mov  [esp+36],dword 0        ;success
1121
    ret
1122
 
1123
.no_ipc_def:
1124
    cmp  eax,2
1125
    jnz  .no_ipc_send
1126
;send message
1127
    cli
1128
;obtain slot from PID
1129
    mov  eax,ebx
1130
    call pid_to_slot
1131
    test eax,eax
1132
    jz   .no_pid
1133
    mov  ebp,eax
1134
;ebp = slot of other process
1135
    shl  eax,8
115 poddubny 1136
    mov  edi,[eax+0x80000+APPDATA.ipc_start]  ;is ipc area defined?
1 ha 1137
    test edi,edi
1138
    jz   .no_ipc_area
115 poddubny 1139
    mov  esi,[eax+0x80000+APPDATA.ipc_size]  ;esi - size of buffer
1 ha 1140
    push dword -1                ;temp variable for read_process_memory
1141
    mov  ebx,esp
1142
    push ecx
1143
    push edx
1144
    mov  ecx,4                   ;read 4 bytes
1145
    mov  eax,ebp
1146
    mov  edx,edi                 ;from beginning of buffer.
1147
    call read_process_memory
1148
    mov  eax,[esp+8]
1149
    test eax,eax
1150
    jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
1151
    add  edx,4                   ;move to next 4 bytes
1152
    mov  eax,ebp
1153
    call read_process_memory     ;read size of occupied space in buffer
1154
    sub  esi,8
1155
    sub  esi,[esp]
1156
    sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
1157
    js   .buffer_overflow        ;esi<0 - not enough memory in buffer
1158
    mov  esi,[esp+8]             ;previous offset
1159
    add  dword [esp+8],8
1160
    mov  edi,[esp]
1161
    add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
1162
    mov  eax,ebp
1163
    call write_process_memory
1164
    add  edx,esi
1165
    sub  edx,4                   ;move to beginning of place for our message
1166
    mov  eax,[second_base_address+0x3010]
115 poddubny 1167
    mov  eax,[eax+TASKDATA.pid]           ;eax - our PID
1 ha 1168
    mov  [esp+8],eax
1169
    mov  eax,ebp
1170
    call write_process_memory    ;write PID
1171
    mov  ebx,esp                 ;address of size of message
1172
    mov  eax,ebp
1173
    add  edx,4
1174
    call write_process_memory    ;write size of message
1175
    add  edx,4
1176
    pop  ecx                     ;ecx - size of message
1177
    pop  eax
1178
    call trans_address
1179
    mov  ebx,eax                 ;ebx - linear address of message
1180
    add  esp,4                   ;pop temporary variable
1181
    mov  eax,ebp
1182
    call write_process_memory    ;write message
1183
    sti
1184
;awake other process
1185
    shl  ebp,8
1186
    mov  eax,ebp
115 poddubny 1187
    or   [eax+0x80000+APPDATA.event_mask],dword 0x40
1 ha 1188
 
1189
    cmp  dword [check_idle_semaphore],20
1190
    jge  .ipc_no_cis
1191
    mov  dword [check_idle_semaphore],5
1192
.ipc_no_cis:
1193
    mov  dword [esp+36],0
1194
    ret
1195
.no_ipc_send:
1196
    mov  dword [esp+36],-1
1197
    ret
1198
.no_pid:
1199
    sti
1200
    mov  dword [esp+36],4
1201
    ret
1202
.no_ipc_area:
1203
    sti
1204
    mov  dword [esp+36],1
1205
    ret
1206
.ipc_blocked:
1207
    sti
1208
    add  esp,12
1209
    mov  dword [esp+36],2
1210
    ret
1211
.buffer_overflow:
1212
    sti
1213
    add  esp,12
1214
    mov  dword [esp+36],3
1215
    ret
1216
;-----------------------------------------------------------------------------
1217
trans_address:
1218
;Input
1219
;  eax - application address
1220
;Output
1221
;  eax - linear address for kernel
1222
    add   eax,std_application_base_address
1223
    ret
1224
;-----------------------------------------------------------------------------
1225
new_start_application_hd:
1226
;eax - file name (kernel address)
1227
;ebx - file name length
1228
;ecx - work area (kernel address)
40 halyavin 1229
;edx - flags
1 ha 1230
;ebp - parameters
5 halyavin 1231
    mov    [appl_path],edi
1 ha 1232
    pushad
1233
 
1234
    mov    esi,new_process_loading
1235
    call   sys_msg_board_str     ;write message to message board
1236
 
1237
;lock application_table_status mutex
1238
.table_status:
1239
    cli
1240
    cmp    [application_table_status],0
1241
    jz     .stf
1242
    sti
1243
    call   change_task
1244
    jmp    .table_status
1245
.stf:
1246
    call   set_application_table_status
1247
 
1248
    push   ebp
1249
    push   ebx
1250
    push   eax
1251
    push   ecx
1252
    call   find_new_process_place ;find new process slot
1253
    sti
1254
    test   eax,eax
61 halyavin 1255
	mov	ecx, -0x20	; too many processes
1 ha 1256
    jz     .failed
1257
 
5 halyavin 1258
;write application name
1259
    xor    eax,eax
1260
    mov    [appl_path_size],eax
1 ha 1261
    mov    eax,[esp+4]
1262
.find_last_byte:
1263
    cmp    byte [eax],0
1264
    jz     .find_last_byte_end
1265
    inc    eax
5 halyavin 1266
    inc    [appl_path_size]
1 ha 1267
    jmp    .find_last_byte
5 halyavin 1268
.find_last_byte_end:
1269
    add    [appl_path_size],24
1 ha 1270
    lea    esi,[eax-11]          ;last 11 bytes = application name
1271
    mov    edi,[new_process_place]
1272
    shl    edi,8
115 poddubny 1273
    add    edi,0x80000+APPDATA.app_name
1 ha 1274
    mov    ecx,11
1275
    cld
1276
    rep    movsb                 ;copy name to extended information about process
1277
 
1278
;read header
1279
    mov    eax,[esp+4]           ;file name
1280
    mov    esi,[esp]             ;work area
1281
    mov    ecx,1                 ;read from first block
1282
    mov    edx,1                 ;read 1 block
1283
    call   read_hd_file
61 halyavin 1284
	mov	ecx, eax
1285
	neg	ecx
1286
	jnz	.cleanfailed
1 ha 1287
 
61 halyavin 1288
    pop    esi
1289
    push   esi
1290
;check menuet signature
1291
	mov	ecx, -0x1F	; not Menuet/Kolibri executable
1 ha 1292
    cmp    [esi+1024+0],dword 'MENU'  ;read_hd_file function write file to +1024 offset
1293
    jnz    .cleanfailed
1294
    cmp    [esi+1024+4],word 'ET'
1295
    jnz    .cleanfailed
1296
    add    esi,1024
1297
    mov    edi,0x90000
1298
    mov    ecx,512/4
1299
    cld
1300
    rep    movsd                 ;copy first block to 0x90000 address for get_app_params function
1301
    call   get_app_params
61 halyavin 1302
	mov	ecx, -0x1F	; not Menuet/Kolibri executable
133 diamond 1303
    jc     .cleanfailed
1 ha 1304
 
1305
    mov    eax,[new_process_place]
91 diamond 1306
	inc	ecx		; -0x1E = no memory
1 ha 1307
    call   create_app_cr3_table  ;create page directory
1308
    test   eax,eax
1309
    jz     .cleanfailed_mem
1310
 
1311
    call   MEM_Get_Linear_Address
1312
 
1313
    mov    ebx,std_application_base_address
1314
    mov    ecx,[app_mem]
1315
    add    ecx,4096-1
1316
    shr    ecx,12
1317
    mov    edx,eax               ;edx - linear address of page directory
1318
    call   mem_alloc_specified_region ;allocate memory for application
61 halyavin 1319
	mov	ecx, -0x1E	; no memory
1 ha 1320
    test   eax,eax
9 halyavin 1321
    jz     .cleanfailed_mem1
1 ha 1322
 
1323
    add    edx,(std_application_base_address shr 20)
1324
    mov    eax,[edx]
1325
    and    eax,not (4096-1)
1326
    call   MEM_Get_Linear_Address
1327
    push   edx                   ;save pointer to first page table
1328
    mov    edx,eax
1329
;read file
1330
    mov    ecx,1
1331
    xor    ebp,ebp
1332
.loop1:
1333
;[esp] - pointer to current page directory entry
1334
;edx - pointer to current page table
1335
;ebp - offset in page
1336
;ecx - current cluster
1337
    push   edx
1338
    mov    eax,[esp+12]          ;file name
1339
    mov    ebx,[esp+16]          ;file name length
1340
    mov    esi,[esp+8]           ;work area
1341
    mov    edx,1                 ;number of blocks to read
1342
    push   ecx
1343
    push   ebp
1344
    cli
1345
    call   read_hd_file
1346
    sti
1347
    pop    ebp
1348
    test   eax,eax
1349
    jnz    .endloop1             ;check io errors
1350
 
1351
    mov    esi,[esp+8+4]         ;work area
1352
    add    esi,1024
1353
    mov    eax,[esp+4]           ;current page table
1354
    mov    eax,[eax]
1355
    and    eax,not (4096-1)
1356
    call   MEM_Get_Linear_Address;calculate linear page address
1357
    lea    edi,[eax+ebp]         ;add page offset
1358
    mov    ecx,512/4
1359
    cld
1360
    rep    movsd                 ;copy data
1361
 
1362
    pop    ecx
1363
    inc    ecx                   ;next block
1364
    mov    eax,[app_i_end] ;todo: precalculate ([app_i_end]+4095)/4096
1365
    add    eax,512-1
1366
    shr    eax,9                 ;calculate application image size
1367
    cmp    ecx,eax
1368
    jg     .endloop11
1369
    pop    edx
1370
    add    ebp,512               ;new offset
1371
    test   ebp,4096
1372
    jz     .loop1
1373
    xor    ebp,ebp
1374
    add    edx,4                 ;go to next page
1375
    test   edx,(4096-1)
1376
    jnz    .loop1
1377
    add    dword [esp],4         ;go to next directory entry
1378
    mov    eax,[esp]
1379
    mov    eax,[eax]
1380
    and    eax,not (4096-1)
1381
    call   MEM_Get_Linear_Address
1382
    mov    edx,eax
1383
    jmp    .loop1
1384
.endloop1:
1385
    add    esp,4                 ;pop ecx
1386
.endloop11:
1387
    add    esp,4+4               ;pop edx, pop edx
1388
 
1389
;add_app_parameters
1390
    add    esp,12                ;now pointer to parameters is on the top of the stack
1391
    call   new_start_application_fl.add_app_parameters ;start process
1392
    mov    [esp+28],eax
1393
    popad
1394
    ret
1395
 
9 halyavin 1396
.cleanfailed_mem1:
1397
;there is mem for directory entry, but there is no mem for pages
1398
;so free directory entry
1399
    mov    eax,[new_process_place]
1400
    shl    eax,8
115 poddubny 1401
    mov    eax,[0x80000+eax+APPDATA.dir_table]
9 halyavin 1402
    call   MEM_Free_Page
1 ha 1403
.cleanfailed_mem:
9 halyavin 1404
;there is no mem for directory entry, display message.
1 ha 1405
    mov    esi,start_not_enough_memory
1406
    call   sys_msg_board_str
1407
.cleanfailed:                    ;clean process name
61 halyavin 1408
	push	ecx
9 halyavin 1409
;can't read file, clean process name.
1410
;this avoid problems with panel application.
1 ha 1411
    mov    edi,[new_process_place]
1412
    shl    edi,8
115 poddubny 1413
    add    edi,0x80000+APPDATA.app_name
1 ha 1414
    mov    ecx,11
1415
    mov    eax,' '
1416
    cld
61 halyavin 1417
    rep    stosb
1418
	pop	eax
1 ha 1419
.failed:
9 halyavin 1420
;no more slots
1 ha 1421
    add    esp,16
61 halyavin 1422
    mov    [esp+1Ch], eax
1423
    popad
1 ha 1424
    mov    [application_table_status],0
1425
    sti
1426
    ret
1427
end if
40 halyavin 1428
 
91 diamond 1429
; \begin{diamond}
1430
        include 'debug.inc'
1431
 
1432
fs_execute:
1433
; ebx - cmdline
1434
; edx - flags
1435
; ebp - full filename
1436
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
1437
        pushad
1438
; check filename length - with terminating NULL must be no more than 1024 symbols
1439
        mov     edi, ebp
1440
        mov     ecx, 1024
1441
        xor     eax, eax
1442
        repnz   scasb
1443
        jz      @f
1444
        popad
1445
        mov     eax, -ERROR_FILE_NOT_FOUND
1446
        ret
1447
@@:
1448
 
1449
        mov     esi, new_process_loading
1450
        call    sys_msg_board_str       ; write message to message board
1451
 
1452
; lock application_table_status mutex
1453
.table_status:
1454
        cli
1455
        cmp     [application_table_status], 0
1456
        jz      .stf
1457
        sti
1458
        call    change_task
1459
        jmp     .table_status
1460
.stf:
1461
        call    set_application_table_status
1462
        push    ebx     ; save command line pointer for add_app_parameters
1463
 
1464
        call    find_new_process_place  ; find new process slot
1465
        call    safe_sti
1466
        test    eax, eax
1467
        mov     ecx, -0x20      ; too many processes
1468
        jz      .failed
1469
 
1470
; write application name
1471
        push    edi
1472
        mov     ecx, edi
1473
        sub     ecx, ebp
1474
        mov     [appl_path], ebp
1475
        mov     [appl_path_size], ecx
1476
        dec     edi
1477
        std
1478
        mov     al, '/'
1479
        repnz   scasb
1480
        cld
1481
        jnz     @f
1482
        inc     edi
1483
@@:
1484
        inc     edi
1485
; now edi points to name without path
1486
        mov     esi, edi
1487
        mov     ecx, 8  ; 8 chars for name
1488
        mov     edi, [new_process_place]
1489
        shl     edi, cl
115 poddubny 1490
        add     edi, 0x80000+APPDATA.app_name
91 diamond 1491
.copy_process_name_loop:
1492
        lodsb
1493
        cmp     al, '.'
1494
        jz      .copy_process_name_done
1495
        test    al, al
1496
        jz      .copy_process_name_done
1497
        stosb
1498
        loop    .copy_process_name_loop
1499
.copy_process_name_done:
1500
        mov     al, ' '
1501
        rep     stosb
1502
        pop     eax
1503
        mov     cl, 3   ; 3 chars for extension
1504
        dec     esi
1505
@@:
1506
        dec     eax
1507
        cmp     eax, esi
1508
        jbe     .copy_process_ext_done
1509
        cmp     byte [eax], '.'
1510
        jnz     @b
1511
        lea     esi, [eax+1]
1512
.copy_process_ext_loop:
1513
        lodsb
1514
        test    al, al
1515
        jz      .copy_process_ext_done
1516
        stosb
1517
        loop    .copy_process_ext_loop
1518
.copy_process_ext_done:
1519
        mov     al, ' '
1520
        rep     stosb
1521
 
1522
; read header
1523
        lea     eax, [esp+8+36]
1524
        mov     edi, 0x90000
1525
        call    dword [eax-4]
1526
        mov     ecx, eax
1527
        neg     ecx
1528
        jnz     .cleanfailed
1529
; check menuet signature
1530
        mov     ecx, -0x1F
1531
        cmp     dword [0x90000], 'MENU'
1532
        jnz     .cleanfailed
1533
        cmp     word [0x90004], 'ET'
1534
        jnz     .cleanfailed
1535
        call    get_app_params
1536
        mov     ecx, -0x1F
133 diamond 1537
        jc      .cleanfailed
1538
; sanity check - because we will load all file,
1539
; file size must be not greater than memory size
1540
        mov     eax, [esp+8+36]
1541
        cmp     [app_mem], eax
1542
        jb      .cleanfailed
91 diamond 1543
 
1544
        mov     eax, [new_process_place]
1545
        inc     ecx     ; -0x1E = no memory
1546
        call    create_app_cr3_table
1547
        test    eax, eax
1548
        jz      .cleanfailed_mem
1549
 
1550
        call    MEM_Get_Linear_Address
1551
 
1552
        mov     ebx, std_application_base_address
1553
        mov     ecx, [app_mem]
1554
        add     ecx, 4095
1555
        shr     ecx, 12
1556
        mov     edx, eax        ; edx - linear address of page directory
1557
        call    mem_alloc_specified_region
1558
        mov     ecx, -0x1E      ; no memory
1559
        test    eax, eax
1560
        jz      .cleanfailed_mem1
1561
 
1562
        add     edx, std_application_base_address shr 20
1563
        mov     eax, [edx]
1564
        and     eax, not 4095
1565
        call    MEM_Get_Linear_Address
1566
        push    edx             ; save pointer to first page table
1567
        mov     edx, eax
1568
; read file
1569
; first block is already read to 0x90000
1570
        mov     eax, [edx]
1571
        and     eax, not 0xFFF
1572
        call    MEM_Get_Linear_Address
1573
        mov     esi, 0x90000
1574
        mov     edi, eax
1575
        mov     ecx, 512/4
1576
        rep     movsd
1577
        sub     edi, eax
1578
.loop1:
1579
; [esp] = pointer to current page directory entry
1580
; edx = pointer to current page table
1581
; edi = offset in page
1582
        mov     eax, [edx]
1583
        and     eax, not 0xFFF
1584
        call    MEM_Get_Linear_Address
1585
        push    edi
1586
        add     edi, eax
1587
        lea     eax, [esp+8+36+8]
1588
        call    dword [eax-4]
1589
        pop     edi
1590
        test    eax, eax
1591
        jnz     .endloop1
1592
        add     edi, 512        ; new offset
1593
        cmp     edi, 4096
1594
        jb      .loop1
1595
        xor     edi, edi
1596
        add     edx, 4          ; go to next page
1597
        test    edx, 4096-1
1598
        jnz     .loop1
1599
        pop     eax
1600
        add     eax, 4          ; go to next directory entry
1601
        push    eax
1602
        mov     eax, [eax]
1603
        and     eax, not 0xFFF
1604
        call    MEM_Get_Linear_Address
1605
        mov     edx, eax
1606
        jmp     .loop1
1607
.endloop1:
1608
        pop     edx
1609
        cmp     eax, 6
1610
        jnz     .cleanfailed_mem2
1611
        call    new_start_application_fl.add_app_parameters
1612
        mov     [esp+28], eax
1613
        popad
1614
        ret
1615
 
1616
.cleanfailed_mem2:
1617
; file read error; free all allocated mem
1618
        mov     ecx, eax
1619
        neg     ecx
1620
        mov     eax, [new_process_place]
1621
        call    dispose_app_cr3_table
1622
        jmp     .cleanfailed
1623
.cleanfailed_mem1:
1624
; there is mem for directory entry, but there is no mem for pages
1625
; so free directory entry
1626
        mov     eax, [new_process_place]
1627
        shl     eax, 8
1628
        mov     eax, [0x80000+eax+0xB8]
1629
        call    MEM_Free_Page
1630
.cleanfailed_mem:
1631
; there is no mem for directory entry, display message
1632
        mov     esi, start_not_enough_memory
1633
        call    sys_msg_board_str
1634
.cleanfailed:
1635
        push    ecx
1636
; clean process name, this avoid problems with @panel
1637
        mov     edi, [new_process_place]
1638
        shl     edi, 8
115 poddubny 1639
        add     edi, 0x80000+APPDATA.app_name
91 diamond 1640
        mov     ecx, 11
1641
        mov     al, ' '
1642
        rep     stosb
1643
        pop     eax
1644
.failed:
1645
        pop     ebx
1646
        mov     [esp+28], eax
1647
        popad
1648
        mov     [application_table_status], 0
1649
        call    safe_sti
1650
        ret
1651
; \end{diamond}