Skip to content

Get Bleemcast beta titles running on flycast. - #2443

Open
Bruceleeto wants to merge 5 commits into
flyinghead:devfrom
Bruceleeto:mmu_work
Open

Get Bleemcast beta titles running on flycast.#2443
Bruceleeto wants to merge 5 commits into
flyinghead:devfrom
Bruceleeto:mmu_work

Conversation

@Bruceleeto

Copy link
Copy Markdown

So, this should allow the vast majority of Bleem'd games that people have been playing on real hw for years to run on flycast. I tested about 6 games from the BleemcastShindouGo archive on the dreamcasttalk.com forum.

  • Hercules
  • Army Men - Sarge's Heroes
  • Medievil 2
  • Rayman 2
  • Megaman Legends
  • 007 Racing.

All that I tested seem to work. I couldnt test them all due to there being hundreds.
One issue I got is many of these titles have actual renderering issues on real hardware so it is difficult to say what is 'incorrect emulation' on flycasts end or just a bleem title being broken normally.
The offical bleem titles also do not work due to how copyprotection stuff I have still yet to figure out.

I'm not confident about this PR but I thought I'd just submit it instead of just abandoning it as if someone else decides to add bleem support later they got something to go off. I decided it be better if these changes dont impact other games as speeding up bleem titles would of involved changes that could impact multiple platforms that I cant test for. like bumping CODE_SIZE to reduce the amount of flushes. For the games I did test they seemed to run ok albeit with some occasional stuttering. As it stands I think the only risk this PR is to a non bleem game is if a non-WinCE title that loads real UTLB entries before enabling AT which could cause it to crash or run slower for all I know.

I guess another issue is this does add a second path through the MMU code that someone has to maintain but should make flycast slightly more accurate so kinda a trade off that's not my place to decide.

Also mmu_flush_table now clears the UTLB and ITLB valid bits, like the non-FAST_MMU version already does. After a TI the fast path kept V=1 on entries the guest had invalidated, which was harmless while nothing read those bits. The strict scan reads them now so I had to sort that out.

One thing I didnt tackle is Flycast doesn't save which MMU mode a game is in, so it re-guesses when you load a savestate. On dev/master that guess might come back wrong already I think but i tried Mario64 and seems to be fine, but this PR adds strict mode as another thing it can wrongly guess, which would leave a non-bleem title running slower and taking faults it shouldn't. Saving mmuOn/mmuStrict in the savestate would fix it most likely, but I didnt want to touch the save format.

cache_entry dropped 1K UTLB entries and find_entry never probed for
them, so a 1K mapping always ended up as TLB_MISS. Cache and look
them up like any other size.

The address LUT is indexed by vaddr >> 12, so a 1K page must not go
in it, or the other three 1K pages in that 4K block alias to the
wrong physical base. Track the page mask of the last translation and
skip the fill for anything smaller than 4K. Those pages then miss
the dynarec's inline check every time and call through.
Some titles load the whole UTLB before setting AT and need real TLB
behavior from then on: exact multi-hit detection, PR protection
faults, first-write faults. The cached fast path has none of that.
It keeps an LRU, a hash cache, WinCE-synthesized entries, and an
untagged address LUT with no protection state.

mmuStrict switches to a full 64-entry scan, reports multi-hit as
TLB_MHIT, applies the PR/D checks on translation, and stops filling
mmuAddressLUT. mmu_set_state turns it on when AT comes up and the
UTLB already holds a real mapping, which the WinCE kernel-magic
detection never covered.

WinCE has to be ruled out first, since it reaches that same state
after an AT toggle or a savestate load and the cached path serves it
fine. The flag is cleared wherever mmuOn is, so it can't survive
into the next guest.
convertSector only knew 2352 -> 2340, which is just a 12-byte sync
skip. A 2336-byte sector has no sync and no header at all, so
synthesize the 4-byte header from the FAD (BCD min/sec/frame, mode
2) and copy the payload after it.

ReadSectors had no 2340-from-SECFMT_2336 case either.
The strict scan looks at all 64 UTLB entries and can't stop early,
because multi-hit detection needs to see the whole table. Cache what
it found, keyed on the 1K page: either the matching entry, or the
fact that nothing matched.

ASID goes in the tag, so the ASID switching these guests use as
dispatch needs no flushing. The cache is dropped where the match set
can actually change: UTLB writes, MMUCR writes, TLB flush,
deserialize. Those sites are hot for everyone, so the flush bails
out when not strict, since nothing else fills it.

Only MMUCR.SV == 0 results are cached. With SV set, matching depends
on sr.MD, and MD flips on every exception. ASID changes also stop
flushing mmuAddressLUT in strict mode, which never fills it anyway.
Strict guests toggle MMUCR.AT around housekeeping at roughly 20 Hz.
Every toggle ran mmu_set_state and ResetCache, so the working set
got recompiled twice per toggle.

Leave the MMU-aware code and memory handlers in place across the
toggle instead. That leaves the MMU handlers live while AT is 0, so
data and instruction translation now return the address unchanged in
that window, matching the hardware. Non-strict guests still take the
reset path.
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