I'm reverse engineering an embedded Z80 application in IDA Pro 7.0. The target system maps one address range to either of a pair of expansion boards. The address decode logic decides which board is mapped based on one bit in a memory-mapped register. I think I've figured out how to map the segments, but I can't figure out how to get IDA to use the bank-switched area.
I've set up my segments like this:
Segment Start End Base
ROM1 00000 02000 0000
ROM2 02000 04000 0000
ROM3 04000 06000 0000
ROM4 06000 08000 0000
ROM5 08000 0A000 0000
IO 0A000 0B000 0000
RAM 0B000 0C000 0000
DREG 1C000 1D000 1000
DRAM 1D000 1E000 1000
DROM 1E000 20000 1000
CROM 2C000 30000 2000
I've allocated base 0x0000 for things that are always mapped (ROM1-5, IO, RAM), base 0x1000 for bank-switched things on one board (DREG, DRAM, DROM), and base 0x2000 for bank-switched things on the other board (CROM). This results in (DREG, DRAM, DROM) and CROM both having the virtual address range 0xC000-0xFFFF, which is correct.
I can't figure out how to tell IDA which bank/base to use, either manually or automatically. Whenever it encounters a reference to a different base it shows the address as a problem and renders it with five digits instead of four (e.g. 0E018h
) and I can't find any way to manually resolve the reference. I've read through the scant official documentation, and I've tried googling various related terms to no avail.
Ideally, I'd like IDA to recognize the bank select register and automatically choose the right segment the way it does for processors with a native segment register. If that's not possible, manually specifying the target bank/base for each reference would be tolerable. Can someone provide guidance on how to achieve either of those, or more generally on how to handle external bank-switching in IDA?
Edit: I set up segment translation to make the fixed segments available from all of the segments, and now code references from the switched segments to the fixed ones work. Data references from fixed to switched still don't resolve. I'm guessing that adding one or the other set of switched segments to the translation list for the fixed segments would make all references to the switched range resolve to that bank, but I need to be able to resolve some to one bank and some to the other so that's not a solution.
Edit: I've discovered that I can use the "Manual" option from the right-click menu to change a jp
or call
operand from e.g. 0E018h
to 1E018h
and thereby manually select a bank. That does make the link resolve, but it appears to be more of a hack than a proper solution as IDA doesn't show names and repeatable comments at the call site like it normally does.