Changeset 4296 for trunk/src


Ignore:
Timestamp:
Sep 21, 2000, 8:24:32 PM (25 years ago)
Author:
hugh
Message:

Updates for COM

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 sandervl Exp $
     1; $Id: iccio.asm,v 1.6 2000-09-21 18:24:32 hugh Exp $
    22
    33; **********************************************************************
     
    1010; compile with ALP
    1111;
    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
     15CODE32  SEGMENT DWORD USE32 PUBLIC 'CODE'
     16CODE32  ENDS
     17DATA32  SEGMENT DWORD USE32 PUBLIC 'DATA'
    2218DATA32  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
     19CONST32  SEGMENT DWORD USE32 PUBLIC 'CONST'
     20CONST32  ENDS
     21BSS32  SEGMENT DWORD USE32 PUBLIC 'BSS'
     22BSS32  ENDS
     23DGROUP  GROUP CONST32, BSS32, DATA32
     24  ASSUME  CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT
     25DATA32  SEGMENT
     26DATA32  ENDS
     27BSS32  SEGMENT
     28BSS32  ENDS
     29CONST32  SEGMENT
     30CONST32  ENDS
     31
     32DATA32  SEGMENT
     33ioentry   DWORD  0
     34gdt    WORD  0
     35DATA32  ENDS
     36
     37CODE32  SEGMENT
    2938
    3039; 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
     48c_outb  PROC
     49  MOV  EDX, [ESP+4]    ; get port
     50  MOV  AL, [ESP+8]    ; get data
     51  OUT  DX,AL
     52  RET
     53c_outb  ENDP
    4754
    4855; 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
     64c_outw  PROC
     65  MOV  EDX, [ESP+4]    ; get port
     66  MOV  AX, [ESP+8]    ; get data
     67  OUT  DX,AX
     68  RET
     69c_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
     80c_outl  PROC
     81  MOV  EDX, [ESP+4]    ; get port
     82  MOV  EAX, [ESP+8]    ; get data
     83  OUT  DX, EAX
     84  RET
     85c_outl  ENDP
    8786
    8887; performs fast input of a byte from an I/O port
     
    9089;
    9190; 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
     96c_inb  PROC
     97  MOV  EDX, [ESP+4]    ; get port
     98  IN  AL,DX
     99  AND  EAX, 000000FFh
     100  RET
     101c_inb  ENDP
    106102
    107103; performs fast input of a word from an I/O port
     
    109105;
    110106; 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
     112c_inw  PROC
     113  MOV  EDX, [ESP+4]    ; get port
     114  IN  AX, DX
     115  AND  EAX, 0000FFFFh    ; mask out word
     116  RET
     117c_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
     128c_inl  PROC
     129  MOV  EDX, [ESP+4]    ; get port
     130  IN  EAX, DX
     131  RET
     132c_inl  ENDP
     133
     134CODE32  ENDS
    167135
    168136;------------------------------------------------------------------------------
    169137
    170 ; performs fast output of a byte to an I/O port
    171 ; this routine is intended to be called from assembler code
    172 ; note there is no stack frame, however 8 byte stack space is required
    173 ;
    174 ; calling convention:
    175 ;   MOV EDX, portnr
    176 ;   MOV AL, data
    177 ;   CALL    a_outb
    178 ;
    179 ;
    180     ALIGN   04H
    181     PUBLIC  a_outb
    182 a_outb  PROC
    183     PUSH    EBX         ; save register
    184     MOV EBX, 4          ; function code 4 = write byte
    185     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    186     POP EBX         ; restore bx
    187     RET
    188 a_outb  ENDP
    189 
    190 ; performs fast output of a word to an I/O port
    191 ; this routine is intended to be called from assembler code
    192 ; note there is no stack frame, however 8 byte stack space is required
    193 ;
    194 ; calling convention:
    195 ;   MOV EDX, portnr
    196 ;   MOV AX, data
    197 ;   CALL    a_outw
    198 ;
    199 ;
    200     ALIGN   04H
    201     PUBLIC  a_outw
    202 a_outw  PROC
    203     PUSH    EBX         ; save register
    204     MOV EBX, 5          ; function code 5 = write word
    205     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    206     POP EBX         ; restore bx
    207     RET
    208 a_outw  ENDP
    209 
    210 ; performs fast output of a long to an I/O port
    211 ; this routine is intended to be called from assembler code
    212 ; note there is no stack frame, however 8 byte stack space is required
    213 ;
    214 ; calling convention:
    215 ;   MOV EDX, portnr
    216 ;   MOV EAX, data
    217 ;   CALL    a_outl
    218 ;
    219 ;
    220     ALIGN   04H
    221     PUBLIC  a_outl
    222 a_outl  PROC
    223     PUSH    EBX         ; save register
    224     MOV EBX, 6          ; function code 6 = write long
    225     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    226     POP EBX         ; restore bx
    227     RET
    228 a_outl  ENDP
    229 
    230 ; performs fast input of a byte from an I/O port
    231 ; this routine is intended to be called from assembler code
    232 ; note there is no stack frame, however 8 byte stack space is required
    233 ;
    234 ; calling convention:
    235 ;   MOV EDX, portnr
    236 ;   CALL    a_inb
    237 ;   ;data in AL
    238 ;
    239     ALIGN   04H
    240     PUBLIC  a_inb
    241 a_inb   PROC
    242     PUSH    EBX         ; save register
    243     MOV EBX, 1          ; function code 1 = read byte
    244     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    245     AND EAX, 000000FFh      ; mask byte
    246     POP EBX         ; restore register
    247     RET
    248 a_inb   ENDP
    249 
    250 
    251 ; performs fast input of a word from an I/O port
    252 ; this routine is intended to be called from assembler code
    253 ; note there is no stack frame, however 8 byte stack space is required
    254 ;
    255 ; calling convention:
    256 ;   MOV EDX, portnr
    257 ;   CALL    a_inb
    258 ;   ;data in AX
    259 ;
    260     ALIGN   04H
    261     PUBLIC  a_inw
    262 a_inw   PROC
    263     PUSH    EBX         ; save register
    264     MOV EBX, 2          ; function code 2 = read word
    265     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    266     AND EAX, 0000FFFFh      ; mask byte
    267     POP EBX         ; restore register
    268     RET
    269 a_inw   ENDP
    270 
    271 ; performs fast input of a dword from an I/O port
    272 ; this routine is intended to be called from assembler code
    273 ; note there is no stack frame, however 8 byte stack space is required
    274 ;
    275 ; calling convention:
    276 ;   MOV EDX, portnr
    277 ;   CALL    a_inl
    278 ;   ;data in EAX
    279 ;
    280     ALIGN   04H
    281     PUBLIC  a_inl
    282 a_inl   PROC
    283     PUSH    EBX         ; save register
    284     MOV EBX, 3          ; function code 3 = read dword
    285     CALL    FWORD PTR [ioentry] ; call intersegment indirect 16:32
    286     POP EBX         ; restore register
    287     RET
    288 a_inl   ENDP
    289 
    290 CODE32  ENDS
    291 
    292 ;------------------------------------------------------------------------------
    293 
    294138; Initialize I/O access via the driver.
    295 ; You *must* call this routine once for each executable that wants to do
     139; You *must* call this routine once for each *thread* that wants to do
    296140; I/O.
    297141;
    298142; The routine is mainly equivalent to a C routine performing the
    299143; following (but no need to add another file):
    300  DosOpen("/dev/fastio$", read, nonexclusive)
    301  DosDevIOCtl(device, XFREE86_IO, IO_GETSEL32)
    302  selector -> ioentry+4
    303  DosClose(device)
    304 ;
    305 ; Calling convention:
    306  int io_init(void)
     144DosOpen("/dev/fastio$", read, nonexclusive)
     145DosDevIOCtl(device, XFREE86IO, IOGETSEL32)
     146selector -> ioentry+4
     147DosClose(device)
     148;
     149; Calling convention:
     150int io_init1(void)
    307151; 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
     156CONST32  SEGMENT
     157  ALIGN  04H
     158devname:
     159  DB  "/dev/fastio$",0
     160CONST32  ENDS
     161
    311162
    312163CODE32  SEGMENT
    313     PUBLIC  _io_init
     164    PUBLIC  io_init1
    314165    EXTRN   DosOpen:PROC
    315166    EXTRN   DosClose:PROC
    316167    EXTRN   DosDevIOCtl:PROC
    317 _io_init    PROC
     168io_init1   PROC
    318169    PUSH    EBP
    319170    MOV EBP, ESP    ; standard stack frame
     
    342193    ALIGN   04H
    343194goon:
    344     LEA EAX, [EBP-16]   ; address of 'len' arg of DosDevIOCtl
    345     PUSH    EAX
    346     PUSH    2       ; sizeof(short)
    347     LEA EAX, [EBP-2]    ; address to return the GDT selector
    348     PUSH    EAX
    349     PUSH    0       ; no parameter len
    350     PUSH    0       ; no parameter size
    351     PUSH    0       ; no parameter address
    352     PUSH    100     ; function code IO_GETSEL32
    353     PUSH    118     ; category code XFREE6_IO
    354     MOV EAX, [EBP-8]    ; file handle
    355     PUSH    EAX
    356     CALL    DosDevIOCtl ; perform ioctl
    357     ADD ESP, 36     ; cleanup stack
    358     CMP EAX, 0      ; is return code = 0?
    359     JE  ok      ; yes, proceed
    360     PUSH    EAX     ; was error, save error code
    361     MOV EAX, [EBP-8]    ; file handle
    362     PUSH    EAX
    363     CALL    DosClose    ; close device
    364     ADD ESP, 4      ; clean stack
    365     POP EAX     ; get error code
    366     LEAVE           ; return error
    367     RET
    368 
    369     ALIGN   04H
     195  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
    370221ok:
    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
     242io_init1 ENDP
     243
     244; void in_init(short)
     245PUBLIC  io_init2
     246  ALIGN  04H
     247io_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
     260io_init2  ENDP
     261
     262  PUBLIC  io_exit1
     263  ALIGN  04H
     264io_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
     280exerr:  XOR  EAX, EAX  ; not ok, RETurn code = ffffffff
     281  DEC  EAX
     282  LEAVE
     283  RET
     284io_exit1  ENDP
     285
    421286
    422287    PUBLIC  _io_init1
     
    523388; for diagnostic only
    524389
    525     PUBLIC  psw
    526     ALIGN   04H
    527 psw PROC
    528     PUSHF           ; get the current PSW
    529     POP EAX     ; into EAX
    530     RET
    531 psw ENDP
     390  PUBLIC  psw
     391  ALIGN  04H
     392psw  PROC
     393  PUSHF      ; get the current PSW
     394  POP  EAX    ; into EAX
     395  RET
     396psw  ENDP
    532397
    533398CODE32  ENDS
    534     END
     399  END
Note: See TracChangeset for help on using the changeset viewer.