summaryrefslogtreecommitdiff
path: root/v2.0/source/EXEC.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v2.0/source/EXEC.ASM')
-rw-r--r--v2.0/source/EXEC.ASM1035
1 files changed, 1035 insertions, 0 deletions
diff --git a/v2.0/source/EXEC.ASM b/v2.0/source/EXEC.ASM
new file mode 100644
index 0000000..d41aceb
--- /dev/null
+++ b/v2.0/source/EXEC.ASM
@@ -0,0 +1,1035 @@
1SUBTTL $exec - load/go a program
2PAGE
3;
4; Assembler usage:
5; LDS DX, name
6; LES BX, blk
7; MOV AH, Exec
8; MOV AL, func
9; INT int_command
10;
11; AL Function
12; -- --------
13; 0 Load and execute the program.
14; 1 Load, create the program header but do not
15; begin execution.
16; 3 Load overlay. No header created.
17;
18; AL = 0 -> load/execute program
19;
20; +---------------------------+
21; | WORD segment address of |
22; | environment. |
23; +---------------------------+
24; | DWORD pointer to ASCIZ |
25; | command line at 80h |
26; +---------------------------+
27; | DWORD pointer to default |
28; | FCB to be passed at 5Ch |
29; +---------------------------+
30; | DWORD pointer to default |
31; | FCB to be passed at 6Ch |
32; +---------------------------+
33;
34; AL = 1 -> load program
35;
36; +---------------------------+
37; | WORD segment address of |
38; | environment. |
39; +---------------------------+
40; | DWORD pointer to ASCIZ |
41; | command line at 80h |
42; +---------------------------+
43; | DWORD pointer to default |
44; | FCB to be passed at 5Ch |
45; +---------------------------+
46; | DWORD pointer to default |
47; | FCB to be passed at 6Ch |
48; +---------------------------+
49; | DWORD returned value of |
50; | CS:IP |
51; +---------------------------+
52; | DWORD returned value of |
53; | SS:IP |
54; +---------------------------+
55;
56; AL = 3 -> load overlay
57;
58; +---------------------------+
59; | WORD segment address where|
60; | file will be loaded. |
61; +---------------------------+
62; | WORD relocation factor to |
63; | be applied to the image. |
64; +---------------------------+
65;
66; Returns:
67; AX = exec_invalid_function
68; = exec_bad_format
69; = exec_bad_environment
70; = exec_not_enough_memory
71; = exec_file_not_found
72;
73
74IF IBM
75ZEXEC_DATA SEGMENT PUBLIC BYTE
76ZERO = $
77ENDIF
78
79exec_blk DD ?
80exec_func DB ?
81exec_fh DW ?
82exec_rel_fac DW ?
83exec_res_len_para DW ?
84exec_init_IP DW ?
85exec_init_CS DW ?
86exec_init_SP DW ?
87exec_init_SS DW ?
88exec_environ DW ?
89exec_size DW ?
90exec_load_block DW ?
91
92exec_load_high DB ?
93
94exec_internal_buffer EQU $
95exec_signature DW ? ; must contain 4D5A (yay zibo!)
96exec_len_mod_512 DW ? ; low 9 bits of length
97exec_pages DW ? ; number of 512b pages in file
98exec_rle_count DW ? ; count of reloc entries
99exec_par_dir DW ? ; number of paragraphs before image
100exec_min_BSS DW ? ; minimum number of para of BSS
101exec_max_BSS DW ? ; max number of para of BSS
102exec_SS DW ? ; stack of image
103exec_SP DW ? ; SP of image
104exec_chksum DW ? ; checksum of file (ignored)
105exec_IP DW ? ; IP of entry
106exec_CS DW ? ; CS of entry
107exec_rle_table DW ? ; byte offset of reloc table
108exec_iov DW ? ; overlay number (0 for root)
109exec_dma DW ?
110exec_internal_buffer_size EQU $-exec_internal_buffer
111
112IF IBM
113exec_ctrlc DB ? ; state of users ctrlc flag
114Exec_low_seg DW ?
115CurrentPDB DW ?
116NUMIO DB ?
117ZEXECDATASIZ = $-ZERO
118ZEXECDATAEND LABEL BYTE
119 PUBLIC ZEXECDATAEND
120ZEXEC_DATA ENDS
121ZEXEC_CODE SEGMENT PUBLIC PARA
122 PUBLIC $EXEC
123ZERO = $
124 procedure $EXEC,FAR
125 ASSUME CS:EGROUP,SS:RESGROUP,ES:NOTHING,DS:NOTHING
126ENDIF
127IF NOT IBM
128 procedure $Exec,NEAR
129 ASSUME DS:NOTHING, ES:NOTHING
130ENDIF
131;
132; validate function
133;
134
135IF IBM
136 PUSH CS
137 POP DS
138 ASSUME DS:EGROUP
139
140 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 0 ; Save current ctrl-c
141 INT int_command
142 MOV exec_ctrlc,DL
143 XOR DX,DX
144 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Turn it off!
145 INT int_command
146
147 MOV AH,Get_current_PDB
148 INT int_command
149 MOV [CurrentPDB],BX
150;
151; set up user return stack info
152;
153 MOV ES,BX
154 LES BX,DWORD PTR [user_sp]
155 MOV WORD PTR ES:[PDB_user_stack+2],ES
156 MOV WORD PTR ES:[PDB_user_stack],BX
157
158 MOV AH,Get_Default_Drive
159 INT int_command
160 MOV DL,AL
161 MOV AH,Set_default_drive
162 INT int_command
163 MOV [NUMIO],AL
164;
165; determine lowest seg address for overwrite problem (round DOWN)
166;
167 MOV CL,4
168 MOV AX,OFFSET ZEXEC_CODE:exec_check
169 SHR AX,CL
170 PUSH CS
171 POP BX
172 ADD AX,BX
173 MOV [exec_low_seg],AX
174
175 CALL get_user_stack
176 ASSUME DS:NOTHING
177 MOV AX,[SI.user_AX]
178 MOV BX,[SI.user_BX]
179 MOV DX,[SI.user_DX]
180 MOV ES,[SI.user_ES]
181 MOV DS,[SI.user_DS]
182ENDIF
183
184 CMP AL,3 ; only 0, 1 or 3 are allowed
185 JNA exec_check_2
186
187exec_bad_fun:
188 error error_invalid_function
189
190exec_ret_err:
191 transfer SYS_RET_ERR
192
193exec_check_2:
194 CMP AL,2
195 JZ exec_bad_fun
196
197 MOV WORD PTR [exec_blk],BX ; stash args
198 MOV WORD PTR [exec_blk+2],ES
199 MOV BYTE PTR [exec_func],AL
200 MOV BYTE PTR [exec_load_high],0
201IF IBM
202 MOV AX,(OPEN SHL 8) + 0
203 INT int_command
204ENDIF
205IF NOT IBM
206 XOR AL,AL ; open for reading
207 invoke $OPEN ; is the file there?
208ENDIF
209 JC exec_ret_err
210 MOV [exec_fh],AX
211 MOV BX,AX
212IF IBM
213 MOV AX,(ioctl SHL 8) ; get device information
214 INT int_command
215ENDIF
216IF NOT IBM
217 XOR AL,AL
218 invoke $IOCTL
219ENDIF
220 TEST DL,devid_ISDEV
221 JZ exec_check_environ
222 MOV AL,exec_file_not_found
223 transfer SYS_RET_ERR
224
225exec_check_environ:
226 MOV [exec_load_block],0
227
228 TEST BYTE PTR [exec_func],exec_func_overlay ; overlays... no environment
229 JNZ exec_read_header
230 LDS SI,DWORD PTR [exec_blk] ; get block
231 MOV AX,[SI].Exec1_environ ; address of environ
232 OR AX,AX
233 JNZ exec_scan_env
234 MOV DS,[CurrentPDB]
235 MOV AX,DS:[PDB_environ]
236 MOV [exec_environ],AX
237 OR AX,AX
238 JZ exec_read_header
239
240exec_scan_env:
241 CLD
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 JZ exec_check ; CX is out... bad environment
250 MOV AL,exec_bad_environment
251 JMP exec_bomb
252
253exec_check:
254 SCASB ; is there another nul byte?
255 JNZ exec_get_environ_len ; no, scan some more
256 PUSH DI
257 MOV BX,DI ; AX <- length of environment
258 ADD BX,0Fh
259 MOV CL,4
260 SHR BX,CL ; number of paragraphs needed
261 PUSH ES
262IF IBM
263 MOV AH,ALLOC
264 INT int_command
265ENDIF
266IF NOT IBM
267 invoke $ALLOC ; can we get the space?
268ENDIF
269 POP DS
270 POP CX
271 JNC exec_save_environ
272 JMP exec_no_mem ; nope... cry and sob
273
274exec_save_environ:
275 MOV ES,AX
276 MOV [exec_environ],AX ; save him for a rainy day
277IF IBM
278 PUSH CX
279 MOV CX,ES
280 ADD CX,BX
281 CMP BX,[exec_low_seg]
282 POP CX
283 JA exec_no_mem
284ENDIF
285 XOR SI,SI
286 XOR DI,DI
287 REP MOVSB ; copy the environment
288
289exec_read_header:
290;
291; We read in the program header into the above data area and determine
292; where in this memory the image will be located.
293;
294IF IBM
295 PUSH CS
296 POP DS ; and put it in DS:DX
297 ASSUME DS:EGROUP
298ENDIF
299IF NOT IBM
300 PUSH SS
301 POP DS ; and put it in DS:DX
302 ASSUME DS:DOSGROUP
303ENDIF
304 MOV CX,exec_internal_buffer_size; header size
305 MOV BX,[exec_fh] ; from the handle
306IF IBM
307 MOV DX,OFFSET EGROUP:exec_signature
308ENDIF
309IF NOT IBM
310 MOV DX,OFFSET DOSGROUP:exec_signature
311ENDIF
312 PUSH ES
313 PUSH DS
314 CALL exec_dealloc
315IF IBM
316 MOV AH,READ
317 INT int_command
318ENDIF
319IF NOT IBM
320 invoke $READ
321ENDIF
322 CALL exec_alloc
323 POP DS
324 POP ES
325 JC exec_bad_file
326 CMP AX,exec_internal_buffer_size; did we read the right number?
327 JNZ exec_com_filej ; yep... continue
328 CMP [exec_max_BSS],0
329 JNZ exec_check_sig
330 MOV [exec_load_high],-1
331exec_check_sig:
332 MOV AX,[exec_signature]
333 CMP AX,exe_valid_signature ; zibo arises!
334 JZ exec_save_start ; assume com file if no signature
335 CMP AX,exe_valid_old_signature ; zibo arises!
336 JZ exec_save_start ; assume com file if no signature
337
338exec_com_filej:
339 JMP exec_com_file
340
341;
342; We have the program header... determine memory requirements
343;
344exec_save_start:
345 MOV AX,[exec_pages] ; get 512-byte pages
346 MOV CL,5 ; convert to paragraphs
347 SHL AX,CL
348 SUB AX,[exec_par_dir] ; AX = size in paragraphs
349 MOV [exec_res_len_para],AX
350
351;
352; Do we need to allocate memory? Yes if function is not load-overlay
353;
354 TEST BYTE PTR [exec_func],exec_func_overlay
355 JZ exec_allocate ; allocation of space
356;
357; get load address from block
358;
359 LES DI,DWORD PTR [exec_blk]
360 MOV AX,ES:[DI].exec3_load_addr
361 MOV [exec_dma],AX
362 MOV AX,ES:[DI].exec3_reloc_fac
363 MOV [exec_rel_fac],AX
364IF IBM
365 JMP exec_find_res
366ENDIF
367IF NOT IBM
368 JMP SHORT exec_find_res
369ENDIF
370
371exec_no_mem:
372 MOV AL,exec_not_enough_memory
373 JMP SHORT exec_bomb ; AX should be set by $ALLOC
374
375exec_bad_file:
376 MOV AL,exec_bad_format
377
378exec_bomb:
379 ASSUME DS:NOTHING,ES:NOTHING
380 PUSH AX
381 MOV BX,[exec_fh]
382 CALL exec_dealloc
383IF IBM
384 MOV AH,CLOSE
385 INT int_command
386ENDIF
387IF NOT IBM
388 invoke $CLOSE
389ENDIF
390 POP AX
391 transfer SYS_RET_ERR
392
393exec_allocate:
394IF IBM
395 ASSUME DS:EGROUP
396ENDIF
397IF NOT IBM
398 ASSUME DS:DOSGROUP
399ENDIF
400 PUSH AX
401 MOV BX,0FFFFh ; see how much room in arena
402 PUSH DS
403IF IBM
404 MOV AH,ALLOC
405 INT int_command
406ENDIF
407IF NOT IBM
408 invoke $ALLOC ; should have carry set and BX has max
409ENDIF
410 POP DS
411 POP AX
412 ADD AX,10h ; room for header
413 CMP BX,11h ; enough room for a header
414 JB exec_no_mem
415 CMP AX,BX ; is there enough for bare image?
416 JA exec_no_mem
417 CMP [exec_load_high],0 ; if load high, use max
418 JNZ exec_BX_max ; use max
419 ADD AX,[exec_min_BSS] ; go for min allocation
420 JC exec_no_mem ; oops! carry
421 CMP AX,BX ; enough space?
422 JA exec_no_mem ; nope...
423 SUB AX,[exec_min_BSS]
424 ADD AX,[exec_max_BSS] ; go for the MAX
425 JC exec_BX_max
426 CMP AX,BX
427 JBE exec_got_block
428
429exec_BX_max:
430 MOV AX,BX
431
432exec_got_block:
433 PUSH DS
434 MOV BX,AX
435 MOV [exec_size],BX
436IF IBM
437 MOV AH,ALLOC
438 INT int_command
439ENDIF
440IF NOT IBM
441 invoke $ALLOC ; get the space
442ENDIF
443 POP DS
444 JC exec_no_mem
445 MOV [exec_load_block],AX
446 ADD AX,10h
447 CMP [exec_load_high],0
448 JZ exec_use_ax ; use ax for load info
449 ADD AX,[exec_size] ; go to end
450 SUB AX,[exec_res_len_para] ; drop off header
451 SUB AX,10h ; drop off pdb
452exec_use_ax:
453 MOV [exec_rel_fac],AX ; new segment
454 MOV [exec_dma],AX ; beginning of dma
455IF IBM
456 CMP AX,[exec_low_seg] ; below loader
457 JA exec_no_mem_try
458 ADD AX,[exec_res_len_para] ; go to end
459 CMP Ax,[exec_low_seg] ; above loader
460 JBE exec_find_res
461exec_try_high:
462 CMP [exec_load_high],0
463 JZ exec_no_memj1
464exec_try_just_below:
465 MOV DX,AX
466 SUB DX,[exec_size] ; get beginning
467 ADD DX,[exec_res_len_para] ; no space
468 CMP DX,[exec_low_seg] ; room there?
469 JA exec_no_memj1
470 MOV AX,[exec_low_seg]
471 SUB AX,[exec_res_len_para]
472 JMP exec_use_ax
473exec_no_mem_try:
474 MOV DX,CS
475 ADD DX,(zexecdatasiz+zexeccodesize+15)/16
476 CMP AX,DX
477 JAE exec_try_high
478 JMP exec_try_just_below
479exec_no_memj1:
480 JMP exec_no_mem
481ENDIF
482
483;
484; Determine the location in the file of the beginning of the resident
485;
486exec_find_res:
487 MOV DX,[exec_par_dir]
488 PUSH DX
489 MOV CL,4
490 SHL DX,CL ; low word of location
491 POP AX
492 MOV CL,12
493 SHR AX,CL ; high word of location
494 MOV CX,AX ; CX <- high
495
496;
497; Read in the resident image (first, seek to it)
498;
499 MOV BX,[exec_fh]
500 PUSH DS
501IF IBM
502 MOV AX,(LSEEK SHL 8) + 0
503 INT int_command
504ENDIF
505IF NOT IBM
506 XOR AL,AL
507 invoke $LSEEK ; seek to resident
508ENDIF
509 POP DS
510
511exec_big_read: ; Read resident into memory
512 MOV BX,[exec_res_len_para]
513 CMP BX,1000h ; too many bytes to read?
514 JB exec_read_ok
515 MOV BX,0FE0h ; max in one chunk FE00 bytes
516
517exec_read_ok:
518 SUB [exec_res_len_para],BX ; we read (soon) this many
519 PUSH BX
520 MOV CL,4
521 SHL BX,CL ; get count in bytes from paras
522 MOV CX,BX ; count in correct register
523 MOV BX,[exec_fh] ; handle in correct register
524 PUSH DS
525 MOV DS,[exec_dma] ; Set up read buffer
526 ASSUME DS:NOTHING
527 XOR DX,DX
528 PUSH CX ; save our count
529 CALL exec_dealloc
530IF IBM
531 MOV AH,READ
532 INT int_command
533ENDIF
534IF NOT IBM
535 invoke $READ ; WOMP!
536ENDIF
537 CALL exec_alloc
538 POP CX ; get old count to verify
539 POP DS
540IF IBM
541 ASSUME DS:EGROUP
542ENDIF
543IF NOT IBM
544 ASSUME DS:DOSGROUP
545ENDIF
546 CMP CX,AX ; did we read enough?
547 POP BX ; get paragraph count back
548 JNZ exec_do_reloc ; and do reloc if no more to read
549;
550; We've read in CX bytes... bump DTA location
551;
552
553 ADD [exec_dma],BX ; bump dma address
554 CMP [exec_res_len_para],0
555 JNZ exec_big_read
556
557;
558; The image has now been read in. We must perform relocation to
559; the current location.
560;
561
562exec_do_reloc:
563 MOV CX,[exec_rel_fac]
564 MOV AX,[exec_SS] ; get initial SS
565 ADD AX,CX ; and relocate him
566 MOV [exec_init_SS],AX
567
568 MOV AX,[exec_SP] ; initial SP
569 MOV [exec_init_SP],AX
570
571 LES AX,DWORD PTR [exec_IP]
572 MOV [exec_init_IP],AX
573 MOV AX,ES
574 ADD AX,CX ; relocated...
575 MOV [exec_init_CS],AX
576
577 XOR CX,CX
578 MOV DX,[exec_rle_table]
579 MOV BX,[exec_fh]
580 PUSH DS
581IF IBM
582 MOV AX,(LSEEK SHL 8) + 0
583 INT int_command
584ENDIF
585IF NOT IBM
586 XOR AX,AX
587 invoke $LSEEK
588ENDIF
589 POP DS
590
591 JNC exec_get_entries
592exec_bad_filej:
593 JMP exec_bad_file
594
595exec_get_entries:
596 MOV DX,[exec_rle_count] ; Number of entries left
597
598exec_read_reloc:
599 ASSUME DS:NOTHING
600 PUSH DX
601IF IBM
602 MOV DX,OFFSET EGROUP:exec_signature
603ENDIF
604IF NOT IBM
605 MOV DX,OFFSET DOSGROUP:exec_signature
606ENDIF
607 MOV CX,((exec_internal_buffer_size)/4)*4
608 MOV BX,[exec_fh]
609 PUSH DS
610 CALL exec_dealloc
611IF IBM
612 MOV AH,READ
613 INT int_command
614ENDIF
615IF NOT IBM
616 invoke $READ
617ENDIF
618 CALL exec_alloc
619 POP ES
620 POP DX
621 JC exec_bad_filej
622 MOV CX,(exec_internal_buffer_size)/4
623IF IBM
624 MOV DI,OFFSET EGROUP:exec_signature ; Pointer to byte location in header
625ENDIF
626IF NOT IBM
627 MOV DI,OFFSET DOSGROUP:exec_signature ; Pointer to byte location in header
628ENDIF
629;
630; Relocate a single address
631;
632 MOV SI,[exec_rel_fac]
633
634exec_reloc_one:
635 CMP DX,0 ; Any more entries?
636 JNE exec_get_addr
637 JMP Exec_set_PDB
638
639exec_get_addr:
640 LDS BX,DWORD PTR ES:[DI] ; Get ra/sa of entry
641 MOV AX,DS ; Relocate address of item
642 ADD AX,SI
643 MOV DS,AX
644 MOV AX,WORD PTR DS:[BX] ; Relocate item
645 ADD AX,SI
646 MOV WORD PTR DS:[BX],AX
647 ADD DI,4
648 DEC DX
649 LOOP exec_reloc_one ; End of internal buffer?
650
651;
652; We've exhausted a single buffer's worth. Read in the next piece
653; of the relocation table.
654;
655
656 PUSH ES
657 POP DS
658 JMP exec_read_reloc
659
660exec_no_memj:
661 JMP exec_no_mem
662
663;
664; we have a .COM file. First, determine if we are merely loading an overlay.
665;
666exec_com_file:
667 TEST BYTE PTR [exec_func],exec_func_overlay
668 JZ exec_alloc_com_file
669 LDS SI,DWORD PTR [exec_blk] ; get arg block
670 LODSW ; get load address
671 MOV [exec_dma],AX
672 JMP SHORT exec_64k ; read it all!
673
674; We must allocate the max possible size block (ick!) and set up
675; CS=DS=ES=SS=PDB pointer, IP=100, SP=max size of block.
676;
677exec_alloc_com_file:
678 MOV BX,0FFFFh
679IF IBM
680 MOV AH,ALLOC
681 INT int_command
682ENDIF
683IF NOT IBM
684 invoke $ALLOC ; largest piece available as error
685ENDIF
686 OR BX,BX
687 JZ exec_no_memj
688 MOV [exec_size],BX ; save size of allocation block
689IF IBM
690 MOV AH,ALLOC
691 INT int_command
692ENDIF
693IF NOT IBM
694 PUSH BX
695 invoke $ALLOC ; largest piece available as error
696 POP BX ; get size of block...
697ENDIF
698 MOV [exec_load_block],AX
699 ADD AX,10h ; increment for header
700 MOV [exec_dma],AX
701 SUB BX,10h ; remember header
702IF IBM
703;
704; need to read up to exec_low_seg (at most)
705;
706 MOV CX,[exec_low_seg]
707 CMP AX,CX ; is base of allocation above spot
708 JA exec_check_64k
709 SUB CX,AX
710 CMP CX,BX
711 JA exec_check_64k
712 MOV BX,CX
713
714exec_check_64k:
715ENDIF
716 CMP BX,1000h ; 64k or more?
717 JAE exec_64k ; yes, read only 64k
718 MOV AX,BX ; convert size to bytes
719 MOV CL,4
720 SHL AX,CL
721 JMP SHORT exec_read_com
722
723exec_64k:
724 MOV AX,0FFFFh ; 64k-1 bytes
725
726exec_read_com:
727 PUSH AX ; save number to read
728 MOV BX,[exec_fh] ; of com file
729 XOR CX,CX ; but seek to 0:0
730 MOV DX,CX
731IF IBM
732 MOV AX,(LSEEK SHL 8) + 0
733 INT int_command
734ENDIF
735IF NOT IBM
736 XOR AX,AX ; seek relative to beginning
737 invoke $LSEEK ; back to beginning of file
738ENDIF
739 MOV BX,[exec_fh]
740 POP CX ; number to read
741 MOV DS,[exec_dma]
742 XOR DX,DX
743 PUSH CX
744 CALL exec_dealloc
745IF IBM
746 MOV AH,READ
747 INT int_command
748ENDIF
749IF NOT IBM
750 invoke $READ ; read in com file
751ENDIF
752 CALL exec_alloc
753 POP SI ; get number of bytes to read
754 CMP AX,SI ; did we read them all?
755IF IBM
756 JNZ exec_skip ; exactly the wrong number... no memory
757 JMP exec_no_mem
758exec_skip:
759ENDIF
760IF NOT IBM
761 JZ exec_no_memj ; exactly the wrong number... no memory
762ENDIF
763 TEST BYTE PTR [exec_func],exec_func_overlay
764 JNZ exec_set_PDB ; no starto, chumo!
765 MOV AX,[exec_DMA]
766 SUB AX,10h
767 MOV [exec_init_CS],AX
768 MOV [exec_init_IP],100h ; initial IP is 100
769 ; SI is at most FFFFh
770 DEC SI ; make room for stack
771 ; SI is at most FFFEh, room for a 0!
772 MOV [exec_init_SP],SI ; max value for read is also SP!
773 MOV [exec_init_SS],AX
774 MOV DS,AX
775 MOV WORD PTR DS:[SI],0 ; 0 for return
776
777exec_set_PDB:
778 MOV BX,[exec_fh] ; we are finished with the file.
779 CALL exec_dealloc
780IF IBM
781 MOV AH,CLOSE
782 INT int_command
783ENDIF
784IF NOT IBM
785 invoke $CLOSE ; release the jfn
786ENDIF
787 CALL exec_alloc
788 TEST BYTE PTR [exec_func],exec_func_overlay
789 JZ exec_build_header
790 transfer SYS_RET_OK ; overlay load -> done
791
792exec_build_header:
793 MOV DX,[exec_load_block]
794;
795; assign the space to the process
796;
797
798 MOV SI,arena_owner ; pointer to owner field
799
800 MOV AX,[exec_environ] ; get environ pointer
801 OR AX,AX
802 JZ NO_OWNER ; no environment
803 DEC AX ; point to header
804 MOV DS,AX
805 MOV DS:[SI],DX ; assign ownership
806NO_OWNER:
807 MOV AX,[exec_load_block] ; get load block pointer
808 DEC AX
809 MOV DS,AX ; point to header
810 MOV DS:[SI],DX ; assign ownership
811
812 PUSH DX
813IF IBM
814 MOV AH,DUP_PDB
815 INT int_command
816 MOV ES,DX
817 MOV [CurrentPDB],DX
818ENDIF
819IF NOT IBM
820 MOV BYTE PTR [CreatePDB], 0FFH ; indicate a new process
821 invoke $Dup_PDB ; ES is now PDB
822ENDIF
823 POP DX
824 PUSH [exec_environ]
825 POP ES:[PDB_environ]
826 MOV SI,[exec_size]
827 ADD SI,DX
828 MOV ES:[PDB_block_len],SI
829;
830; set up proper command line stuff
831;
832 LDS SI,DWORD PTR [exec_blk] ; get the block
833 PUSH DS ; save its location
834 PUSH SI
835 LDS SI,DS:[SI.exec0_5C_FCB] ; get the 5c fcb
836 MOV CX,12 ; copy drive, name and ext
837 PUSH CX
838 MOV DI,5Ch
839 MOV BL,DS:[SI]
840 REP MOVSB
841 XOR AX,AX ; zero extent, etc for CPM
842 STOSW
843 STOSW
844 POP CX
845 POP SI ; get block
846 POP DS
847 PUSH DS ; save (again)
848 PUSH SI
849 LDS SI,DS:[SI.exec0_6C_FCB] ; get 6C FCB
850 MOV DI,6Ch ; do same as above
851 MOV BH,DS:[SI]
852 REP MOVSB
853 STOSW
854 STOSW
855 POP SI ; get block (last time)
856 POP DS
857 LDS SI,DS:[SI.exec0_com_line] ; command line
858 MOV CX,80h
859 MOV DI,CX
860 REP MOVSB ; Wham!
861
862;
863; Process BX into default AX (validity of drive specs on args)
864;
865 DEC CL ; get 0FFh in CX
866 CMP BH,[NUMIO]
867 JBE exec_BH_good
868 MOV BH,CL
869 JMP SHORT exec_BL
870exec_BH_good:
871 XOR BH,BH
872exec_BL:
873 CMP BL,[NUMIO]
874 JBE exec_BL_good
875 MOV BL,CL
876 JMP SHORT exec_set_return
877exec_BL_good:
878 XOR BL,BL
879exec_set_return:
880 invoke get_user_stack ; get his return address
881 PUSH [SI.user_CS] ; suck out the CS and IP
882 PUSH [SI.user_IP]
883 PUSH [SI.user_CS] ; suck out the CS and IP
884 PUSH [SI.user_IP]
885 POP WORD PTR ES:[PDB_Exit]
886 POP WORD PTR ES:[PDB_Exit+2]
887 XOR AX,AX
888 MOV DS,AX
889 POP DS:[addr_int_terminate] ; save them where we can get them later
890 POP DS:[addr_int_terminate+2] ; when the child exits.
891IF NOT IBM
892 MOV WORD PTR [DMAADD],80h
893 MOV DS,[CurrentPDB]
894 MOV WORD PTR [DMAADD+2],DS
895ENDIF
896IF IBM
897 PUSH DX
898 PUSH DS
899 MOV DS,[CurrentPDB]
900 MOV DX,80h
901 MOV AH,SET_DMA
902 INT int_command
903 POP DS
904 POP DX
905ENDIF
906 TEST BYTE PTR [exec_func],exec_func_no_execute
907 JZ exec_go
908
909 LDS SI,DWORD PTR [exec_init_SP] ; get stack
910 LES DI,DWORD PTR [exec_blk] ; and block for return
911 MOV ES:[DI].exec1_SS,DS ; return SS
912
913 DEC SI ; 'push' default AX
914 DEC SI
915 MOV DS:[SI],BX ; save default AX reg
916 MOV ES:[DI].exec1_SP,SI ; return 'SP'
917
918 LDS AX,DWORD PTR [exec_init_IP]
919 MOV ES:[DI].exec1_CS,DS ; initial entry stuff
920
921 MOV ES:[DI].exec1_IP,AX
922 transfer SYS_RET_OK
923
924exec_go:
925IF IBM
926 CALL restore_ctrlc ; restore value of ctrl-c checker
927ENDIF
928 LDS SI,DWORD PTR [exec_init_IP] ; get entry point
929 CLI
930IF NOT IBM
931 MOV BYTE PTR INDOS,0
932ENDIF
933 MOV SS,[exec_init_SS] ; set up user's stack
934 ASSUME SS:NOTHING
935 MOV SP,[exec_init_SP] ; and SP
936 STI
937 PUSH DS ; fake long call to entry
938 PUSH SI
939 MOV ES,DX ; set up proper seg registers
940 MOV DS,DX
941 MOV AX,BX ; set up proper AX
942 procedure exec_long_ret,FAR
943 RET
944exec_long_ret ENDP
945
946$Exec ENDP
947
948 procedure exec_dealloc,near
949 ASSUME DS:NOTHING,ES:NOTHING
950 PUSH BX
951 MOV BX,arena_owner_system
952 CALL exec_do_change_owner
953 POP BX
954 return
955exec_dealloc ENDP
956
957 procedure exec_alloc,near
958 PUSH BX
959 MOV BX,[CurrentPDB]
960 CALL exec_do_change_owner
961 POP BX
962 return
963exec_alloc ENDP
964
965 procedure exec_do_change_owner,NEAR
966 PUSH DS
967 PUSH AX
968 MOV AX,[exec_environ]
969 OR AX,AX
970 JZ exec_alloc_try_load
971 DEC AX
972 MOV DS,AX
973 MOV DS:[arena_owner],BX
974exec_alloc_try_load:
975 MOV AX,[exec_load_block]
976 OR AX,AX
977 JZ exec_alloc_done
978 DEC AX
979 MOV DS,AX
980 MOV DS:[arena_owner],BX
981exec_alloc_done:
982 POP AX
983 POP DS
984 RET
985exec_do_change_owner ENDP
986
987IF IBM
988SYS_RET_ERR:
989 CALL get_user_stack
990 PUSH [SI.user_f]
991 XOR AH,AH
992 MOV [SI.user_AX],AX
993 POPF
994 STC
995 JMP SYS_RET
996SYS_RET_OK:
997 CALL get_user_stack
998 PUSH [SI.user_f]
999 POPF
1000 CLC
1001SYS_RET:
1002 PUSHF
1003 CALL restore_ctrlc
1004 POP [SI.user_f]
1005 JMP exec_long_ret
1006
1007;
1008; get_user_stack returns the user's stack (and hence registers) in DS:SI
1009;
1010 procedure get_user_stack,NEAR
1011 PUSH SS
1012 POP DS
1013 ASSUME DS:RESGROUP
1014 LDS SI,DWORD PTR [user_SP]
1015 RET
1016get_user_stack ENDP
1017;
1018; restore value of the ctrl-c checker
1019;
1020 procedure restore_ctrlc
1021 PUSH AX
1022 PUSH DX
1023 MOV DL,CS:[exec_ctrlc]
1024 MOV AX,(Set_Ctrl_C_Trapping SHL 8) + 1 ; Put it back
1025 INT int_command
1026 POP DX
1027 POP AX
1028 RET
1029restore_ctrlc ENDP
1030
1031ZEXECCODESIZE EQU $-ZERO
1032ZEXECCODEEND LABEL BYTE
1033 PUBLIC ZEXECCODEEND
1034ZEXEC_CODE ENDS
1035ENDIF