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

📄 biosinit.a86

📁 Dos7.01的源代码
💻 A86
📖 第 1 页 / 共 4 页
字号:


DOSUpperMemoryRoot:
;------------------
	les	bx,cs:drdos_ptr
	mov	es:DRDOS_DMD_UPPER[bx],dx	; remember upper memory link
if DOS5
	les	bx,cs:func52_ptr
	mov	es:F52_DMD_UPPER[bx],dx		; remember upper memory link
endif
	xor	ax,ax
	retf	2

HMAAlloc:
;--------
; On Entry:
;	BX = # bytes to allocate
; On Exit:
;	ES:DI -> start of allocated block
;	BX trashed
;
	push	ds
	push	ax
	push	cx
	push	dx
	push	si
	push	bp
	push cs ! pop ds		; establish data seg
	mov	cx,bx			; CX = bytes wanted
	mov	dx,0FFFFh		; anywhere is OK
	call	AllocHMA		; ES:DI -> allocated data
	pop	bp
	pop	si
	pop	dx
	pop	cx
	pop	ax
	pop	ds
	iret


HMAQueryFree:
;------------
; On Entry:
;	None
; On Exit:
;	BX = Size of block remaining (0 if no HMA)
;	ES:DI -> start of available HMA (FFFF:FFFF if no HMA)
;
	push	ds
	push	ax
	push	cx
	push	dx
	push	si
	push	bp
	push cs ! pop ds		; establish data seg
	call	SetupHMA		; allocate the HMA for OS use
	les	bx,cs:drdos_ptr
	mov	di,es:DRDOS_HIMEM_ROOT[bx]
	mov	ax,0FFFFh		; get offset of HMA entry
	mov	es,ax
	test	di,di			; do we have a himem root ?
	 jz	HMAQueryFree10		; no, return failure
	mov	bx,es:2[di]		; BX = size of region
	mov	ax,di			; para align the base
	add	ax,15			; because the allocation will
	and	ax,not 15
	sub	ax,di			; AX bytes left in the para
	add	di,ax			; bias the starting location
	sub	bx,ax			; that many less available
	 ja	HMAQueryFree20		; if non-zero, return it
HMAQueryFree10:
	xor	bx,bx			; BX = zero on failure
	mov	di,0FFFFh		; ES:DI -> FFFF:FFFF
HMAQueryFree20:
	pop	bp
	pop	si
	pop	dx
	pop	cx
	pop	ax
	pop	ds
	iret


	Public	AllocHMA

AllocHMA:
;--------
; On Entry:
;	CX = bytes to allocate
;	DX = offset of allocation
; On Exit:
;	CY set if no can do and ES:DI = FFFF:FFFF
; else
;	ES:DI -> memory allocated (para aligned)
;	CX preserved
;	DX = segment to fixup
;
	les	bx,cs:drdos_ptr
	mov	di,es:DRDOS_HIMEM_ROOT[bx]
	test	di,di			; have we a HIMEM chain ?
	 jz	AllocHMA20
	cmp	di,dx			;  low enough for us
	 ja	AllocHMA20
	mov	ax,0FFFFh		; relocate to magic segment	
	mov	es,ax			; lets examine high memory
	mov	ax,es:2[di]		; get size of himem entry
	mov	si,es:[di]		;  and get himem link
	mov	bx,di
	add	bx,15
	and	bx,not 15		; BX is now para aligned
	sub	bx,di			; BX is bytes left in para
	sub	ax,bx			; so we only have this much
	 jc	AllocHMA20		;  less than a para ?
	add	di,15			; para align the base, dropping
	and	di,not 15		;  non-aligned bit on floor
	cmp	ax,cx			; is himem entry big enough ?
	 jb	AllocHMA20		; no, allocate from 1st MByte
	 je	AllocHMA10		; just made it!
	sub	ax,cx			; how much is left
	cmp	ax,2*WORD		; is it to small to keep ?
	 jb	AllocHMA10		; no, discard the remainder
	mov	bx,di			; point to new entry
	add	bx,cx			;  this many byte up
	mov	es:[bx],si		; fill in link field
	mov	es:2[bx],ax		;  and length
	mov	si,bx			; make this new root
