Grevle Posted November 20 Share Posted November 20 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. Example: scrolltest5.xex *=13200 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 STA SDMCTL ;TURN ANTIC OFF 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 ; SETUP VERTICAL BLANK ADRESS 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 STX HSCROLL ;PUT SOME DOTS ON SCREEN 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 MAIN JMP MAIN *= 31045 ; Vertical Blank interupt INC SCON LDX SCON CPX #3 BCC EXD LDX #0 STX SCON DEC SCROLL LDX SCROLL STX HSCROLL EXD JMP $E462 ; Exit DVI ; The Display list *=36760 ;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 ;DISPLAYLIST SCREEN ADRESS = 36960 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted November 20 Share Posted November 20 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) $70,$70,$70 $5D,$60,$90 $5D, $A0,$90 etc. 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. Quote Link to comment Share on other sites More sharing options...
Rybags Posted November 20 Share Posted November 20 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 2 Quote Link to comment Share on other sites More sharing options...
Grevle Posted November 21 Author Share Posted November 21 Thank You. ..👍 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted November 21 Share Posted November 21 (edited) 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 November 21 by TGB1718 2 Quote Link to comment Share on other sites More sharing options...
TracMan Posted November 21 Share Posted November 21 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. Quote Link to comment Share on other sites More sharing options...
woj Posted November 21 Share Posted November 21 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 😜 Quote Link to comment Share on other sites More sharing options...
Grevle Posted November 21 Author Share Posted November 21 (edited) 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 November 22 by Grevle 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.