Subversion Repositories Kolibri OS

Rev

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