1 /* Project 16 Source Code~
\r
2 * Copyright (C) 2012-2016 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover
\r
4 * This file is part of Project 16.
\r
6 * Project 16 is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 3 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Project 16 is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program. If not, see <http://www.gnu.org/licenses/>, or
\r
18 * write to the Free Software Foundation, Inc., 51 Franklin Street,
\r
19 * Fifth Floor, Boston, MA 02110-1301 USA.
\r
24 #include "src/lib/wcpu/16_wcpu.h"
\r
26 //#define USECPUPROBE
\r
28 byte WCPU_detectfpu()
\r
34 PUSHF ; we gonna modify flags, so back them up
\r
35 .8087 fninit ; Initialize FPU
\r
36 // mov [WORD PTR funk], 55AAh ; Set junk value
\r
37 // fnstsw funk ; Store status word
\r
38 // cmp [BYTE PTR funk], 0 ; If it's not 0, no FPU
\r
39 mov funk, 55AAh ; Set junk value
\r
40 fnstsw funk ; Store status word
\r
41 cmp funk, 0 ; If it's not 0, no FPU
\r
52 fnstcw funk ; Store control word
\r
53 mov ax, funk ; If the bits are not the way
\r
54 and ax, 103Fh ; they should be, no FPU
\r
66 // and [WORD PTR funk], 0FF7Fh ; Clear interrupt bit
\r
67 and funk, 0FF7Fh ; Clear interrupt bit
\r
68 fldcw funk ; Load control word
\r
69 fdisi ; Disable interrupts
\r
70 fstcw funk ; Store control word
\r
71 // test [BYTE PTR funk], 80h ; If it changed, it's an 8087
\r
72 test funk, 80h ; If it changed, it's an 8087
\r
76 POPF ; restore flags we backed up earlier
\r
78 //printf("WCPU_detectfpu():\n fputype=%u\n funk=%u errflag=%u\n", fputype, funk, errflag);
\r
80 if (cpu_flags & CPU_FLAG_FPU) printf(" - With FPU\n");
\r
85 byte WCPU_detectcpu()
\r
89 PUSHF ; we gonna modify flags, so back them up
\r
90 ; first check if its 8086/8088 or 80186/80188
\r
91 PUSHF ; FLAGS -> STACK
\r
92 POP AX ; STACK -> AX
\r
93 AND AX, 00FFFh ; clear 12-15 bits (they are always 1 on 8086/8088 and 80186/80188)
\r
94 PUSH AX ; AX -> STACK
\r
95 POPF ; STACK -> FLAGS
\r
96 ; this is where magic happen
\r
97 PUSHF ; FLAGS -> STACK
\r
98 POP AX ; STACK -> AX
\r
99 AND AX, 0F000h ; 0-11 bits aren't important to us
\r
100 CMP AX, 0F000h ; check if all 12-15 bits are set (simple comparision)
\r
101 JNE _286p ; if no, 286+ CPU
\r
102 MOV cputype, 0 ; if yes, we are done, set cputype to 0 and end this
\r
105 ; now check if its 286 or newer
\r
106 PUSHF ; FLAGS -> STACK
\r
107 POP AX ; STACK -> AX
\r
108 OR AX, 07000h ; set 12-14 bits (they are always cleared by 286 if its real mode)
\r
109 PUSH AX ; AX -> STACK
\r
110 POPF ; STACK -> FLAGS
\r
111 ; this is where magic happen
\r
112 PUSHF ; FLAGS -> STACK
\r
113 POP AX ; STACK -> AX
\r
114 TEST AX, 07000h ; check if at least 1 bit in 12-14 bits range is set (15th won't be set anyway)
\r
115 JNZ _386p ; not all bits clear, its 386+
\r
116 MOV cputype, 1 ; all bits clear, its 286, we are done
\r
119 MOV cputype, 2 ; its 386 or newer, but we don't care if its newer at this point
\r
121 POPF ; restore flags we backed up earlier
\r
126 const char *WCPU_cpudetectmesg()
\r
129 unsigned char cput;
\r
131 cput = WCPU_detectcpu();
\r
134 case 0: cpus = "8086/8088 or 186/88"; break;
\r
135 case 1: cpus = "286"; break;
\r
136 case 2: cpus = "386 or newer"; break;
\r
137 default: cpus = "internal error"; break;
\r
142 const char *WCPU_fpudetectmesg()
\r
145 unsigned char fput;
\r
147 fput = WCPU_detectfpu();
\r
150 case 0: fpus = "none"; break;
\r
151 case 1: fpus = "8087"; break;
\r
152 default: fpus = "internal error"; break;
\r
157 void WCPU_cpufpumesg()
\r
162 printf("detected CPU type: %s\n", WCPU_cpudetectmesg());
\r
163 printf("detected FPU type: %s\n", WCPU_fpudetectmesg());
\r