;cpu: Identify CPU and FPU type v2.23;
;Copyright (c) 1992-2022 by Takayuki Hosoda. All rights reserved.;
;cpu is free software with ABSOLUTELY NO WARRANTY.;
;This program was assembled by Borland's TASM Ver.3.0.;
;[vendorstring] CPU processor [of id:xxxx] with[out|FPU] fpu;
TRUE equ 1
FALSE equ 0
COPYRIGHT equ TRUE
PRINT_FEATURE equ TRUE
CR equ 0dh
LF equ 0ah
MSEOF equ 1ah
I86 equ 00h
I186 equ 01h
V30 equ 02h
V33 equ 03h
I286 equ 04h
I386 equ 05h
C486 equ 06h
I486 equ 07h
X486 equ 08h
P586 equ 09h
;Pentium equ 0ah
P686 equ 0bh
;P6 family equ 0ch
PUNKNOWN equ 0dh
P786 equ 0eh
;Pentium 4 family equ 0fh
FPU equ 1
NDP287 equ 2
NDP387 equ 3
INTEL equ 01h
PUTS macro msg
mov ah, 09h
mov dx, offset msg
int 21h
endm
cpuid macro op
mov eax, op
db 0fh, 0a2h
endm
.386P
CODE SEGMENT USE16
ASSUME CS:CODE,DS:CODE
ORG 0100H
start:
; initial hack and variables;
fputype label
fp_status dw 432dh
signiture db 50h, 55h, 2dh, 1ah
max_id db 00h
cputype db 'X'
push cs
pop ds
push cs
pop es
cld
; print copyright;
mov si, 0080h
lodsb
and al, al
jz short get_cpu
puts copy_right
mov ah, 04ch
int 21h
get_cpu:
call check_cpu
mov byte ptr cputype, al
print_vendor:
mov al, byte ptr max_id
cmp al, 1
jb short print_cpu
puts vdr_id
print_cpu:
mov bl, byte ptr cputype
xor bh, bh
mov bl, byte ptr [offset cpu_tbl + bx]
mov dx, offset cpu_tbl
add dx, bx
mov ah, 09h
int 21h
puts processor
mov al, byte ptr max_id
cmp al, 2
jb @1
puts of_id
mov ebx, dword ptr signiture
mov di, offset fms_num
call print_hex
@1:
puts with
get_fpu:
call check_fpu
mov byte ptr fputype, al
; print_fpu;
or al, al
mov dx, offset nofpu
jz short print_fpu
mov bl, byte ptr cputype
cmp bl, I286
mov dx, offset fpu_87
jb short print_fpu
mov dx, offset fpu_287
cmp al, NDP287
jz short print_fpu
mov dx, offset fpu_onchip
cmp bl, I486
jae short short print_fpu
mov dx, offset fpu_387
print_fpu:
mov ah, 9
int 21h
puts fpu_det
; print_feature;
cmp byte ptr max_id, 1
jb short exit
; print features;
puts feature_flag
mov ebx, dword ptr feature
mov si, offset edx_feature
call show_feature
mov ebx, dword ptr xfeature
or ebx, ebx
jz exit
puts feature_cont
mov si, offset ecx_feature
call show_feature
jmp exit
show_feature proc
or ebx, ebx
jz short end_feature
test bl, 1
jz short shift_feature
push bx
push si
mov dx, si
mov ah, 9
int 21h
pop si
pop bx
shift_feature:
lodsb
cmp al, '$'
jne short shift_feature
shr ebx, 1
cmp bl, 0
jne short comma
jmp short show_feature
comma:
dec si
mov byte ptr [si], ','
jmp short show_feature
end_feature:
ret
endp
exit:
mov al, byte ptr fputype
shl al, 1
shl al, 1
shl al, 1
shl al, 1
or al, byte ptr cputype
mov ah, 04ch
int 21h
;input
; ebx dword ptr variable
; offset fms_num
print_hex proc
mov di, offset fms_num
mov cx, 8
print_hex_loop:
rol ebx, 4
mov al, bl
and al, 0fh
cmp al, 9
jbe @2
add al, 'A' - '0' - 10
@2:
add al, '0'
stosb
loop print_hex_loop
puts fms_num
ret
endp
check_fpu proc
; is fpu;
mov si, offset fp_status ; initialize with non-zero
xor bx, bx
fninit
fnstsw word ptr [si]
mov ax, word ptr [si]
cmp al, 0
jne short end_fpu ; no fpu
; check controll word;
fnstcw word ptr [si]
mov ax, word ptr [si]
and ax, 103fh
cmp ax, 3fh
jne short end_fpu ; incorrect controll word, no fpu
mov bl, 1 ; fpu present
cmp byte ptr cputype, i386
jne end_fpu
fld1
fldz
fdiv
fld st
fchs
fcompp
fstsw word ptr [si]
mov ax, [si]
mov bl, 2
sahf
jz short end_fpu ; i8087 or i287 NDP present
mov bl, 3 ; i387 NDP present
end_fpu:
mov ax, bx
ret
endp
check_cpu proc
test_8086:
mov cl, 33
mov al, 1
shl al, cl
or al, al
jnz short test_186
test_v30:
mov ax, sp
pusha
nop
nop
nop
nop
nop
cmp ax, sp
jne short test_v30_end
mov al, I86
ret
test_v30_end:
popa
test_v33:
mov ax, 0100h
aad 0h
mov al, V33
jz short nec_v33
mov al, V30
nec_v33:
ret
test_186:
pushf
pop ax
test ax, 08000h
jz short test_286
mov al, I186
ret
test_286:
or ax, 04000h
push ax
popf
pushf
pop ax
test ax, 04000h
jnz short test_386
mov al, I286
ret
test_386:
pushfd
pop eax
bts eax, 18
push eax
popfd
pushfd
pop eax
bt eax, 18
jc short test_cpuid
mov al, I386
ret
test_cpuid:
pushfd
pushfd
pop eax
bts eax, 21
push eax
popfd
pushfd
pop eax
popfd
bt eax, 21
jc short get_vendor ; have CPUID instruction
test_Cx486:
mov al, 08h
add al, 08h
and al, 00h
daa
cmp al, 06h
mov al, C486
je short cylix_486
mov al, I486
cylix_486:
ret
get_vendor:
cpuid 0; Highest Function Parameter and Manufacturer ID
mov di, offset vdr_id
mov dword ptr [di], ebx
mov dword ptr [di+4], edx
mov dword ptr [di+8], ecx
or eax, eax
pushf
; check intel;
mov si, offset vdr_id
mov di, offset intel_id
mov cx, 12
repe cmpsb
or cx, cx
jnz check_end
mov byte ptr vendor_flag, INTEL
check_end:
popf
jnz short get_cpuid
mov al, X486
ret
get_cpuid:
inc al
mov byte ptr max_id, al
cpuid 1; Processor Info and Feature Bits
mov dword ptr signiture, eax
mov dword ptr feature, edx
mov dword ptr xfeature, ecx
and ah, 0fh ; Family ID
mov al, X486
cmp ah, 5
jb pre_586
mov al, P586
cmp ah, 5
je short end_id
mov al, P686
cmp ah, 6
je short end_id
mov al, P786
cmp ah, 0fh
jae short end_id
mov al, PUNKNOWN
ret
end_id:
add al, byte ptr vendor_flag
pre_586:
ret
endp
of_id db " of id:$"
fms_num db " h$"
cpu_tbl db cpu86 - cpu_tbl
db cpu186 - cpu_tbl
db cpv30 - cpu_tbl
db cpv33 - cpu_tbl
db cpu286 - cpu_tbl
db cpu386 - cpu_tbl
db cpc486 - cpu_tbl
db cpu486 - cpu_tbl
db cpx486 - cpu_tbl
db cpu586 - cpu_tbl
db pentium - cpu_tbl
db cpu686 - cpu_tbl
db pentiumpro - cpu_tbl
db cpuunknown - cpu_tbl
db cpu786 - cpu_tbl
db pentium4 - cpu_tbl
vdr_id label
cpu86 db "8086$"
cpu186 db "186$"
cpv30 db "V30 $"
cpv33 db "V33$"
cpu286 db "286$"
cpu386 db "386$"
cpx486 db "Enhanced "
cpu486 db "486$"
cpc486 db "Cx486$"
cpu586 db "586$"
pentium db "Pentium$"
cpu686 db "686 family$"
pentiumpro db "P6 family$"
cpuunknown db "Unknown$"
cpu786 db "786 family$"
pentium4 db "Pentium 4 family$"
processor db " processor$"
with db " with$"
nofpu db "out$"
fpu_87 db " 8087$"
fpu_287 db " 287$"
fpu_387 db " 387$"
fpu_onchip db " on-chip$"
fpu_det db " fpu", CR, LF, "$"
vendor_flag db 0
intel_id db "GenuineIntel"
feature db 0, 0, 0, 0
xfeature db 0, 0, 0, 0
; FEATURES;
newline db CR, LF, "$"
signiture_flag db "signiture: $"
feature_flag db "features: $"
feature_cont db ",$"
edx_feature db "fpu$vme$de$pse$"
db "tsc$msr$pae$mce$"
db "cmpxchg8b$apic$b10$sep$"
db "mtrr$pge$mca$cmov$"
db "fcmov$pse-36$psn$clfsh$"
db "b20$ds$acpi$mmx$"
db "fxsr$sse$sse2$ss$"
db "htt$tm$ia64$pbe$"
ecx_feature db "sse3$pclmulqdq$dtes64$monitor$"
db "ds-cpl$vmx$smx$est$"
db "tm2$ssse3$cnnxt-id$sdbg$"
db "fma$cx16$xtpr$pppdcm$"
db "c16$ppcid$dca$sse4.1$"
db "sse4.2$x2apic$movbe$poppcnt$"
db "tsc-deadline$aes$xsave$"
db "osxsave$avx$f16c$rdrnd$hyppervisor$"
dump_feature db "b0$b1$b2$b3$b4$b5$b6$b7$"
db "b8$b9$b10$b11$b12$b13$b14$b15$"
db "b16$b17$b18$b19$b20$b21$b22$b23$"
db "b24$b25$b26$b27$b28$b29$b30$b31$"
copy_right db "cpu: Identify cpu and fpu v2.23 (Feb. 8, 2022)",CR,LF
db "(c) 1992-2022, Takayuki HOSODA.",CR,LF
db "cpu is free software with "
db "ABSOLUTELY NO WARRANTY.$"
CODE ENDS
END start