As programs grow in complexity, tools to manage this complexity become more and more useful. I'm working on a tool written in Python to generate a context-insensitive static call graph of a ca65 program consisting of multiple translation units (.s files).
A "far call" happens when a subroutine in one PRG bank calls a subroutine in another. On some mappers, especially MMC1, a far call takes quite a few cycles to complete, so you can't just toss a small, often-used subroutine in one bank and expect the rest of the program to far call it. And on mappers with 32 KiB PRG bank switching, you can't toss it in a fixed bank either, so you have to either A. duplicate it in all banks containing a subroutine that calls it or B. move all subroutines that call it to the same bank. You can get an idea for what to do based on the call graph.
On a few mappers, the NMI handler needs special consideration. It can be thought of as a subroutine that every other subroutine in the program calls. Mappers with 32 KiB PRG bank switching need at least some of the NMI handler to be duplicated in each bank. MMC1 has a quirk that the NMI handler can't save and restore the entire state of the mapper. Therefore, you usually want to make sure that everything the NMI handler needs is in the fixed bank or in RAM. This becomes more difficult if your NMI handler runs the entire music engine. So you'd look at the call graph to see what the NMI handler is calling and what bank it needs to be in.
A "far call" happens when a subroutine in one PRG bank calls a subroutine in another. On some mappers, especially MMC1, a far call takes quite a few cycles to complete, so you can't just toss a small, often-used subroutine in one bank and expect the rest of the program to far call it. And on mappers with 32 KiB PRG bank switching, you can't toss it in a fixed bank either, so you have to either A. duplicate it in all banks containing a subroutine that calls it or B. move all subroutines that call it to the same bank. You can get an idea for what to do based on the call graph.
On a few mappers, the NMI handler needs special consideration. It can be thought of as a subroutine that every other subroutine in the program calls. Mappers with 32 KiB PRG bank switching need at least some of the NMI handler to be duplicated in each bank. MMC1 has a quirk that the NMI handler can't save and restore the entire state of the mapper. Therefore, you usually want to make sure that everything the NMI handler needs is in the fixed bank or in RAM. This becomes more difficult if your NMI handler runs the entire music engine. So you'd look at the call graph to see what the NMI handler is calling and what bank it needs to be in.