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

📄 biosinit.a86

📁 Dos7.01的源代码
💻 A86
📖 第 1 页 / 共 4 页
字号:
	mov	dx,offset shell		; and the Command Processor
	mov	exec_clseg,ds
	mov	exec_fcb1seg,ds
	mov	exec_fcb2seg,ds
	int	DOS_INT			; Go for it
	mov	ah,MS_C_WRITESTR	; Print an error message and wait for
	mov	dx,offset bad_exec	;  the user to enter new name
	int	DOS_INT
	mov	ah,MS_C_READSTR		; get user to input new COMMAND
	mov	dx,offset shell_ask	;  location
	int	DOS_INT
	call	crlf			; tidy up with CR/LF
	xor	bx,bx
	mov	bl,shell_end
	mov	shell[bx],bh		; replace CR with NULL
	jmps	load_e10

eject
;
;	Initialise the PSP and inform DOS of the
;	location of the BIOSINIT PSP. The MS_P_SETPSP *MUST* be the first 
;	INT21 function call because the PSP Address is used during the
;	entry code except when the INDOS flag is set and certain function 
;	calls are made.
;
;	Then open the Resident character devices so that the dynamically
;	devices can output messages to the screen etc.
; 
config_start:
	mov	cl,4
	mov	bx,ds
	mov	ax,offset psp		; Now force DOS Plus to use the 
	shr	ax,cl			; internal PSP for all disk and
	add	bx,ax			; character I/O
	mov	xftbl_seg,bx		; Update the Handle Table Pointer
	mov	parent_psp,bx		; and make this the root process
	mov	ah,MS_P_SETPSP		; Set the current PSP
	int	DOS_INT
if DOS5
	mov	ax,3306h
	int	21h			; get true version
	mov	dosVersion,bx		; and plant in initial PSP
endif
	call	dos_version_check	; make sure we are on correct DOS

	mov	ax,4458h
	int	DOS_INT			; we need to access local data
	mov	drdos_off,bx		; so save a pointer to it
	mov	drdos_seg,es
	mov	ax,ext_mem_size
	mov	es:DRDOS_EXT_MEM[bx],ax	; save extended memory size in DOS
	mov	ax,5200h
	int	DOS_INT
	mov	func52_off,bx
	mov	func52_seg,es		; save pointer to internal data
if DOS5
	mov	ax,ext_mem_size
	mov	es:F52_EXT_MEM[bx],ax	; save extended memory size in DOS
endif
	mov	ax,(offset TEMP_LDT)/16	; use our temporary LDT's
	add	ax,init_dseg		;  during system init
	mov	es:F52_PATHOFF[bx],0	; point at the LDT's
	mov	es:F52_PATHSEG[bx],ax
	push cs ! pop es

	mov	ah,MS_M_ALLOC		; Allocate all available memory
	mov	bx,0FFFFh		; BX is returned with the maximum
	int	DOS_INT			; available block size

	mov	ah,MS_M_ALLOC		
	int	DOS_INT
	mov	mem_first_base,ax	; Base of 1st allocated block
	mov	mem_current_base,ax	; Base of allocated memory
	mov	mem_current,ax		; Next available Segment

	call	config_finish		; Update DOS with the information
					; obtained from loading the resident
					; drivers.
	mov	ah,MS_DRV_SET		; Select the Default Drive
	mov	dl,init_drv		; passed to us by the BIOS
	int	DOS_INT

	mov	ah,MS_F_DMAOFF		; Initialise the DMA address for 
	mov	dx,offset search_state	; the Search First State data
	int	DOS_INT

	mov	al,init_drv		; get the boot drive then check
	test	init_flags,INIT_COMSPEC	; flags to see if this is the
	 jz	config_s05		; default COMSPEC drive.
	mov	al,comspec_drv

config_s05:
	add	shell,al		; update the drive letter of shell
	add	shell_drv,al		;  and the reload path

	call	open_stdaux		; Open STDAUX as internal handle #0
	call	open_stdcon		; Open Standard CON Devices as #1
	mov	ah,MS_X_CLOSE		; now close AUX again
	mov	bx,STDAUX		; for CONFIG processing
	int	DOS_INT
	ret


