Subversion Repositories Kolibri OS

Rev

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