ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/cdenable/cache.cpp
Revision: 1.4
Committed: 2008-01-01T09:40:34Z (16 years, 10 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.3: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * cache.cpp - simple floppy/cd cache for Win32
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 *
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