Search
lxdream.org :: lxdream :: r929:fd8cb0c82f5f
lxdream 0.9.1
released Jun 29
Download Now
changeset929:fd8cb0c82f5f lxdream-mem
parent928:bf87fbdcc9a5
child930:07e5b11419db
authornkeynes
dateSat Dec 20 03:01:40 2008 +0000 (10 years ago)
branchlxdream-mem
First pass experiment using cached decoding.
src/aica/aica.c
src/asic.c
src/dreamcast.c
src/mem.c
src/mem.h
src/mmio.h
src/pvr2/pvr2.c
src/pvr2/pvr2mem.c
src/sh4/dmac.c
src/sh4/ia32abi.h
src/sh4/intc.c
src/sh4/mmu.c
src/sh4/pmm.c
src/sh4/scif.c
src/sh4/sh4.c
src/sh4/sh4.h
src/sh4/sh4core.h
src/sh4/sh4mem.c
src/sh4/sh4mmio.c
src/sh4/sh4mmio.h
src/sh4/sh4x86.in
src/sh4/timer.c
src/sh4/x86op.h
src/test/testsh4x86.c
1.1 --- a/src/aica/aica.c Sat Dec 20 02:53:41 2008 +0000
1.2 +++ b/src/aica/aica.c Sat Dec 20 03:01:40 2008 +0000
1.3 @@ -194,16 +194,18 @@
1.4 */
1.5
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.15
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 registers
1.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.41
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.55
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.67
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 +0000
2.2 +++ b/src/asic.c Sat Dec 20 03:01:40 2008 +0000
2.3 @@ -416,8 +416,38 @@
2.4 MMIO_WRITE( ASIC, SORTDMACTL, 0 );
2.5 }
2.6
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.46
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.95
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.105
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 +0000
3.2 +++ b/src/dreamcast.c Sat Dec 20 03:01:40 2008 +0000
3.3 @@ -58,6 +58,13 @@
3.4 struct dreamcast_module unknown_module = { "****", NULL, NULL, NULL, NULL,
3.5 NULL, NULL, NULL };
3.6
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 the
3.16 * dreamcast actually fit together.
3.17 @@ -75,12 +82,12 @@
3.18 dreamcast_register_module( &mem_module );
3.19
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_SH4STATS
3.58 sh4_stats_print(stdout);
3.59 #endif
3.60 + print_sh4mem_stats();
3.61 }
3.62
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 +0000
4.2 +++ b/src/mem.c Sat Dec 20 03:01:40 2008 +0000
4.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.14
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.27
4.28 do {
4.29 @@ -245,12 +246,13 @@
4.30 return &mem_rgn[num_mem_rgns-1];
4.31 }
4.32
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.39
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.46
4.47 mem = mem_alloc_pages( size>>LXDREAM_PAGE_BITS );
4.48
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.51
4.52 return mem;
4.53 }
4.54
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 +0000
5.2 +++ b/src/mem.h Sat Dec 20 03:01:40 2008 +0000
5.3 @@ -27,12 +27,24 @@
5.4 extern "C" {
5.5 #endif
5.6
5.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.26
5.27 #define MAX_IO_REGIONS 24
5.28 @@ -45,8 +57,8 @@
5.29 #define MEM_REGION_AUDIO_SCRATCH "Audio Scratch RAM"
5.30 #define MEM_REGION_FLASH "System Flash"
5.31
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 not
5.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 +0000
6.2 +++ b/src/mmio.h Sat Dec 20 03:01:40 2008 +0000
6.3 @@ -16,8 +16,8 @@
6.4 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6.5 * GNU General Public License for more details.
6.6 */
6.7 -#ifndef dream_mmio_H
6.8 -#define dream_mmio_H 1
6.9 +#ifndef lxdream_mmio_H
6.10 +#define lxdream_mmio_H 1
6.11
6.12 #ifdef __cplusplus
6.13 extern "C" {
6.14 @@ -28,6 +28,7 @@
6.15
6.16 #include <stdint.h>
6.17 #include <stdlib.h>
6.18 +#include "mem.h"
6.19
6.20 #define LXDREAM_PAGE_TABLE_ENTRIES 128*1024
6.21 #define LXDREAM_PAGE_SIZE 4096
6.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_BEGIN
6.34 #undef MMIO_REGION
6.35 #undef MMIO_REGION_LIST_END
6.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 write
6.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 #endif
6.79
6.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 #else
6.87
6.88 #ifndef MMIO_IFACE_INCLUDED
6.89 #define MMIO_IFACE_INCLUDED
6.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_END
6.101 #endif
6.102
6.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
6.111
7.1 --- a/src/pvr2/pvr2.c Sat Dec 20 02:53:41 2008 +0000
7.2 +++ b/src/pvr2/pvr2.c Sat Dec 20 03:01:40 2008 +0000
7.3 @@ -462,8 +462,9 @@
7.4 * This has to handle every single register individually as they all get masked
7.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.15
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.23
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.31
7.32
7.33
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.39
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 +0000
8.2 +++ b/src/pvr2/pvr2mem.c Sat Dec 20 03:01:40 2008 +0000
8.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.11
8.12 extern unsigned char *video_base;
8.13
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 aligned
8.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 aligned
8.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 +0000
9.2 +++ b/src/sh4/dmac.c Sat Dec 20 03:01:40 2008 +0000
9.3 @@ -82,13 +82,14 @@
9.4 */
9.5 }
9.6
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.13
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 +0000
10.2 +++ b/src/sh4/ia32abi.h Sat Dec 20 03:01:40 2008 +0000
10.3 @@ -42,6 +42,22 @@
10.4 CALL_ptr(ptr);
10.5 }
10.6
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.29
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.65
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 +0000
11.2 +++ b/src/sh4/intc.c Sat Dec 20 03:01:40 2008 +0000
11.3 @@ -53,8 +53,9 @@
11.4 int priority[INT_NUM_SOURCES];
11.5 } intc_state;
11.6
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.17
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.24
11.25 void INTC_reset()
12.1 --- a/src/sh4/mmu.c Sat Dec 20 02:53:41 2008 +0000
12.2 +++ b/src/sh4/mmu.c Sat Dec 20 03:01:40 2008 +0000
12.3 @@ -143,8 +143,9 @@
12.4 }
12.5 }
12.6
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.17
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.27
12.28 #define ITLB_ENTRY(addr) ((addr>>7)&0x03)
12.29
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.42
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.51
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.60
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.76
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.85
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.92
12.93 /* Cache access - not implemented */
12.94
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 implemented
12.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 implemented
12.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 implemented
12.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 implemented
12.114 }
12.115
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.120
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.125
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.130
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 }
12.135
13.1 --- a/src/sh4/pmm.c Sat Dec 20 02:53:41 2008 +0000
13.2 +++ b/src/sh4/pmm.c Sat Dec 20 03:01:40 2008 +0000
13.3 @@ -131,8 +131,8 @@
13.4 }
13.5 }
13.6
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.17
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 +0000
14.2 +++ b/src/sh4/scif.c Sat Dec 20 03:01:40 2008 +0000
14.3 @@ -455,8 +455,9 @@
14.4 }
14.5 }
14.6
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.17
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 +0000
15.2 +++ b/src/sh4/sh4.c Sat Dec 20 03:01:40 2008 +0000
15.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.8
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.33
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.37
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.43
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.64
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.75
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 +0000
16.2 +++ b/src/sh4/sh4.h Sat Dec 20 03:01:40 2008 +0000
16.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.15
16.16 extern struct sh4_registers sh4r;
17.1 --- a/src/sh4/sh4core.h Sat Dec 20 02:53:41 2008 +0000
17.2 +++ b/src/sh4/sh4core.h Sat Dec 20 03:01:40 2008 +0000
17.3 @@ -170,6 +170,8 @@
17.4 uint32_t sh4_emulate_run_slice(uint32_t);
17.5
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 +0000
18.2 +++ b/src/sh4/sh4mem.c Sat Dec 20 03:01:40 2008 +0000
18.3 @@ -1,7 +1,6 @@
18.4 /**
18.5 * $Id$
18.6 - * sh4mem.c is responsible for the SH4's access to memory (including memory
18.7 - * mapped I/O), using the page maps created in mem.c
18.8 + * sh4mem.c is responsible for interfacing between the SH4's internal memory
18.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.17
18.18 -#define OC_BASE 0x1C000000
18.19 -#define OC_TOP 0x20000000
18.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.28
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.40
18.41 -#ifdef ENABLE_WATCH
18.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_ADDRESS
18.290 +#define RETURN_VIA(exc) do{ *(((void **)__builtin_frame_address(0))+1) = exc; return; } while(0)
18.291 #else
18.292 -#define CHECK_READ_WATCH( addr, size )
18.293 -#define CHECK_WRITE_WATCH( addr, size, val )
18.294 +#define RETURN_VIA(exc) return NULL
18.295 #endif
18.296
18.297 -#ifdef ENABLE_TRACE_IO
18.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 -#else
18.307 -#define TRACE_IO( str, p, r, ... )
18.308 -#define TRACE_P4IO( str, io, r, ... )
18.309 -#endif
18.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.371
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 now
18.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.440
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.466
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 case
18.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 cleanly
18.715 * into the same memory block
18.716 */
18.717 @@ -432,3 +410,109 @@
18.718 }
18.719 }
18.720
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 +0000
19.2 +++ b/src/sh4/sh4mmio.c Sat Dec 20 03:01:40 2008 +0000
19.3 @@ -72,9 +72,10 @@
19.4
19.5 MMIO_REGION_WRITE_DEFFN(BSC)
19.6
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.16
19.17 /********************************* UBC *************************************/
19.18
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.25
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 +0000
20.2 +++ b/src/sh4/sh4mmio.h Sat Dec 20 03:01:40 2008 +0000
20.3 @@ -243,22 +243,22 @@
20.4 void mmu_set_cache_mode( int );
20.5 void mmu_ldtlb(void);
20.6
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.39
20.40
20.41 #ifdef __cplusplus
21.1 --- a/src/sh4/sh4x86.in Sat Dec 20 02:53:41 2008 +0000
21.2 +++ b/src/sh4/sh4x86.in Sat Dec 20 03:01:40 2008 +0000
21.3 @@ -20,6 +20,7 @@
21.4
21.5 #include <assert.h>
21.6 #include <math.h>
21.7 +#include <stddef.h>
21.8
21.9 #ifndef NDEBUG
21.10 #define DEBUG_JUMPS 1
21.11 @@ -322,6 +323,111 @@
21.12 #include "sh4/ia32abi.h"
21.13 #endif
21.14
21.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 valid
21.19 + * and decode otherwise.
21.20 + * At conclusion of this:
21.21 + * R_EBX will contain the address
21.22 + * R_ECX will contain the memory region vtable
21.23 + * R_EAX, R_EDX (and any other volatiles) are clobbered
21.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.147
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.160
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.521
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 ); // 12
21.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 :}
21.892
22.1 --- a/src/sh4/timer.c Sat Dec 20 02:53:41 2008 +0000
22.2 +++ b/src/sh4/timer.c Sat Dec 20 03:01:40 2008 +0000
22.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.6
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.13
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.18
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.30
22.31 uint32_t rtc_output_period;
22.32
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.39
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.46
22.47 /********************************** TMU *************************************/
22.48 @@ -140,22 +140,6 @@
22.49
22.50 static struct TMU_timer TMU_timers[3];
22.51
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.74
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 +0000
23.2 +++ b/src/sh4/x86op.h Sat Dec 20 03:01:40 2008 +0000
23.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.28
23.29 +#define EXPJE_rel8(label) OP(0x3E); JE_rel8(label)
23.30
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 +0000
24.2 +++ b/src/test/testsh4x86.c Sat Dec 20 03:01:40 2008 +0000
24.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 // Stubs
24.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.21
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;
.