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