|
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 |