• No results found

21 - Keyboard Interface

In document CS609 Handouts 1 (Page 172-177)

© Copyright Virtual University of Pakistan 172

21 - Keyboard Interface

Processor Identification

_getproc proc near

pushf ;Secure flag register contents push di

;== Determine whether model came before or after 80286 ====

xor ax,ax ;Set AX to 0 push ax ;and push onto stack popf ;Pop flag register off of stack pushf ;Push back onto stack pop ax ;and pop off of AX

and ax,0f000h ;Do not clear the upper four bits cmp ax,0f000h ;Are bits 12 - 15 all equal to 1?

je not_286_386 ;YES --> Not 80386 or 80286

In the above slide the test for 8086 or not is performed by clearing all the bits of flags register then reading its value by pushing flags and then poping it in AX, the bits 15-12 of ax are checked if they have been set then it’s a 8086.

;-- Test for determining whether 80486, 80386 or 80286 ---mov dl,p_80286 ;In any case, it's one of the mov ax,07000h ;three processors

push ax ;Push 07000h onto stack popf ;Pop flag register off

pushf ;and push back onto the stack pop ax ;Pop into AX register

and ax,07000h ;Mask everything except bits 12-14 je pende ;Are bits 12 - 14 all equal to 0?

;YES --> It's an 80286 inc dl ;No --> it's either an 80386 or an

;80486. First set to 386

;-- The following test to differentiate between 80386 and

---;-- 80486 is based on an extension of the EFlag register on

;-- the 80486 in bit position 18.

;-- The 80386 doesn't have this flag, which is why you

;-- cannot use software to change its contents.

21 - Keyboard Interface

© Copyright Virtual University of Pakistan 173 The above slide further performs the test for 80286 if the previous test fails. It sets the bit 14-12 of flags and then again reads back the value of flags through stack. If the bits 14-12 have been cleared then it’s a 80486.

cli ;No interrupts now

mov ebx,offset array

The above code performs the alignment test as discussed before by test the 18th bit after addressing a double word at an odd address.

pushfd

the above code performs a test to see if CPUID instruction is available or not for which the bit number 21 of flags is set and then read back.

21 - Keyboard Interface

© Copyright Virtual University of Pakistan 174

pende label near ;End testing pop di ;Pop DI off of stack

popf ;Pop flag register off of stack xor dh,dh ;Set high byte of proc. code to 0 mov ax,dx ;Proc. code = return value of funct.

ret ;Return to caller

_getproc endp ;End of procedure

A CPUID Program

#include "stdafx.h"

#include <stdio.h>

#include <dos.h>

unsigned long int id[3];

unsigned char ch='\0';

unsigned int steppingid ; unsigned int model,family,type1 ; unsigned int cpcw;

int main(int argc, char* argv[]) {

_asm xor eax,eax _asm cpuid _asm mov id[0], ebx ; _asm mov id[4], edx ; _asm mov id[8], ecx;

printf(" %s\n ", (char *) (id));

_asm mov eax,1 _asm cpuid _asm mov ecx,eax _asm AND eax,0xf;

_asm mov steppingid,eax;

_asm mov eax, ecx

21 - Keyboard Interface

© Copyright Virtual University of Pakistan 175

_asm shr eax,4 _asm and eax, 0xf;

_asm mov model,eax _asm mov eax,ecx _asm shr eax,8 _asm and eax, 0xf _asm mov family,eax;

_asm mov eax,ecx _asm shr eax,12 _asm and eax, 0x3;

_asm mov type1, eax;

printf("\nstepping is %d\n model is %d\nFamily is %d\nType is

%d\n",steppingid,model,family,type1);

}

The above program places 0 in eax register before issuing the CPUID instruction. The string returned by the instruction is then stored and printed moreover other information about family, model etc is also printed.

21 - Keyboard Interface

© Copyright Virtual University of Pakistan 176 Detecting a Co Processor

_asm finit

_asm mov byte ptr cpcw+1, 0;

_asm fstcw cpcw

if ( *(((char *) (&cpcw))+1)==3) puts("Coprocessor found");

else

puts ("Coprocessor not found");

After initialization the control word is read if the higher byte contains the value 3.

_getco proc near

mov dx,co_none ;First assume there is no CP mov byte ptr cs:wait1,NOP_ CODE ;WAIT-instruction on 8087 mov byte ptr cs:wait2,NOP_ CODE ;Replace by NOP wait1: finit ;Initialize Cop

mov byte ptr cpz+1,0 ;Move high byte control word to 0 wait2: fstcw cpz ;Store control word

cmp byte ptr cpz+1,3 ;High byte control word = 3?

jne gcende ;No ---> No coprocessor

;-- Coprocessor exists. Test for 8087 ---inc dx

and cpz,0 FF7 Fh ;Mask interrupt enable mask flag fldcw cpz ;Load in the control word

fdisi ;Set IEM flag

fstcw cpz ;Store control word test cpz,80h ;IEM flag set?

jne gcende ;YES ---> 8087, end test

In the code above the IEM bit is set and then the value of control word is read to analyse change in the control word. If the most significant bit is set then it’s a 8087 co processor otherwise other tests must be performed.

21 - Keyboard Interface

© Copyright Virtual University of Pakistan 177

;-- Test for 80287/80387 ---inc dx

finit ;Initialize cop fld1 ;Number 1 to cop stack fldz ;Number 0 to cop stack fdiv ;Divide 1 by 0, erg to ST fld st ;Move ST onto stack fchs ;Reverse sign in ST

fcompp ;Compare and pop ST and ST(1)

fstsw cpz ;Store result from status word mov ah,byte ptr cpz+1 ;in memory and move AX register

sahf ;to flag register

je gcende ;Zero-Flag = 1 : 80287 inc dx ;Not 80287, must be 80387 or

inte-;grated coprocessor on 80486 gcende: mov ax,dx ;Move function result to AX

ret ;Return to caller _getco endp

An operation (like division by zero is performed) which results in infinity. Then the sign of the result is reversed, if it can be reversed then its 80387 co processor otherwise its certainly 80287.

In document CS609 Handouts 1 (Page 172-177)

Related documents