# help understanding horizontal scroll

Page 1/2
| 2

Hi,

While working on the V9958 emulation in live.bluemsx.com I ended up a bit confused about how horizontal scroll actually works (in particular the lower 3 bits and edge masks). If someone could help me understand I'd be very thankful.

What I'm trying to fully understand is how the first 24 pixels of a scan line (including border) is rendered given the horizontal scroll register. Assume with hscroll = 0, the following pixels are rendered (I assume):

b b b b b b b b 0 1 2 3 4 5 6 7 x x x x x x x

where b is 8 left border pixels and x'es are the next 8 pixels on the scan line.

so first question: With hscroll = 1 how are the pixels 0-7 mapped (e.g.):
b b b b b b b 0 1 2 3 4 5 6 7 x x x x x x x x
or
b b b b b b b b b b b b b b b 0 1 2 3 4 5 6 7 x
or something else

second question assume border masking is set, which pixels are masked (both in the hscroll = 0 case and when hscroll = 1)

third question, how is border masking looking at the right border?

Any thoughts that can help me fully understand this is appreciated.

Hi dvik, welcome back!

The following is from memory, so I may have made a mistake. But IIRC it's reasonably well explained in the V9958 datasheet. Alternatively you can check the behavior/implementation in openMSX.

Scrolling works as expect, except that the first drawn non-border pixel is always a multiple of 8 (I mean a pixel whose non-scrolled x-coordinate is a multiple of 8). Thus the left border is extended with 0-7 extra border pixels. For example: if you scroll 1 pixel to the left, then the left border is extended with 7 extra border pixels, and the first non-border pixel is the pixel with x-coordinate 8 in the non-scrolled image. The right border is not influenced by scroll-amount.

The left border is now unconditionally extended with 8 pixels. Thus there are only 256-8=248 non-border pixels. All other pixels (including the right border) are the same as in the scenario above.

Thanks, that sounds like I understand it as well. I did look at both the bluemsx source code and openMSX as well as the data sheet, but I didn't feel 100% sure I got it right (neither is super explicit and wanted to confirm my understanding is correct). When it comes to the right border, does that then move 0-7 pixels or is the right border also masked?

Right border does not move, it's not influenced by the mask bit.

And if (hscroll & 7) > 0 the right border is still fixed?

Yes.

Thanks!

@wouter_'s explanations are on point. Unfortunately horizontal scroll on OpenMSX, at least at version 0.14, which is the one I tested, isn't working right when mask is disabled, so it shouldn't be used as reference. WebMSX, on the other side, emulates it correctly, so I put together a small horizontal scroll test program. You can check it out on MSXPen if you feel like it:

https://msxpen.com/?code=-LX1-xpqn2_1RgjiTwlv

Please forgive me for the slowness and for the mistake in labeling the VDP registers. I used the VDP BASIC command number instead of the official one.

I think the funniest thing about the horizontal scroll registers is that when you increment R#26, you scroll left, and when you increment R#27, you scroll right. So if R#26 is 1, everything scrolls 8 pixels to the left. If R#26 is 63, everything scrolls 8 pixels to the right. The scroll field is always treated as a 512 pixel wide picture, but the current page wraps around itself when R#25's bit 0 is reset, and wraps around the other page when R#25's bit 0 is set.

As for R#27, it tells the VDP how many extra border pixels must be painted at the left of each line, and how many pixels won't be painted at the right of each line. So the right border remains fixed, with the same width, while left border grows as R#27 increments, shifting everything to the right. This looks a bit unsightly, so if you set R#25's bit 1 the first 8 pixels to the left are always painted with the same color as the border, becoming hidden. This effectively makes the left border 8 pixels wider.

Sprites aren't affected by horizontal scroll, but you probably already knew that. Also in SCREEN 6 and 7 horizontal scrolls work two pixels at a time.

In the file "MSXTopSecret2Continuo.pdf", chapter 6.8, it has been perfectly explained. It is in Portuguese. Translate.
http://www.afwg.com.br/msx/livros/MSXTopSecret2Continuo.pdf

The book "MSX Top Secret 2" is indeed awesome, but although it explains how to use the horizontal scroll registers, it doesn't really explains what happens when the mask bit in R#25 is unset and you try to use R#27.

If bit 1 of R # 25 is set to 0, the 8 oscillation bits of the screen are shown to the left. Setting it to 1, this is hidden. Of course these 8 bits of screen are lost. With R # 18 we recentrate it if you want.
This is the routine that I use. I do not remember where it came from and I apologize to the author for not mentioning it.

```;___________________________________________________________________
;       MAKE HORIZONTAL SCROLLING (ENTER A = X SCROLL VALUE)
;___________________________________________________________________
SCROLLH:
HALT
LD      B,A
RRA
RRA
RRA
AND     #1F
OUT     (#99),A
LD      A,#80+26
OUT     (#99),A
LD      A,B
AND     7
XOR     7
OUT     (#99),A
LD      A,#80+27
OUT     (#99),A
RET
```
Page 1/2
| 2