1347 lines
36 KiB
NASM
1347 lines
36 KiB
NASM
|
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
|