It's all written in C, and the compiler does the right thing almost all the time. It is OK for "my" code, but some of the library routines are not modified and don't work across memory banks. For example, switch statements with consecutive indexes are handled as jump tables, and the table indexes are always two bytes. So the switch has to be in bank zero, and the body of each case calls the actual code which can be in any bank. That code always ends in an RTC. It's fiddly, but now that I have figured that out, I can live with it.
Another fiddly, and totally undocumented part, is that every function definition has to explicitly have the same bank assignment as the main routine, or you get a memory assignment doesn't match warning ( I forget the exact text). But the warning messages tend to come and go. I have gotten dozens of them, fixed a few, and all of them disappeared. Did I fix them? Or is it just normal C errors, where one real error causes a cascade of fake errors? And what happens if I miss any? Who knows?
Another problem is that certain canned routines, like multi-bit shift routines, don't know about memory banks, and always end in RTS. I'm pretty sure my current problem is one of these, but the only way to see them is to generate a .lst file, and search it. But that's a lot of code, and not all the RTS's matter, and this may not be the problem.
I would like to just run the code until it quits, then back up to the last address that isn't in RAM or the peripheral block. But the normal P&E debugger can't deal with that. Once the code goes into the weeds, P&E is done. I hope Trace will be able to let me find the code.
I probably misused the word "overflow". I just meant that it outgrew the default space of 0x2080-0x7FFF, and I had to convert to banked memory. It's around 27K at the moment.
So, to close, I would like Trace to break on a range of addresses. Although this is a documented option, there isn't any obvious way to do that.