blob: ecd43729fe5e286396b3d1cc4be28d27cca48867 [file] [log] [blame]
Dees_Troy51a0e822012-09-05 15:24:24 -04001;
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
24JMEMDOSA_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
61open_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
93close_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
127seek_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
164read_ok: xor ax,ax ; return zero for OK
165read_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
202write_ok: xor ax,ax ; return zero for OK
203write_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
237xmsavail: 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
241xmsavail_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
322no_ems: xor ax,ax ; it's not there
323avail_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
332ASCII_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
377JMEMDOSA_TXT ends
378
379 end