Subversion Repositories Kolibri OS

Rev

Rev 139 | 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
1 ha 58
 
59
;-----------------------------------------------------------------------------
60
new_sys_threads:
61
;eax=1 - create thread
62
;   ebx=thread start
63
;   ecx=thread stack value
64
;result:
65
;   eax=pid
40 halyavin 66
    xor    edx,edx	; flags=0
1 ha 67
    pushad
68
 
69
    cmp    eax,1
70
    jnz    .ret                  ;other subfunctions
71
    mov    esi,new_process_loading
72
    call   sys_msg_board_str
73
;lock application_table_status mutex
74
.table_status:
75
    cli
76
    cmp    [application_table_status],0
77
    je     .stf
78
    sti
79
    call   change_task
80
    jmp    .table_status
81
.stf:
82
    call   set_application_table_status
83
;find free process slot
84
 
85
    call   find_new_process_place
86
    test   eax,eax
87
    jz     .failed
88
 
89
;set parameters for thread
90
    xor    eax,eax
91
    mov    [app_i_param],eax
92
    mov    [app_i_icon],eax
93
    mov    [app_start],ebx
94
    mov    [app_esp],ecx
95
 
96
    mov    esi,[0x3000]
97
    shl    esi,8
115 poddubny 98
    add    esi,0x80000+APPDATA.app_name
1 ha 99
    mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
100
 
101
    mov    edi,[new_process_place]
102
    shl    edi,8
103
    add    edi,0x80000
115 poddubny 104
    lea    edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
1 ha 105
    mov    ecx,256/4
106
    rep    stosd                 ;clean extended information about new thread
107
    mov    edi,edx
108
    mov    ecx,11
109
    rep    movsb                 ;copy process name
115 poddubny 110
    mov    eax,[ebx+APPDATA.mem_size]
1 ha 111
    mov    [app_mem],eax         ;set memory size
115 poddubny 112
    mov    eax,[ebx+APPDATA.dir_table]
113
    mov    dword [edx-APPDATA.app_name+APPDATA.dir_table],eax        ;copy page directory
1 ha 114
;    mov    eax,[new_process_place]
115
;    mov    ebx,[0x3000]
116
;    call   addreference_app_cr3_table
117
 
118
    push   0                     ;no parameters
147 diamond 119
    call   fs_execute.add_app_parameters ;start thread
1 ha 120
    mov    [esp+28],eax
121
    popad
122
    ret
123
 
124
.failed:
125
    sti
126
    popad
127
    mov    eax,-1
128
    ret
129
.ret:
130
    popad
131
    ret
132
;-----------------------------------------------------------------------------
133
new_mem_resize:
134
;input:
135
;  ebx - new size
136
;result:
137
;  [esp+36]:=0 - normal
138
;  [esp+36]:=1 - error
139
;This function set new application memory size.
140
    mov    esi,ebx               ;save new size
141
    add    ebx,4095
142
    and    ebx,not (4096-1)      ;round up size
143
    mov    ecx,[0x3000]
144
    shl    ecx,8
115 poddubny 145
    mov    edx,[0x80000 + APPDATA.mem_size +ecx]
1 ha 146
    add    edx,4095
147
    and    edx,not (4096-1)      ;old size
115 poddubny 148
    mov    eax,[0x80000 + APPDATA.dir_table+ecx]
1 ha 149
    call   MEM_Get_Linear_Address
150
;eax - linear address of page directory
151
    call   MEM_Heap_Lock         ;guarantee that two threads willn't
152
                                 ;change memory size simultaneously
153
    cmp    ebx,edx
154
;    mov    esi,ebx               ;save new size
155
    jg     .expand
156
 
157
.free:
158
    sub    edx,ebx
159
    jz     .unlock               ;do nothing
160
    mov    ecx,edx
161
    shr    ecx,12
162
    add    ebx,std_application_base_address
163
    call   mem_free_specified_region  ;free unnecessary pages
164
    jmp    .unlock
165
 
166
.expand:
167
    sub    ebx,edx
168
    mov    ecx,ebx
169
    shr    ecx,12
170
    mov    ebx,edx
171
    add    ebx,std_application_base_address
172
    call   mem_alloc_specified_region ;alloc necessary pages
173
    test   eax,eax
174
    jz     .failed               ;not enough memory
175
 
176
.unlock:
177
    mov    ebx,esi
178
    mov    eax,[0x3000]
179
    shl    eax,8
115 poddubny 180
    mov    [eax+0x80000 + APPDATA.mem_size],ebx     ;write new memory size
