diff options
| author | 2026-03-08 05:52:56 -0700 | |
|---|---|---|
| committer | 2026-03-08 08:52:56 -0400 | |
| commit | 4525bead136c52e21e8a6438d7a010956636cca9 (patch) | |
| tree | 087725295fc9bb1f92a648f7e49ee99e97d1f6c2 /src/devices/cpu/sh | |
| parent | 13184ea25598422dfe837c40baafa2d86110909d (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/sh')
| -rw-r--r-- | src/devices/cpu/sh/sh7709s.cpp | 33 |
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 } |