AllocHMA10:
	push	cx			; save length of CODE
	push	dx			;  and offset of CODE
	les	bx,cs:drdos_ptr
	mov	es:DRDOS_HIMEM_ROOT[bx],si
	pop	ax			; AX = offset of CODE
	mov	cl,4
	shr	ax,cl			; make it paras
	mov	dx,0ffffh
	mov	es,dx			; ES:DI -> destination of CODE
	mov	dx,di
	mov	cl,4
	shr	dx,cl			; DX = offset from FFFF in para's
	dec	dx			; DX = offset from 10000
	sub	dx,ax			; DX = fixup segment
	pop	cx			; CX = bytes to move
	clc				; made it!
	ret

AllocHMA20:
	mov	di,0FFFFh		; set ES:DI = FFFF:FFFF
	mov	es,di
	stc				; can't do it
	ret

	Public	SetupHMA

SetupHMA:
;--------
; We have a client for the high memory area at segment FFFF
; We should try and setup a high memory free chain
; XMS only supports allocation of the complete area, so try and grab
;  it all and do our own sub-allocations within it.
;
	push	es
	les	bx,cs:drdos_ptr
	cmp	es:DRDOS_HIMEM_ROOT[bx],0; do we already have a chain ?
	 jnz	SetupHMA10		;  if so skip XMS allocation
	mov	ax,4300h		; check for XMS installation
	int	2fh
	cmp	al,80h
	 jne	SetupHMA20
	mov	ax,4310h		; get address of XMS driver
	int	2fh
	mov	word ptr xms_driver,bx
	mov	word ptr xms_driver+2,es
	mov	ah,0			; version number check
	callf	xms_driver
	cmp	dx,1			; does HiMem exist ?
	 jne	SetupHMA20
	mov	ah,1			; allocate whole HiMem
	mov	dx,0ffffh
	callf	xms_driver
	cmp	ax,1			; did we succeed ?
	 jne	SetupHMA20
	mov	ah,3			; enable a20 gate
	callf	xms_driver
	cmp	ax,1			; did we succeed ?
	 jne	SetupHMA20
	les	bx,cs:drdos_ptr
	mov	es:DRDOS_HIMEM_ROOT[bx],COMMAND_BASE
	mov	ax,0FFFFh		; one entry of FFF0 bytes covers
	mov	es,ax			;  the complete HMA
	inc	ax
	mov	es:word ptr .COMMAND_BASE,ax
	mov	es:word ptr .COMMAND_BASE+2,-COMMAND_BASE
	mov	di,10h			; copy a dummy VDISK header
	mov	si,offset dummyVDISK
	mov	cx,10h
	rep	movsw			; copy up 0x20 bytes
	push	ds			; now fixup JMPF in hi-memory for CALL5
	mov	ds,ax			;  link for PC-NFS
	mov	si,4*30h		; DS:SI -> Int 30 vector
	lea	di,10h[si]		; ES:DI -> himem alias
	movsw ! movsw ! movsb		; copy the JMPF
	pop	ds
SetupHMA10:
	les	bx,cs:drdos_ptr		; private data area in ES:BX
	mov	dx,COMMAND_BASE
	cmp	dx,es:DRDOS_HIMEM_ROOT[bx]
	 jne	SetupHMA20		; should we be reserving space for OS?
	mov	cx,systemSize		; we should reserve this much
	call	ReserveHMA		;  for the OS in the HMA
	 jc	SetupHMA20
	mov	systemHMA,ax		; save for re-use
SetupHMA20:
	pop	es
	ret


	Public	alloc_instseg

