ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/cdenable/cache.cpp
Revision: 1.3
Committed: 2005-01-30T21:42:15Z (19 years, 9 months ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-19, nigel-build-17
Changes since 1.2: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * cache.cpp - simple floppy/cd cache for Win32
3     *
4 gbeauche 1.3 * Basilisk II (C) 1997-2005 Christian Bauer
5 gbeauche 1.1 *
6     * Windows platform specific code copyright (C) Lauri Pesonen
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     */
22    
23     /*
24     Note that this is particularly silly cache code
25     and doesn't even use hash buckets. It is sufficient
26     for floppies and maybe emulated cd's but that's it.
27     */
28    
29     #include "sysdeps.h"
30     #include "windows.h"
31     #include "cache.h"
32    
33     #ifdef __cplusplus
34     extern "C" {
35     #endif
36    
37     #ifdef _DEBUG
38     #define new DEBUG_NEW
39     #undef THIS_FILE
40     static char THIS_FILE[] = __FILE__;
41     #endif
42    
43     void cache_clear( cachetype *cptr )
44     {
45     if(cptr->inited) {
46     cptr->res_count = 0;
47     memset( cptr->LRU, 0, NBLOCKS * sizeof(int) );
48     }
49     }
50    
51     static int init( cachetype *cptr, int sector_size )
52     {
53     cache_clear( cptr );
54     cptr->sector_size = sector_size;
55     cptr->blocks = (char *)VirtualAlloc(
56     NULL, NBLOCKS*sector_size,
57     MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
58     cptr->block = (int *)VirtualAlloc(
59     NULL, NBLOCKS*sizeof(int),
60     MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
61     cptr->LRU = (DWORD *)VirtualAlloc(
62     NULL, NBLOCKS*sizeof(DWORD),
63     MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
64     return(cptr->blocks != NULL);
65     }
66    
67     static void final( cachetype *cptr )
68     {
69     if(cptr->blocks) {
70     VirtualFree( cptr->blocks, 0, MEM_RELEASE );
71     cptr->blocks = 0;
72     }
73     if(cptr->block) {
74     VirtualFree( cptr->block, 0, MEM_RELEASE );
75     cptr->block = 0;
76     }
77     if(cptr->LRU) {
78     VirtualFree( cptr->LRU, 0, MEM_RELEASE );
79     cptr->LRU = 0;
80     }
81     cptr->inited = 0;
82     }
83    
84     void cache_init( cachetype *cptr )
85     {
86     cptr->inited = 0;
87     }
88    
89     void cache_final( cachetype *cptr )
90     {
91     if(cptr->inited) {
92     final( cptr );
93     cptr->inited = 0;
94     }
95     }
96    
97     static int in_cache( cachetype *cptr, int block )
98     {
99     int i;
100     for(i=cptr->res_count-1; i>=0; i--) {
101     if(cptr->block[i] == block) return(i);
102     }
103     return(-1);
104     }
105    
106     static int get_LRU( cachetype *cptr )
107     {
108     int i, result = 0;
109     DWORD mtime = cptr->LRU[0];
110    
111     for(i=1; i<NBLOCKS; i++) {
112     if(cptr->LRU[i] < mtime) {
113     mtime = cptr->LRU[i];
114     result = i;
115     }
116     }
117     return(result);
118     }
119    
120     void cache_put( cachetype *cptr, int block, char *buf, int ss )
121     {
122     int inx;
123    
124     if(!cptr->inited) {
125     if(!init(cptr,ss)) return;
126     cptr->inited = 1;
127     }
128     inx = in_cache( cptr, block );
129     if(inx < 0) {
130     if(cptr->res_count == NBLOCKS) {
131     inx = get_LRU( cptr );
132     } else {
133     inx = cptr->res_count++;
134     }
135     cptr->block[inx] = block;
136     }
137     cptr->LRU[inx] = GetTickCount();
138     memcpy( cptr->blocks + inx * ss, buf, ss );
139     }
140    
141     int cache_get( cachetype *cptr, int block, char *buf )
142     {
143     int inx;
144    
145     if(!cptr->inited) return(0);
146    
147     inx = in_cache( cptr, block );
148     if(inx >= 0) {
149     memcpy( buf, cptr->blocks + inx * cptr->sector_size, cptr->sector_size );
150     return(1);
151     } else {
152     return(0);
153     }
154     }
155    
156     void cache_remove( cachetype *cptr, int block, int ss )
157     {
158     int inx, from;
159    
160     if(!cptr->inited) {
161     if(!init(cptr,ss)) return;
162     cptr->inited = 1;
163     }
164     inx = in_cache( cptr, block );
165     if(inx >= 0) {
166     if(cptr->res_count > 1) {
167     from = cptr->res_count-1;
168     cptr->block[inx] = cptr->block[from];
169     cptr->LRU[inx] = cptr->LRU[from];
170     memcpy(
171     cptr->blocks + inx * cptr->sector_size,
172     cptr->blocks + from * cptr->sector_size,
173     cptr->sector_size
174     );
175     }
176     cptr->res_count--;
177     }
178     }
179    
180     #ifdef __cplusplus
181     } // extern "C"
182     #endif