In issue 18 Kevin Preece writes:

"A request,  I have written routines to perform 4-way hardware tile  based 
scrolling  on  my  STE,  but now I would like to extend  it  to  do  8-way 
scrolling.  Does  anyone have any routines to do this on an  STE,  or  can 
anyone explain it in English?"

I  don't  find it very clear how you can have written  a  4-way  scrolling 
routine without being able to easily convert to 8-way scrolling.  However, 
I  shall  take  it from the beginning and explain  the  new  STE  hardware 
registers and how to create 8-way scrolling around a 'virtual' screen.

There are three lots of registers that the STE uses:

1) The HSCROLL register at $FF8265 allows the screen to be displayed at  a 
pixel offset between 0-15. As this registers increases the screen is pixel 
moved to the left.

2) The LINEWID register at $FF820F.  This register contains the number  of 
extra words that are added to the screen line width. In low resolution the 
normal  screen width is 160 bytes or 80 words (LINEWID=0).  When  you  are 
scrolling (HSCROLL<>0) this register must contain the extra words per line 
minus one fetch,  which in low resolution is four.  As four is  subtracted 
when  HSCROLL<>0 the minimum screen width is 168 bytes,  as if the  screen 
width  is 160 bytes then LINEWID=0 and so when four is subtracted  LINEWID 
would become negative (not good!).

3)  The  VBASELO register at $FF20D is the low byte video  screen  address 
register.  The ST can only display screens that are aligned on a 256  byte 
boundary because it only had high and medium byte video address  registers 
at $FF8201 and $FF8203.  Now that a low byte register is provided the  STE 
can display a screen anywhere in memory (as long as it's an even address).
Also  the STE has read/write video address counter registers  at  $FF8205-
$FF8209.

Example:  With  a  minimum  screen width of 168  bytes  let's  follow  the 
condition of the registers as the screen starts to scroll left.

At an x offset of 0:

     LINEWID = 4         ; 4 extra fetches
     HSCROLL = 0         ; horizontal skew
     VBASELO = 0         ; video address low byte

At an x offset of 1:

     LINEWID = 0         ; subtract 4 because HSCROLL<>0         
     HSCROLL = 1         ; 1 pixel skew
     VBASELO = 0

At an x offset of 2:

     LINEWID = 0
     HSCROLL = 2
     VBASELO = 0

You get the idea ....
When  you  reach an x offset of 16 the HSCROLL goes back to  zero  and  we 
increase the VBASELO register by eight which effectively scrolls 16 pixels 
to the left.

     LINEWID = 4
     HSCROLL = 0
     VBASELO = 8

And  so  on ....  Each time HSCROLL reaches 16 it is reset to  0  and  the 
screen address is increased by 8. If we keep doing this we will end up the 
the screen effortlessly scrolling off to the left.

Of  course as we scroll along what's scrolling in on the right ?  Well  if 
the  screen  width  is  big enough then we will  be  seeing  more  of  the 
'virtual'  screen.  If  we go to far then the next screen line  down  will 
start to scroll in from the right which we don't want.

In the example program I have set up a screen which is four times the size 
of a normal screen,  at 640 by 400 pixels.  This gives a line width of 320 
bytes which is 160 bytes extra than the normal width, so LINEWID=160.

That's horizontal scrolling dealt with,  for vertical scrolling we  simply 
add or subtract the line width from the screen address. In the case of the 
example that's adding or subtracting 320.

The example program allows you to specify an x and y coordinate which will 
be  the  coordinate within the 'virtual' screen that is displayed  on  the 
physical  screen.  Changing both the x and y together allows you  to  move 
in  any direction you want.  The example has a little sine  look-up  table 
which  is used to move the screen of coloured tiles around in  a  circular 
pattern.

I  have done one naughty thing that I should tell you about.  The  example 
needs  a  50Hz interrupt and so it is placed in the ST VBL list  at  $4CE. 
Only  trouble  is if you change the video address registers they  are  not 
updated  until  the  next VBL which occurs before  the  programs  VBL.  In 
plain  English this simply means that the screen would flicker.  To  avoid 
this  you would normally have to put the interrupt on a  higher  priority, 
such as patching into the $70 vector.  I wanted to keep the interrupt side 
of  the program simple and stuck to the VBL list method.  This means  that 
the  video  address  counters  are  used  instead  of  the  video  address 
registers.

The  video address counters on the STE can be written to and when  written 
to  they affect the video display on the next scan line so is  effectively 
immediate. Hope that didn't confuse you too much.

I hope this makes things a little clearer. It would of been useful to know 
your  definition  of  a 'tile',  my interpretation of  this  was  lots  of 
coloured squares !

By the way, all the registers mentioned are byte registers so don't forget 
to put .B after them.

Cheers,

Terry King

