<html>
<body>
<div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream/src/sh4</tt></b></td></tr>
<tr><td><tt><a href="#file1">mmu.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+240</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-2</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">defbd44429d8 -> 677b1d85f1b4</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file2">mmu.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+10</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">defbd44429d8 -> 677b1d85f1b4</td></tr>
<tr><td><tt><a href="#file3">sh4core.in</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+11</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-26</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">defbd44429d8 -> 677b1d85f1b4</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file4">shadow.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+109</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-206</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">defbd44429d8 -> 677b1d85f1b4</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+370</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-234</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >4 modified files</small><br />
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
Fix MMU on non-translated platforms
- reintroduce old VMA translation functions (slightly modified)
- modify shadow processing to work on post-translated memory ops
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>mmu.c</b></big> <small id="info" style="color: #888888;" >defbd44429d8 -> 677b1d85f1b4</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/mmu.c
+++ lxdream/src/sh4/mmu.c
@@ -34,6 +34,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_region_fn_t *sh4_address_space;
mem_region_fn_t *sh4_user_address_space;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/* External address space (usually the same as the global ext_address_space) */
+static mem_region_fn_t *sh4_ext_address_space;
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /* Accessed from the UTLB accessor methods */
uint32_t mmu_urc;
uint32_t mmu_urb;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -92,6 +95,19 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#define IS_STOREQUEUE_PROTECTED() (mmu_user_storequeue_regions == &mmu_default_regions[DEFAULT_STOREQUEUE_SQMD_REGIONS])
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#ifndef SH4_TRANSLATOR
+/* Dummy MMU vtable functions */
+void mmu_utlb_init_vtable( struct utlb_entry *ent, struct utlb_page_entry *page, gboolean writable )
+{
+}
+void mmu_utlb_init_storequeue_vtable( struct utlb_entry *ent, struct utlb_page_entry *page )
+{
+}
+void mmu_utlb_1k_init_vtable( struct utlb_1k_entry *entry )
+{
+}
+#endif
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /*********************** Module public functions ****************************/
/**
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -101,6 +117,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
void MMU_init()
{
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ sh4_ext_address_space = ext_address_space;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sh4_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
sh4_user_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
mmu_user_storequeue_regions = &mmu_default_regions[DEFAULT_STOREQUEUE_REGIONS];
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -343,6 +360,14 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
/********************** Address space maintenance *************************/
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+mem_region_fn_t *mmu_set_ext_address_space( mem_region_fn_t *ext )
+{
+ mem_region_fn_t *old_ext = sh4_ext_address_space;
+ sh4_ext_address_space = ext;
+ mmu_set_tlb_enabled(IS_TLB_ENABLED());
+ return old_ext;
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
* MMU accessor functions just increment URC - fixup here if necessary
*/
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -415,10 +440,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mmu_utlb_register_all();
} else {
for( i=0, ptr = sh4_address_space; i<7; i++, ptr += LXDREAM_PAGE_TABLE_ENTRIES ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- memcpy( ptr, ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ memcpy( ptr, <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >sh4_</span>ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
for( i=0, ptr = sh4_user_address_space; i<4; i++, ptr += LXDREAM_PAGE_TABLE_ENTRIES ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- memcpy( ptr, ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ memcpy( ptr, <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >sh4_</span>ext_address_space, sizeof(mem_region_fn_t) * LXDREAM_PAGE_TABLE_ENTRIES );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
mmu_register_mem_region( 0xE0000000, 0xE4000000, &p4_region_storequeue );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -1190,6 +1215,219 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * Translate a virtual to physical address for reading, raising exceptions as
+ * observed.
+ * @param addr Pointer to the virtual memory address. On successful return,
+ * will be updated to contain the physical address.
+ */
+mem_region_fn_t FASTCALL mmu_get_region_for_vma_read( sh4vma_t *paddr )
+{
+ sh4vma_t addr = *paddr;
+ uint32_t mmucr = MMIO_READ(MMU,MMUCR);
+ if( addr & 0x80000000 ) {
+ if( IS_SH4_PRIVMODE() ) {
+ if( addr >= 0xE0000000 ) {
+ return sh4_address_space[((uint32_t)addr)>>12]; /* P4 - passthrough */
+ } else if( addr < 0xC0000000 ) {
+ /* P1, P2 regions are pass-through (no translation) */
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+ } else {
+ if( addr >= 0xE0000000 && addr < 0xE4000000 &&
+ ((mmucr&MMUCR_SQMD) == 0) ) {
+ /* Conditional user-mode access to the store-queue (no translation) */
+ return &p4_region_storequeue;
+ }
+ sh4_raise_exception(EXC_DATA_ADDR_READ);
+ return NULL;
+ }
+ }
+
+ if( (mmucr & MMUCR_AT) == 0 ) {
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+
+ /* If we get this far, translation is required */
+ int entryNo;
+ if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
+ entryNo = mmu_utlb_lookup_vpn_asid( addr );
+ } else {
+ entryNo = mmu_utlb_lookup_vpn( addr );
+ }
+
+ switch(entryNo) {
+ case -1:
+ RAISE_TLB_ERROR(EXC_TLB_MISS_READ,addr);
+ return NULL;
+ case -2:
+ RAISE_TLB_MULTIHIT_ERROR(addr);
+ return NULL;
+ default:
+ if( (mmu_utlb[entryNo].flags & TLB_USERMODE) == 0 &&
+ !IS_SH4_PRIVMODE() ) {
+ /* protection violation */
+ RAISE_MEM_ERROR(EXC_TLB_PROT_READ,addr);
+ return NULL;
+ }
+
+ /* finally generate the target address */
+ sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
+ (addr & (~mmu_utlb[entryNo].mask));
+ if( pma > 0x1C000000 ) { // Remap 1Cxx .. 1Fxx region to P4
+ addr = pma | 0xE0000000;
+ *paddr = addr;
+ return sh4_address_space[addr>>12];
+ } else {
+ *paddr = pma;
+ return sh4_ext_address_space[pma>>12];
+ }
+ }
+}
+
+/**
+ * Translate a virtual to physical address for prefetch, which mostly
+ * does not raise exceptions.
+ * @param addr Pointer to the virtual memory address. On successful return,
+ * will be updated to contain the physical address.
+ */
+mem_region_fn_t FASTCALL mmu_get_region_for_vma_prefetch( sh4vma_t *paddr )
+{
+ sh4vma_t addr = *paddr;
+ uint32_t mmucr = MMIO_READ(MMU,MMUCR);
+ if( addr & 0x80000000 ) {
+ if( IS_SH4_PRIVMODE() ) {
+ if( addr >= 0xE0000000 ) {
+ return sh4_address_space[((uint32_t)addr)>>12]; /* P4 - passthrough */
+ } else if( addr < 0xC0000000 ) {
+ /* P1, P2 regions are pass-through (no translation) */
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+ } else {
+ if( addr >= 0xE0000000 && addr < 0xE4000000 &&
+ ((mmucr&MMUCR_SQMD) == 0) ) {
+ /* Conditional user-mode access to the store-queue (no translation) */
+ return &p4_region_storequeue;
+ }
+ sh4_raise_exception(EXC_DATA_ADDR_READ);
+ return NULL;
+ }
+ }
+
+ if( (mmucr & MMUCR_AT) == 0 ) {
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+
+ /* If we get this far, translation is required */
+ int entryNo;
+ if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
+ entryNo = mmu_utlb_lookup_vpn_asid( addr );
+ } else {
+ entryNo = mmu_utlb_lookup_vpn( addr );
+ }
+
+ switch(entryNo) {
+ case -1:
+ return &mem_region_unmapped;
+ case -2:
+ RAISE_TLB_MULTIHIT_ERROR(addr);
+ return NULL;
+ default:
+ if( (mmu_utlb[entryNo].flags & TLB_USERMODE) == 0 &&
+ !IS_SH4_PRIVMODE() ) {
+ /* protection violation */
+ return &mem_region_unmapped;
+ }
+
+ /* finally generate the target address */
+ sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
+ (addr & (~mmu_utlb[entryNo].mask));
+ if( pma > 0x1C000000 ) { // Remap 1Cxx .. 1Fxx region to P4
+ addr = pma | 0xE0000000;
+ *paddr = addr;
+ return sh4_address_space[addr>>12];
+ } else {
+ *paddr = pma;
+ return sh4_ext_address_space[pma>>12];
+ }
+ }
+}
+
+/**
+ * Translate a virtual to physical address for writing, raising exceptions as
+ * observed.
+ */
+mem_region_fn_t FASTCALL mmu_get_region_for_vma_write( sh4vma_t *paddr )
+{
+ sh4vma_t addr = *paddr;
+ uint32_t mmucr = MMIO_READ(MMU,MMUCR);
+ if( addr & 0x80000000 ) {
+ if( IS_SH4_PRIVMODE() ) {
+ if( addr >= 0xE0000000 ) {
+ return sh4_address_space[((uint32_t)addr)>>12]; /* P4 - passthrough */
+ } else if( addr < 0xC0000000 ) {
+ /* P1, P2 regions are pass-through (no translation) */
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+ } else {
+ if( addr >= 0xE0000000 && addr < 0xE4000000 &&
+ ((mmucr&MMUCR_SQMD) == 0) ) {
+ /* Conditional user-mode access to the store-queue (no translation) */
+ return &p4_region_storequeue;
+ }
+ sh4_raise_exception(EXC_DATA_ADDR_WRITE);
+ return NULL;
+ }
+ }
+
+ if( (mmucr & MMUCR_AT) == 0 ) {
+ return sh4_ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ }
+
+ /* If we get this far, translation is required */
+ int entryNo;
+ if( ((mmucr & MMUCR_SV) == 0) || !IS_SH4_PRIVMODE() ) {
+ entryNo = mmu_utlb_lookup_vpn_asid( addr );
+ } else {
+ entryNo = mmu_utlb_lookup_vpn( addr );
+ }
+
+ switch(entryNo) {
+ case -1:
+ RAISE_TLB_ERROR(EXC_TLB_MISS_WRITE,addr);
+ return NULL;
+ case -2:
+ RAISE_TLB_MULTIHIT_ERROR(addr);
+ return NULL;
+ default:
+ if( IS_SH4_PRIVMODE() ? ((mmu_utlb[entryNo].flags & TLB_WRITABLE) == 0)
+ : ((mmu_utlb[entryNo].flags & TLB_USERWRITABLE) != TLB_USERWRITABLE) ) {
+ /* protection violation */
+ RAISE_MEM_ERROR(EXC_TLB_PROT_WRITE,addr);
+ return NULL;
+ }
+
+ if( (mmu_utlb[entryNo].flags & TLB_DIRTY) == 0 ) {
+ RAISE_MEM_ERROR(EXC_INIT_PAGE_WRITE, addr);
+ return NULL;
+ }
+
+ /* finally generate the target address */
+ sh4addr_t pma = (mmu_utlb[entryNo].ppn & mmu_utlb[entryNo].mask) |
+ (addr & (~mmu_utlb[entryNo].mask));
+ if( pma > 0x1C000000 ) { // Remap 1Cxx .. 1Fxx region to P4
+ addr = pma | 0xE0000000;
+ *paddr = addr;
+ return sh4_address_space[addr>>12];
+ } else {
+ *paddr = pma;
+ return sh4_ext_address_space[pma>>12];
+ }
+ }
+}
+
+
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /********************** TLB Direct-Access Regions ***************************/
#define ITLB_ENTRY(addr) ((addr>>7)&0x03)
</pre></div>
<hr /><a name="file2" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>mmu.h</b></big> <small id="info" style="color: #888888;" >defbd44429d8 -> 677b1d85f1b4</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/mmu.h
+++ lxdream/src/sh4/mmu.h
@@ -106,8 +106,18 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_region_fn_t tlb_multihit;
};
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/** Set the MMU's target external address space
+ * @return the previous address space.
+ */
+mem_region_fn_t *mmu_set_ext_address_space( mem_region_fn_t *space );
+
+/* Address translation functions */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sh4addr_t FASTCALL mmu_vma_to_phys_disasm( sh4vma_t vma );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+mem_region_fn_t FASTCALL mmu_get_region_for_vma_read( sh4vma_t *addr );
+mem_region_fn_t FASTCALL mmu_get_region_for_vma_write( sh4vma_t *addr );
+mem_region_fn_t FASTCALL mmu_get_region_for_vma_prefetch( sh4vma_t *addr );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/* Translator provided helpers */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > void mmu_utlb_init_vtable( struct utlb_entry *ent, struct utlb_page_entry *page, gboolean writable );
void mmu_utlb_1k_init_vtable( struct utlb_1k_entry *ent );
void mmu_utlb_init_storequeue_vtable( struct utlb_entry *ent, struct utlb_page_entry *page );
</pre></div>
<hr /><a name="file3" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>sh4core.in</b></big> <small id="info" style="color: #888888;" >defbd44429d8 -> 677b1d85f1b4</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/sh4core.in
+++ lxdream/src/sh4/sh4core.in
@@ -162,28 +162,14 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define ADDRSPACE (IS_SH4_PRIVMODE() ? sh4_address_space : sh4_user_address_space)
#define SQADDRSPACE (IS_SH4_PRIVMODE() ? storequeue_address_space : storequeue_user_address_space)
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#ifdef HAVE_FRAME_ADDRESS
-static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }
-#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:
-#define MEM_READ_BYTE( addr, val ) val = ((mem_read_exc_fn_t)ADDRSPACE[(addr)>>12]->read_byte)((addr), &&except)
-#define MEM_READ_BYTE_FOR_WRITE( addr, val ) val = ((mem_read_exc_fn_t)ADDRSPACE[(addr)>>12]->read_byte_for_write)((addr), &&except)
-#define MEM_READ_WORD( addr, val ) val = ((mem_read_exc_fn_t)ADDRSPACE[(addr)>>12]->read_word)((addr), &&except)
-#define MEM_READ_LONG( addr, val ) val = ((mem_read_exc_fn_t)ADDRSPACE[(addr)>>12]->read_long)((addr), &&except)
-#define MEM_WRITE_BYTE( addr, val ) ((mem_write_exc_fn_t)ADDRSPACE[(addr)>>12]->write_byte)((addr), (val), &&except)
-#define MEM_WRITE_WORD( addr, val ) ((mem_write_exc_fn_t)ADDRSPACE[(addr)>>12]->write_word)((addr), (val), &&except)
-#define MEM_WRITE_LONG( addr, val ) ((mem_write_exc_fn_t)ADDRSPACE[(addr)>>12]->write_long)((addr), (val), &&except)
-#define MEM_PREFETCH( addr ) ((mem_prefetch_exc_fn_t)ADDRSPACE[(addr)>>12]->prefetch)((addr), &&except)
-#else
-#define INIT_EXCEPTIONS(label)
-#define MEM_READ_BYTE( addr, val ) val = ADDRSPACE[(addr)>>12]->read_byte(addr)
-#define MEM_READ_BYTE_FOR_WRITE( addr, val ) val = ADDRSPACE[(addr)>>12]->read_byte_for_write(addr)
-#define MEM_READ_WORD( addr, val ) val = ADDRSPACE[(addr)>>12]->read_word(addr)
-#define MEM_READ_LONG( addr, val ) val = ADDRSPACE[(addr)>>12]->read_long(addr)
-#define MEM_WRITE_BYTE( addr, val ) ADDRSPACE[(addr)>>12]->write_byte(addr, val)
-#define MEM_WRITE_WORD( addr, val ) ADDRSPACE[(addr)>>12]->write_word(addr, val)
-#define MEM_WRITE_LONG( addr, val ) ADDRSPACE[(addr)>>12]->write_long(addr, val)
-#define MEM_PREFETCH( addr ) ADDRSPACE[(addr)>>12]->prefetch(addr)
-#endif
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define MEM_READ_BYTE( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_read(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { val = fntmp->read_byte(addrtmp); }
+#define MEM_READ_BYTE_FOR_WRITE( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_write(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { val = fntmp->read_byte_for_write(addrtmp); }
+#define MEM_READ_WORD( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_read(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { val = fntmp->read_word(addrtmp); }
+#define MEM_READ_LONG( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_read(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { val = fntmp->read_long(addrtmp); }
+#define MEM_WRITE_BYTE( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_write(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { fntmp->write_byte(addrtmp,val); }
+#define MEM_WRITE_WORD( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_write(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { fntmp->write_word(addrtmp,val); }
+#define MEM_WRITE_LONG( addr, val ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_write(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { fntmp->write_long(addrtmp,val); }
+#define MEM_PREFETCH( addr ) addrtmp = addr; if( (fntmp = mmu_get_region_for_vma_prefetch(&addrtmp)) == NULL ) { sh4r.in_delay_slot = 0; return TRUE; } else { fntmp->prefetch(addrtmp); }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#define FP_WIDTH (IS_FPU_DOUBLESIZE() ? 8 : 4)
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -346,10 +332,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > uint32_t tmp;
float ftmp;
double dtmp;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int64_t memtmp; // temporary holder for memory reads
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ sh4addr_t addrtmp; // temporary holder for memory addresses
+ mem_region_fn_t fntmp;
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- INIT_EXCEPTIONS(except)
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define R0 sh4r.r[0]
pc = sh4r.pc;
if( pc > 0xFFFFFF00 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -1306,7 +1292,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sh4r.pc = sh4r.new_pc;
sh4r.new_pc += 2;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-except:
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sh4r.in_delay_slot = 0;
return TRUE;
}
</pre></div>
<hr /><a name="file4" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/sh4</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>shadow.c</b></big> <small id="info" style="color: #888888;" >defbd44429d8 -> 677b1d85f1b4</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/sh4/shadow.c
+++ lxdream/src/sh4/shadow.c
@@ -23,18 +23,12 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#include "clock.h"
#include "mem.h"
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#include "mmio.h"
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #include "sh4/sh4.h"
#include "sh4/sh4core.h"
#include "sh4/sh4trans.h"
#include "sh4/mmu.h"
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#ifdef HAVE_FRAME_ADDRESS
-static FASTCALL __attribute__((noinline)) void *__first_arg(void *a, void *b) { return a; }
-#define INIT_EXCEPTIONS(label) goto *__first_arg(&&fnstart,&&label); fnstart:
-#else
-#define INIT_EXCEPTIONS(label)
-#endif
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > typedef enum {
READ_LONG,
WRITE_LONG,
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -53,13 +47,17 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > MemOp op;
sh4addr_t addr;
uint32_t value;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- sh4addr_t exception_pc;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > };
static struct sh4_registers shadow_sh4r;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static struct mem_region_fn **log_address_space;
-static struct mem_region_fn **check_address_space;
-static struct mem_region_fn **real_address_space;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static struct mem_region_fn **shadow_address_space;
+static struct mem_region_fn **p4_address_space;
+
+typedef enum {
+ SHADOW_LOG,
+ SHADOW_CHECK
+} shadow_mode_t;
+static shadow_mode_t shadow_address_mode = SHADOW_LOG;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#define MEM_LOG_SIZE 4096
static struct mem_log_entry *mem_log;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -68,7 +66,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
#define IS_STORE_QUEUE(X) (((X)&0xFC000000) == 0xE0000000)
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >, int exception</span> )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static void log_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
if( mem_log_posn == mem_log_size ) {
struct mem_log_entry *tmp = realloc(mem_log, mem_log_size * sizeof(struct mem_log_entry) * 2);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -79,11 +77,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_log[mem_log_posn].op = op;
mem_log[mem_log_posn].addr = addr;
mem_log[mem_log_posn].value = value;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( exception ) {
- mem_log[mem_log_posn].exception_pc = sh4r.pc;
- } else {
- mem_log[mem_log_posn].exception_pc = -1;
- }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_log_posn++;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -103,7 +96,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value<span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >, int *exception</span> )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static int32_t check_mem_op( MemOp op, sh4addr_t addr, uint32_t value )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
if( mem_check_posn >= mem_log_posn ) {
fprintf( stderr, "Unexpected interpreter memory operation: " );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -121,14 +114,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > print_mem_op(stderr, op, addr, value );
abort();
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-
- if( mem_log[mem_check_posn].exception_pc != -1 ) {
- sh4_reraise_exception(mem_log[mem_check_posn].exception_pc);
- *exception = 1;
- } else {
- *exception = 0;
- }
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return mem_log[mem_check_posn++].value;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -201,202 +186,117 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return isgood;
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_long( sh4addr_t addr, void *exc )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static mem_region_fn_t real_region( sh4addr_t addr )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- INIT_EXCEPTIONS(except);
- int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_long)(addr, &&except);
- log_mem_op( READ_LONG, addr, rv, 0 );
- return rv;
-except:
- log_mem_op( READ_LONG, addr, rv, 1 );
- SH4_EXCEPTION_EXIT();
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( addr >= 0xE0000000 )
+ return p4_address_space[VMA_TO_EXT_ADDR(addr)>>12];
+ else
+ return ext_address_space[VMA_TO_EXT_ADDR(addr)>>12];
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL int32_t log_read_word( sh4addr_t addr, void *exc )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t shadow_read_long( sh4addr_t addr )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- INIT_EXCEPTIONS(except);
- int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_word)(addr, &&except);
- log_mem_op( READ_WORD, addr, rv, 0 );
- return rv;
-except:
- log_mem_op( READ_WORD, addr, rv, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL int32_t log_read_byte( sh4addr_t addr, void *exc )
-{
- INIT_EXCEPTIONS(except);
- int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte)(addr, &&except);
- log_mem_op( READ_BYTE, addr, rv, 0 );
- return rv;
-except:
- log_mem_op( READ_BYTE, addr, rv, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL int32_t log_read_byte_for_write( sh4addr_t addr, void *exc )
-{
- INIT_EXCEPTIONS(except);
- int32_t rv = ((mem_read_exc_fn_t)real_address_space[addr>>12]->read_byte_for_write)(addr, &&except);
- log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 0 );
- return rv;
-except:
- log_mem_op( READ_BYTE_FOR_WRITE, addr, rv, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL void log_write_long( sh4addr_t addr, uint32_t val, void *exc )
-{
- INIT_EXCEPTIONS(except);
- ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_long)(addr, val, &&except);
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_LONG, addr, val, 0 );
- return;
-except:
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_LONG, addr, val, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL void log_write_word( sh4addr_t addr, uint32_t val, void *exc )
-{
- INIT_EXCEPTIONS(except);
- ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_word)(addr, val, &&except);
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_WORD, addr, val, 0 );
- return;
-except:
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_WORD, addr, val, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL void log_write_byte( sh4addr_t addr, uint32_t val, void *exc )
-{
- INIT_EXCEPTIONS(except);
- ((mem_write_exc_fn_t)real_address_space[addr>>12]->write_byte)(addr, val, &&except);
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_BYTE, addr, val, 0 );
- return;
-except:
- if( !IS_STORE_QUEUE(addr) )
- log_mem_op( WRITE_BYTE, addr, val, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL void log_prefetch( sh4addr_t addr, void *exc )
-{
- INIT_EXCEPTIONS(except);
- ((mem_prefetch_exc_fn_t)real_address_space[addr>>12]->prefetch)(addr, &&except);
- log_mem_op( PREFETCH, addr, 0, 0 );
- return;
-except:
- log_mem_op( PREFETCH, addr, 0, 1 );
- SH4_EXCEPTION_EXIT();
-}
-
-static FASTCALL int32_t check_read_long( sh4addr_t addr, void *exc )
-{
- int except;
- int32_t value = check_mem_op( READ_LONG, addr, 0, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
- return value;
-}
-
-static FASTCALL int32_t check_read_word( sh4addr_t addr, void *exc )
-{
- int except;
- int32_t value = check_mem_op( READ_WORD, addr, 0, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
- return value;
-}
-
-static FASTCALL int32_t check_read_byte( sh4addr_t addr, void *exc )
-{
- int except;
- int32_t value = check_mem_op( READ_BYTE, addr, 0, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
- return value;
-}
-
-static FASTCALL int32_t check_read_byte_for_write( sh4addr_t addr, void *exc )
-{
- int except;
- int32_t value = check_mem_op( READ_BYTE_FOR_WRITE, addr, 0, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
- return value;
-}
-
-static FASTCALL void check_write_long( sh4addr_t addr, uint32_t value, void *exc )
-{
- if( !IS_STORE_QUEUE(addr) ) {
- int except;
- check_mem_op( WRITE_LONG, addr, value, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( shadow_address_mode == SHADOW_LOG ) {
+ int32_t rv = real_region(addr)->read_long(addr);
+ log_mem_op( READ_LONG, addr, rv );
+ return rv;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- real_address_space[addr>>12]->write_long(addr, value);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ return check_mem_op( READ_LONG, addr, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_write_word( sh4addr_t addr, uint32_t value, void *exc )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t shadow_read_word( sh4addr_t addr )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( !IS_STORE_QUEUE(addr) ) {
- int except;
- check_mem_op( WRITE_WORD, addr, value, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( shadow_address_mode == SHADOW_LOG ) {
+ int32_t rv = real_region(addr)->read_word(addr);
+ log_mem_op( READ_WORD, addr, rv );
+ return rv;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- real_address_space[addr>>12]->write_word(addr, value);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ return check_mem_op( READ_WORD, addr, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_write_byte( sh4addr_t addr, uint32_t value, void *exc )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t shadow_read_byte( sh4addr_t addr )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- if( !IS_STORE_QUEUE(addr) ){
- int except;
- check_mem_op( WRITE_BYTE, addr, value, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
- }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( shadow_address_mode == SHADOW_LOG ) {
+ int32_t rv = real_region(addr)->read_byte(addr);
+ log_mem_op( READ_BYTE, addr, rv );
+ return rv;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- real_address_space[addr>>12]->write_byte(addr, value);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ return check_mem_op( READ_BYTE, addr, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static FASTCALL void check_prefetch( sh4addr_t addr, void *exc )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL int32_t shadow_read_byte_for_write( sh4addr_t addr )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int except;
- check_mem_op( PREFETCH, addr, 0, &except );
- if( except ) {
- SH4_EXCEPTION_EXIT();
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( shadow_address_mode == SHADOW_LOG ) {
+ int32_t rv = real_region(addr)->read_byte_for_write(addr);
+ log_mem_op( READ_BYTE_FOR_WRITE, addr, rv );
+ return rv;
+ } else {
+ return check_mem_op( READ_BYTE_FOR_WRITE, addr, 0 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-struct mem_region_fn log_fns = {
- (mem_read_fn_t)log_read_long, (mem_write_fn_t)log_write_long,
- (mem_read_fn_t)log_read_word, (mem_write_fn_t)log_write_word,
- (mem_read_fn_t)log_read_byte, (mem_write_fn_t)log_write_byte,
- NULL, NULL, (mem_prefetch_fn_t)log_prefetch, (mem_read_fn_t)log_read_byte_for_write };
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void shadow_write_long( sh4addr_t addr, uint32_t val )
+{
+ if( shadow_address_mode == SHADOW_LOG ) {
+ real_region(addr)->write_long(addr, val);
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_LONG, addr, val );
+ } else {
+ if( !IS_STORE_QUEUE(addr) ) {
+ check_mem_op( WRITE_LONG, addr, val );
+ } else {
+ real_region(addr)->write_long(addr, val);
+ }
+ }
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-struct mem_region_fn check_fns = {
- (mem_read_fn_t)check_read_long, (mem_write_fn_t)check_write_long,
- (mem_read_fn_t)check_read_word, (mem_write_fn_t)check_write_word,
- (mem_read_fn_t)check_read_byte, (mem_write_fn_t)check_write_byte,
- NULL, NULL, (mem_prefetch_fn_t)check_prefetch, (mem_read_fn_t)check_read_byte_for_write };
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void shadow_write_word( sh4addr_t addr, uint32_t val )
+{
+ if( shadow_address_mode == SHADOW_LOG ) {
+ real_region(addr)->write_word(addr, val);
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_WORD, addr, val );
+ } else {
+ if( !IS_STORE_QUEUE(addr) ) {
+ check_mem_op( WRITE_WORD, addr, val );
+ } else {
+ real_region(addr)->write_word(addr, val);
+ }
+ }
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void shadow_write_byte( sh4addr_t addr, uint32_t val )
+{
+ if( shadow_address_mode == SHADOW_LOG ) {
+ real_region(addr)->write_byte(addr, val);
+ if( !IS_STORE_QUEUE(addr) )
+ log_mem_op( WRITE_BYTE, addr, val );
+ } else {
+ if( !IS_STORE_QUEUE(addr) ) {
+ check_mem_op( WRITE_BYTE, addr, val );
+ } else {
+ real_region(addr)->write_byte(addr, val);
+ }
+ }
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static FASTCALL void shadow_prefetch( sh4addr_t addr )
+{
+ if( shadow_address_mode == SHADOW_LOG ) {
+ real_region(addr)->prefetch(addr);
+ log_mem_op( PREFETCH, addr, 0 );
+ } else {
+ check_mem_op( PREFETCH, addr, 0 );
+ }
+}
+struct mem_region_fn shadow_fns = {
+ shadow_read_long, shadow_write_long,
+ shadow_read_word, shadow_write_word,
+ shadow_read_byte, shadow_write_byte,
+ NULL, NULL, shadow_prefetch, shadow_read_byte_for_write };
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
void sh4_shadow_block_begin()
{
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -412,7 +312,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > memcpy( &temp_sh4r, &sh4r, sizeof(struct sh4_registers) );
memcpy( &sh4r, &shadow_sh4r, sizeof(struct sh4_registers) );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- sh4_address_space = check_address_space;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ shadow_address_mode = SHADOW_CHECK;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > mem_check_posn = 0;
sh4r.new_pc = sh4r.pc + 2;
while( sh4r.slice_cycle < temp_sh4r.slice_cycle ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -434,18 +334,17 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
abort();
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- sh4_address_space = real_address_space;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ shadow_address_mode = SHADOW_LOG;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
void sh4_shadow_init()
{
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- real_address_space = sh4_address_space;
- log_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
- check_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 256 );
- for( unsigned i=0; i < (256 * 4096); i++ ) {
- log_address_space[i] = &log_fns;
- check_address_space[i] = &check_fns;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ shadow_address_mode = SHADOW_LOG;
+ p4_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 32 );
+ shadow_address_space = mem_alloc_pages( sizeof(mem_region_fn_t) * 32 );
+ for( unsigned i=0; i < (32 * 4096); i++ ) {
+ shadow_address_space[i] = &shadow_fns;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
mem_log_size = MEM_LOG_SIZE;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -454,6 +353,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
sh4_translate_set_callbacks( sh4_shadow_block_begin, sh4_shadow_block_end );
sh4_translate_set_fastmem( FALSE );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- sh4_translate_set_address_space( log_address_space, log_address_space );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ memcpy( p4_address_space, sh4_address_space + (0xE0000000>>LXDREAM_PAGE_BITS),
+ sizeof(mem_region_fn_t) * (0x20000000>>LXDREAM_PAGE_BITS) );
+ memcpy( sh4_address_space + (0xE0000000>>LXDREAM_PAGE_BITS), shadow_address_space,
+ sizeof(mem_region_fn_t) * (0x20000000>>LXDREAM_PAGE_BITS) );
+ mmu_set_ext_address_space(shadow_address_space);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>