3
{$G+} {enable 286/287 instructions }
5
{ Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane.
6
Based on code contributed by Ge' Weijers. }
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. }
18
XMSDRIVER = pointer; {far} { actually a pointer to code }
20
XMScontext = packed record { registers for calling XMS driver }
22
ds_si : pointer; {far}
25
EMScontext = packed record { registers for calling EMS driver }
27
ds_si : pointer; {far}
29
{ offset is a reserved word in BASM }
31
function jdos_open (var handle : short {far}; const filename {: PChar}) : short;
33
function jdos_close (handle : short) : short;
35
function jdos_seek (handle : short; offs : long) : short;
37
function jdos_read (handle : short; buffer : pointer; {FAR}
38
count : ushort) : short;
39
function jdos_write (handle : short; buffer : pointer; {FAR}
40
count : ushort) : short;
42
procedure jxms_getdriver (var driver : XMSDRIVER);
44
procedure jxms_calldriver (driver : XMSDRIVER;
45
var ctx : XMScontext);
46
function jems_available : short;
48
procedure jems_calldriver (var ctx : EMScontext);
54
function jdos_open (var handle : short {far};
55
const filename {: PChar}) : short; assembler;
56
{ Create and open a temporary file }
60
push si { save all registers for safety }
67
mov cx,0 { normal file attributes }
68
lds dx, filename { get filename pointer }
69
mov ah,3ch { create file }
71
jc open_err { if failed, return error code }
72
lds bx, handle { get handle pointer }
73
mov word ptr [bx],ax { save the handle }
74
xor ax,ax { return zero for OK }
76
pop ds { restore registers and exit }
86
function jdos_close (handle : short) : short; assembler;
87
{ Close the file handle }
91
push si { save all registers for safety }
98
mov bx, handle { file handle }
99
mov ah,3eh { close file }
101
jc close_err { if failed, return error code }
102
xor ax,ax { return zero for OK }
104
pop ds { restore registers and exit }
115
function jdos_seek (handle : short; offs : long) : short; assembler;
116
{ Set file position }
120
push si { save all registers for safety }
127
mov bx, handle { file handle }
128
mov dx, offs.word { LS offset }
129
mov cx, offs.word[2] { MS offset }
130
mov ax,4200h { absolute seek }
132
jc seek_err { if failed, return error code }
133
xor ax,ax { return zero for OK }
135
pop ds { restore registers and exit }
145
function jdos_read (handle : short; buffer : pointer; {FAR}
146
count : ushort) : short; assembler;
151
push si { save all registers for safety }
158
mov bx, handle { file handle }
159
lds dx, buffer { buffer address }
160
mov cx, count { number of bytes }
161
mov ah,3fh { read file }
163
jc read_err { if failed, return error code }
164
cmp ax, count { make sure all bytes were read }
166
mov ax,1 { else return 1 for not OK }
169
xor ax,ax { return zero for OK }
171
pop ds { restore registers and exit }
182
function jdos_write (handle : short; buffer : pointer; {FAR}
183
count : ushort) : short; assembler;
188
push si { save all registers for safety }
195
mov bx, handle { file handle }
196
lds dx, buffer { buffer address }
197
mov cx, count { number of bytes }
198
mov ah,40h { write file }
200
jc write_err { if failed, return error code }
201
cmp ax, count { make sure all bytes written }
203
mov ax,1 { else return 1 for not OK }
206
xor ax,ax { return zero for OK }
208
pop ds { restore registers and exit }
219
procedure jxms_getdriver (var driver : XMSDRIVER); assembler;
220
{ Get the address of the XMS driver, or NIL if not available }
222
xmsavail, xmsavail_done;
224
push si { save all registers for safety }
231
mov ax,4300h { call multiplex interrupt with }
232
int 2fh { a magic cookie, hex 4300 }
233
cmp al,80h { AL should contain hex 80 }
235
xor dx,dx { no XMS driver available }
236
xor ax,ax { return a nil pointer }
239
mov ax,4310h { fetch driver address with }
240
int 2fh { another magic cookie }
241
mov dx,es { copy address to dx:ax }
244
les bx,dword ptr [bp+6] { get pointer to return value }
245
mov word ptr es:[bx],ax
246
mov word ptr es:[bx+2],dx
247
pop ds { restore registers and exit }
254
end; { jxms_getdriver }
256
procedure jxms_calldriver (driver : XMSDRIVER;
257
var ctx : XMScontext); assembler;
258
{ The XMScontext structure contains values for the AX,DX,BX,SI,DS registers.}
259
{ These are loaded, the XMS call is performed, and the new values of the }
260
{ AX,DX,BX registers are written back to the context structure. }
262
push si { save all registers for safety }
269
les bx, ctx { get XMScontext pointer }
270
mov ax,word ptr es:[bx] { load registers }
271
mov dx,word ptr es:[bx+2]
272
mov si,word ptr es:[bx+6]
273
mov ds,word ptr es:[bx+8]
274
mov bx,word ptr es:[bx+4]
275
call dword ptr driver { call the driver }
276
mov cx,bx { save returned BX for a sec }
277
les bx, ctx { get XMScontext pointer }
278
mov word ptr es:[bx],ax { put back ax,dx,bx }
279
mov word ptr es:[bx+2],dx
280
mov word ptr es:[bx+4],cx
281
pop ds { restore registers and exit }
288
end; { jxms_calldriver }
292
function jems_available : short; assembler;
293
{ Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)}
297
ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0';
299
push si { save all registers for safety }
306
mov ax,3567h { get interrupt vector 67h }
310
mov di,000ah { check offs 10 in returned seg }
311
lea si, ASCII_device_name { against literal string }
316
mov ax,1 { match, it's there }
318
no_ems: xor ax,ax { it's not there }
320
pop ds { restore registers and exit }
327
end; { jems_available }
330
procedure jems_calldriver (var ctx : EMScontext); assembler;
331
{ The EMScontext structure contains values for the AX,DX,BX,SI,DS registers. }
332
{ These are loaded, the EMS trap is performed, and the new values of the }
333
{ AX,DX,BX registers are written back to the context structure. }
335
push si { save all registers for safety }
343
les bx, ctx { get EMScontext pointer }
344
mov ax, es:[bx].EMScontext.&ax { load registers }
345
mov dx, es:[bx].EMScontext.&dx
346
mov si, es:[bx].EMScontext.&ds_si.word
347
mov ds, es:[bx].EMScontext.&ds_si.word[2]
348
mov bx, es:[bx].EMScontext.&bx
349
int 67h { call the EMS driver }
350
mov cx,bx { save returned BX for a sec }
351
les bx, ctx { get EMScontext pointer }
352
mov es:[bx].EMScontext.&ax, ax { put back ax,dx,bx }
353
mov es:[bx].EMScontext.&dx, dx
354
mov es:[bx].EMScontext.&bx, cx
356
pop ds { restore registers and exit }
363
end; { jems_calldriver }