revision 929:fd8cb0c82f5f
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 929:fd8cb0c82f5f |
parent | 928:bf87fbdcc9a5 |
child | 930:07e5b11419db |
author | nkeynes |
date | Sat Dec 20 03:01:40 2008 +0000 (15 years ago) |
branch | lxdream-mem |
First pass experiment using cached decoding.
1.1 --- a/src/aica/aica.c Sat Dec 20 02:53:41 2008 +00001.2 +++ b/src/aica/aica.c Sat Dec 20 03:01:40 2008 +00001.3 @@ -194,16 +194,18 @@1.4 */1.6 /* Write to channels 0-31 */1.7 -void mmio_region_AICA0_write( uint32_t reg, uint32_t val )1.8 +MMIO_REGION_WRITE_FN( AICA0, reg, val )1.9 {1.10 + reg &= 0xFFF;1.11 MMIO_WRITE( AICA0, reg, val );1.12 aica_write_channel( reg >> 7, reg % 128, val );1.13 // DEBUG( "AICA0 Write %08X => %08X", val, reg );1.14 }1.16 /* Write to channels 32-64 */1.17 -void mmio_region_AICA1_write( uint32_t reg, uint32_t val )1.18 +MMIO_REGION_WRITE_FN( AICA1, reg, val )1.19 {1.20 + reg &= 0xFFF;1.21 MMIO_WRITE( AICA1, reg, val );1.22 aica_write_channel( (reg >> 7) + 32, reg % 128, val );1.23 // DEBUG( "AICA1 Write %08X => %08X", val, reg );1.24 @@ -212,10 +214,11 @@1.25 /**1.26 * AICA control registers1.27 */1.28 -void mmio_region_AICA2_write( uint32_t reg, uint32_t val )1.29 +MMIO_REGION_WRITE_FN( AICA2, reg, val )1.30 {1.31 uint32_t tmp;1.32 -1.33 + reg &= 0xFFF;1.34 +1.35 switch( reg ) {1.36 case AICA_RESET:1.37 tmp = MMIO_READ( AICA2, AICA_RESET );1.38 @@ -241,11 +244,12 @@1.39 }1.40 }1.42 -int32_t mmio_region_AICA2_read( uint32_t reg )1.43 +MMIO_REGION_READ_FN( AICA2, reg )1.44 {1.45 audio_channel_t channel;1.46 uint32_t channo;1.47 int32_t val;1.48 + reg &= 0xFFF;1.49 switch( reg ) {1.50 case AICA_CHANSTATE:1.51 channo = (MMIO_READ( AICA2, AICA_CHANSEL ) >> 8) & 0x3F;1.52 @@ -266,9 +270,10 @@1.53 }1.54 }1.56 -int32_t mmio_region_AICARTC_read( uint32_t reg )1.57 +MMIO_REGION_READ_FN( AICARTC, reg )1.58 {1.59 int32_t rv = 0;1.60 + reg &= 0xFFF;1.61 switch( reg ) {1.62 case AICA_RTCHI:1.63 rv = (aica_state.time_of_day >> 16) & 0xFFFF;1.64 @@ -281,9 +286,9 @@1.65 return rv;1.66 }1.68 -1.69 -void mmio_region_AICARTC_write( uint32_t reg, uint32_t val )1.70 +MMIO_REGION_WRITE_FN( AICARTC, reg, val )1.71 {1.72 + reg &= 0xFFF;1.73 switch( reg ) {1.74 case AICA_RTCEN:1.75 MMIO_WRITE( AICARTC, reg, val&0x01 );
2.1 --- a/src/asic.c Sat Dec 20 02:53:41 2008 +00002.2 +++ b/src/asic.c Sat Dec 20 03:01:40 2008 +00002.3 @@ -416,8 +416,38 @@2.4 MMIO_WRITE( ASIC, SORTDMACTL, 0 );2.5 }2.7 -void mmio_region_ASIC_write( uint32_t reg, uint32_t val )2.8 +MMIO_REGION_READ_FN( ASIC, reg )2.9 {2.10 + int32_t val;2.11 + reg &= 0xFFF;2.12 + switch( reg ) {2.13 + case PIRQ0:2.14 + case PIRQ1:2.15 + case PIRQ2:2.16 + case IRQA0:2.17 + case IRQA1:2.18 + case IRQA2:2.19 + case IRQB0:2.20 + case IRQB1:2.21 + case IRQB2:2.22 + case IRQC0:2.23 + case IRQC1:2.24 + case IRQC2:2.25 + case MAPLE_STATE:2.26 + val = MMIO_READ(ASIC, reg);2.27 + return val;2.28 + case G2STATUS:2.29 + return g2_read_status();2.30 + default:2.31 + val = MMIO_READ(ASIC, reg);2.32 + return val;2.33 + }2.34 +2.35 +}2.36 +2.37 +MMIO_REGION_WRITE_FN( ASIC, reg, val )2.38 +{2.39 + reg &= 0xFFF;2.40 switch( reg ) {2.41 case PIRQ1:2.42 break; /* Treat this as read-only for the moment */2.43 @@ -496,36 +526,37 @@2.44 }2.45 }2.47 -int32_t mmio_region_ASIC_read( uint32_t reg )2.48 +MMIO_REGION_READ_FN( EXTDMA, reg )2.49 {2.50 - int32_t val;2.51 + uint32_t val;2.52 + reg &= 0xFFF;2.53 + if( !idereg.interface_enabled && IS_IDE_REGISTER(reg) ) {2.54 + return 0xFFFFFFFF; /* disabled */2.55 + }2.56 +2.57 switch( reg ) {2.58 - case PIRQ0:2.59 - case PIRQ1:2.60 - case PIRQ2:2.61 - case IRQA0:2.62 - case IRQA1:2.63 - case IRQA2:2.64 - case IRQB0:2.65 - case IRQB1:2.66 - case IRQB2:2.67 - case IRQC0:2.68 - case IRQC1:2.69 - case IRQC2:2.70 - case MAPLE_STATE:2.71 - val = MMIO_READ(ASIC, reg);2.72 - return val;2.73 - case G2STATUS:2.74 - return g2_read_status();2.75 + case IDEALTSTATUS:2.76 + val = idereg.status;2.77 + return val;2.78 + case IDEDATA: return ide_read_data_pio( );2.79 + case IDEFEAT: return idereg.error;2.80 + case IDECOUNT:return idereg.count;2.81 + case IDELBA0: return ide_get_drive_status();2.82 + case IDELBA1: return idereg.lba1;2.83 + case IDELBA2: return idereg.lba2;2.84 + case IDEDEV: return idereg.device;2.85 + case IDECMD:2.86 + val = ide_read_status();2.87 + return val;2.88 default:2.89 - val = MMIO_READ(ASIC, reg);2.90 + val = MMIO_READ( EXTDMA, reg );2.91 return val;2.92 }2.93 -2.94 }2.96 MMIO_REGION_WRITE_FN( EXTDMA, reg, val )2.97 {2.98 + reg &= 0xFFF;2.99 if( !idereg.interface_enabled && IS_IDE_REGISTER(reg) ) {2.100 return; /* disabled */2.101 }2.102 @@ -645,30 +676,3 @@2.103 }2.104 }2.106 -MMIO_REGION_READ_FN( EXTDMA, reg )2.107 -{2.108 - uint32_t val;2.109 - if( !idereg.interface_enabled && IS_IDE_REGISTER(reg) ) {2.110 - return 0xFFFFFFFF; /* disabled */2.111 - }2.112 -2.113 - switch( reg ) {2.114 - case IDEALTSTATUS:2.115 - val = idereg.status;2.116 - return val;2.117 - case IDEDATA: return ide_read_data_pio( );2.118 - case IDEFEAT: return idereg.error;2.119 - case IDECOUNT:return idereg.count;2.120 - case IDELBA0: return ide_get_drive_status();2.121 - case IDELBA1: return idereg.lba1;2.122 - case IDELBA2: return idereg.lba2;2.123 - case IDEDEV: return idereg.device;2.124 - case IDECMD:2.125 - val = ide_read_status();2.126 - return val;2.127 - default:2.128 - val = MMIO_READ( EXTDMA, reg );2.129 - return val;2.130 - }2.131 -}2.132 -
3.1 --- a/src/dreamcast.c Sat Dec 20 02:53:41 2008 +00003.2 +++ b/src/dreamcast.c Sat Dec 20 03:01:40 2008 +00003.3 @@ -58,6 +58,13 @@3.4 struct dreamcast_module unknown_module = { "****", NULL, NULL, NULL, NULL,3.5 NULL, NULL, NULL };3.7 +extern struct mem_region_fn mem_region_sdram;3.8 +extern struct mem_region_fn mem_region_vram32;3.9 +extern struct mem_region_fn mem_region_vram64;3.10 +extern struct mem_region_fn mem_region_audioram;3.11 +extern struct mem_region_fn mem_region_flashram;3.12 +extern struct mem_region_fn mem_region_bootrom;3.13 +3.14 /**3.15 * This function is responsible for defining how all the pieces of the3.16 * dreamcast actually fit together.3.17 @@ -75,12 +82,12 @@3.18 dreamcast_register_module( &mem_module );3.20 /* Setup standard memory map */3.21 - mem_create_repeating_ram_region( 0x0C000000, 16 MB, MEM_REGION_MAIN, 0x01000000, 0x0F000000 );3.22 - mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO );3.23 - mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH );3.24 - mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO );3.25 - dreamcast_has_bios = mem_load_rom( bios_path, 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS );3.26 - mem_create_ram_region( 0x00200000, 0x00020000, MEM_REGION_FLASH );3.27 + mem_create_repeating_ram_region( 0x0C000000, 16 MB, MEM_REGION_MAIN, &mem_region_sdram, 0x01000000, 0x0F000000 );3.28 + mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO, &mem_region_audioram );3.29 + mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH, NULL );3.30 + mem_create_ram_region( 0x05000000, 8 MB, MEM_REGION_VIDEO, &mem_region_vram32 );3.31 + dreamcast_has_bios = mem_load_rom( bios_path, 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS, &mem_region_bootrom );3.32 + mem_create_ram_region( 0x00200000, 0x00020000, MEM_REGION_FLASH, &mem_region_flashram );3.33 if( flash_path != NULL && flash_path[0] != '\0' ) {3.34 mem_load_block( flash_path, 0x00200000, 0x00020000 );3.35 }3.36 @@ -99,7 +106,7 @@3.37 {3.38 const char *bios_path = lxdream_get_config_value(CONFIG_BIOS_PATH);3.39 const char *flash_path = lxdream_get_config_value(CONFIG_FLASH_PATH);3.40 - dreamcast_has_bios = mem_load_rom( bios_path, 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS );3.41 + dreamcast_has_bios = mem_load_rom( bios_path, 0x00000000, 0x00200000, 0x89f2b1a1, MEM_REGION_BIOS, &mem_region_bootrom );3.42 if( flash_path != NULL && flash_path[0] != '\0' ) {3.43 mem_load_block( flash_path, 0x00200000, 0x00020000 );3.44 }3.45 @@ -120,8 +127,8 @@3.46 void dreamcast_configure_aica_only( )3.47 {3.48 dreamcast_register_module( &mem_module );3.49 - mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO );3.50 - mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH );3.51 + mem_create_ram_region( 0x00800000, 2 MB, MEM_REGION_AUDIO, &mem_region_audioram );3.52 + mem_create_ram_region( 0x00703000, 8 KB, MEM_REGION_AUDIO_SCRATCH, NULL );3.53 dreamcast_register_module( &aica_module );3.54 aica_enable();3.55 dreamcast_state = STATE_STOPPED;3.56 @@ -243,6 +250,7 @@3.57 #ifdef ENABLE_SH4STATS3.58 sh4_stats_print(stdout);3.59 #endif3.60 + print_sh4mem_stats();3.61 }3.63 void dreamcast_program_loaded( const gchar *name, sh4addr_t entry_point )
4.1 --- a/src/mem.c Sat Dec 20 02:53:41 2008 +00004.2 +++ b/src/mem.c Sat Dec 20 03:01:40 2008 +00004.3 @@ -81,7 +81,7 @@4.4 for( j=0; io_rgn[i]->ports[j].id != NULL; j++ ) {4.5 if( io_rgn[i]->ports[j].def_val != UNDEFINED &&4.6 io_rgn[i]->ports[j].def_val != *io_rgn[i]->ports[j].val ) {4.7 - io_rgn[i]->io_write( io_rgn[i]->ports[j].offset,4.8 + io_rgn[i]->fn.write_long( io_rgn[i]->ports[j].offset,4.9 io_rgn[i]->ports[j].def_val );4.10 }4.11 }4.12 @@ -225,7 +225,7 @@4.13 }4.15 struct mem_region *mem_map_region( void *mem, uint32_t base, uint32_t size,4.16 - const char *name, int flags, uint32_t repeat_offset,4.17 + const char *name, mem_region_fn_t fn, int flags, uint32_t repeat_offset,4.18 uint32_t repeat_until )4.19 {4.20 int i;4.21 @@ -234,6 +234,7 @@4.22 mem_rgn[num_mem_rgns].flags = flags;4.23 mem_rgn[num_mem_rgns].name = name;4.24 mem_rgn[num_mem_rgns].mem = mem;4.25 + mem_rgn[num_mem_rgns].fn = fn;4.26 num_mem_rgns++;4.28 do {4.29 @@ -245,12 +246,13 @@4.30 return &mem_rgn[num_mem_rgns-1];4.31 }4.33 -void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name )4.34 +void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn )4.35 {4.36 - return mem_create_repeating_ram_region( base, size, name, size, base );4.37 + return mem_create_repeating_ram_region( base, size, name, fn, size, base );4.38 }4.40 void *mem_create_repeating_ram_region( uint32_t base, uint32_t size, const char *name,4.41 + mem_region_fn_t fn,4.42 uint32_t repeat_offset, uint32_t repeat_until )4.43 {4.44 char *mem;4.45 @@ -262,13 +264,13 @@4.47 mem = mem_alloc_pages( size>>LXDREAM_PAGE_BITS );4.49 - mem_map_region( mem, base, size, name, MEM_FLAG_RAM, repeat_offset, repeat_until );4.50 + mem_map_region( mem, base, size, name, fn, MEM_FLAG_RAM, repeat_offset, repeat_until );4.52 return mem;4.53 }4.55 gboolean mem_load_rom( const gchar *file, uint32_t base, uint32_t size, uint32_t crc,4.56 - const gchar *region_name )4.57 + const gchar *region_name, mem_region_fn_t fn )4.58 {4.59 sh4ptr_t mem;4.60 uint32_t calc_crc;4.61 @@ -281,7 +283,7 @@4.62 ERROR( "Unable to allocate ROM memory: %s (%s)", file, strerror(errno) );4.63 return FALSE;4.64 }4.65 - mem_map_region( mem, base, size, region_name, MEM_FLAG_ROM, size, base );4.66 + mem_map_region( mem, base, size, region_name, fn, MEM_FLAG_ROM, size, base );4.67 } else {4.68 mprotect( mem, size, PROT_READ|PROT_WRITE );4.69 }
5.1 --- a/src/mem.h Sat Dec 20 02:53:41 2008 +00005.2 +++ b/src/mem.h Sat Dec 20 03:01:40 2008 +00005.3 @@ -27,12 +27,24 @@5.4 extern "C" {5.5 #endif5.7 +typedef struct mem_region_fn {5.8 + FASTCALL int32_t (*read_long)(sh4addr_t addr);5.9 + FASTCALL void (*write_long)(sh4addr_t addr, uint32_t val);5.10 + FASTCALL int32_t (*read_word)(sh4addr_t addr);5.11 + FASTCALL void (*write_word)(sh4addr_t addr, uint32_t val);5.12 + FASTCALL int32_t (*read_byte)(sh4addr_t addr);5.13 + FASTCALL void (*write_byte)(sh4addr_t addr, uint32_t val);5.14 + FASTCALL void (*read_burst)(unsigned char *dest, sh4addr_t addr);5.15 + FASTCALL void (*write_burst)(sh4addr_t addr, unsigned char *src);5.16 +} *mem_region_fn_t;5.17 +5.18 typedef struct mem_region {5.19 uint32_t base;5.20 uint32_t size;5.21 const char *name;5.22 sh4ptr_t mem;5.23 uint32_t flags;5.24 + mem_region_fn_t fn;5.25 } *mem_region_t;5.27 #define MAX_IO_REGIONS 245.28 @@ -45,8 +57,8 @@5.29 #define MEM_REGION_AUDIO_SCRATCH "Audio Scratch RAM"5.30 #define MEM_REGION_FLASH "System Flash"5.32 -void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name );5.33 -void *mem_create_repeating_ram_region( uint32_t base, uint32_t size, const char *name,5.34 +void *mem_create_ram_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn );5.35 +void *mem_create_repeating_ram_region( uint32_t base, uint32_t size, const char *name, mem_region_fn_t fn,5.36 uint32_t repeat_offset, uint32_t last_repeat );5.37 /**5.38 * Load a ROM image from the specified filename. If the memory region has not5.39 @@ -55,7 +67,7 @@5.40 * @return TRUE if the image was loaded successfully (irrespective of CRC failure).5.41 */5.42 gboolean mem_load_rom( const gchar *filename, uint32_t base, uint32_t size,5.43 - uint32_t crc, const gchar *region_name );5.44 + uint32_t crc, const gchar *region_name, mem_region_fn_t fn );5.45 void *mem_alloc_pages( int n );5.46 sh4ptr_t mem_get_region( uint32_t addr );5.47 sh4ptr_t mem_get_region_by_name( const char *name );
6.1 --- a/src/mmio.h Sat Dec 20 02:53:41 2008 +00006.2 +++ b/src/mmio.h Sat Dec 20 03:01:40 2008 +00006.3 @@ -16,8 +16,8 @@6.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the6.5 * GNU General Public License for more details.6.6 */6.7 -#ifndef dream_mmio_H6.8 -#define dream_mmio_H 16.9 +#ifndef lxdream_mmio_H6.10 +#define lxdream_mmio_H 16.12 #ifdef __cplusplus6.13 extern "C" {6.14 @@ -28,6 +28,7 @@6.16 #include <stdint.h>6.17 #include <stdlib.h>6.18 +#include "mem.h"6.20 #define LXDREAM_PAGE_TABLE_ENTRIES 128*10246.21 #define LXDREAM_PAGE_SIZE 40966.22 @@ -45,8 +46,7 @@6.23 struct mmio_region {6.24 char *id, *desc;6.25 uint32_t base;6.26 - int32_t (*io_read)(uint32_t addr);6.27 - void (*io_write)(uint32_t addr, uint32_t val);6.28 + struct mem_region_fn fn;6.29 char *mem;6.30 char *save_mem; /* Used to compare for gui updates */6.31 struct mmio_port {6.32 @@ -112,7 +112,7 @@6.33 #undef MMIO_REGION_LIST_BEGIN6.34 #undef MMIO_REGION6.35 #undef MMIO_REGION_LIST_END6.36 -#define MMIO_REGION_BEGIN(b,id,d) struct mmio_region mmio_region_##id = { #id, d, b, mmio_region_##id##_read, mmio_region_##id##_write, 0, 0, {6.37 +#define MMIO_REGION_BEGIN(b,id,d) struct mmio_region mmio_region_##id = { #id, d, b, {mmio_region_##id##_read, mmio_region_##id##_write,mmio_region_##id##_read, mmio_region_##id##_write,mmio_region_##id##_read, mmio_region_##id##_write,NULL, NULL}, 0, 0, {6.38 #define LONG_PORT( o,id,f,def,d ) { #id, d, 32, o, def, f },6.39 #define WORD_PORT( o,id,f,def,d ) { #id, d, 16, o, def, f },6.40 #define BYTE_PORT( o,id,f,def,d ) { #id, d, 8, o, def, f },6.41 @@ -125,14 +125,16 @@6.42 * actually need any direct code on read and/or write6.43 */6.44 #define MMIO_REGION_READ_STUBFN( id ) \6.45 -int32_t mmio_region_##id##_read( uint32_t reg ) { \6.46 +int32_t FASTCALL mmio_region_##id##_read( uint32_t reg ) { \6.47 + reg = reg & 0xFFF; \6.48 int32_t val = MMIO_READ( id, reg ); \6.49 WARN( "Read from unimplemented module %s (%03X => %08X) [%s: %s]",\6.50 #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \6.51 return val; \6.52 }6.53 #define MMIO_REGION_WRITE_STUBFN( id ) \6.54 -void mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \6.55 +void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \6.56 + reg = reg & 0xFFF; \6.57 WARN( "Write to unimplemented module %s (%03X <= %08X) [%s: %s]", \6.58 #id, reg, val, MMIO_REGID(id,reg), MMIO_REGDESC(id,reg) ); \6.59 MMIO_WRITE( id, reg, val ); \6.60 @@ -141,32 +143,26 @@6.61 MMIO_REGION_READ_STUBFN( id ) \6.62 MMIO_REGION_WRITE_STUBFN( id )6.63 #define MMIO_REGION_READ_DEFFN( id ) \6.64 -int32_t mmio_region_##id##_read( uint32_t reg ) { \6.65 - return MMIO_READ( id, reg ); \6.66 +int32_t FASTCALL mmio_region_##id##_read( uint32_t reg ) { \6.67 + return MMIO_READ( id, reg&0xFFF ); \6.68 }6.69 #define MMIO_REGION_WRITE_DEFFN( id ) \6.70 -void mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \6.71 - MMIO_WRITE( id, reg, val ); \6.72 +void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val ) { \6.73 + MMIO_WRITE( id, reg&0xFFF, val ); \6.74 }6.75 #define MMIO_REGION_DEFFNS( id ) \6.76 MMIO_REGION_READ_DEFFN( id ) \6.77 MMIO_REGION_WRITE_DEFFN( id )6.78 #endif6.80 -#define MMIO_REGION_WRITE_FN( id, reg, val ) \6.81 -void mmio_region_##id##_write( uint32_t reg, uint32_t val )6.82 -6.83 -#define MMIO_REGION_READ_FN( id, reg ) \6.84 -int32_t mmio_region_##id##_read( uint32_t reg )6.85 -6.86 #else6.88 #ifndef MMIO_IFACE_INCLUDED6.89 #define MMIO_IFACE_INCLUDED6.90 #define MMIO_REGION_BEGIN(b,id,d) \6.91 extern struct mmio_region mmio_region_##id; \6.92 -int32_t mmio_region_##id##_read(uint32_t); \6.93 -void mmio_region_##id##_write(uint32_t, uint32_t); \6.94 +int32_t FASTCALL mmio_region_##id##_read(uint32_t); \6.95 +void FASTCALL mmio_region_##id##_write(uint32_t, uint32_t); \6.96 enum mmio_region_##id##_port_t {6.97 #define LONG_PORT( o,id,f,def,d ) id = o,6.98 #define WORD_PORT( o,id,f,def,d ) id = o,6.99 @@ -177,5 +173,12 @@6.100 #define MMIO_REGION_LIST_END6.101 #endif6.103 +#define MMIO_REGION_WRITE_FN( id, reg, val ) \6.104 +void FASTCALL mmio_region_##id##_write( uint32_t reg, uint32_t val )6.105 +6.106 +#define MMIO_REGION_READ_FN( id, reg ) \6.107 +int32_t FASTCALL mmio_region_##id##_read( uint32_t reg )6.108 +6.109 +6.110 #endif
7.1 --- a/src/pvr2/pvr2.c Sat Dec 20 02:53:41 2008 +00007.2 +++ b/src/pvr2/pvr2.c Sat Dec 20 03:01:40 2008 +00007.3 @@ -462,8 +462,9 @@7.4 * This has to handle every single register individually as they all get masked7.5 * off differently (and its easier to do it at write time)7.6 */7.7 -void mmio_region_PVR2_write( uint32_t reg, uint32_t val )7.8 +MMIO_REGION_WRITE_FN( PVR2, reg, val )7.9 {7.10 + reg &= 0xFFF;7.11 if( reg >= 0x200 && reg < 0x600 ) { /* Fog table */7.12 MMIO_WRITE( PVR2, reg, val );7.13 return;7.14 @@ -826,6 +827,7 @@7.16 MMIO_REGION_READ_FN( PVR2, reg )7.17 {7.18 + reg &= 0xFFF;7.19 switch( reg ) {7.20 case DISP_SYNCSTAT:7.21 return pvr2_get_sync_status();7.22 @@ -836,6 +838,7 @@7.24 MMIO_REGION_WRITE_FN( PVR2PAL, reg, val )7.25 {7.26 + reg &= 0xFFF;7.27 MMIO_WRITE( PVR2PAL, reg, val );7.28 pvr2_state.palette_changed = TRUE;7.29 }7.30 @@ -858,12 +861,12 @@7.34 -int32_t mmio_region_PVR2TA_read( uint32_t reg )7.35 +MMIO_REGION_READ_FN( PVR2TA, reg )7.36 {7.37 return 0xFFFFFFFF;7.38 }7.40 -void mmio_region_PVR2TA_write( uint32_t reg, uint32_t val )7.41 +MMIO_REGION_WRITE_FN( PVR2TA, reg, val )7.42 {7.43 pvr2_ta_write( (unsigned char *)&val, sizeof(uint32_t) );7.44 }
8.1 --- a/src/pvr2/pvr2mem.c Sat Dec 20 02:53:41 2008 +00008.2 +++ b/src/pvr2/pvr2mem.c Sat Dec 20 03:01:40 2008 +00008.3 @@ -18,12 +18,122 @@8.4 #include <string.h>8.5 #include <stdio.h>8.6 #include <errno.h>8.7 +#include "sh4/sh4core.h"8.8 #include "pvr2.h"8.9 #include "asic.h"8.10 #include "dream.h"8.12 extern unsigned char *video_base;8.14 +/************************* VRAM32 address space ***************************/8.15 +8.16 +static int32_t FASTCALL pvr2_vram32_read_long( sh4addr_t addr )8.17 +{8.18 + pvr2_render_buffer_invalidate(addr, FALSE);8.19 + return *((int32_t *)(video_base+(addr&0x007FFFFF)));8.20 +}8.21 +static int32_t FASTCALL pvr2_vram32_read_word( sh4addr_t addr )8.22 +{8.23 + pvr2_render_buffer_invalidate(addr, FALSE);8.24 + return SIGNEXT16(*((int16_t *)(video_base+(addr&0x007FFFFF))));8.25 +}8.26 +static int32_t FASTCALL pvr2_vram32_read_byte( sh4addr_t addr )8.27 +{8.28 + pvr2_render_buffer_invalidate(addr, FALSE);8.29 + return SIGNEXT8(*((int8_t *)(video_base+(addr&0x007FFFFF))));8.30 +}8.31 +static void FASTCALL pvr2_vram32_write_long( sh4addr_t addr, uint32_t val )8.32 +{8.33 + pvr2_render_buffer_invalidate(addr, TRUE);8.34 + *(uint32_t *)(video_base + (addr&0x007FFFFF)) = val;8.35 +}8.36 +static void FASTCALL pvr2_vram32_write_word( sh4addr_t addr, uint32_t val )8.37 +{8.38 + pvr2_render_buffer_invalidate(addr, TRUE);8.39 + *(uint16_t *)(video_base + (addr&0x007FFFFF)) = (uint16_t)val;8.40 +}8.41 +static void FASTCALL pvr2_vram32_write_byte( sh4addr_t addr, uint32_t val )8.42 +{8.43 + pvr2_render_buffer_invalidate(addr, TRUE);8.44 + *(uint8_t *)(video_base + (addr&0x007FFFFF)) = (uint8_t)val;8.45 +}8.46 +static void FASTCALL pvr2_vram32_read_burst( unsigned char *dest, sh4addr_t addr )8.47 +{8.48 + // Render buffers pretty much have to be (at least) 32-byte aligned8.49 + pvr2_render_buffer_invalidate(addr, FALSE);8.50 + memcpy( dest, (video_base + (addr&0x007FFFFF)), 32 );8.51 +}8.52 +static void FASTCALL pvr2_vram32_write_burst( sh4addr_t addr, unsigned char *src )8.53 +{8.54 + // Render buffers pretty much have to be (at least) 32-byte aligned8.55 + pvr2_render_buffer_invalidate(addr, TRUE);8.56 + memcpy( (video_base + (addr&0x007FFFFF)), src, 32 );8.57 +}8.58 +8.59 +struct mem_region_fn mem_region_vram32 = { pvr2_vram32_read_long, pvr2_vram32_write_long,8.60 + pvr2_vram32_read_word, pvr2_vram32_write_word,8.61 + pvr2_vram32_read_byte, pvr2_vram32_write_byte,8.62 + pvr2_vram32_read_burst, pvr2_vram32_write_burst };8.63 +8.64 +/************************* VRAM64 address space ***************************/8.65 +8.66 +#define TRANSLATE_VIDEO_64BIT_ADDRESS(a) ( (((a)&0x00FFFFF8)>>1)|(((a)&0x00000004)<<20)|((a)&0x03) )8.67 +8.68 +static int32_t FASTCALL pvr2_vram64_read_long( sh4addr_t addr )8.69 +{8.70 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.71 + pvr2_render_buffer_invalidate(addr, FALSE);8.72 + return *((int32_t *)(video_base+(addr&0x007FFFFF)));8.73 +}8.74 +static int32_t FASTCALL pvr2_vram64_read_word( sh4addr_t addr )8.75 +{8.76 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.77 + pvr2_render_buffer_invalidate(addr, FALSE);8.78 + return SIGNEXT16(*((int16_t *)(video_base+(addr&0x007FFFFF))));8.79 +}8.80 +static int32_t FASTCALL pvr2_vram64_read_byte( sh4addr_t addr )8.81 +{8.82 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.83 + pvr2_render_buffer_invalidate(addr, FALSE);8.84 + return SIGNEXT8(*((int8_t *)(video_base+(addr&0x007FFFFF))));8.85 +}8.86 +static void FASTCALL pvr2_vram64_write_long( sh4addr_t addr, uint32_t val )8.87 +{8.88 + texcache_invalidate_page(addr& 0x007FFFFF);8.89 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.90 + pvr2_render_buffer_invalidate(addr, TRUE);8.91 + *(uint32_t *)(video_base + (addr&0x007FFFFF)) = val;8.92 +}8.93 +static void FASTCALL pvr2_vram64_write_word( sh4addr_t addr, uint32_t val )8.94 +{8.95 + texcache_invalidate_page(addr& 0x007FFFFF);8.96 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.97 + pvr2_render_buffer_invalidate(addr, TRUE);8.98 + *(uint16_t *)(video_base + (addr&0x007FFFFF)) = (uint16_t)val;8.99 +}8.100 +static void FASTCALL pvr2_vram64_write_byte( sh4addr_t addr, uint32_t val )8.101 +{8.102 + texcache_invalidate_page(addr& 0x007FFFFF);8.103 + addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);8.104 + pvr2_render_buffer_invalidate(addr, TRUE);8.105 + *(uint8_t *)(video_base + (addr&0x007FFFFF)) = (uint8_t)val;8.106 +}8.107 +static void FASTCALL pvr2_vram64_read_burst( unsigned char *dest, sh4addr_t addr )8.108 +{8.109 + pvr2_vram64_read( dest, addr, 32 );8.110 +}8.111 +static void FASTCALL pvr2_vram64_write_burst( sh4addr_t addr, unsigned char *src )8.112 +{8.113 + pvr2_vram64_write( addr, src, 32 );8.114 +}8.115 +8.116 +struct mem_region_fn mem_region_vram64 = { pvr2_vram64_read_long, pvr2_vram64_write_long,8.117 + pvr2_vram64_read_word, pvr2_vram64_write_word,8.118 + pvr2_vram64_read_byte, pvr2_vram64_write_byte,8.119 + pvr2_vram64_read_burst, pvr2_vram64_write_burst };8.120 +8.121 +8.122 +8.123 void pvr2_dma_write( sh4addr_t destaddr, unsigned char *src, uint32_t count )8.124 {8.125 int region;
9.1 --- a/src/sh4/dmac.c Sat Dec 20 02:53:41 2008 +00009.2 +++ b/src/sh4/dmac.c Sat Dec 20 03:01:40 2008 +00009.3 @@ -82,13 +82,14 @@9.4 */9.5 }9.7 -int32_t mmio_region_DMAC_read( uint32_t reg )9.8 +MMIO_REGION_READ_FN( DMAC, reg )9.9 {9.10 - return MMIO_READ( DMAC, reg );9.11 + return MMIO_READ( DMAC, reg&0xFFF );9.12 }9.14 -void mmio_region_DMAC_write( uint32_t reg, uint32_t val )9.15 +MMIO_REGION_WRITE_FN( DMAC, reg, val )9.16 {9.17 + reg &= 0xFFF;9.18 switch( reg ) {9.19 case DMAOR:9.20 MMIO_WRITE( DMAC, reg, val );
10.1 --- a/src/sh4/ia32abi.h Sat Dec 20 02:53:41 2008 +000010.2 +++ b/src/sh4/ia32abi.h Sat Dec 20 03:01:40 2008 +000010.3 @@ -42,6 +42,22 @@10.4 CALL_ptr(ptr);10.5 }10.7 +static inline void call_func1_r32( int addr_reg, int arg1 )10.8 +{10.9 + if( arg1 != R_EAX ) {10.10 + MOV_r32_r32( arg1, R_EAX );10.11 + }10.12 + CALL_r32(addr_reg);10.13 +}10.14 +10.15 +static inline void call_func1_r32ind( int preg, uint32_t disp32, int arg1 )10.16 +{10.17 + if( arg1 != R_EAX ) {10.18 + MOV_r32_r32( arg1, R_EAX );10.19 + }10.20 + CALL_r32ind(preg, disp32);10.21 +}10.22 +10.23 static inline void call_func2( void *ptr, int arg1, int arg2 )10.24 {10.25 if( arg2 != R_EDX ) {10.26 @@ -53,6 +69,30 @@10.27 CALL_ptr(ptr);10.28 }10.30 +static inline void call_func2_r32( int addr_reg, int arg1, int arg2 )10.31 +{10.32 + if( arg2 != R_EDX ) {10.33 + MOV_r32_r32( arg2, R_EDX );10.34 + }10.35 + if( arg1 != R_EAX ) {10.36 + MOV_r32_r32( arg1, R_EAX );10.37 + }10.38 + CALL_r32(addr_reg);10.39 +}10.40 +10.41 +static inline void call_func2_r32ind( int preg, uint32_t disp32, int arg1, int arg2 )10.42 +{10.43 + if( arg2 != R_EDX ) {10.44 + MOV_r32_r32( arg2, R_EDX );10.45 + }10.46 + if( arg1 != R_EAX ) {10.47 + MOV_r32_r32( arg1, R_EAX );10.48 + }10.49 + CALL_r32ind(preg, disp32);10.50 +}10.51 +10.52 +10.53 +10.54 static inline void call_func1_exc( void *ptr, int arg1, int pc )10.55 {10.56 if( arg1 != R_EAX ) {10.57 @@ -174,12 +214,14 @@10.58 {10.59 PUSH_r32(R_EBP);10.60 load_ptr( R_EBP, ((uint8_t *)&sh4r) + 128 );10.61 - SUB_imm8s_r32( 8, R_ESP );10.62 + PUSH_r32(R_EBX);10.63 + SUB_imm8s_r32( 4, R_ESP );10.64 }10.66 static inline void exit_block( )10.67 {10.68 - ADD_imm8s_r32( 8, R_ESP );10.69 + ADD_imm8s_r32( 4, R_ESP );10.70 + POP_r32(R_EBX);10.71 POP_r32(R_EBP);10.72 RET();10.73 }
11.1 --- a/src/sh4/intc.c Sat Dec 20 02:53:41 2008 +000011.2 +++ b/src/sh4/intc.c Sat Dec 20 03:01:40 2008 +000011.3 @@ -53,8 +53,9 @@11.4 int priority[INT_NUM_SOURCES];11.5 } intc_state;11.7 -void mmio_region_INTC_write( uint32_t reg, uint32_t val )11.8 +MMIO_REGION_WRITE_FN( INTC, reg, val )11.9 {11.10 + reg &= 0xFFF;11.11 /* Well it saves having to use an intermediate table... */11.12 switch( reg ) {11.13 case ICR: /* care about this later */11.14 @@ -95,9 +96,9 @@11.15 MMIO_WRITE( INTC, reg, val );11.16 }11.18 -int32_t mmio_region_INTC_read( uint32_t reg )11.19 +MMIO_REGION_READ_FN( INTC, reg )11.20 {11.21 - return MMIO_READ( INTC, reg );11.22 + return MMIO_READ( INTC, reg & 0xFFF );11.23 }11.25 void INTC_reset()
12.1 --- a/src/sh4/mmu.c Sat Dec 20 02:53:41 2008 +000012.2 +++ b/src/sh4/mmu.c Sat Dec 20 03:01:40 2008 +000012.3 @@ -143,8 +143,9 @@12.4 }12.5 }12.7 -int32_t mmio_region_MMU_read( uint32_t reg )12.8 +MMIO_REGION_READ_FN( MMU, reg )12.9 {12.10 + reg &= 0xFFF;12.11 switch( reg ) {12.12 case MMUCR:12.13 return MMIO_READ( MMU, MMUCR) | (mmu_urc<<10) | (mmu_urb<<18) | (mmu_lrui<<26);12.14 @@ -153,9 +154,10 @@12.15 }12.16 }12.18 -void mmio_region_MMU_write( uint32_t reg, uint32_t val )12.19 +MMIO_REGION_WRITE_FN( MMU, reg, val )12.20 {12.21 uint32_t tmp;12.22 + reg &= 0xFFF;12.23 switch(reg) {12.24 case SH4VER:12.25 return;12.26 @@ -448,18 +450,18 @@12.28 #define ITLB_ENTRY(addr) ((addr>>7)&0x03)12.30 -int32_t mmu_itlb_addr_read( sh4addr_t addr )12.31 +int32_t FASTCALL mmu_itlb_addr_read( sh4addr_t addr )12.32 {12.33 struct itlb_entry *ent = &mmu_itlb[ITLB_ENTRY(addr)];12.34 return ent->vpn | ent->asid | (ent->flags & TLB_VALID);12.35 }12.36 -int32_t mmu_itlb_data_read( sh4addr_t addr )12.37 +int32_t FASTCALL mmu_itlb_data_read( sh4addr_t addr )12.38 {12.39 struct itlb_entry *ent = &mmu_itlb[ITLB_ENTRY(addr)];12.40 return (ent->ppn & 0x1FFFFC00) | ent->flags;12.41 }12.43 -void mmu_itlb_addr_write( sh4addr_t addr, uint32_t val )12.44 +void FASTCALL mmu_itlb_addr_write( sh4addr_t addr, uint32_t val )12.45 {12.46 struct itlb_entry *ent = &mmu_itlb[ITLB_ENTRY(addr)];12.47 ent->vpn = val & 0xFFFFFC00;12.48 @@ -467,7 +469,7 @@12.49 ent->flags = (ent->flags & ~(TLB_VALID)) | (val&TLB_VALID);12.50 }12.52 -void mmu_itlb_data_write( sh4addr_t addr, uint32_t val )12.53 +void FASTCALL mmu_itlb_data_write( sh4addr_t addr, uint32_t val )12.54 {12.55 struct itlb_entry *ent = &mmu_itlb[ITLB_ENTRY(addr)];12.56 ent->ppn = val & 0x1FFFFC00;12.57 @@ -481,13 +483,13 @@12.58 #define UTLB_ASSOC(addr) (addr&0x80)12.59 #define UTLB_DATA2(addr) (addr&0x00800000)12.61 -int32_t mmu_utlb_addr_read( sh4addr_t addr )12.62 +int32_t FASTCALL mmu_utlb_addr_read( sh4addr_t addr )12.63 {12.64 struct utlb_entry *ent = &mmu_utlb[UTLB_ENTRY(addr)];12.65 return ent->vpn | ent->asid | (ent->flags & TLB_VALID) |12.66 ((ent->flags & TLB_DIRTY)<<7);12.67 }12.68 -int32_t mmu_utlb_data_read( sh4addr_t addr )12.69 +int32_t FASTCALL mmu_utlb_data_read( sh4addr_t addr )12.70 {12.71 struct utlb_entry *ent = &mmu_utlb[UTLB_ENTRY(addr)];12.72 if( UTLB_DATA2(addr) ) {12.73 @@ -540,7 +542,7 @@12.74 return result;12.75 }12.77 -void mmu_utlb_addr_write( sh4addr_t addr, uint32_t val )12.78 +void FASTCALL mmu_utlb_addr_write( sh4addr_t addr, uint32_t val )12.79 {12.80 if( UTLB_ASSOC(addr) ) {12.81 int utlb = mmu_utlb_lookup_assoc( val, mmu_asid );12.82 @@ -581,7 +583,7 @@12.83 }12.84 }12.86 -void mmu_utlb_data_write( sh4addr_t addr, uint32_t val )12.87 +void FASTCALL mmu_utlb_data_write( sh4addr_t addr, uint32_t val )12.88 {12.89 struct utlb_entry *ent = &mmu_utlb[UTLB_ENTRY(addr)];12.90 if( UTLB_DATA2(addr) ) {12.91 @@ -601,36 +603,36 @@12.93 /* Cache access - not implemented */12.95 -int32_t mmu_icache_addr_read( sh4addr_t addr )12.96 +int32_t FASTCALL mmu_icache_addr_read( sh4addr_t addr )12.97 {12.98 return 0; // not implemented12.99 }12.100 -int32_t mmu_icache_data_read( sh4addr_t addr )12.101 +int32_t FASTCALL mmu_icache_data_read( sh4addr_t addr )12.102 {12.103 return 0; // not implemented12.104 }12.105 -int32_t mmu_ocache_addr_read( sh4addr_t addr )12.106 +int32_t FASTCALL mmu_ocache_addr_read( sh4addr_t addr )12.107 {12.108 return 0; // not implemented12.109 }12.110 -int32_t mmu_ocache_data_read( sh4addr_t addr )12.111 +int32_t FASTCALL mmu_ocache_data_read( sh4addr_t addr )12.112 {12.113 return 0; // not implemented12.114 }12.116 -void mmu_icache_addr_write( sh4addr_t addr, uint32_t val )12.117 +void FASTCALL mmu_icache_addr_write( sh4addr_t addr, uint32_t val )12.118 {12.119 }12.121 -void mmu_icache_data_write( sh4addr_t addr, uint32_t val )12.122 +void FASTCALL mmu_icache_data_write( sh4addr_t addr, uint32_t val )12.123 {12.124 }12.126 -void mmu_ocache_addr_write( sh4addr_t addr, uint32_t val )12.127 +void FASTCALL mmu_ocache_addr_write( sh4addr_t addr, uint32_t val )12.128 {12.129 }12.131 -void mmu_ocache_data_write( sh4addr_t addr, uint32_t val )12.132 +void FASTCALL mmu_ocache_data_write( sh4addr_t addr, uint32_t val )12.133 {12.134 }
13.1 --- a/src/sh4/pmm.c Sat Dec 20 02:53:41 2008 +000013.2 +++ b/src/sh4/pmm.c Sat Dec 20 03:01:40 2008 +000013.3 @@ -131,8 +131,8 @@13.4 }13.5 }13.7 -int32_t mmio_region_PMM_read( uint32_t reg )13.8 -{13.9 +MMIO_REGION_READ_FN( PMM, reg )13.10 +{13.11 switch( reg & 0x1F ) {13.12 case 0: return 0; /* not a register */13.13 case PMCTR1H:13.14 @@ -150,7 +150,7 @@13.15 }13.16 }13.18 -void mmio_region_PMM_write( uint32_t reg, uint32_t val )13.19 +MMIO_REGION_WRITE_FN( PMM, reg, val )13.20 {13.21 /* Read-only */13.22 }
14.1 --- a/src/sh4/scif.c Sat Dec 20 02:53:41 2008 +000014.2 +++ b/src/sh4/scif.c Sat Dec 20 03:01:40 2008 +000014.3 @@ -455,8 +455,9 @@14.4 }14.5 }14.7 -int32_t mmio_region_SCIF_read( uint32_t reg )14.8 +MMIO_REGION_READ_FN( SCIF, reg )14.9 {14.10 + reg &= 0xFFF;14.11 switch( reg ) {14.12 case SCFRDR2: /* Receive data */14.13 return SCIF_recvq_dequeue(FALSE);14.14 @@ -465,9 +466,10 @@14.15 }14.16 }14.18 -void mmio_region_SCIF_write( uint32_t reg, uint32_t val )14.19 +MMIO_REGION_WRITE_FN( SCIF, reg, val )14.20 {14.21 uint32_t tmp;14.22 + reg &= 0xFFF;14.23 switch( reg ) {14.24 case SCSMR2: /* Serial mode register */14.25 /* Bit 6 => 0 = 8-bit, 1 = 7-bit
15.1 --- a/src/sh4/sh4.c Sat Dec 20 02:53:41 2008 +000015.2 +++ b/src/sh4/sh4.c Sat Dec 20 03:01:40 2008 +000015.3 @@ -41,6 +41,7 @@15.4 void sh4_stop( void );15.5 void sh4_save_state( FILE *f );15.6 int sh4_load_state( FILE *f );15.7 +static void sh4_reset_pointer_cache();15.9 uint32_t sh4_run_slice( uint32_t );15.10 uint32_t sh4_xlat_run_slice( uint32_t );15.11 @@ -53,6 +54,10 @@15.12 struct breakpoint_struct sh4_breakpoints[MAX_BREAKPOINTS];15.13 int sh4_breakpoint_count = 0;15.14 sh4ptr_t sh4_main_ram;15.15 +sh4ptr_t dc_boot_rom;15.16 +sh4ptr_t dc_flash_ram;15.17 +sh4ptr_t dc_audio_ram;15.18 +15.19 gboolean sh4_starting = FALSE;15.20 static gboolean sh4_use_translator = FALSE;15.21 static jmp_buf sh4_exit_jmp_buf;15.22 @@ -80,6 +85,9 @@15.23 {15.24 register_io_regions( mmio_list_sh4mmio );15.25 sh4_main_ram = mem_get_region_by_name(MEM_REGION_MAIN);15.26 + dc_boot_rom = mem_get_region_by_name(MEM_REGION_BIOS);15.27 + dc_flash_ram = mem_get_region_by_name(MEM_REGION_FLASH);15.28 + dc_audio_ram = mem_get_region_by_name(MEM_REGION_AUDIO);15.29 MMU_init();15.30 TMU_init();15.31 sh4_reset();15.32 @@ -101,6 +109,7 @@15.34 /* zero everything out, for the sake of having a consistent state. */15.35 memset( &sh4r, 0, sizeof(sh4r) );15.36 + sh4_reset_pointer_cache();15.38 /* Resume running if we were halted */15.39 sh4r.sh4_state = SH4_STATE_RUNNING;15.40 @@ -234,7 +243,8 @@15.41 sh4r.in_delay_slot = FALSE;15.42 }15.44 - fwrite( &sh4r, sizeof(sh4r), 1, f );15.45 + int len = ((char *)&sh4r.pointer_cache) - ((char *)&sh4r);15.46 + fwrite( &sh4r, len, 1, f );15.47 MMU_save_state( f );15.48 PMM_save_state( f );15.49 INTC_save_state( f );15.50 @@ -247,7 +257,9 @@15.51 if( sh4_use_translator ) {15.52 xlat_flush_cache();15.53 }15.54 - fread( &sh4r, sizeof(sh4r), 1, f );15.55 + int len = ((char *)&sh4r.pointer_cache) - ((char *)&sh4r);15.56 + fread( &sh4r, len, 1, f );15.57 + sh4_reset_pointer_cache();15.58 MMU_load_state( f );15.59 PMM_load_state( f );15.60 INTC_load_state( f );15.61 @@ -255,6 +267,16 @@15.62 return SCIF_load_state( f );15.63 }15.65 +static void sh4_reset_pointer_cache()15.66 +{15.67 + int i;15.68 + for( i=0; i<16; i++ ) {15.69 + sh4r.pointer_cache[i].page_vma = -1;15.70 + sh4r.pointer_cache[i].page_mask = 0xFFFFF000;15.71 + }15.72 + sh4r.pointer_cache[16].page_vma = -1;15.73 + sh4r.pointer_cache[16].page_mask = 0xFFFFF000;15.74 +}15.76 void sh4_set_breakpoint( uint32_t pc, breakpoint_type_t type )15.77 {
16.1 --- a/src/sh4/sh4.h Sat Dec 20 02:53:41 2008 +000016.2 +++ b/src/sh4/sh4.h Sat Dec 20 03:01:40 2008 +000016.3 @@ -87,6 +87,13 @@16.4 * a delay slot (certain rules apply) */16.5 uint32_t slice_cycle; /* Current nanosecond within the timeslice */16.6 int sh4_state; /* Current power-on state (one of the SH4_STATE_* values ) */16.7 +16.8 + /* lxdream cache structures below this point */16.9 + struct {16.10 + uint32_t page_vma;16.11 + uint32_t page_mask;16.12 + struct mem_region_fn *page_fn;16.13 + } pointer_cache[17];16.14 };16.16 extern struct sh4_registers sh4r;
17.1 --- a/src/sh4/sh4core.h Sat Dec 20 02:53:41 2008 +000017.2 +++ b/src/sh4/sh4core.h Sat Dec 20 03:01:40 2008 +000017.3 @@ -170,6 +170,8 @@17.4 uint32_t sh4_emulate_run_slice(uint32_t);17.6 /* SH4 instruction support methods */17.7 +mem_region_fn_t FASTCALL sh7750_decode_address( sh4addr_t address );17.8 +void FASTCALL sh7750_decode_address_copy( sh4addr_t address, mem_region_fn_t result );17.9 void FASTCALL sh4_sleep( void );17.10 void FASTCALL sh4_fsca( uint32_t angle, float *fr );17.11 void FASTCALL sh4_ftrv( float *fv );
18.1 --- a/src/sh4/sh4mem.c Sat Dec 20 02:53:41 2008 +000018.2 +++ b/src/sh4/sh4mem.c Sat Dec 20 03:01:40 2008 +000018.3 @@ -1,7 +1,6 @@18.4 /**18.5 * $Id$18.6 - * sh4mem.c is responsible for the SH4's access to memory (including memory18.7 - * mapped I/O), using the page maps created in mem.c18.8 + * sh4mem.c is responsible for interfacing between the SH4's internal memory18.9 *18.10 * Copyright (c) 2005 Nathan Keynes.18.11 *18.12 @@ -28,375 +27,354 @@18.13 #include "sh4/sh4mmio.h"18.14 #include "sh4/xltcache.h"18.15 #include "pvr2/pvr2.h"18.16 -#include "asic.h"18.18 -#define OC_BASE 0x1C00000018.19 -#define OC_TOP 0x2000000018.20 +/* System regions (probably should be defined elsewhere) */18.21 +extern struct mem_region_fn mem_region_unmapped;18.22 +extern struct mem_region_fn mem_region_sdram;18.23 +extern struct mem_region_fn mem_region_vram32;18.24 +extern struct mem_region_fn mem_region_vram64;18.25 +extern struct mem_region_fn mem_region_audioram;18.26 +extern struct mem_region_fn mem_region_flashram;18.27 +extern struct mem_region_fn mem_region_bootrom;18.29 -#define TRANSLATE_VIDEO_64BIT_ADDRESS(a) ( (((a)&0x00FFFFF8)>>1)|(((a)&0x00000004)<<20)|((a)&0x03)|0x05000000 )18.30 +/* On-chip regions other than defined MMIO regions */18.31 +extern struct mem_region_fn mem_region_storequeue;18.32 +extern struct mem_region_fn mem_region_icache_addr;18.33 +extern struct mem_region_fn mem_region_icache_data;18.34 +extern struct mem_region_fn mem_region_ocache_addr;18.35 +extern struct mem_region_fn mem_region_ocache_data;18.36 +extern struct mem_region_fn mem_region_itlb_addr;18.37 +extern struct mem_region_fn mem_region_itlb_data;18.38 +extern struct mem_region_fn mem_region_utlb_addr;18.39 +extern struct mem_region_fn mem_region_utlb_data;18.41 -#ifdef ENABLE_WATCH18.42 -#define CHECK_READ_WATCH( addr, size ) \18.43 - if( mem_is_watched(addr,size,WATCH_READ) != NULL ) { \18.44 - WARN( "Watch triggered at %08X by %d byte read", addr, size ); \18.45 - sh4_core_exit(CORE_EXIT_HALT); \18.46 - }18.47 -#define CHECK_WRITE_WATCH( addr, size, val ) \18.48 - if( mem_is_watched(addr,size,WATCH_WRITE) != NULL ) { \18.49 - WARN( "Watch triggered at %08X by %d byte write <= %0*X", addr, size, size*2, val ); \18.50 - sh4_core_exit(CORE_EXIT_HALT); \18.51 - }18.52 +extern struct mmio_region *P4_io[];18.53 +18.54 +/********************* The "unmapped" address space ********************/18.55 +/* Always reads as 0, writes have no effect */18.56 +static int32_t FASTCALL unmapped_read_long( sh4addr_t addr )18.57 +{18.58 + return 0;18.59 +}18.60 +static void FASTCALL unmapped_write_long( sh4addr_t addr, uint32_t val )18.61 +{18.62 +}18.63 +static void FASTCALL unmapped_read_burst( unsigned char *dest, sh4addr_t addr )18.64 +{18.65 + memset( dest, 0, 32 );18.66 +}18.67 +static void FASTCALL unmapped_write_burst( sh4addr_t addr, unsigned char *src )18.68 +{18.69 +}18.70 +18.71 +struct mem_region_fn mem_region_unmapped = {18.72 + unmapped_read_long, unmapped_write_long,18.73 + unmapped_read_long, unmapped_write_long,18.74 + unmapped_read_long, unmapped_write_long,18.75 + unmapped_read_burst, unmapped_write_burst };18.76 +18.77 +/********************* Store-queue (long-write only?) ******************/18.78 +static void FASTCALL p4_storequeue_write_long( sh4addr_t addr, uint32_t val )18.79 +{18.80 + sh4r.store_queue[(addr>>2)&0xF] = val;18.81 +}18.82 +static int32_t FASTCALL p4_storequeue_read_long( sh4addr_t addr )18.83 +{18.84 + return sh4r.store_queue[(addr>>2)&0xF];18.85 +}18.86 +struct mem_region_fn p4_region_storequeue = {18.87 + p4_storequeue_read_long, p4_storequeue_write_long,18.88 + p4_storequeue_read_long, p4_storequeue_write_long,18.89 + p4_storequeue_read_long, p4_storequeue_write_long,18.90 + unmapped_read_burst, unmapped_write_burst }; // No burst access.18.91 +18.92 +/********************* The main ram address space **********************/18.93 +static int32_t FASTCALL ext_sdram_read_long( sh4addr_t addr )18.94 +{18.95 + return *((int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));18.96 +}18.97 +static int32_t FASTCALL ext_sdram_read_word( sh4addr_t addr )18.98 +{18.99 + return SIGNEXT16(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));18.100 +}18.101 +static int32_t FASTCALL ext_sdram_read_byte( sh4addr_t addr )18.102 +{18.103 + return SIGNEXT8(*((int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));18.104 +}18.105 +static void FASTCALL ext_sdram_write_long( sh4addr_t addr, uint32_t val )18.106 +{18.107 + *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;18.108 + xlat_invalidate_long(addr);18.109 +}18.110 +static void FASTCALL ext_sdram_write_word( sh4addr_t addr, uint32_t val )18.111 +{18.112 + *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint16_t)val;18.113 + xlat_invalidate_word(addr);18.114 +}18.115 +static void FASTCALL ext_sdram_write_byte( sh4addr_t addr, uint32_t val )18.116 +{18.117 + *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = (uint8_t)val;18.118 + xlat_invalidate_word(addr);18.119 +}18.120 +static void FASTCALL ext_sdram_read_burst( unsigned char *dest, sh4addr_t addr )18.121 +{18.122 + memcpy( dest, sh4_main_ram+(addr&0x00FFFFFF), 32 );18.123 +}18.124 +static void FASTCALL ext_sdram_write_burst( sh4addr_t addr, unsigned char *src )18.125 +{18.126 + memcpy( sh4_main_ram+(addr&0x00FFFFFF), src, 32 );18.127 +}18.128 +18.129 +struct mem_region_fn mem_region_sdram = { ext_sdram_read_long, ext_sdram_write_long,18.130 + ext_sdram_read_word, ext_sdram_write_word,18.131 + ext_sdram_read_byte, ext_sdram_write_byte,18.132 + ext_sdram_read_burst, ext_sdram_write_burst };18.133 +18.134 +18.135 +/********************* The Boot ROM address space **********************/18.136 +extern sh4ptr_t dc_boot_rom;18.137 +extern sh4ptr_t dc_flash_ram;18.138 +extern sh4ptr_t dc_audio_ram;18.139 +static int32_t FASTCALL ext_bootrom_read_long( sh4addr_t addr )18.140 +{18.141 + return *((int32_t *)(dc_boot_rom + (addr&0x001FFFFF)));18.142 +}18.143 +static int32_t FASTCALL ext_bootrom_read_word( sh4addr_t addr )18.144 +{18.145 + return SIGNEXT16(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));18.146 +}18.147 +static int32_t FASTCALL ext_bootrom_read_byte( sh4addr_t addr )18.148 +{18.149 + return SIGNEXT8(*((int16_t *)(dc_boot_rom + (addr&0x001FFFFF))));18.150 +}18.151 +static void FASTCALL ext_bootrom_read_burst( unsigned char *dest, sh4addr_t addr )18.152 +{18.153 + memcpy( dest, sh4_main_ram+(addr&0x001FFFFF), 32 );18.154 +}18.155 +18.156 +struct mem_region_fn mem_region_bootrom = {18.157 + ext_bootrom_read_long, unmapped_write_long,18.158 + ext_bootrom_read_word, unmapped_write_long,18.159 + ext_bootrom_read_byte, unmapped_write_long,18.160 + ext_bootrom_read_burst, unmapped_write_burst };18.161 +18.162 +/********************* The Audio RAM address space **********************/18.163 +static int32_t FASTCALL ext_audioram_read_long( sh4addr_t addr )18.164 +{18.165 + return *((int32_t *)(dc_audio_ram + (addr&0x001FFFFF)));18.166 +}18.167 +static int32_t FASTCALL ext_audioram_read_word( sh4addr_t addr )18.168 +{18.169 + return SIGNEXT16(*((int16_t *)(dc_audio_ram + (addr&0x001FFFFF))));18.170 +}18.171 +static int32_t FASTCALL ext_audioram_read_byte( sh4addr_t addr )18.172 +{18.173 + return SIGNEXT8(*((int16_t *)(dc_audio_ram + (addr&0x001FFFFF))));18.174 +}18.175 +static void FASTCALL ext_audioram_write_long( sh4addr_t addr, uint32_t val )18.176 +{18.177 + *(uint32_t *)(dc_audio_ram + (addr&0x001FFFFF)) = val;18.178 + asic_g2_write_word();18.179 +}18.180 +static void FASTCALL ext_audioram_write_word( sh4addr_t addr, uint32_t val )18.181 +{18.182 + *(uint16_t *)(dc_audio_ram + (addr&0x001FFFFF)) = (uint16_t)val;18.183 + asic_g2_write_word();18.184 +}18.185 +static void FASTCALL ext_audioram_write_byte( sh4addr_t addr, uint32_t val )18.186 +{18.187 + *(uint8_t *)(dc_audio_ram + (addr&0x001FFFFF)) = (uint8_t)val;18.188 + asic_g2_write_word();18.189 +}18.190 +static void FASTCALL ext_audioram_read_burst( unsigned char *dest, sh4addr_t addr )18.191 +{18.192 + memcpy( dest, dc_audio_ram+(addr&0x001FFFFF), 32 );18.193 +}18.194 +static void FASTCALL ext_audioram_write_burst( sh4addr_t addr, unsigned char *src )18.195 +{18.196 + memcpy( dc_audio_ram+(addr&0x001FFFFF), src, 32 );18.197 +}18.198 +18.199 +struct mem_region_fn mem_region_audioram = { ext_audioram_read_long, ext_audioram_write_long,18.200 + ext_audioram_read_word, ext_audioram_write_word,18.201 + ext_audioram_read_byte, ext_audioram_write_byte,18.202 + ext_audioram_read_burst, ext_audioram_write_burst };18.203 +18.204 +/********************* The Flash RAM address space **********************/18.205 +static int32_t FASTCALL ext_flashram_read_long( sh4addr_t addr )18.206 +{18.207 + return *((int32_t *)(dc_flash_ram + (addr&0x0001FFFF)));18.208 +}18.209 +static int32_t FASTCALL ext_flashram_read_word( sh4addr_t addr )18.210 +{18.211 + return SIGNEXT16(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));18.212 +}18.213 +static int32_t FASTCALL ext_flashram_read_byte( sh4addr_t addr )18.214 +{18.215 + return SIGNEXT8(*((int16_t *)(dc_flash_ram + (addr&0x0001FFFF))));18.216 +}18.217 +static void FASTCALL ext_flashram_write_long( sh4addr_t addr, uint32_t val )18.218 +{18.219 + *(uint32_t *)(dc_flash_ram + (addr&0x0001FFFF)) = val;18.220 + asic_g2_write_word();18.221 +}18.222 +static void FASTCALL ext_flashram_write_word( sh4addr_t addr, uint32_t val )18.223 +{18.224 + *(uint16_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint16_t)val;18.225 + asic_g2_write_word();18.226 +}18.227 +static void FASTCALL ext_flashram_write_byte( sh4addr_t addr, uint32_t val )18.228 +{18.229 + *(uint8_t *)(dc_flash_ram + (addr&0x0001FFFF)) = (uint8_t)val;18.230 + asic_g2_write_word();18.231 +}18.232 +static void FASTCALL ext_flashram_read_burst( unsigned char *dest, sh4addr_t addr )18.233 +{18.234 + memcpy( dest, dc_flash_ram+(addr&0x0001FFFF), 32 );18.235 +}18.236 +static void FASTCALL ext_flashram_write_burst( sh4addr_t addr, unsigned char *src )18.237 +{18.238 + memcpy( dc_flash_ram+(addr&0x0001FFFF), src, 32 );18.239 +}18.240 +18.241 +struct mem_region_fn mem_region_flashram = { ext_flashram_read_long, ext_flashram_write_long,18.242 + ext_flashram_read_word, ext_flashram_write_word,18.243 + ext_flashram_read_byte, ext_flashram_write_byte,18.244 + ext_flashram_read_burst, ext_flashram_write_burst };18.245 +18.246 +/**************************************************************************/18.247 +18.248 +struct mem_region_fn p4_region_icache_addr = {18.249 + mmu_icache_addr_read, mmu_icache_addr_write,18.250 + mmu_icache_addr_read, mmu_icache_addr_write,18.251 + mmu_icache_addr_read, mmu_icache_addr_write,18.252 + unmapped_read_burst, unmapped_write_burst };18.253 +struct mem_region_fn p4_region_icache_data = {18.254 + mmu_icache_data_read, mmu_icache_data_write,18.255 + mmu_icache_data_read, mmu_icache_data_write,18.256 + mmu_icache_data_read, mmu_icache_data_write,18.257 + unmapped_read_burst, unmapped_write_burst };18.258 +struct mem_region_fn p4_region_ocache_addr = {18.259 + mmu_ocache_addr_read, mmu_ocache_addr_write,18.260 + mmu_ocache_addr_read, mmu_ocache_addr_write,18.261 + mmu_ocache_addr_read, mmu_ocache_addr_write,18.262 + unmapped_read_burst, unmapped_write_burst };18.263 +struct mem_region_fn p4_region_ocache_data = {18.264 + mmu_ocache_data_read, mmu_ocache_data_write,18.265 + mmu_ocache_data_read, mmu_ocache_data_write,18.266 + mmu_ocache_data_read, mmu_ocache_data_write,18.267 + unmapped_read_burst, unmapped_write_burst };18.268 +struct mem_region_fn p4_region_itlb_addr = {18.269 + mmu_itlb_addr_read, mmu_itlb_addr_write,18.270 + mmu_itlb_addr_read, mmu_itlb_addr_write,18.271 + mmu_itlb_addr_read, mmu_itlb_addr_write,18.272 + unmapped_read_burst, unmapped_write_burst };18.273 +struct mem_region_fn p4_region_itlb_data = {18.274 + mmu_itlb_data_read, mmu_itlb_data_write,18.275 + mmu_itlb_data_read, mmu_itlb_data_write,18.276 + mmu_itlb_data_read, mmu_itlb_data_write,18.277 + unmapped_read_burst, unmapped_write_burst };18.278 +struct mem_region_fn p4_region_utlb_addr = {18.279 + mmu_utlb_addr_read, mmu_utlb_addr_write,18.280 + mmu_utlb_addr_read, mmu_utlb_addr_write,18.281 + mmu_utlb_addr_read, mmu_utlb_addr_write,18.282 + unmapped_read_burst, unmapped_write_burst };18.283 +struct mem_region_fn p4_region_utlb_data = {18.284 + mmu_utlb_data_read, mmu_utlb_data_write,18.285 + mmu_utlb_data_read, mmu_utlb_data_write,18.286 + mmu_utlb_data_read, mmu_utlb_data_write,18.287 + unmapped_read_burst, unmapped_write_burst };18.288 +18.289 +#ifdef HAVE_FRAME_ADDRESS18.290 +#define RETURN_VIA(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; return; } while(0)18.291 #else18.292 -#define CHECK_READ_WATCH( addr, size )18.293 -#define CHECK_WRITE_WATCH( addr, size, val )18.294 +#define RETURN_VIA(exc) return NULL18.295 #endif18.297 -#ifdef ENABLE_TRACE_IO18.298 -#define TRACE_IO( str, p, r, ... ) if(io_rgn[(uint32_t)p]->trace_flag && !MMIO_NOTRACE_BYNUM((uint32_t)p,r)) \18.299 - TRACE( str " [%s.%s: %s]", __VA_ARGS__, \18.300 - MMIO_NAME_BYNUM((uint32_t)p), MMIO_REGID_BYNUM((uint32_t)p, r), \18.301 - MMIO_REGDESC_BYNUM((uint32_t)p, r) )18.302 -#define TRACE_P4IO( str, io, r, ... ) if(io->trace_flag && !MMIO_NOTRACE_IOBYNUM(io,r)) \18.303 - TRACE( str " [%s.%s: %s]", __VA_ARGS__, \18.304 - io->id, MMIO_REGID_IOBYNUM(io, r), \18.305 - MMIO_REGDESC_IOBYNUM(io, r) )18.306 -#else18.307 -#define TRACE_IO( str, p, r, ... )18.308 -#define TRACE_P4IO( str, io, r, ... )18.309 -#endif18.310 -18.311 -extern struct mem_region mem_rgn[];18.312 -extern struct mmio_region *P4_io[];18.313 -18.314 -int32_t FASTCALL sh4_read_p4( sh4addr_t addr )18.315 +int decode_sdram = 0;18.316 +mem_region_fn_t FASTCALL mem_decode_address( sh4addr_t addr )18.317 {18.318 - struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];18.319 - if( !io ) {18.320 - switch( addr & 0x1F000000 ) {18.321 - case 0x00000000: case 0x01000000: case 0x02000000: case 0x03000000:18.322 - /* Store queue - readable? */18.323 - return 0;18.324 - break;18.325 - case 0x10000000: return mmu_icache_addr_read( addr );18.326 - case 0x11000000: return mmu_icache_data_read( addr );18.327 - case 0x12000000: return mmu_itlb_addr_read( addr );18.328 - case 0x13000000: return mmu_itlb_data_read( addr );18.329 - case 0x14000000: return mmu_ocache_addr_read( addr );18.330 - case 0x15000000: return mmu_ocache_data_read( addr );18.331 - case 0x16000000: return mmu_utlb_addr_read( addr );18.332 - case 0x17000000: return mmu_utlb_data_read( addr );18.333 - default:18.334 - WARN( "Attempted read from unknown or invalid P4 region: %08X", addr );18.335 - return 0;18.336 + sh4ptr_t page;18.337 + switch( addr >> 26 ) { /* Area */18.338 + case 0: /* Holly multiplexed */18.339 + page = page_map[(addr&0x1FFFFFFF)>>12];18.340 + if( ((uintptr_t)page) < MAX_IO_REGIONS ) {18.341 + return &io_rgn[(uintptr_t)page]->fn;18.342 + } else if( addr < 0x00200000 ) {18.343 + return &mem_region_bootrom;18.344 + } else if( addr < 0x00400000 ) {18.345 + return &mem_region_flashram;18.346 + } else if( addr >= 0x00800000 && addr < 0x00A00000 ) {18.347 + return &mem_region_audioram;18.348 }18.349 - } else {18.350 - int32_t val = io->io_read( addr&0xFFF );18.351 - TRACE_P4IO( "Long read %08X <= %08X", io, (addr&0xFFF), val, addr );18.352 - return val;18.353 - }18.354 + break;18.355 + case 1: /* VRAM */18.356 + switch( addr >> 24 ) {18.357 + case 4: return &mem_region_vram64; /* 0x04xxxxxx */18.358 + case 5: return &mem_region_vram32; /* 0x05xxxxxx */18.359 + }18.360 + break;18.361 + case 2: /* Unmapped */18.362 + break;18.363 + case 3: /* Main sdram */18.364 + decode_sdram++;18.365 + return &mem_region_sdram;18.366 + case 4: /* Holly burst-access only? */18.367 + break;18.368 + }18.369 + return &mem_region_unmapped;18.370 }18.372 -void FASTCALL sh4_write_p4( sh4addr_t addr, int32_t val )18.373 +int decode_count = 0;18.374 +int p4_count = 0;18.375 +int sq_count = 0;18.376 +18.377 +mem_region_fn_t FASTCALL sh7750_decode_address( sh4addr_t addr )18.378 {18.379 - struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];18.380 - if( !io ) {18.381 - switch( addr & 0x1F000000 ) {18.382 - case 0x00000000: case 0x01000000: case 0x02000000: case 0x03000000:18.383 - /* Store queue */18.384 - SH4_WRITE_STORE_QUEUE( addr, val );18.385 - break;18.386 - case 0x10000000: mmu_icache_addr_write( addr, val ); break;18.387 - case 0x11000000: mmu_icache_data_write( addr, val ); break;18.388 - case 0x12000000: mmu_itlb_addr_write( addr, val ); break;18.389 - case 0x13000000: mmu_itlb_data_write( addr, val ); break;18.390 - case 0x14000000: mmu_ocache_addr_write( addr, val ); break;18.391 - case 0x15000000: mmu_ocache_data_write( addr, val ); break;18.392 - case 0x16000000: mmu_utlb_addr_write( addr, val ); break;18.393 - case 0x17000000: mmu_utlb_data_write( addr, val ); break;18.394 - default:18.395 - if( (addr & 0xFFFF0000 ) == 0xFF940000 ||18.396 - (addr & 0xFFFF0000 ) == 0xFF900000 ) {18.397 - // SDRAM configuration, ignore for now18.398 - } else {18.399 - WARN( "Attempted write to unknown P4 region: %08X", addr );18.400 + decode_count++;18.401 + sh4addr_t region = addr >> 29;18.402 + switch( region ) {18.403 + case 7: /* P4 E0000000-FFFFFFFF - On-chip I/O */18.404 + if( addr < 0xE4000000 ) {18.405 + sq_count++;18.406 + return &p4_region_storequeue;18.407 + } else if( addr < 0xFC000000 ) { /* Control register region */18.408 + p4_count++;18.409 + switch( addr & 0x1F000000 ) {18.410 + case 0x10000000: return &p4_region_icache_addr;18.411 + case 0x11000000: return &p4_region_icache_data;18.412 + case 0x12000000: return &p4_region_itlb_addr;18.413 + case 0x13000000: return &p4_region_itlb_data;18.414 + case 0x14000000: return &p4_region_ocache_addr;18.415 + case 0x15000000: return &p4_region_ocache_data;18.416 + case 0x16000000: return &p4_region_utlb_addr;18.417 + case 0x17000000: return &p4_region_utlb_data;18.418 + default: return &mem_region_unmapped;18.419 }18.420 + } else {18.421 + p4_count++;18.422 + struct mmio_region *io = P4_io[(addr&0x1FFFFFFF)>>19];18.423 + if( io != NULL ) {18.424 + return &io->fn;18.425 + }18.426 + return &mem_region_unmapped;18.427 }18.428 - } else {18.429 - TRACE_P4IO( "Long write %08X => %08X", io, (addr&0xFFF), val, addr );18.430 - io->io_write( addr&0xFFF, val );18.431 + break;18.432 + case 6: /* P3 C0000000-DFFFFFFF - TLB on, Cache on */18.433 + case 5: /* P2 A0000000-BFFFFFFF - TLB off, Cache off*/18.434 + case 4: /* P1 80000000-9FFFFFFF - TLB off, Cache on */18.435 + default: /* P0/U0 00000000-7FFFFFFF - TLB on, Cache on */18.436 + return mem_decode_address( addr & 0x1FFFFFFF );18.437 + /* TODO: Integrate TLB, Operand Cache lookups */18.438 }18.439 }18.441 -int32_t sh4_read_phys_word( sh4addr_t addr )18.442 +void FASTCALL sh7750_decode_address_copy( sh4addr_t addr, mem_region_fn_t result )18.443 {18.444 - sh4ptr_t page;18.445 - if( addr >= 0xE0000000 ) /* P4 Area, handled specially */18.446 - return SIGNEXT16(sh4_read_p4( addr ));18.447 -18.448 - if( (addr&0x1F800000) == 0x04000000 ) {18.449 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.450 - }18.451 -18.452 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.453 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.454 - if( page == NULL ) {18.455 - WARN( "Attempted word read to missing page: %08X",18.456 - addr );18.457 - return 0;18.458 - }18.459 - return SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));18.460 - } else {18.461 - return SIGNEXT16(*(int16_t *)(page+(addr&0xFFF)));18.462 - }18.463 + mem_region_fn_t region = sh7750_decode_address( addr );18.464 + memcpy( result, region, sizeof(struct mem_region_fn) -8 );18.465 }18.467 -/**18.468 - * Convenience function to read a quad-word (implemented as two long reads).18.469 - */18.470 -int64_t FASTCALL sh4_read_quad( sh4addr_t addr )18.471 -{18.472 - return ((int64_t)((uint32_t)sh4_read_long(addr))) |18.473 - (((int64_t)((uint32_t)sh4_read_long(addr+4))) << 32);18.474 -}18.475 -18.476 -int32_t FASTCALL sh4_read_long( sh4addr_t addr )18.477 -{18.478 - sh4ptr_t page;18.479 -18.480 - CHECK_READ_WATCH(addr,4);18.481 -18.482 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */18.483 - return ZEROEXT32(sh4_read_p4( addr ));18.484 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.485 - return ZEROEXT32(*(int32_t *)(sh4_main_ram + (addr&0x00FFFFFF)));18.486 - } else if( (addr&0x1F800000) == 0x04000000 ) {18.487 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.488 - pvr2_render_buffer_invalidate(addr, FALSE);18.489 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.490 - pvr2_render_buffer_invalidate(addr, FALSE);18.491 - }18.492 -18.493 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.494 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.495 - int32_t val;18.496 - if( page == NULL ) {18.497 - WARN( "Attempted long read to missing page: %08X", addr );18.498 - return 0;18.499 - }18.500 - val = io_rgn[(uintptr_t)page]->io_read(addr&0xFFF);18.501 - TRACE_IO( "Long read %08X <= %08X", page, (addr&0xFFF), val, addr );18.502 - return ZEROEXT32(val);18.503 - } else {18.504 - return ZEROEXT32(*(int32_t *)(page+(addr&0xFFF)));18.505 - }18.506 -}18.507 -18.508 -int32_t FASTCALL sh4_read_word( sh4addr_t addr )18.509 -{18.510 - sh4ptr_t page;18.511 -18.512 - CHECK_READ_WATCH(addr,2);18.513 -18.514 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */18.515 - return ZEROEXT32(SIGNEXT16(sh4_read_p4( addr )));18.516 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.517 - return ZEROEXT32(SIGNEXT16(*(int16_t *)(sh4_main_ram + (addr&0x00FFFFFF))));18.518 - } else if( (addr&0x1F800000) == 0x04000000 ) {18.519 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.520 - pvr2_render_buffer_invalidate(addr, FALSE);18.521 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.522 - pvr2_render_buffer_invalidate(addr, FALSE);18.523 - }18.524 -18.525 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.526 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.527 - int32_t val;18.528 - if( page == NULL ) {18.529 - WARN( "Attempted word read to missing page: %08X", addr );18.530 - return 0;18.531 - }18.532 - val = SIGNEXT16(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));18.533 - TRACE_IO( "Word read %04X <= %08X", page, (addr&0xFFF), val&0xFFFF, addr );18.534 - return ZEROEXT32(val);18.535 - } else {18.536 - return ZEROEXT32(SIGNEXT16(*(int16_t *)(page+(addr&0xFFF))));18.537 - }18.538 -}18.539 -18.540 -int32_t FASTCALL sh4_read_byte( sh4addr_t addr )18.541 -{18.542 - sh4ptr_t page;18.543 -18.544 - CHECK_READ_WATCH(addr,1);18.545 -18.546 - if( addr >= 0xE0000000 ) { /* P4 Area, handled specially */18.547 - return ZEROEXT32(SIGNEXT8(sh4_read_p4( addr )));18.548 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.549 - return ZEROEXT32(SIGNEXT8(*(int8_t *)(sh4_main_ram + (addr&0x00FFFFFF))));18.550 - } else if( (addr&0x1F800000) == 0x04000000 ) {18.551 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.552 - pvr2_render_buffer_invalidate(addr, FALSE);18.553 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.554 - pvr2_render_buffer_invalidate(addr, FALSE);18.555 - }18.556 -18.557 -18.558 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.559 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.560 - int32_t val;18.561 - if( page == NULL ) {18.562 - WARN( "Attempted byte read to missing page: %08X", addr );18.563 - return 0;18.564 - }18.565 - val = SIGNEXT8(io_rgn[(uintptr_t)page]->io_read(addr&0xFFF));18.566 - TRACE_IO( "Byte read %02X <= %08X", page, (addr&0xFFF), val&0xFF, addr );18.567 - return ZEROEXT32(val);18.568 - } else {18.569 - return ZEROEXT32(SIGNEXT8(*(int8_t *)(page+(addr&0xFFF))));18.570 - }18.571 -}18.572 -18.573 -/**18.574 - * Convenience function to write a quad-word (implemented as two long writes).18.575 - */18.576 -void FASTCALL sh4_write_quad( sh4addr_t addr, uint64_t val )18.577 -{18.578 - sh4_write_long( addr, (uint32_t)val );18.579 - sh4_write_long( addr+4, (uint32_t)(val>>32) );18.580 -}18.581 -18.582 -void FASTCALL sh4_write_long( sh4addr_t addr, uint32_t val )18.583 -{18.584 - sh4ptr_t page;18.585 -18.586 - CHECK_WRITE_WATCH(addr,4,val);18.587 -18.588 - if( addr >= 0xE0000000 ) {18.589 - if( addr < 0xE4000000 ) { // Shortcut for the extremely common case18.590 - SH4_WRITE_STORE_QUEUE( addr, val );18.591 - } else {18.592 - sh4_write_p4( addr, val );18.593 - }18.594 - return;18.595 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.596 - *(uint32_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;18.597 - xlat_invalidate_long(addr);18.598 - return;18.599 - } else if( (addr&0x1F800000) == 0x04000000 ||18.600 - (addr&0x1F800000) == 0x11000000 ) {18.601 - texcache_invalidate_page(addr& 0x7FFFFF);18.602 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.603 - pvr2_render_buffer_invalidate(addr, TRUE);18.604 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.605 - pvr2_render_buffer_invalidate(addr, TRUE);18.606 - }18.607 -18.608 - if( (addr&0x1FFFFFFF) < 0x200000 ) {18.609 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);18.610 - sh4_stop();18.611 - return;18.612 - }18.613 - if( (addr&0x1F800000) == 0x00800000 )18.614 - asic_g2_write_word();18.615 -18.616 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.617 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.618 - if( page == NULL ) {18.619 - if( (addr & 0x1F000000) >= 0x04000000 &&18.620 - (addr & 0x1F000000) < 0x07000000 )18.621 - return;18.622 - WARN( "Long write to missing page: %08X => %08X", val, addr );18.623 - return;18.624 - }18.625 - TRACE_IO( "Long write %08X => %08X", page, (addr&0xFFF), val, addr );18.626 - io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);18.627 - } else {18.628 - *(uint32_t *)(page+(addr&0xFFF)) = val;18.629 - }18.630 -}18.631 -18.632 -void FASTCALL sh4_write_word( sh4addr_t addr, uint32_t val )18.633 -{18.634 - sh4ptr_t page;18.635 -18.636 - CHECK_WRITE_WATCH(addr,2,val);18.637 -18.638 - if( addr >= 0xE0000000 ) {18.639 - sh4_write_p4( addr, (int16_t)val );18.640 - return;18.641 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.642 - *(uint16_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;18.643 - xlat_invalidate_word(addr);18.644 - return;18.645 - } else if( (addr&0x1F800000) == 0x04000000 ||18.646 - (addr&0x1F800000) == 0x11000000 ) {18.647 - texcache_invalidate_page(addr& 0x7FFFFF);18.648 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.649 - pvr2_render_buffer_invalidate(addr, TRUE);18.650 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.651 - pvr2_render_buffer_invalidate(addr, TRUE);18.652 - }18.653 -18.654 - if( (addr&0x1FFFFFFF) < 0x200000 ) {18.655 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);18.656 - sh4_stop();18.657 - return;18.658 - }18.659 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.660 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.661 - if( page == NULL ) {18.662 - WARN( "Attempted word write to missing page: %08X", addr );18.663 - return;18.664 - }18.665 - TRACE_IO( "Word write %04X => %08X", page, (addr&0xFFF), val&0xFFFF, addr );18.666 - io_rgn[(uintptr_t)page]->io_write(addr&0xFFF, val);18.667 - } else {18.668 - *(uint16_t *)(page+(addr&0xFFF)) = val;18.669 - }18.670 -}18.671 -18.672 -void FASTCALL sh4_write_byte( sh4addr_t addr, uint32_t val )18.673 -{18.674 - sh4ptr_t page;18.675 -18.676 - CHECK_WRITE_WATCH(addr,1,val);18.677 -18.678 - if( addr >= 0xE0000000 ) {18.679 - sh4_write_p4( addr, (int8_t)val );18.680 - return;18.681 - } else if( (addr&0x1C000000) == 0x0C000000 ) {18.682 - *(uint8_t *)(sh4_main_ram + (addr&0x00FFFFFF)) = val;18.683 - xlat_invalidate_word(addr);18.684 - return;18.685 - } else if( (addr&0x1F800000) == 0x04000000 ||18.686 - (addr&0x1F800000) == 0x11000000 ) {18.687 - texcache_invalidate_page(addr& 0x7FFFFF);18.688 - addr = TRANSLATE_VIDEO_64BIT_ADDRESS(addr);18.689 - pvr2_render_buffer_invalidate(addr, TRUE);18.690 - } else if( (addr&0x1F800000) == 0x05000000 ) {18.691 - pvr2_render_buffer_invalidate(addr, TRUE);18.692 - }18.693 -18.694 - if( (addr&0x1FFFFFFF) < 0x200000 ) {18.695 - WARN( "Attempted write to read-only memory: %08X => %08X", val, addr);18.696 - sh4_stop();18.697 - return;18.698 - }18.699 - page = page_map[ (addr & 0x1FFFFFFF) >> 12 ];18.700 - if( ((uintptr_t)page) < MAX_IO_REGIONS ) { /* IO Region */18.701 - if( page == NULL ) {18.702 - WARN( "Attempted byte write to missing page: %08X", addr );18.703 - return;18.704 - }18.705 - TRACE_IO( "Byte write %02X => %08X", page, (addr&0xFFF), val&0xFF, addr );18.706 - io_rgn[(uintptr_t)page]->io_write( (addr&0xFFF), val);18.707 - } else {18.708 - *(uint8_t *)(page+(addr&0xFFF)) = val;18.709 - }18.710 -}18.711 -18.712 -18.713 -18.714 /* FIXME: Handle all the many special cases when the range doesn't fall cleanly18.715 * into the same memory block18.716 */18.717 @@ -432,3 +410,109 @@18.718 }18.719 }18.721 +static uint32_t last_page = -1;18.722 +static mem_region_fn_t last_region = NULL;18.723 +static uint32_t hit_count = 0;18.724 +static uint32_t miss_count = 0;18.725 +static uint32_t rl_count = 0, rw_count = 0, rb_count = 0;18.726 +static uint32_t wl_count = 0, ww_count = 0, wb_count = 0;18.727 +18.728 +/************** Compatibility methods ***************/18.729 +18.730 +int32_t FASTCALL sh4_read_long( sh4addr_t addr )18.731 +{18.732 + rl_count++;18.733 + uint32_t page = (addr & 0xFFFFF000);18.734 + if( page == last_page ) {18.735 + hit_count++;18.736 + return last_region->read_long(addr);18.737 + } else {18.738 + miss_count++;18.739 + last_page = page;18.740 + last_region = sh7750_decode_address(addr);18.741 + return last_region->read_long(addr);18.742 + }18.743 +}18.744 +18.745 +int32_t FASTCALL sh4_read_word( sh4addr_t addr )18.746 +{18.747 + rw_count++;18.748 + uint32_t page = (addr & 0xFFFFF000);18.749 + if( page == last_page ) {18.750 + hit_count++;18.751 + return last_region->read_word(addr);18.752 + } else {18.753 + miss_count++;18.754 + last_page = page;18.755 + last_region = sh7750_decode_address(addr);18.756 + return last_region->read_word(addr);18.757 + }18.758 +}18.759 +18.760 +int32_t FASTCALL sh4_read_byte( sh4addr_t addr )18.761 +{18.762 + rb_count++;18.763 + uint32_t page = (addr & 0xFFFFF000);18.764 + if( page == last_page ) {18.765 + hit_count++;18.766 + return last_region->read_byte(addr);18.767 + } else {18.768 + miss_count++;18.769 + last_page = page;18.770 + last_region = sh7750_decode_address(addr);18.771 + return last_region->read_byte(addr);18.772 + }18.773 +}18.774 +18.775 +void FASTCALL sh4_write_long( sh4addr_t addr, uint32_t val )18.776 +{18.777 + wl_count++;18.778 + uint32_t page = (addr & 0xFFFFF000);18.779 + if( page == last_page ) {18.780 + hit_count++;18.781 + last_region->write_long(addr, val);18.782 + } else {18.783 + miss_count++;18.784 + last_page = page;18.785 + last_region = sh7750_decode_address(addr);18.786 + last_region->write_long(addr,val);18.787 + }18.788 +}18.789 +18.790 +void FASTCALL sh4_write_word( sh4addr_t addr, uint32_t val )18.791 +{18.792 + ww_count++;18.793 + uint32_t page = (addr & 0xFFFFF000);18.794 + if( page == last_page ) {18.795 + hit_count++;18.796 + last_region->write_word(addr, val);18.797 + } else {18.798 + miss_count++;18.799 + last_page = page;18.800 + last_region = sh7750_decode_address(addr);18.801 + last_region->write_word(addr,val);18.802 + }18.803 +}18.804 +18.805 +void FASTCALL sh4_write_byte( sh4addr_t addr, uint32_t val )18.806 +{18.807 + wb_count++;18.808 + uint32_t page = (addr & 0xFFFFF000);18.809 + if( page == last_page ) {18.810 + hit_count++;18.811 + last_region->write_byte(addr, val);18.812 + } else {18.813 + miss_count++;18.814 + last_page = page;18.815 + last_region = sh7750_decode_address(addr);18.816 + last_region->write_byte(addr,val);18.817 + }18.818 +}18.819 +18.820 +void print_sh4mem_stats() {18.821 + printf( "Decodes to p4: %d sq: %d\n", p4_count+sq_count, sq_count );18.822 + printf( "Decodes to sdram: %d\n", decode_sdram );18.823 + printf( "Decodes: %d Hits: %d Miss: %d\n", decode_count, hit_count, miss_count );18.824 + printf( "Read long: %d word: %d byte: %d\n", rl_count, rw_count, rb_count );18.825 + printf( "Write long: %d word: %d byte: %d\n", wl_count, ww_count, wb_count );18.826 +}18.827 \ No newline at end of file
19.1 --- a/src/sh4/sh4mmio.c Sat Dec 20 02:53:41 2008 +000019.2 +++ b/src/sh4/sh4mmio.c Sat Dec 20 03:01:40 2008 +000019.3 @@ -72,9 +72,10 @@19.5 MMIO_REGION_WRITE_DEFFN(BSC)19.7 -int32_t mmio_region_BSC_read( uint32_t reg )19.8 +MMIO_REGION_READ_FN( BSC, reg )19.9 {19.10 int32_t val;19.11 + reg &= 0xFFF;19.12 switch( reg ) {19.13 case PDTRA:19.14 val = bsc_read_pdtra();19.15 @@ -90,13 +91,14 @@19.17 /********************************* UBC *************************************/19.19 -int32_t mmio_region_UBC_read( uint32_t reg )19.20 +MMIO_REGION_READ_FN( UBC, reg )19.21 {19.22 - return MMIO_READ( UBC, reg );19.23 + return MMIO_READ( UBC, reg & 0xFFF );19.24 }19.26 -void mmio_region_UBC_write( uint32_t reg, uint32_t val )19.27 +MMIO_REGION_WRITE_FN( UBC, reg, val )19.28 {19.29 + reg &= 0xFFF;19.30 switch( reg ) {19.31 case BAMRA:19.32 case BAMRB:
20.1 --- a/src/sh4/sh4mmio.h Sat Dec 20 02:53:41 2008 +000020.2 +++ b/src/sh4/sh4mmio.h Sat Dec 20 03:01:40 2008 +000020.3 @@ -243,22 +243,22 @@20.4 void mmu_set_cache_mode( int );20.5 void mmu_ldtlb(void);20.7 -int32_t mmu_icache_addr_read( sh4addr_t addr );20.8 -int32_t mmu_icache_data_read( sh4addr_t addr );20.9 -int32_t mmu_itlb_addr_read( sh4addr_t addr );20.10 -int32_t mmu_itlb_data_read( sh4addr_t addr );20.11 -int32_t mmu_ocache_addr_read( sh4addr_t addr );20.12 -int32_t mmu_ocache_data_read( sh4addr_t addr );20.13 -int32_t mmu_utlb_addr_read( sh4addr_t addr );20.14 -int32_t mmu_utlb_data_read( sh4addr_t addr );20.15 -void mmu_icache_addr_write( sh4addr_t addr, uint32_t val );20.16 -void mmu_icache_data_write( sh4addr_t addr, uint32_t val );20.17 -void mmu_itlb_addr_write( sh4addr_t addr, uint32_t val );20.18 -void mmu_itlb_data_write( sh4addr_t addr, uint32_t val );20.19 -void mmu_ocache_addr_write( sh4addr_t addr, uint32_t val );20.20 -void mmu_ocache_data_write( sh4addr_t addr, uint32_t val );20.21 -void mmu_utlb_addr_write( sh4addr_t addr, uint32_t val );20.22 -void mmu_utlb_data_write( sh4addr_t addr, uint32_t val );20.23 +int32_t FASTCALL mmu_icache_addr_read( sh4addr_t addr );20.24 +int32_t FASTCALL mmu_icache_data_read( sh4addr_t addr );20.25 +int32_t FASTCALL mmu_itlb_addr_read( sh4addr_t addr );20.26 +int32_t FASTCALL mmu_itlb_data_read( sh4addr_t addr );20.27 +int32_t FASTCALL mmu_ocache_addr_read( sh4addr_t addr );20.28 +int32_t FASTCALL mmu_ocache_data_read( sh4addr_t addr );20.29 +int32_t FASTCALL mmu_utlb_addr_read( sh4addr_t addr );20.30 +int32_t FASTCALL mmu_utlb_data_read( sh4addr_t addr );20.31 +void FASTCALL mmu_icache_addr_write( sh4addr_t addr, uint32_t val );20.32 +void FASTCALL mmu_icache_data_write( sh4addr_t addr, uint32_t val );20.33 +void FASTCALL mmu_itlb_addr_write( sh4addr_t addr, uint32_t val );20.34 +void FASTCALL mmu_itlb_data_write( sh4addr_t addr, uint32_t val );20.35 +void FASTCALL mmu_ocache_addr_write( sh4addr_t addr, uint32_t val );20.36 +void FASTCALL mmu_ocache_data_write( sh4addr_t addr, uint32_t val );20.37 +void FASTCALL mmu_utlb_addr_write( sh4addr_t addr, uint32_t val );20.38 +void FASTCALL mmu_utlb_data_write( sh4addr_t addr, uint32_t val );20.41 #ifdef __cplusplus
21.1 --- a/src/sh4/sh4x86.in Sat Dec 20 02:53:41 2008 +000021.2 +++ b/src/sh4/sh4x86.in Sat Dec 20 03:01:40 2008 +000021.3 @@ -20,6 +20,7 @@21.5 #include <assert.h>21.6 #include <math.h>21.7 +#include <stddef.h>21.9 #ifndef NDEBUG21.10 #define DEBUG_JUMPS 121.11 @@ -322,6 +323,111 @@21.12 #include "sh4/ia32abi.h"21.13 #endif21.15 +#define MEM_REGION_PTR(name) offsetof( struct mem_region_fn, name )21.16 +21.17 +/**21.18 + * Given an address in addr_reg and a cache entry, test if the cache is valid21.19 + * and decode otherwise.21.20 + * At conclusion of this:21.21 + * R_EBX will contain the address21.22 + * R_ECX will contain the memory region vtable21.23 + * R_EAX, R_EDX (and any other volatiles) are clobbered21.24 + */21.25 +static inline void MEM_DECODE_ADDRESS( int addr_reg, int rm )21.26 +{21.27 + MOV_r32_r32( addr_reg, R_EBX );21.28 + AND_sh4r_r32( REG_OFFSET(pointer_cache[rm].page_mask), addr_reg );21.29 + CMP_sh4r_r32( REG_OFFSET(pointer_cache[rm].page_vma), addr_reg );21.30 + EXPJE_rel8(uptodate);21.31 + store_spreg( addr_reg, REG_OFFSET(pointer_cache[rm].page_vma) );21.32 + call_func1( sh7750_decode_address, addr_reg );21.33 + store_spreg( R_EAX, REG_OFFSET(pointer_cache[rm].page_fn) );21.34 + JMP_TARGET(uptodate);21.35 + load_spreg( R_ECX, REG_OFFSET(pointer_cache[rm].page_fn) );21.36 +}21.37 +21.38 +static inline void MEM_READ_LONG_CACHED( int addr_reg, int value_reg, int rm )21.39 +{21.40 + MEM_DECODE_ADDRESS( addr_reg, rm );21.41 + call_func1_r32ind( R_ECX, MEM_REGION_PTR(read_long), R_EBX );21.42 + MEM_RESULT(value_reg);21.43 +}21.44 +21.45 +static inline void MEM_READ_WORD_CACHED( int addr_reg, int value_reg, int rm )21.46 +{21.47 + MEM_DECODE_ADDRESS( addr_reg, rm );21.48 + call_func1_r32ind( R_ECX, MEM_REGION_PTR(read_word), R_EBX );21.49 + MEM_RESULT(value_reg);21.50 +}21.51 +21.52 +static inline void MEM_READ_BYTE_CACHED( int addr_reg, int value_reg, int rm )21.53 +{21.54 + MEM_DECODE_ADDRESS( addr_reg, rm );21.55 + call_func1_r32ind( R_ECX, MEM_REGION_PTR(read_byte), R_EBX );21.56 + MEM_RESULT(value_reg);21.57 +}21.58 +21.59 +static inline void MEM_WRITE_LONG_CACHED_SP( int addr_reg, int ebpdisp, int rn )21.60 +{21.61 + MEM_DECODE_ADDRESS( addr_reg, rn );21.62 + MOV_sh4r_r32( ebpdisp, R_EDX );21.63 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_long), R_EBX, R_EDX );21.64 +}21.65 +21.66 +#define MEM_WRITE_LONG_CACHED( addr_reg, value_rm, rn ) MEM_WRITE_LONG_CACHED_SP( addr_reg, REG_OFFSET(r[value_rm]), rn )21.67 +21.68 +static inline void MEM_WRITE_WORD_CACHED( int addr_reg, int value_rm, int rn )21.69 +{21.70 + MEM_DECODE_ADDRESS( addr_reg, rn );21.71 + MOVZX_sh4r16_r32( REG_OFFSET(r[value_rm]), R_EDX );21.72 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_word), R_EBX, R_EDX );21.73 +}21.74 +21.75 +static inline void MEM_WRITE_BYTE_CACHED( int addr_reg, int value_rm, int rn )21.76 +{21.77 + MEM_DECODE_ADDRESS( addr_reg, rn );21.78 + MOVZX_sh4r8_r32( REG_OFFSET(r[value_rm]), R_EDX );21.79 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_byte), R_EBX, R_EDX );21.80 +}21.81 +21.82 +static inline void MEM_WRITE_BYTE_UNCHECKED( int addr_reg, int value_reg, int rn )21.83 +{21.84 + load_spreg( R_ECX, REG_OFFSET(pointer_cache[rn].page_fn) );21.85 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_byte), addr_reg, R_EDX );21.86 +}21.87 +21.88 +static inline void MEM_WRITE_FLOAT_CACHED( int addr_reg, int value_frm, int rn )21.89 +{21.90 + MEM_DECODE_ADDRESS( addr_reg, rn );21.91 + load_fr( R_EDX, value_frm );21.92 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_long), R_EBX, R_EDX );21.93 +}21.94 +21.95 +static inline void MEM_READ_DOUBLE_CACHED( int addr_reg, int value_reg1, int value_reg2, int rm )21.96 +{21.97 + MEM_DECODE_ADDRESS( addr_reg, rm );21.98 + call_func1_r32ind( R_ECX, MEM_REGION_PTR(read_long), R_EBX );21.99 + MOV_r32_esp8( R_EAX, 0 );21.100 + load_spreg( R_ECX, REG_OFFSET(pointer_cache[rm].page_fn) );21.101 + LEA_r32disp8_r32( R_EBX, 4, R_EBX );21.102 + call_func1_r32ind( R_ECX, MEM_REGION_PTR(read_long), R_EBX );21.103 + MEM_RESULT(value_reg2);21.104 + MOV_esp8_r32( 0, value_reg1 );21.105 +}21.106 +21.107 +static inline void MEM_WRITE_DOUBLE_CACHED( int addr_reg, int value_frm, int rn )21.108 +{21.109 + MEM_DECODE_ADDRESS( addr_reg, rn );21.110 + load_dr0( R_EDX, value_frm );21.111 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_long), R_EBX, R_EDX );21.112 + LEA_r32disp8_r32( R_EBX, 4, R_EBX );21.113 + load_spreg( R_ECX, REG_OFFSET(pointer_cache[rn].page_fn) );21.114 + load_dr1( R_EDX, value_frm );21.115 + call_func2_r32ind( R_ECX, MEM_REGION_PTR(write_long), R_EBX, R_EDX );21.116 +}21.117 +21.118 +21.119 +21.120 void sh4_translate_begin_block( sh4addr_t pc )21.121 {21.122 enter_block();21.123 @@ -471,11 +577,9 @@21.124 load_spreg( R_ECX, R_GBR );21.125 ADD_r32_r32( R_ECX, R_EAX );21.126 MMU_TRANSLATE_WRITE( R_EAX );21.127 - MOV_r32_esp8(R_EAX, 0);21.128 - MEM_READ_BYTE( R_EAX, R_EDX );21.129 - MOV_esp8_r32(0, R_EAX);21.130 + MEM_READ_BYTE_CACHED( R_EAX, R_EDX, 16 );21.131 AND_imm32_r32(imm, R_EDX );21.132 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.133 + MEM_WRITE_BYTE_UNCHECKED( R_EBX, R_EDX, 16 );21.134 sh4_x86.tstate = TSTATE_NONE;21.135 :}21.136 CMP/EQ Rm, Rn {:21.137 @@ -679,10 +783,10 @@21.138 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.139 }21.140 MEM_READ_LONG( R_EAX, R_EAX );21.141 - MOV_r32_esp8( R_EAX, 4 );21.142 + MOV_r32_r32( R_EAX, R_EBX );21.143 MOV_esp8_r32( 0, R_EAX );21.144 MEM_READ_LONG( R_EAX, R_EAX );21.145 - MOV_esp8_r32( 4, R_ECX );21.146 + MOV_r32_r32( R_EBX, R_ECX );21.148 IMUL_r32( R_ECX );21.149 ADD_r32_sh4r( R_EAX, R_MACL );21.150 @@ -720,10 +824,10 @@21.151 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );21.152 }21.153 MEM_READ_WORD( R_EAX, R_EAX );21.154 - MOV_r32_esp8( R_EAX, 4 );21.155 + MOV_r32_r32( R_EAX, R_EBX );21.156 MOV_esp8_r32( 0, R_EAX );21.157 MEM_READ_WORD( R_EAX, R_EAX );21.158 - MOV_esp8_r32( 4, R_ECX );21.159 + MOV_r32_r32( R_EBX, R_ECX );21.161 IMUL_r32( R_ECX );21.162 load_spreg( R_ECX, R_S );21.163 @@ -826,11 +930,9 @@21.164 load_spreg( R_ECX, R_GBR );21.165 ADD_r32_r32( R_ECX, R_EAX );21.166 MMU_TRANSLATE_WRITE( R_EAX );21.167 - MOV_r32_esp8( R_EAX, 0 );21.168 - MEM_READ_BYTE( R_EAX, R_EDX );21.169 - MOV_esp8_r32( 0, R_EAX );21.170 + MEM_READ_BYTE_CACHED( R_EAX, R_EDX, 16 );21.171 OR_imm32_r32(imm, R_EDX );21.172 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.173 + MEM_WRITE_BYTE_UNCHECKED( R_EBX, R_EDX, 16 );21.174 sh4_x86.tstate = TSTATE_NONE;21.175 :}21.176 ROTCL Rn {:21.177 @@ -1045,13 +1147,11 @@21.178 COUNT_INST(I_TASB);21.179 load_reg( R_EAX, Rn );21.180 MMU_TRANSLATE_WRITE( R_EAX );21.181 - MOV_r32_esp8( R_EAX, 0 );21.182 - MEM_READ_BYTE( R_EAX, R_EDX );21.183 + MEM_READ_BYTE_CACHED( R_EAX, R_EDX, 16 );21.184 TEST_r8_r8( R_DL, R_DL );21.185 SETE_t();21.186 OR_imm8_r8( 0x80, R_DL );21.187 - MOV_esp8_r32( 0, R_EAX );21.188 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.189 + MEM_WRITE_BYTE_UNCHECKED( R_EBX, R_EDX, 16 );21.190 sh4_x86.tstate = TSTATE_NONE;21.191 :}21.192 TST Rm, Rn {:21.193 @@ -1075,7 +1175,7 @@21.194 load_reg( R_ECX, R_GBR);21.195 ADD_r32_r32( R_ECX, R_EAX );21.196 MMU_TRANSLATE_READ( R_EAX );21.197 - MEM_READ_BYTE( R_EAX, R_EAX );21.198 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, 16 );21.199 TEST_imm8_r8( imm, R_AL );21.200 SETE_t();21.201 sh4_x86.tstate = TSTATE_E;21.202 @@ -1101,11 +1201,9 @@21.203 load_spreg( R_ECX, R_GBR );21.204 ADD_r32_r32( R_ECX, R_EAX );21.205 MMU_TRANSLATE_WRITE( R_EAX );21.206 - MOV_r32_esp8( R_EAX, 0 );21.207 - MEM_READ_BYTE(R_EAX, R_EDX);21.208 - MOV_esp8_r32( 0, R_EAX );21.209 + MEM_READ_BYTE_CACHED(R_EAX, R_EDX, 16);21.210 XOR_imm32_r32( imm, R_EDX );21.211 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.212 + MEM_WRITE_BYTE_UNCHECKED( R_EBX, R_EDX, 16 );21.213 sh4_x86.tstate = TSTATE_NONE;21.214 :}21.215 XTRCT Rm, Rn {:21.216 @@ -1134,8 +1232,7 @@21.217 COUNT_INST(I_MOVB);21.218 load_reg( R_EAX, Rn );21.219 MMU_TRANSLATE_WRITE( R_EAX );21.220 - load_reg( R_EDX, Rm );21.221 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.222 + MEM_WRITE_BYTE_CACHED( R_EAX, Rm, Rn );21.223 sh4_x86.tstate = TSTATE_NONE;21.224 :}21.225 MOV.B Rm, @-Rn {:21.226 @@ -1143,9 +1240,8 @@21.227 load_reg( R_EAX, Rn );21.228 ADD_imm8s_r32( -1, R_EAX );21.229 MMU_TRANSLATE_WRITE( R_EAX );21.230 - load_reg( R_EDX, Rm );21.231 ADD_imm8s_sh4r( -1, REG_OFFSET(r[Rn]) );21.232 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.233 + MEM_WRITE_BYTE_CACHED( R_EAX, Rm, Rn );21.234 sh4_x86.tstate = TSTATE_NONE;21.235 :}21.236 MOV.B Rm, @(R0, Rn) {:21.237 @@ -1154,8 +1250,7 @@21.238 load_reg( R_ECX, Rn );21.239 ADD_r32_r32( R_ECX, R_EAX );21.240 MMU_TRANSLATE_WRITE( R_EAX );21.241 - load_reg( R_EDX, Rm );21.242 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.243 + MEM_WRITE_BYTE_CACHED( R_EAX, Rm, 0 );21.244 sh4_x86.tstate = TSTATE_NONE;21.245 :}21.246 MOV.B R0, @(disp, GBR) {:21.247 @@ -1163,8 +1258,7 @@21.248 load_spreg( R_EAX, R_GBR );21.249 ADD_imm32_r32( disp, R_EAX );21.250 MMU_TRANSLATE_WRITE( R_EAX );21.251 - load_reg( R_EDX, 0 );21.252 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.253 + MEM_WRITE_BYTE_CACHED( R_EAX, 0, 16 );21.254 sh4_x86.tstate = TSTATE_NONE;21.255 :}21.256 MOV.B R0, @(disp, Rn) {:21.257 @@ -1172,15 +1266,14 @@21.258 load_reg( R_EAX, Rn );21.259 ADD_imm32_r32( disp, R_EAX );21.260 MMU_TRANSLATE_WRITE( R_EAX );21.261 - load_reg( R_EDX, 0 );21.262 - MEM_WRITE_BYTE( R_EAX, R_EDX );21.263 + MEM_WRITE_BYTE_CACHED( R_EAX, 0, Rn );21.264 sh4_x86.tstate = TSTATE_NONE;21.265 :}21.266 MOV.B @Rm, Rn {:21.267 COUNT_INST(I_MOVB);21.268 load_reg( R_EAX, Rm );21.269 MMU_TRANSLATE_READ( R_EAX );21.270 - MEM_READ_BYTE( R_EAX, R_EAX );21.271 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, Rm );21.272 store_reg( R_EAX, Rn );21.273 sh4_x86.tstate = TSTATE_NONE;21.274 :}21.275 @@ -1189,7 +1282,7 @@21.276 load_reg( R_EAX, Rm );21.277 MMU_TRANSLATE_READ( R_EAX );21.278 ADD_imm8s_sh4r( 1, REG_OFFSET(r[Rm]) );21.279 - MEM_READ_BYTE( R_EAX, R_EAX );21.280 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, Rm );21.281 store_reg( R_EAX, Rn );21.282 sh4_x86.tstate = TSTATE_NONE;21.283 :}21.284 @@ -1199,7 +1292,7 @@21.285 load_reg( R_ECX, Rm );21.286 ADD_r32_r32( R_ECX, R_EAX );21.287 MMU_TRANSLATE_READ( R_EAX )21.288 - MEM_READ_BYTE( R_EAX, R_EAX );21.289 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, 0 );21.290 store_reg( R_EAX, Rn );21.291 sh4_x86.tstate = TSTATE_NONE;21.292 :}21.293 @@ -1208,7 +1301,7 @@21.294 load_spreg( R_EAX, R_GBR );21.295 ADD_imm32_r32( disp, R_EAX );21.296 MMU_TRANSLATE_READ( R_EAX );21.297 - MEM_READ_BYTE( R_EAX, R_EAX );21.298 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, 16 );21.299 store_reg( R_EAX, 0 );21.300 sh4_x86.tstate = TSTATE_NONE;21.301 :}21.302 @@ -1217,7 +1310,7 @@21.303 load_reg( R_EAX, Rm );21.304 ADD_imm32_r32( disp, R_EAX );21.305 MMU_TRANSLATE_READ( R_EAX );21.306 - MEM_READ_BYTE( R_EAX, R_EAX );21.307 + MEM_READ_BYTE_CACHED( R_EAX, R_EAX, Rm );21.308 store_reg( R_EAX, 0 );21.309 sh4_x86.tstate = TSTATE_NONE;21.310 :}21.311 @@ -1226,8 +1319,7 @@21.312 load_reg( R_EAX, Rn );21.313 check_walign32(R_EAX);21.314 MMU_TRANSLATE_WRITE( R_EAX );21.315 - load_reg( R_EDX, Rm );21.316 - MEM_WRITE_LONG( R_EAX, R_EDX );21.317 + MEM_WRITE_LONG_CACHED( R_EAX, Rm, Rn );21.318 sh4_x86.tstate = TSTATE_NONE;21.319 :}21.320 MOV.L Rm, @-Rn {:21.321 @@ -1236,9 +1328,8 @@21.322 ADD_imm8s_r32( -4, R_EAX );21.323 check_walign32( R_EAX );21.324 MMU_TRANSLATE_WRITE( R_EAX );21.325 - load_reg( R_EDX, Rm );21.326 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.327 - MEM_WRITE_LONG( R_EAX, R_EDX );21.328 + MEM_WRITE_LONG_CACHED( R_EAX, Rm, Rn );21.329 sh4_x86.tstate = TSTATE_NONE;21.330 :}21.331 MOV.L Rm, @(R0, Rn) {:21.332 @@ -1248,8 +1339,7 @@21.333 ADD_r32_r32( R_ECX, R_EAX );21.334 check_walign32( R_EAX );21.335 MMU_TRANSLATE_WRITE( R_EAX );21.336 - load_reg( R_EDX, Rm );21.337 - MEM_WRITE_LONG( R_EAX, R_EDX );21.338 + MEM_WRITE_LONG_CACHED( R_EAX, Rm, 0 );21.339 sh4_x86.tstate = TSTATE_NONE;21.340 :}21.341 MOV.L R0, @(disp, GBR) {:21.342 @@ -1258,8 +1348,7 @@21.343 ADD_imm32_r32( disp, R_EAX );21.344 check_walign32( R_EAX );21.345 MMU_TRANSLATE_WRITE( R_EAX );21.346 - load_reg( R_EDX, 0 );21.347 - MEM_WRITE_LONG( R_EAX, R_EDX );21.348 + MEM_WRITE_LONG_CACHED( R_EAX, 0, 16 );21.349 sh4_x86.tstate = TSTATE_NONE;21.350 :}21.351 MOV.L Rm, @(disp, Rn) {:21.352 @@ -1268,8 +1357,7 @@21.353 ADD_imm32_r32( disp, R_EAX );21.354 check_walign32( R_EAX );21.355 MMU_TRANSLATE_WRITE( R_EAX );21.356 - load_reg( R_EDX, Rm );21.357 - MEM_WRITE_LONG( R_EAX, R_EDX );21.358 + MEM_WRITE_LONG_CACHED( R_EAX, Rm, Rn );21.359 sh4_x86.tstate = TSTATE_NONE;21.360 :}21.361 MOV.L @Rm, Rn {:21.362 @@ -1277,7 +1365,7 @@21.363 load_reg( R_EAX, Rm );21.364 check_ralign32( R_EAX );21.365 MMU_TRANSLATE_READ( R_EAX );21.366 - MEM_READ_LONG( R_EAX, R_EAX );21.367 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.368 store_reg( R_EAX, Rn );21.369 sh4_x86.tstate = TSTATE_NONE;21.370 :}21.371 @@ -1287,7 +1375,7 @@21.372 check_ralign32( R_EAX );21.373 MMU_TRANSLATE_READ( R_EAX );21.374 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.375 - MEM_READ_LONG( R_EAX, R_EAX );21.376 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.377 store_reg( R_EAX, Rn );21.378 sh4_x86.tstate = TSTATE_NONE;21.379 :}21.380 @@ -1298,7 +1386,7 @@21.381 ADD_r32_r32( R_ECX, R_EAX );21.382 check_ralign32( R_EAX );21.383 MMU_TRANSLATE_READ( R_EAX );21.384 - MEM_READ_LONG( R_EAX, R_EAX );21.385 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, 0 );21.386 store_reg( R_EAX, Rn );21.387 sh4_x86.tstate = TSTATE_NONE;21.388 :}21.389 @@ -1308,7 +1396,7 @@21.390 ADD_imm32_r32( disp, R_EAX );21.391 check_ralign32( R_EAX );21.392 MMU_TRANSLATE_READ( R_EAX );21.393 - MEM_READ_LONG( R_EAX, R_EAX );21.394 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, 16 );21.395 store_reg( R_EAX, 0 );21.396 sh4_x86.tstate = TSTATE_NONE;21.397 :}21.398 @@ -1337,7 +1425,7 @@21.399 load_imm32( R_EAX, (pc-sh4_x86.block_start_pc) + disp + 4 - (pc&0x03) );21.400 ADD_sh4r_r32( R_PC, R_EAX );21.401 MMU_TRANSLATE_READ( R_EAX );21.402 - MEM_READ_LONG( R_EAX, R_EAX );21.403 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, 16 );21.404 sh4_x86.tstate = TSTATE_NONE;21.405 }21.406 store_reg( R_EAX, Rn );21.407 @@ -1349,7 +1437,7 @@21.408 ADD_imm8s_r32( disp, R_EAX );21.409 check_ralign32( R_EAX );21.410 MMU_TRANSLATE_READ( R_EAX );21.411 - MEM_READ_LONG( R_EAX, R_EAX );21.412 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.413 store_reg( R_EAX, Rn );21.414 sh4_x86.tstate = TSTATE_NONE;21.415 :}21.416 @@ -1358,8 +1446,7 @@21.417 load_reg( R_EAX, Rn );21.418 check_walign16( R_EAX );21.419 MMU_TRANSLATE_WRITE( R_EAX )21.420 - load_reg( R_EDX, Rm );21.421 - MEM_WRITE_WORD( R_EAX, R_EDX );21.422 + MEM_WRITE_WORD_CACHED( R_EAX, Rm, Rn );21.423 sh4_x86.tstate = TSTATE_NONE;21.424 :}21.425 MOV.W Rm, @-Rn {:21.426 @@ -1368,9 +1455,8 @@21.427 ADD_imm8s_r32( -2, R_EAX );21.428 check_walign16( R_EAX );21.429 MMU_TRANSLATE_WRITE( R_EAX );21.430 - load_reg( R_EDX, Rm );21.431 ADD_imm8s_sh4r( -2, REG_OFFSET(r[Rn]) );21.432 - MEM_WRITE_WORD( R_EAX, R_EDX );21.433 + MEM_WRITE_WORD_CACHED( R_EAX, Rm, Rn );21.434 sh4_x86.tstate = TSTATE_NONE;21.435 :}21.436 MOV.W Rm, @(R0, Rn) {:21.437 @@ -1380,8 +1466,7 @@21.438 ADD_r32_r32( R_ECX, R_EAX );21.439 check_walign16( R_EAX );21.440 MMU_TRANSLATE_WRITE( R_EAX );21.441 - load_reg( R_EDX, Rm );21.442 - MEM_WRITE_WORD( R_EAX, R_EDX );21.443 + MEM_WRITE_WORD_CACHED( R_EAX, Rm, 0 );21.444 sh4_x86.tstate = TSTATE_NONE;21.445 :}21.446 MOV.W R0, @(disp, GBR) {:21.447 @@ -1390,8 +1475,7 @@21.448 ADD_imm32_r32( disp, R_EAX );21.449 check_walign16( R_EAX );21.450 MMU_TRANSLATE_WRITE( R_EAX );21.451 - load_reg( R_EDX, 0 );21.452 - MEM_WRITE_WORD( R_EAX, R_EDX );21.453 + MEM_WRITE_WORD_CACHED( R_EAX, 0, 16 );21.454 sh4_x86.tstate = TSTATE_NONE;21.455 :}21.456 MOV.W R0, @(disp, Rn) {:21.457 @@ -1400,8 +1484,7 @@21.458 ADD_imm32_r32( disp, R_EAX );21.459 check_walign16( R_EAX );21.460 MMU_TRANSLATE_WRITE( R_EAX );21.461 - load_reg( R_EDX, 0 );21.462 - MEM_WRITE_WORD( R_EAX, R_EDX );21.463 + MEM_WRITE_WORD_CACHED( R_EAX, 0, Rn );21.464 sh4_x86.tstate = TSTATE_NONE;21.465 :}21.466 MOV.W @Rm, Rn {:21.467 @@ -1409,7 +1492,7 @@21.468 load_reg( R_EAX, Rm );21.469 check_ralign16( R_EAX );21.470 MMU_TRANSLATE_READ( R_EAX );21.471 - MEM_READ_WORD( R_EAX, R_EAX );21.472 + MEM_READ_WORD_CACHED( R_EAX, R_EAX, Rm );21.473 store_reg( R_EAX, Rn );21.474 sh4_x86.tstate = TSTATE_NONE;21.475 :}21.476 @@ -1419,7 +1502,7 @@21.477 check_ralign16( R_EAX );21.478 MMU_TRANSLATE_READ( R_EAX );21.479 ADD_imm8s_sh4r( 2, REG_OFFSET(r[Rm]) );21.480 - MEM_READ_WORD( R_EAX, R_EAX );21.481 + MEM_READ_WORD_CACHED( R_EAX, R_EAX, Rm );21.482 store_reg( R_EAX, Rn );21.483 sh4_x86.tstate = TSTATE_NONE;21.484 :}21.485 @@ -1430,7 +1513,7 @@21.486 ADD_r32_r32( R_ECX, R_EAX );21.487 check_ralign16( R_EAX );21.488 MMU_TRANSLATE_READ( R_EAX );21.489 - MEM_READ_WORD( R_EAX, R_EAX );21.490 + MEM_READ_WORD_CACHED( R_EAX, R_EAX, 0 );21.491 store_reg( R_EAX, Rn );21.492 sh4_x86.tstate = TSTATE_NONE;21.493 :}21.494 @@ -1440,7 +1523,7 @@21.495 ADD_imm32_r32( disp, R_EAX );21.496 check_ralign16( R_EAX );21.497 MMU_TRANSLATE_READ( R_EAX );21.498 - MEM_READ_WORD( R_EAX, R_EAX );21.499 + MEM_READ_WORD_CACHED( R_EAX, R_EAX, 16 );21.500 store_reg( R_EAX, 0 );21.501 sh4_x86.tstate = TSTATE_NONE;21.502 :}21.503 @@ -1471,7 +1554,7 @@21.504 ADD_imm32_r32( disp, R_EAX );21.505 check_ralign16( R_EAX );21.506 MMU_TRANSLATE_READ( R_EAX );21.507 - MEM_READ_WORD( R_EAX, R_EAX );21.508 + MEM_READ_WORD_CACHED( R_EAX, R_EAX, Rm );21.509 store_reg( R_EAX, 0 );21.510 sh4_x86.tstate = TSTATE_NONE;21.511 :}21.512 @@ -1491,8 +1574,7 @@21.513 load_reg( R_EAX, Rn );21.514 check_walign32( R_EAX );21.515 MMU_TRANSLATE_WRITE( R_EAX );21.516 - load_reg( R_EDX, 0 );21.517 - MEM_WRITE_LONG( R_EAX, R_EDX );21.518 + MEM_WRITE_LONG_CACHED( R_EAX, 0, Rn );21.519 sh4_x86.tstate = TSTATE_NONE;21.520 :}21.522 @@ -1842,14 +1924,11 @@21.523 if( sh4_x86.double_size ) {21.524 check_walign64( R_EAX );21.525 MMU_TRANSLATE_WRITE( R_EAX );21.526 - load_dr0( R_EDX, FRm );21.527 - load_dr1( R_ECX, FRm );21.528 - MEM_WRITE_DOUBLE( R_EAX, R_EDX, R_ECX );21.529 + MEM_WRITE_DOUBLE_CACHED( R_EAX, FRm, Rn );21.530 } else {21.531 check_walign32( R_EAX );21.532 MMU_TRANSLATE_WRITE( R_EAX );21.533 - load_fr( R_EDX, FRm );21.534 - MEM_WRITE_LONG( R_EAX, R_EDX );21.535 + MEM_WRITE_FLOAT_CACHED( R_EAX, FRm, Rn );21.536 }21.537 sh4_x86.tstate = TSTATE_NONE;21.538 :}21.539 @@ -1860,13 +1939,13 @@21.540 if( sh4_x86.double_size ) {21.541 check_ralign64( R_EAX );21.542 MMU_TRANSLATE_READ( R_EAX );21.543 - MEM_READ_DOUBLE( R_EAX, R_EDX, R_EAX );21.544 + MEM_READ_DOUBLE_CACHED( R_EAX, R_EDX, R_EAX, Rm );21.545 store_dr0( R_EDX, FRn );21.546 store_dr1( R_EAX, FRn );21.547 } else {21.548 check_ralign32( R_EAX );21.549 MMU_TRANSLATE_READ( R_EAX );21.550 - MEM_READ_LONG( R_EAX, R_EAX );21.551 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.552 store_fr( R_EAX, FRn );21.553 }21.554 sh4_x86.tstate = TSTATE_NONE;21.555 @@ -1877,19 +1956,16 @@21.556 load_reg( R_EAX, Rn );21.557 if( sh4_x86.double_size ) {21.558 check_walign64( R_EAX );21.559 - ADD_imm8s_r32(-8,R_EAX);21.560 + LEA_r32disp8_r32( R_EAX, -8, R_EAX );21.561 MMU_TRANSLATE_WRITE( R_EAX );21.562 - load_dr0( R_EDX, FRm );21.563 - load_dr1( R_ECX, FRm );21.564 ADD_imm8s_sh4r(-8,REG_OFFSET(r[Rn]));21.565 - MEM_WRITE_DOUBLE( R_EAX, R_EDX, R_ECX );21.566 + MEM_WRITE_DOUBLE_CACHED( R_EAX, FRm, Rn );21.567 } else {21.568 check_walign32( R_EAX );21.569 - ADD_imm8s_r32( -4, R_EAX );21.570 + LEA_r32disp8_r32( R_EAX, -4, R_EAX );21.571 MMU_TRANSLATE_WRITE( R_EAX );21.572 - load_fr( R_EDX, FRm );21.573 ADD_imm8s_sh4r(-4,REG_OFFSET(r[Rn]));21.574 - MEM_WRITE_LONG( R_EAX, R_EDX );21.575 + MEM_WRITE_FLOAT_CACHED( R_EAX, FRm, Rn );21.576 }21.577 sh4_x86.tstate = TSTATE_NONE;21.578 :}21.579 @@ -1901,14 +1977,14 @@21.580 check_ralign64( R_EAX );21.581 MMU_TRANSLATE_READ( R_EAX );21.582 ADD_imm8s_sh4r( 8, REG_OFFSET(r[Rm]) );21.583 - MEM_READ_DOUBLE( R_EAX, R_EDX, R_EAX );21.584 + MEM_READ_DOUBLE_CACHED( R_EAX, R_EDX, R_EAX, Rm );21.585 store_dr0( R_EDX, FRn );21.586 store_dr1( R_EAX, FRn );21.587 } else {21.588 check_ralign32( R_EAX );21.589 MMU_TRANSLATE_READ( R_EAX );21.590 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.591 - MEM_READ_LONG( R_EAX, R_EAX );21.592 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.593 store_fr( R_EAX, FRn );21.594 }21.595 sh4_x86.tstate = TSTATE_NONE;21.596 @@ -1921,14 +1997,11 @@21.597 if( sh4_x86.double_size ) {21.598 check_walign64( R_EAX );21.599 MMU_TRANSLATE_WRITE( R_EAX );21.600 - load_dr0( R_EDX, FRm );21.601 - load_dr1( R_ECX, FRm );21.602 - MEM_WRITE_DOUBLE( R_EAX, R_EDX, R_ECX );21.603 + MEM_WRITE_DOUBLE_CACHED( R_EAX, FRm, 0 );21.604 } else {21.605 check_walign32( R_EAX );21.606 MMU_TRANSLATE_WRITE( R_EAX );21.607 - load_fr( R_EDX, FRm );21.608 - MEM_WRITE_LONG( R_EAX, R_EDX ); // 1221.609 + MEM_WRITE_FLOAT_CACHED( R_EAX, FRm, 0 );21.610 }21.611 sh4_x86.tstate = TSTATE_NONE;21.612 :}21.613 @@ -1940,13 +2013,13 @@21.614 if( sh4_x86.double_size ) {21.615 check_ralign64( R_EAX );21.616 MMU_TRANSLATE_READ( R_EAX );21.617 - MEM_READ_DOUBLE( R_EAX, R_ECX, R_EAX );21.618 + MEM_READ_DOUBLE_CACHED( R_EAX, R_ECX, R_EAX, 0 );21.619 store_dr0( R_ECX, FRn );21.620 store_dr1( R_EAX, FRn );21.621 } else {21.622 check_ralign32( R_EAX );21.623 MMU_TRANSLATE_READ( R_EAX );21.624 - MEM_READ_LONG( R_EAX, R_EAX );21.625 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, 0 );21.626 store_fr( R_EAX, FRn );21.627 }21.628 sh4_x86.tstate = TSTATE_NONE;21.629 @@ -2363,7 +2436,7 @@21.630 check_ralign32( R_EAX );21.631 MMU_TRANSLATE_READ( R_EAX );21.632 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.633 - MEM_READ_LONG( R_EAX, R_EAX );21.634 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.635 store_spreg( R_EAX, R_GBR );21.636 sh4_x86.tstate = TSTATE_NONE;21.637 :}21.638 @@ -2377,7 +2450,7 @@21.639 check_ralign32( R_EAX );21.640 MMU_TRANSLATE_READ( R_EAX );21.641 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.642 - MEM_READ_LONG( R_EAX, R_EAX );21.643 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.644 call_func1( sh4_write_sr, R_EAX );21.645 sh4_x86.priv_checked = FALSE;21.646 sh4_x86.fpuen_checked = FALSE;21.647 @@ -2391,7 +2464,7 @@21.648 check_ralign32( R_EAX );21.649 MMU_TRANSLATE_READ( R_EAX );21.650 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.651 - MEM_READ_LONG( R_EAX, R_EAX );21.652 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.653 store_spreg( R_EAX, R_VBR );21.654 sh4_x86.tstate = TSTATE_NONE;21.655 :}21.656 @@ -2402,7 +2475,7 @@21.657 check_ralign32( R_EAX );21.658 MMU_TRANSLATE_READ( R_EAX );21.659 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.660 - MEM_READ_LONG( R_EAX, R_EAX );21.661 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.662 store_spreg( R_EAX, R_SSR );21.663 sh4_x86.tstate = TSTATE_NONE;21.664 :}21.665 @@ -2413,7 +2486,7 @@21.666 check_ralign32( R_EAX );21.667 MMU_TRANSLATE_READ( R_EAX );21.668 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.669 - MEM_READ_LONG( R_EAX, R_EAX );21.670 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.671 store_spreg( R_EAX, R_SGR );21.672 sh4_x86.tstate = TSTATE_NONE;21.673 :}21.674 @@ -2424,7 +2497,7 @@21.675 check_ralign32( R_EAX );21.676 MMU_TRANSLATE_READ( R_EAX );21.677 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.678 - MEM_READ_LONG( R_EAX, R_EAX );21.679 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.680 store_spreg( R_EAX, R_SPC );21.681 sh4_x86.tstate = TSTATE_NONE;21.682 :}21.683 @@ -2435,7 +2508,7 @@21.684 check_ralign32( R_EAX );21.685 MMU_TRANSLATE_READ( R_EAX );21.686 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.687 - MEM_READ_LONG( R_EAX, R_EAX );21.688 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.689 store_spreg( R_EAX, R_DBR );21.690 sh4_x86.tstate = TSTATE_NONE;21.691 :}21.692 @@ -2446,7 +2519,7 @@21.693 check_ralign32( R_EAX );21.694 MMU_TRANSLATE_READ( R_EAX );21.695 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.696 - MEM_READ_LONG( R_EAX, R_EAX );21.697 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.698 store_spreg( R_EAX, REG_OFFSET(r_bank[Rn_BANK]) );21.699 sh4_x86.tstate = TSTATE_NONE;21.700 :}21.701 @@ -2465,7 +2538,7 @@21.702 check_ralign32( R_EAX );21.703 MMU_TRANSLATE_READ( R_EAX );21.704 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.705 - MEM_READ_LONG( R_EAX, R_EAX );21.706 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.707 call_func1( sh4_write_fpscr, R_EAX );21.708 sh4_x86.tstate = TSTATE_NONE;21.709 return 2;21.710 @@ -2483,7 +2556,7 @@21.711 check_ralign32( R_EAX );21.712 MMU_TRANSLATE_READ( R_EAX );21.713 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.714 - MEM_READ_LONG( R_EAX, R_EAX );21.715 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.716 store_spreg( R_EAX, R_FPUL );21.717 sh4_x86.tstate = TSTATE_NONE;21.718 :}21.719 @@ -2498,7 +2571,7 @@21.720 check_ralign32( R_EAX );21.721 MMU_TRANSLATE_READ( R_EAX );21.722 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.723 - MEM_READ_LONG( R_EAX, R_EAX );21.724 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.725 store_spreg( R_EAX, R_MACH );21.726 sh4_x86.tstate = TSTATE_NONE;21.727 :}21.728 @@ -2513,7 +2586,7 @@21.729 check_ralign32( R_EAX );21.730 MMU_TRANSLATE_READ( R_EAX );21.731 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.732 - MEM_READ_LONG( R_EAX, R_EAX );21.733 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.734 store_spreg( R_EAX, R_MACL );21.735 sh4_x86.tstate = TSTATE_NONE;21.736 :}21.737 @@ -2528,7 +2601,7 @@21.738 check_ralign32( R_EAX );21.739 MMU_TRANSLATE_READ( R_EAX );21.740 ADD_imm8s_sh4r( 4, REG_OFFSET(r[Rm]) );21.741 - MEM_READ_LONG( R_EAX, R_EAX );21.742 + MEM_READ_LONG_CACHED( R_EAX, R_EAX, Rm );21.743 store_spreg( R_EAX, R_PR );21.744 sh4_x86.tstate = TSTATE_NONE;21.745 :}21.746 @@ -2632,12 +2705,11 @@21.747 check_walign32( R_EAX );21.748 ADD_imm8s_r32( -4, R_EAX );21.749 MMU_TRANSLATE_WRITE( R_EAX );21.750 - MOV_r32_esp8( R_EAX, 0 );21.751 + MOV_r32_r32( R_EAX, R_EBX );21.752 call_func0( sh4_read_sr );21.753 MOV_r32_r32( R_EAX, R_EDX );21.754 - MOV_esp8_r32( 0, R_EAX );21.755 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.756 - MEM_WRITE_LONG( R_EAX, R_EDX );21.757 + MEM_WRITE_LONG( R_EBX, R_EDX );21.758 sh4_x86.tstate = TSTATE_NONE;21.759 :}21.760 STC.L VBR, @-Rn {:21.761 @@ -2647,9 +2719,8 @@21.762 check_walign32( R_EAX );21.763 ADD_imm8s_r32( -4, R_EAX );21.764 MMU_TRANSLATE_WRITE( R_EAX );21.765 - load_spreg( R_EDX, R_VBR );21.766 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.767 - MEM_WRITE_LONG( R_EAX, R_EDX );21.768 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_VBR, Rn );21.769 sh4_x86.tstate = TSTATE_NONE;21.770 :}21.771 STC.L SSR, @-Rn {:21.772 @@ -2659,9 +2730,8 @@21.773 check_walign32( R_EAX );21.774 ADD_imm8s_r32( -4, R_EAX );21.775 MMU_TRANSLATE_WRITE( R_EAX );21.776 - load_spreg( R_EDX, R_SSR );21.777 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.778 - MEM_WRITE_LONG( R_EAX, R_EDX );21.779 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_SSR, Rn );21.780 sh4_x86.tstate = TSTATE_NONE;21.781 :}21.782 STC.L SPC, @-Rn {:21.783 @@ -2671,9 +2741,8 @@21.784 check_walign32( R_EAX );21.785 ADD_imm8s_r32( -4, R_EAX );21.786 MMU_TRANSLATE_WRITE( R_EAX );21.787 - load_spreg( R_EDX, R_SPC );21.788 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.789 - MEM_WRITE_LONG( R_EAX, R_EDX );21.790 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_SPC, Rn );21.791 sh4_x86.tstate = TSTATE_NONE;21.792 :}21.793 STC.L SGR, @-Rn {:21.794 @@ -2683,9 +2752,8 @@21.795 check_walign32( R_EAX );21.796 ADD_imm8s_r32( -4, R_EAX );21.797 MMU_TRANSLATE_WRITE( R_EAX );21.798 - load_spreg( R_EDX, R_SGR );21.799 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.800 - MEM_WRITE_LONG( R_EAX, R_EDX );21.801 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_SGR, Rn );21.802 sh4_x86.tstate = TSTATE_NONE;21.803 :}21.804 STC.L DBR, @-Rn {:21.805 @@ -2695,9 +2763,8 @@21.806 check_walign32( R_EAX );21.807 ADD_imm8s_r32( -4, R_EAX );21.808 MMU_TRANSLATE_WRITE( R_EAX );21.809 - load_spreg( R_EDX, R_DBR );21.810 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.811 - MEM_WRITE_LONG( R_EAX, R_EDX );21.812 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_DBR, Rn );21.813 sh4_x86.tstate = TSTATE_NONE;21.814 :}21.815 STC.L Rm_BANK, @-Rn {:21.816 @@ -2707,9 +2774,8 @@21.817 check_walign32( R_EAX );21.818 ADD_imm8s_r32( -4, R_EAX );21.819 MMU_TRANSLATE_WRITE( R_EAX );21.820 - load_spreg( R_EDX, REG_OFFSET(r_bank[Rm_BANK]) );21.821 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.822 - MEM_WRITE_LONG( R_EAX, R_EDX );21.823 + MEM_WRITE_LONG_CACHED_SP( R_EAX, REG_OFFSET(r_bank[Rm_BANK]), Rn );21.824 sh4_x86.tstate = TSTATE_NONE;21.825 :}21.826 STC.L GBR, @-Rn {:21.827 @@ -2718,9 +2784,8 @@21.828 check_walign32( R_EAX );21.829 ADD_imm8s_r32( -4, R_EAX );21.830 MMU_TRANSLATE_WRITE( R_EAX );21.831 - load_spreg( R_EDX, R_GBR );21.832 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.833 - MEM_WRITE_LONG( R_EAX, R_EDX );21.834 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_GBR, Rn );21.835 sh4_x86.tstate = TSTATE_NONE;21.836 :}21.837 STS FPSCR, Rn {:21.838 @@ -2736,9 +2801,8 @@21.839 check_walign32( R_EAX );21.840 ADD_imm8s_r32( -4, R_EAX );21.841 MMU_TRANSLATE_WRITE( R_EAX );21.842 - load_spreg( R_EDX, R_FPSCR );21.843 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.844 - MEM_WRITE_LONG( R_EAX, R_EDX );21.845 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_FPSCR, Rn );21.846 sh4_x86.tstate = TSTATE_NONE;21.847 :}21.848 STS FPUL, Rn {:21.849 @@ -2754,9 +2818,8 @@21.850 check_walign32( R_EAX );21.851 ADD_imm8s_r32( -4, R_EAX );21.852 MMU_TRANSLATE_WRITE( R_EAX );21.853 - load_spreg( R_EDX, R_FPUL );21.854 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.855 - MEM_WRITE_LONG( R_EAX, R_EDX );21.856 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_FPUL, Rn );21.857 sh4_x86.tstate = TSTATE_NONE;21.858 :}21.859 STS MACH, Rn {:21.860 @@ -2770,9 +2833,8 @@21.861 check_walign32( R_EAX );21.862 ADD_imm8s_r32( -4, R_EAX );21.863 MMU_TRANSLATE_WRITE( R_EAX );21.864 - load_spreg( R_EDX, R_MACH );21.865 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.866 - MEM_WRITE_LONG( R_EAX, R_EDX );21.867 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_MACH, Rn );21.868 sh4_x86.tstate = TSTATE_NONE;21.869 :}21.870 STS MACL, Rn {:21.871 @@ -2786,9 +2848,8 @@21.872 check_walign32( R_EAX );21.873 ADD_imm8s_r32( -4, R_EAX );21.874 MMU_TRANSLATE_WRITE( R_EAX );21.875 - load_spreg( R_EDX, R_MACL );21.876 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.877 - MEM_WRITE_LONG( R_EAX, R_EDX );21.878 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_MACL, Rn );21.879 sh4_x86.tstate = TSTATE_NONE;21.880 :}21.881 STS PR, Rn {:21.882 @@ -2802,9 +2863,8 @@21.883 check_walign32( R_EAX );21.884 ADD_imm8s_r32( -4, R_EAX );21.885 MMU_TRANSLATE_WRITE( R_EAX );21.886 - load_spreg( R_EDX, R_PR );21.887 ADD_imm8s_sh4r( -4, REG_OFFSET(r[Rn]) );21.888 - MEM_WRITE_LONG( R_EAX, R_EDX );21.889 + MEM_WRITE_LONG_CACHED_SP( R_EAX, R_PR, Rn );21.890 sh4_x86.tstate = TSTATE_NONE;21.891 :}
22.1 --- a/src/sh4/timer.c Sat Dec 20 02:53:41 2008 +000022.2 +++ b/src/sh4/timer.c Sat Dec 20 03:01:40 2008 +000022.3 @@ -44,9 +44,9 @@22.4 uint32_t sh4_bus_period = 2* 1000 / SH4_BASE_RATE;22.5 uint32_t sh4_peripheral_period = 4 * 2000 / SH4_BASE_RATE;22.7 -int32_t mmio_region_CPG_read( uint32_t reg )22.8 +MMIO_REGION_READ_FN( CPG, reg )22.9 {22.10 - return MMIO_READ( CPG, reg );22.11 + return MMIO_READ( CPG, reg&0xFFF );22.12 }22.14 /* CPU + bus dividers (note officially only the first 6 values are valid) */22.15 @@ -54,11 +54,11 @@22.16 /* Peripheral clock dividers (only first 5 are officially valid) */22.17 int pfc_divider[8] = { 2, 3, 4, 6, 8, 8, 8, 8 };22.19 -void mmio_region_CPG_write( uint32_t reg, uint32_t val )22.20 +MMIO_REGION_WRITE_FN( CPG, reg, val )22.21 {22.22 uint32_t div;22.23 uint32_t primary_clock = sh4_input_freq;22.24 -22.25 + reg &= 0xFFF;22.26 switch( reg ) {22.27 case FRQCR: /* Frequency control */22.28 if( (val & FRQCR_PLL1EN) == 0 )22.29 @@ -98,14 +98,14 @@22.31 uint32_t rtc_output_period;22.33 -int32_t mmio_region_RTC_read( uint32_t reg )22.34 +MMIO_REGION_READ_FN( RTC, reg )22.35 {22.36 - return MMIO_READ( RTC, reg );22.37 + return MMIO_READ( RTC, reg &0xFFF );22.38 }22.40 -void mmio_region_RTC_write( uint32_t reg, uint32_t val )22.41 +MMIO_REGION_WRITE_FN( RTC, reg, val )22.42 {22.43 - MMIO_WRITE( RTC, reg, val );22.44 + MMIO_WRITE( RTC, reg &0xFFF, val );22.45 }22.47 /********************************** TMU *************************************/22.48 @@ -140,22 +140,6 @@22.50 static struct TMU_timer TMU_timers[3];22.52 -int32_t mmio_region_TMU_read( uint32_t reg )22.53 -{22.54 - switch( reg ) {22.55 - case TCNT0:22.56 - TMU_count( 0, sh4r.slice_cycle );22.57 - break;22.58 - case TCNT1:22.59 - TMU_count( 1, sh4r.slice_cycle );22.60 - break;22.61 - case TCNT2:22.62 - TMU_count( 2, sh4r.slice_cycle );22.63 - break;22.64 - }22.65 - return MMIO_READ( TMU, reg );22.66 -}22.67 -22.68 void TMU_set_timer_control( int timer, int tcr )22.69 {22.70 uint32_t period = 1;22.71 @@ -261,10 +245,28 @@22.72 return value;22.73 }22.75 -void mmio_region_TMU_write( uint32_t reg, uint32_t val )22.76 +MMIO_REGION_READ_FN( TMU, reg )22.77 +{22.78 + reg &= 0xFFF;22.79 + switch( reg ) {22.80 + case TCNT0:22.81 + TMU_count( 0, sh4r.slice_cycle );22.82 + break;22.83 + case TCNT1:22.84 + TMU_count( 1, sh4r.slice_cycle );22.85 + break;22.86 + case TCNT2:22.87 + TMU_count( 2, sh4r.slice_cycle );22.88 + break;22.89 + }22.90 + return MMIO_READ( TMU, reg );22.91 +}22.92 +22.93 +MMIO_REGION_WRITE_FN( TMU, reg, val )22.94 {22.95 uint32_t oldval;22.96 int i;22.97 + reg &= 0xFFF;22.98 switch( reg ) {22.99 case TSTR:22.100 oldval = MMIO_READ( TMU, TSTR );
23.1 --- a/src/sh4/x86op.h Sat Dec 20 02:53:41 2008 +000023.2 +++ b/src/sh4/x86op.h Sat Dec 20 03:01:40 2008 +000023.3 @@ -134,8 +134,11 @@23.4 #define AND_imm8_r8(imm8, r1) OP(0x80); MODRM_rm32_r32(r1,4); OP(imm8)23.5 #define AND_imm8s_r32(imm8,r1) OP(0x83); MODRM_rm32_r32(r1,4); OP(imm8)23.6 #define AND_imm32_r32(imm,r1) OP(0x81); MODRM_rm32_r32(r1,4); OP32(imm)23.7 +#define AND_sh4r_r32(disp,r1) OP(0x23); MODRM_r32_sh4r(r1, disp)23.8 #define CALL_r32(r1) OP(0xFF); MODRM_rm32_r32(r1,2)23.9 -#define CALL_ptr(ptr) OP(0xE8); OP32( (((char *)ptr) - (char *)xlat_output) - 4)23.10 +#define CALL_ptr(ptr) OP(0xE8); OP32( (((char *)ptr) - (char *)xlat_output) - 4)23.11 +#define CALL_sh4r(disp) OP(0xFF); MODRM_r32_sh4r(2, disp)23.12 +#define CALL_r32ind(r1,disp) OP(0xFF); OP(0x50 + r1); OP(disp)23.13 #define CLC() OP(0xF8)23.14 #define CMC() OP(0xF5)23.15 #define CMP_sh4r_r32(disp,r1) OP(0x3B); MODRM_r32_sh4r(r1,disp)23.16 @@ -161,6 +164,8 @@23.17 #define MOVSX_r16_r32(r1,r2) OP(0x0F); OP(0xBF); MODRM_rm32_r32(r1,r2)23.18 #define MOVZX_r8_r32(r1,r2) OP(0x0F); OP(0xB6); MODRM_rm32_r32(r1,r2)23.19 #define MOVZX_r16_r32(r1,r2) OP(0x0F); OP(0xB7); MODRM_rm32_r32(r1,r2)23.20 +#define MOVZX_sh4r8_r32(disp,r1) OP(0x0F); OP(0xB6); MODRM_r32_sh4r(r1,disp)23.21 +#define MOVZX_sh4r16_r32(disp,r1) OP(0x0F); OP(0xB7); MODRM_r32_sh4r(r1,disp)23.22 #define MUL_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,4)23.23 #define NEG_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,3)23.24 #define NOT_r32(r1) OP(0xF7); MODRM_rm32_r32(r1,2)23.25 @@ -266,6 +271,7 @@23.26 #define JNC_exc(exc) OP(0x0F); OP(0x83); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)23.27 #define JNO_exc(exc) OP(0x0F); OP(0x81); sh4_x86_add_backpatch(xlat_output, pc, exc); OP32(0)23.29 +#define EXPJE_rel8(label) OP(0x3E); JE_rel8(label)23.31 /* Conditional moves ebp-rel */23.32 #define CMOVE_r32_r32(r1,r2) OP(0x0F); OP(0x44); MODRM_rm32_r32(r1,r2)
24.1 --- a/src/test/testsh4x86.c Sat Dec 20 02:53:41 2008 +000024.2 +++ b/src/test/testsh4x86.c Sat Dec 20 03:01:40 2008 +000024.3 @@ -85,6 +85,14 @@24.4 {24.5 return *(uint32_t *)(inbuf+(addr-start_addr));24.6 }24.7 +mem_region_fn_t FASTCALL sh7750_decode_address( sh4addr_t address )24.8 +{24.9 + return NULL;24.10 +}24.11 +void FASTCALL sh7750_decode_address_copy( sh4addr_t address, mem_region_fn_t out )24.12 +{24.13 +}24.14 +24.15 // Stubs24.16 gboolean sh4_execute_instruction( ) { return TRUE; }24.17 void sh4_accept_interrupt() {}24.18 @@ -175,6 +183,8 @@24.19 mmio_region_MMU.mem = malloc(4096);24.20 memset( mmio_region_MMU.mem, 0, 4096 );24.22 + ((uint32_t *)mmio_region_MMU.mem)[4] = 1;24.23 +24.24 in = fopen( input_file, "ro" );24.25 if( in == NULL ) {24.26 perror( "Unable to open input file" );24.27 @@ -198,7 +208,7 @@24.28 char buf[256];24.29 char op[256];24.30 uintptr_t pc2 = x86_disasm_instruction( pc, buf, sizeof(buf), op );24.31 - fprintf( stdout, "%s\n", buf );24.32 + fprintf( stdout, "%08x: %s\n", pc, buf );24.33 pc = pc2;24.34 }24.35 return 0;
.