⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 biosinit.a86

📁 Dos7.01的源代码
💻 A86
📖 第 1 页 / 共 4 页
字号:
;    File              : $BIOSINIT.A86$
;
;    Description       :
;
;    Original Author   : DIGITAL RESEARCH
;
;    Last Edited By    : $CALDERA$
;
;-----------------------------------------------------------------------;
;    Copyright Work of Caldera, Inc. All Rights Reserved.
;      
;    THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
;    PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
;    ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
;    WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
;    THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
;    HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
;    AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
;    AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
;    COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
;    CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
;    TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
;    CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
;    AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
;    CIVIL LIABILITY.
;-----------------------------------------------------------------------;
;
;    *** Current Edit History ***
;    *** End of Current Edit History ***
;
;    $Log$
;    BIOSINIT.A86 1.43 93/12/03 00:38:19
;    Fix bug in AllocHMA when base not para aligned
;    BIOSINIT.A86 1.42 93/11/29 21:40:03
;    Fill in name field of system DMD's (owner=8) with 'SC'
;    BIOSINIT.A86 1.41 93/11/18 15:43:14 
;    Add primitive multi-master checking
;    BIOSINIT.A86 1.40 93/11/11 12:25:29 
;    VDISK header changes
;    BIOSINIT.A86 1.39 93/11/08 23:19:22 
;    SetupHMA does CALL5 initialisation
;    BIOSINIT.A86 1.38 93/10/29 20:03:48
;    BIOS relocation services restored for possible 3rd party memory manager use
;    BIOSINIT.A86 1.37 93/10/29 19:42:27
;    Change HIDOS default to off
;    BIOSINIT.A86 1.36 93/09/22 15:22:14
;    Change int21/4458 to les bx,cs:drdos_ptr (smaller, faster)
;    BIOSINIT.A86 1.35 93/09/03 20:10:55
;    Support intl YES/NO
;    BIOSINIT.A86 1.34 93/09/02 22:34:42
;    Add header to system allocations
;    BIOSINIT.A86 1.33 93/09/01 17:36:57
;    increase stack size for aspi4dos.sys
;    BIOSINIT.A86 1.31 93/08/06 20:55:16
;    re-arrange device init order for SCREATE.SYS on a VDISK.SYS
;    BIOSINIT.A86 1.28 93/08/02 14:45:43
;    hide preload drives from func_device
;    ENDLOG

	include	i:msdos.equ		; DOS Function Equates
	include	i:psp.def		; PSP Definition
	include i:f52data.def		; Internal DOS data area
	include	i:doshndl.def		; Dummy DOS structures
	include	config.equ
	include	i:fdos.equ
	include	i:modfunc.def

TRUE	   	equ	0FFFFh	      ; value of TRUE
FALSE	   	equ	0	      ; value of FALSE

;
;	Equates for INIT_FLAGS which can be modified by the BIOS
;	the default is a RAM based BDOS (Code and Data) with INIT_DRV
;	specifing the default drive and the initial drive for COMSPEC
;

INIT_ROMCODE	equ	0001h		; Rom based DOS CODE
INIT_COMSPEC	equ	0002h		; COMSPEC_DRV specifies the default
					; Command Processor Drive
INIT_WINDOWS	equ	0004h		; Disable windows support

COMMAND_BASE	equ	000E0h		; must cover FFFF:D0 for CALL5 fixup
COMMAND_SIZE	equ	015C0h

CGROUP	GROUP	CODE, INITCODE, INITDATA, INITPSP, INITENV, DATAEND
CODE	CSEG
eject
;
;	The DOS Code Segment is formatted as follows.
;
DOS_OFFSET	equ	word ptr  .0008h	; Offset of code in segment
HISTORY_CODE	equ	word ptr  .000Ch	; Start of history code
INIT_CODE	equ	word ptr  .000Eh	; Start of initialisation code
DOS_FLAG	equ	word ptr  .001Ch	; Compressed Data Flag
DOS_CODE	equ	word ptr  .001Eh	; DOS Code Length (Bytes)
DOS_DATA	equ	word ptr  .0020h	; DOS Data Length (Bytes)
NO_YES_CHARS	equ	word ptr  .0028h	; DOS Data No/Yes characters

INT31_SEGMENT	equ	word ptr .00C6h		; DOS Data Segment pointer
						; for ROM systems
JMPF_OPCODE	equ	0EAh			; 8086 JMPF instruction

