My solution to this was to generally run all of my logic in the IRQ, starting with screen draws, while the non-interrupt code essentially spins on a tight loop checking on a single memory address. This way I don't have to worry about any of my routines being interrupted. An additional up-side to this is that I effectively have a thread that's not doing anything, and I'm thinking it would be ideal to place my streaming I/O logic into there, essentially spinning through banks and loading files as needed into them.
In particular, I really like the VERA's dual access channels and auto-increment settings, and how they make it really easy to write columns and rows of 16-bit tile data.
Might be quicker to semaphore it, so when your code isn't updating Vera you don't have to execute the code if it hasn't claimed the semaphore. Really depends :)
There's an argument that you shouldn't update in IRQ anyway, but have a Model-View design, so you update your model if you want in the interrupt routine, just using the IRQ as a timer.