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

📄 wdrminit.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	mov	es, ax
	mov	ah, 2
WD_RMI_Set_Init_Time_Loop:
	mov	al, es:[6Ch]
WD_RMI_Wait_For_Tick_Loop:
	cmp	al, es:[6Ch]
	je	WD_RMI_Wait_For_Tick_Loop
	dec	ah
	jnz	WD_RMI_Set_Init_Time_Loop
	pop	es

;------------------------------------------------------------------------------
;
;   Now make sure that the Int 2Fh that we need will actually work.  We'll
;   do this by pointing DOS at somthing bogus for the time being.
;
;------------------------------------------------------------------------------

	mov     ah, 13h
	mov     bx, OFFSET WD_RMI_Int_13h_Hook
	mov     dx, OFFSET WD_RMI_Int_13h_Hook
	int     2Fh

	mov     si, ds
	mov     di, cs
	cmp     si, di
	je	WD_RMI_Cant_Hook_Int13

	mov	WORD PTR cs:[DOS_BIOS_Int13_Vec+2], ds
	mov	WORD PTR cs:[DOS_BIOS_Int13_Vec], dx

	mov	WORD PTR cs:[ROM_BIOS_Int13_Vec+2], es
	mov	WORD PTR cs:[ROM_BIOS_Int13_Vec], bx

	mov     ax, cs
	mov     es, ax
	mov     ds, ax

	call	Check_Hook_Addr_OK
IFNDEF SETUP
	jc	SHORT WD_RMI_Bad_Int_Chain
ELSE
	jc	short WD_RMI_Error_Exit
ENDIF


;------------------------------------------------------------------------------
;
;   It is possible for Int 13h to be hooked, so there may be some point
;   in loading this device.
;
;------------------------------------------------------------------------------

;
;   Make sure the interrupt we plan to use is unmasked.
;
	in      al, 0A1h
	test    al, 01000000b
IFNDEF SETUP
	jnz	SHORT WD_RMI_Wrong_IRQ
ELSE
	jnz     SHORT WD_RMI_Error_Exit
ENDIF


;
;   Check the status I/O port to make sure it looks right.
;
	mov	dx, WDIO_Def_Base_Port+WDIO_Status_Off
	IO_Delay
	IO_Delay
	in      al, dx
	and	al, NOT (WDStat_ECC_Corrected OR WDStat_Index)
	cmp     al, WDStat_Ready OR WDStat_Seek_Complete
IFNDEF SETUP
	jne	SHORT WD_RMI_Status_Bad
ELSE
	jne	SHORT WD_RMI_Error_Exit
ENDIF


;------------------------------------------------------------------------------
;
;   Now read a sector from each hard disk first through Int 13h and
;   then by sending a command directly to the controller.
;
;   We test both drives if present and set the appropriate bit for the
;   drive.  WDCTRL can use ony the drive that validates, even if there
;   are two drives and one doesn't validate
;
;------------------------------------------------------------------------------

	mov     dl, 80h
	mov     di, 41h*4
	call	WDCtrl_Validate_Drive
	pushf
	and	bx, RF_Use_Alt_Stat_80	; Save only alt status bit
	popf				; Restore carry flag
        jc      SHORT WD_RMI_First_Drive_Bogus
        or      bl, RF_Drive_80h_Ours   ; Alt status bit + good drive bit

WD_RMI_First_Drive_Bogus:
	cmp     [Num_Int13_Drives], 1
	je      SHORT WD_RMI_Do_We_Bail_Out

	mov     dl, 81h
	mov     di, 46h*4
        push    bx                      ; Save reference data
	call	WDCtrl_Validate_Drive
	mov	si, bx			; Save alt stat return from call
	pop	bx			; Get previous bits
	jc	SHORT WD_RMI_Do_We_Bail_Out
	and	si, RF_Use_Alt_Stat_81
	or	bx, si
        or      bl, RF_Drive_81h_Ours   ; Alt status bit + good drive bit

WD_RMI_Do_We_Bail_Out:
        test    bl, RF_Drive_80h_Ours OR RF_Drive_81h_Ours ; Either drive good?

IFNDEF SETUP
        jz      SHORT WD_RMI_Validation_Failed ; No, both bad so exit
ELSE
        jz      SHORT WD_RMI_Error_Exit
ENDIF

WD_RMI_Have_Ref_Data:
        movzx   edx, bl                  ; Get the reference data
	xor     bx, bx
	xor     si, si
IFNDEF SETUP
	mov     ax, Device_Load_Ok
ENDIF

;------------------------------------------------------------------------------
;
;   Common exit point for WD real mode init.  At this point, all return values
;   are in AX, BX, and SI.  If Int 13h is hooked then this code will reset
;   the hook.
;
;------------------------------------------------------------------------------