INITCODE	CSEG	PARA 'INITCODE'
	extrn	cleanup:near			; BIOS Clean Up routine
	extrn	config_init:near		; CONFIG Code Init
	extrn	config_finish:near		; Update DOS with Device Info
	extrn	config:near			; CONFIG.SYS Processor
	extrn	crlf:near			; Output CR/LF to screen
	extrn	resident_device_init:near	; Device Driver Init
	extrn	read_dos:near			; load DOS file
	extrn	setup_ldt:near
	extrn	setup_stacks:near
	extrn	dos_version_check:near

		db	'Copyright (c) 1983,1996 '
		db	'Caldera, Inc. All Rights Reserved '
		db	'XXXX-0000-987654321X'


	Public	biosinit
;========
biosinit:
;========
;	entry:	MEM_SIZE    = memory size in paragraphs
;		DEVICE_ROOT = address of 1st resident device driver
;		INIT_DRV    = boot drive (0 = A:, 1 = B:, etc.)
;		INIT_BUF    = minimum # of disk buffers
;		CURRENT_DOS = code segment of DOS (if loaded)
;		INIT_FLAGS  = Control Flags
;		COMSPEC_DRV = Drive for Command Processor
;	
;
; we set up the following variables
;		BIOS_SEG    = low memory BIOS code/data (static)
;		DOS_DSEG    = low memory DOS data area (static)
;		RCODE_SEG   = relocated BIOS code segment
;		DOS_CSEG    = relocated DOS code segment
;		INIT_DSEG   = segment based initialisation data
;
	cld
	cli
	mov	ax,cs			; Initialise our stack and Data Segment
	mov	ds,ax
	mov	ss,ax
	mov	sp,offset stack
	sti

	mov	bios_seg,ax		; Save the BIOS Segment

; Now some code which allows Remote Program Loader to reserve some memory
; which will be safe from being trampled on by the system.
; The RPL takes over Int 2F and has a magic signature "RPL" at offset 3 from
; it's entry point. If this is detected an Int2f is issued
;
; On Entry:
;	AX = 4A06, DX = Segment address of top of memory
; On Exit:
;	DX = segment address of the RPL
;
; On return the system will build a DMD entry for the RPL, with an owner field
; of 8 (ie. System). The RPL can poke this entry to 0 when it wishes to free
; the memory.
;
; In addition we now look for "RPLOADER", and if found we remember the address
; of the entry point so we can call it with status information

	mov	dx,mem_size		; get existing size
	dec	dx			; one para less for upper mem DMD link
	xor	ax,ax
	mov	es,ax			; point to vectors
	mov	bx,4*2fh		; we want Int 2F vector
	les	bx,es:dword ptr [bx]	; pick up the contents
	lea	di,3[bx]		; point to magic signature "RPL"
	mov	si,offset rpl_name
	mov	cx,3
	repe	cmpsb			; does the signature match ?
	 jne	biosinit20
	mov	cx,5			; look also for "RPLOADER"
	repe	cmpsb
	 jne	biosinit10
	mov	rpl_off,bx		; save entry point for use later
	mov	rpl_seg,es
biosinit10:
	mov	ax,4a06h		; magic number for RPL
	int	2fh			; does anyone want to steal memory ?
	inc	dx
	cmp	dx,mem_size		; is memory size unchanged ?
	 jnb	biosinit20
	dec	dx			; point back at start of memory
	dec	dx			;  then one below for DMD start
	mov	es,dx			; ES points to DMD
	mov	DMD_ID,IDZ		; make it last in the chain
	mov	DMD_PSP,8		; owned by system
	lea	di,DMD_NAME		; point to name field
	mov	si,offset rpl_name
	mov	cx,(length rpl_name)/2
	rep	movsw			; initialise name field too
	inc	dx			; skip the DMD for real top
	xchg	dx,mem_size		; replace memory size with new value
	sub	dx,mem_size		; whats the difference ?
	mov	DMD_LEN,dx		; save it's this length
biosinit20:

; End of RPL support
	mov	ax,mem_size		; get top of memory
	sub	ax,MOVE_DOWN
	mov	mem_max,ax		; last available paragraph

	mov	init_dseg,ax		; initialisation data lives here
	mov	cl,4
	mov	dx,offset DYNAMIC_DATA_END+15
	shr	dx,cl			; we need this much dynamic data
	add	ax,dx

