LOCALS

.MODEL	SMALL


.DATA

PUBLIC	szBIOSDate

EXTRN	bCPU_Family:BYTE

szComp_PC		DB	'IBM PC',0
szComp_PCjr		DB	'IBM PCjr',0
szComp_PC_Convertible	DB	'IBM PC Convertible',0
szComp_XT		DB	'IBM PC/XT',0
szComp_XT_286		DB	'IBM PC/XT 286',0
szComp_AT		DB	'IBM PC/AT или аналог',0
szComp_PS2_25		DB	'IBM PS/2 модель 25',0
szComp_PS2_30		DB	'IBM PS/2 модель 30',0
szComp_PS2_30_286	DB	'IBM PS/2 модель 30 286',0
szComp_PS2_50		DB	'IBM PS/2 модель 50',0
szComp_PS2_55SX		DB	'IBM PS/2 модель 55SX',0
szComp_PS2_60		DB	'IBM PS/2 модель 60',0
szComp_PS2_65		DB	'IBM PS/2 модель 65',0
szComp_PS2_70		DB	'IBM PS/2 модель 70',0
szComp_PS2_70_486	DB	'IBM PS/2 модель 70 486',0
szComp_PS2_P70		DB	'IBM PS/2 модель P70 Laptop',0
szComp_PS2_80		DB	'IBM PS/2 модель 80',0
szComp_PS2_80_16MHz	DB	'IBM PS/2 модель 80, 16 МГц',0
szComp_PS2_80_20MHz	DB	'IBM PS/2 модель 80, 20 МГц',0
szComp_PS2_90		DB	'IBM PS/2 модель 90',0
szComp_PS1		DB	'IBM PS/1',0
szComp_Phoenix_AT	DB	'Phoenix PC/AT совместимая BIOS',0
szComp_7552_Gearbox	DB	'7552 Gearbox',0
szComp_Sperry_PC	DB	'Sperry PC',0
szComp_Compaq_Plus	DB	'Compaq XT или Compaq Plus',0
szComp_Compaq_PC	DB	'Compaq PC или Compaq Deskpro',0

Comp_Table		DW	0FF2Dh, OFFSET szComp_Compaq_PC
			DW	0FF30h, OFFSET szComp_Sperry_PC
			DW	0FF9Ah, OFFSET szComp_Compaq_Plus
			DW	000F8h, OFFSET szComp_PS2_80_16MHz
			DW	001F8h, OFFSET szComp_PS2_80_20MHz
			DW	004F8h, OFFSET szComp_PS2_70
			DW	009F8h, OFFSET szComp_PS2_70
			DW	00BF8h, OFFSET szComp_PS2_P70
			DW	00CF8h, OFFSET szComp_PS2_55SX
			DW	00DF8h, OFFSET szComp_PS2_70
			DW	014F8h, OFFSET szComp_PS2_90
			DW	016F8h, OFFSET szComp_PS2_90
			DW	01BF8h, OFFSET szComp_PS2_70_486
			DW	01CF8h, OFFSET szComp_PS2_65
			DW	050F8h, OFFSET szComp_PS2_P70
			DW	080F8h, OFFSET szComp_PS2_80
			DW	0FFF9h, OFFSET szComp_PC_Convertible
			DW	000FAh, OFFSET szComp_PS2_30
			DW	001FAh, OFFSET szComp_PS2_25
			DW	000FBh, OFFSET szComp_XT
			DW	0FFFBh, OFFSET szComp_XT
			DW	000FCh, OFFSET szComp_AT
			DW	001FCh, OFFSET szComp_AT
			DW	002FCh, OFFSET szComp_XT_286
			DW	004FCh, OFFSET szComp_PS2_50
			DW	005FCh, OFFSET szComp_PS2_60
			DW	006FCh, OFFSET szComp_7552_Gearbox
			DW	009FCh, OFFSET szComp_PS2_30_286
			DW	00BFCh, OFFSET szComp_PS1
			DW	081FCh, OFFSET szComp_Phoenix_AT
			DW	0FFFCh, OFFSET szComp_AT
			DW	0FFFDh, OFFSET szComp_PCjr
			DW	0FFFEh, OFFSET szComp_XT
			DW	0FFFFh, OFFSET szComp_PC