alloc_instseg:
; allocate AX paragraphs for data that will have to be instanced during
; multitasking. if Vladivar kernel available ask that, or else just
; try for normal upper memory
	push	ax
	push	bx			; save registers
	push	cx
	mov	cx,F_Version		; is the multi-tasker loaded ?
	mov	ax,OS386_FUNC
	int	OS386_INT
	int	2Fh			; check for Vladivar
	test	cx,cx			; CX=0 if it's there
	pop	cx
	pop	bx
	pop	ax
	 jnz	alloc_hiseg		; no, allocate normally
	push	ax
	push	bx
	push	cx
	push	dx
	mov	dx,ax			; DX = paragraphs required
	mov	cx,F_RealAllocI		; ask nicely for memory
	mov	ax,OS386_FUNC
	int	OS386_INT
	pop	dx
	pop	cx
	pop	bx
	 jc	alloc_intseg10		; did we get any ?
	add	sp,WORD
	clc				; we've done it !!
	ret	

alloc_intseg10:
	pop	ax			; we didn't manage it...
;	jmp	alloc_hiseg

	Public	alloc_hiseg
alloc_hiseg:
; allocate AX paragraphs in high memory if possible, otherwise allocate
; it in conventional memory
	cmp	hidos,0			; do we want to relocate DOS ?
	 je	alloc_seg		;  no, allocate conventionally
	call	alloc_upper		; try to allocate some upper memory
	 jc	alloc_seg		;  can't, so allocate conventional
	ret				;  else return address of allocated mem

alloc_seg_with_padding:
; On Entry:
;	AX = para's required
;	DX = minimum acceptable offset
; On Exit:
;	AX = base para
;
; If gate A20 is enabled we can't use negative offset's for DOS/BIOS so
; we pad conventional memory to avoid this. Avoid seg=0 while here.
	push	cx
	push	dx
	add	dx,15+16		; DX is the offset we will be using
	mov	cl,4			;  so make sure base is high enough
	shr	dx,cl			; convert "offset" to a segment value
	cmp	dx,mem_current		;  make sure we don't generate a
	 jbe	alloc_seg_nopad		;  negative segement value as this
	mov	mem_current,dx		;  will crash if a20 enabled
alloc_seg_nopad:			; pad if necessary
	mov	dl,'M'			; allocate for DOS
	call	alloc_seg		; now we can allocate OK
	pop	dx
	pop	cx
	ret

	Public	alloc_seg
alloc_seg:
;---------
; On Entry:
;	AX = para's required
;	DL = subsegment type
; On Exit:
;	AX = base para
;
	push	ds
	push	cx
	mov	cx,ax			; remember how much was wanted
	inc	ax			; allow an extra para for a header
	add	ax,mem_current		; Return a pointer to AX paragraphs
	cmp	ax,mem_max		; of memory to the calling routine.
	 jae	alloc_s10
	xchg	ax,mem_current
	mov	ds,ax			; DS:0 -> header
	inc	ax			; AX:0 -> buffer
	mov	ds:DMD_ID,dl		; remember the type
	mov	ds:DMD_PSP,ax		; owner = itself
	mov	ds:DMD_LEN,cx		; size in para
	xor	cx,cx			; zero rest for cosmetic reasons
	mov	ds:word ptr DMD_NAME-3,cx
	mov	ds:word ptr DMD_NAME-2,cx
	mov	ds:word ptr DMD_NAME,'S'+256*'D'
	mov	ds:word ptr DMD_NAME+2,cx
	mov	ds:word ptr DMD_NAME+4,cx
	mov	ds:word ptr DMD_NAME+6,cx
	pop	cx
	pop	ds
	ret

alloc_s10:
	hlt				; ##jc##
	jmps	alloc_s10

alloc_upper:
;-----------
; On Entry:
;	AX = paragraphs required
; On Exit:
;	CY clear: 	AX = paragraphs address of allocated memory
;	CY set:		cannot allocate memory (All regs preserved)
;
	push	bx
	push	ax			; save para required
	cmp	himem_base,0		; we have already allocated some ?
	 je	alloc_upper10		; nothing to grow, allocate new block
	mov	bx,himem_size		; himem was this big
	add	bx,ax			; try and extend it
	push	es
	mov	es,himem_base		; point at existing himem
	mov	ah,MS_M_SETBLOCK	; and try and set to new size
	int	DOS_INT
	pop	es
	 jc	alloc_upper10		; can't grow, so allocate new block
	mov	ax,himem_base
	add	ax,himem_size		; return seg above old alloc
	pop	bx			; recover para required
	add	himem_size,bx		; add into himem size
	pop	bx
	clc				; success..
	ret				; return AX = seg

