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

📄 wdrminit.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
PAGE 58,132
;******************************************************************************
TITLE WDRMINIT.ASM -- Real Mode Initialization for WDCTRL.386
;******************************************************************************
;
;   (C) Copyright MICROSOFT Corp., 1990
;
;   Title:      WDRMINIT.ASM -- Real Mode Initialization for WDCTRL.386
;
;   Version:    1.00
;
;   Date:       17-Oct-1990
;
;   Author:     RAL
;
;------------------------------------------------------------------------------
;
;   Change log:
;
;      DATE     REV                 DESCRIPTION
;   ----------- --- -----------------------------------------------------------
;   17-Oct-1990 RAL
;   22-Oct-1991 JGT Switched to alternate status register
;                   Allowed Zenith machines to run by allowing track count
;                       to be THREE off (instead of the 'normal' TWO)
;   24-Oct-1991 JGT Allowed one drive to be non-FastDisk compatible and
;                       load.
;   27-Oct-1991 RAL For for hang if MS-NET kernel server running -- Don't
;		    call DOS to get InDOS ptr once incrmented.
;
; N.b., this file is (nearly) duplicated in apps\setup\dos\wdrminit.asm.
; Changes made to this file should also be made to that file.
;
;==============================================================================

	.386p

;******************************************************************************
;                             I N C L U D E S
;******************************************************************************

	.XLIST
	INCLUDE VMM.Inc
	INCLUDE OptTest.Inc
	INCLUDE BlockDev.Inc
	INCLUDE Int13.Inc
	INCLUDE WDLocal.Inc
	INCLUDE Int2FAPI.Inc
	.LIST

;******************************************************************************

SETUP EQU 1

IFDEF SETUP
    EXTRN _WDCtrlHangError:FAR

BeginProc MACRO ProcName
PUBLIC ProcName
ProcName PROC NEAR
	ENDM

EndProc MACRO ProcName
ProcName ENDP
	ENDM


DGROUP GROUP _DATA

ERR_WDCTRL_FATAL        equ 41
ERR_WDCTRL_BAD_SOFTWARE equ 42


FLAT SEGMENT AT 0

FLAT ENDS


;------------------------------------------------------------------------------

FASTDISK SEGMENT WORD PUBLIC USE16 'CODE'

	 ASSUME CS:FASTDISK
	 ASSUME DS:FASTDISK
	 ASSUME ES:FASTDISK
	 ASSUME SS:FASTDISK

ELSE

VxD_REAL_INIT_SEG

EXTRN Invalid_Win386_Ver_String:BYTE
EXTRN Invalid_Int13_Chain:BYTE
EXTRN Invalid_IRQ_String:BYTE
EXTRN Invalid_Controller_String:BYTE
EXTRN Validation_Failed_String:BYTE
EXTRN Invalid_DOS_Ver_String:BYTE
EXTRN WD_Fatal_Error_Code:BYTE
EXTRN WD_Fatal_Error_Msg:BYTE
EXTRN WD_Incompatible_Sw_Msg:BYTE
EXTRN No_Fixed_Disk_String:BYTE
EXTRN Pause_String:BYTE
EXTRN WD_Env_String_Bail:BYTE
EXTRN ES_Debug:BYTE
EXTRN ES_Debug_Len:BYTE
EXTRN ES_Disable:BYTE
EXTRN ES_Disable_Len:BYTE
EXTRN PS_Enable_Wdctrl:BYTE
EXTRN PS_Force_Enable_80:BYTE
EXTRN PS_Force_Enable_81:BYTE
EXTRN PS_Force_Alt_Status0:BYTE
EXTRN PS_Force_Alt_Status1:BYTE

ENDIF

;******************************************************************************


ALIGN 4
InDOS_Ptr LABEL DWORD
InDOS_Off	    dw	    ?
InDOS_Seg	    dw	    ?
DOS_BIOS_Int13_Vec  dd	    0			    ; 0 means not hooked
ROM_BIOS_Int13_Vec  dd	    0
Service_Addr        dd      0
Int13_Buffer        db      512 dup (?)
My_Read_Buffer      db      512 dup (?)

Num_Int13_Drives    db      0
Signaled_Detection  db	    False

QEMMDeviceName	    db	    'QEMM386$',0
QPIEntryPoint	    dd	    ?
QEMM_Stealth_Enabled db     False


