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

📄 himem2.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;/*
; *                      Microsoft Confidential
; *			 Copyright (C) Microsoft Corporation 1988-1992
; *                      All Rights Reserved.
; */
	page	95,160
	title   'HIMEM2 - Initialization code'

funky	segment word public 'funky'
	extrn	InstallMoveBlock:near	; in high segment
	extrn	textseg:word		; in high segment
	extrn	KiddValley:word
	extrn	KiddValleyTop:word
	extrn	segKiddValley:word
	extrn	cHandles:word
	extrn	pack_and_truncate:near
	extrn	MmovSegReinit:far
	extrn	end_of_funky_seg:byte
	extrn	LEnblA20:word
	extrn	LDsblA20:word
funky	ends

	.xlist
	include	himem.inc		; get structures, equ's, etc.
					;  and open segment
	.list

	public	f000
	public	InitInterrupt
	public	MachineNum

;************************************************************************
;*									*
;*  Global Variables							*
;*									*
;************************************************************************

	extrn	pPPFIRET:word
	extrn	dd_int_loc:word
	extrn	Interrupt:near
	extrn	hiseg:word
	extrn	call_hi_in_di:near
	extrn	fCanChangeA20:byte
	extrn	fHMAMayExist:byte

	extrn	fVDISK:byte
	extrn	IsVDISKIn:near

	extrn	A20Handler:near
	extrn	EnableCount:word
	extrn	MemCorr:word
	extrn	MinHMASize:word

ifdef debug_tsr
	extrn	MoveIt:dword
else
	extrn	MoveIt:word
endif

	extrn	pReqHdr:dword
	extrn	PrevInt2f:dword
	extrn	TopOfTextSeg:word

	extrn	InstallA20:near
	extrn	Int2fHandler:near
	extrn	Is6300Plus:near
	extrn	IsA20On:near

	extrn	pAddMem:word
	extrn	SignOnMsg:byte
	extrn	ROMDisabledMsg:byte
	extrn	UnsupportedROMMsg:byte
	extrn	ROMHookedMsg:byte
	extrn	BadDOSMsg:byte
	extrn	NowInMsg:byte
	extrn	On8086Msg:byte
	extrn	NoExtMemMsg:byte
	extrn	FlushMsg:byte
	extrn	StartMsg:byte
	extrn	HandlesMsg:byte
	extrn	HMAMINMsg:byte
	extrn	KMsg:byte
	extrn	NoHMAMsg:byte
	extrn	A20OnMsg:byte
	extrn	HMAOKMsg:byte
	extrn	VDISKInMsg:byte
	extrn	BadArgMsg:byte

	extrn	DevAttr:word
	extrn	Int15MemSize:word
	extrn	pInt15Vector:word

	extrn	PrevISAInt15:dword
	extrn	ISA15Handler:near

	extrn	EndText:byte

	extrn	XMMControl:far
	extrn	pfnEnabA20:word
	extrn	pfnDisabA20:word
	extrn	LocalEnableA20:near
	extrn	LocalDisableA20:near

;************************************************************************
;*									*
;*   Code/Data below here will be discarded after driver initialization *
;*									*
;************************************************************************

;	Discardable Initialization Data

pCOMPAQ		label	dword	; Pointer to COMPAQ specific for BIM
		dw	0FFE8h	;
		dw	0F000h	;
pBIMGDT 	dw	offset BIMGDT	    ; Offset to BIMGDT for BIM alloc'n
GetBIMMemProc	dw	offset GetBIMMemory ; Offset of GetBIMMemory procedure
BIMBase 	dw	0	; Base address and Lenght of remaining Compaq
BIMLength	dw	0	;   Built-In Memory (set at Init time)

BIMBuffer	dw	?	; Buffer for unlock/lock ROM for BIM
	public	fShadowOff, f1stWasWarning

fShadowOff	db	0	; NZ if shadow RAM should be disabled,
				;   0/1 set by command line switch, 0FFh
				;   set if little extended and hope to disable

