filename | src/sh4/cache.c |
changeset | 983:b0d0785aa194 |
prev | 980:deb4361928fe |
next | 1067:d3c00ffccfcd |
author | nkeynes |
date | Wed Jun 24 06:06:40 2009 +0000 (14 years ago) |
permissions | -rw-r--r-- |
last change | Support shell substitutions in config paths Keep track of last folder in file dialogs Fix out-of-dateness in GTK path dialog |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 * Implements the on-chip operand cache, instruction cache, and store queue.
4 *
5 * Copyright (c) 2008 Nathan Keynes.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
18 #define MODULE sh4_module
20 #include <string.h>
21 #include "dream.h"
22 #include "mem.h"
23 #include "mmio.h"
24 #include "clock.h"
25 #include "sh4/sh4core.h"
26 #include "sh4/sh4mmio.h"
27 #include "sh4/mmu.h"
29 #define OCRAM_START (0x7C000000>>LXDREAM_PAGE_BITS)
30 #define OCRAM_MID (0x7E000000>>LXDREAM_PAGE_BITS)
31 #define OCRAM_END (0x80000000>>LXDREAM_PAGE_BITS)
33 #define CACHE_VALID 1
34 #define CACHE_DIRTY 2
36 #define ICACHE_ENTRY_COUNT 256
37 #define OCACHE_ENTRY_COUNT 512
39 struct cache_line {
40 uint32_t key; // Fast address match - bits 5..28 for valid entry, -1 for invalid entry
41 uint32_t tag; // tag + flags value from the address field
42 };
45 static struct cache_line ccn_icache[ICACHE_ENTRY_COUNT];
46 struct cache_line ccn_ocache[OCACHE_ENTRY_COUNT];
47 static unsigned char ccn_icache_data[ICACHE_ENTRY_COUNT*32];
48 unsigned char ccn_ocache_data[OCACHE_ENTRY_COUNT*32];
51 /*********************** General module requirements ********************/
53 void CCN_reset()
54 {
55 /* Clear everything for consistency */
56 memset( ccn_icache, 0, sizeof(ccn_icache) );
57 memset( ccn_ocache, 0, sizeof(ccn_icache) );
58 memset( ccn_icache_data, 0, sizeof(ccn_icache) );
59 memset( ccn_ocache_data, 0, sizeof(ccn_icache) );
60 }
62 void CCN_save_state( FILE *f )
63 {
64 fwrite( &ccn_icache, sizeof(ccn_icache), 1, f );
65 fwrite( &ccn_icache_data, sizeof(ccn_icache_data), 1, f );
66 fwrite( &ccn_ocache, sizeof(ccn_ocache), 1, f);
67 fwrite( &ccn_ocache_data, sizeof(ccn_ocache_data), 1, f);
68 }
70 int CCN_load_state( FILE *f )
71 {
72 /* Setup the cache mode according to the saved register value
73 * (mem_load runs before this point to load all MMIO data)
74 */
75 mmio_region_MMU_write( CCR, MMIO_READ(MMU, CCR) );
77 if( fread( &ccn_icache, sizeof(ccn_icache), 1, f ) != 1 ) {
78 return 1;
79 }
80 if( fread( &ccn_icache_data, sizeof(ccn_icache_data), 1, f ) != 1 ) {
81 return 1;
82 }
83 if( fread( &ccn_ocache, sizeof(ccn_ocache), 1, f ) != 1 ) {
84 return 1;
85 }
86 if( fread( &ccn_ocache_data, sizeof(ccn_ocache_data), 1, f ) != 1 ) {
87 return 1;
88 }
89 return 0;
90 }
92 /************************* OCRAM memory address space ************************/
94 #define OCRAMPAGE0 (&ccn_ocache_data[4096]) /* Lines 128-255 */
95 #define OCRAMPAGE1 (&ccn_ocache_data[12288]) /* Lines 384-511 */
97 static int32_t FASTCALL ocram_page0_read_long( sh4addr_t addr )
98 {
99 return *((int32_t *)(OCRAMPAGE0 + (addr&0x00000FFF)));
100 }
101 static int32_t FASTCALL ocram_page0_read_word( sh4addr_t addr )
102 {
103 return SIGNEXT16(*((int16_t *)(OCRAMPAGE0 + (addr&0x00000FFF))));
104 }
105 static int32_t FASTCALL ocram_page0_read_byte( sh4addr_t addr )
106 {
107 return SIGNEXT8(*((int16_t *)(OCRAMPAGE0 + (addr&0x00000FFF))));
108 }
109 static void FASTCALL ocram_page0_write_long( sh4addr_t addr, uint32_t val )
110 {
111 *(uint32_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = val;
112 }
113 static void FASTCALL ocram_page0_write_word( sh4addr_t addr, uint32_t val )
114 {
115 *(uint16_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = (uint16_t)val;
116 }
117 static void FASTCALL ocram_page0_write_byte( sh4addr_t addr, uint32_t val )
118 {
119 *(uint8_t *)(OCRAMPAGE0 + (addr&0x00000FFF)) = (uint8_t)val;
120 }
121 static void FASTCALL ocram_page0_read_burst( unsigned char *dest, sh4addr_t addr )
122 {
123 memcpy( dest, OCRAMPAGE0+(addr&0x00000FFF), 32 );
124 }
125 static void FASTCALL ocram_page0_write_burst( sh4addr_t addr, unsigned char *src )
126 {
127 memcpy( OCRAMPAGE0+(addr&0x00000FFF), src, 32 );
128 }
130 struct mem_region_fn mem_region_ocram_page0 = {
131 ocram_page0_read_long, ocram_page0_write_long,
132 ocram_page0_read_word, ocram_page0_write_word,
133 ocram_page0_read_byte, ocram_page0_write_byte,
134 ocram_page0_read_burst, ocram_page0_write_burst,
135 unmapped_prefetch, ocram_page0_read_byte };
137 static int32_t FASTCALL ocram_page1_read_long( sh4addr_t addr )
138 {
139 return *((int32_t *)(OCRAMPAGE1 + (addr&0x00000FFF)));
140 }
141 static int32_t FASTCALL ocram_page1_read_word( sh4addr_t addr )
142 {
143 return SIGNEXT16(*((int16_t *)(OCRAMPAGE1 + (addr&0x00000FFF))));
144 }
145 static int32_t FASTCALL ocram_page1_read_byte( sh4addr_t addr )
146 {
147 return SIGNEXT8(*((int16_t *)(OCRAMPAGE1 + (addr&0x00000FFF))));
148 }
149 static void FASTCALL ocram_page1_write_long( sh4addr_t addr, uint32_t val )
150 {
151 *(uint32_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = val;
152 }
153 static void FASTCALL ocram_page1_write_word( sh4addr_t addr, uint32_t val )
154 {
155 *(uint16_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = (uint16_t)val;
156 }
157 static void FASTCALL ocram_page1_write_byte( sh4addr_t addr, uint32_t val )
158 {
159 *(uint8_t *)(OCRAMPAGE1 + (addr&0x00000FFF)) = (uint8_t)val;
160 }
161 static void FASTCALL ocram_page1_read_burst( unsigned char *dest, sh4addr_t addr )
162 {
163 memcpy( dest, OCRAMPAGE1+(addr&0x00000FFF), 32 );
164 }
165 static void FASTCALL ocram_page1_write_burst( sh4addr_t addr, unsigned char *src )
166 {
167 memcpy( OCRAMPAGE1+(addr&0x00000FFF), src, 32 );
168 }
170 struct mem_region_fn mem_region_ocram_page1 = {
171 ocram_page1_read_long, ocram_page1_write_long,
172 ocram_page1_read_word, ocram_page1_write_word,
173 ocram_page1_read_byte, ocram_page1_write_byte,
174 ocram_page1_read_burst, ocram_page1_write_burst,
175 unmapped_prefetch, ocram_page1_read_byte };
177 /**************************** Cache functions ********************************/
178 char ccn_cache_map[16 MB]; // 24 bits of address space
180 /**
181 * Load a 32-byte cache line from external memory at the given ext address.
182 * @param addr external address pre-masked to 1FFFFFFE0
183 */
184 sh4addr_t FASTCALL ccn_ocache_load_line( sh4addr_t addr )
185 {
186 int entry = addr & 0x00003FE0;
187 struct cache_line *line = &ccn_ocache[entry>>5];
188 unsigned char *cache_data = &ccn_ocache_data[entry];
189 sh4addr_t old_addr = line->tag;
190 line->tag = addr & 0x1FFFFFE0;
191 char oldstate = ccn_cache_map[old_addr>>5];
192 ccn_cache_map[old_addr>>5] = 0;
193 ccn_cache_map[addr>>5] = CACHE_VALID;
194 if( oldstate == (CACHE_VALID|CACHE_DIRTY) ) {
195 // Cache line is dirty - writeback.
196 ext_address_space[old_addr>>12]->write_burst(old_addr, cache_data);
197 }
198 ext_address_space[addr>>12]->read_burst(cache_data, addr & 0x1FFFFFE0);
199 return addr;
200 }
202 /* Long read through the operand cache */
203 /*
204 int32_t FASTCALL ccn_ocache_read_long( sh4addr_t addr );
205 int32_t FASTCALL ccn_ocache_read_word( sh4addr_t addr );
206 int32_t FASTCALL ccn_ocache_read_byte( sh4addr_t addr );
207 void FASTCALL ccn_ocache_write_long_copyback( sh4addr_t addr, uint32_t val );
208 void FASTCALL ccn_ocache_write_word_copyback( sh4addr_t addr, uint32_t val );
209 void FASTCALL ccn_ocache_write_byte_copyback( sh4addr_t addr, uint32_t val );
211 */
212 static int32_t FASTCALL ccn_ocache_read_long( sh4addr_t addr )
213 {
214 addr &= 0x1FFFFFFF;
215 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
216 ccn_ocache_load_line(addr);
217 }
218 return *(int32_t *)&ccn_ocache_data[addr & 0x3FFF];
219 }
221 static int32_t FASTCALL ccn_ocache_read_word( sh4addr_t addr )
222 {
223 addr &= 0x1FFFFFFF;
224 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
225 ccn_ocache_load_line(addr);
226 }
227 return SIGNEXT16(*(int16_t *)&ccn_ocache_data[addr&0x3FFF]);
228 }
230 static int32_t FASTCALL ccn_ocache_read_byte( sh4addr_t addr )
231 {
232 addr &= 0x1FFFFFFF;
233 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
234 ccn_ocache_load_line(addr);
235 }
236 return SIGNEXT8(ccn_ocache_data[addr&0x3FFF]);
237 }
239 static void FASTCALL ccn_ocache_write_long_copyback( sh4addr_t addr, uint32_t value )
240 {
241 addr &= 0x1FFFFFFF;
242 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
243 ccn_ocache_load_line(addr);
244 }
245 ccn_cache_map[addr>>5] |= CACHE_DIRTY;
246 *(uint32_t *)&ccn_ocache_data[addr&0x3FFF] = value;
247 }
249 static void FASTCALL ccn_ocache_write_word_copyback( sh4addr_t addr, uint32_t value )
250 {
251 addr &= 0x1FFFFFFF;
252 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
253 ccn_ocache_load_line(addr);
254 }
255 ccn_cache_map[addr>>5] |= CACHE_DIRTY;
256 *(uint16_t *)&ccn_ocache_data[addr&0x3FFF] = (uint16_t)value;
257 }
259 static void FASTCALL ccn_ocache_write_byte_copyback( sh4addr_t addr, uint32_t value )
260 {
261 addr &= 0x1FFFFFFF;
262 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
263 ccn_ocache_load_line(addr);
264 }
265 ccn_cache_map[addr>>5] |= CACHE_DIRTY;
266 ccn_ocache_data[addr&0x3FFF] = (uint8_t)value;
267 }
269 static void FASTCALL ccn_ocache_prefetch( sh4addr_t addr )
270 {
271 addr &= 0x1FFFFFFF;
272 if( (ccn_cache_map[addr>>5] & CACHE_VALID) == 0 ) {
273 ccn_ocache_load_line(addr);
274 }
275 }
277 void FASTCALL ccn_ocache_invalidate( sh4addr_t addr )
278 {
279 addr &= 0x1FFFFFFF;
280 ccn_cache_map[addr>>5] &= ~CACHE_VALID;
281 }
283 void FASTCALL ccn_ocache_purge( sh4addr_t addr )
284 {
285 addr &= 0x1FFFFFE0;
286 int oldflags = ccn_cache_map[addr>>5];
287 ccn_cache_map[addr>>5] &= ~CACHE_VALID;
288 if( oldflags == (CACHE_VALID|CACHE_DIRTY) ) {
289 unsigned char *cache_data = &ccn_ocache_data[addr & 0x3FE0];
290 ext_address_space[addr>>12]->write_burst(addr, cache_data);
291 }
292 }
294 void FASTCALL ccn_ocache_writeback( sh4addr_t addr )
295 {
296 addr &= 0x1FFFFFE0;
297 if( ccn_cache_map[addr>>5] == (CACHE_VALID|CACHE_DIRTY) ) {
298 ccn_cache_map[addr>>5] &= ~CACHE_DIRTY;
299 unsigned char *cache_data = &ccn_ocache_data[addr & 0x3FE0];
300 ext_address_space[addr>>12]->write_burst(addr, cache_data);
301 }
302 }
304 struct mem_region_fn ccn_ocache_cb_region = {
305 ccn_ocache_read_long, ccn_ocache_write_long_copyback,
306 ccn_ocache_read_word, ccn_ocache_write_word_copyback,
307 ccn_ocache_read_byte, ccn_ocache_write_byte_copyback,
308 unmapped_read_burst, unmapped_write_burst,
309 ccn_ocache_prefetch, ccn_ocache_read_byte };
312 /************************** Cache direct access ******************************/
314 static int32_t FASTCALL ccn_icache_addr_read( sh4addr_t addr )
315 {
316 int entry = (addr & 0x00001FE0);
317 return ccn_icache[entry>>5].tag;
318 }
320 static void FASTCALL ccn_icache_addr_write( sh4addr_t addr, uint32_t val )
321 {
322 int entry = (addr & 0x00003FE0);
323 struct cache_line *line = &ccn_ocache[entry>>5];
324 if( addr & 0x08 ) { // Associative
325 /* FIXME: implement this - requires ITLB lookups, with exception in case of multi-hit */
326 } else {
327 line->tag = val & 0x1FFFFC01;
328 line->key = (val & 0x1FFFFC00)|(entry & 0x000003E0);
329 }
330 }
332 struct mem_region_fn p4_region_icache_addr = {
333 ccn_icache_addr_read, ccn_icache_addr_write,
334 unmapped_read_long, unmapped_write_long,
335 unmapped_read_long, unmapped_write_long,
336 unmapped_read_burst, unmapped_write_burst,
337 unmapped_prefetch, unmapped_read_long };
340 static int32_t FASTCALL ccn_icache_data_read( sh4addr_t addr )
341 {
342 int entry = (addr & 0x00001FFC);
343 return *(uint32_t *)&ccn_icache_data[entry];
344 }
346 static void FASTCALL ccn_icache_data_write( sh4addr_t addr, uint32_t val )
347 {
348 int entry = (addr & 0x00001FFC);
349 *(uint32_t *)&ccn_icache_data[entry] = val;
350 }
352 struct mem_region_fn p4_region_icache_data = {
353 ccn_icache_data_read, ccn_icache_data_write,
354 unmapped_read_long, unmapped_write_long,
355 unmapped_read_long, unmapped_write_long,
356 unmapped_read_burst, unmapped_write_burst,
357 unmapped_prefetch, unmapped_read_long };
359 static int32_t FASTCALL ccn_ocache_addr_read( sh4addr_t addr )
360 {
361 int entry = (addr & 0x00003FE0);
362 sh4addr_t tag = ccn_ocache[entry>>5].tag;
363 return (tag&0x1FFFFC00) | ccn_cache_map[tag>>5];
364 }
366 static void FASTCALL ccn_ocache_addr_write( sh4addr_t addr, uint32_t val )
367 {
368 int entry = (addr & 0x00003FE0);
369 struct cache_line *line = &ccn_ocache[entry>>5];
370 if( addr & 0x08 ) { // Associative
371 } else {
372 sh4addr_t tag = line->tag;
373 if( ccn_cache_map[tag>>5] == (CACHE_VALID|CACHE_DIRTY) ) {
374 // Cache line is dirty - writeback.
375 unsigned char *cache_data = &ccn_ocache_data[entry];
376 ext_address_space[tag>>12]->write_burst(tag, cache_data);
377 }
378 line->tag = tag = (val & 0x1FFFFC00) | (addr & 0x3E0);
379 ccn_cache_map[tag>>5] = val & 0x03;
380 }
381 }
383 struct mem_region_fn p4_region_ocache_addr = {
384 ccn_ocache_addr_read, ccn_ocache_addr_write,
385 unmapped_read_long, unmapped_write_long,
386 unmapped_read_long, unmapped_write_long,
387 unmapped_read_burst, unmapped_write_burst,
388 unmapped_prefetch, unmapped_read_long };
391 static int32_t FASTCALL ccn_ocache_data_read( sh4addr_t addr )
392 {
393 int entry = (addr & 0x00003FFC);
394 return *(uint32_t *)&ccn_ocache_data[entry];
395 }
397 static void FASTCALL ccn_ocache_data_write( sh4addr_t addr, uint32_t val )
398 {
399 int entry = (addr & 0x00003FFC);
400 *(uint32_t *)&ccn_ocache_data[entry] = val;
401 }
403 struct mem_region_fn p4_region_ocache_data = {
404 ccn_ocache_data_read, ccn_ocache_data_write,
405 unmapped_read_long, unmapped_write_long,
406 unmapped_read_long, unmapped_write_long,
407 unmapped_read_burst, unmapped_write_burst,
408 unmapped_prefetch, unmapped_read_long };
411 /****************** Cache control *********************/
413 void CCN_set_cache_control( int reg )
414 {
415 uint32_t i;
417 if( reg & CCR_ICI ) { /* icache invalidate */
418 for( i=0; i<ICACHE_ENTRY_COUNT; i++ ) {
419 ccn_icache[i].key = -1;
420 ccn_icache[i].tag &= ~CACHE_VALID;
421 }
422 }
424 if( reg & CCR_OCI ) { /* ocache invalidate */
425 for( i=0; i<OCACHE_ENTRY_COUNT; i++ ) {
426 ccn_ocache[i].key = -1;
427 ccn_ocache[i].tag &= ~(CACHE_VALID|CACHE_DIRTY);
428 }
429 }
431 switch( reg & (CCR_OIX|CCR_ORA|CCR_OCE) ) {
432 case MEM_OC_INDEX0: /* OIX=0 */
433 for( i=OCRAM_START; i<OCRAM_END; i+=4 ) {
434 sh4_address_space[i] = &mem_region_ocram_page0;
435 sh4_address_space[i+1] = &mem_region_ocram_page0;
436 sh4_address_space[i+2] = &mem_region_ocram_page1;
437 sh4_address_space[i+3] = &mem_region_ocram_page1;
438 }
439 break;
440 case MEM_OC_INDEX1: /* OIX=1 */
441 for( i=OCRAM_START; i<OCRAM_MID; i++ )
442 sh4_address_space[i] = &mem_region_ocram_page0;
443 for( i=OCRAM_MID; i<OCRAM_END; i++ )
444 sh4_address_space[i] = &mem_region_ocram_page1;
445 break;
446 default: /* disabled */
447 for( i=OCRAM_START; i<OCRAM_END; i++ )
448 sh4_address_space[i] = &mem_region_unmapped;
449 break;
450 }
451 }
453 /**
454 * Prefetch for non-storequeue regions
455 */
456 void FASTCALL ccn_prefetch( sh4addr_t addr )
457 {
459 }
461 /************************** Uncached memory access ***************************/
462 int32_t FASTCALL ccn_uncached_read_long( sh4addr_t addr )
463 {
464 sh4r.slice_cycle += (4*sh4_bus_period);
465 addr &= 0x1FFFFFFF;
466 return ext_address_space[addr>>12]->read_long(addr);
467 }
468 int32_t FASTCALL ccn_uncached_read_word( sh4addr_t addr )
469 {
470 sh4r.slice_cycle += (4*sh4_bus_period);
471 addr &= 0x1FFFFFFF;
472 return ext_address_space[addr>>12]->read_word(addr);
473 }
474 int32_t FASTCALL ccn_uncached_read_byte( sh4addr_t addr )
475 {
476 sh4r.slice_cycle += (4*sh4_bus_period);
477 addr &= 0x1FFFFFFF;
478 return ext_address_space[addr>>12]->read_byte(addr);
479 }
480 void FASTCALL ccn_uncached_write_long( sh4addr_t addr, uint32_t val )
481 {
482 sh4r.slice_cycle += (4*sh4_bus_period);
483 addr &= 0x1FFFFFFF;
484 return ext_address_space[addr>>12]->write_long(addr, val);
485 }
486 void FASTCALL ccn_uncached_write_word( sh4addr_t addr, uint32_t val )
487 {
488 sh4r.slice_cycle += (4*sh4_bus_period);
489 addr &= 0x1FFFFFFF;
490 return ext_address_space[addr>>12]->write_word(addr, val);
491 }
492 void FASTCALL ccn_uncached_write_byte( sh4addr_t addr, uint32_t val )
493 {
494 sh4r.slice_cycle += (4*sh4_bus_period);
495 addr &= 0x1FFFFFFF;
496 return ext_address_space[addr>>12]->write_byte(addr, val);
497 }
498 void FASTCALL ccn_uncached_prefetch( sh4addr_t addr )
499 {
500 }
502 struct mem_region_fn ccn_uncached_region = {
503 ccn_uncached_read_long, ccn_uncached_write_long,
504 ccn_uncached_read_word, ccn_uncached_write_word,
505 ccn_uncached_read_byte, ccn_uncached_write_byte,
506 unmapped_read_burst, unmapped_write_burst,
507 ccn_uncached_prefetch, ccn_uncached_read_byte };
510 /********************************* Store-queue *******************************/
511 /*
512 * The storequeue is strictly speaking part of the cache, but most of
513 * the complexity is actually around its addressing (ie in the MMU). The
514 * methods here can assume we've already passed SQMD protection and the TLB
515 * lookups (where appropriate).
516 */
517 void FASTCALL ccn_storequeue_write_long( sh4addr_t addr, uint32_t val )
518 {
519 sh4r.store_queue[(addr>>2)&0xF] = val;
520 }
521 int32_t FASTCALL ccn_storequeue_read_long( sh4addr_t addr )
522 {
523 return sh4r.store_queue[(addr>>2)&0xF];
524 }
526 /**
527 * Variant used when tlb is disabled - address will be the original prefetch
528 * address (ie 0xE0001234). Due to the way the SQ addressing is done, it can't
529 * be hardcoded on 4K page boundaries, so we manually decode it here.
530 */
531 void FASTCALL ccn_storequeue_prefetch( sh4addr_t addr )
532 {
533 int queue = (addr&0x20)>>2;
534 sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
535 uint32_t hi = MMIO_READ( MMU, QACR0 + (queue>>1)) << 24;
536 sh4addr_t target = (addr&0x03FFFFE0) | hi;
537 ext_address_space[target>>12]->write_burst( target, src );
538 }
540 /**
541 * Variant used when tlb is enabled - address in this case is already
542 * mapped to the external target address.
543 */
544 void FASTCALL ccn_storequeue_prefetch_tlb( sh4addr_t addr )
545 {
546 int queue = (addr&0x20)>>2;
547 sh4ptr_t src = (sh4ptr_t)&sh4r.store_queue[queue];
548 ext_address_space[addr>>12]->write_burst( (addr & 0x1FFFFFE0), src );
549 }
.