2012-10-15 02:08:06 +02:00
|
|
|
; File:
|
|
|
|
; cpu.asm
|
|
|
|
; Description:
|
|
|
|
; Query basic CPU running on
|
|
|
|
;
|
|
|
|
; DOS-C
|
|
|
|
; Copyright (c) 2012
|
|
|
|
; FreeDOS
|
|
|
|
; All Rights Reserved
|
|
|
|
;
|
|
|
|
; This file is part of DOS-C.
|
|
|
|
;
|
|
|
|
; DOS-C is free software; you can redistribute it and/or
|
|
|
|
; modify it under the terms of the GNU General Public License
|
|
|
|
; as published by the Free Software Foundation; either version
|
|
|
|
; 2, or (at your option) any later version.
|
|
|
|
;
|
|
|
|
; DOS-C is distributed in the hope that it will be useful, but
|
|
|
|
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
|
|
|
; the GNU General Public License for more details.
|
|
|
|
;
|
|
|
|
;
|
|
|
|
|
|
|
|
%include "segs.inc"
|
|
|
|
segment INIT_TEXT
|
|
|
|
|
|
|
|
CPU 386
|
|
|
|
;*********************************************************************
|
|
|
|
;
|
|
|
|
; UWORD query_cpu() based on Eric Auer's public domain cpulevel.asm
|
|
|
|
; input: none
|
|
|
|
; output: ax = cpu, 0=8086/8088, 1=186/188, 2=286, 3=386+
|
|
|
|
global _query_cpu
|
|
|
|
_query_cpu:
|
|
|
|
; save registers, assumes enough space on stack & valid stack frame setup
|
|
|
|
;push ax - no need to save, return value saved here
|
|
|
|
push bx
|
|
|
|
push cx
|
|
|
|
pushf ; save flags
|
|
|
|
|
|
|
|
; begin check, assume x86 unless later family detected
|
|
|
|
xor bx, bx ; 808x or 186 highest detected family stored in bx
|
|
|
|
push bx
|
|
|
|
popf ; try to clear all flag bits
|
|
|
|
pushf ; copy flags to ax so we can test if clear succeeded
|
|
|
|
pop ax
|
|
|
|
and ax, 0f000h
|
|
|
|
cmp ax, 0f000h
|
|
|
|
jnz is286 ; no the 4 msb stuck set to 1, so is a 808x or 8018x
|
2024-02-04 04:19:02 +01:00
|
|
|
; NEC V20/V30 support 186 instructions but
|
|
|
|
; do not mask the shift count like a 186.
|
|
|
|
; based on https://hg.pushbx.org/ecm/ldebug/file/7f3440d5824d/source/init.asm#l3071
|
|
|
|
; which is based on http://www.textfiles.com/hamradio/v20_bug.txt
|
|
|
|
mov ax, sp ; we use stack to do test
|
2024-02-05 01:38:42 +01:00
|
|
|
mov cx, 0 ; after pop still 0 if 8088/8086
|
2024-02-04 04:19:02 +01:00
|
|
|
push cx
|
2024-02-05 01:38:42 +01:00
|
|
|
inc cx ; after pop still 1 if NEC V20/V30
|
2024-02-04 04:19:02 +01:00
|
|
|
; next instructions may lock system if breakpoint or trace flag set
|
|
|
|
db 8Fh, 0C1h; pop r/m16 with operand cx on 808x, nop on NEC V20/V30
|
|
|
|
mov sp, ax ; reset stack to known good state (pre push, optional pop)
|
2024-02-05 01:38:42 +01:00
|
|
|
or cx, cx ; cx is 0 if 808x, 1 if NEC
|
|
|
|
jz is808x ; if not NEC then goto test for 808x vs 8018x
|
|
|
|
mov bx, cx ; treat NEC V20/V30 as 8018x, i.e. return 1
|
2024-02-04 04:19:02 +01:00
|
|
|
jmp short cleanup
|
|
|
|
is808x:
|
2012-10-15 02:08:06 +02:00
|
|
|
mov ax,1 ; determine if 8086 or 186
|
|
|
|
mov cl,64 ; try to shift further than size of ax
|
|
|
|
shr ax,cl
|
|
|
|
or ax,ax
|
|
|
|
jz is086 ; 186 ignores the upper bits of cl
|
|
|
|
mov bx, 1 ; 186: above 808x, below 286
|
|
|
|
is086: jmp short cleanup
|
|
|
|
is286: mov bx, 2 ; at least 286
|
|
|
|
mov ax, 0f000h
|
|
|
|
push ax
|
|
|
|
popf ; try to set 4 msb of flags
|
|
|
|
pushf ; copy flags to ax so we can test if clear succeeded
|
|
|
|
pop ax
|
|
|
|
test ax, 0f000h
|
|
|
|
jz cleanup ; 4 msb stuck to 0: 80286
|
|
|
|
mov bx, 3 ; at least 386
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
mov ax, bx ; return CPU family
|
|
|
|
popf
|
|
|
|
pop cx
|
|
|
|
pop bx
|
|
|
|
retn
|
|
|
|
|