f1stWasWarning	db	0	; NZ if 1st attempt to diddle A20 generated
				; a warning (and not an error)
	public	fA20Control

fA20Control	db	0ffh	; NZ if himem should take control of A20, even
				;   it was already on when himem loaded.

	public	fCPUClock

fCPUClock	db	0	; NZ if himem should try to preserve CPU clock
				;   speed when gating A20

fEISA		db	0	; NZ if himem should take all EISA memory
				;   blocks
		public	fQuiet
fQuiet		db	0ffh	; NZ if himem should be quiet during install

fSignOnMsg	db	0	; NZ if sign on msg has been displayed

fBigMem 	db	0ffh	; NZ if ISA memory above 16 meg allowed

fNumHandSet	db	0	; NZ if /NUMHANDLES= parameter used
fHMAminSet	db	0	; NZ if /HMAMIN= parameter used


; Parameter tables for GetParms

ParmEntry   struc
cParmChar   db	    0		; 1st char of option on cmd line
pParmRtn    dw	    0		; offset of routine to process option
ParmEntry   ends

; The 1st table is for parameters that have no arguments

ParmTbl1 label	 byte
	ParmEntry   <'E',GPGotEisa>		; /EISA
	ParmEntry   <'V',GPGotVerbose>		; /VERBOSE
	ParmEntry   <'N',GPGotBigMem>		; /NOABOVE16
	ParmEntry   <'Z',GPZSwitch>		; /Z
	db	0				; ** END OF TABLE **

; The 2nd table is for parameters with arguments

ParmTbl2 label	 byte
	ParmEntry   <'H',GPGotMin>		; /HMAMIN=
	ParmEntry   <'N',GPGotHands>		; /NUMHANDLES=
	ParmEntry   <'M',GPGotMachine>		; /MACHINE:
	ParmEntry   <'A',GPGotA20Control>	; /A20CONTROL:
	ParmEntry   <'S',GPGotShadow>		; /SHADOWRAM:
	ParmEntry   <'I',GPGotInt15>		; /INT15=
	ParmEntry   <'C',GPGotCPUClock> 	; /CPUCLOCK:
	db	0				; ** END OF TABLE **


	public	StringParm, MachineNum, MachineName

StringParm	db	13 DUP (' ')

MachineNum	dw	-1

;  Note: the following table MUST be in the same order as the entries in the
;  A20_Scan_Table!  If you add entries here, also add one there!

MachineName	label	byte
	db	'ptlcascade',0		; Phoenix Cascade BIOS
	db	'att6300plus',0 	; AT&T 6300 Plus
	db	'ps2',0 		; IBM PS/2
	db	'hpvectra',0		; HP 'Classic' Vectra (A & A+)
	db	'acer1100',0		; Acer 1100
	db	'toshiba',0		; Toshiba 1600 & 1200XE
	db	'wyse',0		; Wyse 12.5 MHz 286 machine
	db	'tulip',0		; Tulip machines
	db	'zenith',0		; Zenith ZBIOS
	db	'at1',0 		; IBM AT/delay 0
	db	'at2',0 		; IBM AT/delay 1
	db	'at3',0 		; IBM AT/delay 2
	db	'philips',0		; Philips machines
	db	'css',0			; CSS Lab machines
	db	'fasthp',0		; Single byte method for HP Vectras
	db	'ibm7552',0		; IBM 7552 Industrial Computer
	db	'bullmicral',0		; Bull Micral 60 M004
	db	'dell',0		; DELL XBIOS		; M010
	db	'at',0			; IBM AT
	db	0FFh			; end of table

;NOTE: there is code in GetParms which depends on AltNameTbl coming
;      after MachineName table.

	public	AltName1, AltName2, AltName3, AltName4, AltName5
	public	AltName6, AltName7, AltName8, AltName9, AltName10
	public	AltName11, AltName12, AltName13, AltName14, AltName15
	public	AltName16,AltName17	;M004

