NT4/private/ntos/boot/detect/i386/hwmacha.asm
2020-09-30 17:12:29 +02:00

1347 lines
36 KiB
NASM
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

title "Machine Id detection"
;++
;
; Copyright (c) 1989 Microsoft Corporation
;
; Module Name:
;
; machine.asm
;
; Abstract:
;
; This module implements the assembley code necessary to detect
; certain special machines.
;
; Author:
;
; Shie-Lin Tzong (shielint) 28-Oct-1991.
; Most of the code is extracted from Win 3.1 setup program.
;
; Environment:
;
; 80x86 Real Mode.
;
; Revision History:
;
;
;--
.386
extrn _HwBusType: WORD
;
; Machine detection: Test ID equates (different tests must have different
; ID's, all tests in CompTypeTable must be given one of
; the following labels)
;
INT15_C0 equ 1
STR_CMP equ 2
STR_ICMP equ 3
NEC_PS_TEST equ 4
AST_TEST equ 5
;
; STANDARD ROM BIOS MACHINE TYPES used in ROM_BIOS_Machine_ID
;
IBM_PCAT equ 0FCh
IBM_PCAT_SUB1 equ 000h
IBM_PCAT_SUB2 equ 001h
IBM_PS2_50_SUB equ 004h
IBM_PS2_60_SUB equ 005h
IBM_PS2_30 equ 0FAh
IBM_PS2_80 equ 0F8h
IBM_PS2_30_SUB equ 000h
IBM_PS2_80_SUB equ 000h
IBM_PS2_80_SUB2 equ 001h
IBM_PS2_25 equ 0FAh
IBM_PS2_25_SUB equ 001h
IBM_PS2_70 equ 0f8h
IBM_PS2_70_SUB equ 004h
IBM_PS2_70_SUB2 equ 009h
IBM_PS2_70_SUBP equ 00Bh
IBM_PS2_L40SX_M equ 0F8h
IBM_PS2_L40SX_SM equ 023h
;
; IBM ThinkPad 750 and PS2 E model and submodel byte
; We need to identify these two machine because of their weird FDC
;
IBM_THINKPAD_750_MODEL equ 0F8h
IBM_THINKPAD_750_SUBMODEL_L equ 061h
IBM_THINKPAD_750_SUBMODEL_H equ 067h
IBM_THINKPAD_750_SUBMODEL1 equ 0A9h
IBM_PS2_E_MODEL equ 024F8h
;
; Special equates
;
AST_STR_LEN equ 12
;
; CMOS related definitions and macros
;
CMOS_CONTROL_PORT EQU 70h ; command port for cmos
CMOS_DATA_PORT EQU 71h ; cmos data port
;
; CMOS_READ
;
; Description: This macro read a byte from the CMOS register specified
; in (AL).
;
; Parameter: (AL) = address/register to read
; Return: (AL) = data
;
CMOS_READ MACRO
OUT CMOS_CONTROL_PORT,al ; ADDRESS LOCATION AND DISABLE NMI
jmp $ + 2 ; I/O DELAY
IN AL,CMOS_DATA_PORT ; READ IN REQUESTED CMOS DATA
jmp $ + 2 ; I/O DELAY
ENDM
;
; CMOS_WRITE
;
; Description: This macro read a byte from the CMOS register specified
; in (AL).
;
; Parameter: (AL) = address/register to read
; (AH) = data to be written
;
; Return: None
;
CMOS_WRITE MACRO
OUT CMOS_CONTROL_PORT,al ; ADDRESS LOCATION AND DISABLE NMI
jmp $ + 2 ; I/O DELAY
MOV AL,AH ; (AL) = DATA
OUT CMOS_DATA_PORT,AL ; PLACE IN REQUESTED CMOS LOCATION
jmp $ + 2 ; I/O DELAY
ENDM
;
; BCD_TO_BIN
;
; Description: Convert BCD value to binary
;
; Parameter:
; Input: (AL) = 2 digit BCD number to convert
; Output: (AX) = Binary equivalent (all in AL)
;
; Return: None.
;
BCD_TO_BIN macro
xor ah,ah
rol ax,4
ror al,4
aad
ENDM
_DATA SEGMENT PARA USE16 PUBLIC 'DATA'
HP_PC db 'HP VECTRA',0
ATT_PC db 'AT&T',0
IBMPS2_70P db 'IBM PS2 P70',0
IBMPS2_L40SX db 'IBM PS2 L40SX',0
IBM_PS2_E db 'IBM PS2E', 0
IBM_THINKPAD_750 db 'IBM THINKPAD 750',0
NEC_PROSPEED db 'NEC PROSPEED',0
ZENITH_386 db 'ZENITH',0
EVEREX_386_25 db 'EVEREX',0
NCR_386SX db 'NCR',0
NEC_PM_SX_PLUS db 'NEC POWERMATE SX PLUS',0
AST_386_486 db 'AST',0
TOSHIBA_1200XE db 'TOSHIBA T1200XE',0
TOSHIBA_1600 db 'TOSHIBA T1600',0
TOSHIBA_5200 db 'TOSHIBA T5200',0
ATT_NSX20 db 'AT&T NSX/20',0
DEC_PC db 'DECPC',0
DEC_PC_LENGTH equ $ - DEC_PC
AST_STRING db 'AST RESEARCH'
AT_COMPATIBLE db 'AT/AT COMPATIBLE',0
PS2_COMPATIBLE db 'PS2/PS2 COMPATIBLE',0
PS1_COMPATIBLE db 'PS1/PS1 COMPATIBLE',0
NEC_VERSA db 'NEC VERSA/COMPATIBLE', 0
;
;***************************************************************************
;
; TEST INSTRUCTION TABLE
;
; Table for Machine Detection. This table lists the tests to detect
; problem (non-standard) machines.
;
;***************************************************************************
;
;
; The tests need not be performed in the order of there ID's, the only
; restriction is that the DEFAULT_MACHINE ID be last in this list.
;
public CompTypeTable
CompTypeTable dw offset HP_PC
dw offset HP_Vectra_Test
dw offset ATT_PC
dw offset ATT_PC_Test
dw offset IBMPS2_70P
dw offset IBMPS2_70P_Test
dw offset IBMPS2_L40SX
dw offset IBMPS2_L40SX_Test
dw offset NEC_PROSPEED
dw offset NEC_Prospeed_Test
dw offset ZENITH_386
dw offset Zenith_386_Test
dw offset EVEREX_386_25
dw offset Everex_386_25_Test
dw offset NCR_386SX
dw offset NCR_386SX_Test
dw offset NEC_PM_SX_PLUS
dw offset NEC_PM_SX_Plus_Test
dw offset AST_386_486
dw offset AST_386_486_Test
dw offset TOSHIBA_1200XE
dw offset Toshiba_1200XE_Test
dw offset TOSHIBA_1600
dw offset Toshiba_1600_Test
dw offset TOSHIBA_5200
dw offset Toshiba_5200_Test
dw offset ATT_NSX20
dw offset ATT_NSX20_Test
;
; Default Machine must be last since we do not test for it
;
dw 0
;****************************************************************************
;
; Tests for Detecting Non-standard Machines
;
; Tests for detecting machines fall into 4 categories:
;
; - INT15_C0: Get Model and sub-model bytes by doing an Int15 C0 call
; - STR_CMP: Look for particular string in a given area of the BIOS
; - STR_CMP_386: Look for particular string in a given area of the BIOS
; as well as detemining if machine is 386-based or higher
; - Specific: A test specific to a given machine which doesn't fall
; into one of the above three categories.
;
;****************************************************************************
;****************************************************************************
; Test for Hewlett Packard Vectra Computer.
;****************************************************************************
HP_Vectra_Test db STR_CMP
dw 000F8h
dw 0F000h ; String is at F000:00F8
db 2 ; String is 2 characters long
db 'HP'
;****************************************************************************
; Test for AT&T Personal Computer
;****************************************************************************
ATT_PC_Test db STR_CMP
dw 00050h ; Offset 0050h
dw 0FC00h ; String is at FC00:0050h
db 3 ; String is 3 characters long
db 'OLI'
;****************************************************************************
; Test for IBM PS/2 Model P70 (portable)
;****************************************************************************
IBMPS2_70P_Test db INT15_C0
db IBM_PS2_70 ; model byte.
db IBM_PS2_70_SUBP ; sub-model byte.
;****************************************************************************
; Test for IBM PS/2 Model P70 (portable)
;****************************************************************************
IBMPS2_L40SX_Test db INT15_C0
db IBM_PS2_L40SX_M ; model byte.
db IBM_PS2_L40SX_SM ; sub-model byte.
;****************************************************************************
; Test for NEC Prospeed
;****************************************************************************
NEC_Prospeed_Test db STR_CMP
dw 0FFC0h
dw 0F000h
db 4
db 6,6,6,6
;****************************************************************************
; Test for all Zenith 386 Computers
;****************************************************************************
Zenith_386_Test db STR_CMP
dw 0800Ch ; Offset 800Ch
dw 0F000h ; String is at F000:800Ch
db 8 ; String is 8 characters long
db 'ZDS CORP' ; String to check for
;****************************************************************************
; Test for Everex Step 386/25
;****************************************************************************
Everex_386_25_Test db STR_CMP
dw 0FF59h
dw 0F000h
db 10
db '(C)1987AMI'
;****************************************************************************
; Test for NCR PC386SX (all versions?)
;****************************************************************************
NCR_386SX_Test db STR_CMP
dw 0FFEAh
dw 0F000h
db 3
db 'NCR'
;****************************************************************************
; Test for NEC Powermate SX Plus
;****************************************************************************
NEC_PM_SX_Plus_Test db STR_CMP
dw 00000h
dw 0FFF4h
db 2
db 4,2 ; 04 and 02
;****************************************************************************
; Test for ALL AST 386 and 486 machines
;****************************************************************************
AST_386_486_Test db AST_TEST ; Specific
;****************************************************************************
; Test for Toshiba 1200XE
;****************************************************************************
TOSHIBA_1200XE_Test db STR_CMP
dw 00000h
dw 0FE00h
db 7
db 'T1200XE'
;****************************************************************************
; Test for Toshiba 1600
;****************************************************************************
TOSHIBA_1600_Test db STR_CMP
dw 00000h
dw 0FE00h
db 5
db 'T1600'
;****************************************************************************
; Test for Toshiba 5200
;****************************************************************************
TOSHIBA_5200_Test db STR_CMP
dw 00000h
dw 0FE00h
db 5
db 'T5200'
;******************************************************************************
; Test for AT&T NSX/20 ( Safari ) Notebook Computer
;******************************************************************************
;
; BUGBUG shielint I don't think this test works.
;
ATT_NSX20_Test db STR_CMP
dw 0FF40h ; Offset 0FF40h
dw 0F000h ; String is at F000:FF40h
db 7 ; String is 7 characters long
db 'AT&TNSX'
dw 0FFD5h ; Offset 0FFD5h
dw 0F000h ; String is at F000:FF40h
db 2 ; String is 2 characters long
db 36h
db 74h
; db 0
;****************************************************************************
;
; End of machine test tables.
;
;****************************************************************************
; ***************************************************************************
;
; For Eisa System type detection
;
; ***************************************************************************
;
;
; szSystemType: SystemType is read from 0c80-0c83h.
; 0c80-0c81: 0e11: Compressed CPQ (5 bit encoding).
; 0c82: System Board type.
; 0c83: System Board revision level.
;
CPQ_SYSPRO db 'COMPAQ SYSTEMPRO', 0
ALR_SYSPRO db 'ALR SYSTEMPRO', 0
CPQ_SMP_SYSPRO db 'COMPAQ SYMMETRIC SYSTEMPRO', 0
abSystemTypeTable db 0eh, 11h, 01h
dw offset CPQ_SYSPRO ; CPQ01xx 386 ASP
db 0eh, 11h, 11h
dw offset CPQ_SYSPRO ; CPQ11xx 486 ASP
db 05h, 92h, 0a0h
dw offset ALR_SYSPRO ; ALRa0xx
db 0eh, 11h, 15h
dw offset CPQ_SMP_SYSPRO ; CPQ15xx
SYSTABLE_SIZE equ ($-abSystemTypeTable)/5
SystemType db 0, 0, 0, 0
;
; Compaq Portable machine IDs
;
; For these machines, the BIOS incorrectly specifies its keyboard type to
; be enhanced keyboard. So, for these machine we must set _NoBiosKbdCheck
; to TRUE.
;
CompaqPortableInt15Ids dw 0D0h ; LTE Lite 386/25(Athens)
dw 0D8h ; LTE Lite 386/20 (Infinity) 2MB
dw 0DCh ; ;LTE Lite 386/25C (Wizard)
dw 0E0h ; Contura 3/25 (Rapture)
dw 0E1h ; Clipper (Rapture 25 with color panel)
dw 0E4h ; Contura 3/20 (Rapture)
dw 0E8h ; Reserved for Alladin (H4 Color TFT) 25 MHz
dw 0E9h ; Reserved for Houdini
dw 0EAh ; Reserved for Alladin (H4 Color TFT) 33Mhz
dw 0ECh ; Reserved for Genie (H4 Mono TFT)
dw 00F4h ; Reserved for Schooner (Contura 486)
dw 0204h ; Caravel (H4 Contura STN Color)
dw 0208h ; Catamaran (H4 Contura TFT Color)
dw 0FCh ; LTE Lite 386/25E (Mystic)
COMPAQ_INT15ID_SIZE equ ($ - CompaqPortableInt15Ids) / 2
CompaqPortableCmosIds db 052h ; SLT386s/20 (Alfa, Titan/Targa)
db 055h ; LTE 386s (Calypso/Spartan)
db 061h ; LTE Lite 386/25(Athens)
db 062h ; LTE Lite 386/20 (Infinity) 2MB
db 065h ; ;LTE Lite 386/25C (Wizard)
db 067h ; Contura 3/25 (Rapture)
db 069h ; Clipper (Rapture 25 with color panel)
db 068h ; Contura 3/20 (Rapture)
db 06ah ; Reserved for Alladin (H4 Color TFT) 25 MHz
db 06ah ; Reserved for Genie (H4 Mono TFT)
db 06bh ; Reserved for Schooner (Contura 486)
db 06ch ; Caravel (H4 Contura STN Color)
db 06dh ; Catamaran (H4 Contura TFT Color)
db 065h ; LTE Lite 386/25E (Mystic)
COMPAQ_CMOSID_SIZE equ ($ - CompaqPortableCmosIds)
public _NoBiosKbdCheck, _NoLogitechPs2Check
_NoBiosKbdCheck db 0 ; Default FALSE
_NoLogitechPs2Check db 0 ; Default FALSE
NecVersaStrLen dw 9
NecVersaStr db 'NEC VERSA'
AttGlobalystStrLen dw 14
AttGlobalystStr db 'AT&T GLOBALYST'
_DATA ends
_TEXT SEGMENT PARA USE16 PUBLIC 'CODE'
ASSUME CS: _TEXT, DS:_DATA, SS:NOTHING
;++
;
; PUCHAR
; GetMachineId (
; VOID
; )
;
; Routine Description:
;
; This function determines mouse type in the system.
;
; Arguments:
;
; None.
;
; Return Value:
;
; a machine identifier ascii string.
;
;--
public _GetMachineId
_GetMachineId proc near
push es
push ds
push si
push di
push bx
;
; Before we start, check for some type of machines which needs special
; treatment.
;
call SpecialCheckings
or ax, ax ; Do we need to do rest of the detection?
jnz ExitTest ; if (ax) != 0, no.
;
; First, load offset of test table.
;
mov si,offset CompTypeTable
ID_Loop:
mov ax,[si] ; [Ax]-> Current ID we're testing for
push ax ; save the ID in case of match.
inc si
inc si ; [SI] = Offset of test table
push si ; Save SI for next ID
cmp ax, 0 ; If this compares, then we have tested
jne Cont ; for all problem machines: use default
jmp EndDetect
Cont:
mov si,[si] ; [SI] = Test instruction table
mov ah,[si] ; AH = Test type
inc si ; SI points to 1st param of test
Test1: ; Machine ID instruction test
cmp ah,INT15_C0
jne short Test2
mov ah,0c0h ; Here we need to test model bytes.
int 15h ; Use int 15h to retrieve pointer.
inc bx ; increment ponter to model bytes.
inc bx
mov ah,[si] ; model byte from table.
cmp ah,es:[bx] ; Q: Does model byte match ?
jz short Cont2 ; N: No, Not this type of machine.
jmp short NotThisID
Cont2:
inc si ; Y: Compare sub-model byte.
inc bx ; increment table and model byte ponters
mov ah,[si]
cmp ah,es:[bx] ; Q: Does sub-model byte match ?
jnz short NotThisID ; N: No, not this type of machine.
jmp short EndDetect ; Sucess
Test2: ; Compare strings instruction test
cmp ah,STR_CMP
jne short Test3
mov di,[si] ; DI = Offset of string
inc si
inc si
mov dx,[si]
mov es,dx ; ES = Segment of string
inc si
inc si
xor ch,ch
mov cl,[si] ; CX = # characters to compare
inc si ; [SI] = 1st char of string
cld ; Be sure to auto-increment
Test20:
mov al, [si]
cmp al, '?' ; Is it a match-all character?
je short Test25
mov ah, es:[di]
cmp ah, al
jne short NotThisID
Test25:
inc di
inc si
dec cx
cmp cx, 0
je short EndDetect
jmp short Test20
Test3:
cmp ah,AST_TEST
jne short InvalidID ; This can't happen
mov ah,0c0h ; Use int 15h to retrieve pointer
int 15h ; to System Environment Table
;
; Pointer is in ES:BX
;
mov ax,bx ; Point to where 'AST RESEARCH'
add ax,15h ; would be on an AST machine
mov di,ax ; ES:DI = ES:BX+15h
;
; DS:SI is string to compare with
;
mov si,offset AST_STRING
mov cx,AST_STR_LEN ; CX = # characters to compare
cld ; Be sure to auto-increment
repe cmpsb ; Q: Do strings match
jne short NotThisID
;
; Machine is AST, is it 386 or higher? It must be.
;
jmp short EndDetect ; Sucess
InvalidID:
; This can't happen if CompTypeTable is terminated with DEFAULT_MACHINE
;
; This section goes through the Machine IDs one at a time, if no ID is
; found, the last ID (DEFAULT_MACHINE) will be chosen as correct without
; testing.
;
NotThisID:
pop si ; Restore pointer to ID table
pop ax ; remove previous ID from stack
inc si ; Increment to next ID
inc si
jmp ID_Loop ; And test for that ID
EndDetect:
pop si ; Finished tests for current category so
pop ax ; return current category ID in AL
cmp ax, 0 ; if we did not find any we are interested in
jne ExitTest
;
; We did not find any thing by using above approach. Here we will do special
; checking for certain type of machines.
;
cmp _HwBusType, 1 ; Is it an EISA machine?
jne short @f
call DetectEisaSystemType ; mainly for system pro or compatible
cmp ax, 0 ; do we recognize the machine?
jne short ExitTest ; yes, go exit
@@:
;
; if we still did not find the type of the machine, assume it is AT or PS2
; compatible.
;
cmp _HwBusType, 2 ; is it a MCA system?
jne short EndDetect10
mov ax, offset PS2_COMPATIBLE
jmp short ExitTest
EndDetect10:
;
; Check if this is IBM PS/1 compatible machine
;
call DetectPs1
or ax, ax
jnz short ExitTest
mov ax, offset AT_COMPATIBLE
ExitTest:
pop bx
pop di
pop si
pop ds
pop es
ret
_GetMachineId endp
;++
; USHORT
; DetectEisaSystemType (
; VOID
; );
;
; Routine Description:
;
; Determines the type of system (specifically for eisa machines), by reading
; the system board system ID. It compares the 3 of the 4 bytes ID, to
; a predefined table <abSystemTypeTable> and return the index to the
; found entry.
;
; Arguments:
;
; None.
;
; Return Value:
; none
;
; Note this routine destroys es, bx, di, si
;--
DetectEisaSystemType proc
push ds
pop es ; es = ds
;
; 4 byte value is read from 0c80-0c83, and saved in <szSystemType>.
; The value is compared to table in <abSystemTypeTable>, and
; the _SystemType is updated accordingly.
;
mov di, offset SystemType
mov dx, 0c80h
cld ; increment edi
insb ; 0e CPQ
inc dx
insb ; 11
inc dx
insb ; _SystemType
inc dx
insb ; Revision
mov di, offset abSystemTypeTable; First entry in table
mov bx, 0 ; index to first entry
@@:
mov cx, 3 ; number of bytes per entry
mov si, offset SystemType ; match string against table entry
; Note ss = ds
repe cmpsb ; if (ecx == 0 and ZF set)
jz @f ; we have a winner
add di, cx ; next entry in tabl
inc di ; Skip TYPE string.
inc di
inc bx ; index to next enrty
cmp bx, SYSTABLE_SIZE ; Is this last entry?
jb @b ; NO
mov ax, 0
ret
@@:
mov ax, [di] ; _SystemType is last byte.
ret
DetectEisaSystemType endp
;++
; USHORT
; DetectDECpc (
; VOID
; );
;
; Routine Description:
;
; This routine determines if the machine is a DECpc by BACKWARD scanning
; through F000:FFFF - F000:0000 ROM BIOS segment and searching for
; 'DECPC' string. The reason for backward scanning is because most machines
; have their identifiers at the high part of ROM BIOS segment.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ax) = 0 Not DECpc
; (ax) = pointer to ASCii string 'DECpc'
;
; Note this routine destroys es, bx, di, si
;--
DetectDECpc proc
push es
push di
mov ax, 0f000h
mov es, ax ; es = ds
mov ecx, 10000h - 6
mov di, 0ffffh - 4 + 1
mov eax, 'cpCE'
dd00:
cmp eax, es:[di]
je short dd10
dec di
dd05:
loop short dd00
mov ax, 0
jmp short dd99
dd10:
dec di
cmp byte ptr es:[di], 'D'
jne short dd05
dd20:
mov ax, offset DEC_PC
dd99:
pop di
pop es
ret
DetectDECpc endp
;++
; PCHAR
; SpecialChecking (
; VOID
; );
;
; Routine Description:
;
; This routine checks if the target machine is one of COMPAQ portables.
; If yes, the _NoBiosKbdCheck will be set to TRUE. This is because on
; these machines, their BIOS incorrectly specify that they are enhanced
; keyboard.
;
; This routine checks if the target machine is OLIVETTI M600-40 or -60.
; If yes, the _NoLogitechPs2Check will be set to TRUE. This is because
; a bug in the keyboard controller of 'OLD' Olivetti M600 machines.
;
; Arguments:
;
; None.
;
; Return Value:
;
; _NoBiosKbdCheck is set or clear.
; _NoLogitechPs2Check is set or clear.
; (ax) -> a machine id string
;
;--
SpecialCheckings proc near
push bx
push di
push si
;
; First check Compaq Portable machines
;
push ds
mov ax, 0f000h
mov ds, ax
mov di, 0FFEAh
mov cx, 0
mov eax, dword ptr [di] ; Make sure this is compaq machine
mov bx, word ptr [di+4]
pop ds
cmp eax, 'PMOC'
jne short Sc20 ; if nz, not compaq, exit this test
cmp bx, 'QA'
jne short Sc20 ; if nz, not compaq, exit this test
;
; OK, we know it is compaq machine. Now blindly set cpu speed to highest rate
;
mov ax, 0F002H
int 16H
mov ax, 0e800h ; Get int15 SysId, [bx]=SysId if supported
int 15h
jc short Sc10_TestCmos ; function not supported, not compaq
; portable
cmp al, 86h
je short Sc10_TestCmos ; function not supported, not compaq
; portable
mov di, offset CompaqPortableInt15Ids
mov cx, COMPAQ_INT15ID_SIZE
Sc10:
cmp bx, [di]
je short Sc20
add di, 2
dec cx
cmp cx, 0
jne short Sc10
jmp short Sc20
Sc10_TestCmos:
mov al, 24h
CMOS_READ ; [al] = CMOS ID
mov di, offset CompaqPortableCmosIds
mov cx, COMPAQ_CMOSID_SIZE
Sc15:
cmp al, [di]
je short Sc20
add di, 1
dec cx
cmp cx, 0
jne short Sc15
Sc20:
mov _NoBiosKbdCheck, cl ; table < 255 entries
mov ax, offset AT_COMPATIBLE
or cl, cl
jnz Sc_Exit
;
; Test for Olivetti M600 machines
; Search for 'OLIVETTI' in f000:c040 - f000:c060
; and sub model byte 7A at f000:fffd
;
Sc_Test2:
push ds
mov ax, 0f000h
mov ds, ax
mov bx, 0fffdh
cmp byte ptr [bx], 7ah ; is sub model byte == 7a?
jne short Sc_Test2_Exit ; No, exit
mov cx, 20h
mov bx, 0c040h - 1
mov al, 'O'
Sc_Test2_00:
inc bx
cmp [bx], al
je short Sc_Test2_10
loop short Sc_Test2_00
jmp short Sc_Test2_Exit
Sc_Test2_10:
mov edx, 'VILO'
cmp edx, [bx]
jne short Sc_Test2_00
mov edx, 'ITTE'
cmp edx, [bx+4]
jne short Sc_Test2_00
pop ds
mov _NoLogitechPs2Check, dl
mov ax, offset AT_COMPATIBLE
jmp Sc_Exit
Sc_Test2_Exit:
pop ds
Sc_Test3:
;
; Check if this is PS2 E or IBM ThinkPad 750xx model. Floppy driver needs
; to know this to special handle its ChangeLine bit.
;
push es
push ds
mov ah,0c0h ; Here we need to test model bytes.
int 15h ; Use int 15h to retrieve pointer.
inc bx ; increment ponter to model bytes.
inc bx
;
; First check if this is PS2 E
;
cmp word ptr es:[bx], IBM_PS2_E_MODEL
jne short @f
pop ds
pop es
mov eax, offset IBM_PS2_E
jmp Sc_Exit
;
; Is this is ThinkPad 750
;
@@:
cmp byte ptr es:[bx], IBM_THINKPAD_750_MODEL
; Q: Does model byte match ?
jz short @f ; Y: Check submodel byte
jmp short Sc_Test3_Fail ; N: Not IBM ThinkPad
@@:
inc bx ; Move to submodel byte
cmp byte ptr es:[bx], IBM_THINKPAD_750_SUBMODEL_L
; Q: Does sub-model byte match ?
jae short @f ; Y: Possible
jmp short Sc_Test3_Fail ; N: Not IBM THinkPad
@@: cmp byte ptr es:[bx], IBM_THINKPAD_750_SUBMODEL1 ; Is it A9?
je short Sc_Test3_10 ; Yes
cmp byte ptr es:[bx], IBM_THINKPAD_750_SUBMODEL_H
jbe short Sc_Test3_10 ; Yes
jmp short Sc_Test3_Fail ; No
Sc_Test3_10:
;
; Make sure F000:E00E contains "IBM" string
;
mov ax, 0f000h
mov ds, ax
mov bx, 0e00eh
mov eax, [bx]
and eax, 0ffffffh ; Only need 3 bytes
cmp eax, 'MBI'
jne short Sc_Test3_Fail ; No IBM string, Not thinkpad
pop ds
pop es
mov eax, offset IBM_THINKPAD_750
jmp Sc_Exit
Sc_Test3_Fail:
pop ds
pop es
;
; Test for NEC VERSA and compatible machines
; Search for 'NEV VERSA' in f000:e000 - f000:e300
;
Sc_Test4:
push 300h
push 0e000h
push 0f000h
push NecVersaStrLen
push offset NecVersaStr
push ds
call SearchString
cmp ax, 0
je short @f
mov eax, offset NEC_VERSA
add sp, 6 * 2
jmp short Sc_Exit
@@:
add sp, 3 * 2
push AttGlobalystStrLen
push offset AttGlobalystStr
push ds
call SearchString
add sp, 6 * 2
cmp ax, 0
je short Sc_Test5
mov eax, offset NEC_VERSA
jmp short Sc_Exit
Sc_Test5:
;
; Check if this is DECpc
;
call DetectDECpc ; Is it a DECpcxxx?
Sc_Exit:
pop si
pop di
pop bx
ret
SpecialCheckings endp
;++
; VOID
; DetectPs1 (
; VOID
; );
;
; Routine Description:
;
; This routine check if the target machine is PS/1 or PS/1 compatible.
;
; Arguments:
;
; None.
;
; Return Value:
;
; (ax) = PS/1 Compatible.
;
;--
DetectPs1 proc near
if 0
;
; This does NOT work because not ALL the IBM Pc/ValuePoint models support
; this BIOS call!!
;
;
; Call PS/1 specific int 15 to read IBM DOS 4.0 Flags for IBM PS/1
;
; mov ax, 2300h
; int 15h
; jc short Dp99 ; function not supported, not compaq
; ; portable
; mov al, 2eh ; The return value should match
; CMOS_READ ; cmos 2d:2e
; mov ah, al
; mov al, 2dh
; CMOS_READ
; cmp cx, ax
; jne short Dp99
endif
;
; Check if the CMOS 2e and 2f contains memory checksum. On PS/1 machine
; the check should fail.
;
mov cx, 2dh ; from 10h to 2dh
mov ax, 0
mov dx, 0
Dp10:
mov al, cl
CMOS_READ
add dx, ax
dec cx
cmp cx, 0fh
jne short Dp10
mov ax, 2eh
CMOS_READ
mov ah, al
mov al, 2fh
CMOS_READ
cmp ax, dx
je short Dp99 ; NOT PS/1
;
; Next check if CMOS reg 37 contains 19
; if yes, we assume it is PS/1.
;
mov al, 37h
CMOS_READ
BCD_TO_BIN
cmp ax, 19
jne short Dp99
mov ax, offset PS1_COMPATIBLE
ret
Dp99:
mov ax, 0
ret
DetectPs1 endp
;++
; BOOLEAN
; SearchString (
; IN StringSeg,
; IN StringOffset,
; IN StringLength,
; IN MemorySeg,
; IN MemoryOffset,
; IN MemoryLength
; );
;
; Routine Description:
;
; This routine searches a string in the specified memory range
;
; Arguments:
;
;
; Return Value:
;
; (ax) = TRUE or FALSE
;
;--
SearchString proc near
StringSeg equ [bp + 4]
StringOffset equ [bp + 6]
StringLength equ [bp + 8]
MemorySeg equ [bp + 10]
MemoryOffset equ [bp + 12]
MemoryLength equ [bp + 14]
push bp
mov bp, sp
push ds
push es
push si
push di
mov ax, StringSeg
mov ds, ax
mov si, StringOffset
mov dx, StringLength
mov ax, MemorySeg
mov es, ax
mov di, MemoryOffset
mov cx, MemoryLength
Ss_FirstLevel:
mov ax, 0
cmp cx, dx
je short Ss_Exit
mov al, es:[di]
cmp al, 61h
jb short @f
cmp al, 7Ah
ja short @f
sub al, 20h
@@:
cmp al, [si]
je short Ss_MatchString
inc di
dec cx
cmp cx, 0
jne short Ss_FirstLevel
mov ax, 0
Ss_Exit:
pop di
pop si
pop es
pop ds
pop bp
ret
Ss_MatchString:
push dx ; Save string length
push si
push di
Ss_00:
dec dx
cmp dx, 0
jne short Ss_10
mov ax, 1
pop di
pop si
pop dx
jmp Ss_Exit
Ss_10:
inc si
@@:
inc di
mov al, es:[di]
cmp al, 20h ; Is it a space or ctrl-code
ja short @f ; No, continue
mov al, 20h ; make it a space
cmp byte ptr es:[di+1], 20h ; Is next char also a space or ctrl-code
ja short @f ; No, continue
jmp short @b ; yes, skip current space
@@:
cmp al, 61h
jb short @f
cmp al, 7Ah
ja short @f
sub al, 20h
@@:
cmp al, [si]
je short Ss_00
pop di
pop si
pop dx
inc di
dec cx
jmp short Ss_FirstLevel
SearchString endp
_TEXT ends
END