Comp_Table_Count	=	($-Comp_Table)/4

szBIOS_AMI		DB	'American Megatrends',0
szBIOS_AMI_1		DB	'AMI',0
szBIOS_Award		DB	'Award Software',0
szBIOS_Phoenix		DB	'Phoenix Technologies',0
szBIOS_C&T		DB	'Chips & Technology',0
szBIOS_C&T_1		DB	'C&T',0
szBIOS_Mylex		DB	'Mylex Corporation',0
szBIOS_MR_BIOS		DB	'Microid Research',0
szBIOS_MR_BIOS_1	DB	'MR BIOS',0
szBIOS_DTK		DB	'Datatech Enterprises',0
szBIOS_DTK_1		DB	'DTK',0
szBIOS_Quadtel		DB	'Quadtel',0
szBIOS_AST		DB	'AST Research',0
szBIOS_Insignia		DB	'Insignia Solutions',0
szBIOS_Toshiba		DB	'Toshiba',0
szBIOS_Compaq		DB	'Compaq',0
szBIOS_IBM		DB	'IBM',0
szBIOS_Acer		DB	'Acer',0
szBIOS_Olivetti		DB	'Olivetti',0
szBIOS_Zenith		DB	'Zenith',0

BIOS_Table		DW	OFFSET szBIOS_AMI,	OFFSET szBIOS_AMI
			DW	OFFSET szBIOS_AMI_1,	OFFSET szBIOS_AMI
			DW	OFFSET szBIOS_Award,	OFFSET szBIOS_Award
			DW	OFFSET szBIOS_Phoenix,	OFFSET szBIOS_Phoenix
			DW	OFFSET szBIOS_C&T,	OFFSET szBIOS_C&T
			DW	OFFSET szBIOS_C&T_1,	OFFSET szBIOS_C&T
			DW	OFFSET szBIOS_Mylex,	OFFSET szBIOS_Mylex
			DW	OFFSET szBIOS_MR_BIOS,	OFFSET szBIOS_MR_BIOS
			DW	OFFSET szBIOS_MR_BIOS_1,OFFSET szBIOS_MR_BIOS
			DW	OFFSET szBIOS_DTK,	OFFSET szBIOS_DTK
			DW	OFFSET szBIOS_DTK_1,	OFFSET szBIOS_DTK
			DW	OFFSET szBIOS_Quadtel,	OFFSET szBIOS_Quadtel
			DW	OFFSET szBIOS_AST,	OFFSET szBIOS_AST
			DW	OFFSET szBIOS_Insignia,	OFFSET szBIOS_Insignia
			DW	OFFSET szBIOS_Toshiba,	OFFSET szBIOS_Toshiba
			DW	OFFSET szBIOS_Compaq,	OFFSET szBIOS_Compaq
			DW	OFFSET szBIOS_IBM,	OFFSET szBIOS_IBM
			DW	OFFSET szBIOS_Acer,	OFFSET szBIOS_Acer
			DW	OFFSET szBIOS_Olivetti,	OFFSET szBIOS_Olivetti
			DW	OFFSET szBIOS_Zenith,	OFFSET szBIOS_Zenith
BIOS_Table_Count	=	($-BIOS_Table)/4

szMathCo_8087		DB	'8087',0
szMathCo_80287		DB	'80287',0
szMathCo_80C287		DB	'80C287',0
szMathCo_80387		DB	'80387',0
szMathCo_FPU		DB	'Встроенный',0
szMathCo_Weitek		DB	'Weitek',0

szNone			DB	'Нет',0

