LOCALS

.MODEL	SMALL


.DATA

PUBLIC	szMouseDrvrVer

szSC_Adlib		DB	"Adlib-совместимая",0
szNotFound		DB	"Не обнаружена",0

szKbdType1		DB	"83/84-клавишная",0
szKbdType2		DB	"101/102-клавишная расширенная",0

szMouse_Bus		DB	"Шинная",0
szMouse_Serial		DB	"Последовательная",0
szMouse_Inport		DB	"Встроенная",0
szMouse_PS2		DB	"Мышь PS/2",0
szMouse_HP		DB	"Мышь Hewlett-Packard",0
szUnknown		DB	"Неизвестная",0
szMouse_NotInstalled	DB	"Мышь или драйвер не установлены",0

Mouse_Types		DW	OFFSET szUnknown
			DW	OFFSET szMouse_Bus
			DW	OFFSET szMouse_Serial
			DW	OFFSET szMouse_Inport
			DW	OFFSET szMouse_PS2
			DW	OFFSET szMouse_HP
Mouse_Types_MaxIndex	=	($-Mouse_Types)/2-1

sWindows		DB	", Windows "

szMouseDrvrVer		DB	6 DUP(0)	;строка с версией драйвера мыши


.DATA?

PUBLIC	bLPTPorts
PUBLIC	bCOMPorts
PUBLIC	bGamePort
PUBLIC	bSC_flag
PUBLIC	pszSCType
PUBLIC	pszKbdType
PUBLIC	bMouse_flag
PUBLIC	pszMouseType
PUBLIC	szOS

bLPTPorts		DB	?	;количество параллельных портов LPT
					;в формате ASCII
bCOMPorts		DB	?	;количество последовательных портов COM
					;в формате ASCII
bGamePort		DB	?	;количество игровых портов
					;в формате ASCII
bSC_flag		DB	?	;флаг наличия звуковой карты
pszSCType		DW	?	;указатель на строку в формате ASCIIZ
					;с типом звуковой карты
pszKbdType		DW	?	;указатель на строку в формате ASCIIZ
					;с типом клавиатуры
bMouse_flag		DB	?	;флаг наличия мыши
pszMouseType		DW	?	;указатель на строку в формате ASCIIZ
					;с типом мыши
szOS			DB	29 DUP(?)	;строка с типом операционной
						;системы


.CODE

PUBLIC	GetOtherInfo

EXTRN	ByteToStr:PROC
EXTRN	StrLen:PROC
EXTRN	ByteToHex:PROC
EXTRN	DetectAdlib:PROC
EXTRN	DetectWindows:PROC

;*******************************************************************************
;GetOtherInfo	определяет основную информацию о разном
;*******************************************************************************
;Использует:	ByteToStr, StrLen, ByteToHex, GetNumPorts, DetectAdlib,
;		DetectWindows
;		int 11h, int 33h, int 21h
;
;Вызов:		нет
;
;Возврат:	нет
;
;Изменяемые
;  регистры:	AX,BX,CX,DX,Flags
;*******************************************************************************
GetOtherInfo	PROC

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

		mov	ax,40h
		mov	es,ax		;ES = сегмент области данных BIOS

;-------------------------------------------------------------------------------
;Параллельные порты LPT
;-------------------------------------------------------------------------------

;Количество параллельных портов LPT

		mov	di,8		;ES:DI -> таблица базовых адресов
					;параллельных портов LPT
		mov	cl,3
		call	GetNumPorts	;DL = количество установленных
					;параллельных портов LPT
		mov	[bLPTPorts],dl

;-------------------------------------------------------------------------------
;Последовательные порты COM
;-------------------------------------------------------------------------------

;Количество последовательных портов COM

		xor	di,di		;ES:DI -> таблица базовых адресов
					;последовательных портов COM
		mov	cl,4
		call	GetNumPorts	;DL = количество установленных
					;последовательных портов COM
		mov	[bCOMPorts],dl

;-------------------------------------------------------------------------------
;Игровой порт
;-------------------------------------------------------------------------------

		mov	[bGamePort],'0'

		int	11h		;AX = список оборудования в побитовом
					;кодировании
		test	ah,10h		;бит 4: 1 = игровой адаптер установлен
					;бит 4: 0 = игровой адаптер не установлен
		jnz	@@GamePort_Ok

		mov	dx,200h		;DX = порт игрового адаптера
		in	al,dx
		cmp	al,0FFh
		jne	@@GamePort_Ok
		inc	dx
		in	al,dx
		cmp	al,0FFh
		je	@@GamePort_End

@@GamePort_Ok:	inc	[bGamePort]

@@GamePort_End:

;-------------------------------------------------------------------------------
;Звуковая карта
;-------------------------------------------------------------------------------

		mov	[pszSCType],OFFSET szNotFound

		call	DetectAdlib	;AX=0 - не обнаружена Adlib-совместимая
					;звуковая карта
					;AX=1 - обнаружена Adlib-совместимая
					;звуковая карта
		mov	[bSC_flag],al
		or	ax,ax
		jz	@@SC_End

		mov	[pszSCType],OFFSET szSC_Adlib

@@SC_End:

;-------------------------------------------------------------------------------
;Клавиатура
;-------------------------------------------------------------------------------

