I would like to improve the memory map in my existing Sega Saturn Loader. I used https://wiki.yabause.org/index.php5?title=SH-2CPU to develop the initial memory map.
Advanced features I would like to implement:
31 | 30 | 29 | Description
-- | -- | -- | --
0 | 0 | 0 | Cache used (only if CE bit in CCR is set, otherwise no cache)
0 | 0 | 1 | Cache not used
0 | 1 | 0 | Associative purge area (Always returns $2312)
0 | 1 | 1 | Direct access to cache addresses (1K data, mirrored every 1K)
1 | 0 | 0 | Same as Cxxxxxxx
1 | 0 | 1 | Same as 2xxxxxxx
1 | 1 | 0 | Direct R/W access to cache data (4K data mirrored every 4K)
1 | 1 | 1 | On-chip registers
So any advice on how to implement these? Is this something that goes in the loader or in the CPU spec? Thanks in advance.
Ghidra can do bit-mapped and byte-mapped memory blocks. Can you use that feature to deal with your mirrored regions?
I'm not familiar with bit-mapped or byte-mapped memory blocks. Can you point me to a some documentation to read? Thanks again.
When you create new memory blocks with the Memory Map in the GUI, you can change the block type. If you choose one of the mapped types, you'll be able to specify not only the location of the new block, but the source address of where to map the bytes from. A cool feature was recently added to the master branch that allows you to change the mapping ratio, which is useful if you are, for example, mapping ROM to RAM where they each have a different word size. You can press F1 in the Add Memory Block dialog to read more about it.
The MemoryBlockUtils class has some methods in there that will let you create these types of blocks from your Loader.
If you choose one of the mapped types, you'll be able to specify not only the location of the new block, but the source address of where to map the bytes from.
Oh wow that looks useful. I'll spend some time researching that.
I think it would be handy to be able to do this via pspec. At least for mirrored memory regions.
I think it would be handy to be able to do this via pspec. At least for mirrored memory regions.
I agree. One of the very first things I usually have to do with a new program is to create a memory map that reflects the particular processor.
Ghidra can do bit-mapped and byte-mapped memory blocks. Can you use that feature to deal with your mirrored regions?
I'm looking through the Ghidra docs and I don't understand the difference between an overlay, bit-mapped, and byte-mapped memory blocks. Overlay seems to be a different set of bytes at the same region as an already allocated memory region. What's the difference between bit-mapped and byte-mapped memory blocks?
Bit-mapped will have bit-addressing (addr 0 is 1, addr1 is 1, addr2 is 1, etc). It's only useful in a couple of architectures. If your processor is byte-addressable, then byte-mapping is what you would think of as mirroring. Overlays let you reuse address ranges by creating fake address spaces. The Ghidra loaders will sometimes create these to map in parts of the file into memory that weren't intended to get mapped into memory.
OMG, this is amazing! I have been wanting something like this for ages, and was about to start trying to write a plugin to do this... I am so happy.
Maybe a question I could answer with a few minutes testing, but to all the regions share the same "knowledge" as if 10 bytes into a region is a function, do all blocks (from the same source) know it's a function and the args etc? Or does the work need to be duplicated in each "copy"?
The work needs to be duplicated.
The work needs to be duplicated.
... that doesn't make sense, especially if the memory region is a "mirror". While it can be easily tackled by a script, or better yet auto scheduled analyzer via the AutoAnalysisManager, that's still a headache. I would have expected references to the "mirror" address to be considered a reference to the address being "reflected"
The bytes are mirrored, but they may have a different context in the new mapping. Consider the 16-bit PIC architecture where 24-bit ROM gets mirrored to a section of 16-bit RAM in order for code to read code bytes (Program Space Visibility feature).
Duplicating the markup would be situation dependent, but there is an argument for having a built-in option.
The bytes are mirrored, but they may have a different context in the new mapping. Consider the 16-bit PIC architecture where 24-bit ROM gets mirrored to a section of 16-bit RAM in order for code to read code bytes (Program Space Visibility feature).
Duplicating the markup would be situation dependent, but there is an argument for having a built-in option.
Maybe something like a "pure" byte mapped block. It would be useful for situations where the memory is just an uncached view.
Most helpful comment
The bytes are mirrored, but they may have a different context in the new mapping. Consider the 16-bit PIC architecture where 24-bit ROM gets mirrored to a section of 16-bit RAM in order for code to read code bytes (Program Space Visibility feature).
Duplicating the markup would be situation dependent, but there is an argument for having a built-in option.