As usual on the Oric the core of the issue has to do with the amount of data to move in one frame, and the fact there is no double buffering.
Technically we don't need all these intermediate buffers, but we also want to avoid flickering as much as possible, which is why we tend to use buffers, to do composition where it's invisible, and then "blitt" that to the screen.
In practice, there are methods that can be used to reduce copying, but they end up being extremely complex to apply, and tend to use quite a lot of memory.
The fastest possible way to display an image on the Oric is basically to have the image stored as code as immediate values, so something like that:
Code: Select all
LDA #first_byte_of_the_image
STA $A000+0
LDA #second_byte_of_the_image
STA $A000+1
(...)
LDA #last_byte_of_the_image
STA $A000+7999
This takes 2 bytes per LDA, 3 bytes per STA, so that's 8000*5 bytes = 40000 bytes, and takes 2 cycles per immediate LDA, 4 cycles per absolute long STA, so that's 8000*6 cycles = 48000 cycles, knowing that we have about 20000 cycles per frame when running at 50fps, so just doing that already takes 2.4 frames
Obviously that's not a viable option.
The opposite option is the naive double for loop with two pointers in zero page, the amount of memory used is trivial, but the time literally explodes because of the number of loops and index management.
So in general we try to get something in between, with some code unrolling in one direction (either horizontal and vertical), and looping on the other direction, which is slower than the first example, but manageable in term of memory usage.
A common solution to reduce the processing time is to have some UI elements, like some high-scores, title logo, etc... because if you don't have to update 20% of the screen, it means the code now runs 20% faster.
The big difficult in games really are sprites, because they move, you need to be able to restore the background where they previously were present, but if you do that on the HIRES screen, if the electron beam passes over the area where you just erased the sprite before drawing the new one, you will see a flickering mess on the screen.
If your drawing code is fast enough that it can do that in less than a frame, then you are good to go, but when doing HIRES animation WITH a scrolling, there's no way to do that faster than 50hz, which is why we use intermediate buffers.
That being said, there are methods that can be used to scroll on place the areas where there are no sprites, and use some optimized erase/draw for the sprites using some "dirty rectangle" methods, but it's extremely complicated to implement.