alloc_upper10:
	mov	ax,(MS_M_STRATEGY*256)+1; set allocation strategy
	mov	bl,41h			;  to best fit, high only
	int	DOS_INT
	pop bx ! push bx		; recover para required in BX
	mov	ah, MS_M_ALLOC		;  and try to allocate them
	int	DOS_INT
	pushf ! push ax			; save CF and possible address
	mov	ax,(MS_M_STRATEGY*256)+1; set allocation strategy
	mov	bl,0			;  to first fit
	int	DOS_INT
	pop ax ! popf			; restore CF and possible address
	 jc	alloc_upper20		; can't allocate, use conventional
	cmp	ax,mem_size		; is it from upper memory ?
	 ja	alloc_upper15		; yes, we can use it
	push	es			; it's conventional, free it up
	mov	es,ax			;  seg address in ES
	mov	ah,MS_M_FREE
	int	DOS_INT			; free up this memory
	pop	es
	jmps	alloc_upper20		; try again with XMS

alloc_upper15:
	mov	himem_base,ax		; save base value
	pop	himem_size		; save size
	pop	bx			; and return seg in AX
	clc				; success..
	ret

alloc_upper20:
	pop	ax
	pop	bx			; restore regs
	push ds ! push es
	push bx ! push cx ! push dx ! push si ! push di ! push bp
	push	ax			; save allocation size
	mov	ax,4300h		; check for XMS installation
	int	2fh
	cmp	al,80h
	 jne	alloc_upper30
	mov	ax,4310h		; get address of XMS driver
	int	2fh
	mov	word ptr xms_driver,bx
	mov	word ptr xms_driver+2,es
	pop dx ! push dx		; DX = allocation size
	mov	ah,10h			; allocate upper memory block
	callf	xms_driver
	cmp	ax,1			; did we succeed ?
	 jne	alloc_upper30
	pop	ax			; recover allocation size
	mov	ax,bx			; return para address of himem
	pop bp ! pop di ! pop si ! pop dx ! pop cx ! pop bx
	pop es ! pop ds
	clc				; success
	ret
	
alloc_upper30:
	pop	ax			; recover allocation size
	pop bp ! pop di ! pop si ! pop dx ! pop cx ! pop bx
	pop es ! pop ds
	stc				; failure....
	ret


mark_system_memory:
;------------------
; ensure any memory we have allocated is owned by PSP 0008, a magic value
;  used to indicate system memory
	push	es
	les	bx,func52_ptr		; get internal data in ES:BX
	mov	es,es:F52_DMDROOT[bx]	; get 1st DMD entry
	mov	ah,MS_P_GETPSP
	int	DOS_INT			; get our PSP in BX
mark_sm10:
	cmp	es:DMD_ID,'M'
	 je	mark_sm20		; check we have a valid DMD
	cmp	es:DMD_ID,'Z'
	 jne	mark_sm50		; stop if we don't
mark_sm20:
	cmp	bx,es:DMD_PSP		; is it ours ??
	 jne	mark_sm30
	mov	es:DMD_PSP,0008		; mark as system
mark_sm30:
	cmp	es:DMD_PSP,0008		; if system mark as SC
	 jne	mark_sm40
	xor	ax,ax			; zero rest for cosmetic reasons
	mov	ds:word ptr DMD_NAME-3,ax
	mov	ds:word ptr DMD_NAME-2,ax
	mov	ds:word ptr DMD_NAME,'S'+256*'C'
	mov	ds:word ptr DMD_NAME+2,ax
	mov	ds:word ptr DMD_NAME+4,ax
	mov	ds:word ptr DMD_NAME+6,ax
mark_sm40:
	cmp	es:DMD_ID,'Z'		; is it the last DMD ?
	 je	mark_sm50		;  then stop
	mov	ax,es
	inc	ax			; skip DMD header and add
	add	ax,DMD_LEN		;  length to find next DMD
	mov	es,ax
	jmps	mark_sm10		; now go and look at that

⌨️ 快捷键说明

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