| 1 | ; $Id: iccio.asm,v 1.3 1999-06-10 20:47:59 phaller 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
|
|---|