;******************************************************************************
;
;   WD_Real_Mode_Init
;
;   DESCRIPTION:
;       This procedure attempts to detect a standard AT type hard disk
;       controller being used for Int 13h.  It will check for two hard
;       disk drives by monitoring changes to the cylinder register after
;       various reads.  Note that this code will use the DOS Int 2Fh, AH=13h
;       to bypass any caching software that may be installed.
;
;       To detect the presence of a Western Digital controller this code
;       will do the following:
;           Get original Int 13h vector from DOS
;           For disks 80h and 81h (if either exists) do
;               Read port 1F7h (Status) and make sure it looks OK
;               Read sector 1, track 0, head 0
;               Temp=Value of port(1F4h)
;               Read sector 1, track 2, head 0
;               If Temp=Value of port(1F4h) then NOT OK
;               If Temp-Value of port(1F4h) > 4 then NOT OK
;
;   ENTRY:
;       CS=DS=ES
;       AX = Win386 version number (requires 3.10)
;	SI = Environment segment
;
;   EXIT:
;       EDX = Flags
;             Bit 0 = 1 if drive 80h is on standard AT controller
;             Bit 1 = 1 if drive 81h is on standard AT controller
;             Bit 2 = 1 if alternate status register should be used
;
;   USES:
;
;==============================================================================

BeginProc WDCtrl_Real_Mode_Init

IFNDEF SETUP
	cmp     ax, 30Ah
	jb      WD_RMI_Invalid_Win386

        ;** Save the loader service address
	mov	[Service_Addr], ecx

	call	Test_Disable_Switch		; Q: User set /D:F option?
	jc	WD_RMI_Dont_Load_Silent 	;    Y: Don't load

        ;** Here we check for two environment strings:
        ;**     WDCTRLDISABLE=Y         ;Disables WDCTRL (displays message)
        ;**     WDCTRLDEBUG=Y           ;Stops debugger at INT 3 in RM Init
	mov	es, si			; Set ES to our environment
        mov     si, OFFSET ES_Disable   ;'WDCTRLDISABLE='
        xor     ch,ch
        mov     cl, ES_Disable_Len
        call    WD_RMI_Get_Env_String   ;Get the value for the string
        or      ax, ax                  ;Bail out?
        jz      SHORT WD_RMI_NoEnvBailOut ;No
        mov     dx, OFFSET WD_Env_String_Bail ;Get message
        jmp     WD_RMI_Print_Error      ;Exit with error

WD_RMI_NoEnvBailOut:
        mov     si, OFFSET ES_Debug     ;'WDCTRLDEBUG='
        xor     ch,ch
        mov     cl, ES_Debug_Len
        call    WD_RMI_Get_Env_String
        or      ax, ax
        jz      SHORT WD_RMI_NoInt3
        int     3                       ;Break to debugger
WD_RMI_NoInt3:
	;** Check for SYSTEM.INI string that must be set to true for
	;** WDCTRL to load.
        mov     ax, 3                   ;Service:  Get_Profile_Boolean
        xor     ecx, ecx                ;Default is FALSE
        xor     si, si                  ;[386Enh] is default section
	mov	di, OFFSET PS_Enable_Wdctrl ;'32BITDISKACCESS'
        call    cs:[Service_Addr]       ;Call loader service
	or	cx, cx
	jz	WD_RMI_Dont_Load_Silent

        ;** We have a SYSTEM.INI switch here to force WDCTRL enabled
        ;**     without validation.  This is useful for drives that fail
        ;**     validation, but work fine with FastDisk.
        mov     ax, 3                   ;Service:  Get_Profile_Boolean
        xor     ecx, ecx                ;Default is FALSE
        xor     si, si                  ;[386Enh] is default section
        mov     di, OFFSET PS_Force_Enable_80 ;'WDCTRLDRIVE0', 0
        call    cs:[Service_Addr]       ;Call loader service
        or      cx, cx
        mov     bl,0                    ;Clear the flag bits
        jz      SHORT WD_RMI_No_Drive_80 ;Drive not forced enabled
        or      bl, RF_Drive_80h_Ours   ;Flag that drive 80h was forced on
WD_RMI_No_Drive_80:
        mov     ax, 3                   ;Service:  Get_Profile_Boolean
        xor     ecx, ecx                ;Default is FALSE
        xor     si, si                  ;[386Enh] is default section
        mov     di, OFFSET PS_Force_Enable_81 ;'WDCTRLDRIVE1', 0
        push    bx                      ;Save flag bits
        call    cs:[Service_Addr]       ;Call loader service
        pop     bx
        or      cx, cx
        jz      SHORT WD_RMI_No_Drive_81 ;Drive not forced enabled
        or      bl, RF_Drive_81h_Ours   ;Flag that drive 80h was forced on
