# Algorithm for Scroll

Página 1/2
| 2

I've developed an algorithm for Scroll on Screens 1/2, here's the link if anyone is in need of one, or if you have suggestions for improving it:

Entrar ou registrar-se para comentar

euh e.g. "hl = buf" is that assembly?

what assembler assembles that?

hl = ?, means:
ld hl,?
or
pop hl (if you are receiving it in a C function)
or
etc

Just set hl, de, bc as you prefer, the important is setting the registers with the values shown in the "algorithm".

For example, the line RT: hl = buf[766] de = buf[767] bc = 767 lddr, could be coded in this way:
ld hl,buf+766
ld de,buf+767
ld bc,767
lddr

The code for Scroll Up, could be coded in this way:

```    ld    hl,buf + 32
ld    de,buf + 0
ld    bc,736
ldir

ld    hl,aux
ld    de,buf  + 736
ld    bc,32
ldir

in    a,(99h) ; clear F flag
waitf:
in    a,(99h)
and   080h
jr    z,waitf ; wait scan end

xor   a
out   (99h),a
ld    a,18h + 40h
out   (99h),a

ld    hl,buf
ld    bc,098h
otir
otir
otir```

waitf:
in a,(99h)
and 080h
jr z,waitf

What's supposed to do? Waiting vblank? Better you poll JIFFY system variable in RAM (update every 1/50th of sec). If you directly read the status register you reset the interrupt flag too, so interrupts may not occur..

Before your first out (99h),a you have to di (disable interrupts) and ei (enable interrupts) just before second out (they will be reenabled just immediately after your second out). You jave to disable them cause vdp registers are used during ISR too and ot can cause some mistakes (you know, in a complete code there isn't only the scrolling routine)
And you can use OTIR only if all your scrolling stay in vertical blank (else you'll have corrupts VRAM, plenty of garbage). But a simple 8 pixel scrolling is fast enough.

thegeps wrote:

waitf:
in a,(99h)
and 080h
jr z,waitf

What's supposed to do? Waiting vblank? Better you poll JIFFY system variable in RAM (update every 1/50th of sec). If you directly read the status register you reset the interrupt flag too, so interrupts may not occur..

Additionally the flag may be missed entirely. This is a known issue when polling auto-reset status flags. If it happens to be set by the VDP at the same time that it’s read by the CPU, the CPU will never see a 1.

Thank you guys for the hints about the interrupts, and the polling problem.

I've created 3 examples to show the scroll working. In these examples, I'm looping the screen, so I get the line that is going out of the screen and use it as aux (buffer with the new characters).

The first example uses the present scrolling algorithm in the 8 directions, using screen2 with the pattern and color tables repeated 3 times.
Scroll Ok in all 8 directions

The second example shows what happens if you try to use this same algorithm to scroll a full image, in this case, the pattern and color tables are fulfilled like in a photo, and the names table is filled 3 times with 0-255.
You see the problem in vertical scrolling, because the characters roll in the same bank (up, middle, down).
Vertical Scroll with Error

And in the last example, I've changed the algorithm to work with full images, transferring the necessary parts of the pattern and the color tables from one bank to another. The problem here is that there is no time to transfer the 2304 bytes to the VDP in the vblank duration, and this causes a noise problem.
Vertical Scroll with noise

Later I will publish this algorithm for the scroll of full images in order to find ideas to improve its speed.

noises are caused by OTIR instruction. It's too fast and if it run out of the vblank it cause VRAM garbage. Instead of:
otir
otir
otir

use:

loop1:
outi
jp nz,loop1
loop2:
outi
jp nz,loop2
loop3:
outi
jp nz,loop3

Try it also in openMSX on an MSX1 like the Toshiba HX-10. It looks different (worse) than in WebMSX.

Página 1/2
| 2