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

Last change on this file since 5280 was 1979, checked in by sandervl, 26 years ago

EB's devname offset fix

File size: 6.7 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 MOV EBX,13 ; special function code
233 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32
234
235 ; thread should now be running at IOPL=3
236
237 XOR EAX, EAX ; return code = 0
238 LEAVE ; clean stack frame
239 RET ; exit
240io_init1 ENDP
241
242; void in_init(short)
243PUBLIC io_init2
244 ALIGN 04H
245io_init2 PROC
246
247 MOV gdt, AX ; store in ioentry address selector part
248 XOR EAX, EAX ; EAX = 0
249 MOV DWORD PTR [ioentry], EAX ; clear ioentry offset part
250 ; return code = 0 (in EAX)
251
252 ; now use this function to raise the IOPL
253 MOV EBX,13 ; special function code
254 CALL FWORD PTR [ioentry] ; CALL intersegment indirect 16:32
255
256 XOR EAX, EAX ; return code = 0
257 ret
258io_init2 ENDP
259
260 PUBLIC io_exit1
261 ALIGN 04H
262io_exit1 PROC
263 push EBP
264 MOV EBP, ESP ; stackframe, I am accustomed to this :-)
265
266 MOV AX, gdt ; check if ioinit was called once
267 OR AX, AX
268 JZ exerr ; no gdt entry, so process cannot be at IOPL=3
269 ; through this mechanism
270
271 MOV EBX, 14 ; function code to disable iopl
272 CALL FWORD PTR [ioentry] ; call intersegment indirect 16:32
273
274 ; process should now be at IOPL=3 again
275 XOR EAX, EAX ; ok, RETurn code = 0
276 LEAVE
277 RET
278exerr: XOR EAX, EAX ; not ok, RETurn code = ffffffff
279 DEC EAX
280 LEAVE
281 RET
282io_exit1 ENDP
283
284
285
286; for diagnostic only
287
288 PUBLIC psw
289 ALIGN 04H
290psw PROC
291 PUSHF ; get the current PSW
292 POP EAX ; into EAX
293 RET
294psw ENDP
295
296CODE32 ENDS
297 END
Note: See TracBrowser for help on using the repository browser.