;
;	Relocate the DOS CODE from high memory to immediately above
;	the device drivers, buffers etc. Then call the DOS_CLEANUP code
;	so that any self segment pointers maintained in the DOS DATA
;	can be updated. Then free all the unused memory and reopen the
;	standard devices.
;
config_end:
	push	es
	mov	al,last_drv		; get lastdrive value
	les	bx,func52_ptr
	cmp	al,es:F52_PHYDRV[bx]	; less than the # of Physical drives ?
	 ja	config_end10
	mov	al,es:F52_PHYDRV[bx]	; ensure minimum of # physical drives
config_end10:
	mov	es:F52_LASTDRV[bx],al	; set # of drives installed
	mov	cl,4			; we will be converting byte-paras
	mov	ah,LDT_LEN		; we need this many bytes per drive
	mul	ah			; *lastdrive
	add	ax,15			; round LDT's size up to para
	shr	ax,cl
	mov	dl,'L'			; allocate LDT's
	call	alloc_instseg		; Allocate memory AX is destination
	mov	es:F52_PATHOFF[bx],0	; point at the LDT's
	mov	es:F52_PATHSEG[bx],ax	; save seg we just allocated
	pop	es

	call	setup_ldt		; initialise LDT structures

	call	setup_stacks		; allocate stacks

	call	relocate_system		; relocate system as requested

	push	es			; Free all of the unused memory
	mov	es,mem_current_base	; ES: Base Allocated Memory
	mov	bx,mem_current		; Get the currently allocated memory
	sub	bx,mem_current_base	; and subtract mem_current_base to
	mov	ah,MS_M_SETBLOCK	; give the number of paragraphs used
	int	DOS_INT			; and modify block accordingly

; Kludge - if the CONFIG file has had a line of the form INSTALL= to load a TSR
; then that TSR will have inherited the handles, so bumping the open count, but
; the func 31 exit leaves all these files open. As a result we will get the
; wrong internal file numbers unless we force complete closure. So we keep
; trying to close each internal handle until we get an error.

	mov	ah,MS_P_GETPSP
	int	DOS_INT			; get current PSP
	mov	es,bx
	mov	cx,PSP_XFNMAX		; Close all the standard handles
	les	di,PSP_XFTPTR		; and then reopen them in case a
	mov	bx,0			; dynamicly loadable device has
cfg_e10:				; replaced the BIOS driver
	mov	dl,es:[di+bx]		; save old internal handle
	mov	ah,MS_X_CLOSE
	int	DOS_INT			; try and close this handle
	mov	es:[di+bx],dl		; put the internal handle back 
	 jnc	cfg_e10			; and try and close it again
	mov	es:byte ptr [di+bx],0ffh
	inc	bx			; mark as closed and try next handle
	loop	cfg_e10
	pop	es
;;	jmps	open_std	

open_std:
	call	open_stdaux		; open AUX device as STDAUX
	call	open_stdcon		; now STDIN, STDOUT, STDERR
;	jmp	open_stdprn		; finally STDPRN

open_stdprn:
	mov	ax,(MS_X_OPEN * 256) + 1
	mov	dx,offset printer	; Open the PRN device
	int	DOS_INT
	 jc	open_sp10		; No PRN device
	cmp	ax,STDPRN		; If all the previous Opens were
	 jz	open_sp10		; successful then this is STDPRN
	mov	bx,ax			; otherwise force this to STDPRN
	mov	cx,STDPRN
	mov	ah,MS_X_DUP2
	int	DOS_INT
	mov	ah,MS_X_CLOSE
	int	DOS_INT
open_sp10:
	ret

open_stdcon:
	mov	ax,(MS_X_OPEN * 256) + 2
	mov	dx,offset console	; Open the CON device
	int	DOS_INT
	 jc	open_sc10		; No CON device
	mov	bx,ax			; First Open should be STDIN
	mov	cx,STDOUT		; Force Duplicate to STDOUT
	mov	ah,MS_X_DUP2
	int	DOS_INT
	mov	cx,STDERR		; Then Force Duplicate to STDERR
	mov	ah,MS_X_DUP2
	int	DOS_INT
