Skip to content

cpu/sh/sh7709s.cpp : Fix up background cycle accounting and bank conflict checks - #15685

Open
jesus-ramos wants to merge 17 commits into
mamedev:masterfrom
jesus-ramos:sh7709s-amx-fixes
Open

cpu/sh/sh7709s.cpp : Fix up background cycle accounting and bank conflict checks#15685
jesus-ramos wants to merge 17 commits into
mamedev:masterfrom
jesus-ramos:sh7709s-amx-fixes

Conversation

@jesus-ramos

@jesus-ramos jesus-ramos commented Jul 12, 2026

Copy link
Copy Markdown
Contributor
  • Overall timing fixes
  • Use icache sampling as the default, a lot less CPU intensive. Added compile time option to sample every instruction for debugging
  • Implements nandflash timing which influences slowdown in some gameplay sections where background loads occur
  • Fixup critical word first handling
  • Adds a couple more notes about slowdown behavior related to how the game handles bullet checks and how flash timing affects slowdown during background loads

@jesus-ramos

Copy link
Copy Markdown
Contributor Author

Some stuff I want to get to when I have time is better handling the icache updates without hogging all your CPU.

I might swap that over to sampling pc just on data accesses and then just hardcoding the fixed cost payment for the cache flush loop when the cache flush is done. A bit hacky but throwing it all into generate_opcode per instruction would make the games not really playable on some weaker systems and the costs of these are only relevant in a couple of minor areas or immediately following the cache flush where the whole cache is emptied out so some heuristics might work out alright.

@jesus-ramos jesus-ramos changed the title SH7709S : Fix up background cycle accounting and bank conflict checks cpu/sh/sh7709s.cpp : Fix up background cycle accounting and bank conflict checks Jul 12, 2026
@jesus-ramos

Copy link
Copy Markdown
Contributor Author

Looks like one of the last bits to get to for cv1k timing is the nand flash read times. They don't add up too much in early games, but the latter titles definitely use it way more mid stage or mid patterns.

@jesus-ramos

jesus-ramos commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Had some time so finished up a couple more things I wanted to get to, updated the first comment to reflect everything in here now.

I did some extra checks and the BREQ hold from the blitter taking up bus time doesn't seem too influential, may be some corner cases where those eat into the total frame icount enough to cause it to spill but its usually a couple thousand bus cycles and uploads aren't done super frequently. For most frames that it would matter because of when the uploads take place it would have to be after the previous frame either cache flushed or thrashed and started trying to grab the bus after firing off the blitter with upload commands. It's probably not too hard to plumb this but the way the blitter accounting is done in a separate thread makes it not so straightforward.

Playability is good, confirmed a couple games matched by rank properly and those line up great now. Maybe some small spots where there might be a tiny bit less slowdown than pcb but route matching is difficult.

Burst writes should only need 3 additional bus cycles for a 4 word write
Bank conflict on a running precharge command on sdram should block the
whole bank so we should be using the AMX bits to determine the bank for
the conflict depending on AMX bit settings
Instead of ticking with the icache updates just use total_cycles()
and calculate the elapsed cycles since the last memory op
Used the wrong address for some lookups when accounting for cache line
write backs. Doesn't actually cause any issues since it's just going to
be another SDRAM access anyway but fix it so it's clearer
Updated the timing values and wrote them down in a more sane format from
the docs

generate_opcode() to cover all opcodes is too heavy so switch to
sampling for icache on memory accesses. Seems decent enough without
eating up all your cpu.

Account for the uncached instruction fetches in the bad cache flush when
the flush finishes to make sure we pay a good chunk of penalty there.
src/devices/machine/nandflash.{cpp,h}: Add nandflash ready delay timing
Add a couple of extra comments about slowdown oddities that show up in
some titles
Don't need to use m_precharge_remaining_cycles as it's a fixed cost we
can calculate on the background elapsed cycles

Fix the write cycles for writeback
It reads the critical word first with wraparound, not just stalls until
critical word first.
eeprom, sound, flash all should go through uncached areas, the listed
map addresses are the physical addresses with region bits stripped.
Updated the handlers to use the 0xB0000000 region 5 base used in the
games instead
@jesus-ramos

Copy link
Copy Markdown
Contributor Author

Rebased on latest sh drc changes and fixed a couple things I missed. Still tracking down some remaining bits of slowdown that show up more in later games but those have been a bit elusive.

I didn't reference the right table in the docs for this one, high bits
should be the bank bits
WCR1 penalty should be charged only if the subsequent access close in
time causes a read->write or area switch
Based on older RISC designs updated some cpu internal behavior that
seems to line up with observed pcb behavior
@jesus-ramos

Copy link
Copy Markdown
Contributor Author

Alright, think I managed to track the last of it. Had to infer some of it based on pcb slowdown footage + comparative cache miss count for those frames.

All the nastier slowdown areas behaving as expected now. Icache is still sampled by default but that doesn't seem to affect too much based on comparison with heavy + sampled checks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant