- Timestamp:
- Sep 21, 2000, 8:24:32 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/iccio.asm
r2285 r4296 1 ; $Id: iccio.asm,v 1. 5 1999-12-31 13:55:12 sandervlExp $1 ; $Id: iccio.asm,v 1.6 2000-09-21 18:24:32 hugh Exp $ 2 2 3 3 ; ********************************************************************** … … 10 10 ; compile with ALP 11 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 ASSUME DS:FLAT,SS:FLAT 19 EXTRN ioentry:DWORD 20 EXTRN gdt:WORD 21 EXTRN devname:BYTE 12 TITLE ICCIO.ASM 13 .386 14 .387 15 CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE' 16 CODE32 ENDS 17 DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA' 22 18 DATA32 ENDS 23 24 CODE32 SEGMENT DWORD PUBLIC USE32 'CODE' 25 ; ASSUME CS:FLAT ,DS:FLAT,SS:FLAT 26 ASSUME DS:FLAT,SS:FLAT 27 28 ALIGN 04H 19 CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST' 20 CONST32 ENDS 21 BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS' 22 BSS32 ENDS 23 DGROUP GROUP CONST32, BSS32, DATA32 24 ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT 25 DATA32 SEGMENT 26 DATA32 ENDS 27 BSS32 SEGMENT 28 BSS32 ENDS 29 CONST32 SEGMENT 30 CONST32 ENDS 31 32 DATA32 SEGMENT 33 ioentry DWORD 0 34 gdt WORD 0 35 DATA32 ENDS 36 37 CODE32 SEGMENT 29 38 30 39 ; performs fast output of a byte to an I/O port 31 ; this routine is intended to be called from icc C code 32 ; 33 ; Calling convention: 34 ; void _c_outb(short port,char data) 35 ; 36 ; 37 PUBLIC _c_outb 38 _c_outb PROC 39 MOV EDX, DWORD PTR [ESP+4] ; get port 40 MOV AL, BYTE PTR [ESP+8] ; get data 41 PUSH EBX ; save register 42 MOV EBX, 4 ; function code 4 = write byte 43 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 44 POP EBX 45 RET 46 _c_outb ENDP 40 ; this routine is intended to be called from gcc C code 41 ; 42 ; Calling convention: 43 ; void c_outb1(short port,char data) 44 ; 45 ; 46 PUBLIC c_outb 47 ALIGN 04H 48 c_outb PROC 49 MOV EDX, [ESP+4] ; get port 50 MOV AL, [ESP+8] ; get data 51 OUT DX,AL 52 RET 53 c_outb ENDP 47 54 48 55 ; performs fast output of a word to an I/O port 49 ; this routine is intended to be called from icc C code 50 ; 51 ; Calling convention: 52 ; void _c_outw(short port,short data) 53 ; 54 ; 55 ALIGN 04H 56 57 PUBLIC _c_outw 58 _c_outw PROC 59 MOV EDX, DWORD PTR [ESP+4] ; get port 60 MOV AX, WORD PTR [ESP+8] ; get data 61 PUSH EBX ; save register 62 MOV EBX, 5 ; function code 5 = write word 63 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 64 POP EBX 65 RET 66 _c_outw ENDP 67 68 ; performs fast output of a dword to an I/O port 69 ; this routine is intended to be called from icc C code 70 ; 71 ; Calling convention: 72 ; void _c_outl(short port,long data) 73 ; 74 ; 75 ALIGN 04H 76 77 PUBLIC _c_outl 78 _c_outl PROC 79 MOV EDX, DWORD PTR [ESP+4] ; get port 80 MOV EAX, DWORD PTR [ESP+8] ; get data 81 PUSH EBX ; save register 82 MOV EBX, 6 ; function code 6 = write dword 83 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 84 POP EBX 85 RET 86 _c_outl ENDP 56 ; this routine is intended to be called from gcc C code 57 ; 58 ; Calling convention: 59 ; void c_outw1(short port,short data) 60 ; 61 ; 62 PUBLIC c_outw 63 ALIGN 04H 64 c_outw PROC 65 MOV EDX, [ESP+4] ; get port 66 MOV AX, [ESP+8] ; get data 67 OUT DX,AX 68 RET 69 c_outw ENDP 70 71 ; performs fast output of a longword to an I/O port 72 ; this routine is intended to be called from gcc C code 73 ; 74 ; Calling convention: 75 ; void c_outl1(short port,long data) 76 ; 77 ; 78 PUBLIC c_outl 79 ALIGN 04H 80 c_outl PROC 81 MOV EDX, [ESP+4] ; get port 82 MOV EAX, [ESP+8] ; get data 83 OUT DX, EAX 84 RET 85 c_outl ENDP 87 86 88 87 ; performs fast input of a byte from an I/O port … … 90 89 ; 91 90 ; Calling convention: 92 ; char _c_inb(short port) 93 ; 94 ; 95 ALIGN 04H 96 PUBLIC _c_inb 97 _c_inb PROC 98 MOV EDX, DWORD PTR [ESP+4] ; get port number 99 PUSH EBX ; save register 100 MOV EBX, 1 ; function code 1 = read byte 101 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 102 AND EAX, 000000ffH ; mask out required byte 103 POP EBX ; restore register 104 RET 105 _c_inb ENDP 91 ; char c_inb1(short port) 92 ; 93 ; 94 PUBLIC c_inb 95 ALIGN 04H 96 c_inb PROC 97 MOV EDX, [ESP+4] ; get port 98 IN AL,DX 99 AND EAX, 000000FFh 100 RET 101 c_inb ENDP 106 102 107 103 ; performs fast input of a word from an I/O port … … 109 105 ; 110 106 ; Calling convention: 111 ; short _c_inw(short port) 112 ; 113 ; 114 ALIGN 04H 115 PUBLIC _c_inw 116 _c_inw PROC 117 MOV EDX, DWORD PTR [ESP+4] ; get port number 118 PUSH EBX ; save register 119 MOV EBX, 2 ; function code 2 = read short 120 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 121 AND EAX, 0000ffffH ; mask out required byte 122 POP EBX ; restore register 123 RET 124 _c_inw ENDP 125 126 ; performs fast input of a dword from an I/O port 127 ; this routine is intended to be called from gcc C code 128 ; 129 ; Calling convention: 130 ; long _c_inl(short port) 131 ; 132 ; 133 ALIGN 04H 134 PUBLIC _c_inl 135 _c_inl PROC 136 MOV EDX, DWORD PTR [ESP+4] ; get port number 137 PUSH EBX ; save register 138 MOV EBX, 3 ; function code 3 = read long 139 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 140 ; AND EAX, 000000ffH ; mask out required byte 141 POP EBX ; restore register 142 RET 143 _c_inl ENDP 144 145 ALIGN 4 146 PUBLIC _c_readmsr 147 _c_readmsr PROC NEAR 148 PUSH EBP 149 MOV EBP, ESP 150 PUSH EAX 151 PUSH EBX 152 PUSH ECX 153 PUSH EDX ; save register 154 MOV ECX, DWORD PTR [EBP+8] ; get msr reg 155 MOV EBX, 7 ; function code 7 = read msr 156 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 157 MOV EBX, DWORD PTR [EBP+12] ; LONGLONG ptr 158 MOV DWORD PTR [EBX+4], EDX 159 MOV DWORD PTR [EBX], EAX 160 POP EDX 161 POP ECX 162 POP EBX ; restore register 163 POP EAX 164 POP EBP 165 RET 166 _c_readmsr ENDP 107 ; short c_inw1(short port) 108 ; 109 ; 110 PUBLIC c_inw 111 ALIGN 04H 112 c_inw PROC 113 MOV EDX, [ESP+4] ; get port 114 IN AX, DX 115 AND EAX, 0000FFFFh ; mask out word 116 RET 117 c_inw ENDP 118 119 ; performs fast input of a longword from an I/O port 120 ; this routine is intended to be called from gcc C code 121 ; 122 ; Calling convention: 123 ; lomg c_inl1(short port) 124 ; 125 ; 126 PUBLIC c_inl 127 ALIGN 04H 128 c_inl PROC 129 MOV EDX, [ESP+4] ; get port 130 IN EAX, DX 131 RET 132 c_inl ENDP 133 134 CODE32 ENDS 167 135 168 136 ;------------------------------------------------------------------------------ 169 137 170 ; performs fast output of a byte to an I/O port171 ; this routine is intended to be called from assembler code172 ; note there is no stack frame, however 8 byte stack space is required173 ;174 ; calling convention:175 ; MOV EDX, portnr176 ; MOV AL, data177 ; CALL a_outb178 ;179 ;180 ALIGN 04H181 PUBLIC a_outb182 a_outb PROC183 PUSH EBX ; save register184 MOV EBX, 4 ; function code 4 = write byte185 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32186 POP EBX ; restore bx187 RET188 a_outb ENDP189 190 ; performs fast output of a word to an I/O port191 ; this routine is intended to be called from assembler code192 ; note there is no stack frame, however 8 byte stack space is required193 ;194 ; calling convention:195 ; MOV EDX, portnr196 ; MOV AX, data197 ; CALL a_outw198 ;199 ;200 ALIGN 04H201 PUBLIC a_outw202 a_outw PROC203 PUSH EBX ; save register204 MOV EBX, 5 ; function code 5 = write word205 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32206 POP EBX ; restore bx207 RET208 a_outw ENDP209 210 ; performs fast output of a long to an I/O port211 ; this routine is intended to be called from assembler code212 ; note there is no stack frame, however 8 byte stack space is required213 ;214 ; calling convention:215 ; MOV EDX, portnr216 ; MOV EAX, data217 ; CALL a_outl218 ;219 ;220 ALIGN 04H221 PUBLIC a_outl222 a_outl PROC223 PUSH EBX ; save register224 MOV EBX, 6 ; function code 6 = write long225 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32226 POP EBX ; restore bx227 RET228 a_outl ENDP229 230 ; performs fast input of a byte from an I/O port231 ; this routine is intended to be called from assembler code232 ; note there is no stack frame, however 8 byte stack space is required233 ;234 ; calling convention:235 ; MOV EDX, portnr236 ; CALL a_inb237 ; ;data in AL238 ;239 ALIGN 04H240 PUBLIC a_inb241 a_inb PROC242 PUSH EBX ; save register243 MOV EBX, 1 ; function code 1 = read byte244 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32245 AND EAX, 000000FFh ; mask byte246 POP EBX ; restore register247 RET248 a_inb ENDP249 250 251 ; performs fast input of a word from an I/O port252 ; this routine is intended to be called from assembler code253 ; note there is no stack frame, however 8 byte stack space is required254 ;255 ; calling convention:256 ; MOV EDX, portnr257 ; CALL a_inb258 ; ;data in AX259 ;260 ALIGN 04H261 PUBLIC a_inw262 a_inw PROC263 PUSH EBX ; save register264 MOV EBX, 2 ; function code 2 = read word265 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32266 AND EAX, 0000FFFFh ; mask byte267 POP EBX ; restore register268 RET269 a_inw ENDP270 271 ; performs fast input of a dword from an I/O port272 ; this routine is intended to be called from assembler code273 ; note there is no stack frame, however 8 byte stack space is required274 ;275 ; calling convention:276 ; MOV EDX, portnr277 ; CALL a_inl278 ; ;data in EAX279 ;280 ALIGN 04H281 PUBLIC a_inl282 a_inl PROC283 PUSH EBX ; save register284 MOV EBX, 3 ; function code 3 = read dword285 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32286 POP EBX ; restore register287 RET288 a_inl ENDP289 290 CODE32 ENDS291 292 ;------------------------------------------------------------------------------293 294 138 ; Initialize I/O access via the driver. 295 ; You *must* call this routine once for each executablethat wants to do139 ; You *must* call this routine once for each *thread* that wants to do 296 140 ; I/O. 297 141 ; 298 142 ; The routine is mainly equivalent to a C routine performing the 299 143 ; following (but no need to add another file): 300 ; 301 ; DosDevIOCtl(device, XFREE86_IO, IO_GETSEL32)302 ; 303 ; 304 ; 305 ; Calling convention: 306 ; int io_init(void)144 ; DosOpen("/dev/fastio$", read, nonexclusive) 145 ; DosDevIOCtl(device, XFREE86IO, IOGETSEL32) 146 ; selector -> ioentry+4 147 ; DosClose(device) 148 ; 149 ; Calling convention: 150 ; int io_init1(void) 307 151 ; Return: 308 ; 0 if successful 309 ; standard APIRET return code if error 310 ; 152 ; 0 if successful 153 ; standard APIRET RETurn code if error 154 ; 155 156 CONST32 SEGMENT 157 ALIGN 04H 158 devname: 159 DB "/dev/fastio$",0 160 CONST32 ENDS 161 311 162 312 163 CODE32 SEGMENT 313 PUBLIC _io_init164 PUBLIC io_init1 314 165 EXTRN DosOpen:PROC 315 166 EXTRN DosClose:PROC 316 167 EXTRN DosDevIOCtl:PROC 317 _io_initPROC168 io_init1 PROC 318 169 PUSH EBP 319 170 MOV EBP, ESP ; standard stack frame … … 342 193 ALIGN 04H 343 194 goon: 344 LEA EAX, [EBP-16]; address of 'len' arg of DosDevIOCtl345 PUSHEAX346 PUSH 2; sizeof(short)347 LEA EAX, [EBP-2]; address to return the GDT selector348 PUSHEAX349 PUSH 0; no parameter len350 PUSH 0; no parameter size351 PUSH 0; no parameter address352 PUSH 100 ; function code IO_GETSEL32353 PUSH 118 ; category code XFREE6_IO354 MOV EAX, [EBP-8]; file handle355 PUSHEAX356 CALL DosDevIOCtl; perform ioctl357 ADD ESP, 36; cleanup stack358 CMP EAX, 0; is return code = 0?359 JE ok; yes, proceed360 PUSH EAX; was error, save error code361 MOV EAX, [EBP-8]; file handle362 PUSHEAX363 CALL DosClose; close device364 ADD ESP, 4; clean stack365 POP EAX; get error code366 LEAVE; return error367 368 369 ALIGN04H195 LEA EAX, [EBP-16] ; address of 'len' arg of DosDevIOCtl 196 PUSH EAX 197 PUSH 2 ; sizeof(short) 198 LEA EAX, [EBP-2] ; address to return the GDT selector 199 PUSH EAX 200 PUSH 0 ; no parameter len 201 PUSH 0 ; no parameter size 202 PUSH 0 ; no parameter address 203 PUSH 100 ; function code IOGETSEL32 204 PUSH 118 ; category code XFREE6IO 205 MOV EAX,[EBP-8] ; file handle 206 PUSH EAX 207 CALL DosDevIOCtl ; perform ioctl 208 ADD ESP, 36 ; cleanup stack 209 CMP EAX, 0 ; is return code = 0? 210 JE ok ; yes, proceed 211 PUSH EAX ; was error, save error code 212 MOV EAX, [EBP-8] ; file handle 213 PUSH EAX 214 CALL DosClose ; close device 215 ADD ESP,4 ; clean stack 216 POP EAX ; get error code 217 LEAVE ; return error 218 RET 219 220 ALIGN 04H 370 221 ok: 371 MOV EAX,[EBP-8] ; file handle 372 PUSH EAX ; do normal close 373 CALL DosClose 374 ADD ESP, 4 ; clean stack 375 376 MOV AX, WORD PTR [EBP-2] ; load gdt selector 377 MOV gdt, AX ; store in ioentry address selector part 378 XOR EAX, EAX ; eax = 0 379 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 380 ; return code = 0 (in %eax) 381 LEAVE ; clean stack frame 382 RET ; exit 383 _io_init ENDP 384 385 ; just for symmetry, does nothing 386 387 ALIGN 04H 388 PUBLIC _io_exit 389 _io_exit PROC 390 XOR EAX,EAX 391 RET 392 _io_exit ENDP 393 394 ALIGN 04H 395 PUBLIC int03 396 397 int03 PROC 398 INT 3 399 RET 400 int03 ENDP 401 402 ;------------------------------------------------------------------------------ 403 404 ; Initialize I/O access via the driver. 405 ; You *must* call this routine once for each *thread* that wants to do 406 ; I/O. 407 ; 408 ; The routine is mainly equivalent to a C routine performing the 409 ; following (but no need to add another file): 410 ; DosOpen("/dev/fastio$", read, nonexclusive) 411 ; DosDevIOCtl(device, XFREE86IO, IOGETSEL32) 412 ; selector -> ioentry+4 413 ; DosClose(device) 414 ; 415 ; Calling convention: 416 ; int io_init1(void) 417 ; Return: 418 ; 0 if successful 419 ; standard APIRET RETurn code if error 420 ; 222 MOV EAX, [EBP-8] ; file handle 223 PUSH EAX ; do normal close 224 CALL DosClose 225 ADD ESP,4 ; clean stack 226 227 MOV AX, [EBP-2] ; load gdt selector 228 MOV gdt, AX ; store in ioentry address selector part 229 XOR EAX, EAX ; EAX = 0 230 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 231 ; return code = 0 (in EAX) 232 233 ; now use this function to raise the IOPL 234 MOV EBX,13 ; special function code 235 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32 236 237 ; thread should now be running at IOPL=3 238 239 XOR EAX, EAX ; return code = 0 240 LEAVE ; clean stack frame 241 RET ; exit 242 io_init1 ENDP 243 244 ; void in_init(short) 245 PUBLIC io_init2 246 ALIGN 04H 247 io_init2 PROC 248 249 MOV gdt, AX ; store in ioentry address selector part 250 XOR EAX, EAX ; EAX = 0 251 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part 252 ; return code = 0 (in EAX) 253 254 ; now use this function to raise the IOPL 255 MOV EBX,13 ; special function code 256 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32 257 258 XOR EAX, EAX ; return code = 0 259 ret 260 io_init2 ENDP 261 262 PUBLIC io_exit1 263 ALIGN 04H 264 io_exit1 PROC 265 push EBP 266 MOV EBP, ESP ; stackframe, I am accustomed to this :-) 267 268 MOV AX, gdt ; check if ioinit was called once 269 OR AX, AX 270 JZ exerr ; no gdt entry, so process cannot be at IOPL=3 271 ; through this mechanism 272 273 MOV EBX, 14 ; function code to disable iopl 274 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32 275 276 ; process should now be at IOPL=3 again 277 XOR EAX, EAX ; ok, RETurn code = 0 278 LEAVE 279 RET 280 exerr: XOR EAX, EAX ; not ok, RETurn code = ffffffff 281 DEC EAX 282 LEAVE 283 RET 284 io_exit1 ENDP 285 421 286 422 287 PUBLIC _io_init1 … … 523 388 ; for diagnostic only 524 389 525 526 ALIGN04H527 psw PROC528 PUSHF; get the current PSW529 POP EAX; into EAX530 531 psw ENDP390 PUBLIC psw 391 ALIGN 04H 392 psw PROC 393 PUSHF ; get the current PSW 394 POP EAX ; into EAX 395 RET 396 psw ENDP 532 397 533 398 CODE32 ENDS 534 399 END
Note:
See TracChangeset
for help on using the changeset viewer.