summaryrefslogtreecommitdiff
path: root/v4.0/src/DOS/EXEC.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/DOS/EXEC.ASM')
-rw-r--r--v4.0/src/DOS/EXEC.ASM931
1 files changed, 931 insertions, 0 deletions
diff --git a/v4.0/src/DOS/EXEC.ASM b/v4.0/src/DOS/EXEC.ASM
new file mode 100644
index 0000000..aa120c2
--- /dev/null
+++ b/v4.0/src/DOS/EXEC.ASM
@@ -0,0 +1,931 @@
1; SCCSID = @(#)exec.asm 1.3 85/08/13
2; SCCSID = @(#)exec.asm 1.3 85/08/13
3; AN000 version 4.0 jan. 1988
4; A007 PTM 3957 - fake vesrion for IBMCACHE.COM
5; A008 PTM 4070 - fake version for MS WINDOWS
6
7SUBTTL $exec - load/go a program
8PAGE
9;
10; Assembler usage:
11; LDS DX, name
12; LES BX, blk
13; MOV AH, Exec
14; MOV AL, func
15; INT int_command
16;
17; AL Function
18; -- --------
19; 0 Load and execute the program.
20; 1 Load, create the program header but do not
21; begin execution.
22; 3 Load overlay. No header created.
23;
24; AL = 0 -> load/execute program
25;
26; +---------------------------+
27; | WORD segment address of |
28; | environment. |
29; +---------------------------+
30; | DWORD pointer to ASCIZ |
31; | command line at 80h |
32; +---------------------------+
33; | DWORD pointer to default |
34; | FCB to be passed at 5Ch |
35; +---------------------------+
36; | DWORD pointer to default |
37; | FCB to be passed at 6Ch |
38; +---------------------------+
39;
40; AL = 1 -> load program
41;
42; +---------------------------+
43; | WORD segment address of |
44; | environment. |
45; +---------------------------+
46; | DWORD pointer to ASCIZ |
47; | command line at 80h |
48; +---------------------------+
49; | DWORD pointer to default |
50; | FCB to be passed at 5Ch |
51; +---------------------------+
52; | DWORD pointer to default |
53; | FCB to be passed at 6Ch |
54; +---------------------------+
55; | DWORD returned value of |
56; | CS:IP |
57; +---------------------------+
58; | DWORD returned value of |
59; | SS:IP |
60; +---------------------------+
61;
62; AL = 3 -> load overlay
63;
64; +---------------------------+
65; | WORD segment address where|
66; | file will be loaded. |
67; +---------------------------+
68; | WORD relocation factor to |
69; | be applied to the image. |
70; +---------------------------+
71;
72; Returns:
73; AX = error_invalid_function
74; = error_bad_format
75; = error_bad_environment
76; = error_not_enough_memory
77; = error_file_not_found
78;
79; Revision history:
80;
81; A000 version 4.00 Jan. 1988
82;
83include EA.INC
84include version.inc
85
86 I_Need Temp_Var2,WORD ;AN000;file type from $open
87 I_Need Special_Entries,WORD ;AN007;address of special entries
88 I_Need Special_Version,WORD ;AN007;special version number
89 I_Need Fake_Count,BYTE ;AN008;fake version count
90
91IF BUFFERFLAG
92 extrn restore_user_map:near
93ENDIF
94
95TABLE SEGMENT
96
97exec_init_SP DW ?
98exec_init_SS DW ?
99exec_init_IP DW ?
100exec_init_CS DW ?
101
102exec_internal_buffer EQU OpenBuf
103
104exec_signature DW ? ; must contain 4D5A (yay zibo!)
105exec_len_mod_512 DW ? ; low 9 bits of length
106exec_pages DW ? ; number of 512b pages in file
107exec_rle_count DW ? ; count of reloc entries
108exec_par_dir DW ? ; number of paragraphs before image
109exec_min_BSS DW ? ; minimum number of para of BSS
110exec_max_BSS DW ? ; max number of para of BSS
111exec_SS DW ? ; stack of image
112exec_SP DW ? ; SP of image
113exec_chksum DW ? ; checksum of file (ignored)
114exec_IP DW ? ; IP of entry
115exec_CS DW ? ; CS of entry
116exec_rle_table DW ? ; byte offset of reloc table
117Exec_header_len EQU $-Exec_Signature
118
119exec_internal_buffer_size EQU (128+128+53+curdirLEN)
120%out Please make sure that the following are contiguous and of the
121%out following sizes:
122%out
123%out OpenBuf 128
124%out RenBuf 128
125%out SearchBuf 53
126%out DummyCDS CurDirLen
127
128TABLE ENDS
129
130.sall
131
132procedure $Exec,NEAR
133 ASSUME DS:NOTHING, ES:NOTHING
134PUBLIC EXEC001S,EXEC001E
135EXEC001S:
136 LocalVar exec_blk,DWORD
137 LocalVar exec_func,BYTE
138 LocalVar exec_load_high,BYTE
139 LocalVar exec_fh,WORD
140 LocalVar exec_rel_fac,WORD
141 LocalVar exec_res_len_para,WORD
142 LocalVar exec_environ,WORD
143 LocalVar exec_size,WORD
144 LocalVar exec_load_block,WORD
145 LocalVar exec_dma,WORD
146 LocalVar execNameLen,WORD
147 LocalVar execName,DWORD
148EXEC001E:
149 Enter
150;
151; validate function
152;
153
154 CMP AL,3 ; only 0, 1 or 3 are allowed
155 JNA exec_check_2
156
157exec_bad_fun:
158 MOV EXTERR_LOCUS,errLOC_Unk ; Extended Error Locus
159 mov al,error_invalid_function
160
161exec_ret_err:
162 Leave
163 transfer SYS_RET_ERR
164
165exec_check_2:
166 CMP AL,2
167 JZ exec_bad_fun
168
169 MOV exec_blkL,BX ; stash args
170 MOV exec_blkH,ES
171 MOV exec_func,AL
172 MOV exec_load_high,0
173;
174; set up length of exec name
175;
176 MOV execNameL,DX
177 MOV execNameH,DS
178 MOV SI,DX ; move pointer to convenient place
179 invoke DStrLen
180 MOV ExecNameLen,CX ; save length
181
182 XOR AL,AL ; open for reading
183 PUSH BP
184 invoke $OPEN ; is the file there?
185 POP BP
186 JC exec_ret_err
187;File Type Checking
188; CMP BYTE PTR [Temp_Var2],EAEXISTING ;AN000;;FT. old file ?
189; JZ oldexf ;AN000;;FT. yes
190; TEST BYTE PTR EXEC_FUNC,EXEC_FUNC_OVERLAY ;AN000;;FT. exec overlay?
191; JNZ exovrly ;AN000;;FT. yes
192; CMP BYTE PTR [Temp_Var2],EAEXECUTABLE ;AN000;;FT. only file type
193; JZ oldexf ;AN000;;FT. 3 & 4 will pass
194; CMP BYTE PTR [Temp_Var2],EAINSTALLABLE ;AN000;;FT.
195; JZ oldexf ;AN000;;FT.
196;exerr: ;AN000;;FT.
197; MOV AL,error_access_denied ;AN000;;FT. error
198; JMP exec_ret_err ;AN000;;FT.
199;exovrly: ;AN000;;FT.
200; CMP BYTE PTR [Temp_Var2],EAOVERLAY ;AN000;;FT. only 5,6,7 pass
201; JZ oldexf ;AN000;;FT.
202; CMP BYTE PTR [Temp_Var2],EADEV_DRIVER ;AN000;;FT.
203; JZ oldexf ;AN000;;FT.
204; CMP BYTE PTR [Temp_Var2],EAIFS_DRIVER ;AN000;;FT.
205; JNZ exerr ;AN000;;FT.
206;
207;oldexf: ;AN000;
208;File Type Checking
209
210 MOV exec_fh,AX
211 MOV BX,AX
212 XOR AL,AL
213 invoke $IOCTL
214 JC Exec_bombJ
215 TEST DL,devid_ISDEV
216 JZ exec_check_environ
217 MOV AL,error_file_not_found
218Exec_bombJ:
219 JMP Exec_Bomb
220
221BadEnv:
222 MOV AL,error_bad_environment
223 JMP exec_bomb
224
225exec_check_environ:
226 MOV exec_load_block,0
227 MOV exec_environ,0
228
229 TEST BYTE PTR exec_func,exec_func_overlay ; overlays... no environment
230 JNZ exec_read_header
231 LDS SI,exec_blk ; get block
232 MOV AX,[SI].Exec1_environ ; address of environ
233 OR AX,AX
234 JNZ exec_scan_env
235 MOV DS,CurrentPDB
236 MOV AX,DS:[PDB_environ]
237 MOV exec_environ,AX
238 OR AX,AX
239 JZ exec_read_header
240
241exec_scan_env:
242 MOV ES,AX
243 XOR DI,DI
244 MOV CX,07FFFh ; at most 32k of environment
245 XOR AL,AL
246
247exec_get_environ_len:
248 REPNZ SCASB ; find that nul byte
249 JNZ BadEnv
250 DEC CX ; Dec CX for the next nul byte test
251 JB BadEnv ; gone beyond the end of the environment
252 SCASB ; is there another nul byte?
253 JNZ exec_get_environ_len ; no, scan some more
254 PUSH DI
255 LEA BX,[DI+0Fh+2]
256 ADD BX,ExecNameLen ; BX <- length of environment
257 ; remember argv[0] length
258 ; round up and remember argc
259 MOV CL,4
260 SHR BX,CL ; number of paragraphs needed
261 PUSH ES
262 invoke $ALLOC ; can we get the space?
263 POP DS
264 POP CX
265 JNC exec_save_environ
266 JMP exec_no_mem ; nope... cry and sob
267
268exec_save_environ:
269 MOV ES,AX
270 MOV exec_environ,AX ; save him for a rainy day
271 XOR SI,SI
272 MOV DI,SI
273 REP MOVSB ; copy the environment
274 MOV AX,1
275 STOSW
276 LDS SI,execName
277 MOV CX,execNameLen
278 REP MOVSB
279
280exec_read_header:
281;
282; We read in the program header into the above data area and determine
283; where in this memory the image will be located.
284;
285 Context DS
286 MOV CX,exec_header_len ; header size
287 MOV DX,OFFSET DOSGROUP:exec_signature
288 PUSH ES
289 PUSH DS
290 CALL ExecRead
291 POP DS
292 POP ES
293 JC exec_bad_file
294 OR AX,AX
295 JZ exec_bad_file
296 CMP AX,exec_header_len ; did we read the right number?
297 JNZ exec_com_filej ; yep... continue
298 TEST exec_max_BSS,-1 ; indicate load high?
299 JNZ exec_check_sig
300 MOV exec_load_high,-1
301exec_check_sig:
302 MOV AX,exec_signature
303 CMP AX,exe_valid_signature ; zibo arises!
304 JZ exec_save_start ; assume com file if no signature
305 CMP AX,exe_valid_old_signature ; zibo arises!
306 JZ exec_save_start ; assume com file if no signature
307
308exec_com_filej:
309 JMP exec_com_file
310
311;
312; We have the program header... determine memory requirements
313;
314exec_save_start:
315 MOV AX,exec_pages ; get 512-byte pages
316 MOV CL,5 ; convert to paragraphs
317 SHL AX,CL
318 SUB AX,exec_par_dir ; AX = size in paragraphs
319 MOV exec_res_len_para,AX
320
321;
322; Do we need to allocate memory? Yes if function is not load-overlay
323;
324 TEST BYTE PTR exec_func,exec_func_overlay
325 JZ exec_allocate ; allocation of space
326;
327; get load address from block
328;
329 LES DI,exec_blk
330 MOV AX,ES:[DI].exec3_load_addr
331 MOV exec_dma,AX
332 MOV AX,ES:[DI].exec3_reloc_fac
333 MOV exec_rel_fac,AX
334IF DEBUG
335 JMP exec_find_res
336ELSE
337 JMP SHORT exec_find_res
338ENDIF
339
340exec_no_mem:
341 MOV AL,error_not_enough_memory
342 JMP SHORT exec_bomb
343
344exec_bad_file:
345 MOV AL,error_bad_format
346
347exec_bomb:
348 ASSUME DS:NOTHING,ES:NOTHING
349 MOV BX,exec_fh
350 CALL exec_dealloc
351 LeaveCrit CritMem
352 SaveReg <AX,BP>
353 invoke $CLOSE
354 RestoreReg <BP,AX>
355 JMP Exec_Ret_Err
356
357exec_allocate:
358 DOSAssume CS,<DS>,"EXEC/exec_allocate"
359 PUSH AX
360 MOV BX,0FFFFh ; see how much room in arena
361 PUSH DS
362 invoke $ALLOC ; should have carry set and BX has max
363 POP DS
364 POP AX
365 ADD AX,10h ; room for header
366 CMP BX,11h ; enough room for a header
367 JB exec_no_mem
368 CMP AX,BX ; is there enough for bare image?
369 JA exec_no_mem
370 TEST exec_load_high,-1 ; if load high, use max
371 JNZ exec_BX_max ; use max
372 ADD AX,exec_min_BSS ; go for min allocation
373 JC exec_no_mem ; oops! carry
374 CMP AX,BX ; enough space?
375 JA exec_no_mem ; nope...
376 SUB AX,exec_min_BSS
377 ADD AX,exec_max_BSS ; go for the MAX
378 JC exec_BX_max
379 CMP AX,BX
380 JBE exec_got_block
381
382exec_BX_max:
383 MOV AX,BX
384
385exec_got_block:
386 PUSH DS
387 MOV BX,AX
388 MOV exec_size,BX
389 invoke $ALLOC ; get the space
390 POP DS
391 JC exec_no_mem
392 MOV exec_load_block,AX
393 ADD AX,10h
394 TEST exec_load_high,-1
395 JZ exec_use_ax ; use ax for load info
396 ADD AX,exec_size ; go to end
397 SUB AX,exec_res_len_para ; drop off header
398 SUB AX,10h ; drop off pdb
399exec_use_ax:
400 MOV exec_rel_fac,AX ; new segment
401 MOV exec_dma,AX ; beginning of dma
402
403;
404; Determine the location in the file of the beginning of the resident
405;
406exec_find_res:
407 MOV DX,exec_par_dir
408 PUSH DX
409 MOV CL,4
410 SHL DX,CL ; low word of location
411 POP AX
412 MOV CL,12
413 SHR AX,CL ; high word of location
414 MOV CX,AX ; CX <- high
415
416;
417; Read in the resident image (first, seek to it)
418;
419 MOV BX,exec_fh
420 PUSH DS
421 XOR AL,AL
422 invoke $LSEEK ; seek to resident
423 POP DS
424 jnc exec_big_read
425 jmp exec_bomb
426
427exec_big_read: ; Read resident into memory
428 MOV BX,exec_res_len_para
429 CMP BX,1000h ; too many bytes to read?
430 JB exec_read_ok
431 MOV BX,0FE0h ; max in one chunk FE00 bytes
432
433exec_read_ok:
434 SUB exec_res_len_para,BX ; we read (soon) this many
435 PUSH BX
436 MOV CL,4
437 SHL BX,CL ; get count in bytes from paras
438 MOV CX,BX ; count in correct register
439 PUSH DS
440 MOV DS,exec_dma ; Set up read buffer
441 ASSUME DS:NOTHING
442 XOR DX,DX
443 PUSH CX ; save our count
444 CALL ExecRead
445 POP CX ; get old count to verify
446 POP DS
447 JC exec_bad_fileJ
448 DOSAssume CS,<DS>,"EXEC/exec_read_ok"
449 CMP CX,AX ; did we read enough?
450 POP BX ; get paragraph count back
451 JZ execCheckEnd ; and do reloc if no more to read
452;
453; The read did not match the request. If we are off by 512 bytes or more
454; then the header lied and we have an error.
455;
456 SUB CX,AX
457 CMP CX,512
458 JAE Exec_Bad_fileJ
459;
460; We've read in CX bytes... bump DTA location
461;
462ExecCheckEnd:
463 ADD exec_dma,BX ; bump dma address
464 TEST exec_res_len_para,-1
465 JNZ exec_big_read
466;
467; The image has now been read in. We must perform relocation to
468; the current location.
469;
470exec_do_reloc:
471 MOV CX,exec_rel_fac
472 MOV AX,exec_SS ; get initial SS
473 ADD AX,CX ; and relocate him
474 MOV exec_init_SS,AX
475
476 MOV AX,exec_SP ; initial SP
477 MOV exec_init_SP,AX
478
479 LES AX,DWORD PTR exec_IP
480 MOV exec_init_IP,AX
481 MOV AX,ES
482 ADD AX,CX ; relocated...
483 MOV exec_init_CS,AX
484
485 XOR CX,CX
486 MOV DX,exec_rle_table
487 MOV BX,exec_fh
488 PUSH DS
489 XOR AX,AX
490 invoke $LSEEK
491 POP DS
492
493 JNC exec_get_entries
494exec_bad_filej:
495 JMP exec_bad_file
496
497exec_get_entries:
498 MOV DX,exec_rle_count ; Number of entries left
499
500exec_read_reloc:
501 ASSUME DS:NOTHING
502 PUSH DX
503 MOV DX,OFFSET DOSGROUP:exec_internal_buffer
504 MOV CX,((exec_internal_buffer_size)/4)*4
505 PUSH DS
506 CALL ExecRead
507 POP ES
508 POP DX
509 JC exec_bad_filej
510 MOV CX,(exec_internal_buffer_size)/4
511 MOV DI,OFFSET DOSGROUP:exec_internal_buffer ; Pointer to byte location in header
512;
513; Relocate a single address
514;
515 MOV SI,exec_rel_fac
516
517exec_reloc_one:
518 OR DX,DX ; Any more entries?
519 JE exec_set_PDBJ
520
521exec_get_addr:
522 LDS BX,DWORD PTR ES:[DI] ; Get ra/sa of entry
523 MOV AX,DS ; Relocate address of item
524 ADD AX,SI
525 MOV DS,AX
526 ADD [BX],SI
527 ADD DI,4
528 DEC DX
529 LOOP exec_reloc_one ; End of internal buffer?
530
531;
532; We've exhausted a single buffer's worth. Read in the next piece
533; of the relocation table.
534;
535
536 PUSH ES
537 POP DS
538 JMP exec_read_reloc
539
540exec_set_PDBJ:
541 JMP exec_set_PDB
542
543exec_no_memj:
544 JMP exec_no_mem
545
546;
547; we have a .COM file. First, determine if we are merely loading an overlay.
548;
549exec_com_file:
550 TEST BYTE PTR exec_func,exec_func_overlay
551 JZ exec_alloc_com_file
552 LDS SI,exec_blk ; get arg block
553 LODSW ; get load address
554 MOV exec_dma,AX
555 MOV AX,0FFFFh
556 JMP SHORT exec_read_block ; read it all!
557
558; We must allocate the max possible size block (ick!) and set up
559; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block.
560;
561exec_alloc_com_file:
562 MOV BX,0FFFFh
563 invoke $ALLOC ; largest piece available as error
564 OR BX,BX
565 JZ exec_no_memj
566 MOV exec_size,BX ; save size of allocation block
567 PUSH BX
568 invoke $ALLOC ; largest piece available as error
569 POP BX ; get size of block...
570 MOV exec_load_block,AX
571 ADD AX,10h ; increment for header
572 MOV exec_dma,AX
573 XOR AX,AX ; presume 64K read...
574 CMP BX,1000h ; 64k or more in block?
575 JAE exec_read_com ; yes, read only 64k
576 MOV AX,BX ; convert size to bytes
577 MOV CL,4
578 SHL AX,CL
579exec_read_com:
580 SUB AX,100h ; remember size of psp
581exec_read_block:
582 PUSH AX ; save number to read
583 MOV BX,exec_fh ; of com file
584 XOR CX,CX ; but seek to 0:0
585 MOV DX,CX
586 XOR AX,AX ; seek relative to beginning
587 invoke $LSEEK ; back to beginning of file
588 POP CX ; number to read
589 MOV DS,exec_dma
590 XOR DX,DX
591 PUSH CX
592 CALL ExecRead
593 POP SI ; get number of bytes to read
594 jnc OkRead
595 jmp exec_bad_file
596OkRead:
597 CMP AX,SI ; did we read them all?
598 JZ exec_no_memj ; exactly the wrong number... no memory
599 TEST BYTE PTR exec_func,exec_func_overlay
600 JNZ exec_set_PDB ; no starto, chumo!
601 MOV AX,exec_DMA
602 SUB AX,10h
603 MOV exec_init_CS,AX
604 MOV exec_init_IP,100h ; initial IP is 100
605;
606; SI is at most FF00h. Add FE to account for PSP - word of 0 on stack.
607;
608 ADD SI,0FEh ; make room for stack
609 MOV exec_init_SP,SI ; max value for read is also SP!
610 MOV exec_init_SS,AX
611 MOV DS,AX
612 MOV WORD PTR [SI],0 ; 0 for return
613
614exec_set_PDB:
615 MOV BX,exec_fh ; we are finished with the file.
616 CALL exec_dealloc
617 PUSH BP
618 invoke $CLOSE ; release the jfn
619 POP BP
620 CALL exec_alloc
621 TEST BYTE PTR exec_func,exec_func_overlay
622 JZ exec_build_header
623 CALL Scan_Execname ;MS.;AN007;
624 CALL Scan_Special_Entries ;MS.;AN007;
625 Leave
626 transfer SYS_RET_OK ; overlay load -> done
627
628exec_build_header:
629 MOV DX,exec_load_block
630;
631; assign the space to the process
632;
633
634 MOV SI,arena_owner ; pointer to owner field
635
636 MOV AX,exec_environ ; get environ pointer
637 OR AX,AX
638 JZ NO_OWNER ; no environment
639 DEC AX ; point to header
640 MOV DS,AX
641 MOV [SI],DX ; assign ownership
642NO_OWNER:
643 MOV AX,exec_load_block ; get load block pointer
644 DEC AX
645 MOV DS,AX ; point to header
646 MOV [SI],DX ; assign ownership
647
648 PUSH DS ;AN000;MS. make ES=DS
649 POP ES ;AN000;MS.
650 MOV DI,ARENA_NAME ;AN000;MS. ES:DI points to destination
651 CALL Scan_Execname ;AN007;MS. parse execname
652 ; ds:si->name, cx=name length
653 PUSH CX ;AN007;;MS. save for fake version
654 PUSH SI ;AN007;;MS. save for fake version
655
656movename: ;AN000;
657 LODSB ;AN000;;MS. get char
658 CMP AL,'.' ;AN000;;MS. is '.' ,may be name.exe
659 JZ mem_done ;AN000;;MS. no, move to header
660 ;AN000;
661 STOSB ;AN000;;MS. move char
662 LOOP movename ;AN000;;MS. continue
663mem_done: ;AN000;
664 XOR AL,AL ;AN000;;MS. make ASCIIZ
665 CMP DI,SIZE ARENA ;AN000;MS. if not all filled
666 JAE fill8 ;AN000;MS.
667 STOSB ;AN000;MS.
668fill8: ;AN000;
669 POP SI ;AN007;MS. ds:si -> file name
670 POP CX ;AN007;MS.
671
672 CALL Scan_Special_Entries ;AN007;MS.
673
674 PUSH DX
675 MOV SI,exec_size
676 ADD SI,DX
677 invoke $Dup_PDB ; ES is now PDB
678 POP DX
679
680 PUSH exec_environ
681 POP ES:[PDB_environ]
682;
683; set up proper command line stuff
684;
685 LDS SI,exec_blk ; get the block
686 PUSH DS ; save its location
687 PUSH SI
688 LDS SI,[SI.exec0_5C_FCB] ; get the 5c fcb
689;
690; DS points to user space 5C FCB
691;
692 MOV CX,12 ; copy drive, name and ext
693 PUSH CX
694 MOV DI,5Ch
695 MOV BL,[SI]
696 REP MOVSB
697;
698; DI = 5Ch + 12 = 5Ch + 0Ch = 68h
699;
700 XOR AX,AX ; zero extent, etc for CPM
701 STOSW
702 STOSW
703;
704; DI = 5Ch + 12 + 4 = 5Ch + 10h = 6Ch
705;
706 POP CX
707 POP SI ; get block
708 POP DS
709 PUSH DS ; save (again)
710 PUSH SI
711 LDS SI,[SI.exec0_6C_FCB] ; get 6C FCB
712;
713; DS points to user space 6C FCB
714;
715 MOV BH,[SI] ; do same as above
716 REP MOVSB
717 STOSW
718 STOSW
719 POP SI ; get block (last time)
720 POP DS
721 LDS SI,[SI.exec0_com_line] ; command line
722;
723; DS points to user space 80 command line
724;
725 OR CL,80h
726 MOV DI,CX
727 REP MOVSB ; Wham!
728;
729; Process BX into default AX (validity of drive specs on args). We no longer
730; care about DS:SI.
731;
732 DEC CL ; get 0FFh in CL
733 MOV AL,BH
734 XOR BH,BH
735 invoke GetVisDrv
736 JNC exec_BL
737 MOV BH,CL
738exec_BL:
739 MOV AL,BL
740 XOR BL,BL
741 invoke GetVisDrv
742 JNC exec_Set_Return
743 MOV BL,CL
744exec_set_return:
745 invoke get_user_stack ; get his return address
746 PUSH [SI.user_CS] ; suck out the CS and IP
747 PUSH [SI.user_IP]
748 PUSH [SI.user_CS] ; suck out the CS and IP
749 PUSH [SI.user_IP]
750 POP WORD PTR ES:[PDB_Exit]
751 POP WORD PTR ES:[PDB_Exit+2]
752 XOR AX,AX
753 MOV DS,AX
754 POP DS:[addr_int_terminate] ; save them where we can get them later
755 POP DS:[addr_int_terminate+2] ; when the child exits.
756 MOV WORD PTR DMAADD,80h
757 MOV DS,CurrentPDB
758 MOV WORD PTR DMAADD+2,DS
759 TEST BYTE PTR exec_func,exec_func_no_execute
760 JZ exec_go
761
762 LDS SI,DWORD PTR exec_init_SP ; get stack
763 LES DI,exec_blk ; and block for return
764 MOV ES:[DI].exec1_SS,DS ; return SS
765
766 DEC SI ; 'push' default AX
767 DEC SI
768 MOV [SI],BX ; save default AX reg
769 MOV ES:[DI].exec1_SP,SI ; return 'SP'
770
771 LDS AX,DWORD PTR exec_init_IP
772 MOV ES:[DI].exec1_CS,DS ; initial entry stuff
773
774 MOV ES:[DI].exec1_IP,AX
775 Leave
776 transfer SYS_RET_OK
777
778exec_go:
779 LDS SI,DWORD PTR exec_init_IP ; get entry point
780 LES DI,DWORD PTR exec_init_SP ; new stack
781 MOV AX,ES
782;
783; DS:SI points to entry point
784; AX:DI points to initial stack
785; DX has PDB pointer
786; BX has initial AX value
787;
788 CLI
789 MOV BYTE PTR INDOS,0
790 ASSUME SS:NOTHING
791 MOV SS,AX ; set up user's stack
792 MOV SP,DI ; and SP
793 STI
794 PUSH DS ; fake long call to entry
795 PUSH SI
796 MOV ES,DX ; set up proper seg registers
797 MOV DS,DX
798 MOV AX,BX ; set up proper AX
799procedure exec_long_ret,FAR
800
801IF BUFFERFLAG
802 invoke restore_user_map
803ENDIF
804
805 RET
806EndProc exec_long_ret
807
808EndProc $Exec
809
810Procedure ExecRead,NEAR
811 CALL exec_dealloc
812 MOV bx,exec_fh
813 PUSH BP
814 invoke $READ
815 POP BP
816 CALL exec_alloc
817 return
818EndProc ExecRead
819
820procedure exec_dealloc,near
821 ASSUME DS:NOTHING,ES:NOTHING
822 PUSH BX
823 MOV BX,arena_owner_system
824 EnterCrit CritMEM
825 CALL ChangeOwners
826 POP BX
827 return
828EndProc exec_dealloc
829
830procedure exec_alloc,near
831 PUSH BX
832 MOV BX,CurrentPDB
833 CALL ChangeOwners
834 LeaveCrit CritMEM
835 POP BX
836 return
837EndProc exec_alloc
838
839procedure ChangeOwners,NEAR
840 pushf
841 PUSH AX
842 MOV AX,exec_environ
843 CALL ChangeOwner
844 MOV AX,exec_load_block
845 Call ChangeOwner
846 POP AX
847 popf
848 return
849EndProc ChangeOwners
850
851Procedure ChangeOwner,near
852 OR AX,AX ; is area allocated?
853 retz ; no, do nothing
854 DEC AX
855 PUSH DS
856 MOV DS,AX
857 MOV DS:[arena_owner],BX
858 POP DS
859 return
860EndProc ChangeOwner
861
862Procedure Scan_Execname,near ;AN000;MS.
863
864 LDS SI,execName ;AN000;MS. DS:SI points to name
865save_begin: ;AN000;
866 MOV CX,SI ;AN000;MS. CX= starting addr
867scan0: ;AN000;
868 LODSB ;AN000;MS. get char
869 CMP AL,':' ;AN000;;MS. is ':' , may be A:name
870 JZ save_begin ;AN000;;MS. yes, save si
871 CMP AL,'\' ;AN000;;MS. is '\', may be A:\name
872 JZ save_begin ;AN000;;MS. yes, save si
873 CMP AL,0 ;AN000;;MS. is end of name
874 JNZ scan0 ;AN000;;MS. no, continue scanning
875 SUB SI,CX ;AN000;;MS. get name's length
876 XCHG SI,CX ;AN000;;MS. cx= length, si= starting addr
877
878 return ;AN000;;MS.
879EndProc Scan_Execname ;AN000;;MS.
880
881
882Procedure Scan_Special_Entries,near ;AN000;MS.
883
884 DEC CX ;AN007;MS. cx= name length
885 MOV DI,CS:[Special_Entries] ;AN007;MS. es:di -> addr of special entries
886 CALL Reset_Version ;AN008;MS.
887 PUSH CS ;AN007;MS.
888 POP ES ;AN007;MS.
889Getentries: ;AN007;MS.
890 MOV AL,ES:[DI] ;AN007;MS. end of list
891 OR AL,AL ;AN007;MS.
892 JZ end_list ;AN007;MS. yes
893 MOV CS:[Temp_Var2],DI ;AN007;MS. save di
894 CMP AL,CL ;AN007;MS. same length ?
895 JNZ skipone ;AN007;MS. no
896 INC DI ;AN007;MS. es:di -> special name
897 PUSH CX ;AN007;MS. save length and name addr
898 PUSH SI ;AN007;MS.
899 REPZ CMPSB ;AN007;MS. same name ?
900 JNZ not_matched ;AN007;MS. no
901 MOV AX,ES:[DI] ;AN007;MS. get special version
902 MOV CS:[Special_Version],AX ;AN007;MS. save it
903 MOV AL,ES:[DI+2] ;AN008;MS. get fake count
904 MOV CS:[Fake_Count],AL ;AN007;MS. save it
905 POP SI ;AN007;MS.
906 POP CX ;AN007;MS.
907 JMP SHORT end_list ;AN007;MS.
908not_matched: ;AN007;MS.
909 POP SI ;AN007;MS. restore si,cx
910 POP CX ;AN007;MS.
911skipone: ;AN007;MS.
912 MOV DI,CS:[Temp_Var2] ;AN007;MS. restore old di
913 XOR AH,AH ;AN007;MS. position to next entry
914 ADD DI,AX ;AN007;MS.
915 ADD DI,4 ;AN007;MS.
916 JMP Getentries ;AN007;MS.
917
918
919end_list: ;AN007;MS.
920 return
921EndProc Scan_Special_Entries ;AN000;;MS.
922
923Procedure Reset_Version,near ;AN008;MS.
924
925 CMP CS:[Fake_Count],0FFH ;AN008;MS.
926 JNZ dont_reset ;AN008;MS.
927 MOV CS:[Special_Version],0 ;AN008;MS. reset to current version
928dont_reset:
929 return
930EndProc Reset_Version,near ;AN008;;MS.
931 \ No newline at end of file