1 ha 181
;search threads and update
182
;application memory size infomation
115 poddubny 183
    mov    ecx,[eax+0x80000 + APPDATA.dir_table]
1 ha 184
    mov    eax,2
185
 
186
.search_threads:
187
;eax = current slot
188
;ebx = new memory size
189
;ecx = page directory
190
    cmp    eax,[0x3004]
191
    jg     .search_threads_end
192
    mov    edx,eax
193
    shl    edx,5
115 poddubny 194
    cmp    word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
1 ha 195
    jz     .search_threads_next
196
    shl    edx,3
115 poddubny 197
    cmp    [edx+0x80000+APPDATA.dir_table],ecx     ;if it is our thread?
1 ha 198
    jnz    .search_threads_next
115 poddubny 199
    mov    [edx+0x80000+APPDATA.mem_size],ebx     ;update memory size
1 ha 200
.search_threads_next:
201
    inc    eax
202
    jmp    .search_threads
203
.search_threads_end:
204
 
205
    call   MEM_Heap_UnLock
206
    mov    dword [esp+36],0
207
    ret
208
 
209
.failed:
210
    call   MEM_Heap_UnLock
211
    mov    dword [esp+36],1
212
    ret
213
;-----------------------------------------------------------------------------
214
pid_to_slot:
215
;Input:
216
;  eax - pid of process
217
;Output:
218
;  eax - slot of process or 0 if process don't exists
219
;Search process by PID.
220
    push   ebx
221
    push   ecx
222
    mov    ebx,[0x3004]
223
    shl    ebx,5
224
    mov    ecx,2*32
225
 
226
.loop:
227
;ecx=offset of current process info entry
228
;ebx=maximum permitted offset
115 poddubny 229
    cmp    byte [second_base_address+0x3000+ecx+TASKDATA.state],9
1 ha 230
    jz     .endloop              ;skip empty slots