WD_RMI_No_Drive_81:
        test    bl,bl                   ;Any bits set?
        jz      SHORT WD_RMI_No_Force_Enable ;No.  Do normal validation

        ;** Now that we have verified that the user wanted one or two
        ;**     drives forced on, they can also specify if the drive
        ;**     should use the alternate status register.  Default is NO.
        mov     ax, 3                   ;Service:  Get_Profile_Boolean
        xor     ecx, ecx                ;Default is FALSE
        xor     si, si                  ;[386Enh] is default section
	mov	di, OFFSET PS_Force_Alt_Status0 ;'WDCTRLALTSTATUS0', 0
        push    bx                      ;Save flag bits
        call    cs:[Service_Addr]       ;Call loader service
        pop     bx
        or      cx, cx
	jz	SHORT WD_RMI_No_Alt_Status0 ;Drive not forced enabled
	or	bl, RF_Use_Alt_Stat_80	;Flag that user wanted alt status reg
WD_RMI_No_Alt_Status0:

        mov     ax, 3                   ;Service:  Get_Profile_Boolean
        xor     ecx, ecx                ;Default is FALSE
        xor     si, si                  ;[386Enh] is default section
	mov	di, OFFSET PS_Force_Alt_Status1 ;'WDCTRLALTSTATUS1', 0
        push    bx                      ;Save flag bits
        call    cs:[Service_Addr]       ;Call loader service
        pop     bx
        or      cx, cx
	jz	SHORT WD_RMI_No_Alt_Status1 ;Drive not forced enabled
	or	bl, RF_Use_Alt_Stat_81	;Flag that user wanted alt status reg
WD_RMI_No_Alt_Status1:

        jmp     WD_RMI_Have_Ref_Data    ;Force it on as if validation
                                        ;  passed successfully

WD_RMI_No_Force_Enable:

        push    ds                      ;Restore ES
        pop     es

ENDIF

;------------------------------------------------------------------------------
;
;   Now make sure that we have some Int 13h drives by calling Get Drive
;   Parameters for drive 80h.
;
;------------------------------------------------------------------------------

	mov     ah, 08h                         ; Get drive parameters
	mov     dl, 80h                         ; For first drive
	int	13h				; Q: Is there one or more?
	sti					; STI TO WORK AROUND AD-DOS!
IFNDEF SETUP
	jc	WD_RMI_No_Disk_Drives		;    N: Pretty pointless
ELSE
	jc	WD_RMI_Error_Exit		;    N: Pretty pointless
ENDIF
						;    Y: Do some funky tests
	mov     [Num_Int13_Drives], dl          ; Save this for later
;------------------------------------------------------------------------------
;
;   Now do a check for the COMPAQ dual WDCTRL configuration. COMPAQ machines
;   have the ability to support two WDCTRLs at different I/O ports but which
;   share the same IRQ (12). This would work, WDCTRL would handle one, and
;   COMPAQ driver (EXTDISK.SYS) the other, except for the fact that the IRQ
;   is shared. We don't have code to handle the IRQ sharing so we'll just
;   punt this config and not install.
;
;------------------------------------------------------------------------------
    ;
    ; First see if this is a COMPAQ machine. This is the same detection
    ;	code that is in VFD
    ;
	push	es
	mov	ax, 0F000h
	mov	es, ax
	cmp	DWORD PTR es:[0FFE8h], 'OC30'
	clc
	jnz	SHORT CompDoneP 	; Not COMPAQ
	cmp	DWORD PTR es:[0FFECh], 'QAPM'
	clc
	jnz	SHORT CompDoneP 	; Not COMPAQ
    ;
    ; Is a COMPAQ machine, check for DUAL controler config by reading CMOS
    ;
	mov	ax, 1bh			; Secondary controller drive 1
	mov	dx, 70h			; CMOS Index I/O port 
	out	dx, al
	inc	dx			; CMOS data I/O port 
	IO_Delay
	IO_Delay
	in	al, dx			; Get drive type
	or	al, al			; Q: Do we have a drive (clears carry)?
	jz	short CompDoneP 	;  N: jump with carry clear
	dec	dx
	mov	al, 0eh			; Check if CMOS is OK
	IO_Delay
	IO_Delay
	out	dx, al
	inc	dx
	IO_Delay
	IO_Delay
	in	al, dx
	test	al, 60h 		; Q: Is CMOS Valid (clears carry)?
					;    Checking CMOS Bad Checksum and
					;	      CMOS Config Invalid
	jnz	short CompDoneP 	;  N: Error, jump with carry clear
	xor	ecx,ecx
	dec	ecx			; Report validation phase 0FF,0FF
	stc				; SET CARRY, dual controler config
