Jump to content

Horisontal Scrolling LMS help

Recommended Posts

Im trying my hand at Horisontal fine scrolling in assembly, i set up the graphics mode in assembly that is the equalent to Basic mode 7+16.


As i understand i need to change the LMS or display list during the scroll to make it work properly. In my example below the changig of the LMS and display list is missing,

Because im not sure how and when to alter the LMS and Displaylist in the program ? , I read the scrolling tutorial, but im slow to adopt to parsing and methods i don't understand fully.








SCROLL = 1600          
SCON = 1601 
HSCROLL = 54276      
SDMCTL = 559 ; Can turn on and off Antic (needed when creating display list)
SDLSTL = 560 ; Shadow display list pointer low - Antic må vite hvor den nye display listen er
SDLSTH = 561 ; Shadow display list pointer high 

     LDA #0
     LDA #152 ; LOW BYTE
     STA SDLSTL ; store low byte of display list adress
     LDA #143 ; HIGHBYTE
     STA SDLSTH ;store high byte of display list adress
     LDA #34
     STA SDMCTL ; ... Turn on Antic again
    LDX #121 ;Setup VBI Highbyte 121*256+Lowbyte 69 = adress for VBI = 31045
    LDY #69
    LDA #7
    JSR $E45C ; SetVB

    LDA #0
    STA 512
    LDA #150 ; DLI ADRESS 38400
    STA 513
    LDA #192 ; =192   ; ENABLE DLI
    STA 54286 ;NMIEN    

LDX #0


LDX #1
STX 36970
STX 36990
STX 37150
STX 37200
STX 37300
STX 37400
STX 37500
STX 37600
STX 37700
STX 37850
STX 37900
STX 38100
STX 38300
STX 39000
STX 39500
STX 40500
STX 40600
STX 40700
STX 40750
STX 40770


 *=  31045 ; Vertical Blank interupt

CPX #3

LDX #0




JMP $E462 ; Exit DVI

; The Display list

;GR 7+16  


.BYTE 112,112,112 ;= Three blank lines

.BYTE 93,96,144

.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29,29,29,29,29,29
.BYTE 29,29,29,29,29

.BYTE 65,152,143 



Link to comment
Share on other sites

For horizontal scrolling to work, each line that scrolls needs to be wider than the visible screen.

So for each line that you want to scroll will need an LMS instruction with the address of that line.


So if you want a 64 byte wide line you would start your screen (in your example $9060)



$5D, $A0,$90




I think you have to be careful crossing a 4K boundary, aligning the start address is critical if that's going to happen.


To do the scroll, you increment or decrement the fine scroll register, when you reach 7 or 0 depending which way your going

you add or subtract 1 from the low byte of each LMS address and then set/reset the fine scroll register.

If your careful, you may not need to update the LMS high byte.


Link to comment
Share on other sites

Generally you want to alter DLists during VBlank or at least after the relevant part has been displayed.

Hscrol register - easiest done in VBlank but if you have multiple scroll areas then you'd adjust it just before each area starts.


The thing with LMS + Hscrol  - each works the opposite way.

If you increment the LMS address, the display moves to the left, increment HScrol it moves to the right.


A trick you could use is to have a "world coordinate" origin type of system which operates in 160h pixel values.

To get the LMS value, shift it right twice then add it to the normal screen origin.

To get the HSCROL value, AND it with #3 then EOR with #3.

So then you'd have a running set of values like:

World X      Actual LMS     Actual HSCROL

0 0 3

1 0 2

2 0 1

3 0 0

4 1 3

5 1 2

6 1 1

7 1 0

8 2 3

  • Like 2
Link to comment
Share on other sites

One minor point, if you want your scrolling to be "circular" i.e. appear to be continuous, the beginning 'x' number

of bytes on the left of a line have to be the same as the 'x' number of bytes at the end of a line, where 'x' is the number of bytes

needed when scrolling is reset to not see any change on screen.


Edited by TGB1718
  • Like 2
Link to comment
Share on other sites

The scrolling part using LMS is really not difficult, it is simply CPU labour saving.  However, there are different and complex ways of providing and laying out the memory for the scrolling region.  Most screens will typically have different regions such as a change in graphic mode in low or hires/ LMS for any non scrolling score panel, so fix the memory and the LMS for that into the display list first.


Then at it's simplest lay out the full scrolling region memory based on the number of bytes across the scrolling region x the number of lines.


Imagine a simple example, if you were using Antic mode 4 (basic mode 12) instead, since it's also 40 bytes across, if you allow 128 chars per line, you get 128/40 or just over 3 screens horizontally.  Say you are scrolling over 16 rows of the screen, that's just 16 x 128 bytes or 2k for the whole lot, not bad when you think 960 bytes (40 x 24) is required normally for one screen.  So you would set each LMS instruction at 128 bytes plus the one on the previous line.


Each time you want to move the screen fully one character to the right, you just need to clear the carry flag, increment the LMS instructions memory pointer low byte and then if there is a carry, additionally increment the LMS high byte.  Bingo, the screen 'view portal' moves across the graphics image.  Because, if you already laid out the screen data for several screens wide, you only have to deal with the increment of LMS instructions.  There is no requirement for drawing new data to the right hand side of the screen.  Best example here is to think of the game Scramble where it scrolls continously.


However, when you do this with Mode 7, then you have a lot more mode lines and hence LMS instructions.  Any horizontal layed out memory will be 8 times bigger to support each row line.  But, see how much simpler it still is to increment only up to 192 LMS instructions using the method above, rather than do a complete move of the screen like other machines have to do.


However, there are scrolling games that use bitmap screens that lay out the working screen in a couple of screens width, since you can't afford the memory to layout all of the horizontally scrolling level.  The way they work is to allow you to move your view portal across into the 3 screens width where they are 'building' the level and at some point, they jump the LMS back to the left most first screen.  So they draw the new screen in two places, on the right where you are moving into and redrawing it on the left behind the area you already scrolled through, so you can jump back to it.


Link to comment
Share on other sites

16 hours ago, Rybags said:

The thing with LMS + Hscrol  - each works the opposite way.

If you increment the LMS address, the display moves to the left, increment HScrol it moves to the right.

And if I still remember it right, the VBXE attribute map has it somewhat different, which caused me a huge understanding pain when doing the Popeye horizontal screen shakes 😜 

Link to comment
Share on other sites

Thank you guys 😊. Lots of useful information for me and others. 👍


In mode 7 i was just planning to have a draw routine that draws a randomized cave as the scrolling occurs instead of having a pre layed out memory map.

The randomized cave routine must have a control  routine that sort of increase the difficulty of caves. Back in the day i made something like that in Atari Basic.

That code is lost and i wanted to sort of replicate it in assembly.


Edited by Grevle
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...