]> 4ch.mooo.com Git - 16.git/blob - 16/xlib/xdetect.asm
code miraculously works on real hardware
[16.git] / 16 / xlib / xdetect.asm
1 ;-----------------------------------------------------------------------\r
2 ; MODULE XDETECT\r
3 ;\r
4 ; Hardware detection module\r
5 ;\r
6 ; Compile with Tasm.\r
7 ; C callable.\r
8 ;\r
9 ;\r
10 ; ****** XLIB - Mode X graphics library                ****************\r
11 ; ******                                               ****************\r
12 ; ****** Written By Themie Gouthas                     ****************\r
13 ;\r
14 ; egg@dstos3.dsto.gov.au\r
15 ; teg@bart.dsto.gov.au\r
16 ;-----------------------------------------------------------------------\r
17 LOCALS\r
18 .8086\r
19 \r
20 include model.inc\r
21 include xdetect.inc\r
22 \r
23         .data\r
24 \r
25 _MouseButtonCount dw 0\r
26 _MouseVersion     dw 0\r
27 _MouseType        db 0\r
28 _MouseIRQ         db 0\r
29 \r
30         .code\r
31 \r
32 \r
33 i86       equ 0\r
34 i186      equ 1\r
35 i286      equ 2\r
36 i386sx    equ 3\r
37 i386dx    equ 4\r
38 i486      equ 5\r
39 \r
40 \r
41 NONE      equ 0\r
42 MDA       equ 1\r
43 CGA       equ 2\r
44 EGAMono   equ 3\r
45 EGAColor  equ 4\r
46 VGAMono   equ 5\r
47 VGAColor  equ 6\r
48 MCGAMono  equ 7\r
49 MCGAColor equ 8\r
50 \r
51 PS2_CARDS db  0,1,2,2,4,3,2,5,6,2,8,7,8\r
52 \r
53 \r
54 ;-----------------------------------------------------------------------\r
55 ; PC Graphics detection routine. Returns graphics card type\r
56 ;\r
57 ; C callable as:\r
58 ;    unsigned int x_graphics_card();\r
59 ;\r
60 ;\r
61 \r
62 proc _x_graphics_card\r
63         push bp                  ; Preserve caller's stack frame\r
64         mov  bp,sp\r
65         mov  ax,1A00h            ; Try calling VGA Identity Adapter function\r
66         int  10h\r
67         cmp  al,1Ah              ; Do we have PS/2 video bios ?\r
68         jne  @@not_PS2           ; No!\r
69 \r
70         cmp  bl,0Ch              ; bl > 0Ch => CGA hardware\r
71         jg   @@is_CGA            ; Jump if we have CGA\r
72         xor  bh,bh\r
73         xor  ah,ah\r
74         mov  al,cs:PS2_CARDS[bx] ; Load ax from PS/2 hardware table\r
75         jmp  short @@done        ; return ax\r
76 @@is_CGA:\r
77         mov  ax,CGA              ; Have detected CGA, return id\r
78         jmp  short @@done\r
79 @@not_PS2:                       ; OK We don't have PS/2 Video bios\r
80         mov  ah,12h              ; Set alternate function service\r
81         mov  bx,10h              ; Set to return EGA information\r
82         int  10h                 ; call video service\r
83         cmp  bx,10h              ; Is EGA there ?\r
84         je   @@simple_adapter    ; Nop!\r
85         mov  ah,12h              ; Since we have EGA bios, get details\r
86         mov  bl,10h\r
87         int  10h\r
88         or   bh,bh               ; Do we have colour EGA ?\r
89         jz   @@ega_color         ; Yes\r
90         mov  ax,EGAMono          ; Otherwise we have Mono EGA\r
91         jmp  short @@done\r
92 @@ega_color:\r
93         mov  ax,EGAColor         ; Have detected EGA Color, return id\r
94         jmp  short @@done\r
95 @@simple_adapter:\r
96         int  11h                 ; Lets try equipment determination service\r
97         and  al,30h\r
98         shr  al,4\r
99         xor  ah,ah\r
100         or   al,al               ; Do we have any graphics card at all ?\r
101         jz   @@done              ; No ? This is a stupid machine!\r
102         cmp  al,3                ; Do We have a Mono adapter\r
103         jne  @@is_CGA            ; No\r
104         mov  ax,MDA              ; Have detected MDA, return id\r
105 @@done:\r
106         pop  bp                  ;restore caller's stack frame\r
107         ret\r
108 _x_graphics_card endp\r
109 \r
110 \r
111 ;-----------------------------------------------------------------------\r
112 ; PC Processor detection routine\r
113 ;\r
114 ; C callable as:\r
115 ;    unsigned int x_processor();\r
116 ;\r
117 ;\r
118 proc _x_processor\r
119         push bp\r
120         mov  bp,sp\r
121         pushf                    ; Save flags\r
122         xor  ax,ax               ; Clear AX\r
123         push ax                  ; Push it on the stack\r
124         popf                     ; Zero the flags\r
125         pushf                    ; Try to zero bits 12-15\r
126         pop  ax                  ; Recover flags\r
127         and  ax,0F000h           ; If bits 12-15 are 1 => i86 or i286\r
128         cmp  ax,0F000h\r
129         jne  @@1\r
130 \r
131         push cx                  ; save CX\r
132         mov  ax,0FFFFh           ; Set all AX bits\r
133         mov  cl,33               ; Will shift once on 80186\r
134         shl  ax,cl               ; or 33 x on 8086\r
135         pop  cx\r
136         mov  ax,i186\r
137         jnz  @@done\r
138         mov  ax,i86              ; 0 => 8086/8088\r
139         jmp  short @@done\r
140 \r
141 @@1:\r
142         mov  ax,07000h           ; Try to set bits 12-14\r
143         push ax\r
144         popf\r
145         pushf\r
146         pop  ax\r
147         and  ax,07000h           ; If bits 12-14 are 0 => i286\r
148         mov  ax,i286\r
149         jz   @@done\r
150 \r
151         ;; 386/486 resolution code taken from WHATCPU.ASM by\r
152         ;; Dave M. Walker\r
153 \r
154 \r
155         P386\r
156         mov  eax,cr0\r
157         mov  ebx,eax                 ;Original CR0 into EBX\r
158         or   al,10h                  ;Set bit\r
159         mov  cr0,eax                 ;Store it\r
160         mov  eax,cr0                 ;Read it back\r
161         mov  cr0,ebx                 ;Restore CR0\r
162         test al,10h                  ;Did it set?\r
163         mov  ax,i386sx\r
164         jz   @@done                  ;Jump if 386SX\r
165 \r
166        ;*** Test AC bit in EFLAGS (386DX won't change)\r
167         mov     ecx,esp                 ;Original ESP in ECX\r
168         pushfd                          ;Original EFLAGS in EBX\r
169         pop     ebx\r
170         and     esp,not 3               ;Align stack to prevent 486\r
171                                         ;  fault when AC is flipped\r
172         mov     eax,ebx                 ;EFLAGS => EAX\r
173         xor     eax,40000h              ;Flip AC flag\r
174         push    eax                     ;Store it\r
175         popfd\r
176         pushfd                          ;Read it back\r
177         pop     eax\r
178         push    ebx                     ;Restore EFLAGS\r
179         popfd\r
180         mov     esp,ecx                 ;Restore ESP\r
181         cmp     eax,ebx                 ;Compare old/new AC bits\r
182         mov     ax,i386dx\r
183         je      @@done\r
184 is_486:                                 ;Until the Pentium appears...\r
185         mov   ax,i486\r
186 @@done:\r
187         popf\r
188         .286\r
189         pop  bp\r
190         ret\r
191 _x_processor endp\r
192 \r
193 .8086\r
194 ;-----------------------------------------------------------------------\r
195 ; PC Numeric coprocessor detection routine\r
196 ;\r
197 ; C callable as:\r
198 ;    unsigned int x_coprocessor();\r
199 ;\r
200 ;  Based on an article in PC Tech Journal, Aug 87 by Ted Forgeron\r
201 ;\r
202 ;  Returns 1 if coprocessor found, zero otherwise\r
203 \r
204 _x_coprocessor   proc\r
205 ARG     control:word=StkSize\r
206         push   bp\r
207         mov    bp,sp\r
208         sub    sp,StkSize\r
209 \r
210         fninit                          ; try to initialize the copro.\r
211         mov    [control],0              ; clear control word variable\r
212         fnstcw control                  ; put control word in memory\r
213         mov    ax,[control]             ;\r
214         cmp    ah,03h                   ; do we have a coprocessor ?\r
215         je     @@HaveCopro              ; jump if yes!\r
216         xor    ax,ax                    ; return 0 since nothing found\r
217         jmp    short @@done\r
218 @@HaveCopro:\r
219         mov    ax,1\r
220 @@done:\r
221         mov    sp,bp\r
222         pop    bp\r
223         ret\r
224 _x_coprocessor   endp\r
225 \r
226 \r
227 ;-----------------------------------------------------------------------\r
228 ; PC Mouse Driver detection routine\r
229 ;\r
230 ; C callable as:\r
231 ;    unsigned int x_mousedriver();\r
232 ;\r
233 ;\r
234 ;  Returns 1 if mouse driver found, zero otherwise\r
235 _x_mousedriver proc\r
236                push bp\r
237                mov  bp,sp\r
238                mov  ax,3533h        ; Get int 33 interrupt vector\r
239                int  21h             ; Call dos\r
240                xor  cx,cx           ; Clear "found" flag\r
241                mov  ax,es           ; Is the vector null (ES==0 && BX==0) ?\r
242                or   bx,ax\r
243                jz   @@NoMouseDriver ; Yes! No mouse driver installed - Jump\r
244 \r
245                ; Just make absolutely sure the vector points to the mouse\r
246                ; driver (just in case)\r
247 \r
248                xor  ax,ax           ; FUNC 0: Mouse Initialization\r
249                int   33h\r
250                or    ax,ax          ; Do we have an installed mouse driver ?\r
251                jz    @@NoMouseDriver; No ?\r
252                mov   [_MouseButtonCount],bx\r
253 \r
254                mov   ax,24h\r
255                int   33h\r
256                mov   [_MouseVersion],bx\r
257                mov   [_MouseType],ch\r
258                mov   [_MouseIRQ],cl\r
259 \r
260                mov  cx,1            ; Yes! set flag\r
261 \r
262 @@NoMouseDriver:\r
263                mov  ax,cx           ; Return "found" flag\r
264                pop  bp\r
265                ret\r
266 _x_mousedriver endp\r
267 \r
268 \r
269 end\r