/packages/pasjpeg/src/jmemdosa.pas
Pascal | 365 lines | 306 code | 39 blank | 20 comment | 0 complexity | 71508fabaccd2d0c6b293db56b23a6d3 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, LGPL-3.0
1Unit jmemdosa; 2 3{$G+} {enable 286/287 instructions } 4 5{ Original: jmemdosa.asm ; Copyright (C) 1992, Thomas G. Lane. 6 Based on code contributed by Ge' Weijers. } 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 12interface 13 14uses 15 jmorecfg; 16 17type 18 XMSDRIVER = pointer; {far} { actually a pointer to code } 19type 20 XMScontext = packed record { registers for calling XMS driver } 21 ax, dx, bx : ushort; 22 ds_si : pointer; {far} 23 end; 24type 25 EMScontext = packed record { registers for calling EMS driver } 26 ax, dx, bx : ushort; 27 ds_si : pointer; {far} 28 end; 29{ offset is a reserved word in BASM } 30 31function jdos_open (var handle : short {far}; const filename {: PChar}) : short; 32 33function jdos_close (handle : short) : short; 34 35function jdos_seek (handle : short; offs : long) : short; 36 37function jdos_read (handle : short; buffer : pointer; {FAR} 38 count : ushort) : short; 39function jdos_write (handle : short; buffer : pointer; {FAR} 40 count : ushort) : short; 41 42procedure jxms_getdriver (var driver : XMSDRIVER); 43 44procedure jxms_calldriver (driver : XMSDRIVER; 45 var ctx : XMScontext); 46function jems_available : short; 47 48procedure jems_calldriver (var ctx : EMScontext); 49 50 51implementation 52 53 54function jdos_open (var handle : short {far}; 55 const filename {: PChar}) : short; assembler; 56{ Create and open a temporary file } 57label 58 open_err; 59asm 60 push si { save all registers for safety } 61 push di 62 push bx 63 push cx 64 push dx 65 push es 66 push ds 67 mov cx,0 { normal file attributes } 68 lds dx, filename { get filename pointer } 69 mov ah,3ch { create file } 70 int 21h 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 } 75open_err: 76 pop ds { restore registers and exit } 77 pop es 78 pop dx 79 pop cx 80 pop bx 81 pop di 82 pop si 83end; { jdos_open } 84 85 86function jdos_close (handle : short) : short; assembler; 87{ Close the file handle } 88label 89 close_err; 90asm 91 push si { save all registers for safety } 92 push di 93 push bx 94 push cx 95 push dx 96 push es 97 push ds 98 mov bx, handle { file handle } 99 mov ah,3eh { close file } 100 int 21h 101 jc close_err { if failed, return error code } 102 xor ax,ax { return zero for OK } 103close_err: 104 pop ds { restore registers and exit } 105 pop es 106 pop dx 107 pop cx 108 pop bx 109 pop di 110 pop si 111end; { jdos_close } 112 113 114 115function jdos_seek (handle : short; offs : long) : short; assembler; 116{ Set file position } 117label 118 seek_err; 119asm 120 push si { save all registers for safety } 121 push di 122 push bx 123 push cx 124 push dx 125 push es 126 push ds 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 } 131 int 21h 132 jc seek_err { if failed, return error code } 133 xor ax,ax { return zero for OK } 134seek_err: 135 pop ds { restore registers and exit } 136 pop es 137 pop dx 138 pop cx 139 pop bx 140 pop di 141 pop si 142end; { jdos_seek } 143 144 145function jdos_read (handle : short; buffer : pointer; {FAR} 146 count : ushort) : short; assembler; 147{ Read from file } 148label 149 read_ok, read_err; 150asm 151 push si { save all registers for safety } 152 push di 153 push bx 154 push cx 155 push dx 156 push es 157 push ds 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 } 162 int 21h 163 jc read_err { if failed, return error code } 164 cmp ax, count { make sure all bytes were read } 165 je read_ok 166 mov ax,1 { else return 1 for not OK } 167 jmp read_err 168read_ok: 169 xor ax,ax { return zero for OK } 170read_err: 171 pop ds { restore registers and exit } 172 pop es 173 pop dx 174 pop cx 175 pop bx 176 pop di 177 pop si 178end; { jdos_read } 179 180 181 182function jdos_write (handle : short; buffer : pointer; {FAR} 183 count : ushort) : short; assembler; 184{ Write to file } 185label 186 write_ok, write_err; 187asm 188 push si { save all registers for safety } 189 push di 190 push bx 191 push cx 192 push dx 193 push es 194 push ds 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 } 199 int 21h 200 jc write_err { if failed, return error code } 201 cmp ax, count { make sure all bytes written } 202 je write_ok 203 mov ax,1 { else return 1 for not OK } 204 jmp write_err 205write_ok: 206 xor ax,ax { return zero for OK } 207write_err: 208 pop ds { restore registers and exit } 209 pop es 210 pop dx 211 pop cx 212 pop bx 213 pop di 214 pop si 215end; { jdos_write } 216 217 218 219procedure jxms_getdriver (var driver : XMSDRIVER); assembler; 220{ Get the address of the XMS driver, or NIL if not available } 221label 222 xmsavail, xmsavail_done; 223asm 224 push si { save all registers for safety } 225 push di 226 push bx 227 push cx 228 push dx 229 push es 230 push ds 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 } 234 je xmsavail 235 xor dx,dx { no XMS driver available } 236 xor ax,ax { return a nil pointer } 237 jmp xmsavail_done 238xmsavail: 239 mov ax,4310h { fetch driver address with } 240 int 2fh { another magic cookie } 241 mov dx,es { copy address to dx:ax } 242 mov ax,bx 243xmsavail_done: 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 } 248 pop es 249 pop dx 250 pop cx 251 pop bx 252 pop di 253 pop si 254end; { jxms_getdriver } 255 256procedure 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. } 261asm 262 push si { save all registers for safety } 263 push di 264 push bx 265 push cx 266 push dx 267 push es 268 push ds 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 } 282 pop es 283 pop dx 284 pop cx 285 pop bx 286 pop di 287 pop si 288end; { jxms_calldriver } 289 290 291 292function jems_available : short; assembler; 293{ Have we got an EMS driver? (this comes straight from the EMS 4.0 specs)} 294label 295 no_ems, avail_done; 296const 297 ASCII_device_name : packed array[0..7] of char = 'EMMXXXX0'; 298asm 299 push si { save all registers for safety } 300 push di 301 push bx 302 push cx 303 push dx 304 push es 305 push ds 306 mov ax,3567h { get interrupt vector 67h } 307 int 21h 308 push cs 309 pop ds 310 mov di,000ah { check offs 10 in returned seg } 311 lea si, ASCII_device_name { against literal string } 312 mov cx,8 313 cld 314 repe cmpsb 315 jne no_ems 316 mov ax,1 { match, it's there } 317 jmp avail_done 318no_ems: xor ax,ax { it's not there } 319avail_done: 320 pop ds { restore registers and exit } 321 pop es 322 pop dx 323 pop cx 324 pop bx 325 pop di 326 pop si 327end; { jems_available } 328 329 330procedure 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. } 334asm 335 push si { save all registers for safety } 336 push di 337 push bx 338 push cx 339 push dx 340 push es 341 push ds 342 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 355 356 pop ds { restore registers and exit } 357 pop es 358 pop dx 359 pop cx 360 pop bx 361 pop di 362 pop si 363end; { jems_calldriver } 364 365end.