; Now we try to relocate the BIOS
	mov	dx,rcode_len		; we want to keep this much BIOS code
	add	systemSize,dx		;  so add to reserved space in HMA
	mov	dx,icode_len		; how much do we want to move ?
	shr	dx,cl
	 jz	biosinit30		; if ROMed we have nothing to relocate
	mov	rcode_seg,ax		; relocated BIOS lives here
	add	ax,dx			; remember how much we allocated
	mov	dx,rcode_offset
	mov	si,dx
	mov	di,dx
	shr	dx,cl			; DX = para offset of data
	sub	rcode_seg,dx		; adjust our segment value
	mov	es,rcode_seg
	mov	cx,icode_len
	rep	movsb			; copy it up
biosinit30:
	mov	dos_cseg,ax		; a relocated DOS image will live here

	mov	ax,offset biosinit_end+32
	mov	cl,4			; Leave the Last Paragraph Free for
    shr ax,cl           ;  himem DMD 
	neg	ax			; Calculate the destination
	add	ax,mem_size		; Segment for the BIOS relocation

	mov	cx,offset biosinit_end	; Relocate the BIOSINIT code to 
	mov	si,offset biosinit	; the top of available memory
	mov	di,si
	sub	cx,si			; Size of BIOSINIT
	mov	es,ax			; Initialize ES and copy CX words
	rep	movsb

	push	es			; fiddle RETF to relocated code
	mov	ax,offset relocated_init
	push	ax
	retf
;
;	Generic BIOS INIT Patch area
;
	include	i:patch.cod
;
;	BIOSINIT CODE and DATA have now been relocated to high memory
;
relocated_init:
	mov	ax,cs
	cli
	mov	ss,ax
	mov	sp,offset stack
	sti
	mov	ds,ax			; All Segment registers now point
	mov	es,ax			; to the relocated BIOSINIT


	call	config_init		; initialize setup module
	call	dd_fixup		; fixup relocatable device drivers
	les	di,device_root		; initialize all the resident
	call	resident_device_init	;   device drivers
	push cs ! pop es

	mov	dx,1			; phase one of RPL initialisation
	call	rploader		;  inform RPLoader if present
	call	Verify386		; CY set if not a 386
	mov	ax,mem_current		; get ending address returned by BIOS
	 jc	dont_align
	cmp	ax,0100h
	 jae	dont_align		; lets be 4 KByte aligned to benefit
	mov	ax,0100h		;  the multi tasker (386 or above)
dont_align:
	mov	free_seg,ax		;  and save as first Free Segment
	cmp	current_dos,0		; does the OEM want us to read
	 jnz	dos_reloc		;   the DOS file from disk?
	mov	ax,dos_cseg
	mov	current_dos,ax		; the file is held on the INIT_DRV with
	call	read_dos		;   the name specified in DOS_NAME

eject
;
;	The following code will relocate the DOS code.
;
dos_reloc:
;
; We now move the DOS data to low memory
;
	mov	ax,current_dos
	mov	dos_cseg,ax		; Update the DOS Code Segment
	mov	ds,ax

	mov	cl,4

	mov	ax,ds:DOS_CODE		; get size of DOS code
	add	cs:systemSize,ax	;  and add to the system size
	shr	ax,cl			; convert to para's
	mov	cs:dosCodeParaSize,ax	; save for EMM386.SYS
	
	mov	ax,ds:DOS_OFFSET	; remember we have padding
	add	cs:dos_coff,ax		;  and adjust DOS init offset
	shr	ax,cl			; also adjust DOS segment
	sub	cs:dos_cseg,ax		;  to account for padding

	xor	ax,ax
	mov	es,ax			; ES -> interrupt vectors
	mov	ax,ds:DOS_DATA		; get # of bytes of DOS data
	shr	ax,cl			; get para size of DOS data
	xchg	ax,cs:free_seg		; get seg for DOS data
	add	cs:free_seg,ax		; remember how much we used
	mov	es:INT31_SEGMENT,ax	; update the segment value of INT31
	mov	es,ax			;  so ROMMED systems can find PCM_DSEG
	mov	cs:dos_dseg,ax		; we need to remember where too...

	mov	si,ds:DOS_CODE		; offset of DOS Data
	xor	di,di			; destination offset

	test	DOS_FLAG,1		; has the DOS Data been compressed
	 jnz	dos_r20			; yes so call the decompress routine
	mov	cx,ds:DOS_DATA		;  otherwise just copy the data.
	rep	movsb
	jmps	dos_r40