AltNameTbl	label	byte
AltName3    db	'3',0			; Phoenix Cascade BIOS
AltName5    db	'5',0			; AT&T 6300 Plus
AltName2    db	'2',0			; IBM PS/2
AltName4    db	'4',0			; HP 'Classic' Vectra (A & A+)
AltName6    db	'6',0			; Acer 1100
AltName7    db	'7',0			; Toshiba 1600 & 1200XE
AltName8    db	'8',0			; Wyse 12.5 Mhz 286 machine
AltName9    db	'9',0			; Tulip machine
AltName10   db	'10',0			; Zenith ZBIOS
AltName11   db	'11',0			; IBM AT/delay 0
AltName12   db	'12',0			; IBM AT/delay 1
AltName13   db	'13',0			; IBM AT/delay 2
	    db	'13',0			; Philips machines (same as AT3)
	    db	'12',0			; CSS machines
AltName14   db	'14',0			; Single byte HP Vectra m/cs
AltName15   db	'15',0			; IBM 7552 Industrial Computer
AltName16   db	'16',0			; Bull Micral 60          M004
AltName17   db	'17',0
AltName1    db	'1',0			; IBM AT
	    db	0FFh			; end of table

ifdef	debug_tsr	;-----------------------------------------------

;*----------------------------------------------------------------------*
;*									*
;*  ExeStart -								*
;*									*
;*	Entry point when himem is invoked as an .EXE.			*
;*									*
;*----------------------------------------------------------------------*

lpCmdLine	dd	81h		; far ptr to command tail

	public	ExeStart

ExeStart:

	mov	word ptr cs:[lpCmdLine+2],es	; save PSP segment in pointer

	mov	ax,cs		; Setup segment regs to all be the same
	mov	ds,ax
	mov	es,ax

	call	InitDriver	; Initialize...

	mov	ax,TopOfTextSeg	; TopOfTextSeg == 0 is error installing
	or	ax,ax
	jnz	@f

	mov	ax,4C03h	; error, so just terminate
	int	21h
@@:
	mov	di,offset pack_and_truncate
	jmp	call_hi_in_di	; terminate and stay resident

endif			;------------------------------------------------



;*----------------------------------------------------------------------*
;*									*
;*  InitInterrupt -							*
;*									*
;*	Called by MS-DOS immediately after Strategy routine		*
;*									*
;*  ARGS:   None							*
;*  RETS:   Return code in Request Header's Status field		*
;*  REGS:   Preserved							*
;*									*
;*	This entry point is used only during initialization.		*
;*	It replaces itself with a much shorter version which only	*
;*	serves to report the appropriate errors when this driver	*
;*	is called in error.						*
;*									*
;*----------------------------------------------------------------------*

InitInterrupt   proc    far

	; Save the registers including flags.

	push    ax		; We cannot use pusha\popa because
	push    bx		;	we could be on an 8086 at this point
	push    cx
	push    dx
	push    ds
	push    es
	push    di
	push    si
	push    bp
	pushf

	push	cs		; Set DS=CS for access to global variables.
	pop	ds

	les	di,[pReqHdr]	; ES:DI = Request Header

	mov     bl,es:[di].Command ; Get Function code in BL

	or	bl,bl		; Only Function 00h (Init) is legal
	jz	IInit

	cmp     bl,16		; Test for "legal" DOS functions
	jle     IOtherFunc

IBogusFunc:
	mov     ax,8003h	; Return "Unknown Command"
	jmp     short IExit

IOtherFunc:
	xor     ax,ax		; Return zero for unsupported functions
	jmp     short IExit

IInit:
	call    InitDriver	; Initialize the driver
	les	di,[pReqHdr]	; Restore es:di = Request Header

