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.
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.
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.
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.
21 ; Based on code contributed by Ge' Weijers.
24 JMEMDOSA_TXT
segment byte public 'CODE'
26 assume cs:JMEMDOSA_TXT
33 public _jxms_getdriver
34 public _jxms_calldriver
35 public _jems_available
36 public _jems_calldriver
39 ; short far jdos_open (short far * handle, char far * filename)
41 ; Create and open a temporary file
46 push si ; save all registers for safety
53 mov cx,0 ; normal file attributes
54 lds dx,dword ptr [bp+10] ; get filename pointer
55 mov ah,3ch ; create file
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
74 ; short far jdos_close (short handle)
76 ; Close the file handle
81 push si ; save all registers for safety
88 mov bx,word ptr [bp+6] ; file handle
89 mov ah,3eh
; close file
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
106 ; short far jdos_seek (short handle, long offset)
113 push si ; save all registers for safety
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
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
140 ; short far jdos_read (short handle, void far * buffer, unsigned short count)
147 push si ; save all registers for safety
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
159 jc read_err
; if failed, return error code
160 cmp ax,word ptr [bp+12] ; make sure all bytes were read
162 mov ax,1 ; else return 1 for not OK
164 read_ok: xor ax,ax ; return zero for OK
165 read_err: pop ds ; restore registers and exit
178 ; short far jdos_write (short handle, void far * buffer, unsigned short count)
185 push si ; save all registers for safety
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
197 jc write_err
; if failed, return error code
198 cmp ax,word ptr [bp+12] ; make sure all bytes written
200 mov ax,1 ; else return 1 for not OK
202 write_ok: xor ax,ax ; return zero for OK
203 write_err: pop ds ; restore registers and exit
216 ; void far jxms_getdriver (XMSDRIVER far *)
218 ; Get the address of the XMS driver, or NULL if not available
220 _jxms_getdriver
proc far
223 push si ; save all registers for safety
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
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
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
257 ; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
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.
263 _jxms_calldriver
proc far
266 push si ; save all registers for safety
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
294 _jxms_calldriver
endp
298 ; short far jems_available (void)
300 ; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
302 _jems_available
proc far
303 push si ; save all registers for safety
310 mov ax,3567h ; get interrupt vector 67h
314 mov di,000ah ; check offs 10 in returned seg
315 lea si,ASCII_device_name
; against literal string
320 mov ax,1 ; match, it's there
322 no_ems: xor ax,ax ; it's not there
323 avail_done: pop ds ; restore registers and exit
332 ASCII_device_name
db "EMMXXXX0"
338 ; void far jems_calldriver (EMScontext far *)
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.
344 _jems_calldriver
proc far
347 push si ; save all registers for safety
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
375 _jems_calldriver
endp