Changing registers during VDP LMMV command

Door Metalion

Paladin (1008)

afbeelding van Metalion

21-08-2019, 16:29

Hi everyone,

I'm toying with the LMMV command, changing registers while it's being executed.
I'm doing my tests on OpenMSX (but made some preliminary tests on real hardware).

I've calculated as best as I could the time needed by the VDP to draw 1 line of the rectangle (approx 800 t). After that time, I'm changing the R#44 (color) to see what happens. The first 10 lines are working as it should (a fresh new line is drawn in the new color). But after the 10th line, it does not work anymore. Suddenly, it draws only 63 pixels with the new color, then only 46 or 45 (always keeping of course a full length of 64 pixels). Something like this :

11111111
22222222
33333333
........
AAAAAAAA
BBBBBBBC <- 63 pixels 'B' / 1 pixel 'C'
CCCCCCDD <- 46 pixels 'C' / 18 pixels 'D'
DDDEEEEE <- 45 pixels 'D' / 19 pixels 'E'

Why that behaviour ?
Why is it not a linear process ?

PS : The whole code is made between DI/EI to prevent an interrupt messing with it

Aangemeld of registreer om reacties te plaatsen

Van Grauw

Ascended (8455)

afbeelding van Grauw

21-08-2019, 16:52

The command engine speeds up during vertical blanking and slows down during active display.

This is due to there being a limited supply of VRAM access slots during active display.

Van Metalion

Paladin (1008)

afbeelding van Metalion

21-08-2019, 17:00

Yes, but I'm waiting for the 'jiffy' counter to change before starting the LMMV command, therefore I'm starting it at the beginning of the frame. And 10 lines of 64 pixels in SCREEN5 are only 320 bytes, so I do not think that the VBLANK border is yet crossed (according to your VDP speed tests Smile ).

Maybe it speeds up also during HBLANK ?

Van Grauw

Ascended (8455)

afbeelding van Grauw

21-08-2019, 17:26

Metalion wrote:

Yes, but I'm waiting for the 'jiffy' counter to change before starting the LMMV command, therefore I'm starting it at the beginning of the frame. And 10 lines of 64 pixels in SCREEN5 are only 320 bytes, so I do not think that the VBLANK border is yet crossed (according to your VDP speed tests Smile ).

LMMV at 60 Hz fills 1344 bytes / frame. So filling 320 bytes takes around 14000 cycles, roughly calculated of course not accounting for speed variation. At 60 Hz vertical blanking lasts 11400 cycles, so you’re exceeding it I think? (LMMV is pretty slow.)

Additionally, if you wait for JIFFY the BIOS ISR + DiskROM hooks run first before returning to your code, which take somewhere around 6000-8000 cycles or so. So you only have about 4000 cycles of the blanking period left when your copy is started.

Metalion wrote:

Maybe it speeds up also during HBLANK ?

During vertical blanking nothing happens in horizontal blanking either.

For horizontal blanking during active display, as you can see here the access slots are equally far apart when sprites are enabled, the VDP is busy fetching sprite data. Even if you disable sprites, horizontal blanking lasts only 57 CPU cycles, and the VDP command engine itself is slow, so it can’t utilise all the additional slots available. So there is some speedup but not as much as you saw.

Van Metalion

Paladin (1008)

afbeelding van Metalion

21-08-2019, 17:17

Yes, I think you are right.

My LMMV command starts during VBLANK, therefore it is speeded up for those 10 first lines.
Starting at the 11th line, it gets slowed down by the active display.

Van Grauw

Ascended (8455)

afbeelding van Grauw

21-08-2019, 17:21

You can check the VR status flag after the copy completes to determine if it is still blanking.

Alternatively you can disable the screen during your test and see if the outcome is different.

Van Metalion

Paladin (1008)

afbeelding van Metalion

21-08-2019, 18:33

Grauw wrote:

Alternatively you can disable the screen during your test and see if the outcome is different.

I did that.

And indeed the outcome is different, in the sense that the timing per line is now almost constant. However, almost is not enough, as the timing per line is too much sensitive. There is only 1 Z80 cycle between making a too short line at the 11th position and making a too long one at the 7th position. Nonetheless, I'll check on real hardware tonight.

Van Metalion

Paladin (1008)

afbeelding van Metalion

21-08-2019, 21:05

Metalion wrote:

Nonetheless, I'll check on real hardware tonight.

Done.
The result is the same as on OpenMSX (which is a tribute to its accuracy).

Van NYYRIKKI

Enlighted (5385)

afbeelding van NYYRIKKI

21-08-2019, 21:39

Metalion wrote:

timing per line is now almost constant. However, almost is not enough, as the timing per line is too much sensitive. There is only 1 Z80 cycle between making a too short line at the 11th position and making a too long one at the 7th position.

... and this I believe comes down to the VRAM access slots... Way more than you like to know: http://map.grauw.nl/articles/vdp-vram-timing/vdp-timing.html