;***************************************************** ;* ;* Program Load ;* ;***************************************************** ; ; LDTAB Entry Format: ; 0 2 4 6 8 ; +-----+-----+-----+-----+-----+-----+-----+-----+ ; | START | MIN | MAX | PD | ; +-----+-----+-----+-----+-----+-----+-----+-----+ ; ; 8 10(A) 12(C) 14(E) 16(10) 17(11) ; +-----+-----+-----+-----+-----+-----+-----+-----+-----+ ; | ATR | FSTRT | FLEN | TYPE| ID | ; +-----+-----+-----+-----+-----+-----+-----+-----+-----+ ; ; ; start Absolute Address requested ; min Min memory wanted ; max Max memory wanted ; pd PD to allocate to ; atr Attributes, Memory Flags ; fstrt Starting paragraph in File ; flen # of paragraphs in file ; type Group type ; id Segment Address of this group ; ; The Load Table contains 9 entries, One for each ; potential Group in Command File and One extra ; for Independent Memory Allocations. ldt_start equ word ptr 0 ldt_min equ word ptr ldt_start + word ldt_max equ word ptr ldt_min + word ldt_pd equ word ptr ldt_max + word ldt_atr equ word ptr ldt_pd + word ldt_fstrt equ word ptr ldt_atr + word ldt_flen equ word ptr ldt_fstrt + word ldt_type equ byte ptr ldt_flen + word ldt_id equ word ptr ldt_type + byte ldtlen equ ldt_id + word ;========= cload_ent: ; entry point to load for a chain command ;========= ; Assumes UDA is set in passed PD. push bx ! mov bx,1 jmps load ;======== load_ent: ; User entry point to load .CMD file for execution ;======== ; input: DX = address of open FCB in u_wrkseg ; output: BX = segment addr of Base Page ; = 0ffffh if error ; CX = Error Code sub bx,bx ;jmp load ;==== load: ; Intermodule entry point to load .CMD file ;==== ; input: DX = addr of open FCB in u_wrkseg ; BX = addr of unused PD to initialize ; 0 - do not init PD ; 1 - chain load (PD addr on stack) ; output: BX = seg addr of Base Page ; = 0ffffh if error ; CX = Error Code ; Get MXLoad Queue push dx ! push bx mov cx,f_qread ! mov dx,offset mxloadqpb call osif mov lod_chain,false pop lod_pd ! pop si cmp lod_pd,1 ! jne ld_cf pop lod_pd ! mov lod_chain,true ; Copy FCB into lod_fcb ; SI-> user FCB in u_wrkseg ld_cf: mov cx,fcblen/2 ! mov di,offset lod_fcb push es ! push ds ! push ds mov ds,u_wrkseg ! pop es rep movsw pop ds ! pop es ; Read the Header mov bx,offset lod_fcb mov byte ptr fcb_r0+2[bx],0 mov ax,0 ;record # mov bx,1 ;# of sectors mov dx,offset lod_dma ;DMA offset mov cx,sysdat ;DMA segment call drd ! cmp di,1 ;check for EOF in header read je lod_eof jcxz ndpchk lod_eof: mov cx, e_bad_load ; tried to load a 0 length cmd file mov bx, 0ffffh ; or one whose header is incorrect jmp lod_exit ndpchk: ;see if 8087 required mov lod_ndp,0 ;default = no mov bx, offset lod_dma test ch_lbyte[bx],need_8087 jz ndp_flg ;not required - but is it optional? cmp owner_8087,0ffffh ;needs it,but is there one in system? jnz ndp_yes ;yes- flag it mov cx,e_nondp ;no - abandon load & return mov bx, 0ffffh jmp lod_exit ndp_flg: test ch_lbyte[bx],opt_8087 ;will use it if present? jz h_hdr ;doesn't want it at all cmp owner_8087,0ffffh ;will use it,but is there one ? jnz ndp_yes ;if not, flag it as an emulator user mov lod_ndp,1 jmp h_hdr ndp_yes: mov lod_ndp,0ffh ;flag it as an 8087 user h_hdr: mov lod_suspnd,0 ;default = no suspend needed test ch_lbyte[bx],susp_mode ;require background suspension ? jz h_hdr1 ;no... mov lod_suspnd,0ffh ;yes, flag pd later h_hdr1: mov lod_indma,0 ; initialize Load Disk and User ; from FCB mov bx,rlr mov al,p_user[bx] mov lod_user,al mov al,p_dsk[bx] ;default disk of calling PD mov lod_disk,al ;1-15 -> A-P mov bx,offset lod_fcb mov al,fcb_dr[bx] mov lod_fifty,al ;base page address 50H, 0=default test al,al ! jz use_ddsk dec al ;1-15 -> A-P mov lod_disk,al use_ddsk: test byte ptr fcb_name+7[bx],080h ! jz use_dusr mov lod_user,0 use_dusr: ; Initialize ldtab ; Zero ldtab mov cx,ldtabsiz/2 ! sub ax,ax mov di,offset ldtab push es ! mov es,sysdat rep stos ax ! pop es ; 1st ldtab entry is UDA and LSTK ; if a PD was specified... mov lod_nldt,0 mov si,offset ldtab cmp lod_pd,0 ! jne sel_uda jmp gc_ifo sel_uda: cmp lod_ndp,0 ;see if 8087 user and long jz form_uda ;uda is needed cmp lod_ndp,0ffh ;no... jz form_87uda form_emuda: mov ldt_min[si],(lstklen+em87len)/16 ;8087 emulator user mov ldt_max[si],(lstklen+em87len)/16 ;64 byte extension jmp cont_uda form_87uda: mov ldt_min[si],(lstklen+u8087len)/16 ;8087 user mov ldt_max[si],(lstklen+u8087len)/16 ;96 byte extension jmp cont_uda form_uda: mov ldt_min[si],(lstklen+ulen)/16 ;min=max=UDA+STK paragraphs mov ldt_max[si],(lstklen+ulen)/16 cont_uda: mov ax,lod_pd ! mov ldt_pd[si],ax mov ldt_atr[si],mf_load add si,ldtlen inc lod_nldt cmp lod_chain,true ! jne gc_ifo ;We are CHAINING. Free all memory ; except UDA area and LDSTK. This will keep ; the first partition for the chain ; as well as not crash the system. push si mov cx,f_freeall ! call osif ;transfer memory to new pd mov bx,rlr mov ax,p_mem[bx] ! mov p_mem[bx],0 mov bx,lod_pd ! mov p_mem[bx],ax pop si gc_ifo: ;go through CMD header and init ;a ldtab entry per header entry. ;alloc abs mem mov bx,offset lod_dma mov al,ch_lbyte[bx] ; save fixup flag mov lod_lbyte,al mov ax,ch_fixrec[bx] ; save record # of fixups, if any mov lod_fixrec,ax mov lod_fixrec1,ax mov cx,ch_entmax ; BX = offset LOD_DMA mov dx,8 ; DX = position in file ch_more:cmp ch_form[bx],0 ! jne ch_doit jmp ch_next ch_doit: mov al,ch_form[bx] ! mov ldt_type[si],al ;type of seg mov ax,ch_length[bx] ! mov ldt_flen[si],ax ;length mov ldt_fstrt[si],dx ! add dx,ax ;pos in file mov ax,ch_base[bx] ! mov ldt_start[si],ax ;abs seg mov ax,ch_min[bx] ! mov ldt_min[si],ax ;min needed mov ax,ch_max[bx] cmp ax,0 ! jne setmax mov ax,ch_min[bx] setmax: mov ldt_max[si],ax ;max wanted mov ax,lod_pd ! mov ldt_pd[si],ax ;pd to alloc to cmp ax,0 ! je not_load mov ax,mf_load jmps not_load skipjmp:jmps ch_more ;if mpm not_load: cmp ch_form[bx],1 ! jne try_sh add ax,mf_code ! jmps s_atr try_sh: cmp ch_form[bx],9 ! jne s_atr add ax,mf_code+mf_share s_atr: mov ldt_atr[si],ax ;memory flags ;if abs, allocate memory cmp ldt_start[si],0 ! je ch_nabs ;see if abs mem jmps ch_al ch_nabs: cmp ldt_type[si],9 jne ch_nxt ;see if shared code push cx push bx ! push dx ;save load DMA and position in file call get_sh pop dx ! pop bx cmp cx,0 ! pop cx je ch_nxt jmp ld_out ch_al: push bx ! push dx ! push cx ! push si mov cx,f_malloc ! mov dx,si call osif ! pop si mov ax,ldt_start[si] ! mov ldt_id[si],ax cmp cx,0 ! pop cx ! pop dx ! pop bx je ch_nxt ;couldn't find memory mov bx,0ffffh ! mov cx,e_no_memory jmp ld_out ;endif ;if ccpm ;not_load: cmp ch_form[bx],9 ! jne try_code ; mov ch_form[bx],1 ; mov ldt_type[si],1 ;try_code: cmp ch_form[bx],1 ! jne s_atr ; add ax,mf_code ;s_atr: mov ldt_atr[si],ax ;memory flags ; ; ;if abs, allocate memory ; cmp ldt_start[si],0 ! je ch_nxt ;see if abs mem ;ch_al: push bx ! push dx ! push cx ! push si ; mov cx,f_malloc ! mov dx,si ; call osif ! pop si ; mov ax,ldt_start[si] ! mov ldt_id[si],ax ; cmp cx,0 ! pop cx ! pop dx ! pop bx ; je ch_nxt ; ;couldn't find memory ; mov bx,0ffffh ! mov cx,e_no_memory ; jmp ld_out ; ;endif ch_nxt: add si,ldtlen inc lod_nldt ch_next:add bx,chlen loop skipjmp ; alloc all other memory ; SI -> mpb for non_abs mem req. ;add all parts together for a single malloc mov bx,offset ldtab mov cx,lod_nldt mov lod_nrels,0 lt_more:cmp ldt_min[bx],0 ! je lt_next cmp ldt_start[bx],0 ! jne lt_next mov ax,ldt_min[bx] mov dx,ax add ldt_min[si],ax cmp dx,ldt_min[si] ! jbe lt_m ; check for ovrflw mov ldt_min[si],0ffffh lt_m: mov ax,ldt_max[bx] mov dx,ax add ldt_max[si],ax cmp dx,ldt_max[si] ! jbe lt_m1 ; check for ovrflw mov ldt_max[si],0ffffh lt_m1: inc lod_nrels lt_next:add bx,ldtlen ! loop lt_more ;malloc cmp lod_pd,0 ! je noloadf mov ldt_atr[si],mf_load noloadf:mov ax,lod_pd ! mov ldt_pd[si],ax push si ! mov dx,si ! mov cx,f_malloc call osif ! pop si mov ax,ldt_start[si] ! mov ldt_id[si],ax cmp bx,0ffffh ! jne lt_sprd ;Not Enough Memory - release any ; memory already allocated ld_out: push cx mov bx,offset ldtab mov cx,lod_nldt ! inc cx lg_more: cmp ldt_id[bx],0 ! je lg_next push cx ! push bx ! push ds ;push MFPB on stack push ldt_pd[bx] push ldt_id[bx] mov dx,sp ! push ss ! pop ds mov cx,f_memfree call osif pop cx ! pop cx pop ds ! pop bx ! pop cx lg_next: add bx,ldtlen ! loop lg_more mov bx,0ffffh ! pop cx ! jmp lod_exit lt_sprd: ;spread the memory allocated ;amongst the nrels ;1st give everyone the minimum mov bx,offset ldtab mov cx,lod_nldt ls_more:cmp ldt_start[bx],0 ! jne ls_next mov ax,ldt_min[bx] sub ldt_min[si],ax cmp ax,ldt_max[bx] ! jne ls_next mov dx,ldt_start[si] ! mov ldt_start[bx],dx add ldt_start[si],ax dec lod_nrels ls_next:add bx,ldtlen ! loop ls_more ;spread whats left amongst those that need more mov bx,offset ldtab mov cx,lod_nldt lsl_mre:cmp ldt_start[bx],0 ! jne lsl_nxt mov ax,ldt_start[si] ! mov ldt_start[bx],ax mov ax,ldt_min[si] cmp ax,0 ! je adj_start push cx ! sub cx,cx mov dx,cx ! mov cl,lod_nrels div cx ! pop cx cmp dx,0 ! je evendiv inc ax evendiv: mov dx,ldt_max[bx] ! sub dx,ldt_min[bx] cmp ax,dx ! jbe nottoomuch mov ax,dx nottoomuch: add ldt_min[bx],ax ! sub ldt_min[si],ax adj_start: mov ax,ldt_min[bx] ! add ldt_start[si],ax dec lod_nrels lsl_nxt:add bx,ldtlen ! loop lsl_mre ; fill memory from file mov si,offset ldtab mov cx,lod_nldt lf_mre: cmp ldt_flen[si],0 ! je lf_nxt push cx ! push ldt_start[si] ! push si call lod_group pop si ! pop ldt_start[si] cmp cx,0 ! pop cx je lf_nxt ;if ccpm ; ; jmp ld_out ;endif ;if mpm ; error in lod_group ; if loading shared code we also ; have to release Shared Code from SCL. ; It will be the top item in the list. cmp ldt_atr[si],mf_load+mf_code+mf_share je rm_sh jmp ld_out rm_sh: push cx ; remember Err Code ; Remove PD from SCL pushf ! cli mov bx,scl mov ax,p_thread[bx] mov scl,ax popf ; Release the memory push ds ! push bx mov bx,p_mem[bx] ! push ms_start[bx] mov ax,ss ! mov ds,ax mov dx,sp ! mov cx,f_memfree call osif pop ax ! pop bx ! pop ds ; Place PD on PUL pushf ! cli mov ax,pul mov pul,bx mov p_link[bx],ax popf pop cx jmp ld_out ;endif lf_nxt: add si,ldtlen ! loop lf_mre ; Check for fixup records and do fixups test lod_lbyte,80h ; hi bit of last byte in cmd header jz init_base ; is set if fixups fx_read: mov ax,lod_fixrec ; get record # of fixups in file mov bx,1 ; read one record mov cx,ds mov dx, offset lod_dma call drd ; do random read jcxz fx_read_ok ; 0=ok,CL=0ff if EOF inc cl ; EOF ? jnz fx_err ; some read error, not EOF mov ax,lod_fixrec1 ; make sure one fixup cmp ax,lod_fixrec ; record was read since cmd header je fx_err ; said we needed them jmps init_base fx_read_ok: ; go look for fixup records mov bx,offset lod_dma ; BX-> at fixup records fx_chk: mov al,fix_grp[bx] ; any more fixups? test al,al jz init_base and al,0fh ; low nibble is target group call tblsrch ; find target group in load table mov dx,ldt_start[di] ; DX = target segment, this is ; what we add to the load image mov al,fix_grp[bx] ; location group is high nibble mov cl,4 ; put in low nibble of AL shr al,cl call tblsrch ; DI = location load table entry mov ax,ldt_start[di] ; AX = base segment of location add ax,fix_para[bx] ; add paragraph offset push es ; absolute paragraph in memory mov es,ax xor ax,ax mov al,fix_offs[bx] ; get offset of fixup location mov di,ax add es:[di],dx ; make the fixup (finally) pop es add bx,fixlen ; do next fixup cmp bx,offset lod_dma + dskrecl ; end of this record ? jne fx_chk inc lod_fixrec ; read another record jmps fx_read ; of fixups tblsrch: ;------- ; Search for group in load table ; entry: AL = group # to match on ; exit: DI = load group entry that matches or ; pop return and exit loader ; BX,DX preserved mov cx,lod_nldt ; # entries in table mov di,offset ldtab srchloop: cmp al,ldt_type[di] je srchdn ; found group's entry add di,ldtlen loop srchloop pop ax jmps fx_err srchdn: ret fx_err: mov cx,e_fixuprec jmp ld_out ; init Base Page ; 1st Data Group has Base Page ; if none then first nonshared ; Code Group (8080 model) init_base: mov lod_8080,0 mov si,offset ldtab mov cx,lod_nldt lb_more:cmp ldt_type[si],2 ! je lb_fnd add si,ldtlen ! loop lb_more mov si,offset ldtab mov cx,lod_nldt lbc_mre: cmp ldt_type[si],1 ! je lb_fnd80 add si,ldtlen ! loop lbc_mre mov cx,e_no_cseg ! jmp ld_out lb_fnd80: mov lod_8080,1 lb_fnd: push es ! mov es,ldt_start[si] mov lod_basep,es sub ax,ax ! mov di,ax mov cx,05bh/2 ! rep stos ax mov al,lod_8080 ! mov es:.5,al mov si,offset ldtab mov cx,lod_nldt lbb_mre:cmp ldt_type[si],0 ! je lbb_nxt mov ax,6 ! mov bl,ldt_type[si] cmp bl,9 ! jne lbb_nsh mov bl,1 lbb_nsh: dec bl ! mul bl ! mov bx,ax ;calculate last byte (3 byte value) ; =(paragraphs*16)-1 push cx ! mov dx,ldt_min[si] push dx ! mov cl,4 ! shl dx,cl push dx ! dec dx ! mov es:[bx],dx pop cx ! pop dx ! push cx mov cl,12 ! shr dx,cl ! pop cx cmp cx,0 ! jne lbb_nzer cmp dx,0 ! je lbb_zer dec dl ! jmps lbb_nzer lbb_zer: mov es:word ptr [bx],0 lbb_nzer: mov es:2[bx],dl ! pop cx ;put starting paragraph in place mov ax,ldt_start[si] ! mov es:3[bx],ax lbb_nxt:add si,ldtlen ! loop lbb_mre ;if 8080 model, copy CS info into DS info cmp lod_8080,1 ! jne lnot80 push ds ! push es ! pop ds ! mov si,0 mov di,6 ! mov cx,3 rep movsw ! pop ds lnot80: mov al,lod_fifty ;initialize base page load disk mov es:.50H,al pop es ; init PD ,UDA and LDSTK mov bx,lod_basep cmp lod_pd,0 ! jne lip_1 jmp lod_exit lip_1: mov si,offset ldtab mov bx,lod_pd ; if 8087 user, flag it cmp lod_ndp, 0 jz lip_2 cmp lod_ndp, 1 jnz true_87 or p_sflag[bx],psf_em87 jmp lip_2 true_87: or p_flag[bx],pf_8087 lip_2: ;if it requires suspend mode, flag it cmp lod_suspnd,0ffh jnz lip_3 or p_sflag[bx],psf_suspend lip_3: mov ax,ldt_start[si] mov p_uda[bx],ax ; remember where lstk,uda are mov lod_uda,ax push es ! mov es,ax ; if 8087 user, use long uda cmp lod_ndp,0 jz shrt_uda cmp lod_ndp,1 jz med_uda add ax,(u8087len/16) ! jmp inter_uda ; full 8087 user, long uda med_uda: add ax,(em87len/16) ! jmp inter_uda ; uses 87 emulator,medium uda shrt_uda: add ax,(ulen/16) ; no 8087 activity,short uda inter_uda: mov lod_lstk,ax ; initialize UDA,LDSTK with zeros xor di,di ! mov ax,di ; if 8087 user, use long uda cmp lod_ndp,0 jz shrt_uda1 ; if 8087 emulator user, use medium uda cmp lod_ndp,1 jnz long_uda1 mov cx,(em87len + lstklen)/2 ! jmp inter_uda1 long_uda1: mov cx,(u8087len + lstklen)/2 ! jmp inter_uda1 shrt_uda1: mov cx,(ulen + lstklen)/2 inter_uda1: rep stos ax ! pop es ; setup p_uda for creat_proc mov ax,sysdat sub p_uda[bx],ax mov p_stat[bx],ps_run mov p_prior[bx],200 ; init load disk/user mov al,lod_user ! mov p_luser[bx],al mov al,lod_disk ! mov p_ldsk[bx],al ; init UDA push es ! mov es,lod_uda mov u_dma_ofst,(offset bpg_dma) mov bx,lod_basep mov u_dma_seg,bx mov ax,lod_lstk cmp lod_ndp,0ffh ; if 8087 user, init control word for jnz not_8087 ; first dispatch's frstor mov u_8087, controlw ; 03ffh = post-init 8087 state push ax mov ax,sysvec87_of mov u_ivec87_of,ax mov ax,sysvec87_sg mov u_ivec87_sg,ax pop ax not_8087: push ds ! mov ds,bx mov u_initds,bx mov u_inites,bx mov u_initss,ax mov ax,bpg_cseg cmp ax,0 ! jne h_cs pop ds ! pop es ! mov cx,e_no_cseg jmp ld_out h_cs: mov u_initcs,ax mov ax,bpg_eseg cmp ax,0 ! je noes mov u_inites,ax noes: mov u_stack_sp,(offset ls_sp) sub dx,dx ! mov al,bpg_8080 cmp al,0 ! je n80m mov dx,0100h n80m: mov ds,u_initss mov ls_offset,dx ;set up initial stack mov ls_flags,0200h ;for a RETF from user mov ls_roffset,offset user_retf ;process, see SUPIF.SUP mov ls_rcseg,cs ;module for USER_RETF: pop ds ! pop es ;code mov bx,lod_basep sub cx,cx lod_exit: push cx ! push bx mov cx,f_qwrite ! mov dx,offset mxloadqpb call osif ! pop bx ! pop cx ! ret lod_group: ;load a group described in ldtab ;---------- ; input: SI = addr of ldtab entry ; output: CX = Error Code ; see if first part already in DMA mov bx,si mov ax,lod_indma ;starting paragraph in dma mov cx,ldt_fstrt[bx] ;AX = starting paragraph in local DMA ;CX = starting paragraph to transfer ;BX -> ldtab entry cmp cx,ax ! jb rd_first ;starts at or after the pp. in dma sub cx,ax cmp cx,8 ! jae rd_first ;starts in the dma mov dx,8 ! sub dx,cx ;CX = # of pp. to skip ;DX = length of remaining buffer cmp dx,ldt_flen[bx] ! jbe xfer mov dx,ldt_flen[bx] xfer: mov si,offset lod_dma mov ax,cx ! mov cl,4 ! shl ax,cl add si,ax ;SI -> beginning of transfer area ; in lod_dma mov ax,dx ! mov cl,3 ! shl ax,cl mov cx,ax ;CX = number of words to transfer xor di,di push es ! mov es,ldt_start[bx] rep movsw ! pop es add ldt_start[bx],dx sub ldt_flen[bx],dx ! add ldt_fstrt[bx],dx rd_first: cmp ldt_flen[bx],0 ! jne rd_1st sub cx,cx ! ret rd_1st: test ldt_fstrt[bx],07h ! jnz rd_indma cmp ldt_flen[bx],8 ! jae xf_d rd_indma: push bx mov ax,ldt_fstrt[bx] shr ax,1 ! shr ax,1 ! shr ax,1 ; Record # mov bx,1 ; read 1 record mov dx,offset lod_dma ; DMA offset mov cx,sysdat ; DMA segment call drd pop bx jcxz rd_agn cmp cx,0ffh ! jne rd_r3 mov cx,0 rd_r3: ret rd_agn: mov ax,ldt_fstrt[bx] and ax,0fff8h ; note starting paragraph mov lod_indma,ax ; in DMA mov si,bx ! jmp lod_group ; We are at a Sector Boundary with at least ; a sector to place into the user area xf_d: push bx sub dx,dx ; DMA offset mov cx,ldt_start[bx] ; DMA segment mov ax,ldt_fstrt[bx] shr ax,1 ! shr ax,1 ! shr ax,1 ; Record # mov bx,ldt_flen[bx] shr bx,1 ! shr bx,1 ! shr bx,1 ; # of records push bx call drd pop ax ! pop bx jcxz xfer_n cmp cx,0ffh ! jne rd_r4 xor cx,cx rd_r4: ret xfer_n: shl ax,1 ! shl ax,1 ! shl ax,1 add ldt_start[bx],ax add ldt_fstrt[bx],ax sub ldt_flen[bx],ax jmp rd_first drd: ; input: AX = Record Number ; BX = Number of Sectors ; CX = dma segment ; DX = dma offset ; output: CX = 0 if okay ; CX = 0FFH if End of File ; else Error Code mov u_dma_ofst,dx mov u_dma_seg,cx ; read BX sectors starting at Record AX drd_lp: push bx ;old # sectors push ax ;old record # cmp bx,128 ! jbe drd_r mov bx,128 ; Max Mulit-sector count is 128 drd_r: mov cl,u_mult_cnt push cx mov u_mult_cnt,bl push bx mov si,offset lod_fcb mov fcb_r0[si],ax mov cx,f_freadrdm ! mov dx,si push es ! call osif ! pop es pop dx ;multi_cnt used pop cx ! mov u_mult_cnt,cl cmp bl,1 ! jbe dr_r2 mov cx,e_bad_read ! mov bx,0ffffh pop ax ! pop ax ! ret dr_r2: mov cl,bl xor bh,bh ! mov di,bx ;save BL for header read check pop ax ! add ax,dx ;adjust record # pop bx ! sub bx,dx ;adjust # sectors shl dx,1 ! shl dx,1 ! shl dx,1 add u_dma_seg,dx ; check for CTRL C. If hit while loading ; last set of characters, this is the place to ; clean things up... push cx ! push ax ! push bx ! push di mov cx,f_ciostat ! call osif pop di ! pop bx ! pop ax ! pop cx ; Now see if CTRL C was hit during the ; the load. mov si,rlr test p_flag[si],pf_ctlc ! jz dr_r1 mov cx,e_abort ! mov bx,0ffffh ret dr_r1: cmp cl,0 ! je dr_r5 mov cx,0ffh ! ret dr_r5: cmp bx,0 ! jne dr_r6 xor cx,cx ret dr_r6: jmp drd_lp ;if mpm get_sh: ;------ ; Allocate memory for shared code. If memory already ; exists then mark LDTAB entry with FLEN=0 for no load. ; START must be non-zero on success. ; ; input: SI = LDTAB Entry for shared code ; output: CX = 0 on success ; = 0ffffh on failure ; SI is unchanged ; ; 1. Look for PD Name on SCL, making sure ; LDSK and LUSER are the same. mov bx,(offset scl)-p_thread gs_nxt: push si mov dx,offset lod_fcb ! add dx,fcb_name mov cx,f_findpdname ! call osif ; BX=pd found or 0ffffh pop si cmp bx,0ffffh ! je no_sh mov al,lod_disk cmp p_ldsk[bx],al ! jne gs_nxt mov al,lod_user cmp p_luser[bx],al ! jne gs_nxt ; 2. if (1.) then Share the Memory. ; 2.1 Set FLEN=0 push bx ! push si call shmem pop si ! pop bx cmp cx,0ffffh ! je no_sh mov ldt_flen[si],0 ; Put SHARE PD on end of SCL ; BX = SHARE PD pushf ! cli mov di,(offset SCL)-p_thread sh_nin1: cmp p_thread[di],bx ! je sh_rm ;look for share PD mov di,p_thread[di] ! jmps sh_nin1 sh_rm: mov ax,p_thread[bx] ;take it off the list mov p_thread[di],ax sh_in: cmp p_thread[di],0 ! je sh_end ;look for the end mov di,p_thread[di] ! jmps sh_in sh_end: mov p_thread[di],bx ;insert share PD on end xor cx,cx mov p_thread[bx],cx popf ! ret ;success ; 3. if (NOT 1.) allocate memory to NEW PD no_sh: ; get new PD pushf ! cli mov bx,pul cmp bx,0 ! je sherr mov ax,p_link[bx] ! mov pul,ax popf ; alloc memory for code segment push bx ! push si mov cx,f_malloc mov dx,si call osif pop si ! pop bx cmp cx,0 ! jne merr ; initialize new PD name ; BX = New PD push si mov si,ldt_pd[si] ;SI=old pd push si mov di,bx add si,p_name ! add di,p_name mov cx,4 push es ! mov ax,ds ! mov es,ax rep movsw pop es ! pop di ! pop si ; DI = old PD, BX=New PD mov al,lod_user ! mov p_luser[bx],al mov al,lod_disk ! mov p_ldsk[bx],al ; share w/new PD mov ax,ldt_start[si] push bx ! push si ! push ds push ax ! push bx ! push di mov ax,ss ! mov ds,ax mov dx,sp ! mov cx,f_share call osif add sp,6 pop ds ! pop si ! pop bx ; put new PD on SCL pushf ! cli mov di,(offset SCL)-p_thread sh_nin: cmp p_thread[di],0 ! je sh_doit mov di,p_thread[di] ! jmps sh_nin sh_doit: mov p_thread[di],bx ;insert new share PD xor cx,cx mov p_thread[bx],cx popf ! ret ;success merr: pushf ! cli mov ax,pul mov p_link[bx],ax mov pul,bx sherr: popf mov cx,0ffffh ! ret shmem: ;----- ;input: SI = LDTAB ; BX = Owner PD ; Load_pd = Requestor ; Have to set LDT_START ; lea di,(p_mem-ms_link)[bx] sm_nxt: mov di,ms_link[di] cmp di,0 ! je sm_no mov ax,ms_flags[di] and ax,mf_share+mf_code+mf_load cmp ax,mf_share+mf_code+mf_load ! jne sm_nxt push si ! push ds push ms_start[di] push ms_start[di] push lod_pd push bx mov ax,ss ! mov ds,ax mov dx,sp ! mov cx,f_share call osif ; This will always work. pop ax ! pop ax ! pop ax pop dx ! pop ds ! pop si mov ldt_start[si],dx ret sm_no: mov cx,0ffffh ! ret