IExit:
	or	ax,0100h	; Turn on the "Done" bit
	mov	es:[di].Status,ax ; Store return code

	popff			; restore the registers
	pop	bp
	pop	si
	pop	di
	pop	es
	pop	ds
	pop	dx
	pop	cx
	pop	bx
	pop	ax
	mov	dd_int_loc,offset Interrupt	; replace Interrupt with
	ret					; tiny permanent stub

InitInterrupt   endp

;*----------------------------------------------------------------------*
;*									*
;*  InitDriver -							*
;*									*
;*	Called when driver is Initialized.				*
;*									*
;*  ARGS:   ES:DI = Address of the Request Header			*
;*  RETS:   pHdr.Address = Bottom of resident driver code		*
;*  REGS:   AX, CX and Flags are clobbered				*
;*									*
;*----------------------------------------------------------------------*

	public	InitDriver

InitDriver  proc    near

	cld

ifndef	debug_tsr
	call	LocateHiSeg	; locate the hiseg in low memory properly

	mov	di, offset MMovSegReinit
	mov	es, hiseg
	push	cs
	call	call_hi_in_di	; re-initialize the mem mover

	mov	ax,cs
	push	es
	mov	es,hiseg
	assume	es:funky
	add	textseg,ax	; relocate text segment pointer
	add	LEnblA20+2, ax	; update ptrs to enble & disable a20 rtns
	add	LDsblA20+2, ax
	pop	es
	assume	es:nothing
endif

	mov	ah,30h		; make sure we've got DOS 3.00 or higher
	int	21h		; Get DOS versions number
	cmp	al,3
	jae     IDCheckXMS

	mov	dx,offset BadDOSMsg
	jmp	IDFlushMe

IDCheckXMS:
	mov	ax,(INT2F_ID SHL 8) OR INT2F_INS_CHK
	int	2Fh		; make sure there's no other XMS installed
	cmp	al,80h		; Is INT 2F hooked?
	jne     IDNotInYet
	mov	dx,offset NowInMsg
	jmp	IDFlushMe

IDNotInYet:
	xor     ax,ax			; Move 0 into the Flags register
	push    ax
	popf
	pushf				; Try and get it back out
	pop     ax
	and     ax,0F000h		; If the top four bits are set...
	cmp     ax,0F000h
	mov	dx,offset On8086Msg	; we're on an 8086
	jnz	@f
	jmp	IDFlushMe		; so crap out
@@:
	call	GetInt15Memory		; If Int 15h/88h reports < 384k of
	cmp	ax,384			;   extended memory available, then
	jae	@f			;   we will try to increase memory
	mov	fShadowOFF,0FFh 	;   by stealing shadow RAM
@@:
	call	GetParms		; process command line parameters

	mov	ah, 2			; Force VERBOSE mode if user is
	int	16h			;   holding down the Alt key
	test	al, 08h 		; Int 16h/2 == Get Keyboard Flags
	jz	@f			;   08h set if Alt key down
	mov	fQuiet, 0
@@:

ifndef	debug_tsr
	call	DispSignOnMsg
endif
	mov	di,offset InstallMoveBlock ; install moveblock function
	push	cs			; setup for far return
	call	call_hi_in_di		; call into high segment

	call	IsA20On 		; Is A20 already enabled?
	or	ax,ax			;   (may zap cx, si, di)
	jz	IDInsA20		;   no, go install A20 handler

	mov	dx,offset A20OnMsg	; "A20 already on" message
	cmp	fA20Control,0		; should we take control of A20 anyway?
	jne	IDInsA20		;   yes, go muck with it
	mov	[fCanChangeA20],0	;   no,  don't allow changing of A20
	call	DispInfoMsg		;	 and tell user about it
	jmp	short IDAfterA20

IDInsA20:
	call	InstallA20		; install proper A20 handler
	jnc	@f
	jmp	IDFlushMe		; CY means fatal error
@@:

;	Note:  A side affect of the previous InstallA20 is that MemCorr
;	  is set to reflect the adjustment factor if we're on an AT&T 6300+

