📄 winsrch.asm
字号:
; Check for precharge of high
;
CPBcheckFF:
cmp dword ptr ds:[4],-1
jne short CPBROMdetected
cmp dword ptr ds:[8],-1
jne short CPBROMdetected
cmp dword ptr ds:[12],-1
je short CPBFloatingBus
;
; ROM detected
;
CPBROMdetected:
stc
jmp short CPBexit
;
; Floating Bus was detected (no ROM)
;
CPBFloatingBus:
clc
CPBexit:
pop ds
ret
CheckPrechargeBus endp
endif
;******************************************************************************
; CheckForROMHeader
;
; ENTRY
; AX = Segment address of ROM.
; EXIT
; CY = Found a VDU ROM at this location.
; NC = Did not find a valid ROM at this location.
; AX = Segment address of NEXT ROM location.
; DX = Length of this ROM in paragraphs
;
; DESCRIPTION
; This routine looks at the ROM located at the segment address
; specified in AX to see if 0TH and 1ST Bytes = 0AA55H.
; If so, it calculates the checksum over the length of
; ROM. If the checksum is valid it updates AX to point
; to the location of the next ROM.
;
; For option ROMs, the layout of each valid ROM is as follows:
;
; OFFSET +-----------------------+
; 0 | 55h |
; +-----------------------+
; 1 | AAh |
; +-----------------------+
; 2 | ROM size / 512 |
; +-----------------------+
; 3 | Start of init code |
; :
; n-1 | |
; +-----------------------+
; (Sum of all bytes MOD 100h is 00h.)
;
;******************************************************************************
CheckForROMHeader proc near
push ds
; The ROM segment address is loaded into DS and the memory
; is tested to see if the ROM signature is there.
mov ds,ax
xor bx,bx
cmp [bx].ROM_RECOGNITION,ROM_SIGNATURE
jne SHORT CFR_no_ROM_found
; If a ROM signature is there than compute the ROM's checksum.
; The size of the ROM is stored as the number of 512 bytes
; blocks. It is loaded into CX as the number of bytes.
xor esi,esi
xor ecx,ecx
mov ch,[bx].ROM_LEN
shl ecx,1
or ecx,ecx ;Q: 128K ROM?
jnz SHORT CFRcont ; N: continue
mov ecx,20000h ; Y: 128K ROM
CFRcont:
mov edx,ecx
; Each byte is loaded from the ROM area and added to the
; checksum in BL. At the end of the loop the value in BL
; should be zero. If not than this isn't a ROM.
CFR_next_byte:
lodsb
add bl,al
dec ecx
jnz short CFR_next_byte
or bl,bl ;Q: Is this a ROM?
jnz short CFR_no_ROM_found ; N: ROM not found
; If this is reached then the address reflects a ROM. The
; size of the ROM in DX is in bytes and is converted into
; the number of paragraphs.
; The original ROM address in DS is loaded into AX and
; incremented to point to the next possible ROM segment.
shr edx,4
mov ax,ds
add dx,NEXT_ROM_SEG - 1 ;increment to next
and dx,ROUND_BY_2K_SEG ;truncate to 2K boundary
add ax,dx
stc
jmp SHORT CFR_return_code
; If this is not a ROM then the next possible address
; is changed into a paragraph count.
; The original ROM address in DS is loaded into AX and
; incremented to point to the next possible ROM segment.
CFR_no_ROM_found:
mov dx,NEXT_ROM_SEG
mov ax,ds
add ax,dx
clc
CFR_return_code:
pop ds
ret
CheckForROMHeader endp
;******************************************************************************
; CheckForCompaqROM
;
; ENTRY
; none
; EXIT
; CY - If set then the area is not Compaq's VIDEO ROM and can not be used.
; But, it must be removed from the window map
; - AX = next ROM segment
; - DX = ROM length in paragraphs
; DESCRIPTION
;
;******************************************************************************
CheckForCompaqROM proc near
; The entrance registers are saved.
push ds
push es
ifdef E000
; Can't be Compaq's ROM if not a Compaq system
call IsCompaq
jnz short CFCR_not_Compaqs_ROM
endif
; The data in the ROM area is compared to the data at
; the default VIDEO rom area.
; DS:SI is the default location for COMPAQ's VIDEO ROM.
push 0C000h
pop ds
xor esi,esi
; ES:DI is the ROM location to verfify
push REMAP_VIDEO_ROM_SEGMENT
pop es
xor di,di
; The data in the two ROM areas are now checked to see if they
; are the same. DX is the ROM length in paragraphs.
mov cx,dx
shl cx,2
repe cmpsd
jne short CFCR_not_Compaqs_ROM
; If the ROM data matches then now the VIDEO ROM location
; interrupt vector is checked to see if it was remapped.
xor esi,esi
mov ds,si
ASSUME DS:ABS0
cmp [int10+2],REMAP_VIDEO_ROM_SEGMENT
jne short CFCR_not_Compaqs_ROM
; No one has hooked the int 10 vector. Now check to make
; sure the offset of the int 10 vector lies within the ROM
; length specifed in the header. This is an attempt to
; prevent us from reclaiming the shadow on ROMs that do not
; specify their length correctly.
;
mov cx, dx ; dx has length in paras
shl cx, 4 ; cx has length in bytes
cmp cx, [int10] ; Q: is the ROM lentgh <= the offset of int10
jbe short CFCR_not_Compaqs_ROM
; Y: do not recalim shadow
; If this is reached then the ROM appears to be Compaq's
; VIDEO ROM remapped so set the appropriate state.
push R_CODE
pop ds
assume ds:R_CODE
or [Current_State],fState_CEGAinst
mov [CROM_Length],dx
clc
jmp SHORT CFCR_return_code
CFCR_not_Compaqs_ROM:
stc
CFCR_return_code:
pop es
pop ds
ASSUME ds:_DATA
ret
CheckForCompaqROM endp
;******************************************************************************
; CheckForMappedRAM
;
; ENTRY
; AX = Segment address for RAM search.
; EXIT
; CY = Found RAM at this location.
; NC = Did not find RAM at this location.
; AX = Segment address of next RAM location.
; DX = Length of this RAM
;
; DESCRIPTION
; This routine looks at the address range potentially used
; by the Page Frame to determine if any RAM is in the way.
; It updates the map accordingly.
;******************************************************************************
CheckForMappedRAM proc near
push cx
push ds
pushf
cli ;;; clear ints during this test
; search for RAM
;
xor dx,dx ; length = 0
ram_loop:
mov ds,ax
add ax,NEXT_ROM_SEG ; prepare for next chunk
;
; Do not search if the area has been eXcluded/Included/EMS/RAM/ROM by the user
;
mov bx,ds
shr bx,8 ; index into 4K page
cmp cs:[Page4K][bx],0 ;Q: Did user specify this page excluded/EMS/RAM?
jnz short no_more_ram ; Y: don't feel for RAM!
; M002 - Start
;;; mov bx,ds:0A0H ; get current word
;;; push bx ; save it
;;; mov cx,ds:0A2H ; get following word
;;; push cx ; save it
;;; not bx
mov bx, ds:0A2H ; save word at ds:A2H
mov cx, ds:0A0H
;
; Let us ensure that the value we're going to write out to the bus
; is not going to contain FCH as we're going to preset the bus to
; 0FCH before reading it back.
;
cmp cx, 0303h ; Q: is neg cx = FCFCH
jne @f ; N: fine
inc cx ; Y: change cx to some other value
@@:
not cx ; neg word at ds:A0H
push cx ; save it for future comparison
xchg ds:0A0H, cx ; write this negated word to ds:A0
; and save ds:A0h in cx
;;; mov word ptr ds:0A0H,bx ; try to clear word
; M002 - End
mov word ptr ds:0A2H,0FFFFh ; charge up data bus
;
; the instructions following and preceeding the xchg... below
; are carefully chosen to not contain the value in cx as part of the
; instruction.
;
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
;;; mov cx,DS:0A0H ; M002
xchg ds:0A0H, cx ; M002: restore word at ds:A0H and get
; M002: current value in cx
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
cld ;;; preset the bus to 0FCh
; M002 - Start
mov ds:0A2H,bx ; restore to it's original value
pop bx ; get value that was written to
; ds:A0h in bx
cmp bx, cx ; Q: was it really written out
jne short no_more_ram ; N: leave
;;; cmp bx,cx ;Q: RAM here ?
;;; pop bx ; restore following word
;;; mov ds:0A2H,bx ; to it's original value
;;; pop bx ; restore test word
;;; mov ds:0A0H,bx ; to it's original value
;;; jne short no_more_ram ; N: leave
; M002 - End
; Y: RAM - keep looking
add dx,NEXT_ROM_SEG ; increment length count
cmp ax,LAST_RAM_SEGMENT ;Q: last RAM location ?
jbe short ram_loop ; N: continue searching
mov ds,ax ; Y: no more searching
no_more_ram:
;
mov ax,ds ; get current segment
or dx,dx ;Q: any RAM found ?
jnz short ram_found ; Y: set RAM found & chk DS seg again
; N:
add ax,NEXT_ROM_SEG ; AX -> next one to check
popf
clc ; set no RAM
jmp short ram_exit ; and leave
;
ram_found:
popf
stc
ram_exit:
pop ds
pop cx
ASSUME ds:_DATA
ret
CheckForMappedRAM endp
;---------------------------------------------------------------------------
;
; ExcludePS2Options - Find PS/2 Option addresses
;
; ExcludePS2Options(EXPS2PDevTab,EXPS2PIFile)
;
; ENTRY:
; Know we are on a PS/2 system
;
; EXIT:
; AX == 0
; ERROR (usually INVALID POSCardTable (bad TabelRev))
;
; AX != 0
;
; USES: EAX,ECX,EDX
;
; NOTE: Ported from win386 3.0 sources.
;
;----------------------------------------------------------------------------
ExcludePS2Options proc near
enter 8,0
EXPS2TotOptions equ dword ptr [ebp-4]
EXPS2Flags equ dword ptr [ebp-8]
EXPS2F_FndOpt equ 00000000000000000000000000000001b
EXPS2F_FndOptBit equ 0
push ds
push esi
push edi
push ebx
mov ax, cs
mov ds, ax
lea esi, PS2DATA ; ds:esi -> PS2DATA
xor eax,eax
mov EXPS2Flags,eax
cld
lodsw ; Get TotalOptions
.erre TotalOptions EQ 0
mov EXPS2TotOptions, eax
lodsw ; Get table revision
.erre TabelRev EQ 2
cmp ax,CUR_PS2_TABLE_REV
jne Bad_Rev
xor eax, eax ; Card number
Card_Loop:
push eax
or al, ADAPTER_ENB
cli
out ADAPTER_POS, al ; Enable Card
jmp $+2
jmp $+2
mov edx, ID_ADDR_LO ; Get Card ID
in al, dx
jmp $+2
jmp $+2
mov ah, al
inc edx
in al, dx
xchg ah, al ; ID now in ax
btr EXPS2Flags,EXPS2F_FndOptBit
mov ecx, EXPS2TotOptions
push esi ; Save ptr to Option Tables
Option_Loop:
cmp ax, [esi.OptID] ; This card?
je short Found_Option
Continue_Scan:
movzx ebx, [esi.LookupCnt] ; # Entries in table to skip
lea esi, [esi.LookupTab] ; Point to table
shl ebx, 1 ; Two bytes per entry
.erre (SIZE MemAddr) EQ 2
add esi, ebx ; Skip the table
loop Option_Loop
IFDEF DEBUG
cmp ax,0FFFFh
je short No_Adap
or ax,ax
jz short No_Adap
bt EXPS2Flags,EXPS2F_FndOptBit
jc short No_Adap
;; trace_out "No entry in WIN386.PS2 for adapter #AX found in slot # ",NO_EOL
pop esi
pop eax
push eax
push esi
inc eax
;; trace_out "#AX"
No_Adap:
ENDIF
End_Option_Loop:
pop esi
mov al, ADAPTER_DSB
out ADAPTER_POS, al ; Disable setup
sti
pop eax ; Card number
inc eax
cmp eax, MAX_CARDS ; Done all cards?
jb short Card_Loop ; On to the next one
jmp OK_exit
Found_Option:
bts EXPS2Flags,EXPS2F_FndOptBit
push eax
push ecx
push esi
add esi, 2 ; Toss ID word
.erre OptID EQ 0
.erre POS2Mask EQ (OptID + 2)
mov edi, 4 ; Number of POS bytes
mov edx, ID_ADDR+2 ; First POS byte
xor ebx, ebx ; Table index
POS_Loop:
xor eax,eax
cld
lodsw ; Get mask and count
.erre POS2Shft EQ (POS2Mask + 1)
.erre POS3Shft EQ (POS3Mask + 1)
.erre POS4Shft EQ (POS4Mask + 1)
.erre POS5Shft EQ (POS5Mask + 1)
mov ecx, eax
xchg ch, cl ; cl gets shift count
or ah, al
jz short Ignore_Byte ; Stuff this one
in al, dx ; Get POS byte
and al, ch ; Mask it
ror al, cl ; Shift it
or bl, al ; Or into index
Ignore_Byte:
inc edx ; Next POS byte
dec edi
jnz short POS_Loop
cld
xor eax,eax
lodsw ; # entries in table
.erre LookUpCnt EQ (POS5Shft + 1)
.erre LookUpTab EQ (LookUpCnt + 2)
cmp ebx, eax ; Index in range?
jae short ContinueJ ; No, ignore
shl ebx, 1 ; Offset in table
.erre (SIZE MemAddr) EQ 2
movzx eax, word ptr [esi+ebx] ; Get entry
.erre PGLen EQ (StartPg + 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -