;***************************************************** ;* ;* Program Load ;* ;***************************************************** ;=========== cload_entry: ; entry point to load for a chain command ;=========== ; Assumes UDA is set in passed PD. push bx ! mov bx,1 jmps load ;========== load_entry: ; 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 mpmif mov load_chain,false pop load_pd ! pop load_fcb cmp load_pd,1 ! jne ld_read pop load_pd ! mov load_chain,true ; Read the Header ld_read: mov bx,load_fcb mov fcb_nxtrec[bx],0 ;read 1st record mov dx,offset load_dma mov cx,sysdat call diskread ! jcxz have_header jmp load_exit have_header: mov load_indma,0 ; 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 load_nldtabents,0 mov si,offset ldtab cmp load_pd,0 ! jne form_uda jmp get_ch_info form_uda: mov ldtab_min[si],(lstklen+ulen)/16 ;min=max=UDA+STK paragraphs mov ldtab_max[si],(lstklen+ulen)/16 mov ax,load_pd ! mov ldtab_pd[si],ax mov ldtab_attrib[si],mf_load add si,ldtablen inc load_nldtabents cmp load_chain,true ! jne get_ch_info ;free any memory obtained by process ;except uda,ldstack segment push si mov bx,load_pd ! mov ax,p_uda[bx] mov bx,rlr ! mov bx,p_mem[bx] ld_fnext: cmp bx,0 ! je ld_freeit cmp ms_start[bx],ax ! je ld_freenxt and ms_flags[bx],not mf_load ld_freenxt: mov bx,ms_link[bx] ! jmps ld_fnext ld_freeit: push ax ! mov cl,0ffh ! push cx push cx ! push cx mov dx,sp ! mov cx,ss ! mov ds,cx mov cx,f_freemem ! call mpmif pop cx ! pop cx ! pop cx mov ds,sysdat ! pop ax ; free load memory except uda,ldstack mov bx,offset ldtab ! mov ldtab_start[bx],ax sub cx,cx ! push cx add ax,(lstklen+ulen)/16 ! push ax mov dx,sp ! mov ax,ss ! mov ds,ax mov cx,f_memfree ! call mpmif pop ax ! pop ax mov ds,sysdat ;transfer memory to new pd mov bx,rlr mov ax,p_mem[bx] ! mov p_mem[bx],0 mov bx,load_pd ! mov p_mem[bx],ax pop si get_ch_info: ;go through CMD header and init ;a ldtab entry per header entry. ;alloc abs mem mov cx,ch_entmax ! mov bx,offset load_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 ldtab_type[si],al ;type of seg mov ax,ch_length[bx] ! mov ldtab_flen[si],ax ;length mov ldtab_fstrt[si],dx ! add dx,ax ;pos in file mov ax,ch_base[bx] ! mov ldtab_start[si],ax ;abs seg mov ax,ch_min[bx] ! mov ldtab_min[si],ax ;min needed mov ax,ch_max[bx] cmp ax,0 ! jne setmax mov ax,ch_min[bx] setmax: mov ldtab_max[si],ax ;max wanted mov ax,load_pd ! mov ldtab_pd[si],ax ;pd to alloc to cmp ax,0 ! je not_load mov ax,mf_load jmps not_load skipjmp:jmps ch_more not_load: cmp ch_form[bx],1 ! jne try_shared add ax,mf_code ! jmps set_attrib try_shared: cmp ch_form[bx],9 ! jne set_attrib add ax,mf_code+mf_share set_attrib: mov ldtab_attrib[si],ax ;memory flags ;if abs, allocate memory cmp ldtab_start[si],0 ! je ch_notabs ;see if abs mem jmps ch_alloc ch_notabs: cmp ldtab_type[si],9 ! jne ch_nxt ;see if shared code ch_alloc: push bx ! push dx ! push cx ! push si mov cx,f_malloc ! mov dx,si call mpmif ! pop si mov ax,ldtab_start[si] ! mov ldtab_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 load_giveup ch_nxt: add si,ldtablen inc load_nldtabents 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,load_nldtabents mov load_nrelsegs,0 lt_more:cmp ldtab_min[bx],0 ! je lt_next cmp ldtab_start[bx],0 ! jne lt_next mov ax,ldtab_min[bx] ! add ldtab_min[si],ax mov ax,ldtab_max[bx] ! add ldtab_max[si],ax inc load_nrelsegs lt_next:add bx,ldtablen ! loop lt_more ;malloc mov ax,ldtab_max[si] ! mov load_maxwanted,ax mov ax,ldtab_min[si] ! mov load_minwanted,ax cmp load_pd,0 ! je noloadf mov ldtab_attrib[si],mf_load noloadf:mov ax,load_pd ! mov ldtab_pd[si],ax push si ! mov dx,si ! mov cx,f_malloc call mpmif ! pop si mov ax,ldtab_start[si] ! mov ldtab_id[si],ax cmp bx,0ffffh ! jne lt_spread ;Not Enough Memory - release any ; memory already allocated load_giveup:push cx mov bx,offset ldtab mov cx,load_nldtabents ! inc cx lg_more: cmp ldtab_id[bx],0 ! je lg_next push cx ! push bx ! push ds ;push MFPB on stack push ldtab_pd[bx] push ldtab_id[bx] mov dx,sp ! push ss ! pop ds mov cx,f_memfree call mpmif pop cx ! pop cx pop ds ! pop bx ! pop cx lg_next: add bx,ldtablen ! loop lg_more mov bx,0ffffh ! pop cx ! jmp load_exit lt_spread: ;spread the memory allocated ;amongst the nrelsegs ls_spread1: ;1st give everyone the minimum mov bx,offset ldtab mov cx,load_nldtabents ls_more:cmp ldtab_start[bx],0 ! jne ls_next mov ax,ldtab_min[bx] sub ldtab_min[si],ax cmp ax,ldtab_max[bx] ! jne ls_next mov dx,ldtab_start[si] ! mov ldtab_start[bx],dx add ldtab_start[si],ax dec load_nrelsegs ls_next:add bx,ldtablen ! loop ls_more ;spread whats left amongst those that need more mov bx,offset ldtab mov cx,load_nldtabents lsl_mre:cmp ldtab_start[bx],0 ! jne lsl_nxt mov ax,ldtab_start[si] ! mov ldtab_start[bx],ax mov ax,ldtab_min[si] cmp ax,0 ! je adj_start push cx ! sub cx,cx mov dx,cx ! mov cl,load_nrelsegs div cx ! pop cx cmp dx,0 ! je evendiv inc ax evendiv: mov dx,ldtab_max[bx] ! sub dx,ldtab_min[bx] cmp ax,dx ! jbe nottoomuch mov ax,dx nottoomuch: add ldtab_min[bx],ax ! sub ldtab_min[si],ax adj_start: mov ax,ldtab_min[bx] ! add ldtab_start[si],ax dec load_nrelsegs lsl_nxt:add bx,ldtablen ! loop lsl_mre ; fill memory from file mov si,offset ldtab mov cx,load_nldtabents lf_mre: cmp ldtab_flen[si],0 ! je lf_nxt push cx ! push ldtab_start[si] ! push si call load_group pop si ! pop ldtab_start[si] cmp cx,0 ! pop cx je lf_nxt jmp load_giveup lf_nxt: add si,ldtablen ! loop lf_mre ; init Base Page ; 1st Data Group has Base Page ; if none then first nonshared ; Code Group (8080 model) mov load_8080,0 mov si,offset ldtab mov cx,load_nldtabents lb_more:cmp ldtab_type[si],2 ! je lb_found add si,ldtablen ! loop lb_more mov si,offset ldtab mov cx,load_nldtabents lbc_mre: cmp ldtab_type[si],1 ! je lb_found8080 add si,ldtablen ! loop lbc_mre mov cx,e_no_cseg ! jmp load_giveup lb_found8080: mov load_8080,1 lb_found: push es ! mov es,ldtab_start[si] mov load_basep,es sub ax,ax ! mov di,ax mov cx,05bh/2 ! rep stos ax mov al,load_8080 ! mov es:.5,al mov si,offset ldtab mov cx,load_nldtabents lbb_mre:cmp ldtab_type[si],0 ! je lbb_nxt mov ax,6 ! mov bl,ldtab_type[si] dec bl ! mul bl ! mov bx,ax mov dx,ldtab_min[si] ! push dx mov cl,12 ! shr dx,cl ! mov es:2[bx],dl pop dx ! mov cl,4 ! shl dx,cl dec dx ! mov es:[bx],dx mov ax,ldtab_start[si] ! mov es:3[bx],ax lbb_nxt:add si,ldtablen ! loop lbb_mre ;if 8080 model, copy CS info into DS info cmp load_8080,1 ! jne lnot8080 push ds ! push es ! pop ds ! mov si,0 mov di,6 ! mov cx,3 rep movsw ! pop ds lnot8080: pop es ; init PD ,UDA and LDSTK mov bx,load_basep cmp load_pd,0 ! jne lip_1 jmp load_exit lip_1: mov si,offset ldtab mov bx,load_pd mov ax,ldtab_start[si] mov p_uda[bx],ax ; remember where lstk,uda are mov load_uda,ax push es ! mov es,ax add ax,(ulen/16) ! mov load_lstk,ax ; initialize UDA,LDSTK with zeros sub di,di ! mov ax,di mov cx,(ulen + lstklen)/2 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,p_user[bx] ! mov p_luser[bx],al mov al,p_dsk[bx] ! mov p_ldsk[bx],al push es ! mov es,u_wrkseg mov di,load_fcb cmp es:byte ptr [di],0 ! je ldisk_set mov al,es:[di] ! mov p_ldsk[bx],al ldisk_set: pop es ; init UDA push es ! mov es,load_uda mov u_dma_ofst,(offset bpg_dma) mov bx,load_basep mov u_dma_seg,bx mov ax,load_lstk 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 have_cs pop ds ! pop es ! mov cx,e_no_cseg jmp load_giveup have_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 not8080mod mov dx,0100h not8080mod: mov ds,u_initss mov ls_offset,dx mov ls_flags,0200h mov ls_roffset,offset user_retf mov ls_rcseg,cs pop ds ! pop es mov bx,load_basep sub cx,cx load_exit: push cx ! push bx mov cx,f_qwrite ! mov dx,offset mxloadqpb call mpmif ! pop bx ! pop cx ! ret load_giveup1: jmp load_giveup load_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,load_indma mov cx,ldtab_fstrt[bx] ;CX = starting paragraph to transfer ;BX -> ldtab entry cmp cx,load_indma ! jb read_first ;starts at or after the pp. in dma sub cx,load_indma cmp cx,8 ! jae read_first ;starts in the dma mov dx,8 ! sub dx,cx ;CX = # of pp. to skip ;DX = length of remaining buffer cmp dx,ldtab_flen[bx] ! jbe transfer mov dx,ldtab_flen[bx] transfer: mov si,offset load_dma mov ax,cx ! mov cl,4 ! shl ax,cl add si,ax ;SI -> beginning of transfer area ; in load_dma mov ax,dx ! mov cl,3 ! shl ax,cl mov cx,ax ;CX = number of words to transfer sub di,di push es ! mov es,ldtab_start[bx] rep movsw ! pop es add ldtab_start[bx],dx sub ldtab_flen[bx],dx ! add ldtab_fstrt[bx],dx read_first: cmp ldtab_flen[bx],0 ! jne read_1st sub cx,cx ! ret read_1st: cmp ldtab_flen[bx],8 ! jae xfer_direct push bx ! mov dx,offset load_dma mov cx,sysdat call diskread ! pop bx jcxz read_again ret read_again: mov ax,ldtab_fstrt[bx] mov load_indma,ax mov si,bx ! jmp load_group xfer_direct: push bx ! sub dx,dx mov cx,ldtab_start[bx] call diskread ! pop bx jcxz xfer_1 ret xfer_1: add ldtab_start[bx],8 add ldtab_fstrt[bx],8 sub ldtab_flen[bx],8 jmp read_first diskread: ; input: DX = dma offset ; CX = dma segment push es ! xchg dx,cx ! push cx mov cx,f_setdmab ! call mpmif pop dx ! mov cx,f_setdma call mpmif ! pop es mov cx,f_freadseq ! mov dx,load_fcb push ds ! mov ds,u_wrkseg push es ! call mpmif ! pop es ! pop ds sub cx,cx cmp bl,0ffh ! jne dr_ret mov cx,e_bad_read ! mov bx,0ffffh ! ret dr_ret: mov bx,rlr test p_flag[bx],pf_ctlc ! jz dr_r1 mov cx,e_abort ! mov bx,0ffffh dr_r1: ret