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