WD_RMI_Common_Exit:
	call	Clean_Up_Hooks
	ret

IFDEF SETUP

WD_RMI_Error_Exit:
	 mov   edx, 0
	 jmp   short WD_RMI_Common_Exit

ENDIF

;------------------------------------------------------------------------------
;
;   Error handlers
;
;------------------------------------------------------------------------------


IFNDEF SETUP
;
;   No disk drives were installed
;
WD_RMI_No_Disk_Drives:
	mov     dx, OFFSET No_Fixed_Disk_String
	jmp     SHORT WD_RMI_Print_Error
ENDIF

IFNDEF SETUP
;
;   Not running on Win386 verstion 3.10 or later
;
WD_RMI_Invalid_Win386:
	mov     dx, OFFSET Invalid_Win386_Ver_String
	jmp     SHORT WD_RMI_Print_Error
ENDIF

;
;   The DOS Int 2Fh did not work.  Assume wrong DOS version.
;
WD_RMI_Cant_Hook_Int13:
	mov     dx, cs
	mov     ds, dx
	mov     es, dx
IFNDEF SETUP
	mov     dx, OFFSET Invalid_DOS_Ver_String
	jmp     SHORT WD_RMI_Print_Error
ELSE
	jmp   SHORT WD_RMI_Error_Exit
ENDIF

IFNDEF SETUP
;
;   The Int 13h chain was hooked, but it appears that someone else has
;   hooked it in front of us.
;
WD_RMI_Bad_Int_Chain:
	mov     dx, OFFSET Invalid_Int13_Chain
	jmp     SHORT WD_RMI_Print_Error

;
;   The controller is not using the correct IRQ or the IRQ is masked.
;
WD_RMI_Wrong_IRQ:
	mov	dx, OFFSET Invalid_IRQ_String
	jmp     SHORT WD_RMI_Print_Error


;
;   The initial read of the controller status port did not match our
;   expectation.
;
WD_RMI_Status_Bad:
	mov	cx, ax
	call	Clean_Up_Hooks

	mov     dx, OFFSET Invalid_Controller_String
	mov     ah, 9
	int	21h

	mov	al, cl
	call	Print_Hex_Byte
	jmp	SHORT WD_RMI_Dont_Load


;
;   The controller did not pass our tests.
;
WD_RMI_Validation_Failed:
	call	Clean_Up_Hooks

	mov	dx, OFFSET Validation_Failed_String
	mov     ah, 9
	int	21h

	mov	al, cl
	call	Print_Hex_Byte

	mov	ah, 02h
	mov	dl, ','
	int	21h
	mov	dl, ' '
	int	21h

	mov	al, ch
	call	Print_Hex_Byte

	jmp	SHORT WD_RMI_Dont_Load


WD_RMI_Print_Error:
	call	Clean_Up_Hooks
	mov     ah, 9
	int	21h

WD_RMI_Dont_Load:
	mov	dx, OFFSET Pause_String
	mov	ah, 9
	int	21h

	xor	ax, ax
	int	16h

WD_RMI_Dont_Load_Silent:
	xor     bx, bx
	xor     si, si
	mov     ax, Abort_Device_Load + No_Fail_Message
	jmp     WD_RMI_Common_Exit
ENDIF

EndProc WDCtrl_Real_Mode_Init


;******************************************************************************
;
;   Detect_QEMM_Stealth
;
;   DESCRIPTION:
;	Specific check for QEMM stealth.  We'll call QEMM if it is installed
;	to find out if stealth is on.  This is done before entering the main
;	part of the detection code since we need to make DOS calls to open
;	the device driver.
;
;   ENTRY:
;	DS=ES=CS
;
;   EXIT:
;	None
;
;   USES:
;	Flags
;
;==============================================================================

BeginProc Detect_QEMM_Stealth

	pusha
;
;   Open QEMM device driver
;
	mov	dx, OFFSET QEMMDeviceName
	mov	ax, 3D00h
	int	21h				; Try to open QEMM386$
	jc	SHORT DQS_No_QEMM		; If CY, QEMM-386 not present
	mov	bx, ax				; Save file handle in BX
	mov	dx, OFFSET QPIEntryPoint	; Store the entry point here
	mov	cx, 4				; We're reading 4 bytes
	mov	ax, 4402h			; IOCTL read control string
	int	21h
	pushf					; Save error code
	mov	ah, 3Eh 			; Close the file handle
	int	21h
	popf
	jc	SHORT DQS_No_QEMM