open_sc10:
	ret
	
open_stdaux:
	mov	ax,(MS_X_OPEN * 256) + 2
	mov	dx,offset auxilary	; Open the AUX device
	int	DOS_INT			; to get internal handle 0
	 jc	open_sa10		; No AUX device
	mov	bx,ax			; Force DUP to STDAUX
	mov	cx,STDAUX
	mov	ah,MS_X_DUP2
	int	DOS_INT
	mov	ah,MS_X_CLOSE
	int	DOS_INT
open_sa10:
	ret


eject
relocate_system:
	push ds ! push es
	cmp	dos_target_seg,0FFFFh	; is the OS going high ?
	 jne	relocate_system10
	call	SetupHMA		; make sure HMA chain is established
	xor	cx,cx
	xchg	cx,systemHMA		; free up any space reserved for the OS
	call	FreeHMA
	call	ReserveCommandHMA	; reserve space for COMMAND.COM
relocate_system10:
	call	reloc_bios		; move down relocatable drivers
	call	reloc_dos		; move DOS above drivers if RAM based
	xor	cx,cx
	xchg	cx,commandHMA
	call	FreeHMA			; return command.com HMA space to pool
	cli
	mov	ds,dos_dseg		; DS -> DOS data segment
	callf	cs:dos_init		; (in case of CS relative fixups)
	sti
	pop es ! pop ds
	ret

eject
reloc_dos:				; move DOS down to just above drivers
;----------
	push	ds
	push	es
	test	init_flags,INIT_ROMCODE	; Run the DOS code in ROM
	 jz $+5 ! jmp reloc_dos90	; at CURRENT_DOS - No Code Reloc
	mov	es,current_dos
	mov	cx,es:DOS_CODE		; get DOS code size in bytes
	mov	ax,dos_target_seg	; get DOS target
	cmp	ax,0FFFFh		; it it seg FFFF ?
	 jne	reloc_dos10
	mov	es,current_dos
	mov	dx,es:DOS_OFFSET
	call	AllocHMA		; allocate CX bytes, offset < DX
	 jnc	reloc_dos50		;  if we can use high memory
	xor	ax,ax			; can't, so try auto-allocation
reloc_dos10:
	test	ax,ax			; has a specific address been
	 jnz	reloc_dos40		;  specified ?
	push	cx			; save DOS code size
	xchg	ax,cx
	mov	cl,4
	shr	ax,cl			; convert to paragraphs
	pop	cx
	cmp	hidos,0			; do we want to relocate DOS ?
	 je	reloc_dos20		;  no, allocate conventionally
	call	alloc_upper		;  else allocate space for the DOS
	 jnc	reloc_dos40		;  in upper memory if possible
reloc_dos20:
	mov	es,current_dos		; if conventional memory we
	mov	ax,es:INIT_CODE		;  can discard INIT code
	cmp	history_flg,0		; is history enabled ?
	 jne	reloc_dos30
	mov	ax,es:HISTORY_CODE	; no, discard history code as well
reloc_dos30:
	push	cx
	add	ax,15
	mov	cl,4			; convert to paragraphs
	shr	ax,cl
	pop	cx
	call	alloc_seg_with_padding	; allocate in conventional memory
reloc_dos40:
	xchg	ax,dx			; save segment address
	mov	es,current_dos		; point at code
	mov	ax,es:DOS_OFFSET	; get offset of code start
	xor	di,di
	mov	es,dx			; ES:DI -> destination address
	push	cx			; save DOS size
	mov	cl,4
	shr	ax,cl			; AX = header size in para's
	sub	dx,ax			; adjust DOS segment accordingly
	pop	cx			; CX = DOS size in bytes
reloc_dos50:
; At this point
; CX = # bytes to move
; ES:DI -> destination
; DX = segment to fixup
;
	mov	dos_cseg,dx		; new code segment for DOS
	mov	ds,current_dos		; DS -> DOS code
	xor	si,si
	shr	cx,1			; CX = # of words in DOS
	rep	movsw			; copy DOS down

