]>
Commit | Line | Data |
---|---|---|
1 | ; | |
2 | ; jmemdosa.asm | |
3 | ; | |
4 | ; Copyright (C) 1992, Thomas G. Lane. | |
5 | ; This file is part of the Independent JPEG Group's software. | |
6 | ; For conditions of distribution and use, see the accompanying README file. | |
7 | ; | |
8 | ; This file contains low-level interface routines to support the MS-DOS | |
9 | ; backing store manager (jmemdos.c). Routines are provided to access disk | |
10 | ; files through direct DOS calls, and to access XMS and EMS drivers. | |
11 | ; | |
12 | ; This file should assemble with Microsoft's MASM or any compatible | |
13 | ; assembler (including Borland's Turbo Assembler). If you haven't got | |
14 | ; a compatible assembler, better fall back to jmemansi.c or jmemname.c. | |
15 | ; | |
16 | ; To minimize dependence on the C compiler's register usage conventions, | |
17 | ; we save and restore all 8086 registers, even though most compilers only | |
18 | ; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return | |
19 | ; values, which everybody returns in AX. | |
20 | ; | |
21 | ; Based on code contributed by Ge' Weijers. | |
22 | ; | |
23 | ||
24 | JMEMDOSA_TXT segment byte public 'CODE' | |
25 | ||
26 | assume cs:JMEMDOSA_TXT | |
27 | ||
28 | public _jdos_open | |
29 | public _jdos_close | |
30 | public _jdos_seek | |
31 | public _jdos_read | |
32 | public _jdos_write | |
33 | public _jxms_getdriver | |
34 | public _jxms_calldriver | |
35 | public _jems_available | |
36 | public _jems_calldriver | |
37 | ||
38 | ; | |
39 | ; short far jdos_open (short far * handle, char far * filename) | |
40 | ; | |
41 | ; Create and open a temporary file | |
42 | ; | |
43 | _jdos_open proc far | |
44 | push bp ; linkage | |
45 | mov bp,sp | |
46 | push si ; save all registers for safety | |
47 | push di | |
48 | push bx | |
49 | push cx | |
50 | push dx | |
51 | push es | |
52 | push ds | |
53 | mov cx,0 ; normal file attributes | |
54 | lds dx,dword ptr [bp+10] ; get filename pointer | |
55 | mov ah,3ch ; create file | |
56 | int 21h | |
57 | jc open_err ; if failed, return error code | |
58 | lds bx,dword ptr [bp+6] ; get handle pointer | |
59 | mov word ptr [bx],ax ; save the handle | |
60 | xor ax,ax ; return zero for OK | |
61 | open_err: pop ds ; restore registers and exit | |
62 | pop es | |
63 | pop dx | |
64 | pop cx | |
65 | pop bx | |
66 | pop di | |
67 | pop si | |
68 | pop bp | |
69 | ret | |
70 | _jdos_open endp | |
71 | ||
72 | ||
73 | ; | |
74 | ; short far jdos_close (short handle) | |
75 | ; | |
76 | ; Close the file handle | |
77 | ; | |
78 | _jdos_close proc far | |
79 | push bp ; linkage | |
80 | mov bp,sp | |
81 | push si ; save all registers for safety | |
82 | push di | |
83 | push bx | |
84 | push cx | |
85 | push dx | |
86 | push es | |
87 | push ds | |
88 | mov bx,word ptr [bp+6] ; file handle | |
89 | mov ah,3eh ; close file | |
90 | int 21h | |
91 | jc close_err ; if failed, return error code | |
92 | xor ax,ax ; return zero for OK | |
93 | close_err: pop ds ; restore registers and exit | |
94 | pop es | |
95 | pop dx | |
96 | pop cx | |
97 | pop bx | |
98 | pop di | |
99 | pop si | |
100 | pop bp | |
101 | ret | |
102 | _jdos_close endp | |
103 | ||
104 | ||
105 | ; | |
106 | ; short far jdos_seek (short handle, long offset) | |
107 | ; | |
108 | ; Set file position | |
109 | ; | |
110 | _jdos_seek proc far | |
111 | push bp ; linkage | |
112 | mov bp,sp | |
113 | push si ; save all registers for safety | |
114 | push di | |
115 | push bx | |
116 | push cx | |
117 | push dx | |
118 | push es | |
119 | push ds | |
120 | mov bx,word ptr [bp+6] ; file handle | |
121 | mov dx,word ptr [bp+8] ; LS offset | |
122 | mov cx,word ptr [bp+10] ; MS offset | |
123 | mov ax,4200h ; absolute seek | |
124 | int 21h | |
125 | jc seek_err ; if failed, return error code | |
126 | xor ax,ax ; return zero for OK | |
127 | seek_err: pop ds ; restore registers and exit | |
128 | pop es | |
129 | pop dx | |
130 | pop cx | |
131 | pop bx | |
132 | pop di | |
133 | pop si | |
134 | pop bp | |
135 | ret | |
136 | _jdos_seek endp | |
137 | ||
138 | ||
139 | ; | |
140 | ; short far jdos_read (short handle, void far * buffer, unsigned short count) | |
141 | ; | |
142 | ; Read from file | |
143 | ; | |
144 | _jdos_read proc far | |
145 | push bp ; linkage | |
146 | mov bp,sp | |
147 | push si ; save all registers for safety | |
148 | push di | |
149 | push bx | |
150 | push cx | |
151 | push dx | |
152 | push es | |
153 | push ds | |
154 | mov bx,word ptr [bp+6] ; file handle | |
155 | lds dx,dword ptr [bp+8] ; buffer address | |
156 | mov cx,word ptr [bp+12] ; number of bytes | |
157 | mov ah,3fh ; read file | |
158 | int 21h | |
159 | jc read_err ; if failed, return error code | |
160 | cmp ax,word ptr [bp+12] ; make sure all bytes were read | |
161 | je read_ok | |
162 | mov ax,1 ; else return 1 for not OK | |
163 | jmp short read_err | |
164 | read_ok: xor ax,ax ; return zero for OK | |
165 | read_err: pop ds ; restore registers and exit | |
166 | pop es | |
167 | pop dx | |
168 | pop cx | |
169 | pop bx | |
170 | pop di | |
171 | pop si | |
172 | pop bp | |
173 | ret | |
174 | _jdos_read endp | |
175 | ||
176 | ||
177 | ; | |
178 | ; short far jdos_write (short handle, void far * buffer, unsigned short count) | |
179 | ; | |
180 | ; Write to file | |
181 | ; | |
182 | _jdos_write proc far | |
183 | push bp ; linkage | |
184 | mov bp,sp | |
185 | push si ; save all registers for safety | |
186 | push di | |
187 | push bx | |
188 | push cx | |
189 | push dx | |
190 | push es | |
191 | push ds | |
192 | mov bx,word ptr [bp+6] ; file handle | |
193 | lds dx,dword ptr [bp+8] ; buffer address | |
194 | mov cx,word ptr [bp+12] ; number of bytes | |
195 | mov ah,40h ; write file | |
196 | int 21h | |
197 | jc write_err ; if failed, return error code | |
198 | cmp ax,word ptr [bp+12] ; make sure all bytes written | |
199 | je write_ok | |
200 | mov ax,1 ; else return 1 for not OK | |
201 | jmp short write_err | |
202 | write_ok: xor ax,ax ; return zero for OK | |
203 | write_err: pop ds ; restore registers and exit | |
204 | pop es | |
205 | pop dx | |
206 | pop cx | |
207 | pop bx | |
208 | pop di | |
209 | pop si | |
210 | pop bp | |
211 | ret | |
212 | _jdos_write endp | |
213 | ||
214 | ||
215 | ; | |
216 | ; void far jxms_getdriver (XMSDRIVER far *) | |
217 | ; | |
218 | ; Get the address of the XMS driver, or NULL if not available | |
219 | ; | |
220 | _jxms_getdriver proc far | |
221 | push bp ; linkage | |
222 | mov bp,sp | |
223 | push si ; save all registers for safety | |
224 | push di | |
225 | push bx | |
226 | push cx | |
227 | push dx | |
228 | push es | |
229 | push ds | |
230 | mov ax,4300h ; call multiplex interrupt with | |
231 | int 2fh ; a magic cookie, hex 4300 | |
232 | cmp al,80h ; AL should contain hex 80 | |
233 | je xmsavail | |
234 | xor dx,dx ; no XMS driver available | |
235 | xor ax,ax ; return a nil pointer | |
236 | jmp short xmsavail_done | |
237 | xmsavail: mov ax,4310h ; fetch driver address with | |
238 | int 2fh ; another magic cookie | |
239 | mov dx,es ; copy address to dx:ax | |
240 | mov ax,bx | |
241 | xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value | |
242 | mov word ptr es:[bx],ax | |
243 | mov word ptr es:[bx+2],dx | |
244 | pop ds ; restore registers and exit | |
245 | pop es | |
246 | pop dx | |
247 | pop cx | |
248 | pop bx | |
249 | pop di | |
250 | pop si | |
251 | pop bp | |
252 | ret | |
253 | _jxms_getdriver endp | |
254 | ||
255 | ||
256 | ; | |
257 | ; void far jxms_calldriver (XMSDRIVER, XMScontext far *) | |
258 | ; | |
259 | ; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers. | |
260 | ; These are loaded, the XMS call is performed, and the new values of the | |
261 | ; AX,DX,BX registers are written back to the context structure. | |
262 | ; | |
263 | _jxms_calldriver proc far | |
264 | push bp ; linkage | |
265 | mov bp,sp | |
266 | push si ; save all registers for safety | |
267 | push di | |
268 | push bx | |
269 | push cx | |
270 | push dx | |
271 | push es | |
272 | push ds | |
273 | les bx,dword ptr [bp+10] ; get XMScontext pointer | |
274 | mov ax,word ptr es:[bx] ; load registers | |
275 | mov dx,word ptr es:[bx+2] | |
276 | mov si,word ptr es:[bx+6] | |
277 | mov ds,word ptr es:[bx+8] | |
278 | mov bx,word ptr es:[bx+4] | |
279 | call dword ptr [bp+6] ; call the driver | |
280 | mov cx,bx ; save returned BX for a sec | |
281 | les bx,dword ptr [bp+10] ; get XMScontext pointer | |
282 | mov word ptr es:[bx],ax ; put back ax,dx,bx | |
283 | mov word ptr es:[bx+2],dx | |
284 | mov word ptr es:[bx+4],cx | |
285 | pop ds ; restore registers and exit | |
286 | pop es | |
287 | pop dx | |
288 | pop cx | |
289 | pop bx | |
290 | pop di | |
291 | pop si | |
292 | pop bp | |
293 | ret | |
294 | _jxms_calldriver endp | |
295 | ||
296 | ||
297 | ; | |
298 | ; short far jems_available (void) | |
299 | ; | |
300 | ; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs) | |
301 | ; | |
302 | _jems_available proc far | |
303 | push si ; save all registers for safety | |
304 | push di | |
305 | push bx | |
306 | push cx | |
307 | push dx | |
308 | push es | |
309 | push ds | |
310 | mov ax,3567h ; get interrupt vector 67h | |
311 | int 21h | |
312 | push cs | |
313 | pop ds | |
314 | mov di,000ah ; check offs 10 in returned seg | |
315 | lea si,ASCII_device_name ; against literal string | |
316 | mov cx,8 | |
317 | cld | |
318 | repe cmpsb | |
319 | jne no_ems | |
320 | mov ax,1 ; match, it's there | |
321 | jmp short avail_done | |
322 | no_ems: xor ax,ax ; it's not there | |
323 | avail_done: pop ds ; restore registers and exit | |
324 | pop es | |
325 | pop dx | |
326 | pop cx | |
327 | pop bx | |
328 | pop di | |
329 | pop si | |
330 | ret | |
331 | ||
332 | ASCII_device_name db "EMMXXXX0" | |
333 | ||
334 | _jems_available endp | |
335 | ||
336 | ||
337 | ; | |
338 | ; void far jems_calldriver (EMScontext far *) | |
339 | ; | |
340 | ; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. | |
341 | ; These are loaded, the EMS trap is performed, and the new values of the | |
342 | ; AX,DX,BX registers are written back to the context structure. | |
343 | ; | |
344 | _jems_calldriver proc far | |
345 | push bp ; linkage | |
346 | mov bp,sp | |
347 | push si ; save all registers for safety | |
348 | push di | |
349 | push bx | |
350 | push cx | |
351 | push dx | |
352 | push es | |
353 | push ds | |
354 | les bx,dword ptr [bp+6] ; get EMScontext pointer | |
355 | mov ax,word ptr es:[bx] ; load registers | |
356 | mov dx,word ptr es:[bx+2] | |
357 | mov si,word ptr es:[bx+6] | |
358 | mov ds,word ptr es:[bx+8] | |
359 | mov bx,word ptr es:[bx+4] | |
360 | int 67h ; call the EMS driver | |
361 | mov cx,bx ; save returned BX for a sec | |
362 | les bx,dword ptr [bp+6] ; get EMScontext pointer | |
363 | mov word ptr es:[bx],ax ; put back ax,dx,bx | |
364 | mov word ptr es:[bx+2],dx | |
365 | mov word ptr es:[bx+4],cx | |
366 | pop ds ; restore registers and exit | |
367 | pop es | |
368 | pop dx | |
369 | pop cx | |
370 | pop bx | |
371 | pop di | |
372 | pop si | |
373 | pop bp | |
374 | ret | |
375 | _jems_calldriver endp | |
376 | ||
377 | JMEMDOSA_TXT ends | |
378 | ||
379 | end |