xref: /plan9/sys/src/cmd/gs/jpeg/jmemdosa.asm (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1*7dd7cddfSDavid du Colombier;
2*7dd7cddfSDavid du Colombier; jmemdosa.asm
3*7dd7cddfSDavid du Colombier;
4*7dd7cddfSDavid du Colombier; Copyright (C) 1992, Thomas G. Lane.
5*7dd7cddfSDavid du Colombier; This file is part of the Independent JPEG Group's software.
6*7dd7cddfSDavid du Colombier; For conditions of distribution and use, see the accompanying README file.
7*7dd7cddfSDavid du Colombier;
8*7dd7cddfSDavid du Colombier; This file contains low-level interface routines to support the MS-DOS
9*7dd7cddfSDavid du Colombier; backing store manager (jmemdos.c).  Routines are provided to access disk
10*7dd7cddfSDavid du Colombier; files through direct DOS calls, and to access XMS and EMS drivers.
11*7dd7cddfSDavid du Colombier;
12*7dd7cddfSDavid du Colombier; This file should assemble with Microsoft's MASM or any compatible
13*7dd7cddfSDavid du Colombier; assembler (including Borland's Turbo Assembler).  If you haven't got
14*7dd7cddfSDavid du Colombier; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
15*7dd7cddfSDavid du Colombier;
16*7dd7cddfSDavid du Colombier; To minimize dependence on the C compiler's register usage conventions,
17*7dd7cddfSDavid du Colombier; we save and restore all 8086 registers, even though most compilers only
18*7dd7cddfSDavid du Colombier; require SI,DI,DS to be preserved.  Also, we use only 16-bit-wide return
19*7dd7cddfSDavid du Colombier; values, which everybody returns in AX.
20*7dd7cddfSDavid du Colombier;
21*7dd7cddfSDavid du Colombier; Based on code contributed by Ge' Weijers.
22*7dd7cddfSDavid du Colombier;
23*7dd7cddfSDavid du Colombier
24*7dd7cddfSDavid du ColombierJMEMDOSA_TXT	segment byte public 'CODE'
25*7dd7cddfSDavid du Colombier
26*7dd7cddfSDavid du Colombier		assume	cs:JMEMDOSA_TXT
27*7dd7cddfSDavid du Colombier
28*7dd7cddfSDavid du Colombier		public	_jdos_open
29*7dd7cddfSDavid du Colombier		public	_jdos_close
30*7dd7cddfSDavid du Colombier		public	_jdos_seek
31*7dd7cddfSDavid du Colombier		public	_jdos_read
32*7dd7cddfSDavid du Colombier		public	_jdos_write
33*7dd7cddfSDavid du Colombier		public	_jxms_getdriver
34*7dd7cddfSDavid du Colombier		public	_jxms_calldriver
35*7dd7cddfSDavid du Colombier		public	_jems_available
36*7dd7cddfSDavid du Colombier		public	_jems_calldriver
37*7dd7cddfSDavid du Colombier
38*7dd7cddfSDavid du Colombier;
39*7dd7cddfSDavid du Colombier; short far jdos_open (short far * handle, char far * filename)
40*7dd7cddfSDavid du Colombier;
41*7dd7cddfSDavid du Colombier; Create and open a temporary file
42*7dd7cddfSDavid du Colombier;
43*7dd7cddfSDavid du Colombier_jdos_open	proc	far
44*7dd7cddfSDavid du Colombier		push	bp			; linkage
45*7dd7cddfSDavid du Colombier		mov 	bp,sp
46*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
47*7dd7cddfSDavid du Colombier		push	di
48*7dd7cddfSDavid du Colombier		push	bx
49*7dd7cddfSDavid du Colombier		push	cx
50*7dd7cddfSDavid du Colombier		push	dx
51*7dd7cddfSDavid du Colombier		push	es
52*7dd7cddfSDavid du Colombier		push	ds
53*7dd7cddfSDavid du Colombier		mov	cx,0			; normal file attributes
54*7dd7cddfSDavid du Colombier		lds	dx,dword ptr [bp+10]	; get filename pointer
55*7dd7cddfSDavid du Colombier		mov	ah,3ch			; create file
56*7dd7cddfSDavid du Colombier		int	21h
57*7dd7cddfSDavid du Colombier		jc	open_err		; if failed, return error code
58*7dd7cddfSDavid du Colombier		lds	bx,dword ptr [bp+6]	; get handle pointer
59*7dd7cddfSDavid du Colombier		mov	word ptr [bx],ax	; save the handle
60*7dd7cddfSDavid du Colombier		xor	ax,ax			; return zero for OK
61*7dd7cddfSDavid du Colombieropen_err:	pop	ds			; restore registers and exit
62*7dd7cddfSDavid du Colombier		pop	es
63*7dd7cddfSDavid du Colombier		pop	dx
64*7dd7cddfSDavid du Colombier		pop	cx
65*7dd7cddfSDavid du Colombier		pop	bx
66*7dd7cddfSDavid du Colombier		pop	di
67*7dd7cddfSDavid du Colombier		pop	si
68*7dd7cddfSDavid du Colombier		pop 	bp
69*7dd7cddfSDavid du Colombier		ret
70*7dd7cddfSDavid du Colombier_jdos_open	endp
71*7dd7cddfSDavid du Colombier
72*7dd7cddfSDavid du Colombier
73*7dd7cddfSDavid du Colombier;
74*7dd7cddfSDavid du Colombier; short far jdos_close (short handle)
75*7dd7cddfSDavid du Colombier;
76*7dd7cddfSDavid du Colombier; Close the file handle
77*7dd7cddfSDavid du Colombier;
78*7dd7cddfSDavid du Colombier_jdos_close	proc	far
79*7dd7cddfSDavid du Colombier		push	bp			; linkage
80*7dd7cddfSDavid du Colombier		mov 	bp,sp
81*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
82*7dd7cddfSDavid du Colombier		push	di
83*7dd7cddfSDavid du Colombier		push	bx
84*7dd7cddfSDavid du Colombier		push	cx
85*7dd7cddfSDavid du Colombier		push	dx
86*7dd7cddfSDavid du Colombier		push	es
87*7dd7cddfSDavid du Colombier		push	ds
88*7dd7cddfSDavid du Colombier		mov	bx,word ptr [bp+6]	; file handle
89*7dd7cddfSDavid du Colombier		mov	ah,3eh			; close file
90*7dd7cddfSDavid du Colombier		int	21h
91*7dd7cddfSDavid du Colombier		jc	close_err		; if failed, return error code
92*7dd7cddfSDavid du Colombier		xor	ax,ax			; return zero for OK
93*7dd7cddfSDavid du Colombierclose_err:	pop	ds			; restore registers and exit
94*7dd7cddfSDavid du Colombier		pop	es
95*7dd7cddfSDavid du Colombier		pop	dx
96*7dd7cddfSDavid du Colombier		pop	cx
97*7dd7cddfSDavid du Colombier		pop	bx
98*7dd7cddfSDavid du Colombier		pop	di
99*7dd7cddfSDavid du Colombier		pop	si
100*7dd7cddfSDavid du Colombier		pop 	bp
101*7dd7cddfSDavid du Colombier		ret
102*7dd7cddfSDavid du Colombier_jdos_close	endp
103*7dd7cddfSDavid du Colombier
104*7dd7cddfSDavid du Colombier
105*7dd7cddfSDavid du Colombier;
106*7dd7cddfSDavid du Colombier; short far jdos_seek (short handle, long offset)
107*7dd7cddfSDavid du Colombier;
108*7dd7cddfSDavid du Colombier; Set file position
109*7dd7cddfSDavid du Colombier;
110*7dd7cddfSDavid du Colombier_jdos_seek	proc	far
111*7dd7cddfSDavid du Colombier		push	bp			; linkage
112*7dd7cddfSDavid du Colombier		mov 	bp,sp
113*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
114*7dd7cddfSDavid du Colombier		push	di
115*7dd7cddfSDavid du Colombier		push	bx
116*7dd7cddfSDavid du Colombier		push	cx
117*7dd7cddfSDavid du Colombier		push	dx
118*7dd7cddfSDavid du Colombier		push	es
119*7dd7cddfSDavid du Colombier		push	ds
120*7dd7cddfSDavid du Colombier		mov	bx,word ptr [bp+6]	; file handle
121*7dd7cddfSDavid du Colombier		mov	dx,word ptr [bp+8]	; LS offset
122*7dd7cddfSDavid du Colombier		mov	cx,word ptr [bp+10]	; MS offset
123*7dd7cddfSDavid du Colombier		mov	ax,4200h		; absolute seek
124*7dd7cddfSDavid du Colombier		int	21h
125*7dd7cddfSDavid du Colombier		jc	seek_err		; if failed, return error code
126*7dd7cddfSDavid du Colombier		xor	ax,ax			; return zero for OK
127*7dd7cddfSDavid du Colombierseek_err:	pop	ds			; restore registers and exit
128*7dd7cddfSDavid du Colombier		pop	es
129*7dd7cddfSDavid du Colombier		pop	dx
130*7dd7cddfSDavid du Colombier		pop	cx
131*7dd7cddfSDavid du Colombier		pop	bx
132*7dd7cddfSDavid du Colombier		pop	di
133*7dd7cddfSDavid du Colombier		pop	si
134*7dd7cddfSDavid du Colombier		pop 	bp
135*7dd7cddfSDavid du Colombier		ret
136*7dd7cddfSDavid du Colombier_jdos_seek	endp
137*7dd7cddfSDavid du Colombier
138*7dd7cddfSDavid du Colombier
139*7dd7cddfSDavid du Colombier;
140*7dd7cddfSDavid du Colombier; short far jdos_read (short handle, void far * buffer, unsigned short count)
141*7dd7cddfSDavid du Colombier;
142*7dd7cddfSDavid du Colombier; Read from file
143*7dd7cddfSDavid du Colombier;
144*7dd7cddfSDavid du Colombier_jdos_read	proc	far
145*7dd7cddfSDavid du Colombier		push	bp			; linkage
146*7dd7cddfSDavid du Colombier		mov 	bp,sp
147*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
148*7dd7cddfSDavid du Colombier		push	di
149*7dd7cddfSDavid du Colombier		push	bx
150*7dd7cddfSDavid du Colombier		push	cx
151*7dd7cddfSDavid du Colombier		push	dx
152*7dd7cddfSDavid du Colombier		push	es
153*7dd7cddfSDavid du Colombier		push	ds
154*7dd7cddfSDavid du Colombier		mov	bx,word ptr [bp+6]	; file handle
155*7dd7cddfSDavid du Colombier		lds	dx,dword ptr [bp+8]	; buffer address
156*7dd7cddfSDavid du Colombier		mov	cx,word ptr [bp+12]	; number of bytes
157*7dd7cddfSDavid du Colombier		mov	ah,3fh			; read file
158*7dd7cddfSDavid du Colombier		int	21h
159*7dd7cddfSDavid du Colombier		jc	read_err		; if failed, return error code
160*7dd7cddfSDavid du Colombier		cmp	ax,word ptr [bp+12]	; make sure all bytes were read
161*7dd7cddfSDavid du Colombier		je	read_ok
162*7dd7cddfSDavid du Colombier		mov	ax,1			; else return 1 for not OK
163*7dd7cddfSDavid du Colombier		jmp	short read_err
164*7dd7cddfSDavid du Colombierread_ok:	xor	ax,ax			; return zero for OK
165*7dd7cddfSDavid du Colombierread_err:	pop	ds			; restore registers and exit
166*7dd7cddfSDavid du Colombier		pop	es
167*7dd7cddfSDavid du Colombier		pop	dx
168*7dd7cddfSDavid du Colombier		pop	cx
169*7dd7cddfSDavid du Colombier		pop	bx
170*7dd7cddfSDavid du Colombier		pop	di
171*7dd7cddfSDavid du Colombier		pop	si
172*7dd7cddfSDavid du Colombier		pop 	bp
173*7dd7cddfSDavid du Colombier		ret
174*7dd7cddfSDavid du Colombier_jdos_read	endp
175*7dd7cddfSDavid du Colombier
176*7dd7cddfSDavid du Colombier
177*7dd7cddfSDavid du Colombier;
178*7dd7cddfSDavid du Colombier; short far jdos_write (short handle, void far * buffer, unsigned short count)
179*7dd7cddfSDavid du Colombier;
180*7dd7cddfSDavid du Colombier; Write to file
181*7dd7cddfSDavid du Colombier;
182*7dd7cddfSDavid du Colombier_jdos_write	proc	far
183*7dd7cddfSDavid du Colombier		push	bp			; linkage
184*7dd7cddfSDavid du Colombier		mov 	bp,sp
185*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
186*7dd7cddfSDavid du Colombier		push	di
187*7dd7cddfSDavid du Colombier		push	bx
188*7dd7cddfSDavid du Colombier		push	cx
189*7dd7cddfSDavid du Colombier		push	dx
190*7dd7cddfSDavid du Colombier		push	es
191*7dd7cddfSDavid du Colombier		push	ds
192*7dd7cddfSDavid du Colombier		mov	bx,word ptr [bp+6]	; file handle
193*7dd7cddfSDavid du Colombier		lds	dx,dword ptr [bp+8]	; buffer address
194*7dd7cddfSDavid du Colombier		mov	cx,word ptr [bp+12]	; number of bytes
195*7dd7cddfSDavid du Colombier		mov	ah,40h			; write file
196*7dd7cddfSDavid du Colombier		int	21h
197*7dd7cddfSDavid du Colombier		jc	write_err		; if failed, return error code
198*7dd7cddfSDavid du Colombier		cmp	ax,word ptr [bp+12]	; make sure all bytes written
199*7dd7cddfSDavid du Colombier		je	write_ok
200*7dd7cddfSDavid du Colombier		mov	ax,1			; else return 1 for not OK
201*7dd7cddfSDavid du Colombier		jmp	short write_err
202*7dd7cddfSDavid du Colombierwrite_ok:	xor	ax,ax			; return zero for OK
203*7dd7cddfSDavid du Colombierwrite_err:	pop	ds			; restore registers and exit
204*7dd7cddfSDavid du Colombier		pop	es
205*7dd7cddfSDavid du Colombier		pop	dx
206*7dd7cddfSDavid du Colombier		pop	cx
207*7dd7cddfSDavid du Colombier		pop	bx
208*7dd7cddfSDavid du Colombier		pop	di
209*7dd7cddfSDavid du Colombier		pop	si
210*7dd7cddfSDavid du Colombier		pop 	bp
211*7dd7cddfSDavid du Colombier		ret
212*7dd7cddfSDavid du Colombier_jdos_write	endp
213*7dd7cddfSDavid du Colombier
214*7dd7cddfSDavid du Colombier
215*7dd7cddfSDavid du Colombier;
216*7dd7cddfSDavid du Colombier; void far jxms_getdriver (XMSDRIVER far *)
217*7dd7cddfSDavid du Colombier;
218*7dd7cddfSDavid du Colombier; Get the address of the XMS driver, or NULL if not available
219*7dd7cddfSDavid du Colombier;
220*7dd7cddfSDavid du Colombier_jxms_getdriver	proc	far
221*7dd7cddfSDavid du Colombier		push	bp			; linkage
222*7dd7cddfSDavid du Colombier		mov 	bp,sp
223*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
224*7dd7cddfSDavid du Colombier		push	di
225*7dd7cddfSDavid du Colombier		push	bx
226*7dd7cddfSDavid du Colombier		push	cx
227*7dd7cddfSDavid du Colombier		push	dx
228*7dd7cddfSDavid du Colombier		push	es
229*7dd7cddfSDavid du Colombier		push	ds
230*7dd7cddfSDavid du Colombier		mov 	ax,4300h		; call multiplex interrupt with
231*7dd7cddfSDavid du Colombier		int	2fh			; a magic cookie, hex 4300
232*7dd7cddfSDavid du Colombier		cmp 	al,80h			; AL should contain hex 80
233*7dd7cddfSDavid du Colombier		je	xmsavail
234*7dd7cddfSDavid du Colombier		xor 	dx,dx			; no XMS driver available
235*7dd7cddfSDavid du Colombier		xor 	ax,ax			; return a nil pointer
236*7dd7cddfSDavid du Colombier		jmp	short xmsavail_done
237*7dd7cddfSDavid du Colombierxmsavail:	mov 	ax,4310h		; fetch driver address with
238*7dd7cddfSDavid du Colombier		int	2fh			; another magic cookie
239*7dd7cddfSDavid du Colombier		mov 	dx,es			; copy address to dx:ax
240*7dd7cddfSDavid du Colombier		mov 	ax,bx
241*7dd7cddfSDavid du Colombierxmsavail_done:	les 	bx,dword ptr [bp+6]	; get pointer to return value
242*7dd7cddfSDavid du Colombier		mov	word ptr es:[bx],ax
243*7dd7cddfSDavid du Colombier		mov	word ptr es:[bx+2],dx
244*7dd7cddfSDavid du Colombier		pop	ds			; restore registers and exit
245*7dd7cddfSDavid du Colombier		pop	es
246*7dd7cddfSDavid du Colombier		pop	dx
247*7dd7cddfSDavid du Colombier		pop	cx
248*7dd7cddfSDavid du Colombier		pop	bx
249*7dd7cddfSDavid du Colombier		pop	di
250*7dd7cddfSDavid du Colombier		pop	si
251*7dd7cddfSDavid du Colombier		pop	bp
252*7dd7cddfSDavid du Colombier		ret
253*7dd7cddfSDavid du Colombier_jxms_getdriver	endp
254*7dd7cddfSDavid du Colombier
255*7dd7cddfSDavid du Colombier
256*7dd7cddfSDavid du Colombier;
257*7dd7cddfSDavid du Colombier; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
258*7dd7cddfSDavid du Colombier;
259*7dd7cddfSDavid du Colombier; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
260*7dd7cddfSDavid du Colombier; These are loaded, the XMS call is performed, and the new values of the
261*7dd7cddfSDavid du Colombier; AX,DX,BX registers are written back to the context structure.
262*7dd7cddfSDavid du Colombier;
263*7dd7cddfSDavid du Colombier_jxms_calldriver 	proc	far
264*7dd7cddfSDavid du Colombier		push	bp			; linkage
265*7dd7cddfSDavid du Colombier		mov 	bp,sp
266*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
267*7dd7cddfSDavid du Colombier		push	di
268*7dd7cddfSDavid du Colombier		push	bx
269*7dd7cddfSDavid du Colombier		push	cx
270*7dd7cddfSDavid du Colombier		push	dx
271*7dd7cddfSDavid du Colombier		push	es
272*7dd7cddfSDavid du Colombier		push	ds
273*7dd7cddfSDavid du Colombier		les 	bx,dword ptr [bp+10]	; get XMScontext pointer
274*7dd7cddfSDavid du Colombier		mov 	ax,word ptr es:[bx]	; load registers
275*7dd7cddfSDavid du Colombier		mov 	dx,word ptr es:[bx+2]
276*7dd7cddfSDavid du Colombier		mov 	si,word ptr es:[bx+6]
277*7dd7cddfSDavid du Colombier		mov 	ds,word ptr es:[bx+8]
278*7dd7cddfSDavid du Colombier		mov 	bx,word ptr es:[bx+4]
279*7dd7cddfSDavid du Colombier		call	dword ptr [bp+6]	; call the driver
280*7dd7cddfSDavid du Colombier		mov	cx,bx			; save returned BX for a sec
281*7dd7cddfSDavid du Colombier		les 	bx,dword ptr [bp+10]	; get XMScontext pointer
282*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx],ax	; put back ax,dx,bx
283*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx+2],dx
284*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx+4],cx
285*7dd7cddfSDavid du Colombier		pop	ds			; restore registers and exit
286*7dd7cddfSDavid du Colombier		pop	es
287*7dd7cddfSDavid du Colombier		pop	dx
288*7dd7cddfSDavid du Colombier		pop	cx
289*7dd7cddfSDavid du Colombier		pop	bx
290*7dd7cddfSDavid du Colombier		pop	di
291*7dd7cddfSDavid du Colombier		pop	si
292*7dd7cddfSDavid du Colombier		pop 	bp
293*7dd7cddfSDavid du Colombier		ret
294*7dd7cddfSDavid du Colombier_jxms_calldriver 	endp
295*7dd7cddfSDavid du Colombier
296*7dd7cddfSDavid du Colombier
297*7dd7cddfSDavid du Colombier;
298*7dd7cddfSDavid du Colombier; short far jems_available (void)
299*7dd7cddfSDavid du Colombier;
300*7dd7cddfSDavid du Colombier; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
301*7dd7cddfSDavid du Colombier;
302*7dd7cddfSDavid du Colombier_jems_available	proc	far
303*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
304*7dd7cddfSDavid du Colombier		push	di
305*7dd7cddfSDavid du Colombier		push	bx
306*7dd7cddfSDavid du Colombier		push	cx
307*7dd7cddfSDavid du Colombier		push	dx
308*7dd7cddfSDavid du Colombier		push	es
309*7dd7cddfSDavid du Colombier		push	ds
310*7dd7cddfSDavid du Colombier		mov	ax,3567h		; get interrupt vector 67h
311*7dd7cddfSDavid du Colombier		int	21h
312*7dd7cddfSDavid du Colombier		push	cs
313*7dd7cddfSDavid du Colombier		pop	ds
314*7dd7cddfSDavid du Colombier		mov	di,000ah		; check offs 10 in returned seg
315*7dd7cddfSDavid du Colombier		lea	si,ASCII_device_name	; against literal string
316*7dd7cddfSDavid du Colombier		mov	cx,8
317*7dd7cddfSDavid du Colombier		cld
318*7dd7cddfSDavid du Colombier		repe cmpsb
319*7dd7cddfSDavid du Colombier		jne	no_ems
320*7dd7cddfSDavid du Colombier		mov	ax,1			; match, it's there
321*7dd7cddfSDavid du Colombier		jmp	short avail_done
322*7dd7cddfSDavid du Colombierno_ems:		xor	ax,ax			; it's not there
323*7dd7cddfSDavid du Colombieravail_done:	pop	ds			; restore registers and exit
324*7dd7cddfSDavid du Colombier		pop	es
325*7dd7cddfSDavid du Colombier		pop	dx
326*7dd7cddfSDavid du Colombier		pop	cx
327*7dd7cddfSDavid du Colombier		pop	bx
328*7dd7cddfSDavid du Colombier		pop	di
329*7dd7cddfSDavid du Colombier		pop	si
330*7dd7cddfSDavid du Colombier		ret
331*7dd7cddfSDavid du Colombier
332*7dd7cddfSDavid du ColombierASCII_device_name	db	"EMMXXXX0"
333*7dd7cddfSDavid du Colombier
334*7dd7cddfSDavid du Colombier_jems_available	endp
335*7dd7cddfSDavid du Colombier
336*7dd7cddfSDavid du Colombier
337*7dd7cddfSDavid du Colombier;
338*7dd7cddfSDavid du Colombier; void far jems_calldriver (EMScontext far *)
339*7dd7cddfSDavid du Colombier;
340*7dd7cddfSDavid du Colombier; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
341*7dd7cddfSDavid du Colombier; These are loaded, the EMS trap is performed, and the new values of the
342*7dd7cddfSDavid du Colombier; AX,DX,BX registers are written back to the context structure.
343*7dd7cddfSDavid du Colombier;
344*7dd7cddfSDavid du Colombier_jems_calldriver	proc far
345*7dd7cddfSDavid du Colombier		push	bp			; linkage
346*7dd7cddfSDavid du Colombier		mov 	bp,sp
347*7dd7cddfSDavid du Colombier		push	si			; save all registers for safety
348*7dd7cddfSDavid du Colombier		push	di
349*7dd7cddfSDavid du Colombier		push	bx
350*7dd7cddfSDavid du Colombier		push	cx
351*7dd7cddfSDavid du Colombier		push	dx
352*7dd7cddfSDavid du Colombier		push	es
353*7dd7cddfSDavid du Colombier		push	ds
354*7dd7cddfSDavid du Colombier		les 	bx,dword ptr [bp+6]	; get EMScontext pointer
355*7dd7cddfSDavid du Colombier		mov 	ax,word ptr es:[bx]	; load registers
356*7dd7cddfSDavid du Colombier		mov 	dx,word ptr es:[bx+2]
357*7dd7cddfSDavid du Colombier		mov 	si,word ptr es:[bx+6]
358*7dd7cddfSDavid du Colombier		mov 	ds,word ptr es:[bx+8]
359*7dd7cddfSDavid du Colombier		mov 	bx,word ptr es:[bx+4]
360*7dd7cddfSDavid du Colombier		int	67h			; call the EMS driver
361*7dd7cddfSDavid du Colombier		mov	cx,bx			; save returned BX for a sec
362*7dd7cddfSDavid du Colombier		les 	bx,dword ptr [bp+6]	; get EMScontext pointer
363*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx],ax	; put back ax,dx,bx
364*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx+2],dx
365*7dd7cddfSDavid du Colombier		mov 	word ptr es:[bx+4],cx
366*7dd7cddfSDavid du Colombier		pop	ds			; restore registers and exit
367*7dd7cddfSDavid du Colombier		pop	es
368*7dd7cddfSDavid du Colombier		pop	dx
369*7dd7cddfSDavid du Colombier		pop	cx
370*7dd7cddfSDavid du Colombier		pop	bx
371*7dd7cddfSDavid du Colombier		pop	di
372*7dd7cddfSDavid du Colombier		pop	si
373*7dd7cddfSDavid du Colombier		pop 	bp
374*7dd7cddfSDavid du Colombier		ret
375*7dd7cddfSDavid du Colombier_jems_calldriver	endp
376*7dd7cddfSDavid du Colombier
377*7dd7cddfSDavid du ColombierJMEMDOSA_TXT	ends
378*7dd7cddfSDavid du Colombier
379*7dd7cddfSDavid du Colombier		end
380