;EQUIP.ASM
;company : LOGICAL DEVICES, INC.
;author  : Michael R. Appleton
;project : ALLPRO-88
;created : 8/15/90
;last rev:
;-----------------------------------------------------------------------------
;
;
; This routine returns the processor type in the AX:
;	AX	CPU type
;	---	--------
;	30h	NEC V20/V30
;	86h	INTEL 8088/8086
;	186h	INTEL 80188/80186
;	286h	INTEL 80286
;	386h	INTEL 80386
;	486h	INTEL 80486

	COMPILER equ	2
	include casm.mac

	begcode
procdef		proc_type,<>
;	PUSH	BP		; Save BP
;	MOV	BP,SP

	pushf			; Save FLAG registers
	xor	ax,ax		; Clear AX and push onto the stack.
	push	ax
	popf			;  Pop a zero into FLAGs register
	pushf			;  Attempt to set bit 12-15 to a zero
	pop	ax		;  Recover FLAG word
	and	ax, 0f000h	;  If Bits 12-15 are set then the processor
	cmp	ax, 0f000h	;  is an 8018x or an 808x
	jz	is_0_1

	mov	ax, 07000h	;  Try to set FLAG bits 12-14 (NT, IOPL)
	push 	ax
	popf			;  put 07000H into flags
	pushf
	pop	ax

	and	ax,07000h	;if bits 12-14 are cleared then the
	jz	is_80286	;processor is an 286

is_386_486:
;					the following are 386/486
;					privileged instructions
;
	db	0fh,20h,0c0h		;mov	eax,cr0
	db	66h,8bh,0d8h		;mov	ebx,eax
	db	66h,35h,0,0,0,20h	;xor	eax,20000000h
	db	0fh,22h,0c0h		;mov	cr0,eax
	db	0fh,20h,0c0h		;mov	eax,cr0
	db	66h,3bh,0c3h		;cmp	eax,ebx
	je	is_80386		;jmp 	if 386
;
is_80486:			;Else it is a 486
	mov	ax, 486h	;return 486 in AX
	jmp	done
is_80386:			;Else it is a 386
	mov	ax, 386h	;return 386 in AX
	jmp	done
is_80286:
	mov	ax, 286h	;return 286 in AX
	jmp	done
is_0_1:				;It is a 8086, a 80186, or a V20/V30
	push 	cx		;  Save CX the only other register used	
	mov	ax, 0ffffh	;  Set AX to all 1s
	mov	cl, 33		;  Will shift it 33 times if it is an
				;  808x, or 1 time if it is an 8018x.
	shl	ax, cl		;  If we shift 33 times all bits are
	jnz	is_80186	;  zero. If any bits are on it's an 18x 
is_8086:			;  Else we have an 8086 or V20/V30.
	pop	cx		;  restore cx
	xor	al,al		;  Sets ZF
	mov	al,40h		;  64 decimal
	mul	al		;  64**2 > 255
	jz	is_v30		;  V20/V30 MUL leaves ZF untouched
				;  8086 ZF==OF after MUL
	mov	ax,86h		;  Return 86 in AX
	jmp	done	
is_v30:
	mov	ax,30h		;  Return 30 in AX
	jmp	done

is_80186:
	mov 	ax, 186h	;  Return 186 in AX
	pop	cx

done:
	popf			; Recover original FLAG register
;	POP	BP		; Restore BP
	pret

	pend proc_type
;
;-----------------------------------------------------------------------------
;
	begdata
EMS_NAME 	db	"EMMXXXX0",0
	enddata

procdef ems_installed, <>

		Push	ES
		Push	DI
		Push	SI
		push	cx
		Mov	SI, offset EMS_NAME
		Mov	AX,0
		Mov	ES,AX
		Mov	AX,word ptr ES:[414]    ;AX=int 67h segment
		mov	ES,ax
		Mov	DI,10
		Mov	CX,8
		Mov	AX,1
		Cld
		Repe Cmpsb
		Je	eiret
		Sub	AX,AX
eiret:
		pop	cx
		Pop	SI
		Pop	DI
		Pop	ES
		pret				;...done

pend	ems_installed

;
;-----------------------------------------------------------------------------
;
procdef get_DOS_version, <>

		push	CX
		push	BX
		mov	ah,030h
		mov	al,0
		int	21h
		pop	BX
		pop	CX
		pret				;...done

pend	get_DOS_version

;
;-----------------------------------------------------------------------------
;


PPI8255PortA	Equ	060H			;ibms 8255 port A
PPI8255PortB	Equ	061H			;ibms 8255 port B
PPI8255PortC	Equ	062H			;ibms 8255 port C
PPI8255CmdStat	Equ	063H			;ibms 8255 command / status register

CTC8253Timer0	Equ	040H			;ibms 8253 timer port 0
CTC8253Timer1	Equ	041H			;ibms 8253 timer port 1
CTC8253Timer2	Equ	042H			;ibms 8253 timer port 2
CTC8253Command	Equ	043H			;ibms 8253 timer command register


MAXCOUNT	equ	1000h

procdef get_CPU_speed, <>

		PUSH	BX
		PUSH	CX
		IN	AL,61h
		OR 	AL,1
		OUT	61h,AL

		MOV	AL,0b8h				;one shot BCD
		OUT	CTC8253Command,AL		;TIMER2 MODE 4
;
		CLI
		MOV	CX,22
		MOV	AL,low MAXCOUNT			;timer LSB
		OUT	CTC8253Timer2,AL
		MOV	AL,high MAXCOUNT			;timer MSB
		OUT	CTC8253Timer2,AL		;start timer 2
rloop:	
;		nop
		xor	AX,AX
		CMP	AX,0
		DEC	CX
		JNZ	rloop
		MOV	AL,080h
		OUT	CTC8253Command,AL		;Latch timer 2 count
;
		IN	AL,CTC8253Timer2		;get timer 2 LSB
		MOV	AH,00h
		MOV	BX,AX

		IN	AL,CTC8253Timer2                ;get timer 2 MSB
		MOV	AH,0
		MOV	CL,8
		SHL	AX,CL
		ADD  	BX,AX
		MOV	AX,MAXCOUNT
		SUB	AX,BX

		STI
		POP	CX
		POP	BX
		pret

pend get_CPU_speed

;
;-----------------------------------------------------------------------------
;
procdef get_conv_mem , <>
		push	es
		mov	ax,040h
		mov	es,ax
		mov	AX,word ptr ES:[13h]
		pop	es
		pret
pend get_conv_mem
;
;-----------------------------------------------------------------------------
;
procdef get_display_mode , <>
		push	cx
		int	11h
		and	al,30h
		mov	cl,4
		shr	al,cl
		mov	ah,0
		and	al,03
		pop	cx
		pret

pend get_display_mode
;
;-----------------------------------------------------------------------------
;

	endcode