;
;   At this point QPIEntryPoint contains the address of the QEMM entry
;   point.  We KNOW that we're on version 6.0 or later (since the IOCTL worked)
;   so we'll make the stealth install call.
;
	xor	cx, cx				; Set CL to zero just in case...
	mov	ax, 30*100h+0			; QEMM get info call
	push	ds				; More paranoia...
	push	es
	call	[QPIEntryPoint] 		; Call Mr. QEMM
	pop	es
	pop	ds
	test	cl, cl				; Q: Is stealth enabled?
	jz	SHORT DQS_No_Stealth		;    N: Don't set falg
						;    Y: Set flag for use later
	mov	[QEMM_Stealth_Enabled], True

DQS_No_Stealth:
DQS_No_QEMM:
	popa
	ret

EndProc Detect_QEMM_Stealth


;******************************************************************************
;
;   Check_Hook_Addr_OK
;
;   DESCRIPTION:
;	This procedure checks the BIOS Int 13h interrupt vector value to
;	see if it is "acceptable".  The address is considered acceptable
;	iff the segment is >= A000h or QEMM 6.0 or greater is installed
;	and stealth is enabled or the hook code responds to our Int 2Fh.
;
;   ENTRY:
;	DS=ES=CS
;
;   EXIT:
;	If carry set then
;	    Hook is NOT acceptable
;	else (carry clear)
;	    Hook address looks good
;
;   USES:
;	Flags
;
;==============================================================================

BeginProc Check_Hook_Addr_OK

	cmp	WORD PTR [ROM_BIOS_Int13_Vec+2], 0A000h
	jae	SHORT CHAO_Quick_OK_Exit

	pusha


;------------------------------------------------------------------------------
;
;   Broadcast an Int 2Fh that asks DOS Int 13h hookers if they are "blockdev
;   aware".  If they are aware of BlockDev and want fastdisk drivers to load
;   then they will return 0 in CX.
;
;------------------------------------------------------------------------------

	mov	ax, (W386_Int_Multiplex SHL 8) + W386_Device_Broadcast
	mov	bx, BlockDev_Device_ID
	.ERRE	BlockDev_API_Int13_Chain_Check	 ; Should not be 0!
	mov	cx, BlockDev_API_Int13_Chain_Check
	int	2Fh
	jcxz	SHORT CHAO_Chain_Is_OK

;------------------------------------------------------------------------------
;
;   Specific check for QEMM stealth.  We'll call QEMM if it is installed
;   to find out if stealth is on.  If it is then we'll load anyway.
;
;------------------------------------------------------------------------------

;
;   Now make sure that both hooks point to the same code segment as a sanity
;   check.
;
	mov	ax, WORD PTR [ROM_BIOS_Int13_Vec+2]
	cmp	ax, WORD PTR [DOS_BIOS_Int13_Vec+2]
	jne	SHORT CHAO_QEMM_Seg_Check_Failed

	cmp	[QEMM_Stealth_Enabled], True	; Q: Stealth on?
	jne	SHORT CHAO_QEMM_Seg_Check_Failed;    N: Not gonna do it!

;
;   All success cases exit here
;
CHAO_Chain_Is_OK:
	popa
CHAO_Quick_OK_Exit:
	clc
	ret

;
;   All failure cases exit here
;
CHAO_QEMM_Seg_Check_Failed:
CHAO_No_Stealth:
CHAO_No_QEMM:
	popa
	stc
	ret

EndProc Check_Hook_Addr_OK


IFNDEF SETUP


;******************************************************************************
;
;   Test_Disable_Switch
;
;   DESCRIPTION:
;	This procedure scans the parameters passed to Win386 for /d:F which
;	is a debug switch to disable "FastDisk".  It if is found then
;	WDCTRL will not load.
;
;   ENTRY:
;	None
;
;   EXIT:
;	If carry flag set then /D:F selected.  WDCTRL should not load.
;
;   USES:
;	Flags
;
;==============================================================================

BeginProc Test_Disable_Switch

	push	ds
	pusha

	mov	ah, 62h 			; Get current PSP
	int	21h
	mov	ds, bx				; ES -> Current PSP

    ;
    ; Get command-line debug option
    ;
    ; There are several forms for this:
    ;
    ;	  /d:s foo /d:p
    ;
    ; In this case, the first /d: is ours, the second isn't, the second
    ; is an argument to the app "foo". We detect the boundary (in this case
    ; the "foo") by detecting a character which is not a tab, space or '/'
    ; which is not part of a '/' arg. Thus:
    ;
    ;	  foo	 is a boundary
    ;	  /goooo is not a boundary
    ;	  /d:&	 is not a boundary and will be skipped, valid debug options
    ;		   are either 'A'-'Z' or 'a'-'z'
    ;

⌨️ 快捷键说明

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