source: trunk/src/ddraw/iccio1.asm@ 10367

Last change on this file since 10367 was 6812, checked in by sandervl, 24 years ago

minor updates

File size: 7.1 KB
Line 
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
13CODE32 SEGMENT DWORD USE32 PUBLIC 'CODE'
14CODE32 ENDS
15DATA32 SEGMENT DWORD USE32 PUBLIC 'DATA'
16DATA32 ENDS
17CONST32 SEGMENT DWORD USE32 PUBLIC 'CONST'
18CONST32 ENDS
19BSS32 SEGMENT DWORD USE32 PUBLIC 'BSS'
20BSS32 ENDS
21DGROUP GROUP CONST32, BSS32, DATA32
22 ASSUME CS:FLAT, DS:FLAT, SS:FLAT, ES:FLAT
23DATA32 SEGMENT
24DATA32 ENDS
25BSS32 SEGMENT
26BSS32 ENDS
27CONST32 SEGMENT
28CONST32 ENDS
29
30DATA32 SEGMENT
31ioentry DWORD 0
32gdt WORD 0
33DATA32 ENDS
34
35CODE32 SEGMENT
36
37; performs fast output of a byte to an I/O port
38; this routine is intended to be called from gcc C code
39;
40; Calling convention:
41; void c_outb1(short port,char data)
42;
43;
44 PUBLIC c_outb1
45 ALIGN 04H
46c_outb1 PROC
47 MOV EDX, [ESP+4] ; get port
48 MOV AL, [ESP+8] ; get data
49 OUT DX,AL
50 RET
51c_outb1 ENDP
52
53; performs fast output of a word to an I/O port
54; this routine is intended to be called from gcc C code
55;
56; Calling convention:
57; void c_outw1(short port,short data)
58;
59;
60 PUBLIC c_outw1
61 ALIGN 04H
62c_outw1 PROC
63 MOV EDX, [ESP+4] ; get port
64 MOV AX, [ESP+8] ; get data
65 OUT DX,AX
66 RET
67c_outw1 ENDP
68
69; performs fast output of a longword to an I/O port
70; this routine is intended to be called from gcc C code
71;
72; Calling convention:
73; void c_outl1(short port,long data)
74;
75;
76 PUBLIC c_outl1
77 ALIGN 04H
78c_outl1 PROC
79 MOV EDX, [ESP+4] ; get port
80 MOV EAX, [ESP+8] ; get data
81 OUT DX, EAX
82 RET
83c_outl1 ENDP
84
85; performs fast input of a byte from an I/O port
86; this routine is intended to be called from gcc C code
87;
88; Calling convention:
89; char c_inb1(short port)
90;
91;
92 PUBLIC c_inb1
93 ALIGN 04H
94c_inb1 PROC
95 MOV EDX, [ESP+4] ; get port
96 IN AL,DX
97 AND EAX, 000000FFh
98 RET
99c_inb1 ENDP
100
101; performs fast input of a word from an I/O port
102; this routine is intended to be called from gcc C code
103;
104; Calling convention:
105; short c_inw1(short port)
106;
107;
108 PUBLIC c_inw1
109 ALIGN 04H
110c_inw1 PROC
111 MOV EDX, [ESP+4] ; get port
112 IN AX, DX
113 AND EAX, 0000FFFFh ; mask out word
114 RET
115c_inw1 ENDP
116
117; performs fast input of a longword from an I/O port
118; this routine is intended to be called from gcc C code
119;
120; Calling convention:
121; lomg c_inl1(short port)
122;
123;
124 PUBLIC c_inl1
125 ALIGN 04H
126c_inl1 PROC
127 MOV EDX, [ESP+4] ; get port
128 IN EAX, DX
129 RET
130c_inl1 ENDP
131
132CODE32 ENDS
133
134;------------------------------------------------------------------------------
135
136; Initialize I/O access via the driver.
137; You *must* call this routine once for each *thread* that wants to do
138; I/O.
139;
140; The routine is mainly equivalent to a C routine performing the
141; following (but no need to add another file):
142; DosOpen("/dev/fastio$", read, nonexclusive)
143; DosDevIOCtl(device, XFREE86IO, IOGETSEL32)
144; selector -> ioentry+4
145; DosClose(device)
146;
147; Calling convention:
148; int io_init1(void)
149; Return:
150; 0 if successful
151; standard APIRET RETurn code if error
152;
153
154CONST32 SEGMENT
155 ALIGN 04H
156devname:
157 DB "/dev/fastio$",0
158CONST32 ENDS
159
160
161CODE32 SEGMENT
162 PUBLIC io_init1
163 EXTRN DosOpen:PROC
164 EXTRN DosClose:PROC
165 EXTRN DosDevIOCtl:PROC
166 ALIGN 04H
167io_init1 PROC
168 PUSH EBP
169 MOV EBP, ESP ; standard stack frame
170 SUB ESP, 16 ; reserve memory
171 ; -16 = len arg of DosDevIOCtl
172 ; -12 = action arg of DosOpen
173 ; -8 = fd arg of DosOpen
174 ; -2 = short GDT selector arg
175 PUSH 0 ; (PEAOP2)NULL
176 PUSH 66 ; OPENACCESSREADWRITE|OPENSHAREDENYNONE
177 PUSH 1 ; FILEOPEN
178 PUSH 0 ; FILENORMAL
179 PUSH 0 ; initial size
180 LEA EAX, [EBP-12] ; Adress of 'action' arg
181 PUSH EAX
182 LEA EAX, [EBP-8] ; Address of 'fd' arg
183 PUSH EAX
184 PUSH OFFSET FLAT:devname
185 CALL DosOpen ; call DosOpen
186 ADD ESP, 32 ; cleanup stack frame
187 CMP EAX, 0 ; is return code zero?
188 JE goon ; yes, proceed
189 LEAVE ; no RETurn error
190 RET
191 ALIGN 04H
192goon:
193 LEA EAX, [EBP-16] ; address of 'len' arg of DosDevIOCtl
194 PUSH EAX
195 PUSH 2 ; sizeof(short)
196 LEA EAX, [EBP-2] ; address to return the GDT selector
197 PUSH EAX
198 PUSH 0 ; no parameter len
199 PUSH 0 ; no parameter size
200 PUSH 0 ; no parameter address
201 PUSH 100 ; function code IOGETSEL32
202 PUSH 118 ; category code XFREE6IO
203 MOV EAX,[EBP-8] ; file handle
204 PUSH EAX
205 CALL DosDevIOCtl ; perform ioctl
206 ADD ESP, 36 ; cleanup stack
207 CMP EAX, 0 ; is return code = 0?
208 JE ok ; yes, proceed
209 PUSH EAX ; was error, save error code
210 MOV EAX, [EBP-8] ; file handle
211 PUSH EAX
212 CALL DosClose ; close device
213 ADD ESP,4 ; clean stack
214 POP EAX ; get error code
215 LEAVE ; return error
216 RET
217
218 ALIGN 04H
219ok:
220 MOV EAX, [EBP-8] ; file handle
221 PUSH EAX ; do normal close
222 CALL DosClose
223 ADD ESP,4 ; clean stack
224
225 MOV AX, [EBP-2] ; load gdt selector
226 MOV gdt, AX ; store in ioentry address selector part
227 XOR EAX, EAX ; EAX = 0
228 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part
229 ; return code = 0 (in EAX)
230
231 ; now use this function to raise the IOPL
232 PUSH EBX ; bird fix
233 MOV EBX,13 ; special function code
234 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32
235 POP EBX ; bird fix
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 MOV EAX, dword ptr [ESP+4]
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 PUSH EBX ; bird fix
256 MOV EBX,13 ; special function code
257 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32
258 POP EBX ; bird fix
259
260 XOR EAX, EAX ; return code = 0
261 ret
262io_init2 ENDP
263
264 PUBLIC io_exit1
265 ALIGN 04H
266io_exit1 PROC
267 push EBP
268 MOV EBP, ESP ; stackframe, I am accustomed to this :-)
269
270 MOV AX, gdt ; check if ioinit was called once
271 OR AX, AX
272 JZ exerr ; no gdt entry, so process cannot be at IOPL=3
273 ; through this mechanism
274 PUSH EBX ; bird fix
275 MOV EBX, 14 ; function code to disable iopl
276 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
277 POP EBX ; bird fix
278
279 ; process should now be at IOPL=3 again
280 XOR EAX, EAX ; ok, RETurn code = 0
281 LEAVE
282 RET
283exerr: XOR EAX, EAX ; not ok, RETurn code = ffffffff
284 DEC EAX
285 LEAVE
286 RET
287io_exit1 ENDP
288
289
290
291; for diagnostic only
292
293;; PUBLIC psw
294;; ALIGN 04H
295;;psw PROC
296;; PUSHF ; get the current PSW
297;; POP EAX ; into EAX
298;; RET
299;;psw ENDP
300
301CODE32 ENDS
302 END
Note: See TracBrowser for help on using the repository browser.