I always wandered if it would be possible to temporarily 'pause' a VDP command by writing 0 to R46 and then writing the original command to it again later.
Looking at openMSX if seems the registers are modified at run-time, although it is not clear if these registers actually accurately represent the 'state' of the currently running command?
You can stop the current command, but starting it again from where it was interrupted is not so easy, I've had random glitches, like a missing line, also in plain VRAM to VRAM copy.
About the Stop engine trick: i've tryed in the past but this approach is source of trouble if you do for example a LMMM XOR operation because of grauw already said.
Yes that is a good point indeed.
In my particular case I am not using any logic operations that would have those kind of side effects, so it would be alright.
However, experimented a bit and did some thinking; the major problems with the 'stop engine' trick seems to be that:
- For copying wide horizontal blocks, the X gets reset, which means that potentially a large part of a single horizontal line might be copied again. This makes the trick quite unstable and would thus still require adding buffers to your timings if you use line-interrupts to process a sequence of VDP commands. Might then as well split into smaller commands and use more line interrupts to make it reliable and the timings tighter.
- There is a small theoretical window where the command ends just after polling the CE bit. The code would then mistakenly restart the command although it technically already finished (not sure what happens if certain registers have reached value 0 by then; may have unintended side effects?)
You can stop the current command, but starting it again from where it was interrupted is not so easy, I've had random glitches, like a missing line, also in plain VRAM to VRAM copy.
Thanks for the info! Good to know that indeed, it is not a reliable strategy
Proposal: maybe trying to synchronize to the horizontal retrace flag with a variable delay could reveal some info about the precise delay to apply to r18 write in order to avoid (if possible) the glitch? (I know, timing constraints are tight)
You can stop the current command, but starting it again from where it was interrupted is not so easy, I've had random glitches, like a missing line, also in plain VRAM to VRAM copy.
Thanks for the info! Good to know that indeed, it is not a reliable strategy
Better if you do your own tests as well, l could have missed something important
Proposal: maybe trying to synchronize to the horizontal retrace flag with a variable delay could reveal some info about the precise delay to apply to r18 write in order to avoid (if possible) the glitch? (I know, timing constraints are tight)
This is what I was thinking. When I have done my tests I wasn't aware of the fact vdp timings.
Now one should try to make the R18 change fall between cycle 130 and 144
Maybe also 98-144 is a good window, even if in z80 cycles it is about 7 cycles only
@ARTRAG: i've sent you a bizzarre approach to avoid (teoretically) the R18 issue. It's very bizzare and maybe could be the start ing point of some other ideas...
It is based on the idea to pause the cmd engine instead of stopping it .
Can you share the bizarre idea with the rest of us?
I’m curious how you could pause the command engine.
It is so much bizzarre than i'm ashamed to tell about:
the R18 corruption seems to appear not very often, if the misgnaling between the new r18 value and the cmd engine takes one scanline to re-align i expect to see the corruption more than one time x scanline on the average. this is because the vdp can move rougly more than 1 byte x scanline during command execution.
I expect that the misaligning got fixed just after the next byte read or written after the corrupted one.
so the idea was this. if i can pause the VDP CMD engine as long enough to delay the vdp byte write/read operation from CMD Engine, by issuing a in a, (0x98) there is a chance that the CPU I/O request takes place stealing a cycle to the VDP engine, the readed byte could be corrupted, but it does not matter, because its value is discarded.
However there should be the chance that the vdp has already in queue a byte I/O for the cmd engine and the CPU I/O got delayed. in this scenario, corruption occours.
But maybe my idea could serve as a basis for another similar approach.
I'm not sure if i explained clearly the trick, anyway
What's do you think about this?
Something like this ?
ld de,value+(18+128)*256 ld c,0x99 out(c),e in a,(0x98) out(c),d
I.e. by occupying the bus with the CPU, the command engine should take the slot after R18 has been changed