;Тип клавиатуры

		mov	[pszKbdType],OFFSET szKbdType1

		mov	al,es:[96h]	;AL = байт типа/режима клавиатуры
					;бит 4: 1 = установлена 101/102-клавишная
					;           расширенная клавиатура
		test	al,10h
		jz	@@Kbd_End

		mov	[pszKbdType],OFFSET szKbdType2

@@Kbd_End:

		push	ds
		pop	es		;ES = сегмент данных

;-------------------------------------------------------------------------------
;Мышь
;-------------------------------------------------------------------------------

		mov	[bMouse_flag],0
		mov	[pszMouseType],OFFSET szMouse_NotInstalled

		xor	ax,ax		;AX = функция инициализации мыши
		int	33h		;AX = состояние мыши:
					;     0000h - драйвер мыши или мышь
					;             не установлены
					;     FFFFh - драйвер мыши и мышь
					;             установлены
					;BX = количество клавиш у мыши:
					;     2 - две клавиши
					;     0 - больше или меньше чем две
					;     3 - мышь системы Mouse Systems
					;         (3 клавиши)
		inc	ax
		jnz	@@Mouse_End

		inc	[bMouse_flag]

;Тип мыши

		mov	ax,24h		;AX = функция определения типа мыши
		int	33h		;BH = верхний номер версии драйвера
					;BL = нижний номер версии драйвера
					;CH = тип мыши
					;     1 - Bus Mouse
					;     2 - Serial Mouse
					;     3 - Inport Mouse
					;     4 - PS/2 Mouse
					;     5 - HP Mouse
					;CL = номер используемого прерывания (IRQ)
					;     0 - IBM PS/2
					;     2,3,4,5,7 - IBM PC

		push	bx

		mov	bl,ch

		cmp	bl,Mouse_Types_MaxIndex
		jbe	@@Mouse_01

		xor	bl,bl

@@Mouse_01:	xor	bh,bh
		shl	bx,1
		mov	ax,[Mouse_Types+bx]
		mov	[pszMouseType],ax

		pop	bx

;Версия драйвера мыши

		mov	di,OFFSET szMouseDrvrVer

		cld

		mov	al,bh		;записываем старший номер версии
		call	ByteToHex

		cmp	al,'0'
		je	@@Mouse_02

		stosb

@@Mouse_02:	mov	al,ah
		stosb

		mov	al,'.'
		stosb

		mov	al,bl		;записываем младший номер версии
		call	ByteToHex
		stosw

@@Mouse_End:

;-------------------------------------------------------------------------------
;Операционная система
;-------------------------------------------------------------------------------

		mov	di,OFFSET szOS

;Версия DOS

		mov	ax,'OD'
		stosw
		mov	ax,' S'
		stosw

		mov	ah,30h		;AH=30h (функция определения версии DOS)
		int	21h		;AL = старший номер версии
					;AH = младший номер версии

		push	ax
		call	ByteToStr
		pop	ax

		mov	si,di
		call	StrLen		;CX = длина строки
		add	di,cx

		mov	al,'.'
		stosb

		mov	al,ah		;записываем младший номер версии
		aam
		add	ax,'00'
		xchg	al,ah
		stosw

;Версия Windows

		call	DetectWindows	;AL=1 - Windows обнаружена
					;       BH = старший номер версии
					;       BL = младший номер версии
					;AL=0 - Windows не обнаружена
					;       BX=0
		or	al,al
		jz	@@OS_End

		mov	si,OFFSET sWindows

		mov	cx,10
		rep	movsb

		mov	al,bh		;записываем старший номер версии
		push	bx
		call	ByteToStr
		pop	bx

		mov	si,di
		call	StrLen		;CX = длина строки
		add	di,cx

		mov	al,'.'
		stosb

		mov	al,bl		;записываем младший номер версии
		aam
		add	ax,'00'
		xchg	al,ah
		stosw

@@OS_End:	mov	BYTE PTR [di],0

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

		ret

GetOtherInfo	ENDP

;*******************************************************************************
;GetNumPorts	возвращает количество портов (COM, LPT) в формате ASCII
;*******************************************************************************
;Использует:	нет
;
;Вызов:		ES:DI -> таблица базовых адресов портов (COM, LPT)
;		CL = число элементов таблицы
;
;Возврат:	DL = количество портов (COM, LPT) в формате ASCII
;
;Изменяемые
;  регистры:	AX,CX,DL,Flags
;*******************************************************************************
GetNumPorts	PROC

		push	di

		mov	dl,'0'		;DL='0' (счетчик портов в формате ASCII)
		xor	ch,ch

		cld

@@PortAddrLoop:	mov	ax,es:[di]	;AX = базовый адрес порта
					;(AX=0 - порт не используется)
		inc	di
		inc	di
		or	ax,ax
		jz	@@Continue

		push	di
		push	cx

		dec	cx
		jz	@@IncrNumPorts
		repne	scasw		;проверяем, есть ли еще такой же
					;базовый адрес в таблице
		je	@@01

@@IncrNumPorts:	inc	dx

@@01:		pop	cx
		pop	di

@@Continue:	loop	@@PortAddrLoop

		pop	di

		ret

GetNumPorts	ENDP


END
