/packages/pasjpeg/src/jmemdosa.pas
https://github.com/slibre/freepascal · Pascal · 365 lines · 306 code · 39 blank · 20 comment · 0 complexity · 71508fabaccd2d0c6b293db56b23a6d3 MD5 · raw file
- Unit jmemdosa;
- {$G+} {enable 286/287 instructions }
- { Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane.
- Based on code contributed by Ge' Weijers. }
- { 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. }
- interface
- uses
- jmorecfg;
- type
- XMSDRIVER = pointer; {far} { actually a pointer to code }
- type
- XMScontext = packed record { registers for calling XMS driver }
- ax, dx, bx : ushort;
- ds_si : pointer; {far}
- end;
- type
- EMScontext = packed record { registers for calling EMS driver }
- ax, dx, bx : ushort;
- ds_si : pointer; {far}
- end;
- { offset is a reserved word in BASM }
- function jdos_open (var handle : short {far}; const filename {: PChar}) : short;
- function jdos_close (handle : short) : short;
- function jdos_seek (handle : short; offs : long) : short;
- function jdos_read (handle : short; buffer : pointer; {FAR}
- count : ushort) : short;
- function jdos_write (handle : short; buffer : pointer; {FAR}
- count : ushort) : short;
- procedure jxms_getdriver (var driver : XMSDRIVER);
- procedure jxms_calldriver (driver : XMSDRIVER;
- var ctx : XMScontext);
- function jems_available : short;
- procedure jems_calldriver (var ctx : EMScontext);
- implementation
- function jdos_open (var handle : short {far};
- const filename {: PChar}) : short; assembler;
- { Create and open a temporary file }
- label
- open_err;
- asm
- 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, filename { get filename pointer }
- mov ah,3ch { create file }
- int 21h
- jc open_err { if failed, return error code }
- lds bx, handle { 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
- end; { jdos_open }
- function jdos_close (handle : short) : short; assembler;
- { Close the file handle }
- label
- close_err;
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx, handle { 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
- end; { jdos_close }
- function jdos_seek (handle : short; offs : long) : short; assembler;
- { Set file position }
- label
- seek_err;
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx, handle { file handle }
- mov dx, offs.word { LS offset }
- mov cx, offs.word[2] { 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
- end; { jdos_seek }
- function jdos_read (handle : short; buffer : pointer; {FAR}
- count : ushort) : short; assembler;
- { Read from file }
- label
- read_ok, read_err;
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx, handle { file handle }
- lds dx, buffer { buffer address }
- mov cx, count { number of bytes }
- mov ah,3fh { read file }
- int 21h
- jc read_err { if failed, return error code }
- cmp ax, count { make sure all bytes were read }
- je read_ok
- mov ax,1 { else return 1 for not OK }
- jmp 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
- end; { jdos_read }
- function jdos_write (handle : short; buffer : pointer; {FAR}
- count : ushort) : short; assembler;
- { Write to file }
- label
- write_ok, write_err;
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- mov bx, handle { file handle }
- lds dx, buffer { buffer address }
- mov cx, count { number of bytes }
- mov ah,40h { write file }
- int 21h
- jc write_err { if failed, return error code }
- cmp ax, count { make sure all bytes written }
- je write_ok
- mov ax,1 { else return 1 for not OK }
- jmp 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
- end; { jdos_write }
- procedure jxms_getdriver (var driver : XMSDRIVER); assembler;
- { Get the address of the XMS driver, or NIL if not available }
- label
- xmsavail, xmsavail_done;
- asm
- 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 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
- end; { jxms_getdriver }
- procedure jxms_calldriver (driver : XMSDRIVER;
- var ctx : XMScontext); assembler;
- { 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. }
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- les bx, ctx { 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 driver { call the driver }
- mov cx,bx { save returned BX for a sec }
- les bx, ctx { 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
- end; { jxms_calldriver }
- function jems_available : short; assembler;
- { Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)}
- label
- no_ems, avail_done;
- const
- ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0';
- asm
- 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 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
- end; { jems_available }
- procedure jems_calldriver (var ctx : EMScontext); assembler;
- { 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. }
- asm
- push si { save all registers for safety }
- push di
- push bx
- push cx
- push dx
- push es
- push ds
- les bx, ctx { get EMScontext pointer }
- mov ax, es:[bx].EMScontext.&ax { load registers }
- mov dx, es:[bx].EMScontext.&dx
- mov si, es:[bx].EMScontext.&ds_si.word
- mov ds, es:[bx].EMScontext.&ds_si.word[2]
- mov bx, es:[bx].EMScontext.&bx
- int 67h { call the EMS driver }
- mov cx,bx { save returned BX for a sec }
- les bx, ctx { get EMScontext pointer }
- mov es:[bx].EMScontext.&ax, ax { put back ax,dx,bx }
- mov es:[bx].EMScontext.&dx, dx
- mov es:[bx].EMScontext.&bx, cx
- pop ds { restore registers and exit }
- pop es
- pop dx
- pop cx
- pop bx
- pop di
- pop si
- end; { jems_calldriver }
- end.