📄 winsrch.asm
字号:
jz short DRexit ; N: finished
mov cs:[VGAROM],0BFFFh ; Y: include C000 ROM area
mov cs:[E000ROM],0E000h ; and exclude E000 ROM area
DRcheckE000:
;
; DO NOT ADD ANY CODE BETWEEN DRcheckE000 & DRexit
;
DRexit:
pop ds
ret
DefaultROM endp
;===============================================================================
;==
;== CheckToken: Checks for Token Ring card. Adapted from code by Helix.
;==
;== Enter:
;==
;== Exit:
;==
;===============================================================================
public CheckToken
CheckToken proc near
push si
push di
push es
cmp cs:[NoTR], TRUE ;Don't do it if disabled
je CT_exit
mov dx,0a20h ;load primary base i/o address
in al,dx ;get BIOS/MMIO address
cmp al,0ffh ;token ring adapter present ?
jne short gottr ;yes
mov dx,0a24h ;load alternate base i/o address
in al,dx ;get BIOS/MMIO address
cmp al,0ffh ;token ring adapter present ?
je short CT_exit ;no
gottr: and al,0fch ;mask off interrupt bits
shr al,1 ;shift to correct position
or al,80h ;mask on high bit
mov ah,al ;load ah with result
mov al,0 ;zero al
mov es,ax ;load es with rom address
mov si,1f00h ;point to adapter id area
mov cx,12 ;load id word length
chkid: lods word ptr es:[si] ;get id byte
and al,0fh ;mask off high nybble
xor al,0fh ;complement value
mov ah,es:[si+16h] ;get complement id byte
and ah,0fh ;mask off high nybble
cmp al,ah ;does complement id byte match ?
jne short CT_exit ;no
loop chkid ;iterate loop
push dx ;save port address
mov bx, es ;mark the 8k ROM space as INUSE
mov dl, INUSE
call SetFlag
inc bh ;2nd 4k page of ROM
call SetFlag
pop dx
test gs:[GenFlags], fMCA ; Q: MCA system
jnz CT_mca ; Y:
mov ah, es:[1E00h] ; N: get shared RAM addr on ISA
jmp short CT_len
CT_mca: ;get shared RAM address on MCA
inc dx ;add 2 to I/O address
inc dx
in al, dx ;get shifted RAM address
and al, 0FEh ;mask off low bit
mov ah, al
CT_len:
xor al, al ;ax = paragraph RAM address
xor ch, ch
mov cl, es:[1E01h] ;get shared RAM size
and cl, 0Ch ;(bits 2&3: 00=8k, 01=16k,
shr cl, 1 ; 10=32k, 11=64k)
shr cl, 1
inc cl
shl cl, 1 ;cx = RAM size in 4k pages
mov bx, ax ;mark the shared RAM space
mov dl, INUSE ; as INUSE
CT_set_ram:
call SetFlag
inc bh
loop CT_set_ram
CT_exit:
pop es
pop di
pop si
ret
CheckToken endp
ifdef E000
;===============================================================================
;==
;== CheckE000: Determines if E000h area is available by default. Adapted
;== from code by Helix.
;==
;== Enter:
;==
;== Exit:
;==
;===============================================================================
public CheckE000
CheckE000 proc near
; DefaultROM will have set E000ROM to 0E000h if this is not a Compaq
; system. This causes E000h-EFFFh to be excluded as ROM by default,
; but we want to be a little smarter than that. If we can identify
; and 'deshadow' a video bios in the E000h area, E000h is made available
; by default.
push ds
push es
assume ds:nothing, es:nothing
cmp cs:[Highscan], TRUE
jne CE_exit
mov ax,0e000h ; from Helix...
mov es,ax
cmp word ptr es:[0],0aa55h
jne short CE_exit
mov ch,es:[2]
mov cl,0
push ds
mov ax,0c000h
mov ds,ax
xor si,si
xor di,di
rep cmpsw
pop ds
jne short CE_exit
call deshadow_command
jc short CE_exit
; 'Deshadowed' the video rom, add first 32k of E000 as RAM. Why 32k?
; That's what Helix does!
movzx di, byte ptr cs:[HighSet]
add byte ptr cs:[HighSet], 4
mov word ptr cs:[HighSet][di], 0E000h ; from E000h
mov word ptr cs:[HighSet][di+2], 0E7FFh ; to E7FFh
CE_exit:
pop es
pop ds
ret
CheckE000 endp
public deshadow_command
deshadow_command proc near
push ax ;save work regs
push bx ;...
push cx ;...
push si ;...
push di ;...
push ds ;...
push es ;...
; scan interrupt vectors for those pointing to E000 area
xor ax,ax ;assume IDT at zero
mov es,ax ;...
xor di,di ;zero offset
deshadow_command_2:
mov ax,word ptr es:[di] ;get offset
shr ax,4 ;...
add ax,word ptr es:[di+2] ;add in segment to get abs. seg
jc short deshadow_command_4 ;overflow= bigger then ff
cmp ah,0e0h ;if not between e0
jb short deshadow_command_4
cmp ah,0e7h ;and e7
ja short deshadow_command_4 ; skip
; vector found pointing to E000 area
mov bx,di ;save offset of vector found
lds si,es:[di] ;point DS:SI at target area
mov ax,ds ;convert to C000 address
sub ax,2000h ;...
mov es,ax ;equivalent area of C000
mov di,si ;same offset
mov cx,100h ;check for 256 bytes the same
repe cmpsb ;compare two areas
jne short deshadow_command_error ;problems
; code in C000 seems to be the same as in the E000 area
xor ax,ax ;restore vector pointer
mov es,ax ;...
mov di,bx ;...
sub byte ptr es:[di+3],20h ;change E000 vector to C000
deshadow_command_4:
add di,4 ;step to next vector
cmp di,320h ;if more to check,
jb short deshadow_command_2 ;look at the next vector
; complete IDT scanned with no problem cases
pop es ;restore entry regs
pop ds ;...
pop di ;...
pop si ;...
pop cx ;...
pop bx ;...
pop ax ;...
clc ;clear carry for ok
ret ;& return
deshadow_command_error:
pop es ;restore entry regs
pop ds ;...
pop di ;...
pop si ;...
pop dx ;...
pop cx ;...
pop bx ;...
pop ax ;...
xor dx,dx
stc ;set carry for error
ret ;& return
deshadow_command endp
assume ds:_DATA
endif
;===============================================================================
;==
;== DefaultInclude: Determines if Include parameter is for RAM or EMS.
;==
;== Enter:
;== cs:IncSet[1] = RAM
;==
;== Exit:
;== cs:IncSet[1] = RAM or EMS
;==
;===============================================================================
DefaultInclude proc near
push ax
push bx
push si
push di
lea bx,cs:[RAMSet] ; assume RAM
xor si,si
cmp cs:[UMBset],TRUE ;Q: Was RAM specified?
je short DItran ; Y: RAM was implied
cmp gs:[NoEMSset],TRUE ;Q: Was NoEMS specified?
je short DItran ; Y: RAM was implied
cmp gs:[NoPFset],TRUE ;Q: Was FRAME=NONE specified?
je short DItran ; Y: RAM was implied
;
; No RAM parameters were specified, thus Include is taken as EMS windows.
;
lea bx,cs:[EMSSet] ; default is EMS
;
; Move Include ranges to either RAM or EMS ranges
;
DItran:
movzx di,byte ptr cs:[bx] ; get pointer into RAM/EMS set
mov ax,cs:[IncSet][2][si] ; get address from INCLUDE set
mov cs:[bx][di],ax ; save in RAM/EMS set
or ax,ax ;Q: Any more addresses?
jz short DIexit ; N: exit
add si,2 ; Y: increment to next address
add byte ptr cs:[bx],2
jmp short DItran ; get next address
DIexit:
pop di
pop si
pop bx
pop ax
ret
DefaultInclude endp
;===============================================================================
;==
;== ProcessRange: Process range array constructed by the parser and transfer
;== information to the [Page4K] array. The parser array has
;== the following structure:
;==
;== 0 [n*4+2|array flag]
;== 2 [ entry # 1 FROM ]
;== 4 [ entry # 1 TO ]
;== 6 [ entry # 2 FROM ]
;== 8 [ entry # 2 TO ]
;== : : : : : : :
;== n*4-2 [ entry # n FROM ]
;== n*4+2 [ entry # n TO ]
;==
;== Enter:
;== SI = address of parser range array to process.
;== Page4K[0..255] = Uninitialized with flag in parser array.
;==
;== Exit:
;== Page4K[0..255] = Initialized with this flag.
;==
;===============================================================================
ProcessRange proc near
push ax
push bx
push dx
push ds
mov ax,seg LAST
mov ds,ax
assume ds:LAST
mov dl,byte ptr [si+1] ; array flag (include,exclude,RAM,EMS,etc...)
add si,2 ; point ro first range
PRnext:
lodsw ; Get FROM
or ax,ax ;Q: Any more ranges?
jz short PRexit ; N: finished processing
mov bx,ax ; Y: BX has lower limit
call SetFlag ; set flag for FROM value
lodsw ; AX has upper limit
PRnextPage:
add bx,100h ; next 4K page
jc PRnext ; if overflow, goto next range
cmp bx,ax ;Q: Has upper limit been reached?
ja PRnext ; Y: Try next range (X=FROM-TO)
call SetFlag ; N: set flag for next 4K page
jmp short PRnextPage
PRexit:
pop ds
pop dx
pop bx
pop ax
ret
assume ds:_DATA
ProcessRange endp
;===============================================================================
;==
;== ExcludeRange: Exclude range in Page4K[] array.
;==
;== Enter:
;== AX = starting paragraph address
;== BX = ending paragraph address
;==
;== Exit:
;== Page4K[AX-BX] = EXCLUDE
;==
;===============================================================================
ExcludeRange proc near
push bx
push dx
mov dl,EXCLUDE
ERloop:
call SetFlag
sub bx,100h
cmp ax,bx ;Q: End of range?
jbe short ERloop ; N: continue excluding
pop dx
pop bx
ret
ExcludeRange endp
;===============================================================================
;==
;== SetFlag: Set proper flag in Page4K[] array.
;==
;== Enter:
;== DL = proper flag.
;== BX = index to Page4K[] array.
;==
;== Exit:
;== Page4K[BX] = DL
;==
;===============================================================================
SetFlag proc near
push bx
shr bx,8 ; paragraph to 4K page
and cs:[Page4K][bx],not INUSE ; no longer INUSE
or cs:[Page4K][bx],dl ; mark with current flag
pop bx
ret
SetFlag endp
;===============================================================================
;==
;== RangeOverlap: Checks Include/eXclude/RAM/EMS ranges for overlap. Exclude
;== has precedence over WIN, RAM or EMS. WIN has precedence
;== over RAM or EMS. RAM has precedence over EMS.
;==
;== Enter:
;== Page4K[] array completely filled out.
;==
;== Exit:
;== [msg_flag] = Overlap_MSG flag set if an overlap is detected.
;==
;===============================================================================
RangeOverlap proc near
push ecx
mov ecx,100h ; loop through 256 entries
ROPage4K:
test cs:[Page4K][ecx-1],EMS+RAM+ROM+WIN ;Q: EMS,RAM,ROM or WIN set?
jz short ROnextPage4K ; N: next 4K page
test cs:[Page4K][ecx-1],EXCLUDE ;Q: Is this page also excluded?
jz short RO4KWINpage ; N: try WIN
and cs:[Page4K][ecx-1],EXCLUDE ; Y: mark 4K page as excluded
jmp short ROmsg ; warn user with msg
RO4KWINpage:
test cs:[Page4K][ecx-1],EMS+RAM+ROM ;Q: EMS,RAM,or ROM set?
jz short ROnextPage4K ; N: next 4K page
test cs:[Page4K][ecx-1],WIN ;Q: Is this page also WIN?
jz short RO4KRAMpage ; N: try RAM
and cs:[Page4K][ecx-1],WIN ; Y: mark 4K page as WIN
;;; jmp short ROmsg ; warn user with msg
jmp short RONextPage4K ; no warning for WIN= overlap
; (MEMMAKER makes WIN= overlaps)
RO4KRAMpage:
test cs:[Page4K][ecx-1],RAM+ROM ;Q: Is RAM or ROM set?
jz short ROnextPage4K ; N: EMS only, next 4K page
btr cs:[Page4K][ecx-1],EMSbit ;Q: Is RAM/ROM and EMS set?
jnc short ROnextPage4K ; N: RAM only, next 4K page
ROmsg:
or gs:[msg_flag],Overlap_MSG ; range overlap message
ROnextPage4K:
loop ROPage4K
pop ecx
ret
RangeOverlap endp
;===============================================================================
;==
;== GetPageFrame: Given the user has not selected a page frame base address,
;== this routine will find an available 64K area.
;==
;== Enter:
;== Page4K[] array completely filled out.
;==
;== Exit:
;== [PF_Base] = page frame base address
;==
;===============================================================================
GetPageFrame proc near
;
; Check to see if the base address of the page frame needs to be selected
;
cmp gs:[NoEMSset],TRUE ;Q: Has NoEMS switch been used?
je short GPFexit ; Y: don't select one.
cmp gs:[NoPFset],TRUE ;Q: Has FRAME=NONE switch been used?
je short GPFexit ; Y: don't select one.
cmp gs:[PF_Base],FREE ;Q: Has page frame been selected?
jne short GPFexit ; Y: don't reselect one.
test cs:[PnSet],P0+P1+P2+P3 ;Q: XMA2EMS mode selected?
jnz short GPFexit ; Y: don't select page frame
;
; Check default page frame address of E000h for a conflict
;
mov ax,0E000h ; default page frame address
call CheckPageFrame ; check for a page frame
or bx,bx ;Q: Conflict?
jz short GPFfound ; N: found page frame
;
; Check area from 8000h to F000h for page frame with no conflict.
;
mov dx,[end_of_base_memory_PTE] ; get lowest PTE candidate
shl dx,8 ; paragraph address
mov ax,0F000h ; highest page frame possible
cmp dx,8000h ;Q: Above 512K?
jae short GPFfind ; Y: continue
mov dx,8000h ; N: lowest possible page frame address
GPFfind:
call CheckPageFrame ; check [AX] for a page frame
or bx,bx ;Q: Conflict?
jz short GPFfound ; N: found page frame
sub ax,400h ; Y: try 16K lower
cmp ax,dx ;Q: Valid page frame address?
jae short GPFfind ; Y: try this address range
mov ax,FREE ; N: no page frame address found
GPFfound:
mov gs:[PF_Base],ax ; save page frame address
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -