ray@ole.UUCP (Ray Berry) (02/25/89)
Does anyone know a simple way of detecting whether code is executing (in real mode) on a 386 vs non-386 (286/86) cpu? I'll summarize responses. Thanks. -- Ray Berry KB7HT uucp: ...{uw-beaver|uiucuxc}tikal!ole!ray CS: 73407,3152 Seattle Silicon Corp. 3075 112th Ave NE. Bellevue WA 98004 (206) 828 4422
martin@zeus.hf.intel.com (Martin Wilde) (02/28/89)
> Does anyone know a simple way of detecting whether code is executing >(in real mode) on a 386 vs non-386 (286/86) cpu? I'll summarize responses. >Thanks. >-- >Ray Berry KB7HT uucp: ...{uw-beaver|uiucuxc}tikal!ole!ray CS: 73407,3152 >Seattle Silicon Corp. 3075 112th Ave NE. Bellevue WA 98004 (206) 828 4422 Here is a small program that was presented in IBM PC Technical Journal a while back. It seems to work fine. I have tried it on both 286 Xenix and 386 Unix and it reports the cputype correctly. The source is in Microsoft Assembler and normal C code. I make to warranties or guarantees about the code, just passing it on. #!/bin/sh # shar: Shell Archiver (v1.22) # # Run the following text with /bin/sh to create: # Makefile # cpu.asm # cputype.c # sed 's/^X//' << 'SHAR_EOF' > Makefile && XCC = /bin/cc XASM=/bin/masm XCFLAGS = -O -Ml XASMFLAGS = -Mx X Xall: cpu.o X $(CC) $(CFLAGS) -o cputype cputype.c cpu.o X Xcpu.o: X $(ASM) $(ASMFLAGS) cpu.asm X Xclean: X rm -f cpu.o cputype cputype.o SHAR_EOF chmod 0644 Makefile || echo "restore of Makefile fails" sed 's/^X//' << 'SHAR_EOF' > cpu.asm && X; Function cputype(), for real OR protected mode. Returns (in AX) X; the value 0 (86), 20 (186), 30 (286), 40 (386); negative if protected mode. X X .286p ;enable protected-mode instructions X_text segment byte public 'code' ; use Microsoft C names X assume cs:_text X public _cputype X_cputype proc far X push bp X push sp ;86/186 will push SP-2, X pop ax ;286/386 will push SP X cmp ax,sp X jz not86 ;if equal, SP was pushed X mov ax,10 ;is it 86 or 186 X mov cl,32 ;186 uses count mod32 = 0 X shl ax,cl ;86 shifts 32 so ax = 0 X jnz exit ;non-zero: no shift, so 186 X mov ax,20 ;zero: shifted out all bits X jmp exit Xnot86: pushf ;Test 16 or 23 operand size: X mov ax,sp ;pushed 2 or 4 bytes flags? X popf ;restore SP X inc ax ;restore AX by 2 bytes X inc ax X cmp ax,sp ;did pushf change SP by 2? X jnz is32bit ;if not, then 4 bytes of flags X Xis16bit: sub sp,6 ;Is it 286 or 386 in 16-bit mode? X mov bp,sp ;allocate space for GDT ptr X sgdt qword ptr [bp] ;(use PWORD PTR for MASM5) X add sp,4 ;discard 2 words of GDT pointer X pop ax ;get third word X inc ah ;286 stores -1, 386 0 or 1 X jnz is386 X Xis286: mov ax,30 ;set return value X jmp testprot Xis32bit: db 66H ;16-bit override in 32-bit mode Xis386: mov ax,40 Xtestprot: smsw cx ;Protected? Machine status -> CX X ror cx,1 ;protection bit -> carry flag X jnc exit ;real mode if no carry X neg ax ;protected: return neg value Xexit: pop bp X ret X_cputype endp X_text ends X end SHAR_EOF chmod 0644 cpu.asm || echo "restore of cpu.asm fails" sed 's/^X//' << 'SHAR_EOF' > cputype.c && X/* X * This program determines the cputype. X * The function returns the type. X */ X Xextern short cputype(); X Xmain() X{ X short type; X X type = cputype(); X X switch (type) { X X case 0: printf("cpu is 8086\n"); X break; X X case 20: printf("cpu is 80186\n"); X break; X X case 30: printf("cpu is 80286 in real mode\n"); X break; X X case 40: printf("cpu is 80386 in real mode\n"); X break; X X case -30: printf("cpu is 80286 in protected mode\n"); X break; X X case -40: printf("cpu is 80386 in protected mode\n"); X break; X X default: printf("unknown cpu type!\n"); X break; X } X} SHAR_EOF chmod 0644 cputype.c || echo "restore of cputype.c fails" exit 0 _/_ | ______ __. __ / o ____ | textronix!reed!littlei!zeus:martin / / / <_(_/|_/ (_<__<_/ / < |