OSDN Git Service

major changes to entire project for tweaking it amd making it cleaner!! OK PNGWEN...
[proj16/16.git] / src / lib / wcpu / wcpu.c
1 /* Project 16 Source Code~
2  * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669
3  *
4  * This file is part of Project 16.
5  *
6  * Project 16 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Project 16 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>, or
18  * write to the Free Software Foundation, Inc., 51 Franklin Street,
19  * Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22 /* tab size = 8 */
23
24 #include "src/lib/wcpu/wcpu.h"
25
26 byte detectcpu()
27 {
28         byte cputype;
29         __asm
30         {
31                 PUSHF                   ; we gonna modify flags, so back them up
32                 ; first check if its 8086/8088 or 80186/80188
33                 PUSHF                   ; FLAGS -> STACK
34                 POP     AX              ; STACK -> AX
35                 AND     AX, 00FFFh      ; clear 12-15 bits (they are always 1 on 8086/8088 and 80186/80188)
36                 PUSH    AX              ; AX -> STACK
37                 POPF                    ; STACK -> FLAGS
38                 ; this is where magic happen
39                 PUSHF                   ; FLAGS -> STACK
40                 POP     AX              ; STACK -> AX
41                 AND     AX, 0F000h      ; 0-11 bits aren't important to us
42                 CMP     AX, 0F000h      ; check if all 12-15 bits are set (simple comparision)
43                 JNE     _286p           ; if no, 286+ CPU
44                 MOV     cputype, 0      ; if yes, we are done, set cputype to 0 and end this
45                 JMP     _done
46         _286p:
47                 ; now check if its 286 or newer
48                 PUSHF                   ; FLAGS -> STACK
49                 POP     AX              ; STACK -> AX
50                 OR      AX, 07000h      ; set 12-14 bits (they are always cleared by 286 if its real mode)
51                 PUSH    AX              ; AX -> STACK
52                 POPF                    ; STACK -> FLAGS
53                 ; this is where magic happen
54                 PUSHF                   ; FLAGS -> STACK
55                 POP     AX              ; STACK -> AX
56                 TEST    AX, 07000h      ; check if at least 1 bit in 12-14 bits range is set (15th won't be set anyway)
57                 JNZ     _386p           ; not all bits clear, its 386+
58                 MOV     cputype, 1      ; all bits clear, its 286, we are done
59                 JMP     _done
60         _386p:
61                 MOV     cputype, 2      ; its 386 or newer, but we don't care if its newer at this point
62         _done:
63                 POPF                    ; restore flags we backed up earlier
64         }
65         return cputype;
66 }
67
68 #ifdef TEST
69 int main(int argc, char **argv)
70 {
71         const char *cpus;
72         unsigned char cput;
73
74         cput = detectcpu();
75         switch(cput)
76         {
77                 case 0: cpus = "8086/8088 or 186/88"; break;
78                 case 1: cpus = "286"; break;
79                 case 2: cpus = "386 or newer"; break;
80                 default: cpus = "internal error"; break;
81         }
82         printf("detected CPU type: %s\n", cpus);
83         return 0;
84 }
85 #endif
86