home *** CD-ROM | disk | FTP | other *** search
/ Mega Top 1 / os2_top1.zip / os2_top1 / APPS / PROG / PASCAL / SPEED2 / SRC / LIB / CACHE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-28  |  18.0 KB  |  716 lines

  1. UNIT Cache;
  2.  
  3. {**************************************************************************
  4.  *                   Sourcefile for Speed-386                             *
  5.  *        (C) 1993,94 R.Nürnberger Franz-Mehring-Str.2 09112 Chemnitz     *
  6.  *                                                                        *
  7.  *  Cache routines for fast input/output to files via memory buffer       *
  8.  *                                                                        *
  9.  *                                                                        *
  10.  **************************************************************************}
  11.  
  12. INTERFACE
  13.  
  14. USES dos;
  15.  
  16. CONST
  17.      MaxCacheFiles=10;  {Maximal file handles to cache}
  18.  
  19.      {Cache error codes}
  20.      cerrorok=0;
  21.      cerrornotinfile=1;
  22.      cerrortoomanyfiles=2;
  23.      cerrorclosed=3;
  24.      cerrornomemory=4;
  25.      cerrorcacheamount=5;
  26.      cerrorother=99;
  27.  
  28. TYPE
  29.      CacheFile=WORD;
  30.  
  31. CONST
  32.      corewrite =1;
  33.      coreset   =2;
  34.      coappend  =3;
  35.  
  36. VAR CacheIOResult:LONGWORD;
  37.  
  38. FUNCTION CacheFilePos(nr:CacheFile):LONGWORD;
  39. FUNCTION CacheEOF(nr:CacheFile):BOOLEAN;
  40. PROCEDURE CacheSeek(nr:CacheFile;Pos:LONGWORD);
  41. PROCEDURE CacheRewrite(var nr:CacheFile;fname:STRING; cache:Word);
  42. PROCEDURE CacheReset(var nr:CacheFile;fname:STRING; cache:word);
  43. PROCEDURE CacheAppend(var nr:CacheFile;fname:STRING; cache:word);
  44. PROCEDURE CacheErase(fname:STRING);
  45. PROCEDURE CacheClose(var nr:CacheFile);
  46. PROCEDURE CacheClose1(var nr:CacheFile);
  47. PROCEDURE CacheRead(nr:CacheFile; var value:BYTE);
  48. PROCEDURE CachereadExt(nr:CacheFile; var value; l:LongWord);
  49. PROCEDURE CacheWrite(nr:CacheFile;value:BYTE);
  50. PROCEDURE CacheWriteExt(nr:CacheFile; var value; l:LongWord);
  51. PROCEDURE CacheWriteString(nr:CacheFile; var value:STRING);
  52. PROCEDURE cacheexit;
  53. FUNCTION CacheOpen(fname:STRING;task:BYTE;cacheamount:LongWord):BYTE;
  54. PROCEDURE CacheGetFTime(nr:CacheFile; var year,month,day,hour,min,twosec:WORD);
  55. FUNCTION CacheFileSize(nr:CacheFile):LONGWORD;
  56. PROCEDURE CacheInit;
  57.  
  58. VAR
  59.    FileData:ARRAY[1..MaxCacheFiles] OF RECORD
  60.                                       block,lblock:LONGWORD;
  61.                                       offset,loffset:LONGWORD;
  62.                                       bitpos:BYTE;
  63.                                       changed:BOOLEAN;
  64.                                       p:^ Word;
  65.                                       maxcachemem:LONGWORD;
  66.                                       f:FILE;
  67.                                       Fill:WORD; {to fill up to 128 Byte}
  68.                                     END;
  69.  
  70. IMPLEMENTATION
  71.  
  72. PROCEDURE cacheinit;
  73. var i:CacheFile;
  74. BEGIN
  75.     FOR i:=1 to MaxCachefiles DO filedata[i].p:=NIL;
  76.     CacheIOResult:=cerrorok;
  77. END;
  78.  
  79. PROCEDURE CacheGetFTime(nr:CacheFile; var year,month,day,hour,min,twosec:WORD);
  80. BEGIN
  81.      GetFTime(filedata[nr].f,year,month,day,hour,min,twosec);
  82.      IF doserror=0 THEN CacheIOResult:=cerrorok
  83.      ELSE CacheIOResult:=cerrorclosed;
  84. END;
  85.  
  86. PROCEDURE expand(nr:CacheFile);
  87. BEGIN
  88.      {inc(filedata[nr].loffset);
  89.      IF filedata[nr].loffset=filedata[nr].maxcachemem THEN
  90.      BEGIN
  91.           inc(filedata[nr].lblock);
  92.           filedata[nr].loffset:=0;
  93.      END;}
  94.      ASM
  95.         MOV ESI,OFFSET(_FILEDATA)
  96.         MOVZXW EAX,$NR
  97.         DEC EAX
  98.         SHL EAX,7
  99.         ADD ESI,EAX              ;This does not change during the run
  100.  
  101.         INCD [ESI+12]            ;Filedata[nr].loffset
  102.  
  103.         MOV EAX,[ESI+12]         ;Filedata[nr].lOffset
  104.         CMP EAX,[ESI+22]         ;Filedata[nr].Maxcachemem
  105.         JNE _!L8
  106.  
  107.         INCD [ESI+4]             ;Filedata[nr].lblock
  108.         MOVD [ESI+12],0          ;Filedata[nr].loffset
  109. _!L8:
  110.      END; {asm}
  111. END;
  112.  
  113. FUNCTION CacheFilePos(nr:CacheFile):LONGWORD;
  114. BEGIN
  115.      {CacheFilePos:=filedata[nr].block*filedata[nr].maxcachemem+filedata[nr].offset;}
  116.      ASM
  117.          MOV ESI,OFFSET(_FILEDATA)
  118.          MOVZXW EAX,$NR
  119.          DEC EAX
  120.          SHL EAX,7
  121.          ADD ESI,EAX
  122.  
  123.          MOV EAX,[ESI+0]   ;Filedata[nr].block
  124.          MULD [ESI+22]     ;Filedata[nr].MaxCachemem
  125.          ADD EAX,[ESI+8]   ;Filedata[nr].Offset
  126.          MOV [EBP-4],EAX   ;Function result
  127.      END;
  128. END;
  129.  
  130. FUNCTION CacheFileSize(nr:CacheFile):LONGWORD;
  131. BEGIN
  132.      CacheFileSize:=filedata[nr].lblock*filedata[nr].maxcachemem+filedata[nr].loffset;
  133. END;
  134.  
  135. PROCEDURE CacheBlockIO(nr:CacheFile;blocknr:LONGWORD;_write:BOOLEAN);
  136. var l:LONGWORD;
  137.     po:LONGWORD;
  138. BEGIN
  139.      {IF filedata[nr].changed THEN
  140.      BEGIN
  141.           filedata[nr].changed:=FALSE;
  142.           cacheblockio(nr,filedata[nr].block,TRUE);
  143.           IF CacheIOResult>cerrorok THEN Exit;
  144.      END;
  145.      IF blocknr=filedata[nr].lblock THEN l:=filedata[nr].loffset
  146.      ELSE l:=filedata[nr].maxcachemem;
  147.      po:=filedata[nr].maxcachemem;
  148.      po:=po*blocknr;
  149.      Seek(filedata[nr].f,po);
  150.      CacheIOResult:=ioresult;
  151.      IF l>0 THEN IF CacheIOResult=0 THEN
  152.      BEGIN
  153.           IF _write THEN BlockWrite(filedata[nr].f,filedata[nr].p^,l)
  154.           ELSE BlockRead(filedata[nr].f,filedata[nr].p^,l);
  155.           CacheIOResult:=ioresult;
  156.      END;}
  157.      ASM
  158.          MOV ESI,OFFSET(_FILEDATA)
  159.          MOVZXW EAX,$NR
  160.          DEC EAX
  161.          SHL EAX,7
  162.          ADD ESI,EAX             ;this does not change during the run
  163.  
  164.          CMPB [ESI+17],0         ;Filedata[nr].changed
  165.          JE _!L13                ;not changed
  166.  
  167.          ;Filedata[nr].changed
  168.          MOVB [ESI+17],0         ;Filedata[nr].Changed=FALSE
  169.  
  170.          PUSH ESI                ;for further use
  171.  
  172.          PUSH $NR
  173.          PUSHL [ESI+0]
  174.          PUSH 1
  175.          CALLN32 _CACHEBLOCKIO
  176.  
  177.          POP ESI
  178.  
  179.          CMPD _CACHEIORESULT,0
  180.          JNE _!L19        ;exit this
  181. _!L13:
  182.          ;Filedata[nr] not changed
  183.          MOV EBX,[ESI+22]  ;Filedata[nr].maxcachemem
  184.  
  185.          MOV EAX,$BLOCKNR
  186.          CMP EAX,[ESI+4]   ;Filedata[nr].lblock
  187.          JNE _!L17         ;otherwise its maxcachemem from above
  188.          MOV EBX,[ESI+12]  ;Filedata[nr].loffset
  189. _!L17:
  190.          MOV $L,EBX
  191. _!L18:
  192.          MOV EAX,[ESI+22]  ;Filedata[nr].maxcachemem
  193.          MULD $BLOCKNR
  194.          MOV $PO,EAX
  195.  
  196.          PUSH ESI          ;for further use
  197.  
  198.          LEA EAX,[ESI+26]  ;Filedata[nr].f
  199.          PUSH EAX
  200.          PUSHL $PO
  201.          CALLN32 SYSTEM._SEEK
  202.  
  203.          POP ESI
  204.          MOV EAX,_IORESULT
  205.          MOV _CACHEIORESULT,EAX
  206.          CMPD $L,0
  207.          JNA _!L19        ;exit
  208.  
  209.          CMPD _CACHEIORESULT,0
  210.          JNE _!L19        ;exit
  211.  
  212.          CMPB $_WRITE,0
  213.          JE _!L23         ;Read is requested
  214.  
  215.          LEA EAX,[ESI+26]    ;Filedata[nr].f
  216.          PUSH EAX
  217.          MOV ESI,[ESI+18]    ;Filedata[nr].p^
  218.          PUSH ESI
  219.          PUSHL $L
  220.          CALLN32 SYSTEM._BLOCKWRITE  ;dont care about ESI
  221.          JMP _!L24
  222. _!L23:
  223.          LEA EAX,[ESI+26]    ;Filedata[nr].f
  224.          PUSH EAX
  225.          MOV ESI,[ESI+18]    ;Filedata[nr].p^
  226.          PUSH ESI
  227.          PUSHL $L
  228.          CALLN32 SYSTEM._BLOCKREAD   ;dont care about ESI
  229. _!L24:
  230.          MOV EAX,_IORESULT
  231.          MOV _CACHEIORESULT,EAX
  232. _!L19:
  233.      END;
  234. END;
  235.  
  236.  
  237. FUNCTION CacheEOF(nr:CacheFile):BOOLEAN;
  238. BEGIN
  239.      cacheeof:=(filedata[nr].offset=filedata[nr].loffset)AND(
  240.        filedata[nr].block=filedata[nr].lblock);
  241.      {ASM
  242.         MOVB [EBP-4],0       ;result is initially false
  243.         MOV ESI,OFFSET(_FILEDATA)
  244.         MOVZXW EAX,$NR
  245.         DEC EAX
  246.         SHL EAX,7
  247.         ADD ESI,EAX            ;This does not change during the run
  248.  
  249.         MOV EAX,[ESI+8]        ;Filedata[nr].offset
  250.         CMP EAX,[ESI+12]       ;Filedata[nr].loffset
  251.         JNE _!L25
  252.         MOV EAX,[ESI+0]        ;Filedata[nr].block
  253.         CMP EAX,[ESI+4]        ;Filedata[nr].lblock
  254.         JNE _!L25
  255.         MOVB [EBP-4],1         ;EOF is TRUE
  256. _!L25:
  257.      END;} {asm}
  258. END;
  259.  
  260.  
  261. PROCEDURE CacheSeek(nr:CacheFile;Pos:LONGWORD);
  262. var
  263.     pblock:LONGWORD;
  264.     poffset:LongWord;
  265. BEGIN
  266.   {CacheIOResult:=cerrorok;
  267.   pblock:=Pos DIV filedata[nr].maxcachemem;
  268.   poffset:=Pos MOD filedata[nr].maxcachemem;
  269.   IF Pos>filedata[nr].loffset+filedata[nr].maxcachemem*filedata[nr].lblock THEN
  270.   BEGIN
  271.        CacheIOResult:=cerrornotinfile;
  272.        Exit;
  273.   END;
  274.   IF pblock<>filedata[nr].block THEN cacheblockio(nr,pblock,FALSE);
  275.   filedata[nr].bitpos:=0;
  276.   filedata[nr].offset:=poffset;
  277.   filedata[nr].block:=pblock;}
  278.   ASM
  279.       MOVD _CACHEIORESULT,0
  280.  
  281.       MOV ESI,OFFSET(_FILEDATA)
  282.       MOVZXW EAX,$NR
  283.       DEC EAX
  284.       SHL EAX,7
  285.       ADD ESI,EAX             ;This does not change during the run
  286.  
  287.       MOV EAX,$POS
  288.       XOR EDX,EDX
  289.       DIVD [ESI+22]           ;Filedata[nr].maxcachemem
  290.       MOV $PBLOCK,EAX
  291.       MOV $POFFSET,EDX
  292.  
  293.       MOV EAX,[ESI+22]        ;Filedata[nr].maxcachemem
  294.       MULD [ESI+4]            ;Filedata[nr].lblock
  295.       ADD EAX,[ESI+12]        ;Filedata[nr].lOffset
  296.       CMP $POS,EAX
  297.       JBE _!L27
  298.       MOVD _CACHEIORESULT,1
  299.       JMP _!L26                  ;exit this
  300. _!L27:
  301.       MOV EAX,$PBLOCK
  302.       CMP EAX,[ESI+0]             ;Filedata[nr].block
  303.       JE _!L29
  304.  
  305.       PUSH ESI                  ;for further use
  306.  
  307.       PUSH $NR
  308.       PUSHL $PBLOCK
  309.       PUSH 0                    ;read it
  310.       CALLN32 _CACHEBLOCKIO
  311.  
  312.       POP ESI
  313. _!L29:
  314.       MOVB [ESI+16],0           ;filedata[nr].bitpos
  315.       MOV EAX,$POFFSET
  316.       MOV [ESI+8],EAX           ;filedata[nr].offset
  317.       MOV EAX,$PBLOCK
  318.       MOV [ESI+0],EAX           ;filedata[nr].block
  319. _!L26:
  320.   END; {asm}
  321. END;
  322.  
  323. FUNCTION CacheOpen(fname:STRING;task:BYTE;cacheamount:word):BYTE;
  324. var
  325.    l:LONGWORD;
  326.    nr:BYTE;
  327. BEGIN
  328.   nr:=1;
  329.   CacheIOResult:=cerrorok;
  330.   while(filedata[nr].p<>NIL)AND(nr<=maxcachefiles+1) DO inc(nr);
  331.   IF nr>maxcachefiles THEN
  332.   BEGIN
  333.       CacheIOResult:=cerrortoomanyfiles;
  334.       Exit;
  335.   END;
  336.   Cacheopen:=nr;
  337.  
  338.   filedata[nr].maxcachemem:=cacheamount;
  339.   Assign(filedata[nr].f,fname);
  340.   filedata[nr].changed:=FALSE;
  341.   filedata[nr].bitpos:=0;
  342.   CASE task OF
  343.         corewrite:Rewrite(filedata[nr].f,1);
  344.         coAppend,coreset:Reset(filedata[nr].f,1);
  345.   END; {case}
  346.   CacheIOResult:=ioresult;
  347.   IF CacheIOResult>cerrorok THEN Exit;
  348.   l:=filesize(filedata[nr].f);
  349.   filedata[nr].lblock:=l DIV filedata[nr].maxcachemem;
  350.   filedata[nr].loffset:=l MOD filedata[nr].maxcachemem;
  351.   GetMem(filedata[nr].p,filedata[nr].maxcachemem);
  352.  
  353.   IF task<>coappend THEN
  354.   BEGIN
  355.        cacheblockio(nr,0,FALSE); {read}
  356.        filedata[nr].block:=0;
  357.        filedata[nr].offset:=0;
  358.   END
  359.   ELSE
  360.   BEGIN
  361.        cacheblockio(nr,filedata[nr].lblock,FALSE); {read}
  362.        filedata[nr].block:=filedata[nr].lblock;
  363.        filedata[nr].offset:=filedata[nr].loffset;
  364.   END;
  365. END;
  366.  
  367.  
  368. PROCEDURE CacheRewrite(var nr:CacheFile;
  369. fname:STRING; cache:word);
  370. BEGIN
  371.   nr:=cacheopen(fname,corewrite,cache);
  372. END;
  373.  
  374.  
  375. PROCEDURE CacheReset(var nr:CacheFile;fname:STRING; cache:word);
  376. BEGIN
  377.      nr:=cacheopen(fname,coreset,cache);
  378. END;
  379.  
  380.  
  381. PROCEDURE CacheAppend(var nr:CacheFile;fname:STRING; cache:word);
  382. BEGIN
  383.      nr:=cacheopen(fname,coappend,cache);
  384. END;
  385.  
  386.  
  387.  
  388. PROCEDURE CacheErase(fname:STRING);
  389. BEGIN
  390.   Erase(fname);
  391.   CacheIOResult:=ioresult;
  392. END;
  393.  
  394.  
  395. PROCEDURE CacheClose(var nr:CacheFile);
  396. BEGIN
  397.   Cacheioresult:=cerrorok;
  398.   IF nr>=MaxCacheFiles THEN exit;
  399.   IF filedata[nr].p=NIL THEN
  400.   BEGIN
  401.       CacheIOResult:=cerrorclosed;
  402.       Exit;
  403.   END;
  404.   IF filedata[nr].changed THEN
  405.   BEGIN
  406.        filedata[nr].changed:=FALSE;
  407.        cacheblockio(nr,filedata[nr].block,TRUE); {write}
  408.   END;
  409.   Close(filedata[nr].f);
  410.   CacheIOResult:=ioresult;
  411.   FreeMem(filedata[nr].p,filedata[nr].maxcachemem);
  412.   filedata[nr].p:=NIL;
  413.   nr:=maxcachefiles;
  414. END;
  415.  
  416.  
  417. PROCEDURE CacheClose1(var nr:CacheFile);
  418. BEGIN
  419.   CacheIoresult:=Cerrorok;
  420.   IF nr=MaxCacheFiles THEN exit;
  421.   IF filedata[nr].p=NIL THEN
  422.   BEGIN
  423.       CacheIOResult:=cerrorclosed;
  424.       Exit;
  425.   END;
  426.   Close(filedata[nr].f);
  427.   CacheIOResult:=ioresult;
  428.   FreeMem(filedata[nr].p,filedata[nr].maxcachemem);
  429.   filedata[nr].p:=NIL;
  430.   nr:=maxcachefiles;
  431. END;
  432.  
  433.  
  434. PROCEDURE CacheRead(nr:CacheFile; var value:BYTE);
  435. var v:pointer;
  436.     o:LONGWORD;
  437.     pp:POINTER;
  438. BEGIN
  439.   {IF cacheeof(nr) THEN
  440.   BEGIN
  441.       CacheIOResult:=cerrornotinfile;
  442.       Exit;
  443.   END;
  444.   o:=filedata[nr].offset;
  445.   pp:=filedata[nr].p;
  446.   ASM
  447.      MOV ESI,$pp
  448.      ADD ESI,$o
  449.      CLD
  450.      LODSB
  451.      MOV EDI,$value
  452.      STOSB
  453.   END;
  454.   inc(filedata[nr].offset);
  455.   IF filedata[nr].offset>=filedata[nr].maxcachemem THEN
  456.   BEGIN
  457.        cacheblockio(nr,filedata[nr].block+1,FALSE);
  458.        filedata[nr].offset:=0;
  459.        inc(filedata[nr].block);
  460.   END;}
  461.   ASM
  462.       PUSH $NR
  463.       CALLN32 _CACHEEOF
  464.       CMP AL,0
  465.       JE _!L64
  466.       MOVD _CACHEIORESULT,1
  467.       JMP _!L63
  468. _!L64:
  469.       MOV ESI,OFFSET(_FILEDATA)
  470.       MOVZXW EAX,$NR
  471.       DEC EAX
  472.       SHL EAX,7
  473.       ADD ESI,EAX              ;This does not change dzring the run
  474.  
  475.       MOV EAX,[ESI+8]          ;Filedata[nr].offset
  476.       MOV $O,EAX
  477.       MOV EAX,[ESI+18]         ;Filedata[nr].p
  478.       MOV $PP,EAX
  479.  
  480.       PUSH ESI                 ;for further use
  481.  
  482.       MOV ESI,$PP
  483.       ADD ESI,$O
  484.       CLD
  485.       LODSB
  486.       MOV EDI,$VALUE
  487.       STOSB
  488.  
  489.       POP ESI
  490.  
  491.       INCD [ESI+8]             ;Filedata[nr].offset
  492.       MOV EAX,[ESI+8]      ;Filedata[nr].offset
  493.       CMP EAX,[ESI+22]     ;Filedata[nr].maxcachemem
  494.       JB _!L63             ;exit this
  495.  
  496.       PUSH ESI             ;for further use
  497.  
  498.       PUSH $NR
  499.       MOV EAX,[ESI+0]
  500.       INC EAX
  501.       PUSH EAX
  502.       PUSH 0
  503.       CALLN32 _CACHEBLOCKIO
  504.  
  505.       POP ESI
  506.  
  507.       MOVD [ESI+8],0       ;Filedata[nr].offset
  508.       INCD [ESI+0]         ;Filedata[nr].block
  509. _!L63:
  510.   END;
  511. END;
  512.  
  513.  
  514. PROCEDURE CacheReadExt(nr:CacheFile; var value; l:LongWord);
  515. var t:LongWord;
  516. BEGIN
  517.      IF l>0 THEN FOR t:=0 to l-1 DO
  518.      BEGIN
  519.           ASM
  520.              PUSH $nr
  521.              MOV EDI,$value
  522.              ADD EDI,$t
  523.              PUSH EDI
  524.              CALLN32 _CacheRead
  525.           END;
  526.      END;
  527. END;
  528.  
  529.  
  530. PROCEDURE CacheWrite(nr:CacheFile;value:BYTE);
  531. VAR pp:POINTER;
  532.     o:LONGWORD;
  533.     c:BOOLEAN;
  534. BEGIN
  535.      {pp:=filedata[nr].p;
  536.      o:=filedata[nr].offset;
  537.      c:=filedata[nr].Changed;
  538.      ASM
  539.         PUSH ESI
  540.  
  541.         MOV ESI,$pp
  542.         ADD ESI,$o
  543.         MOV AL,[ESI+0]
  544.         CMP AL,$value
  545.         JE !nw
  546.         MOV AL,$value
  547.         MOV [ESI+0],AL
  548.         MOVB $c,1
  549. !nw:
  550.         POP ESI
  551.      END;
  552.      filedata[nr].changed:=c;
  553.      IF CacheEOF(nr) THEN
  554.      BEGIN
  555.           filedata[nr].changed:=true;
  556.           expand(nr);
  557.      END;
  558.      inc(filedata[nr].offset);
  559.  
  560.      IF filedata[nr].offset=filedata[nr].maxcachemem THEN
  561.      BEGIN
  562.           filedata[nr].changed:=FALSE;
  563.           CacheBlockIO(nr,filedata[nr].block,TRUE);
  564.           filedata[nr].offset:=0;
  565.           inc(filedata[nr].block);
  566.           CacheBlockIO(nr,filedata[nr].block,FALSE);
  567.      END;}
  568.      ASM
  569.          MOV ESI,OFFSET(_FILEDATA)
  570.          MOVZXW EAX,$NR
  571.          DEC EAX
  572.          SHL EAX,7
  573.          ADD ESI,EAX               ;This  does not change during the run
  574.  
  575.          MOV EAX,[ESI+18]          ;Filedata[nr].p
  576.          MOV $PP,EAX
  577.          MOV EAX,[ESI+8]           ;Filedata[nr].offset
  578.          MOV $O,EAX
  579.          MOV AL,[ESI+17]           ;Filedata[nr].changed
  580.          MOV $C,AL
  581.  
  582.          PUSH ESI                 ;for further use
  583.  
  584.          MOV ESI,$PP
  585.          ADD ESI,$O
  586.          MOV AL,[ESI+0]
  587.          CMP AL,$VALUE
  588.          JE !NW
  589.          MOV AL,$VALUE
  590.          MOV [ESI+0],AL
  591.          MOVB $C,1
  592. !NW:
  593.          POP ESI
  594.  
  595.          MOV AL,$C
  596.          MOV [ESI+17],AL           ;Filedata[nr].changed
  597.  
  598.          PUSH ESI                  ;For further use
  599.  
  600.          PUSH $NR
  601.          CALLN32 _CACHEEOF
  602.  
  603.          POP ESI
  604.  
  605.          CMP AL,0
  606.          JE _!L72
  607.  
  608.          MOVB [ESI+17],1           ;Filedata[nr].changed
  609.  
  610.          PUSH ESI                  ;for further use
  611.  
  612.          PUSH $NR
  613.          CALLN32 _EXPAND
  614.  
  615.          POP ESI
  616. _!L72:
  617.          INCD [ESI+8]              ;Filedata[nr].offset
  618.  
  619.          MOV EAX,[ESI+8]           ;Filedata[nr].offset
  620.          CMP EAX,[ESI+22]          ;Filedata[nr].maxcachemem
  621.          JNE _!L74
  622.  
  623.          MOVB [ESI+17],0          ;Filedata[nr].changed
  624.  
  625.          PUSH ESI                 ;for further use
  626.  
  627.          ;write old block
  628.          PUSH $NR
  629.          PUSHL [ESI+0]            ;Filedata[nr].block
  630.          PUSH 1
  631.          CALLN32 _CACHEBLOCKIO
  632.  
  633.          POP ESI
  634.          MOVD [ESI+8],0           ;Filedata[nr].offset
  635.          INCD [ESI+0]             ;Filedata[nr].block
  636.  
  637.          ;Read new block
  638.          PUSH $NR
  639.          PUSHL [ESI+0]            ;Filedata[nr].block
  640.          PUSH 0
  641.          CALLN32 _CACHEBLOCKIO
  642. _!L74:
  643.      END;
  644. END;
  645.  
  646.  
  647. PROCEDURE CacheWriteExt(nr:CacheFile; var value; l:LongWord);
  648. var
  649.     t:LongWord;
  650.     v:POINTER;
  651. BEGIN
  652.      ASM
  653.         MOV EAX,$value
  654.         MOV $v,EAX
  655.      END;
  656.      IF l>0 THEN FOR t:=0 to l-1 DO
  657.      BEGIN
  658.           ASM
  659.              PUSH $nr
  660.              MOV EDI,$v
  661.              ADD EDI,$t
  662.              MOV AL,[EDI+0]
  663.              XOR AH,AH
  664.              PUSH AX
  665.              CALLN32 _CacheWrite
  666.           END;
  667.           IF cacheioresult<>0 THEN exit;
  668.      END;
  669. END;
  670.  
  671.  
  672. PROCEDURE CacheWriteString(nr:CacheFile; var value:STRING);
  673. BEGIN
  674.      ASM
  675.         PUSH $nr         ;File
  676.         MOV EDI,$value
  677.         MOV AL,[EDI+0]   ;length
  678.         INC EDI  ;value[1]
  679.         PUSH EDI
  680.         MOVZX EAX,AL
  681.         PUSH EAX
  682.         CALLN32 _CacheWriteExt
  683.      END;
  684. END;
  685.  
  686.  
  687. var CacheExitSave:pointer;
  688.  
  689.  
  690. PROCEDURE cacheexit;
  691. var i:CacheFile;
  692. BEGIN
  693.   Exitproc:=CacheExitsave;
  694.   FOR i:=1 to maxcachefiles DO
  695.   BEGIN
  696.        IF filedata[i].p<>NIL THEN
  697.        BEGIN
  698.             IF filedata[i].changed THEN
  699.             BEGIN
  700.                  filedata[i].changed:=FALSE;
  701.                  cacheblockio(i,filedata[i].block,TRUE); {write}
  702.             END;
  703.             Close(filedata[i].f);
  704.             CacheIOResult:=ioresult;
  705.             FreeMem(filedata[i].p,filedata[i].maxcachemem);
  706.             filedata[i].p:=NIL;
  707.        END;
  708.    END;
  709. END;
  710.  
  711. BEGIN
  712.   CacheExitsave:=Exitproc;
  713.   Exitproc:=@cacheexit;
  714.   cacheinit;
  715. END.
  716.