IDAfterA20:
	call	InitHandles	; initialize handle table

	call	ScanEISA	; scan EISA memory into table

	call	CheckZBim	; Check for & allocate Zenith BIM

	call	CheckBIM	; Check for & allocate Compaq BIM

;	Turn off shadow RAM if desired/possible

	cmp	fShadowOFF,0	; should shadow RAM be turned off?
	jz	@f

	call	ShadowRAMOff	; try to turn it off--also adds to free list

	or	dx,dx		; display a msg if ShadowRAMOff is
	jz	@f		;   pointing to one
	call	DispInfoMsg
@@:
	call	IsVDISKIn		; Is a VDISK style allocator already
	cmp	[fVDISK],0		;   installed?	Don't bother to load
	jz	@f			;   if so, cause we'll just fail all
	mov	dx,offset VDISKInMsg	;   future calls anyway...
	jmp	short IDFlushMe
@@:

;	Looks like himem will install, allocate Big ISA memory (above 16 meg)
;	now if available

	cmp	[fBigMem], 0		; Was parameter specified?
	je	@f			; NO: don't bother trying to get it
	call	GetBIGMemory		; Get extra ISA memory
@@:

	call    GetInt15Memory	; how much extended memory is installed?
	cmp     ax,64		; Is there >= 64K of extended?
	jae	IDHMAOK

	push	es
	mov	es,hiseg
	assume	es:funky
	mov	bx,[KiddValley]	; get size of memory we already have in tables
	mov	cx,[cHandles]

IDAnyMem:
	cmp	[bx].Flags,FREEFLAG
	jnz	IDAnyMem_1	; brif not a valid free block
	mov	ax, [bx].Len.hi
	or	ax, [bx].Len.lo
	jnz	IDAnyMem_2
IDAnyMem_1:
	add	bx,SIZE Handle
	loop	IDAnyMem
IDAnyMem_2:
	pop	es
	assume	es:nothing

	mov	dx,offset NoHMAMsg
	or	ax,ax			; no HMA, any other memory to control?
	jnz	disp_hma_msg		; jmp if some memory

;	We can't find any memory to manage.

	mov	dx,offset NoExtMemMsg

;	Display the message in DX followed by the "Flush" message.

IDFlushMe:
	call	DispErrMsg
	mov	dx,offset FlushMsg
	call	DispErrMsg

	xor	ax,ax			; discard the driver
	mov	[TopOfTextSeg],ax

ifndef	debug_tsr			;-------------------------------
	les	di,[pReqHdr]
	mov	es:[di].Units,al
	and	cs:DevAttr,not 8000h	; clr bit 15 in attrib of driver header
endif
	jmp	short IDReturn		;-------------------------------

IDHMAOK:
	mov     [fHMAMayExist],1
	mov	dx,offset HMAOKMsg
disp_hma_msg:
	call	DispInfoMsg

	call    HookInt2F		; "turn on" the driver

;	Initialization finished (or failed) -- return to caller

IDReturn:

ifndef	debug_tsr			;-------------------------------
	mov	di,offset pack_and_truncate
	jmp	call_hi_in_di		; pack stuff down and terminate
else
	mov	ax, hiseg		; make sure far pointer to handle
	mov	es, ax			;   table has correct segment
	mov	es:[segKiddValley], ax
endif					;-------------------------------
	ret

InitDriver	endp

;----------------------------------------------------------------------------
;  DispXxxMsg Routines -- Display informational, error or sign on messages,
;			  if enabled by /VERBOSE parameter.  Error msgs
;			  are displayed regardless of /VERBOSE.
;  Entry:
;	DX = offset of msg to display
;  Exit:
;
;  Used:
;	AX
;----------------------------------------------------------------------------
	public	DispInfoMsg, DispInfoChar, DispErrMsg

DispInfoMsg	proc	near
	cmp	cs:[fQuiet], 0		; display an informational msg if
	jnz	short DIM_ret		;   not in QUIET mode

⌨️ 快捷键说明

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