diff --git a/driver.c b/driver.c index 69d2426..d5b0361 100644 --- a/driver.c +++ b/driver.c @@ -2,6 +2,7 @@ #include #include +#include #include #include "driver.h" #include "driverwrapper.h" @@ -250,6 +251,7 @@ static Word DoMountURL(struct GSOSDP *dp) { mountURLRec->result = OUT_OF_MEMORY; return drvrNoResrc; } + sess->useCache = TRUE; err = SetURL(sess, mountURLRec->url, TRUE, FALSE); if (err != OPERATION_SUCCESSFUL) { @@ -333,6 +335,33 @@ static Word DoRead(struct GSOSDP *dp) { dp->transferCount = 0; return drvrBadBlock; } + + LongWord firstBlockNum; + LongWord endBlockNum; + unsigned char *bufferPtr; + + Boolean useCache = sess->useCache + && (int)dp->cachePriority > 0 + && (dp->fstNum & 0x8000) == 0 + && dp->blockSize == BLOCK_SIZE; + if (useCache) { + firstBlockNum = dp->blockNum; + endBlockNum = firstBlockNum + dp->requestCount / BLOCK_SIZE; + bufferPtr = dp->bufferPtr; + for (; dp->blockNum < endBlockNum; dp->blockNum++) { + if (!CacheFindBlk()) { + goto skipCache; + } + memmove(bufferPtr, dp->cachePointer, BLOCK_SIZE); + bufferPtr += BLOCK_SIZE; + } + dp->blockNum = firstBlockNum; + dp->transferCount = dp->requestCount; + return 0; +skipCache: + useCache = (dp->blockNum == firstBlockNum); + dp->blockNum = firstBlockNum; + } enum NetDiskError err = DoHTTPRequest(sess, readStart, readEnd); if (err != OPERATION_SUCCESSFUL) { @@ -362,6 +391,19 @@ static Word DoRead(struct GSOSDP *dp) { return drvrIOError; } + if (useCache && sess->readCount == 0) { + bufferPtr = dp->bufferPtr; + dp->blockNum = firstBlockNum; + for (; dp->blockNum < endBlockNum; dp->blockNum++) { + if (!CacheAddBlk()) { + break; + } + memmove(dp->cachePointer, bufferPtr, BLOCK_SIZE); + bufferPtr += BLOCK_SIZE; + } + dp->blockNum = firstBlockNum; + } + return 0; } diff --git a/session.h b/session.h index 1538f60..202e6d7 100644 --- a/session.h +++ b/session.h @@ -55,6 +55,9 @@ typedef struct Session { /* Length of disk image data */ LongWord dataLength; + /* Should the GS/OS block cache be used? */ + Boolean useCache; + /* Buffer for initial bytes of file (which may be a disk image header) */ union { unsigned char buf[32];