📄 winsrch.asm
字号:
.386p
page 58,132
;=============================================================================
title W I N S R C H - searches for EMS and UMB windows
;=============================================================================
;==
;== (C) Copyright MICROSOFT Corp. 1990-1991
;== (C) Copyright COMPAQ Computer Corp. 1990-1991
;==
;== Title: EMM386.EXE - MICROSOFT Expanded Memory Manager 386 Driver
;==
;== Module: WinSrch - searches for EMS and UMB windows
;==
;== Version: 1.00
;==
;== Date: July 9,1990
;==
;== Author: Leo Cohen
;== (some routines extracted from ROM_SRCH.ASM: Daniel J. Mazina,
;== Richard D. Vail,
;== & Patrick Wu)
;==
;=============================================================================
;==
;== Change Log:
;==
;== DATE REVISION Description
;== -------- -------- --------------------------------------------
;== 07/09/90 0.00 Original (* routines from ROM_SRCH.ASM)
;==
;== 01/18/91 M002 use xchg instead of move to write into
;== adapter space for ram determination.
;==
;== 01/30/91 M004 When trying to reclaim shadow ROM in routine
;== CheckForCompaqROM, check to make sure that
;== the offset of the int 10 vector lies within
;== ROM length as specifed in the ROM header.
;==
;=============================================================================
;==
;== Functional Description:
;==
;== This module determines the areas which will be used by CEMM. These
;== areas include: page frame, other EMS windows above base memory, UMB
;== windows, and EMS base memory windows. It analyzes the user parameters
;== and detects ROM and RAM areas to best determine these EMS/UMB windows.
;==
;==
;=============================================================================
;== P U B L I C D E C L A R A T I O N S
;=============================================================================
public Page4K
public UMBtable
public NumOfUMBwindows
public FindWindowLocations
public ROMcheck
public RAMcheck
ifdef ROMCOMP
public ROMstart
endif
public CPQvideoROM
public DefaultROM
public DefaultInclude
public ProcessRange
public ExcludeRange
public RangeOverlap
public SetFlag
public GetPageFrame
public SetPageFrame
public EMSwindows
public UMBwindows
public BaseEMSwindows
public CheckEMSwindow
public CheckPageFrame
public CheckForROMHeader
public CheckForCompaqROM
public UpdatePageArray
public PFB_warning
public IsCompaq
;=============================================================================
;== E X T E R N A L D E C L A R A T I O N S
;=============================================================================
LAST segment
ifdef ROMCOMP
extrn UnProtectROM:near
extrn ProtectROM:near
extrn FixROMptrs:near
endif
extrn Pn:byte
extrn PnSet:word
extrn eXcSet:word
extrn IncSet:word
extrn DfltSet:word
extrn RAMSet:word
extrn ROMSet:word
extrn EMSSet:word
extrn WINset:word
extrn HighSet:word
extrn VGAROM:word
extrn E000ROM:word
extrn ROMparm:byte
extrn pCOMPAQ:dword
extrn szCOMPAQ:byte
extrn UMBset:byte
extrn PS2DATA:byte
extrn Highscan:byte
extrn NoTR:byte
extrn RangeSets:byte
extrn RangeSave:byte
extrn RANGESIZE:abs
extrn HRAMSet:word
extrn BRAMSet:word
extrn ToshSet:word
extrn TOSHbeg:word
extrn TOSHend:word
extrn toshiba_machine:byte
LAST ends
_DATA segment
extrn ROMID:byte
_DATA ends
;=============================================================================
;== L O C A L C O N S T A N T S
;=============================================================================
include vdmseg.inc
include emm386.inc
include romstruc.equ
include emmfunct.inc
include emmdata.inc
include ps2ex.inc
include ps2equ.inc
include eisaex.inc
;=============================================================================
;== For ROM, RAM, and CPQ Video ROM search
;=============================================================================
FIRST_ROM_SEGMENT = 01000H ; Segment address of first option ROM.
LAST_ROM_SEGMENT = 0DF80H ; Segment address of last option ROM.*A
FIRST_RAM_SEGMENT = 01000H ; Seg address of 1st possible RAM addr
;910520 LAST_RAM_SEGMENT= 0DF80H ; Seg addr of last possible RAM addr
LAST_RAM_SEGMENT = 0EF80H ; Seg addr of last possible RAM addr 910520
REMAP_VIDEO_ROM_SEGMENT = 0E000H ; Seg address of optional sys rom
ROM_SIGNATURE = 0AA55h
NEXT_ROM_SEG = 080H ; 2K seg increment to next ROM location
ROUND_BY_2K_SEG = 0FF80h ; rounding factor for 2k seg addresses
SIZE_OF_16K_PAGE = 0400h ; length of a EMS page in paragraphs
;=============================================================================
;== For XMA2EMS mode
;=============================================================================
P0 EQU 1
P1 EQU 1 SHL 1
P2 EQU 1 SHL 2
P3 EQU 1 SHL 3
P254 EQU 1 SHL 4
P255 EQU 1 SHL 5
;=============================================================================
;== C O D E S E G M E N T
;=============================================================================
LAST segment
assume cs:LAST,ds:_DATA,gs:R_CODE
;=============================================================================
;== L O C A L D A T A
;=============================================================================
; Data items between ZeroInitData and ZeroInitSize are set to zero (suprise)
; when FindWindowsLocations is called since it may be called more than once.
ZeroInitData label byte
PFB_warning dw 0
Page4K db 256 dup (0)
NumOfUMBwindows db 0
UMBtable db 128 dup (0)
ZEROINITSIZE equ $-ZeroInitData
LastChanceBuf db 4*1024 dup(0)
SetTable label word
dw offset LAST:DfltSet
dw offset LAST:HRAMSet
dw offset LAST:BRAMSet
dw offset LAST:ToshSet
dw offset LAST:eXcSet
dw offset LAST:RAMSet
dw offset LAST:ROMSet
dw offset LAST:EMSSet
dw offset LAST:WINset
NumberOfSets equ ($-SetTable)/2
Pass db -1
EISAdata db (size GSI_data) dup (?)
ifdef ROMCOMP
ROM64k db 'DEP'
Num64kROMs equ $-ROM64k
ROM40k db 'BHL'
Num40kROMs equ $-ROM40k
ROM32k db 'FG'
Num32kROMs equ $-ROM32k
ROMstart dw 0
endif
ROMChangeCount equ 20
;===============================================================================
;==
;== FindWindowLocations: This routine creates an array of 256 entries. Each
;== entry represents a 4K page in the first megabyte.
;== After searching the option ROM area, it marks any
;== entry which included ROM or RAM appropriately. Then
;== it takes the user defined ranges from the command line
;== and merges this information into this array. This
;== array is then analyzed to create the UMB and EMS
;== windows necessary for operation.
;==
;== Entry
;== cs:PF_windows[] = table of possible page frame addresses.
;== cs:DefltSet[] = array of default unused areas.
;== cs:eXcSet[] = array of user specified areas to exclude.
;== cs:IncSet[] = array of user specified areas to include.
;== cs:RAMSet[] = array of user specified areas to include RAM.
;== cs:EMSet[] = array of user specified areas to include EMS.
;== CS = LAST segment
;== DS = _DATA segment
;== GS = R_CODE segment
;==
;== Exit
;== ds:EMS_window[] = initialized
;== ds:EMS_window_locations[] = initialized
;== ds:EMSsegLoc[] = initialized
;== ds:[number_EMS_windows] = initialized
;== ds:UMBtable[] = initialized
;== ds:[XMA2EMS] = initialized
;== gs:[PF_Base] = initialized
;==
;===============================================================================
FindWindowLocations proc near
pushad
cld
; This routine may be called more than once, so after the first pass
; some data must be reinitialized.
push cs
pop es
inc Pass ; Q: 1st time?
jnz short FWLagain ; N:
mov cx, RANGESIZE ; 1st time, save inital state
mov si, offset LAST:RangeSets ; of the ranges so they can
mov di, offset LAST:RangeSave ; be reused next time.
rep movs byte ptr es:[di], es:[si]
jmp short FWLcont
FWLagain:
xor ax, ax ; 2nd time, zero initialize
mov cx, ZEROINITSIZE ; some data
mov di, offset LAST:ZeroInitData
rep stosb
mov cx, RANGESIZE ; and restore the saved ranges
mov si, offset LAST:RangeSave
mov di, offset LAST:RangeSets
rep movs byte ptr es:[di], es:[si]
FWLcont:
;
; Get first 16K multiple PTE entry after base memory. Used for base EMS windows.
;
int 12h
shr ax,2 ; 4K page
add ax,3 ; round up
and ax,0FFFCh ; multiple of 4K
mov [end_of_base_memory_PTE],ax
;
; Determine default memory areas not to use for EMS/UMB windows.
;
call DefaultROM
; Check for Token Ring card
call CheckToken
; Check Toshiba special exclude areas
call Toshiba_exclude
ifdef E000
; Determine if can 'deshadow' video ROM at E000h
test gs:[GenFlags], fMCA ; Q: MCA
jnz short FWLskipE000 ; Y: E000 is other ROM
call CheckE000
FWLskipE000:
endif
;
; Check if Include ranges are for RAM or EMS: if no RAM switches, then EMS
;
call DefaultInclude
;
; If this is an MCA machine we'll do the detection of adapters using the
; POS bytes.
;
ifdef ROMIDMCA
xor ax, ax ; Assume that POS did not work
cmp [ROMID],ROMIDPS2 ; Q: Is it a PS2
jne short FWLromscan ; N: do rom scan
endif
test gs:[GenFlags], fMCA ; Q: MCA
jz short FWLchkEISA ; N: check if EISA
; Y: do POS detection
call ExcludePS2Options
jmp short FWLromscan
FWLchkEISA:
test gs:[GenFlags], fEISA ; Q: EISA
jz FWLromscan ; N: do rom scan
call ExcludeEISAOptions
;
; Detect Option ROMs
;
FWLromscan:
call ROMcheck
;
; Detect Compaq VIDEO ROM
;
call CPQVideoROM
;
; Check if ROM can be mapped over by RAM
;
ifdef ROMCOMP
call CPQROMcheck
endif
call ROMcompress
;ifndef IBMCOPYRIGHT
; IBM version doesn't do this because their QBASIC uses ROM Basic
call ROMbasic
;endif
;
; Process Default, Exclude, Include, RAM, and EMS range arrays (sets)
;
xor bx,bx
mov cx,NumberOfSets ; number of range arrays
FWLsetLoop:
mov si,cs:[SetTable][bx] ; get array address
call ProcessRange
add bx,2
loop FWLsetLoop
;
; Detect Option RAM
;
call RAMcheck
;
; Mark HighScan regions as available
;
lea si, cs:[HighSet]
call ProcessRange
;
; We now try to scan again using Ralph's algo
;
push edx
mov edx, 0c0h ; start c0h
FWLscanagn:
call LastChanceScan
inc edx
cmp edx, 0f0h ; until efh
jb short FWLscanagn
pop edx
;
; Make sure there are no overlaps in the ranges: Exclude takes precedence.
;
call RangeOverlap
; On a Toshiba system, don't allow the user to put the EMS page frame over
; reserved upper memory.
call ToshInvPFbase
;
; Now the EMS/UMB windows are selected: First get a page frame address
;
call GetPageFrame
;
; Set up the page frame
;
call SetPageFrame
;
; Set up EMS windows in the 640K to 1MB region
;
call EMSwindows
;
; Set up UMB windows in the 640K to 1MB region
;
call UMBwindows
;
; Set up base EMS windows
;
call BaseEMSwindows
popad
ret
FindWindowLocations endp
;===============================================================================
;==
;== ROMcheck: Detect Option ROMs.
;== This section of code searches the auxiliary rom area
;== (from C0000 up to E0000) in 2K increments. A ROM checksum is
;== calculated to insure that the ROMs are valid. Valid ROMs must
;== have the 1st byte = 55H and the next byte = 0AAH. The next
;== byte indicates the size of the ROM in 512-byte blocks. The
;== sum of all bytes in the ROM, modulo 256, must be zero.
;==
;== If a ROM is not found at a location, the next location 2K-bytes
;== down is examined. However, if it is found, the next location
;== after this ROM is tried. The next ROM location is determine
;== according to the size of the previous ROM.
;==
;== Enter:
;== Page4K[BX] = uninitialzed with detected ROM locations.
;==
;== Exit:
;== Page4K[BX] = initialzed with detected ROM locations.
;==
;===============================================================================
ROMcheck proc near
push ax
;
; Memory above 640k is searched for any VIDEO or option ROMs located there.
;
;QLEO mov ax,FIRST_ROM_SEGMENT
mov ax,[end_of_base_memory_PTE]
shl ax,8
RcNextROMlocation:
call CheckForROMHeader
ifndef MSFLAG
jc short RcROMDetected
sub ax,NEXT_ROM_SEG
call CheckPrechargeBus
endif
jnc short RcLast
RcROMDetected:
call UpdatePageArray
RcLast:
cmp ax,LAST_ROM_SEGMENT
jbe short RcNextROMlocation
pop ax
ret
ROMcheck endp
;===============================================================================
;==
;== RAMcheck: Detect RAM mapped in the Option ROM space.
;==
;== Enter:
;== Page4K[BX] = uninitialzed with detected RAM locations.
;==
;== Exit:
;== Page4K[BX] = initialzed with detected RAM locations. (Unusable)
;==
;===============================================================================
RAMcheck proc near
push ax
;
; ROM area is checked to insure no common RAM is mapped in the option space.
;
;QLEO mov ax,FIRST_RAM_SEGMENT
mov ax,[end_of_base_memory_PTE]
shl ax,8
RAcNextRAMlocation:
call CheckForMappedRAM
jnc short RAcLast
call UpdatePageArray
RAcLast:
cmp ax,LAST_RAM_SEGMENT
jbe short RAcNextRAMlocation
pop ax
ret
RAMcheck endp
;===============================================================================
;==
;== CPQVideoROM: Detect Compaq Video ROM.
;==
;== Enter:
;== Page4K[BX] = uninitialized for E000h segment.
;==
;== Exit:
;== Page4K[BX] = E000h segment is either usable or INUSE.
;==
;===============================================================================
CPQVideoROM proc near
push ax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -