PageRenderTime 17ms CodeModel.GetById 13ms app.highlight 2ms RepoModel.GetById 0ms app.codeStats 1ms

/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
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.