Search
lxdream.org :: lxdream/src/sh4/sh4mem.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/sh4/sh4mem.c
changeset 930:07e5b11419db
prev929:fd8cb0c82f5f
next931:430048ea8b71
author nkeynes
date Mon Dec 22 09:51:11 2008 +0000 (13 years ago)
branchlxdream-mem
permissions -rw-r--r--
last change Remove pointer cache and add full address-space map. Much better
view annotate diff log raw
     1 /**
     2  * $Id$
     3  * sh4mem.c is responsible for interfacing between the SH4's internal memory
     4  *
     5  * Copyright (c) 2005 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 <zlib.h>
    22 #include "dream.h"
    23 #include "mem.h"
    24 #include "mmio.h"
    25 #include "dreamcast.h"
    26 #include "sh4/sh4core.h"
    27 #include "sh4/sh4mmio.h"
    28 #include "sh4/xltcache.h"
    29 #include "pvr2/pvr2.h"
    31 /* System regions (probably should be defined elsewhere) */
    32 extern struct mem_region_fn mem_region_unmapped;
    33 extern struct mem_region_fn mem_region_sdram;
    34 extern struct mem_region_fn mem_region_vram32;
    35 extern struct mem_region_fn mem_region_vram64;
    36 extern struct mem_region_fn mem_region_audioram;
    37 extern struct mem_region_fn mem_region_flashram;
    38 extern struct mem_region_fn mem_region_bootrom;
    40 /* On-chip regions other than defined MMIO regions */
    41 extern struct mem_region_fn mem_region_storequeue;
    42 extern struct mem_region_fn mem_region_icache_addr;
    43 extern struct mem_region_fn mem_region_icache_data;
    44 extern struct mem_region_fn mem_region_ocache_addr;
    45 extern struct mem_region_fn mem_region_ocache_data;
    46 extern struct mem_region_fn mem_region_itlb_addr;
    47 extern struct mem_region_fn mem_region_itlb_data;
    48 extern struct mem_region_fn mem_region_utlb_addr;
    49 extern struct mem_region_fn mem_region_utlb_data;
    51 extern struct mmio_region *P4_io[];
    53 mem_region_fn_t *sh4_address_space;
    55 /********************* The "unmapped" address space ********************/
    56 /* Always reads as 0, writes have no effect */
    57 static int32_t FASTCALL unmapped_read_long( sh4addr_t addr )
    58 {
    59     return 0;
    60 }
    61 static void FASTCALL unmapped_write_long( sh4addr_t addr, uint32_t val )
    62 {
    63 }
    64 static void FASTCALL unmapped_read_burst( unsigned char *dest, sh4addr_t addr )
    65 {
    66     memset( dest, 0, 32 );
    67 }
    68 static void FASTCALL unmapped_write_burst( sh4addr_t addr, unsigned char *src )
    69 {
    70 }
    72 struct mem_region_fn mem_region_unmapped = { 
    73         unmapped_read_long, unmapped_write_long, 
    74         unmapped_read_long, unmapped_write_long, 
    75         unmapped_read_long, unmapped_write_long, 
    76         unmapped_read_burst, unmapped_write_burst }; 
    78 /********************* Store-queue (long-write only?) ******************/
    79 static void FASTCALL p4_storequeue_write_long( sh4addr_t addr, uint32_t val )
    80 {
    81     sh4r.store_queue[(addr>>2)&0xF] = val;
    82 }
    83 static int32_t FASTCALL p4_storequeue_read_long( sh4addr_t addr )
    84 {
    85     return sh4r.store_queue[(addr>>2)&0xF];
    86 }
    87 struct mem_region_fn p4_region_storequeue = { 
    88         p4_storequeue_read_long, p4_storequeue_write_long,
    89         p4_storequeue_read_long, p4_storequeue_write_long,
    90         p4_storequeue_read_long, p4_storequeue_write_long,
    91         unmapped_read_burst, unmapped_write_burst }; // No burst access.
    93 /********************* The main ram address space **********************/
    94 static int32_t FASTCALL ext_sdram_read_long( sh4addr_t addr )
    95 {
    96     return *((int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));
    97 }
    98 static int32_t FASTCALL ext_sdram_read_word( sh4addr_t addr )
    99 {
   100     return SIGNEXT16(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
   101 }
   102 static int32_t FASTCALL ext_sdram_read_byte( sh4addr_t addr )
   103 {
   104     return SIGNEXT8(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));
   105 }
   106 static void FASTCALL ext_sdram_write_long( sh4addr_t addr, uint32_t val )
   107 {
   108     *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;
   109     xlat_invalidate_long(addr);
   110 }
   111 static void FASTCALL ext_sdram_write_word( sh4addr_t addr, uint32_t val )
   112 {
   113     *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint16_t)val;
   114     xlat_invalidate_word(addr);
   115 }
   116 static void FASTCALL ext_sdram_write_byte( sh4addr_t addr, uint32_t val )
   117 {
   118     *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint8_t)val;
   119     xlat_invalidate_word(addr);
   120 }
   121 static void FASTCALL ext_sdram_read_burst( unsigned char *dest, sh4addr_t addr )
   122 {
   123     memcpy( dest, sh4_main_ram+(addr&0x00FFFFFF), 32 );
   124 }
   125 static void FASTCALL ext_sdram_write_burst( sh4addr_t addr, unsigned char *src )
   126 {
   127     memcpy( sh4_main_ram+(addr&0x00FFFFFF), src, 32 );
   128 }
   130 struct mem_region_fn mem_region_sdram = { ext_sdram_read_long, ext_sdram_write_long, 
   131         ext_sdram_read_word, ext_sdram_write_word, 
   132         ext_sdram_read_byte, ext_sdram_write_byte, 
   133         ext_sdram_read_burst, ext_sdram_write_burst }; 
   136 /********************* The Boot ROM address space **********************/
   137 extern sh4ptr_t dc_boot_rom;
   138 extern sh4ptr_t dc_flash_ram;
   139 extern sh4ptr_t dc_audio_ram;
   140 static int32_t FASTCALL ext_bootrom_read_long( sh4addr_t addr )
   141 {
   142     return *((int32_t *)(dc_boot_rom + (addr&0x001FFFFF)));
   143 }
   144 static int32_t FASTCALL ext_bootrom_read_word( sh4addr_t addr )
   145 {
   146     return SIGNEXT16(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));
   147 }
   148 static int32_t FASTCALL ext_bootrom_read_byte( sh4addr_t addr )
   149 {
   150     return SIGNEXT8(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));
   151 }
   152 static void FASTCALL ext_bootrom_read_burst( unsigned char *dest, sh4addr_t addr )
   153 {
   154     memcpy( dest, sh4_main_ram+(addr&0x001FFFFF), 32 );
   155 }
   157 struct mem_region_fn mem_region_bootrom = { 
   158         ext_bootrom_read_long, unmapped_write_long, 
   159         ext_bootrom_read_word, unmapped_write_long, 
   160         ext_bootrom_read_byte, unmapped_write_long, 
   161         ext_bootrom_read_burst, unmapped_write_burst }; 
   163 /********************* The Audio RAM address space **********************/
   164 static int32_t FASTCALL ext_audioram_read_long( sh4addr_t addr )
   165 {
   166     return *((int32_t *)(dc_audio_ram + (addr&0x001FFFFF)));
   167 }
   168 static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )
   169 {
   170     return SIGNEXT16(*((int16_t *)(dc_audio_ram + (addr&0x001FFFFF))));
   171 }
   172 static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )
   173 {
   174     return SIGNEXT8(*((int16_t *)(dc_audio_ram + (addr&0x001FFFFF))));
   175 }
   176 static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )
   177 {
   178     *(uint32_t *)(dc_audio_ram + (addr&0x001FFFFF)) = val;
   179     asic_g2_write_word();
   180 }
   181 static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )
   182 {
   183     *(uint16_t *)(dc_audio_ram + (addr&0x001FFFFF)) = (uint16_t)val;
   184     asic_g2_write_word();
   185 }
   186 static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )
   187 {
   188     *(uint8_t *)(dc_audio_ram + (addr&0x001FFFFF)) = (uint8_t)val;
   189     asic_g2_write_word();
   190 }
   191 static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )
   192 {
   193     memcpy( dest, dc_audio_ram+(addr&0x001FFFFF), 32 );
   194 }
   195 static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )
   196 {
   197     memcpy( dc_audio_ram+(addr&0x001FFFFF), src, 32 );
   198 }
   200 struct mem_region_fn mem_region_audioram = { ext_audioram_read_long, ext_audioram_write_long, 
   201         ext_audioram_read_word, ext_audioram_write_word, 
   202         ext_audioram_read_byte, ext_audioram_write_byte, 
   203         ext_audioram_read_burst, ext_audioram_write_burst }; 
   205 /********************* The Flash RAM address space **********************/
   206 static int32_t FASTCALL ext_flashram_read_long( sh4addr_t addr )
   207 {
   208     return *((int32_t *)(dc_flash_ram + (addr&0x0001FFFF)));
   209 }
   210 static int32_t FASTCALL ext_flashram_read_word( sh4addr_t addr )
   211 {
   212     return SIGNEXT16(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));
   213 }
   214 static int32_t FASTCALL ext_flashram_read_byte( sh4addr_t addr )
   215 {
   216     return SIGNEXT8(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));
   217 }
   218 static void FASTCALL ext_flashram_write_long( sh4addr_t addr, uint32_t val )
   219 {
   220     *(uint32_t *)(dc_flash_ram + (addr&0x0001FFFF)) = val;
   221     asic_g2_write_word();
   222 }
   223 static void FASTCALL ext_flashram_write_word( sh4addr_t addr, uint32_t val )
   224 {
   225     *(uint16_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint16_t)val;
   226     asic_g2_write_word();
   227 }
   228 static void FASTCALL ext_flashram_write_byte( sh4addr_t addr, uint32_t val )
   229 {
   230     *(uint8_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint8_t)val;
   231     asic_g2_write_word();
   232 }
   233 static void FASTCALL ext_flashram_read_burst( unsigned char *dest, sh4addr_t addr )
   234 {
   235     memcpy( dest, dc_flash_ram+(addr&0x0001FFFF), 32 );
   236 }
   237 static void FASTCALL ext_flashram_write_burst( sh4addr_t addr, unsigned char *src )
   238 {
   239     memcpy( dc_flash_ram+(addr&0x0001FFFF), src, 32 );
   240 }
   242 struct mem_region_fn mem_region_flashram = { ext_flashram_read_long, ext_flashram_write_long, 
   243         ext_flashram_read_word, ext_flashram_write_word, 
   244         ext_flashram_read_byte, ext_flashram_write_byte, 
   245         ext_flashram_read_burst, ext_flashram_write_burst }; 
   247 /**************************************************************************/
   249 struct mem_region_fn p4_region_icache_addr = {
   250         mmu_icache_addr_read, mmu_icache_addr_write,
   251         mmu_icache_addr_read, mmu_icache_addr_write,
   252         mmu_icache_addr_read, mmu_icache_addr_write,
   253         unmapped_read_burst, unmapped_write_burst };
   254 struct mem_region_fn p4_region_icache_data = {
   255         mmu_icache_data_read, mmu_icache_data_write,
   256         mmu_icache_data_read, mmu_icache_data_write,
   257         mmu_icache_data_read, mmu_icache_data_write,
   258         unmapped_read_burst, unmapped_write_burst };
   259 struct mem_region_fn p4_region_ocache_addr = {
   260         mmu_ocache_addr_read, mmu_ocache_addr_write,
   261         mmu_ocache_addr_read, mmu_ocache_addr_write,
   262         mmu_ocache_addr_read, mmu_ocache_addr_write,
   263         unmapped_read_burst, unmapped_write_burst };
   264 struct mem_region_fn p4_region_ocache_data = {
   265         mmu_ocache_data_read, mmu_ocache_data_write,
   266         mmu_ocache_data_read, mmu_ocache_data_write,
   267         mmu_ocache_data_read, mmu_ocache_data_write,
   268         unmapped_read_burst, unmapped_write_burst };
   269 struct mem_region_fn p4_region_itlb_addr = {
   270         mmu_itlb_addr_read, mmu_itlb_addr_write,
   271         mmu_itlb_addr_read, mmu_itlb_addr_write,
   272         mmu_itlb_addr_read, mmu_itlb_addr_write,
   273         unmapped_read_burst, unmapped_write_burst };
   274 struct mem_region_fn p4_region_itlb_data = {
   275         mmu_itlb_data_read, mmu_itlb_data_write,
   276         mmu_itlb_data_read, mmu_itlb_data_write,
   277         mmu_itlb_data_read, mmu_itlb_data_write,
   278         unmapped_read_burst, unmapped_write_burst };
   279 struct mem_region_fn p4_region_utlb_addr = {
   280         mmu_utlb_addr_read, mmu_utlb_addr_write,
   281         mmu_utlb_addr_read, mmu_utlb_addr_write,
   282         mmu_utlb_addr_read, mmu_utlb_addr_write,
   283         unmapped_read_burst, unmapped_write_burst };
   284 struct mem_region_fn p4_region_utlb_data = {
   285         mmu_utlb_data_read, mmu_utlb_data_write,
   286         mmu_utlb_data_read, mmu_utlb_data_write,
   287         mmu_utlb_data_read, mmu_utlb_data_write,
   288         unmapped_read_burst, unmapped_write_burst };
   290 #ifdef HAVE_FRAME_ADDRESS
   291 #define RETURN_VIA(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; return; } while(0)
   292 #else
   293 #define RETURN_VIA(exc) return NULL
   294 #endif
   296 int decode_sdram = 0;
   297 mem_region_fn_t FASTCALL mem_decode_address( sh4addr_t addr )
   298 {
   299     sh4ptr_t page;
   300     switch( addr >> 26 ) { /* Area */
   301     case 0: /* Holly multiplexed */
   302         page = page_map[(addr&0x1FFFFFFF)>>12];
   303         if( ((uintptr_t)page) < MAX_IO_REGIONS ) {
   304             return &io_rgn[(uintptr_t)page]->fn;
   305         } else if( addr < 0x00200000 ) {
   306             return &mem_region_bootrom;
   307         } else if( addr < 0x00400000 ) {
   308             return &mem_region_flashram;
   309         } else if( addr >= 0x00800000 && addr < 0x00A00000 ) {
   310             return &mem_region_audioram;
   311         }
   312         break;
   313     case 1: /* VRAM */
   314         switch( addr >> 24 ) {
   315         case 4: return &mem_region_vram64; /* 0x04xxxxxx */
   316         case 5: return &mem_region_vram32; /* 0x05xxxxxx */ 
   317         }    
   318         break;
   319     case 2: /* Unmapped */
   320         break;
   321     case 3: /* Main sdram */
   322         decode_sdram++;
   323         return &mem_region_sdram;
   324     case 4: /* Holly burst-access only? */
   325         break;
   326     }
   327     return &mem_region_unmapped;
   328 }
   330 int decode_count = 0;
   331 int p4_count = 0;
   332 int sq_count = 0;
   334 mem_region_fn_t FASTCALL sh7750_decode_address( sh4addr_t addr )
   335 {
   336     decode_count++;
   337     sh4addr_t region = addr >> 29;
   338     switch( region ) {
   339     case 7: /* P4 E0000000-FFFFFFFF - On-chip I/O */
   340         if( addr < 0xE4000000 ) {
   341             sq_count++;
   342             return &p4_region_storequeue;
   343         } else if( addr < 0xFC000000 ) { /* Control register region */
   344             p4_count++;
   345             switch( addr & 0x1F000000 ) {
   346             case 0x10000000: return &p4_region_icache_addr;
   347             case 0x11000000: return &p4_region_icache_data;
   348             case 0x12000000: return &p4_region_itlb_addr;
   349             case 0x13000000: return &p4_region_itlb_data;
   350             case 0x14000000: return &p4_region_ocache_addr;
   351             case 0x15000000: return &p4_region_ocache_data;
   352             case 0x16000000: return &p4_region_utlb_addr;
   353             case 0x17000000: return &p4_region_utlb_data;
   354             default: return &mem_region_unmapped;
   355             }
   356         } else {
   357             p4_count++;
   358             struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];
   359             if( io != NULL ) {
   360                 return &io->fn;
   361             }
   362             return &mem_region_unmapped;
   363         }
   364         break;
   365     case 6: /* P3 C0000000-DFFFFFFF - TLB on, Cache on */
   366     case 5: /* P2 A0000000-BFFFFFFF - TLB off, Cache off*/
   367     case 4: /* P1 80000000-9FFFFFFF - TLB off, Cache on */
   368     default: /* P0/U0 00000000-7FFFFFFF - TLB on, Cache on */
   369         return mem_decode_address( addr & 0x1FFFFFFF ); 
   370         /* TODO: Integrate TLB, Operand Cache lookups */
   371     }
   372 }
   374 void FASTCALL sh7750_decode_address_copy( sh4addr_t addr, mem_region_fn_t result )
   375 {
   376     mem_region_fn_t region = sh7750_decode_address( addr );
   377     memcpy( result, region, sizeof(struct mem_region_fn) -8 );
   378 }
   380 /* FIXME: Handle all the many special cases when the range doesn't fall cleanly
   381  * into the same memory block
   382  */
   383 void mem_copy_from_sh4( sh4ptr_t dest, sh4addr_t srcaddr, size_t count ) {
   384     if( srcaddr >= 0x04000000 && srcaddr < 0x05000000 ) {
   385         pvr2_vram64_read( dest, srcaddr, count );
   386     } else {
   387         sh4ptr_t src = mem_get_region(srcaddr);
   388         if( src == NULL ) {
   389             WARN( "Attempted block read from unknown address %08X", srcaddr );
   390         } else {
   391             memcpy( dest, src, count );
   392         }
   393     }
   394 }
   396 void mem_copy_to_sh4( sh4addr_t destaddr, sh4ptr_t src, size_t count ) {
   397     if( destaddr >= 0x10000000 && destaddr < 0x14000000 ) {
   398         pvr2_dma_write( destaddr, src, count );
   399         return;
   400     } else if( (destaddr & 0x1F800000) == 0x05000000 ) {
   401         pvr2_render_buffer_invalidate( destaddr, TRUE );
   402     } else if( (destaddr & 0x1F800000) == 0x04000000 ) {
   403         pvr2_vram64_write( destaddr, src, count );
   404         return;
   405     }
   406     sh4ptr_t dest = mem_get_region(destaddr);
   407     if( dest == NULL )
   408         WARN( "Attempted block write to unknown address %08X", destaddr );
   409     else {
   410         xlat_invalidate_block( destaddr, count );
   411         memcpy( dest, src, count );
   412     }
   413 }
   415 static uint32_t last_page = -1;
   416 static mem_region_fn_t last_region = NULL; 
   417 static uint32_t hit_count = 0;
   418 static uint32_t miss_count = 0;
   419 static uint32_t rl_count = 0, rw_count = 0, rb_count = 0;
   420 static uint32_t wl_count = 0, ww_count = 0, wb_count = 0;
   422 /************** Compatibility methods ***************/
   424 int32_t FASTCALL sh4_read_long( sh4addr_t addr )
   425 {
   426     rl_count++;
   427     return sh4_address_space[addr>>12]->read_long(addr);
   428 }
   430 int32_t FASTCALL sh4_read_word( sh4addr_t addr )
   431 {
   432     rw_count++;
   433     return sh4_address_space[addr>>12]->read_word(addr);
   434 }
   436 int32_t FASTCALL sh4_read_byte( sh4addr_t addr )
   437 {
   438     rb_count++;
   439     return sh4_address_space[addr>>12]->read_byte(addr);
   440 }
   442 void FASTCALL sh4_write_long( sh4addr_t addr, uint32_t val )
   443 {
   444     wl_count++;
   445     sh4_address_space[addr>>12]->write_long(addr, val);
   446 }
   448 void FASTCALL sh4_write_word( sh4addr_t addr, uint32_t val )
   449 {
   450     ww_count++;
   451     sh4_address_space[addr>>12]->write_word(addr,val);
   452 }
   454 void FASTCALL sh4_write_byte( sh4addr_t addr, uint32_t val )
   455 {
   456     wb_count++;
   457     sh4_address_space[addr>>12]->write_byte(addr, val);
   458 }
   460 extern mem_region_fn_t *ext_address_space;
   462 static void sh4_register_mem_region( uint32_t start, uint32_t end, mem_region_fn_t fn )
   463 {
   464     int count = (end - start) >> 12;
   465     mem_region_fn_t *ptr = &sh4_address_space[start>>12];
   466     while( count-- > 0 ) {
   467         *ptr++ = fn;
   468     }
   469 }
   472 void sh4_mem_init()
   473 {
   474     int i;
   475     mem_region_fn_t *ptr;
   476     sh4_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
   477     for( i=0, ptr = sh4_address_space; i<7; i++, ptr += LXDREAM_PAGE_TABLE_ENTRIES ) {
   478         memcpy( ptr, ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
   479     }
   481     /* Setup main P4 regions */
   482     sh4_register_mem_region( 0xE0000000, 0xE4000000, &p4_region_storequeue );
   483     sh4_register_mem_region( 0xE4000000, 0xF0000000, &mem_region_unmapped );
   484     sh4_register_mem_region( 0xF0000000, 0xF1000000, &p4_region_icache_addr );
   485     sh4_register_mem_region( 0xF1000000, 0xF2000000, &p4_region_icache_data );
   486     sh4_register_mem_region( 0xF2000000, 0xF3000000, &p4_region_itlb_addr );
   487     sh4_register_mem_region( 0xF3000000, 0xF4000000, &p4_region_itlb_data );
   488     sh4_register_mem_region( 0xF4000000, 0xF5000000, &p4_region_ocache_addr );
   489     sh4_register_mem_region( 0xF5000000, 0xF6000000, &p4_region_ocache_data );
   490     sh4_register_mem_region( 0xF6000000, 0xF7000000, &p4_region_utlb_addr );
   491     sh4_register_mem_region( 0xF7000000, 0xF8000000, &p4_region_utlb_data );
   492     sh4_register_mem_region( 0xF8000000, 0x00000000, &mem_region_unmapped );
   494     /* Setup P4 control region */
   495     sh4_register_mem_region( 0xFF000000, 0xFF001000, &mmio_region_MMU.fn );
   496     sh4_register_mem_region( 0xFF100000, 0xFF101000, &mmio_region_PMM.fn );
   497     sh4_register_mem_region( 0xFF200000, 0xFF201000, &mmio_region_UBC.fn );
   498     sh4_register_mem_region( 0xFF800000, 0xFF801000, &mmio_region_BSC.fn );
   499     sh4_register_mem_region( 0xFF900000, 0xFFA00000, &mem_region_unmapped ); // SDMR2 + SDMR3
   500     sh4_register_mem_region( 0xFFA00000, 0xFFA01000, &mmio_region_DMAC.fn );
   501     sh4_register_mem_region( 0xFFC00000, 0xFFC01000, &mmio_region_CPG.fn );
   502     sh4_register_mem_region( 0xFFC80000, 0xFFC81000, &mmio_region_RTC.fn );
   503     sh4_register_mem_region( 0xFFD00000, 0xFFD01000, &mmio_region_INTC.fn );
   504     sh4_register_mem_region( 0xFFD80000, 0xFFD81000, &mmio_region_TMU.fn );
   505     sh4_register_mem_region( 0xFFE00000, 0xFFE01000, &mmio_region_SCI.fn );
   506     sh4_register_mem_region( 0xFFE80000, 0xFFE81000, &mmio_region_SCIF.fn );
   507     sh4_register_mem_region( 0xFFF00000, 0xFFF01000, &mem_region_unmapped ); // H-UDI    
   508 }
   510 void print_sh4mem_stats() {
   511     printf( "Decodes to p4: %d sq: %d\n", p4_count+sq_count, sq_count );
   512     printf( "Decodes to sdram: %d\n", decode_sdram );
   513     printf( "Decodes: %d Hits: %d Miss: %d\n", decode_count, hit_count, miss_count );
   514     printf( "Read long:  %d word: %d byte: %d\n", rl_count, rw_count, rb_count );
   515     printf( "Write long: %d word: %d byte: %d\n", wl_count, ww_count, wb_count );
.