You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
8.1 KiB
379 lines
8.1 KiB
; |
|
; 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
|
|
|