Simon's system, if I understood correctly, generates the data outside of ISR, and does the display bus access in the ISR.
It's exactly the correct way to do it. No need to turn it around.
All you need is guarding against non-atomic operations.
The problem is content update happening in parallel to transferring that content into the display. Because updating the display is a never-ending process, you can philosophically say the content is always partial. But the interesting notion is, how the content is partial. Is it:
* Lacking part of a single value (for example, lowest 8 bits out of 16-bit value are old, highest 8 bits are new; this results in corruption, as the mixed value makes no sense)
* Lacking part of a single full screen frame (say, upper half of screen is old, lower half of screen is new)
* The whole display frame is old data
Given this, the practical implementation options are, respectively:
1) don't do anything - temporary display corruption occurs when the content is updated at bad timing
2) guard against single word accesses by disabling ISR
- no corruption, but it's unpredictable when the modification is visible: this frame, or the next frame
- in moving video, this could look like smear (part of the picture is from previous frame; what part, that depends and jitters)
- this is likely perfectly OK in Simon's case
- slight jitter caused to ISR timing because of atomic safeguards disabling the ISR
3) double buffering of the whole display content
- no corruption; all updates done to the buffer apply at once, to the next full frame
- requires more memory
- requires some buffer handling / swapping code
- causes a delay in display update
To implement 2, qualify the variable that needs to be written in the main thread loop, volatile, and surround writing to it by first disabling, then re-enabling interrupts.
Unless you are 100% sure the operation is inherently atomic; then volatile alone is sufficient.
You can also look at the C11 atomic types.