Actually if I remember correctly, the corruption appears also when the raster is in the vertical border ...
So waiting the horizontal retrace probably is not the solution
When I’m looking at the horizontal VRAM access layout, I feel like it may be safe to change the register between cycles 130 and 144 (where r#18 is latched). But that is difficult to time so precisely. I think the most practical approach is to just synchronize the r#18 write with the VDP command execution. Are there situations where this is too much of an inconvenience?
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?
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.
I have never tried but I think you can probably do it. But the X coordinate resets so there is a little repetition of work.
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?
Afaik they do. Anyway, look in the V9938 application manual, it is documented in section 6 of the commands chapter on page 85.
When I’m looking at the horizontal VRAM access layout, I feel like it may be safe to change the register between cycles 130 and 144 (where r#18 is latched). But that is difficult to time so precisely. I think the most practical approach is to just synchronize the r#18 write with the VDP command execution. Are there situations where this is too much of an inconvenience?
If sprites are active it seems that 98-162 is a good range
Why 130-144? Where does 144 come from?
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.
On the other hand, the sync to CE command works but is rather uncomfortable, if you need to send multiple commands in a single frame and squeze the last drop of speed from v9938. As we know, the vdp cannot tell us via interrupt: "OK i've finished".
that's the main reason in trying to find and alternative way to interact with R18..... :-| If only the R18 would have been buffered and synched at the start of each scanline...... :-(
Where does 144 come from?
See https://github.com/openMSX/openMSX/issues/1310#issuecomment-...
If you want a change to BL, SPD, M1-M5 and the horizontal adjust to take effect in the current line, you must change the value before cycle ~144. After that it’s too late and it will be latched the next line.
Presuming that the effect relates to a desync between when the offset affects the command engine (immediate?) and the display engine (latched at cycle 144), it seems like ideally you would want to change r#18 as shortly before that as possible. In the left erase there is a short period where the VDP is more or less idle, so I took the start of the idle time (cycle 130) up to cycle 144 as being potentially the safest moment to do change r#18.
Awesome finding! Great work Grauw! Now we know that the processing of a new line starts in the middle of the left erase, ~144 cycles after the sync signal. 144 VDP cycles correspond to 24 z80 cycles.
Is there a way to sync the change of R18 to cycle 144 of the VDP ?
Maybe testing HR,since it is set , one should count 88+130 vdp cycles (14+21 z80 cycles) ?
When I’m looking at the horizontal VRAM access layout, I feel like it may be safe to change the register between cycles 130 and 144 (where r#18 is latched). But that is difficult to time so precisely. I think the most practical approach is to just synchronize the r#18 write with the VDP command execution. Are there situations where this is too much of an inconvenience?
Having the possibility to copy a whole block 240x176 with one command would free a lot of CPU time in my scrolling routine.
Now I have to copy 15 slices of 16x176, one per frame, in order to keep the processing within a frame and to have the time for setting R18 before the new vdp copy
Is there a way to sync the change of R18 to cycle 144 of the VDP ?
Problem I see is that a HR polling loop takes time, causing jitter between when HR is flagged and the Z80 detects it. Getting a cycle-exact timing would require a carefully written synchronization sequence that spans dozens of lines. And that’s not considering complications like systems where VDP I/O gets (an) extra wait cycle(s), or VDP and CPU having different clock crystals which can drift slightly.
So syncing exactly to VDP cycle 144 seems impossible or at least impractical. But if the “safe window” before it is big enough, doing it within x cycles before cycle 144 may be good enough.
Btw to react quickly it can set up an indirect register write in advance (r#17), then it needs just a single OUT when ready.
Having the possibility to copy a whole block 240x176 with one command would free a lot of CPU time in my scrolling routine. Now I have to copy 15 slices of 16x176, one per frame, in order to keep the processing within a frame and to have the time for setting R18 before the new vdp copy
But if you want to be able to scroll the other direction at positions not aligned to 16, you’ll need to slice it up anyway. Not needed in all situations (e.g. horizontal SHMUP), but still. And it’s only issueing one copy / frame, which seems a minor hassle compared to dealing with precise timing shenanigans.