115 poddubny 231
    cmp    [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID
1 ha 232
    jz     .pid_found
233
.endloop:
234
    add    ecx,32
235
    cmp    ecx,ebx
236
    jle    .loop
237
 
238
    pop    ecx
239
    pop    ebx
240
    xor    eax,eax
241
    ret
242
 
243
.pid_found:
244
    shr    ecx,5
245
    mov    eax,ecx               ;convert offset to index of slot
246
    pop    ecx
247
    pop    ebx
248
    ret
249
;-----------------------------------------------------------------------------
250
is_new_process:
251
;Input:
252
;  eax - process slot
253
;Output:
254
;  eax=1 - it is new process
255
;  eax=0 - it is old process
256
;    shl   eax,5
257
;    mov   eax,[second_base_address+0x3000+eax+0x10]
258
;    cmp   eax,std_application_base_address  ;check base address of application
259
;    jz    .new_process
260
;    xor   eax,eax
261
;    ret
262
 
263
;.new_process:
264
    mov   eax,1
265
    ret
266
;-----------------------------------------------------------------------------
267
write_process_memory:
268
;Input:
269
;  eax - process slot
270
;  ebx - buffer address
271
;  ecx - buffer size
272
;  edx - start address in other process
273
;Output:
274
;  eax - number of bytes written
275
    pushad
276
    shl  eax,8
115 poddubny 277
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 278
    call MEM_Get_Linear_Address
279
    mov  ebp,eax
280
;ebp=linear address of page directory of other process.
281
    add  edx,std_application_base_address  ;convert to linear address
282
    test ecx,ecx
283
    jle  .ret
284
 
285
.write_loop:
286
;ebx = current buffer address
287
;ecx>0 = current size
288
;edx = current address in other process
289
;ebp = linear address of page directory
290
 
291
    call MEM_Heap_Lock           ;cli
292
    mov  esi,edx
293
    shr  esi,22
294
    mov  eax,[ebp+4*esi]         ;find page directory entry
295
    and  eax,not (4096-1)        ;clear flags
296
    test eax,eax
297
    jz   .page_not_found
298
    call MEM_Get_Linear_Address  ;calculate linear address of page table
299
    test eax,eax
300
    jz   .page_not_found
301
    mov  esi,edx
302
    shr  esi,12
303
    and  esi,1023
304
    mov  eax,[eax+4*esi]         ;find page table entry
305
    and  eax,not (4096-1)
306
    test eax,eax
307
    jz   .page_not_found
308
    call MEM_Get_Linear_Address  ;calculate linear address of page
309
    test eax,eax
310
    jz   .page_not_found
311
    mov  edi,eax
312
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
313
    call MEM_Heap_UnLock         ;sti
314
 
315
    mov  esi,edx
316
    and  esi,4095
317
    add  edi,esi                 ;add offset in page
318
;edi = linear address corresponding edx in other process
319
    sub  esi,4096
320
    neg  esi                     ;esi - number of remaining bytes in page
321
    cmp  esi,ecx
322
    jl   .min_ecx
323
    mov  esi,ecx
324
.min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
325
    sub  ecx,esi
326
    push ecx
327
    mov  ecx,esi                 ;ecx - number of bytes to write
328
    mov  esi,ebx                 ;esi - source, edi - destination
329
    add  edx,ecx                 ;move pointer in address space of other process
330
    push edi
331
 
332
;move ecx bytes
333
    test ecx,3
334
    jnz  .not_aligned
335
    shr  ecx,2
336
    rep  movsd
337
    jmp  .next_iter
338
.not_aligned:
339
    rep  movsb
340
.next_iter:
341
 
342
    pop  eax
343
    and  eax,not (4096-1)        ;eax - linear address of current page
344
    call MEM_Free_Page_Linear    ;free reference
345
    mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
346
    pop  ecx                     ;restore number of remaining bytes
347
    test ecx,ecx
348
    jnz  .write_loop
349
.ret:
350
    popad
351
    mov  eax,ecx
352
    ret
353
 
354
.page_not_found:
355
    call MEM_Heap_UnLock         ;error has appeared in critical region
356
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
357
    neg  ecx                     ;ecx=number_of_written_bytes
358
    mov  [esp+28],ecx            ;[esp+28]<-->eax
359
    popad
360
    ret
361
;-----------------------------------------------------------------------------
362
syscall_test:
363
;for testing memory manager from applications.
364
    mov  edx,ecx
365
    mov  ecx,ebx
366
    call trans_address
367
    mov  ebx,eax
368
    mov  eax,[0x3000]
369
    call read_process_memory
370
    ret
371
;-----------------------------------------------------------------------------
372
read_process_memory:
373
;Input:
374
;  eax - process slot
375
;  ebx - buffer address
376
;  ecx - buffer size
377
;  edx - start address in other process
378
;Output:
379
;  eax - number of bytes read.
380
    pushad
381
    shl  eax,8
115 poddubny 382
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 383
    call MEM_Get_Linear_Address
384
    mov  ebp,eax
385
    add  edx,std_application_base_address
386
.read_loop:
387
;ebx = current buffer address
388
;ecx>0 = current size
389
;edx = current address in other process
390
;ebp = linear address of page directory
391
 
392
    call MEM_Heap_Lock           ;cli
393
    mov  esi,edx
394
    shr  esi,22
395
    mov  eax,[ebp+4*esi]         ;find page directory entry
396
    and  eax,not (4096-1)
397
    test eax,eax
398
    jz   .page_not_found
399
    call MEM_Get_Linear_Address
400
    test eax,eax
401
    jz   .page_not_found
402
    mov  esi,edx
403
    shr  esi,12
404
    and  esi,1023
405
    mov  eax,[eax+4*esi]         ;find page table entry
406
    and  eax,not (4096-1)
407
    test eax,eax
408
    jz   .page_not_found
409
    call MEM_Get_Linear_Address  ;calculate linear address of page
410
    test eax,eax
411
    jz   .page_not_found
412
    mov  esi,eax
413
    call MEM_Add_Reference_Linear;guarantee that page willn't disappear
414
    call MEM_Heap_UnLock         ;sti
415
 
416
    mov  edi,edx
417
    and  edi,4095
418
    add  esi,edi                 ;add offset in page
419
;esi = linear address corresponding edx in other process
420
    sub  edi,4096
421
    neg  edi
422
 
423
;edi=min(edi,ecx) - number of bytes to copy
424
    cmp  edi,ecx
425
    jl   .min_ecx
426
    mov  edi,ecx
427
.min_ecx:
428
 
429
    sub  ecx,edi                 ;update size of remaining bytes
430
    add  edx,edi                 ;update current pointer in other address space.
431
    push ecx
432
    mov  ecx,edi                 ;ecx - number of bytes to read
433
    mov  edi,ebx                 ;esi - source, edi - destination
434
    push esi
435
;move ecx bytes
436
    test ecx,3
437
    jnz  .not_aligned
438
    shr  ecx,2
439
    rep  movsd
440
    jmp  .next_iter
441
.not_aligned:
442
    rep  movsb
443
.next_iter:
444
    pop  eax
445
    and  eax,not (4096-1)        ;eax - linear address of current page
446
    call MEM_Free_Page_Linear    ;free reference
447
    mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
448
    pop  ecx                     ;restore number of remaining bytes
449
    test ecx,ecx
450
    jnz  .read_loop
451
 
452
    popad
453
    mov  eax,ecx
454
    ret
455
 
456
.page_not_found:
457
    call MEM_Heap_UnLock         ;error has appeared in critical region
458
    sub  ecx,[esp+24]            ;[esp+24]<-->ecx
459
    neg  ecx                     ;ecx=number_of_read_bytes
460
    mov  [esp+28],ecx            ;[esp+28]<-->eax
461
    popad
462
    ret
463
;-----------------------------------------------------------------------------
464
check_region:
465
;input:
466
;  ebx - start of buffer
467
;  ecx - size of buffer
468
;result:
469
;  eax = 1 region lays in app memory
470
;  eax = 0 region don't lays in app memory
471
    mov  eax,[0x3000]
472
    jmp  check_process_region
473
;-----------------------------------------------------------------------------
474
check_process_region:
475
;input:
476
;  eax - slot
477
;  ebx - start of buffer
478
;  ecx - size of buffer
479
;result:
480
;  eax = 1 region lays in app memory
481
;  eax = 0 region don't lays in app memory
482
    test ecx,ecx
483
    jle  .ok
484
    shl  eax,5
115 poddubny 485
    cmp  word [0x3000+eax+TASKDATA.state],0
1 ha 486
    jnz  .failed
487
    shl  eax,3
115 poddubny 488
    mov  eax,[0x80000+eax+APPDATA.dir_table]
1 ha 489
    test eax,eax
490
    jz   .failed
491
    call MEM_Get_Linear_Address
492
    push ebx
493
    push ecx
494
    push edx
495
    mov  edx,ebx
496
    and  edx,not (4096-1)
497
    sub  ebx,edx
498
    add  ecx,ebx
499
    mov  ebx,edx
500
    add  ecx,(4096-1)
501
    and  ecx,not (4096-1)
502
.loop:
503
;eax - linear address of page directory
504
;ebx - current page
505
;ecx - current size
506
    mov  edx,ebx
507
    shr  edx,22
508
    mov  edx,[eax+4*edx]
509
    and  edx,not (4096-1)
510
    test edx,edx
511
    jz   .failed1
512
    push eax
513
    mov  eax,edx
514
    call MEM_Get_Linear_Address
515
    mov  edx,ebx
516
    shr  edx,12
517
    and  edx,(1024-1)
518
    mov  eax,[eax+4*edx]
519
    and  eax,not (4096-1)
520
    test eax,eax
521
    pop  eax
522
    jz   .failed1
523
    add  ebx,4096
524
    sub  ecx,4096
525
    jg   .loop
526
    pop  edx
527
    pop  ecx
528
    pop  ebx
529
.ok:
530
    mov  eax,1
531
    ret
532
 
533
.failed1:
534
    pop  edx
535
    pop  ecx
536
    pop  ebx
537
.failed:
538
    xor  eax,eax
539
    ret
540
;-----------------------------------------------------------------------------
541
new_sys_ipc:
542
;input:
543
;  eax=1 - set ipc buffer area
544
;    ebx=address of buffer
545
;    ecx=size of buffer
546
;  eax=2 - send message
547
;    ebx=PID
548
;    ecx=address of message
549
;    edx=size of message
550
    cmp  eax,1
551
    jnz  .no_ipc_def
552
;set ipc buffer area
553
    mov  edi,[0x3000]
554
    shl  edi,8
555
    add  edi,0x80000
556
    cli
115 poddubny 557
    mov  [edi+APPDATA.ipc_start],ebx          ;set fields in extended information area
558
    mov  [edi+APPDATA.ipc_size],ecx
1 ha 559
    sti
560
    mov  [esp+36],dword 0        ;success
561
    ret
562
 
563
.no_ipc_def:
564
    cmp  eax,2
565
    jnz  .no_ipc_send
566
;send message
567
    cli
568
;obtain slot from PID
569
    mov  eax,ebx
570
    call pid_to_slot
571
    test eax,eax
572
    jz   .no_pid
573
    mov  ebp,eax
574
;ebp = slot of other process
575
    shl  eax,8
115 poddubny 576
    mov  edi,[eax+0x80000+APPDATA.ipc_start]  ;is ipc area defined?
1 ha 577
    test edi,edi
578
    jz   .no_ipc_area
115 poddubny 579
    mov  esi,[eax+0x80000+APPDATA.ipc_size]  ;esi - size of buffer
1 ha 580
    push dword -1                ;temp variable for read_process_memory
581
    mov  ebx,esp
582
    push ecx
583
    push edx
584
    mov  ecx,4                   ;read 4 bytes
585
    mov  eax,ebp
586
    mov  edx,edi                 ;from beginning of buffer.
587
    call read_process_memory
588
    mov  eax,[esp+8]
589
    test eax,eax
590
    jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
591
    add  edx,4                   ;move to next 4 bytes
592
    mov  eax,ebp
593
    call read_process_memory     ;read size of occupied space in buffer
594
    sub  esi,8
595
    sub  esi,[esp]
596
    sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
597
    js   .buffer_overflow        ;esi<0 - not enough memory in buffer
598
    mov  esi,[esp+8]             ;previous offset
599
    add  dword [esp+8],8
600
    mov  edi,[esp]
601
    add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
602
    mov  eax,ebp
603
    call write_process_memory
604
    add  edx,esi
605
    sub  edx,4                   ;move to beginning of place for our message
606
    mov  eax,[second_base_address+0x3010]
115 poddubny 607
    mov  eax,[eax+TASKDATA.pid]           ;eax - our PID
1 ha 608
    mov  [esp+8],eax
609
    mov  eax,ebp
610
    call write_process_memory    ;write PID
611
    mov  ebx,esp                 ;address of size of message
612
    mov  eax,ebp
613
    add  edx,4
614
    call write_process_memory    ;write size of message
615
    add  edx,4
616
    pop  ecx                     ;ecx - size of message
617
    pop  eax
618
    call trans_address
619
    mov  ebx,eax                 ;ebx - linear address of message
620
    add  esp,4                   ;pop temporary variable
621
    mov  eax,ebp
622
    call write_process_memory    ;write message
623
    sti
624
;awake other process
625
    shl  ebp,8
626
    mov  eax,ebp
115 poddubny 627
    or   [eax+0x80000+APPDATA.event_mask],dword 0x40
1 ha 628
 
629
    cmp  dword [check_idle_semaphore],20
630
    jge  .ipc_no_cis
631
    mov  dword [check_idle_semaphore],5
632
.ipc_no_cis:
633
    mov  dword [esp+36],0
634
    ret
635
.no_ipc_send:
636
    mov  dword [esp+36],-1
637
    ret
638
.no_pid:
639
    sti
640
    mov  dword [esp+36],4
641
    ret
642
.no_ipc_area:
643
    sti
644
    mov  dword [esp+36],1
645
    ret
646
.ipc_blocked:
647
    sti
648
    add  esp,12
649
    mov  dword [esp+36],2
650
    ret
651
.buffer_overflow:
652
    sti
653
    add  esp,12
654
    mov  dword [esp+36],3
655
    ret
656
;-----------------------------------------------------------------------------
657
trans_address:
658
;Input
659
;  eax - application address
660
;Output
661
;  eax - linear address for kernel
662
    add   eax,std_application_base_address
663
    ret
664
;-----------------------------------------------------------------------------
665
 
91 diamond 666
; \begin{diamond}
667
        include 'debug.inc'
668
 
669
fs_execute:
670
; ebx - cmdline
671
; edx - flags
672
; ebp - full filename
673
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
674
        pushad
675
; check filename length - with terminating NULL must be no more than 1024 symbols
676
        mov     edi, ebp
677
        mov     ecx, 1024
678
        xor     eax, eax
679
        repnz   scasb
680
        jz      @f
681
        popad
682
        mov     eax, -ERROR_FILE_NOT_FOUND
683
        ret
684
@@:
685
 
686
        mov     esi, new_process_loading
687
        call    sys_msg_board_str       ; write message to message board
688
 
689
; lock application_table_status mutex
690
.table_status:
691
        cli
692
        cmp     [application_table_status], 0
693
        jz      .stf
694
        sti
695
        call    change_task
696
        jmp     .table_status
697
.stf:
698
        call    set_application_table_status
699
        push    ebx     ; save command line pointer for add_app_parameters
700
 
701
        call    find_new_process_place  ; find new process slot
702
        call    safe_sti
703
        test    eax, eax
704
        mov     ecx, -0x20      ; too many processes
705
        jz      .failed
706
 
707
; write application name
708
        push    edi
709
        mov     ecx, edi
710
        sub     ecx, ebp
711
        mov     [appl_path], ebp
712
        mov     [appl_path_size], ecx
713
        dec     edi
714
        std
715
        mov     al, '/'
716
        repnz   scasb
717
        cld
718
        jnz     @f
719
        inc     edi
720
@@:
721
        inc     edi
722
; now edi points to name without path
723
        mov     esi, edi
724
        mov     ecx, 8  ; 8 chars for name
725
        mov     edi, [new_process_place]
726
        shl     edi, cl
115 poddubny 727
        add     edi, 0x80000+APPDATA.app_name
91 diamond 728
.copy_process_name_loop:
729
        lodsb
730
        cmp     al, '.'
731
        jz      .copy_process_name_done
732
        test    al, al
733
        jz      .copy_process_name_done
734
        stosb
735
        loop    .copy_process_name_loop
736
.copy_process_name_done:
737
        mov     al, ' '
738
        rep     stosb
739
        pop     eax
740
        mov     cl, 3   ; 3 chars for extension
741
        dec     esi
742
@@:
743
        dec     eax
744
        cmp     eax, esi
745
        jbe     .copy_process_ext_done
746
        cmp     byte [eax], '.'
747
        jnz     @b
748
        lea     esi, [eax+1]
749
.copy_process_ext_loop:
750
        lodsb
751
        test    al, al
752
        jz      .copy_process_ext_done
753
        stosb
754
        loop    .copy_process_ext_loop
755
.copy_process_ext_done:
756
        mov     al, ' '
757
        rep     stosb
758
 
759
; read header
760
        lea     eax, [esp+8+36]
761
        mov     edi, 0x90000
762
        call    dword [eax-4]
763
        mov     ecx, eax
764
        neg     ecx
765
        jnz     .cleanfailed
766
; check menuet signature
767
        mov     ecx, -0x1F
768
        cmp     dword [0x90000], 'MENU'
769
        jnz     .cleanfailed
770
        cmp     word [0x90004], 'ET'
771
        jnz     .cleanfailed
772
        call    get_app_params
773
        mov     ecx, -0x1F
133 diamond 774
        jc      .cleanfailed
775
; sanity check - because we will load all file,
776
; file size must be not greater than memory size
777
        mov     eax, [esp+8+36]
778
        cmp     [app_mem], eax
779
        jb      .cleanfailed
91 diamond 780
 
781
        mov     eax, [new_process_place]
782
        inc     ecx     ; -0x1E = no memory
783
        call    create_app_cr3_table
784
        test    eax, eax
785
        jz      .cleanfailed_mem
786
 
787
        call    MEM_Get_Linear_Address
788
 
789
        mov     ebx, std_application_base_address
790
        mov     ecx, [app_mem]
791
        add     ecx, 4095
792
        shr     ecx, 12
793
        mov     edx, eax        ; edx - linear address of page directory
794
        call    mem_alloc_specified_region
795
        mov     ecx, -0x1E      ; no memory
796
        test    eax, eax
797
        jz      .cleanfailed_mem1
798
 
799
        add     edx, std_application_base_address shr 20
800
        mov     eax, [edx]
801
        and     eax, not 4095
802
        call    MEM_Get_Linear_Address
803
        push    edx             ; save pointer to first page table
804
        mov     edx, eax
805
; read file
806
; first block is already read to 0x90000
807
        mov     eax, [edx]
808
        and     eax, not 0xFFF
809
        call    MEM_Get_Linear_Address
810
        mov     esi, 0x90000
811
        mov     edi, eax
812
        mov     ecx, 512/4
813
        rep     movsd
814
        sub     edi, eax
815
.loop1:
816
; [esp] = pointer to current page directory entry
817
; edx = pointer to current page table
818
; edi = offset in page
819
        mov     eax, [edx]
820
        and     eax, not 0xFFF
821
        call    MEM_Get_Linear_Address
822
        push    edi
823
        add     edi, eax
824
        lea     eax, [esp+8+36+8]
825
        call    dword [eax-4]
826
        pop     edi
827
        test    eax, eax
828
        jnz     .endloop1
829
        add     edi, 512        ; new offset
830
        cmp     edi, 4096
831
        jb      .loop1
832
        xor     edi, edi
833
        add     edx, 4          ; go to next page
834
        test    edx, 4096-1
835
        jnz     .loop1
836
        pop     eax
837
        add     eax, 4          ; go to next directory entry
838
        push    eax
839
        mov     eax, [eax]
840
        and     eax, not 0xFFF
841
        call    MEM_Get_Linear_Address
842
        mov     edx, eax
843
        jmp     .loop1
844
.endloop1:
845
        pop     edx
846
        cmp     eax, 6
847
        jnz     .cleanfailed_mem2
147 diamond 848
        call    .add_app_parameters
91 diamond 849
        mov     [esp+28], eax
850
        popad
851
        ret
852
 
853
.cleanfailed_mem2:
854
; file read error; free all allocated mem
855
        mov     ecx, eax
856
        neg     ecx
857
        mov     eax, [new_process_place]
858
        call    dispose_app_cr3_table
859
        jmp     .cleanfailed
860
.cleanfailed_mem1:
861
; there is mem for directory entry, but there is no mem for pages
862
; so free directory entry
863
        mov     eax, [new_process_place]
864
        shl     eax, 8
865
        mov     eax, [0x80000+eax+0xB8]
866
        call    MEM_Free_Page
867
.cleanfailed_mem:
868
; there is no mem for directory entry, display message
869
        mov     esi, start_not_enough_memory
870
        call    sys_msg_board_str
871
.cleanfailed:
872
        push    ecx
873
; clean process name, this avoid problems with @panel
874
        mov     edi, [new_process_place]
875
        shl     edi, 8
115 poddubny 876
        add     edi, 0x80000+APPDATA.app_name
91 diamond 877
        mov     ecx, 11
878
        mov     al, ' '
879
        rep     stosb
880
        pop     eax
881
.failed:
882
        pop     ebx
883
        mov     [esp+28], eax
884
        popad
885
        mov     [application_table_status], 0
886
        call    safe_sti
887
        ret
888
; \end{diamond}
147 diamond 889
.add_app_parameters:
890
;input:
891
;  [esp] - pointer to parameters
892
;  [esp+4]-[esp+36] pushad registers.
893
;result
894
;  eax - pid of new process
895
;        or zero if failed
896
    cli
897
    mov    ebx,[new_process_place]
898
    cmp    ebx,[0x3004]
899
    jle    .noinc
900
    inc    dword [0x3004]        ;update number of processes
901
.noinc:
902
 
903
;   mov    ebx,[new_process_place]
904
;set 0x8c field of extended information about process
905
;(size of application memory)
906
    shl    ebx,8
907
    mov    eax,[app_mem]
908
    mov    [second_base_address+0x80000+APPDATA.mem_size+ebx],eax
909
;set 0x10 field of information about process
910
;(application base address)
911
;    mov    ebx,[new_process_place]
912
;    shl    ebx,5
913
    shr    ebx,3
914
    mov    dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
915
 
916
;add command line parameters
917
.add_command_line:
918
    mov    edx,[app_i_param]
919
    test   edx,edx
920
    jz     .no_command_line      ;application don't need parameters
921
    mov    eax,[esp+4]
922
    test   eax,eax
923
    jz     .no_command_line      ;no parameters specified
924
;calculate parameter length
925
    mov    esi,eax
926
    xor    ecx,ecx
927
    inc    ecx          ; include terminating null
928
.command_line_len:
929
    cmp    byte [esi],0
930
    jz     .command_line_len_end
931
    inc    esi
932
    inc    ecx
933
    cmp    ecx,256
934
    jl     .command_line_len
935
 
936
.command_line_len_end:
937
;ecx - parameter length
938
;edx - address of parameters in new process address space
939
    mov    ebx,eax               ;ebx - address of parameters in our address space
940
    mov    eax,[new_process_place]
941
    call   write_process_memory  ;copy parameters to new process address space
942
 
943
.no_command_line:
944
;******************************************************************
945
    mov    edx,[app_i_icon]
946
    test   edx,edx
947
    jz     .no_command_line_1      ;application don't need path of file
948
    mov    ebx,[appl_path]
949
    mov    ecx,[appl_path_size]
950
    mov    eax,[new_process_place]
951
    call   write_process_memory  ;copy path of file to new process address space
952
.no_command_line_1:
953
;******************************************************************
954
    mov    ebx,[new_process_place]
955
    mov    eax,ebx
956
    shl    ebx,5
957
    mov    [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL
958
    mov    [ebx+window_data+WDATA.fl_redraw],1
959
    add    ebx,0x3000            ;ebx - pointer to information about process
960
    mov    [ebx+TASKDATA.wnd_number],al  ;set window number on screen = process slot
961
 
962
    mov    [ebx+TASKDATA.event_mask],dword 1+2+4     ;set default event flags (see 40 function)
963
 
964
    inc    dword [process_number]
965
    mov    eax,[process_number]
966
    mov    [ebx+TASKDATA.pid],eax           ;set PID
967
 
968
    mov    ecx,ebx
969
    add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
970
;set draw data to full screen
971
    mov    [ecx+RECT.left],dword 0
972
    mov    [ecx+RECT.top],dword 0
973
    mov    eax,[0xfe00]
974
    mov    [ecx+RECT.right],eax
975
    mov    eax,[0xfe04]
976
    mov    [ecx+RECT.bottom],eax
977
;set cr3 register in TSS of application
978
    mov    ecx,[new_process_place]
979
    shl    ecx,8
980
    mov    eax,[0x80000+APPDATA.dir_table+ecx]
981
    add    eax,8+16              ;add flags
982
    mov    [l.cr3],eax
983
 
984
    mov    eax,[app_start]
985
    mov    [l.eip],eax           ;set eip in TSS
986
    mov    eax,[app_esp]
987
    mov    [l.esp],eax           ;set stack in TSS
988
 
989
;gdt
990
    ;mov    ebx,[new_process_place]
991
    ;shl    ebx,3
992
    mov    ax,app_code           ;ax - selector of code segment
993
    ;add    ax,bx
994
    mov    [l.cs],ax
995
    mov    ax,app_data
996
    ;add    ax,bx                 ;ax - selector of data segment
997
    mov    [l.ss],ax
998
    mov    [l.ds],ax
999
    mov    [l.es],ax
1000
    mov    [l.fs],ax
1001
    mov    ax,graph_data         ;ax - selector of graphic segment
1002
    mov    [l.gs],ax
1003
    mov    [l.io],word 128
1004
    mov    [l.eflags],dword 0x11202
1005
    mov    [l.ss0],os_data
1006
    mov    ebx,[new_process_place]
1007
    shl    ebx,12
1008
    add    ebx,sysint_stack_data+4096
1009
    mov    [l.esp0],ebx
1010
 
1011
;copy tss to it place
1012
    mov    eax,tss_sceleton
1013
    mov    ebx,[new_process_place]
1014
    imul   ebx,tss_step
1015
    add    ebx,tss_data          ;ebx - address of application TSS
1016
    mov    ecx,120
1017
    call   memmove
1018
 
1019
;Add IO access table - bit array of permitted ports
1020
    or     eax,-1
1021
    mov    edi,[new_process_place]
1022
    imul   edi,tss_step
1023
    add    edi,tss_data+128
1024
    mov    ecx,2048
1025
    cld
1026
    rep    stosd                 ;full access to 2048*8=16384 ports
1027
 
1028
    mov    ecx,ebx               ;ecx - address of application TSS
1029
    mov    edi,[new_process_place]
1030
    shl    edi,3
1031
;set TSS descriptor
1032
    mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
1033
    mov    [edi+gdts+tss0+2],cx  ;part of offset
1034
    mov    eax,ecx
1035
    shr    eax,16
1036
    mov    [edi+gdts+tss0+4],al  ;part of offset
1037
    mov    [edi+gdts+tss0+7],ah  ;part of offset
1038
    mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
1039
 
1040
 
1041
;flush keyboard and buttons queue
1042
    mov    [0xf400],byte 0
1043
    mov    [0xf500],byte 0
1044
 
1045
    mov    edi,[new_process_place]
1046
    shl    edi,5
1047
    add    edi,window_data
1048
    mov    ebx,[new_process_place]
1049
    movzx  esi,word [0xC000+ebx*2]
1050
    lea    esi,[0xC400+esi*2]
1051
    call   windowactivate        ;gui initialization
1052
 
1053
    mov    ebx,[new_process_place]
1054
    shl    ebx,5
1055
; set if debuggee
1056
        test    byte [esp+28], 1
1057
        jz      .no_debug
1058
        mov     [0x3000+ebx+TASKDATA.state], 1        ; set process state - suspended
1059
        mov     eax, [0x3000]
1060
        mov     [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
1061
        jmp     .debug
1062
.no_debug:
1063
        mov     [0x3000+ebx+TASKDATA.state], 0        ; set process state - running
1064
.debug:
1065
 
1066
    mov    esi,new_process_running
1067
    call   sys_msg_board_str     ;output information about succefull startup
1068
 
1069
;    add    esp,4                 ;pop pointer to parameters
1070
;    popad
1071
    mov    eax,[process_number]  ;set result
1072
    mov    [application_table_status],0 ;unlock application_table_status mutex
1073
    call   safe_sti
1074
    ret    4
1075
 
1076
end if