reloc_dos90:				; fixups performed
	pop	es
	pop	ds
	ret



	Public	HookInt2F

HookInt2F:
;---------
; Hook Int 2F during device driver initialisation so we can intercept
; some broadcasts
; On Entry:
;	None (beware DS/ES can be anything)
; On Exit:
;	None (All regs preserved)
;
	push	es
	push	ax
	push	bx
	les	bx,cs:drdos_ptr
	mov	bx,es:DRDOS_INT2F[bx]	; ES:BX -> Int 2F hooks
	mov	ax,offset Int2FHandler
	xchg	ax,es:4[bx]		; get Int 2F offset
	mov	cs:int2FOff,ax
	mov	ax,cs
	xchg	ax,es:6[bx]		; get Int 2F segment
	mov	cs:int2FSeg,ax
	pop	bx
	pop	ax
	pop	es
	ret

	Public	UnhookInt2F

UnhookInt2F:
;-----------
; Device driver initialisation has finished, so unhook from Int 2F
; On Entry:
;	None (beware DS/ES can be anything)
; On Exit:
;	None (All regs preserved)
;
	push	es
	push	ax
	push	bx
	les	bx,cs:drdos_ptr
	mov	bx,es:DRDOS_INT2F[bx]	; ES:BX -> Int 2F hooks
	mov	ax,cs:int2FOff
	mov	es:4[bx],ax		; restore Int 2F offset
	mov	ax,cs:int2FSeg
	mov	es:6[bx],ax		; restore Int 2F segment
	pop	bx
	pop	ax
	pop	es
	ret


; During device driver init we provide some services on Int 2F
; eg. 12FF for EMM386.SYS and 4A01/4A02 for Windows HIMEM.SYS

Int2FHandler:
;------------
; On Entry:
;	callers DS on stack
; On Exit:
;	if not handled pass on to BIOS, callers DS on stack, all regs preserved
;
	pop	ds			; pop DS from stack
	cmp	ax,4A01h		; Query Free HMA Space ?
	 je	HMAQueryFree
	cmp	ax,4A02h		; Allocate HMA Space ?
	 je	HMAAlloc
	cmp	ax,12FFh		; is it a relocation service ?
	 jne	OldInt2F
	sti				; if we RETF don't leave IF disabled
	cmp	bx,9			; register upper memory link
	 je	DOSUpperMemoryRoot
	cmp	bx,1			; Relocate BDOS
	 jb	DOSQuerySize		; what's the size of DOS
	 je	DOSRelocate		; where to put it
	cmp	bx,3			; Relocate BIOS
	 jb	BIOSQuerySize		; what's the size of BIOS
	 je	BIOSRelocate		; where to put it

OldInt2F:
	push	ds			; DS on stack as expected
		db	JMPF_OPCODE
int2FOff	dw	0
int2FSeg	dw	0


; Enquire DOS size
DOSQuerySize:
;------------
; On Entry:
;	None
; On Exit:
;	AX = 0
;	DX = DOS Size in para's
;
	mov	dx,cs:dosCodeParaSize	; DX = para's required for DOS code
	jmps	RelocExit

; Relocate DOS
DOSRelocate:
;-----------
; On Entry:
;	DX = para to reloacte to (FFFF=HMA)
; On Exit:
;	AX = 0
;
	mov	cs:dos_target_seg,dx	; save where
	jmps	RelocExit


; Enquire BIOS size
BIOSQuerySize:
;-------------
; On Entry:
;	None
; On Exit:
;	AX = 0
;	DX = BIOS Size in para's
;
	mov	dx,cs:rcode_len		; DX = bytes required for BIOS code
	add	dx,15
	mov	cl,4
	shr	dx,cl			; DX para's required
	jmps	RelocExit

; Relocate BIOS
BIOSRelocate:
;------------
; On Entry:
;	DX = para to reloacte to (FFFF=HMA)
; On Exit:
;	AX = 0
;
	mov	cs:bios_target_seg,dx	; save where
;	jmps	RelocExit

RelocExit:
	xor	ax,ax			; indicate success
	retf	2

⌨️ 快捷键说明

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