+ #if IOCACHE_USE_PAGES
+ char *page_map;
+ size_t offset;
+ tIOCache_PageInfo *prev;
+ tIOCache_PageInfo *page = IOCache_int_GetPage(Cache, Sector, &prev, &offset);
+ if( page )
+ {
+ Uint32 mask = (1 << offset/Cache->SectorSize);
+ int ret = !(page->PresentSectors & mask);
+ if( ret )
+ {
+ page_map = MM_MapTemp( page->BasePhys );
+ memcpy( page_map + offset, Buffer, Cache->SectorSize );
+ MM_FreeTemp( page_map );
+ page->PresentSectors |= mask;
+ }
+ Mutex_Release( &Cache->Lock );
+ return ret;
+ }
+ else if( Cache->CacheUsed <= Cache->CacheSize )
+ {
+ page = malloc( sizeof(tIOCache_PageInfo) );
+ page->BasePhys = MM_AllocPhys();
+ page_map = MM_MapTemp( page->BasePhys );
+
+ page->GlobalNext = gIOCache_GlobalPages;
+ gIOCache_GlobalPages = page;
+ }
+ else
+ {
+ tIOCache_PageInfo *oldest = Cache->Pages, *oldestPrev = NULL;
+ for( tIOCache_PageInfo *ent = Cache->Pages; ent; prev = ent, ent = ent->CacheNext )
+ {
+ if( ent->LastAccess < oldest->LastAccess ) {
+ oldest = ent;
+ oldestPrev = prev;
+ }
+ }
+ // Remove oldest from list
+ *(oldestPrev ? &oldestPrev->CacheNext : &Cache->Pages) = oldest->CacheNext;
+ page = oldest;
+ page_map = MM_MapTemp( page->BasePhys );
+ // Flush
+ if( page->DirtySectors && Cache->Mode != IOCACHE_VIRTUAL )
+ {
+ for( int i = 0; i < PAGE_SIZE/Cache->SectorSize; i ++ )
+ Cache->Write(Cache->ID, page->BaseOffset/Cache->SectorSize+i,
+ page_map + i * Cache->SectorSize);
+ }
+ }
+
+ // Create a new page
+ page->CacheNext = prev->CacheNext;
+ prev->CacheNext = page;
+
+ page->Owner = Cache;
+ page->LastAccess = now();
+
+ page->BaseOffset = (Sector*Cache->SectorSize) & ~(PAGE_SIZE-1);
+ page->PresentSectors = 0;
+ page->DirtySectors = 0;
+
+ memcpy( page_map + offset, Buffer, Cache->SectorSize );
+
+ MM_FreeTemp(page_map);
+
+ #else
+ tIOCache_Ent *ent, *prev;
+ tIOCache_Ent *new;
+ tIOCache_Ent *oldest = NULL, *oldestPrev;