123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- ;
- ; jmemdosa.asm
- ;
- ; Copyright (C) 1992, Thomas G. Lane.
- ; This file is part of the Independent JPEG Group's software.
- ; For conditions of distribution and use, see the accompanying README file.
- ;
- ; This file contains low-level interface routines to support the MS-DOS
- ; backing store manager (jmemdos.c). Routines are provided to access disk
- ; files through direct DOS calls, and to access XMS and EMS drivers.
- ;
- ; This file should assemble with Microsoft's MASM or any compatible
- ; assembler (including Borland's Turbo Assembler). If you haven't got
- ; a compatible assembler, better fall back to jmemansi.c or jmemname.c.
- ;
- ; To minimize dependence on the C compiler's register usage conventions,
- ; we save and restore all 8086 registers, even though most compilers only
- ; require SI,DI,DS to be preserved. Also, we use only 16-bit-wide return
- ; values, which everybody returns in AX.
- ;
- ; Based on code contributed by Ge' Weijers.
- ;
- JMEMDOSA_TXT segment byte public 'CODE'
- assume cs:JMEMDOSA_TXT
- public _jdos_open
- public _jdos_close
- public _jdos_seek
- public _jdos_read
- public _jdos_write
- public _jxms_getdriver
- public _jxms_calldriver
- public _jems_available
- public _jems_calldriver
- ;
- ; short far jdos_open (short far * handle, char far * filename)
- ;
- ; Create and open a temporary file
- ;
- _jdos_open proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov cx,0 ; normal file attributes
- lds dx,dword ptr [bp+10] ; get filename pointer
- mov ah,3ch ; create file
- int 21h
- jc open_err ; if failed, return error code
- lds bx,dword ptr [bp+6] ; get handle pointer
- mov word ptr [bx],ax ; save the handle
- xor ax,ax ; return zero for OK
- open_err: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jdos_open endp
- ;
- ; short far jdos_close (short handle)
- ;
- ; Close the file handle
- ;
- _jdos_close proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx,word ptr [bp+6] ; file handle
- mov ah,3eh ; close file
- int 21h
- jc close_err ; if failed, return error code
- xor ax,ax ; return zero for OK
- close_err: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jdos_close endp
- ;
- ; short far jdos_seek (short handle, long offset)
- ;
- ; Set file position
- ;
- _jdos_seek proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx,word ptr [bp+6] ; file handle
- mov dx,word ptr [bp+8] ; LS offset
- mov cx,word ptr [bp+10] ; MS offset
- mov ax,4200h ; absolute seek
- int 21h
- jc seek_err ; if failed, return error code
- xor ax,ax ; return zero for OK
- seek_err: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jdos_seek endp
- ;
- ; short far jdos_read (short handle, void far * buffer, unsigned short count)
- ;
- ; Read from file
- ;
- _jdos_read proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx,word ptr [bp+6] ; file handle
- lds dx,dword ptr [bp+8] ; buffer address
- mov cx,word ptr [bp+12] ; number of bytes
- mov ah,3fh ; read file
- int 21h
- jc read_err ; if failed, return error code
- cmp ax,word ptr [bp+12] ; make sure all bytes were read
- je read_ok
- mov ax,1 ; else return 1 for not OK
- jmp short read_err
- read_ok: xor ax,ax ; return zero for OK
- read_err: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jdos_read endp
- ;
- ; short far jdos_write (short handle, void far * buffer, unsigned short count)
- ;
- ; Write to file
- ;
- _jdos_write proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx,word ptr [bp+6] ; file handle
- lds dx,dword ptr [bp+8] ; buffer address
- mov cx,word ptr [bp+12] ; number of bytes
- mov ah,40h ; write file
- int 21h
- jc write_err ; if failed, return error code
- cmp ax,word ptr [bp+12] ; make sure all bytes written
- je write_ok
- mov ax,1 ; else return 1 for not OK
- jmp short write_err
- write_ok: xor ax,ax ; return zero for OK
- write_err: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jdos_write endp
- ;
- ; void far jxms_getdriver (XMSDRIVER far *)
- ;
- ; Get the address of the XMS driver, or NULL if not available
- ;
- _jxms_getdriver proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov ax,4300h ; call multiplex interrupt with
- int 2fh ; a magic cookie, hex 4300
- cmp al,80h ; AL should contain hex 80
- je xmsavail
- xor dx,dx ; no XMS driver available
- xor ax,ax ; return a nil pointer
- jmp short xmsavail_done
- xmsavail: mov ax,4310h ; fetch driver address with
- int 2fh ; another magic cookie
- mov dx,es ; copy address to dx:ax
- mov ax,bx
- xmsavail_done: les bx,dword ptr [bp+6] ; get pointer to return value
- mov word ptr es:[bx],ax
- mov word ptr es:[bx+2],dx
- pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jxms_getdriver endp
- ;
- ; void far jxms_calldriver (XMSDRIVER, XMScontext far *)
- ;
- ; The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.
- ; These are loaded, the XMS call is performed, and the new values of the
- ; AX,DX,BX registers are written back to the context structure.
- ;
- _jxms_calldriver proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- les bx,dword ptr [bp+10] ; get XMScontext pointer
- mov ax,word ptr es:[bx] ; load registers
- mov dx,word ptr es:[bx+2]
- mov si,word ptr es:[bx+6]
- mov ds,word ptr es:[bx+8]
- mov bx,word ptr es:[bx+4]
- call dword ptr [bp+6] ; call the driver
- mov cx,bx ; save returned BX for a sec
- les bx,dword ptr [bp+10] ; get XMScontext pointer
- mov word ptr es:[bx],ax ; put back ax,dx,bx
- mov word ptr es:[bx+2],dx
- mov word ptr es:[bx+4],cx
- pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jxms_calldriver endp
- ;
- ; short far jems_available (void)
- ;
- ; Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)
- ;
- _jems_available proc far
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov ax,3567h ; get interrupt vector 67h
- int 21h
- push cs
- pop ds
- mov di,000ah ; check offs 10 in returned seg
- lea si,ASCII_device_name ; against literal string
- mov cx,8
- cld
- repe cmpsb
- jne no_ems
- mov ax,1 ; match, it's there
- jmp short avail_done
- no_ems: xor ax,ax ; it's not there
- avail_done: pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- ret
- ASCII_device_name db "EMMXXXX0"
- _jems_available endp
- ;
- ; void far jems_calldriver (EMScontext far *)
- ;
- ; The EMScontext structure contains values for the AX,DX,BX,SI,DS registers.
- ; These are loaded, the EMS trap is performed, and the new values of the
- ; AX,DX,BX registers are written back to the context structure.
- ;
- _jems_calldriver proc far
- push bp ; linkage
- mov bp,sp
- push si ; save all registers for safety
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- les bx,dword ptr [bp+6] ; get EMScontext pointer
- mov ax,word ptr es:[bx] ; load registers
- mov dx,word ptr es:[bx+2]
- mov si,word ptr es:[bx+6]
- mov ds,word ptr es:[bx+8]
- mov bx,word ptr es:[bx+4]
- int 67h ; call the EMS driver
- mov cx,bx ; save returned BX for a sec
- les bx,dword ptr [bp+6] ; get EMScontext pointer
- mov word ptr es:[bx],ax ; put back ax,dx,bx
- mov word ptr es:[bx+2],dx
- mov word ptr es:[bx+4],cx
- pop ds ; restore registers and exit
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- pop bp
- ret
- _jems_calldriver endp
- JMEMDOSA_TXT ends
- end
|