szUnknown1		DB	'Неизвестный',0
szUnknown2		DB	'Неизвестная',0

szBIOSDate		DB	'??.??.??',0	;строка с датой BIOS


.DATA?

PUBLIC	pszComputerType
PUBLIC	pszBIOSName
PUBLIC	szCPU
PUBLIC	bMathCo
PUBLIC	pszMathCo

pszComputerType		DW	?		;указатель на строку в формате
						;ASCIIZ с типом компьютера
pszBIOSName		DW	?		;указатель на строку в формате
						;ASCIIZ с идентификатором BIOS
szCPU			DB	35 DUP(?)	;строка с типом процессора
bMathCo			DB	?		;тип сопроцессора
pszMathCo		DW	?		;указатель на строку в формате
						;ASCIIZ с типом сопроцессора
szMathCo_x87_&_Weitek	DB	20 DUP(?)


.CODE

PUBLIC	GetComputerInfo

EXTRN	MemSearch:PROC
EXTRN	GetCPUTypeStr:PROC
EXTRN	CPU_Speed:PROC
EXTRN	FPUx87_ID:PROC
EXTRN	StrLen:PROC
EXTRN	WordToStr:PROC

;*******************************************************************************
;GetComputerInfo определяет основную информацию о компьютере
;*******************************************************************************
;Использует:	MemSearch, GetCPUTypeStr, CPU_Speed, FPUx87_ID, StrLen,
;		WordToStr
;		int 11h, int 15h
;
;Вызов:		нет
;
;Возврат:	нет
;
;Изменяемые
;  регистры:	AX,BX,CX,DX,Flags
;*******************************************************************************
GetComputerInfo	PROC

		push	es		;сохраняем регистры в стеке
		push	si
		push	di

;-------------------------------------------------------------------------------
;Тип компьютера
;-------------------------------------------------------------------------------

		mov	ah,0C0h		;AH = функция получения параметров
					;конфигурации системы
		int	15h		;CF = флаг успешного/неудачного завершения
					;ES:BX -> таблица системной конфигурации
		jc	@@NoSubmodel
		or	ah,ah
		jz	@@NoSubmodel

		mov	ax,es:[bx+2]	;AL = идентификатор машины
					;AH = дополнительный код модели
		jmp	@@Comp_01

@@NoSubmodel:	mov	ax,0F000h	;AX = сегмент системной ROM BIOS
		mov	es,ax
		mov	al,es:[0FFFEh]	;AL = идентификатор машины
		mov	ah,0FFh

@@Comp_01:	mov	bx,OFFSET Comp_Table
		mov	cx,Comp_Table_Count

@@CompLoop:	mov	dx,[bx+2]
		cmp	ax,[bx]
		jz	@@Comp_End

		add	bx,4
		loop	@@CompLoop

		mov	dx,OFFSET szUnknown2	;DS:DX -> szUnknown2

@@Comp_End:	mov	[pszComputerType],dx

;-------------------------------------------------------------------------------
;Идентификатор BIOS
;-------------------------------------------------------------------------------

		mov	ax,0F000h
		mov	es,ax		;ES = сегмент системной ROM BIOS

		xor	di,di		;ES:DI -> область поиска

		mov	bx,OFFSET BIOS_Table
		mov	cx,BIOS_Table_Count

@@BIOSLoop:	push	bx
		push	cx

		mov	si,[bx]		;DS:SI -> искомая строка
		call	StrLen		;CX = длина искомой строки
		mov	bx,cx		;BX = длина искомой строки
		mov	cx,0FFF0h	;CX = длина области поиска
		call	MemSearch	;ZF=1, если строка найдена
					;ZF=0, если строка не найдена

		pop	cx
		pop	bx
		mov	dx,[bx+2]
		jz	@@BIOS_End

		add	bx,4
		loop	@@BIOSLoop

		mov	dx,OFFSET szUnknown2	;DS:DX -> szUnknown2