;
;	This routine will decompress the DOS data area which has 
;	been compressed after linking using Andy Wightmans data 
;	compression algorithm.
;
dos_r20:
	lodsw				; get control word
	mov	cx,ax			; as a count
	 jcxz	dos_r40			; all done
	test	cx,8000h		; negative ?
	 jnz	dos_r30			; yes do zeros
	rep	movsb			; else move in data bytes
	jmps	dos_r20			; and to the next

dos_r30:
	and	cx,7fffh		; remove sign
	 jcxz	dos_r20			; none to do
	xor	ax,ax
	rep	stosb			; fill with zeros
	jmps	dos_r20

dos_r40:
	push cs ! pop ds
	push cs ! pop es

	mov	cl,4			; reserve space for resident DDSC's
	mov	ax,DDSC_LEN
	mul	dev_count		; AX byte are required
	add	ax,15
	shr	ax,cl			; AX para are required
	xchg	ax,free_seg
	add	free_seg,ax		; we have allocated the space
	mov	res_ddsc_seg,ax		; point res_ddsc_ptr at the space
	mov	dx,dos_dseg
	sub	ax,dx			; DOS resident DDSC_'s use DOS data seg
	cmp	ax,1000h		; surely we must fit ?
	 jae	dos_r50
	shl	ax,cl			; offset within pcmode data segment
	mov	res_ddsc_off,ax
	mov	res_ddsc_seg,dx		; setup pointer to resident DDSC's
dos_r50:

;
;	Call the DOS INIT Code passing all the information setup
;	by the BIOS.
;
	mov	ax,mem_size		; pass the Memory Size, the first free
	mov	bx,free_seg		;  segment and the initial 
	mov	dl,init_drv		;  drive to the DOS init routine
	cli
	mov	ds,dos_dseg		; DS -> DOS data segment
	callf	cs:dos_init

	mov	es,cs:dos_dseg
	mov	bx,26h			; ES:BX -> list of lists
	mov	ax,es:word ptr F52_FCBPTR[bx]
    shr ax,1 ! shr ax,1     
    shr ax,1 ! shr ax,1     
	and	es:word ptr F52_FCBPTR[bx],15
	add	es:word ptr F52_FCBPTR+2[bx],ax
	sti
	push cs ! pop ds
	mov	es,current_dos		; internationalise the yes/no chars
	mov	di,es:NO_YES_CHARS
	mov	es,dos_dseg		; ES:DI -> internal table
	mov	ax,word ptr no_char
	stosw				; replace default no chars
	mov	ax,word ptr yes_char
	stosw				; replace default yes chars
	push cs ! pop es
	add	dos_coff,3		; next dos_init call just fixes up
					;  segment relocations

	mov	dx,2			; phase two of RPL initialisation
	call	rploader		;  inform RPLoader if present

	call	config_start		; get free memory
	call	config			; read and process CONFIG.SYS
	call	config_end		; relocate DOS code and free memory

	mov	ax,(MS_X_OPEN*256)+2	; Open for Write
	mov	dx,offset idle_dev	; Get the IDLE Device Name#
	int	DOS_INT			; Open the device
	 jc	dos_r70			; Quit on Error
	push	ax			; Save the Handle
	mov	ax,4458h		; Get the address of the IDLE data
	int	DOS_INT			; area in ES:AX
	pop	bx			; Restore the Handle
	mov	idle_off,ax		; Save the data area offset and 
	mov	idle_seg,es		; segment
	mov	ax,4403h
	mov	dx,offset idle_off
	mov	cx,DWORD
	int	DOS_INT
	mov	ah,MS_X_CLOSE
	int	DOS_INT

dos_r70:
	call	mark_system_memory	; ensure any memory we have allocated
					; is marked as system
	mov	bios_offset,offset cleanup
	callf	bios			; execute BIOS cleanup code

	mov	ax,(MS_M_STRATEGY*256)+3
	xor	bx,bx			; unlink in upper memory region
	int	21h

	mov	dx,3			; phase three of RPL initialisation
	call	rploader		;  inform RPLoader if present

	mov	ax,12ffh		; magic cleanup call to MemMAX
	mov	bx,5			;  to do any tidy ups it wishes
	xor	cx,cx
	xor	dx,dx
	int	2fh

	push cs ! pop es
load_e10:
	mov	ax,(MS_X_EXEC * 256)+0	; Exec the Command Processor
	mov	bx,offset exec_env	; Get the Parameter Block Address

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -