home *** CD-ROM | disk | FTP | other *** search
- UNIT Cache;
-
- {**************************************************************************
- * Sourcefile for Speed-386 *
- * (C) 1993,94 R.Nürnberger Franz-Mehring-Str.2 09112 Chemnitz *
- * *
- * Cache routines for fast input/output to files via memory buffer *
- * *
- * *
- **************************************************************************}
-
- INTERFACE
-
- USES dos;
-
- CONST
- MaxCacheFiles=10; {Maximal file handles to cache}
-
- {Cache error codes}
- cerrorok=0;
- cerrornotinfile=1;
- cerrortoomanyfiles=2;
- cerrorclosed=3;
- cerrornomemory=4;
- cerrorcacheamount=5;
- cerrorother=99;
-
- TYPE
- CacheFile=WORD;
-
- CONST
- corewrite =1;
- coreset =2;
- coappend =3;
-
- VAR CacheIOResult:LONGWORD;
-
- FUNCTION CacheFilePos(nr:CacheFile):LONGWORD;
- FUNCTION CacheEOF(nr:CacheFile):BOOLEAN;
- PROCEDURE CacheSeek(nr:CacheFile;Pos:LONGWORD);
- PROCEDURE CacheRewrite(var nr:CacheFile;fname:STRING; cache:Word);
- PROCEDURE CacheReset(var nr:CacheFile;fname:STRING; cache:word);
- PROCEDURE CacheAppend(var nr:CacheFile;fname:STRING; cache:word);
- PROCEDURE CacheErase(fname:STRING);
- PROCEDURE CacheClose(var nr:CacheFile);
- PROCEDURE CacheClose1(var nr:CacheFile);
- PROCEDURE CacheRead(nr:CacheFile; var value:BYTE);
- PROCEDURE CachereadExt(nr:CacheFile; var value; l:LongWord);
- PROCEDURE CacheWrite(nr:CacheFile;value:BYTE);
- PROCEDURE CacheWriteExt(nr:CacheFile; var value; l:LongWord);
- PROCEDURE CacheWriteString(nr:CacheFile; var value:STRING);
- PROCEDURE cacheexit;
- FUNCTION CacheOpen(fname:STRING;task:BYTE;cacheamount:LongWord):BYTE;
- PROCEDURE CacheGetFTime(nr:CacheFile; var year,month,day,hour,min,twosec:WORD);
- FUNCTION CacheFileSize(nr:CacheFile):LONGWORD;
- PROCEDURE CacheInit;
-
- VAR
- FileData:ARRAY[1..MaxCacheFiles] OF RECORD
- block,lblock:LONGWORD;
- offset,loffset:LONGWORD;
- bitpos:BYTE;
- changed:BOOLEAN;
- p:^ Word;
- maxcachemem:LONGWORD;
- f:FILE;
- Fill:WORD; {to fill up to 128 Byte}
- END;
-
- IMPLEMENTATION
-
- PROCEDURE cacheinit;
- var i:CacheFile;
- BEGIN
- FOR i:=1 to MaxCachefiles DO filedata[i].p:=NIL;
- CacheIOResult:=cerrorok;
- END;
-
- PROCEDURE CacheGetFTime(nr:CacheFile; var year,month,day,hour,min,twosec:WORD);
- BEGIN
- GetFTime(filedata[nr].f,year,month,day,hour,min,twosec);
- IF doserror=0 THEN CacheIOResult:=cerrorok
- ELSE CacheIOResult:=cerrorclosed;
- END;
-
- PROCEDURE expand(nr:CacheFile);
- BEGIN
- {inc(filedata[nr].loffset);
- IF filedata[nr].loffset=filedata[nr].maxcachemem THEN
- BEGIN
- inc(filedata[nr].lblock);
- filedata[nr].loffset:=0;
- END;}
- ASM
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;This does not change during the run
-
- INCD [ESI+12] ;Filedata[nr].loffset
-
- MOV EAX,[ESI+12] ;Filedata[nr].lOffset
- CMP EAX,[ESI+22] ;Filedata[nr].Maxcachemem
- JNE _!L8
-
- INCD [ESI+4] ;Filedata[nr].lblock
- MOVD [ESI+12],0 ;Filedata[nr].loffset
- _!L8:
- END; {asm}
- END;
-
- FUNCTION CacheFilePos(nr:CacheFile):LONGWORD;
- BEGIN
- {CacheFilePos:=filedata[nr].block*filedata[nr].maxcachemem+filedata[nr].offset;}
- ASM
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX
-
- MOV EAX,[ESI+0] ;Filedata[nr].block
- MULD [ESI+22] ;Filedata[nr].MaxCachemem
- ADD EAX,[ESI+8] ;Filedata[nr].Offset
- MOV [EBP-4],EAX ;Function result
- END;
- END;
-
- FUNCTION CacheFileSize(nr:CacheFile):LONGWORD;
- BEGIN
- CacheFileSize:=filedata[nr].lblock*filedata[nr].maxcachemem+filedata[nr].loffset;
- END;
-
- PROCEDURE CacheBlockIO(nr:CacheFile;blocknr:LONGWORD;_write:BOOLEAN);
- var l:LONGWORD;
- po:LONGWORD;
- BEGIN
- {IF filedata[nr].changed THEN
- BEGIN
- filedata[nr].changed:=FALSE;
- cacheblockio(nr,filedata[nr].block,TRUE);
- IF CacheIOResult>cerrorok THEN Exit;
- END;
- IF blocknr=filedata[nr].lblock THEN l:=filedata[nr].loffset
- ELSE l:=filedata[nr].maxcachemem;
- po:=filedata[nr].maxcachemem;
- po:=po*blocknr;
- Seek(filedata[nr].f,po);
- CacheIOResult:=ioresult;
- IF l>0 THEN IF CacheIOResult=0 THEN
- BEGIN
- IF _write THEN BlockWrite(filedata[nr].f,filedata[nr].p^,l)
- ELSE BlockRead(filedata[nr].f,filedata[nr].p^,l);
- CacheIOResult:=ioresult;
- END;}
- ASM
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;this does not change during the run
-
- CMPB [ESI+17],0 ;Filedata[nr].changed
- JE _!L13 ;not changed
-
- ;Filedata[nr].changed
- MOVB [ESI+17],0 ;Filedata[nr].Changed=FALSE
-
- PUSH ESI ;for further use
-
- PUSH $NR
- PUSHL [ESI+0]
- PUSH 1
- CALLN32 _CACHEBLOCKIO
-
- POP ESI
-
- CMPD _CACHEIORESULT,0
- JNE _!L19 ;exit this
- _!L13:
- ;Filedata[nr] not changed
- MOV EBX,[ESI+22] ;Filedata[nr].maxcachemem
-
- MOV EAX,$BLOCKNR
- CMP EAX,[ESI+4] ;Filedata[nr].lblock
- JNE _!L17 ;otherwise its maxcachemem from above
- MOV EBX,[ESI+12] ;Filedata[nr].loffset
- _!L17:
- MOV $L,EBX
- _!L18:
- MOV EAX,[ESI+22] ;Filedata[nr].maxcachemem
- MULD $BLOCKNR
- MOV $PO,EAX
-
- PUSH ESI ;for further use
-
- LEA EAX,[ESI+26] ;Filedata[nr].f
- PUSH EAX
- PUSHL $PO
- CALLN32 SYSTEM._SEEK
-
- POP ESI
- MOV EAX,_IORESULT
- MOV _CACHEIORESULT,EAX
- CMPD $L,0
- JNA _!L19 ;exit
-
- CMPD _CACHEIORESULT,0
- JNE _!L19 ;exit
-
- CMPB $_WRITE,0
- JE _!L23 ;Read is requested
-
- LEA EAX,[ESI+26] ;Filedata[nr].f
- PUSH EAX
- MOV ESI,[ESI+18] ;Filedata[nr].p^
- PUSH ESI
- PUSHL $L
- CALLN32 SYSTEM._BLOCKWRITE ;dont care about ESI
- JMP _!L24
- _!L23:
- LEA EAX,[ESI+26] ;Filedata[nr].f
- PUSH EAX
- MOV ESI,[ESI+18] ;Filedata[nr].p^
- PUSH ESI
- PUSHL $L
- CALLN32 SYSTEM._BLOCKREAD ;dont care about ESI
- _!L24:
- MOV EAX,_IORESULT
- MOV _CACHEIORESULT,EAX
- _!L19:
- END;
- END;
-
-
- FUNCTION CacheEOF(nr:CacheFile):BOOLEAN;
- BEGIN
- cacheeof:=(filedata[nr].offset=filedata[nr].loffset)AND(
- filedata[nr].block=filedata[nr].lblock);
- {ASM
- MOVB [EBP-4],0 ;result is initially false
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;This does not change during the run
-
- MOV EAX,[ESI+8] ;Filedata[nr].offset
- CMP EAX,[ESI+12] ;Filedata[nr].loffset
- JNE _!L25
- MOV EAX,[ESI+0] ;Filedata[nr].block
- CMP EAX,[ESI+4] ;Filedata[nr].lblock
- JNE _!L25
- MOVB [EBP-4],1 ;EOF is TRUE
- _!L25:
- END;} {asm}
- END;
-
-
- PROCEDURE CacheSeek(nr:CacheFile;Pos:LONGWORD);
- var
- pblock:LONGWORD;
- poffset:LongWord;
- BEGIN
- {CacheIOResult:=cerrorok;
- pblock:=Pos DIV filedata[nr].maxcachemem;
- poffset:=Pos MOD filedata[nr].maxcachemem;
- IF Pos>filedata[nr].loffset+filedata[nr].maxcachemem*filedata[nr].lblock THEN
- BEGIN
- CacheIOResult:=cerrornotinfile;
- Exit;
- END;
- IF pblock<>filedata[nr].block THEN cacheblockio(nr,pblock,FALSE);
- filedata[nr].bitpos:=0;
- filedata[nr].offset:=poffset;
- filedata[nr].block:=pblock;}
- ASM
- MOVD _CACHEIORESULT,0
-
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;This does not change during the run
-
- MOV EAX,$POS
- XOR EDX,EDX
- DIVD [ESI+22] ;Filedata[nr].maxcachemem
- MOV $PBLOCK,EAX
- MOV $POFFSET,EDX
-
- MOV EAX,[ESI+22] ;Filedata[nr].maxcachemem
- MULD [ESI+4] ;Filedata[nr].lblock
- ADD EAX,[ESI+12] ;Filedata[nr].lOffset
- CMP $POS,EAX
- JBE _!L27
- MOVD _CACHEIORESULT,1
- JMP _!L26 ;exit this
- _!L27:
- MOV EAX,$PBLOCK
- CMP EAX,[ESI+0] ;Filedata[nr].block
- JE _!L29
-
- PUSH ESI ;for further use
-
- PUSH $NR
- PUSHL $PBLOCK
- PUSH 0 ;read it
- CALLN32 _CACHEBLOCKIO
-
- POP ESI
- _!L29:
- MOVB [ESI+16],0 ;filedata[nr].bitpos
- MOV EAX,$POFFSET
- MOV [ESI+8],EAX ;filedata[nr].offset
- MOV EAX,$PBLOCK
- MOV [ESI+0],EAX ;filedata[nr].block
- _!L26:
- END; {asm}
- END;
-
- FUNCTION CacheOpen(fname:STRING;task:BYTE;cacheamount:word):BYTE;
- var
- l:LONGWORD;
- nr:BYTE;
- BEGIN
- nr:=1;
- CacheIOResult:=cerrorok;
- while(filedata[nr].p<>NIL)AND(nr<=maxcachefiles+1) DO inc(nr);
- IF nr>maxcachefiles THEN
- BEGIN
- CacheIOResult:=cerrortoomanyfiles;
- Exit;
- END;
- Cacheopen:=nr;
-
- filedata[nr].maxcachemem:=cacheamount;
- Assign(filedata[nr].f,fname);
- filedata[nr].changed:=FALSE;
- filedata[nr].bitpos:=0;
- CASE task OF
- corewrite:Rewrite(filedata[nr].f,1);
- coAppend,coreset:Reset(filedata[nr].f,1);
- END; {case}
- CacheIOResult:=ioresult;
- IF CacheIOResult>cerrorok THEN Exit;
- l:=filesize(filedata[nr].f);
- filedata[nr].lblock:=l DIV filedata[nr].maxcachemem;
- filedata[nr].loffset:=l MOD filedata[nr].maxcachemem;
- GetMem(filedata[nr].p,filedata[nr].maxcachemem);
-
- IF task<>coappend THEN
- BEGIN
- cacheblockio(nr,0,FALSE); {read}
- filedata[nr].block:=0;
- filedata[nr].offset:=0;
- END
- ELSE
- BEGIN
- cacheblockio(nr,filedata[nr].lblock,FALSE); {read}
- filedata[nr].block:=filedata[nr].lblock;
- filedata[nr].offset:=filedata[nr].loffset;
- END;
- END;
-
-
- PROCEDURE CacheRewrite(var nr:CacheFile;
- fname:STRING; cache:word);
- BEGIN
- nr:=cacheopen(fname,corewrite,cache);
- END;
-
-
- PROCEDURE CacheReset(var nr:CacheFile;fname:STRING; cache:word);
- BEGIN
- nr:=cacheopen(fname,coreset,cache);
- END;
-
-
- PROCEDURE CacheAppend(var nr:CacheFile;fname:STRING; cache:word);
- BEGIN
- nr:=cacheopen(fname,coappend,cache);
- END;
-
-
-
- PROCEDURE CacheErase(fname:STRING);
- BEGIN
- Erase(fname);
- CacheIOResult:=ioresult;
- END;
-
-
- PROCEDURE CacheClose(var nr:CacheFile);
- BEGIN
- Cacheioresult:=cerrorok;
- IF nr>=MaxCacheFiles THEN exit;
- IF filedata[nr].p=NIL THEN
- BEGIN
- CacheIOResult:=cerrorclosed;
- Exit;
- END;
- IF filedata[nr].changed THEN
- BEGIN
- filedata[nr].changed:=FALSE;
- cacheblockio(nr,filedata[nr].block,TRUE); {write}
- END;
- Close(filedata[nr].f);
- CacheIOResult:=ioresult;
- FreeMem(filedata[nr].p,filedata[nr].maxcachemem);
- filedata[nr].p:=NIL;
- nr:=maxcachefiles;
- END;
-
-
- PROCEDURE CacheClose1(var nr:CacheFile);
- BEGIN
- CacheIoresult:=Cerrorok;
- IF nr=MaxCacheFiles THEN exit;
- IF filedata[nr].p=NIL THEN
- BEGIN
- CacheIOResult:=cerrorclosed;
- Exit;
- END;
- Close(filedata[nr].f);
- CacheIOResult:=ioresult;
- FreeMem(filedata[nr].p,filedata[nr].maxcachemem);
- filedata[nr].p:=NIL;
- nr:=maxcachefiles;
- END;
-
-
- PROCEDURE CacheRead(nr:CacheFile; var value:BYTE);
- var v:pointer;
- o:LONGWORD;
- pp:POINTER;
- BEGIN
- {IF cacheeof(nr) THEN
- BEGIN
- CacheIOResult:=cerrornotinfile;
- Exit;
- END;
- o:=filedata[nr].offset;
- pp:=filedata[nr].p;
- ASM
- MOV ESI,$pp
- ADD ESI,$o
- CLD
- LODSB
- MOV EDI,$value
- STOSB
- END;
- inc(filedata[nr].offset);
- IF filedata[nr].offset>=filedata[nr].maxcachemem THEN
- BEGIN
- cacheblockio(nr,filedata[nr].block+1,FALSE);
- filedata[nr].offset:=0;
- inc(filedata[nr].block);
- END;}
- ASM
- PUSH $NR
- CALLN32 _CACHEEOF
- CMP AL,0
- JE _!L64
- MOVD _CACHEIORESULT,1
- JMP _!L63
- _!L64:
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;This does not change dzring the run
-
- MOV EAX,[ESI+8] ;Filedata[nr].offset
- MOV $O,EAX
- MOV EAX,[ESI+18] ;Filedata[nr].p
- MOV $PP,EAX
-
- PUSH ESI ;for further use
-
- MOV ESI,$PP
- ADD ESI,$O
- CLD
- LODSB
- MOV EDI,$VALUE
- STOSB
-
- POP ESI
-
- INCD [ESI+8] ;Filedata[nr].offset
- MOV EAX,[ESI+8] ;Filedata[nr].offset
- CMP EAX,[ESI+22] ;Filedata[nr].maxcachemem
- JB _!L63 ;exit this
-
- PUSH ESI ;for further use
-
- PUSH $NR
- MOV EAX,[ESI+0]
- INC EAX
- PUSH EAX
- PUSH 0
- CALLN32 _CACHEBLOCKIO
-
- POP ESI
-
- MOVD [ESI+8],0 ;Filedata[nr].offset
- INCD [ESI+0] ;Filedata[nr].block
- _!L63:
- END;
- END;
-
-
- PROCEDURE CacheReadExt(nr:CacheFile; var value; l:LongWord);
- var t:LongWord;
- BEGIN
- IF l>0 THEN FOR t:=0 to l-1 DO
- BEGIN
- ASM
- PUSH $nr
- MOV EDI,$value
- ADD EDI,$t
- PUSH EDI
- CALLN32 _CacheRead
- END;
- END;
- END;
-
-
- PROCEDURE CacheWrite(nr:CacheFile;value:BYTE);
- VAR pp:POINTER;
- o:LONGWORD;
- c:BOOLEAN;
- BEGIN
- {pp:=filedata[nr].p;
- o:=filedata[nr].offset;
- c:=filedata[nr].Changed;
- ASM
- PUSH ESI
-
- MOV ESI,$pp
- ADD ESI,$o
- MOV AL,[ESI+0]
- CMP AL,$value
- JE !nw
- MOV AL,$value
- MOV [ESI+0],AL
- MOVB $c,1
- !nw:
- POP ESI
- END;
- filedata[nr].changed:=c;
- IF CacheEOF(nr) THEN
- BEGIN
- filedata[nr].changed:=true;
- expand(nr);
- END;
- inc(filedata[nr].offset);
-
- IF filedata[nr].offset=filedata[nr].maxcachemem THEN
- BEGIN
- filedata[nr].changed:=FALSE;
- CacheBlockIO(nr,filedata[nr].block,TRUE);
- filedata[nr].offset:=0;
- inc(filedata[nr].block);
- CacheBlockIO(nr,filedata[nr].block,FALSE);
- END;}
- ASM
- MOV ESI,OFFSET(_FILEDATA)
- MOVZXW EAX,$NR
- DEC EAX
- SHL EAX,7
- ADD ESI,EAX ;This does not change during the run
-
- MOV EAX,[ESI+18] ;Filedata[nr].p
- MOV $PP,EAX
- MOV EAX,[ESI+8] ;Filedata[nr].offset
- MOV $O,EAX
- MOV AL,[ESI+17] ;Filedata[nr].changed
- MOV $C,AL
-
- PUSH ESI ;for further use
-
- MOV ESI,$PP
- ADD ESI,$O
- MOV AL,[ESI+0]
- CMP AL,$VALUE
- JE !NW
- MOV AL,$VALUE
- MOV [ESI+0],AL
- MOVB $C,1
- !NW:
- POP ESI
-
- MOV AL,$C
- MOV [ESI+17],AL ;Filedata[nr].changed
-
- PUSH ESI ;For further use
-
- PUSH $NR
- CALLN32 _CACHEEOF
-
- POP ESI
-
- CMP AL,0
- JE _!L72
-
- MOVB [ESI+17],1 ;Filedata[nr].changed
-
- PUSH ESI ;for further use
-
- PUSH $NR
- CALLN32 _EXPAND
-
- POP ESI
- _!L72:
- INCD [ESI+8] ;Filedata[nr].offset
-
- MOV EAX,[ESI+8] ;Filedata[nr].offset
- CMP EAX,[ESI+22] ;Filedata[nr].maxcachemem
- JNE _!L74
-
- MOVB [ESI+17],0 ;Filedata[nr].changed
-
- PUSH ESI ;for further use
-
- ;write old block
- PUSH $NR
- PUSHL [ESI+0] ;Filedata[nr].block
- PUSH 1
- CALLN32 _CACHEBLOCKIO
-
- POP ESI
- MOVD [ESI+8],0 ;Filedata[nr].offset
- INCD [ESI+0] ;Filedata[nr].block
-
- ;Read new block
- PUSH $NR
- PUSHL [ESI+0] ;Filedata[nr].block
- PUSH 0
- CALLN32 _CACHEBLOCKIO
- _!L74:
- END;
- END;
-
-
- PROCEDURE CacheWriteExt(nr:CacheFile; var value; l:LongWord);
- var
- t:LongWord;
- v:POINTER;
- BEGIN
- ASM
- MOV EAX,$value
- MOV $v,EAX
- END;
- IF l>0 THEN FOR t:=0 to l-1 DO
- BEGIN
- ASM
- PUSH $nr
- MOV EDI,$v
- ADD EDI,$t
- MOV AL,[EDI+0]
- XOR AH,AH
- PUSH AX
- CALLN32 _CacheWrite
- END;
- IF cacheioresult<>0 THEN exit;
- END;
- END;
-
-
- PROCEDURE CacheWriteString(nr:CacheFile; var value:STRING);
- BEGIN
- ASM
- PUSH $nr ;File
- MOV EDI,$value
- MOV AL,[EDI+0] ;length
- INC EDI ;value[1]
- PUSH EDI
- MOVZX EAX,AL
- PUSH EAX
- CALLN32 _CacheWriteExt
- END;
- END;
-
-
- var CacheExitSave:pointer;
-
-
- PROCEDURE cacheexit;
- var i:CacheFile;
- BEGIN
- Exitproc:=CacheExitsave;
- FOR i:=1 to maxcachefiles DO
- BEGIN
- IF filedata[i].p<>NIL THEN
- BEGIN
- IF filedata[i].changed THEN
- BEGIN
- filedata[i].changed:=FALSE;
- cacheblockio(i,filedata[i].block,TRUE); {write}
- END;
- Close(filedata[i].f);
- CacheIOResult:=ioresult;
- FreeMem(filedata[i].p,filedata[i].maxcachemem);
- filedata[i].p:=NIL;
- END;
- END;
- END;
-
- BEGIN
- CacheExitsave:=Exitproc;
- Exitproc:=@cacheexit;
- cacheinit;
- END.
-