summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu
diff options
context:
space:
mode:
author Jesus Ramos <jesus-ramos@live.com>2026-03-08 05:52:56 -0700
committer GitHub <noreply@github.com>2026-03-08 08:52:56 -0400
commit4525bead136c52e21e8a6438d7a010956636cca9 (patch)
tree087725295fc9bb1f92a648f7e49ee99e97d1f6c2 /src/devices/cpu
parent13184ea25598422dfe837c40baafa2d86110909d (diff)
sh/sh7709s.cpp: Fix bug in DRC memory accessor using clobbered IO reg (#15074)
Fix a shift error in the wcr1 register values Add bcr2 plumbing for determining cache line fetch reads based off BCR2. Area 0 is set via external pins so hardcoding the cv1k value, this is typically code space though so it only affects timing during copy of code to main memory
Diffstat (limited to 'src/devices/cpu')
-rw-r--r--src/devices/cpu/sh/sh7709s.cpp33
1 files changed, 22 insertions, 11 deletions
diff --git a/src/devices/cpu/sh/sh7709s.cpp b/src/devices/cpu/sh/sh7709s.cpp
index 0d453ac76f9..5d90b78bc6b 100644
--- a/src/devices/cpu/sh/sh7709s.cpp
+++ b/src/devices/cpu/sh/sh7709s.cpp
@@ -166,8 +166,7 @@ static unsigned int get_wcr1_timing(uint32_t address, uint16_t wcr1)
if (area > 6 || area == 1)
return 0;
- unsigned int area_shift = 12 - (area * 2);
- unsigned int area_val = (wcr1 >> area_shift) & 0x3;
+ unsigned int area_val = (wcr1 >> (area * 2)) & 0x3;
if (area_val == 0)
return 1;
@@ -269,6 +268,23 @@ unsigned int mcr_tras(uint16_t mcr)
return ((mcr >> 8) & 0x3) + 2;
}
+unsigned int cache_line_fetch_count(uint32_t address, uint16_t bcr2)
+{
+ unsigned int area = get_area(address);
+
+ // Hardcoded for area 0 for cv1k code rom, 16 bit bus size
+ if (area == 0)
+ return 8;
+
+ // Not encoded in bcr2
+ if (area == 1)
+ return 0;
+
+ unsigned int bcr2_val = (bcr2 >> (area * 2)) & 0x3;
+
+ return SH7709S_CACHE_LINE_SIZE >> bcr2_val;
+}
+
// Some of the values used here are bus cycles that might need conversion but it's close enough for now
// It's possible for some instructions to overlap in the pipeline with the fetches but that's a good bit
// of extra tracking required
@@ -303,7 +319,7 @@ wb_handle:
// If we can't use burst timing it's gonna be pricey to access
// Each access will have to initiate bus access and wait to read 4 words for the cache line fill
if (!burst_capable)
- penalty += (BUS_ACCESS_PENALTY + get_wcr2_timing(address, m_wcr2)) * 4;
+ penalty += (BUS_ACCESS_PENALTY + get_wcr2_timing(address, m_wcr2)) * cache_line_fetch_count(address, m_bcr2);
else if (!is_wb) // For cache line writeback we can ignore the stall as well as CAS latency
penalty += CACHE_MISS_STALL_PENALTY + get_wcr2_timing(address, m_wcr2);
@@ -418,6 +434,9 @@ void sh7709s_device::static_generate_memory_accessor(int size, int iswrite, cons
UML_AND(block, I0, I0, SH34_AM); // and r0, r0, #AM (0x1fffffff)
+ UML_MOV(block, mem(&m_sh2_state->arg0), I0); // mov [arg0],i0
+ UML_MOV(block, mem(&m_sh2_state->arg1), size); // mov [arg1],size
+
UML_LABEL(block, label++); // label:
if (!debugger_enabled())
@@ -458,8 +477,6 @@ void sh7709s_device::static_generate_memory_accessor(int size, int iswrite, cons
UML_LOAD(block, I0, fastbase, I0, SIZE_DWORD, SCALE_x1); // load i0,fastbase,i0,dword_x1
}
- UML_MOV(block, mem(&m_sh2_state->arg0), I0); // mov [arg0],i0
- UML_MOV(block, mem(&m_sh2_state->arg1), size); // mov [arg1],size
UML_CALLC(block, cfunc_drc_memory_access_read, this); // callc cfunc_drc_memory_access_read,this
UML_RET(block); // ret
@@ -482,8 +499,6 @@ void sh7709s_device::static_generate_memory_accessor(int size, int iswrite, cons
UML_STORE(block, fastbase, I0, I1, SIZE_DWORD, SCALE_x1); // store fastbase,i0,i1,dword_x1
}
- UML_MOV(block, mem(&m_sh2_state->arg0), I0); // mov [arg0],i0
- UML_MOV(block, mem(&m_sh2_state->arg1), size); // mov [arg1],size
UML_CALLC(block, cfunc_drc_memory_access_write, this); // callc cfunc_drc_memory_access_write,this
UML_RET(block); // ret
@@ -511,8 +526,6 @@ void sh7709s_device::static_generate_memory_accessor(int size, int iswrite, cons
break;
}
- UML_MOV(block, mem(&m_sh2_state->arg0), I0); // mov [arg0],i0
- UML_MOV(block, mem(&m_sh2_state->arg1), size); // mov [arg1],size
UML_CALLC(block, cfunc_drc_memory_access_write, this); // callc cfunc_drc_memory_access_write,this
}
else
@@ -532,8 +545,6 @@ void sh7709s_device::static_generate_memory_accessor(int size, int iswrite, cons
break;
}
- UML_MOV(block, mem(&m_sh2_state->arg0), I0); // mov [arg0],i0
- UML_MOV(block, mem(&m_sh2_state->arg1), size); // mov [arg1],size
UML_CALLC(block, cfunc_drc_memory_access_read, this); // callc cfunc_drc_memory_access_read,this
}