CompDoneP:
	pop	es
IFNDEF SETUP
	jc	WD_RMI_Validation_Failed	; Don't instl COMPAQ dual CTRL
ELSE
	jc	WD_RMI_Error_Exit		; Don't instl COMPAQ dual CTRL
ENDIF

;------------------------------------------------------------------------------
;
;   Check for QEMM stealth.  WDCTRL will load if stealth is enabled even though
;   the Int 13h hook points to a "bad" location (QEMM hooks it).
;
;------------------------------------------------------------------------------

	call	Detect_QEMM_Stealth

;------------------------------------------------------------------------------
;
;   Now do lots of party stuff to make sure cache programs flush or at least
;   don't try to lazy-write any data while we do this test.  To make sure
;   of this we will do the following:
;	Broadcast the BlockDev hardware detection API Int 2Fh
;	Do an Int 13h read of sector 0 on both drives
;	Do a DOS disk reset on drives C-Z (may flush)
;	Set the InDOS flag
;
;------------------------------------------------------------------------------
;
;   Broadcast an Int 2Fh that tells cache programs that disk hardware detection
;   is about to begin.	This broadcast can be intercepted by new cache
;   programs to prevent unnecessary flushes and to prevent conflicts.
;
;------------------------------------------------------------------------------

	mov	ax, (W386_Int_Multiplex SHL 8) + W386_Device_Broadcast
	mov	bx, BlockDev_Device_ID
	mov	cx, BlockDev_API_Hw_Detect_Start
	int	2Fh

;------------------------------------------------------------------------------
;
;   Some cache programs punt the entire cache when someone that is not DOS
;   does an Int 13h.  Hopefully this will happen when we do this read.
;
;------------------------------------------------------------------------------

	mov	ax, 0201h			; Read 1 sector
	mov	bx, OFFSET Int13_Buffer 	; Into this buffer (ES:BX)
	mov	cx, 0001h			; Track 0, sector 1
	mov	dx, 0080h			; Head 0, drive 80h
	int	13h				; Do it!
	sti					; STI TO WORK AROUND AD-DOS!

	cmp	[Num_Int13_Drives], 1		; Q: More than one drive?
	je	SHORT WD_RMI_Reset_Drives	;    N: Done

	mov	ax, 0201h			; Read 1 sector
	mov	bx, OFFSET Int13_Buffer 	; Into this buffer (ES:BX)
	mov	cx, 0001h			; Track 0, sector 1
	mov	dx, 0081h			; Head 0, drive 81h
	int	13h				; Do it!
	sti					; STI TO WORK AROUND AD-DOS!


;------------------------------------------------------------------------------
;
;   Do a disk reset on every drive C-Z so that cache programs will flush.
;   PC Super Kwik will pay attention to this DOS call and flush lazy writes.
;
;------------------------------------------------------------------------------

WD_RMI_Reset_Drives:
	mov	ah, 19h
	int	21h
	push	ax

	mov	dl, 2				; Start with drive C:

WD_RMI_Flush_Loop:
	mov	ah, 0Eh 			; Select the drive
	int	21h				; (AL contains max drive)

	mov	ah, 0Dh 			; Flush the drive
	int	21h

	inc	dl				; DL = Next drive to flush
	cmp	dl, al				; Q: Any more drives to flush?
	jb	SHORT WD_RMI_Flush_Loop 	;    Y: Keep looking

	pop	dx				; DL = Original default drive
	mov	ah, 0Eh 			; Select drive
	int	21h

;------------------------------------------------------------------------------
;
;   TSRs should not pop up and do DOS calls when the InDOS flag is set.
;   We will leave the flag non-zero throughout the entire test.
;
;------------------------------------------------------------------------------

WD_RMI_Set_InDOS:
	push	es

	mov	ah, 34h
	int	21h				; ES:[BX] -> InDOS flag
	inc	BYTE PTR es:[bx]
	mov	[InDOS_Seg], es
	mov	[InDOS_Off], bx

	pop	es

	mov	[Signaled_Detection], True	; Set flag to indicate that
						; we need to dec InDOS and
						; do end detection Int 2Fh call

;------------------------------------------------------------------------------
;
;   Now wait for 2 clock ticks to make sure all disk activity that may
;   have slipped in before we bumped InDOS will complete.
;
;------------------------------------------------------------------------------

	sti					; Paranoia in case some random
						; software int turned off ints
	push	es
	mov	ax, 40h

⌨️ 快捷键说明

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