@@BIOS_End:	mov	[pszBIOSName],dx

;-------------------------------------------------------------------------------
;Дата BIOS
;-------------------------------------------------------------------------------

		mov	ax,es:[0FFF5h+3]	;записываем число
		mov	WORD PTR [szBIOSDate],ax

		mov	ax,es:[0FFF5h]		;записываем номер месяца
		mov	WORD PTR [szBIOSDate+3],ax

		mov	ax,es:[0FFF5h+6]	;записываем год
		mov	WORD PTR [szBIOSDate+6],ax

;-------------------------------------------------------------------------------
;Тип процессора
;-------------------------------------------------------------------------------

		call	GetCPUTypeStr	;DX = смещение строки с типом процессора
		mov	si,dx

		call	StrLen		;CX = длина строки

		push	ds
		pop	es		;ES = сегмент данных
		mov	di,OFFSET szCPU	;ES:DI -> szCPU

		cld
		rep	movsb		;копируем строку с типом процессора
		mov	BYTE PTR [di],0

		call	CPU_Speed	;AX = тактовая частота процессора
		or	ax,ax		;тактовая частота процессора определена?
		jz	@@CPU_End

		mov	BYTE PTR [di],'-'	;добавляем тире
		inc	di

		call	WordToStr	;преобразуем числовое значение тактовой
					;частоты процессора в строку

@@CPU_End:

;-------------------------------------------------------------------------------
;Тип сопроцессора
;-------------------------------------------------------------------------------

		call	FPUx87_ID	;AL = тип сопроцессора
		mov	[bMathCo],al

		mov	dx,OFFSET szNone
		or	al,al		;сопроцессор отсутствует или
					;установлен сопроцессор Weitek?
		jz	@@Weitek

		cmp	al,2		;тип сопроцессора - 8087/80287?
		jne	@@80387

		mov	dx,OFFSET szMathCo_8087
		cmp	[bCPU_Family],2	;тип процессора - ниже 80286?
		jb	@@MathCo_End

		mov	dx,OFFSET szMathCo_80287
		jmp	@@Weitek

@@80387:	cmp	al,3		;тип сопроцессора - 80387?
		jne	@@FPU

		mov	dx,OFFSET szMathCo_80C287
		cmp	[bCPU_Family],3	;тип процессора - ниже 80386?
		jb	@@MathCo_End

		mov	dx,OFFSET szMathCo_80387
		jmp	@@Weitek

@@FPU:		mov	dx,OFFSET szMathCo_FPU

@@Weitek:	cmp	[bCPU_Family],3	;тип процессора - ниже 80386?
		jb	@@MathCo_End

.386
		xor	eax,eax
		int	11h		;получение списка оборудования
					;EAX = список оборудования в побитовом
					;кодировании
					;бит 24: 1 = установлен математический
					;            сопроцессор Weitek
		test	eax,1000000h	;установлен сопроцессор Weitek?
.8086
		jz	@@MathCo_End

		cmp	[bMathCo],0	;сопроцессор x87 отсутствует (Weitek -
					;единственный сопроцессор)?
		je	@@Only_Weitek

		mov	si,dx		;DS:SI -> строка с названием
					;сопроцессора x87
		call	StrLen		;CX = длина строки
		mov	dx,OFFSET szMathCo_x87_&_Weitek
		mov	di,dx
		rep	movsb		;копируем строку с названием
					;сопроцессора x87

		mov	ax,'и '		;добавляем " и "
		stosw
		mov	al,' '
		stosb

		mov	si,OFFSET szMathCo_Weitek	;копируем строку "Weitek"
		mov	cx,7
		rep	movsb
		jmp	@@MathCo_End

@@Only_Weitek:	mov	dx,OFFSET szMathCo_Weitek

@@MathCo_End:	mov	[pszMathCo],dx

		pop	di		;восстанавливаем регистры
		pop	si
		pop	es

		ret

GetComputerInfo	ENDP


END
