1 | ; **********************************************************************
|
---|
2 | ; Copyright (C) 1995 by Holger Veit (Holger.Veit@gmd.de)
|
---|
3 | ; Use at your own risk! No Warranty! The author is not responsible for
|
---|
4 | ; any damage or loss of data caused by proper or improper use of this
|
---|
5 | ; device driver.
|
---|
6 | ; **********************************************************************
|
---|
7 | ;
|
---|
8 | ; compile with ALP
|
---|
9 | ;
|
---|
10 | TITLE ICCIO.ASM
|
---|
11 | .386
|
---|
12 | .387
|
---|
13 |
|
---|
14 | DATA32 SEGMENT DWORD PUBLIC USE32 'DATA'
|
---|
15 | ASSUME CS:FLAT ,DS:FLAT,SS:FLAT
|
---|
16 | EXTRN ioentry:DWORD
|
---|
17 | EXTRN gdt:WORD
|
---|
18 | EXTRN devname:BYTE
|
---|
19 | DATA32 ENDS
|
---|
20 |
|
---|
21 | CODE32 SEGMENT DWORD PUBLIC USE32 'CODE'
|
---|
22 | ASSUME CS:FLAT ,DS:FLAT,SS:FLAT
|
---|
23 |
|
---|
24 | ALIGN 04H
|
---|
25 |
|
---|
26 | ; performs fast output of a byte to an I/O port
|
---|
27 | ; this routine is intended to be called from icc C code
|
---|
28 | ;
|
---|
29 | ; Calling convention:
|
---|
30 | ; void _c_outb(short port,char data)
|
---|
31 | ;
|
---|
32 | ;
|
---|
33 | PUBLIC _c_outb
|
---|
34 | _c_outb PROC
|
---|
35 | MOV EDX, DWORD PTR [ESP+4] ; get port
|
---|
36 | MOV AL, BYTE PTR [ESP+8] ; get data
|
---|
37 | PUSH EBX ; save register
|
---|
38 | MOV EBX, 4 ; function code 4 = write byte
|
---|
39 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
40 | POP EBX
|
---|
41 | RET
|
---|
42 | _c_outb ENDP
|
---|
43 |
|
---|
44 | ; performs fast output of a word to an I/O port
|
---|
45 | ; this routine is intended to be called from icc C code
|
---|
46 | ;
|
---|
47 | ; Calling convention:
|
---|
48 | ; void _c_outw(short port,short data)
|
---|
49 | ;
|
---|
50 | ;
|
---|
51 | ALIGN 04H
|
---|
52 |
|
---|
53 | PUBLIC _c_outw
|
---|
54 | _c_outw PROC
|
---|
55 | MOV EDX, DWORD PTR [ESP+4] ; get port
|
---|
56 | MOV AX, WORD PTR [ESP+8] ; get data
|
---|
57 | PUSH EBX ; save register
|
---|
58 | MOV EBX, 5 ; function code 5 = write word
|
---|
59 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
60 | POP EBX
|
---|
61 | RET
|
---|
62 | _c_outw ENDP
|
---|
63 |
|
---|
64 | ; performs fast output of a dword to an I/O port
|
---|
65 | ; this routine is intended to be called from icc C code
|
---|
66 | ;
|
---|
67 | ; Calling convention:
|
---|
68 | ; void _c_outl(short port,long data)
|
---|
69 | ;
|
---|
70 | ;
|
---|
71 | ALIGN 04H
|
---|
72 |
|
---|
73 | PUBLIC _c_outl
|
---|
74 | _c_outl PROC
|
---|
75 | MOV EDX, DWORD PTR [ESP+4] ; get port
|
---|
76 | MOV EAX, DWORD PTR [ESP+8] ; get data
|
---|
77 | PUSH EBX ; save register
|
---|
78 | MOV EBX, 6 ; function code 6 = write dword
|
---|
79 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
80 | POP EBX
|
---|
81 | RET
|
---|
82 | _c_outl ENDP
|
---|
83 |
|
---|
84 | ; performs fast input of a byte from an I/O port
|
---|
85 | ; this routine is intended to be called from gcc C code
|
---|
86 | ;
|
---|
87 | ; Calling convention:
|
---|
88 | ; char _c_inb(short port)
|
---|
89 | ;
|
---|
90 | ;
|
---|
91 | ALIGN 04H
|
---|
92 | PUBLIC _c_inb
|
---|
93 | _c_inb PROC
|
---|
94 | MOV EDX, DWORD PTR [ESP+4] ; get port number
|
---|
95 | PUSH EBX ; save register
|
---|
96 | MOV EBX, 1 ; function code 1 = read byte
|
---|
97 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
98 | AND EAX, 000000ffH ; mask out required byte
|
---|
99 | POP EBX ; restore register
|
---|
100 | RET
|
---|
101 | _c_inb ENDP
|
---|
102 |
|
---|
103 | ; performs fast input of a word from an I/O port
|
---|
104 | ; this routine is intended to be called from gcc C code
|
---|
105 | ;
|
---|
106 | ; Calling convention:
|
---|
107 | ; short _c_inw(short port)
|
---|
108 | ;
|
---|
109 | ;
|
---|
110 | ALIGN 04H
|
---|
111 | PUBLIC _c_inw
|
---|
112 | _c_inw PROC
|
---|
113 | MOV EDX, DWORD PTR [ESP+4] ; get port number
|
---|
114 | PUSH EBX ; save register
|
---|
115 | MOV EBX, 2 ; function code 2 = read short
|
---|
116 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
117 | AND EAX, 0000ffffH ; mask out required byte
|
---|
118 | POP EBX ; restore register
|
---|
119 | RET
|
---|
120 | _c_inw ENDP
|
---|
121 |
|
---|
122 | ; performs fast input of a dword from an I/O port
|
---|
123 | ; this routine is intended to be called from gcc C code
|
---|
124 | ;
|
---|
125 | ; Calling convention:
|
---|
126 | ; long _c_inl(short port)
|
---|
127 | ;
|
---|
128 | ;
|
---|
129 | ALIGN 04H
|
---|
130 | PUBLIC _c_inl
|
---|
131 | _c_inl PROC
|
---|
132 | MOV EDX, DWORD PTR [ESP+4] ; get port number
|
---|
133 | PUSH EBX ; save register
|
---|
134 | MOV EBX, 3 ; function code 3 = read long
|
---|
135 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
136 | ; AND EAX, 000000ffH ; mask out required byte
|
---|
137 | POP EBX ; restore register
|
---|
138 | RET
|
---|
139 | _c_inl ENDP
|
---|
140 |
|
---|
141 | ALIGN 4
|
---|
142 | PUBLIC _c_readmsr
|
---|
143 | _c_readmsr PROC NEAR
|
---|
144 | PUSH EBP
|
---|
145 | MOV EBP, ESP
|
---|
146 | PUSH EAX
|
---|
147 | PUSH EBX
|
---|
148 | PUSH ECX
|
---|
149 | PUSH EDX ; save register
|
---|
150 | MOV ECX, DWORD PTR [EBP+8] ; get msr reg
|
---|
151 | MOV EBX, 7 ; function code 7 = read msr
|
---|
152 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
153 | MOV EBX, DWORD PTR [EBP+12] ; LONGLONG ptr
|
---|
154 | MOV DWORD PTR [EBX+4], EDX
|
---|
155 | MOV DWORD PTR [EBX], EAX
|
---|
156 | POP EDX
|
---|
157 | POP ECX
|
---|
158 | POP EBX ; restore register
|
---|
159 | POP EAX
|
---|
160 | POP EBP
|
---|
161 | RET
|
---|
162 | _c_readmsr ENDP
|
---|
163 |
|
---|
164 | ;------------------------------------------------------------------------------
|
---|
165 |
|
---|
166 | ; performs fast output of a byte to an I/O port
|
---|
167 | ; this routine is intended to be called from assembler code
|
---|
168 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
169 | ;
|
---|
170 | ; calling convention:
|
---|
171 | ; MOV EDX, portnr
|
---|
172 | ; MOV AL, data
|
---|
173 | ; CALL a_outb
|
---|
174 | ;
|
---|
175 | ;
|
---|
176 | ALIGN 04H
|
---|
177 | PUBLIC a_outb
|
---|
178 | a_outb PROC
|
---|
179 | PUSH EBX ; save register
|
---|
180 | MOV EBX, 4 ; function code 4 = write byte
|
---|
181 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
182 | POP EBX ; restore bx
|
---|
183 | RET
|
---|
184 | a_outb ENDP
|
---|
185 |
|
---|
186 | ; performs fast output of a word to an I/O port
|
---|
187 | ; this routine is intended to be called from assembler code
|
---|
188 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
189 | ;
|
---|
190 | ; calling convention:
|
---|
191 | ; MOV EDX, portnr
|
---|
192 | ; MOV AX, data
|
---|
193 | ; CALL a_outw
|
---|
194 | ;
|
---|
195 | ;
|
---|
196 | ALIGN 04H
|
---|
197 | PUBLIC a_outw
|
---|
198 | a_outw PROC
|
---|
199 | PUSH EBX ; save register
|
---|
200 | MOV EBX, 5 ; function code 5 = write word
|
---|
201 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
202 | POP EBX ; restore bx
|
---|
203 | RET
|
---|
204 | a_outw ENDP
|
---|
205 |
|
---|
206 | ; performs fast output of a long to an I/O port
|
---|
207 | ; this routine is intended to be called from assembler code
|
---|
208 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
209 | ;
|
---|
210 | ; calling convention:
|
---|
211 | ; MOV EDX, portnr
|
---|
212 | ; MOV EAX, data
|
---|
213 | ; CALL a_outl
|
---|
214 | ;
|
---|
215 | ;
|
---|
216 | ALIGN 04H
|
---|
217 | PUBLIC a_outl
|
---|
218 | a_outl PROC
|
---|
219 | PUSH EBX ; save register
|
---|
220 | MOV EBX, 6 ; function code 6 = write long
|
---|
221 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
222 | POP EBX ; restore bx
|
---|
223 | RET
|
---|
224 | a_outl ENDP
|
---|
225 |
|
---|
226 | ; performs fast input of a byte from an I/O port
|
---|
227 | ; this routine is intended to be called from assembler code
|
---|
228 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
229 | ;
|
---|
230 | ; calling convention:
|
---|
231 | ; MOV EDX, portnr
|
---|
232 | ; CALL a_inb
|
---|
233 | ; ;data in AL
|
---|
234 | ;
|
---|
235 | ALIGN 04H
|
---|
236 | PUBLIC a_inb
|
---|
237 | a_inb PROC
|
---|
238 | PUSH EBX ; save register
|
---|
239 | MOV EBX, 1 ; function code 1 = read byte
|
---|
240 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
241 | AND EAX, 000000FFh ; mask byte
|
---|
242 | POP EBX ; restore register
|
---|
243 | RET
|
---|
244 | a_inb ENDP
|
---|
245 |
|
---|
246 |
|
---|
247 | ; performs fast input of a word from an I/O port
|
---|
248 | ; this routine is intended to be called from assembler code
|
---|
249 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
250 | ;
|
---|
251 | ; calling convention:
|
---|
252 | ; MOV EDX, portnr
|
---|
253 | ; CALL a_inb
|
---|
254 | ; ;data in AX
|
---|
255 | ;
|
---|
256 | ALIGN 04H
|
---|
257 | PUBLIC a_inw
|
---|
258 | a_inw PROC
|
---|
259 | PUSH EBX ; save register
|
---|
260 | MOV EBX, 2 ; function code 2 = read word
|
---|
261 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
262 | AND EAX, 0000FFFFh ; mask byte
|
---|
263 | POP EBX ; restore register
|
---|
264 | RET
|
---|
265 | a_inw ENDP
|
---|
266 |
|
---|
267 | ; performs fast input of a dword from an I/O port
|
---|
268 | ; this routine is intended to be called from assembler code
|
---|
269 | ; note there is no stack frame, however 8 byte stack space is required
|
---|
270 | ;
|
---|
271 | ; calling convention:
|
---|
272 | ; MOV EDX, portnr
|
---|
273 | ; CALL a_inl
|
---|
274 | ; ;data in EAX
|
---|
275 | ;
|
---|
276 | ALIGN 04H
|
---|
277 | PUBLIC a_inl
|
---|
278 | a_inl PROC
|
---|
279 | PUSH EBX ; save register
|
---|
280 | MOV EBX, 3 ; function code 3 = read dword
|
---|
281 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
282 | POP EBX ; restore register
|
---|
283 | RET
|
---|
284 | a_inl ENDP
|
---|
285 |
|
---|
286 | CODE32 ENDS
|
---|
287 |
|
---|
288 | ;------------------------------------------------------------------------------
|
---|
289 |
|
---|
290 | ; Initialize I/O access via the driver.
|
---|
291 | ; You *must* call this routine once for each executable that wants to do
|
---|
292 | ; I/O.
|
---|
293 | ;
|
---|
294 | ; The routine is mainly equivalent to a C routine performing the
|
---|
295 | ; following (but no need to add another file):
|
---|
296 | ; DosOpen("/dev/fastio$", read, nonexclusive)
|
---|
297 | ; DosDevIOCtl(device, XFREE86_IO, IO_GETSEL32)
|
---|
298 | ; selector -> ioentry+4
|
---|
299 | ; DosClose(device)
|
---|
300 | ;
|
---|
301 | ; Calling convention:
|
---|
302 | ; int io_init(void)
|
---|
303 | ; Return:
|
---|
304 | ; 0 if successful
|
---|
305 | ; standard APIRET return code if error
|
---|
306 | ;
|
---|
307 |
|
---|
308 | CODE32 SEGMENT
|
---|
309 | PUBLIC _io_init
|
---|
310 | EXTRN DosOpen:PROC
|
---|
311 | EXTRN DosClose:PROC
|
---|
312 | EXTRN DosDevIOCtl:PROC
|
---|
313 | _io_init PROC
|
---|
314 | PUSH EBP
|
---|
315 | MOV EBP, ESP ; standard stack frame
|
---|
316 | SUB ESP, 16 ; reserve memory
|
---|
317 | ; -16 = len arg of DosDevIOCtl
|
---|
318 | ; -12 = action arg of DosOpen
|
---|
319 | ; -8 = fd arg of DosOpen
|
---|
320 | ; -2 = short GDT selector arg
|
---|
321 | PUSH 0 ; (PEAOP2)NULL
|
---|
322 | PUSH 66 ; OPEN_ACCESS_READWRITE|OPEN_SHARE_DENYNONE
|
---|
323 | PUSH 1 ; FILE_OPEN
|
---|
324 | PUSH 0 ; FILE_NORMAL
|
---|
325 | PUSH 0 ; initial size
|
---|
326 | LEA EAX, [EBP-12] ; Adress of 'action' arg
|
---|
327 | PUSH EAX
|
---|
328 | LEA EAX, [EBP-8] ; Address of 'fd' arg
|
---|
329 | PUSH EAX
|
---|
330 | PUSH OFFSET devname
|
---|
331 | CALL DosOpen ; call DosOpen
|
---|
332 | ADD ESP, 32 ; cleanup stack frame
|
---|
333 | CMP EAX, 0 ; is return code zero?
|
---|
334 | JE goon ; yes, proceed
|
---|
335 | LEAVE ; no return error
|
---|
336 | RET
|
---|
337 |
|
---|
338 | ALIGN 04H
|
---|
339 | goon:
|
---|
340 | LEA EAX, [EBP-16] ; address of 'len' arg of DosDevIOCtl
|
---|
341 | PUSH EAX
|
---|
342 | PUSH 2 ; sizeof(short)
|
---|
343 | LEA EAX, [EBP-2] ; address to return the GDT selector
|
---|
344 | PUSH EAX
|
---|
345 | PUSH 0 ; no parameter len
|
---|
346 | PUSH 0 ; no parameter size
|
---|
347 | PUSH 0 ; no parameter address
|
---|
348 | PUSH 100 ; function code IO_GETSEL32
|
---|
349 | PUSH 118 ; category code XFREE6_IO
|
---|
350 | MOV EAX, [EBP-8] ; file handle
|
---|
351 | PUSH EAX
|
---|
352 | CALL DosDevIOCtl ; perform ioctl
|
---|
353 | ADD ESP, 36 ; cleanup stack
|
---|
354 | CMP EAX, 0 ; is return code = 0?
|
---|
355 | JE ok ; yes, proceed
|
---|
356 | PUSH EAX ; was error, save error code
|
---|
357 | MOV EAX, [EBP-8] ; file handle
|
---|
358 | PUSH EAX
|
---|
359 | CALL DosClose ; close device
|
---|
360 | ADD ESP, 4 ; clean stack
|
---|
361 | POP EAX ; get error code
|
---|
362 | LEAVE ; return error
|
---|
363 | RET
|
---|
364 |
|
---|
365 | ALIGN 04H
|
---|
366 | ok:
|
---|
367 | MOV EAX,[EBP-8] ; file handle
|
---|
368 | PUSH EAX ; do normal close
|
---|
369 | CALL DosClose
|
---|
370 | ADD ESP, 4 ; clean stack
|
---|
371 |
|
---|
372 | MOV AX, WORD PTR [EBP-2] ; load gdt selector
|
---|
373 | MOV gdt, AX ; store in ioentry address selector part
|
---|
374 | XOR EAX, EAX ; eax = 0
|
---|
375 | MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part
|
---|
376 | ; return code = 0 (in %eax)
|
---|
377 | LEAVE ; clean stack frame
|
---|
378 | RET ; exit
|
---|
379 | _io_init ENDP
|
---|
380 |
|
---|
381 | ; just for symmetry, does nothing
|
---|
382 |
|
---|
383 | ALIGN 04H
|
---|
384 | PUBLIC _io_exit
|
---|
385 | _io_exit PROC
|
---|
386 | XOR EAX,EAX
|
---|
387 | RET
|
---|
388 | _io_exit ENDP
|
---|
389 |
|
---|
390 | ALIGN 04H
|
---|
391 | PUBLIC int03
|
---|
392 |
|
---|
393 | int03 PROC
|
---|
394 | INT 3
|
---|
395 | RET
|
---|
396 | int03 ENDP
|
---|
397 |
|
---|
398 | ;------------------------------------------------------------------------------
|
---|
399 |
|
---|
400 | ; Initialize I/O access via the driver.
|
---|
401 | ; You *must* call this routine once for each *thread* that wants to do
|
---|
402 | ; I/O.
|
---|
403 | ;
|
---|
404 | ; The routine is mainly equivalent to a C routine performing the
|
---|
405 | ; following (but no need to add another file):
|
---|
406 | ; DosOpen("/dev/fastio$", read, nonexclusive)
|
---|
407 | ; DosDevIOCtl(device, XFREE86IO, IOGETSEL32)
|
---|
408 | ; selector -> ioentry+4
|
---|
409 | ; DosClose(device)
|
---|
410 | ;
|
---|
411 | ; Calling convention:
|
---|
412 | ; int io_init1(void)
|
---|
413 | ; Return:
|
---|
414 | ; 0 if successful
|
---|
415 | ; standard APIRET RETurn code if error
|
---|
416 | ;
|
---|
417 |
|
---|
418 | PUBLIC _io_init1
|
---|
419 | ALIGN 04H
|
---|
420 | _io_init1 PROC
|
---|
421 | PUSH EBP
|
---|
422 | MOV EBP, ESP ; standard stack frame
|
---|
423 | SUB ESP, 16 ; reserve memory
|
---|
424 | ; -16 = len arg of DosDevIOCtl
|
---|
425 | ; -12 = action arg of DosOpen
|
---|
426 | ; -8 = fd arg of DosOpen
|
---|
427 | ; -2 = short GDT selector arg
|
---|
428 | PUSH 0 ; (PEAOP2)NULL
|
---|
429 | PUSH 66 ; OPENACCESSREADWRITE|OPENSHAREDENYNONE
|
---|
430 | PUSH 1 ; FILEOPEN
|
---|
431 | PUSH 0 ; FILENORMAL
|
---|
432 | PUSH 0 ; initial size
|
---|
433 | LEA EAX, [EBP-12] ; Adress of 'action' arg
|
---|
434 | PUSH EAX
|
---|
435 | LEA EAX, [EBP-8] ; Address of 'fd' arg
|
---|
436 | PUSH EAX
|
---|
437 | PUSH OFFSET devname
|
---|
438 | CALL DosOpen ; call DosOpen
|
---|
439 | ADD ESP, 32 ; cleanup stack frame
|
---|
440 | CMP EAX, 0 ; is return code zero?
|
---|
441 | JE goon1 ; yes, proceed
|
---|
442 | LEAVE ; no RETurn error
|
---|
443 | RET
|
---|
444 | ALIGN 04H
|
---|
445 | goon1:
|
---|
446 | LEA EAX, [EBP-16] ; address of 'len' arg of DosDevIOCtl
|
---|
447 | PUSH EAX
|
---|
448 | PUSH 2 ; sizeof(short)
|
---|
449 | LEA EAX, [EBP-2] ; address to return the GDT selector
|
---|
450 | PUSH EAX
|
---|
451 | PUSH 0 ; no parameter len
|
---|
452 | PUSH 0 ; no parameter size
|
---|
453 | PUSH 0 ; no parameter address
|
---|
454 | PUSH 100 ; function code IOGETSEL32
|
---|
455 | PUSH 118 ; category code XFREE6IO
|
---|
456 | MOV EAX,[EBP-8] ; file handle
|
---|
457 | PUSH EAX
|
---|
458 | CALL DosDevIOCtl ; perform ioctl
|
---|
459 | ADD ESP, 36 ; cleanup stack
|
---|
460 | CMP EAX, 0 ; is return code = 0?
|
---|
461 | JE ok1 ; yes, proceed
|
---|
462 | PUSH EAX ; was error, save error code
|
---|
463 | MOV EAX, [EBP-8] ; file handle
|
---|
464 | PUSH EAX
|
---|
465 | CALL DosClose ; close device
|
---|
466 | ADD ESP,4 ; clean stack
|
---|
467 | POP EAX ; get error code
|
---|
468 | LEAVE ; return error
|
---|
469 | RET
|
---|
470 |
|
---|
471 | ALIGN 04H
|
---|
472 | ok1:
|
---|
473 | MOV EAX, [EBP-8] ; file handle
|
---|
474 | PUSH EAX ; do normal close
|
---|
475 | CALL DosClose
|
---|
476 | ADD ESP,4 ; clean stack
|
---|
477 |
|
---|
478 | MOV AX, [EBP-2] ; load gdt selector
|
---|
479 | MOV gdt, AX ; store in ioentry address selector part
|
---|
480 | XOR EAX, EAX ; EAX = 0
|
---|
481 | MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part
|
---|
482 | ; return code = 0 (in EAX)
|
---|
483 |
|
---|
484 | ; now use this function to raise the IOPL
|
---|
485 | MOV EBX,13 ; special function code
|
---|
486 | CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32
|
---|
487 |
|
---|
488 | ; thread should now be running at IOPL=3
|
---|
489 |
|
---|
490 | XOR EAX, EAX ; return code = 0
|
---|
491 | LEAVE ; clean stack frame
|
---|
492 | RET ; exit
|
---|
493 | _io_init1 ENDP
|
---|
494 |
|
---|
495 | PUBLIC _io_exit1
|
---|
496 | ALIGN 04H
|
---|
497 | _io_exit1 PROC
|
---|
498 | push EBP
|
---|
499 | MOV EBP, ESP ; stackframe, I am accustomed to this :-)
|
---|
500 |
|
---|
501 | MOV AX, gdt ; check if ioinit was called once
|
---|
502 | OR AX, AX
|
---|
503 | JZ exerr ; no gdt entry, so process cannot be at IOPL=3
|
---|
504 | ; through this mechanism
|
---|
505 |
|
---|
506 | MOV EBX, 14 ; function code to disable iopl
|
---|
507 | CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
|
---|
508 |
|
---|
509 | ; process should now be at IOPL=3 again
|
---|
510 | XOR EAX, EAX ; ok, RETurn code = 0
|
---|
511 | LEAVE
|
---|
512 | RET
|
---|
513 | exerr: XOR EAX, EAX ; not ok, RETurn code = ffffffff
|
---|
514 | DEC EAX
|
---|
515 | LEAVE
|
---|
516 | RET
|
---|
517 | _io_exit1 ENDP
|
---|
518 |
|
---|
519 | ; for diagnostic only
|
---|
520 |
|
---|
521 | PUBLIC psw
|
---|
522 | ALIGN 04H
|
---|
523 | psw PROC
|
---|
524 | PUSHF ; get the current PSW
|
---|
525 | POP EAX ; into EAX
|
---|
526 | RET
|
---|
527 | psw ENDP
|
---|
528 |
|
---|
529 | CODE32 ENDS
|
---|
530 | END
|
---|