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