Files
Digital-Research-Source-Code/MPM OPERATING SYSTEMS/MPM-86/MPM-86 2.0 SOURCES/02/LOAD.SUP
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

438 lines
12 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;*****************************************************
;*
;* 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