Home | History | Annotate | Download | only in jpeg
      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
    380