+mksmith Posted July 3, 2022 Share Posted July 3, 2022 Hi all, I been wanting to look into scrolling for quite a while to see how we can achieve having maps > 256 columns (horizontal). In various guises across the forum (for 7800basic) there are quite a few examples generally using plotmap (drawing a left and right screen halves - there is a 32 column limit to drawing using plotmap) to do the job shifting the location to help simulate fine scrolling and it worked very well for me in my GnG sample (which just happened to fit nicely with the split level map). Anyway I did some research around some techniques used and starting with pure 7800basic got things moving but then converted the main routine to pure assembly (thanks to some learning doing PETSCII as well as assistance @RevEng has generously provided to myself and the community over the last few years). The main goals were the following: get a map larger than 256 characters wide (currently 512) use the 'Under the Hood' TM method after drawing the initial screen to simulate fine scrolling - this method allows us to directly access the screen row zones of already drawn and saved objects rather than redrawing everything use hand-coded assembly for the best possible speed performance (even my low level of knowledge of 6502 has shown significant increases) Stretch goals: ideally make it multi-directional (left and right) - TBC can we use double buffering of screen buffers to increase performance? (yes we can but currently at the expense of redrawing the background when switching buffers. Shifting sections of the back buffer each frame rather than at the end also spreads the load.) Map and buffer Maps are designed for 512x17 in size width can be customised (recommended 256 increments due to math) height can be customised (adding or removing MAPSCREENBUFFERROWX entries) changes will need to be made to the shift/copy routines to accommodate Buffer is designed for 42x17 in size and scrolling from right to left Columns 41/42 are used to load the next incoming characters Scrolling based on 8 pixels (or 2 characters) for better performance Process Draw initial screen background (a left and right side) and save screen Shift background using the 'Under the hood' method At completion of the shift, restore the background zone(s) to their starting position, shift the buffer columns over 2 characters and copy in the next 2 characters Notes As the 'Under the Hood' TM method is used we don't need to continually draw the background We need to add a drawwait call to ensure the restore/shift/copy routine doesn't tear the screen but this introduces a 1 frame delay (and potentially more??). To match this I've added a counter to simulate this during fine scroll Overall the scroll shifts every 2nd (or could be more if required) frame then allowing time for other updates on the other frame(s) On PAL there is frame variations (TBD) making the scrolling less smooth If moving 8 pixels just call the CourseScroll routine directly The routine could be changed to copy the map data out of ROM but larger maps might be difficult to access due to bank requirements Src 20220704.scrolling.zip Build View on JS7800 scrolling.a78 Final thoughts There are probably a few things that can be improved so please feel free to discuss! Hopefully some of you will find this useful for your projects! The Uridium map was grabbed out of CharPad Pro by Subcrist Software (https://subchristsoftware.itch.io/charpad-pro) is highly recommended and is a fantastic map building tool even for the 7800! The characterset width was reduced to cater for our 7800 needs (tip!! multi-color on the c64 is essentially double-width and can be halved for 7800 needs). 10 1 Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted July 3, 2022 Share Posted July 3, 2022 Matt, this is fantastic, thanks for sharing this! edit- sorry should have said, Win10 gets upset with the file when opening as a compressed folder but 7ZIP is fine. 5 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 3, 2022 Share Posted July 3, 2022 (edited) @mksmith I'm getting "The archive is corrupt" ? edit: online unzip works (I'm using winrar) Edited July 3, 2022 by Eagle 2 Quote Link to comment Share on other sites More sharing options...
+Trebor Posted July 3, 2022 Share Posted July 3, 2022 Also decompressed fine with 7-Zip. I'm running v22.00 x64 under Windows 10. 3 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 3, 2022 Author Share Posted July 3, 2022 Strange - just zipped up with built-in zipper in Win11. Will upload again ? 1 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 4, 2022 Author Share Posted July 4, 2022 I've updated the attached source in the first post (used 7-zip this time). 2 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 4, 2022 Share Posted July 4, 2022 Hmm 7000 cycles, not great, not terrible 2 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 4, 2022 Author Share Posted July 4, 2022 2 hours ago, Eagle said: Hmm 7000 cycles, not great, not terrible There is definitely a lot of repetitive shifting of data - the double buffer version is nice as it allows that to be spread over multiple frames at the cost of redrawing to switch buffers. There is a major cost on the final shift in this single buffer version but saving on the redrawing is a big win regardless. I'm sure someone with a better idea on 6502 could make a few savings somewhere. Also some of the loops could be unrolled and/or in-lined to save a few cycles. Certainly very happy to take any feedback people might have to make it better! 2 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 5, 2022 Author Share Posted July 5, 2022 Started expanding the scrolling to cater for left and right movement. Updated the buffer to 44 columns and repositioned the default positions. I've inlined the main shift and copy routines which will save 6 cycles per column activity at the expense code space. Next up will be getting the left -> right scrolling going (will do the coarse scrolling first). 3 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 5, 2022 Share Posted July 5, 2022 Why you redrawing screen instead of changing Display List screen address? 1 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 5, 2022 Author Share Posted July 5, 2022 2 hours ago, Eagle said: Why you redrawing screen instead of changing Display List screen address? The 'Under the Hood' method utilises the savescreen/restorescreen/drawscreen feature of 7800basic. Normally moving objects (maps, sprites etc) are redrawn each loop as part of that process but what the 'Under the Hood' method allows us to do is directly access the zone objects to shift them within their zone without calling the 'plot' feature each time. My next step in this would be shifting game sprites (ones staying within their zones) using this process without calling plotsprite each frame - probably not so easy depending on the actual game play. It may not be as optimised as fully controlling the process yourself but that is definitely way above what the majority of us (including me!!) are currently capable of doing without 7800basic. I guess this is a bit of a halfway mode but still allow the use of 7800basic. 1 Quote Link to comment Share on other sites More sharing options...
SlidellMan Posted July 5, 2022 Share Posted July 5, 2022 Matt, Can this be used for vertical scrolling? 1 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 5, 2022 Author Share Posted July 5, 2022 18 minutes ago, SlidellMan said: Matt, Can this be used for vertical scrolling? Unfortunately not in it current format. It would definitely be possible but the 'Under the Hood' savings will need to be removed as things would be crossing screen zones. 2 1 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 8, 2022 Share Posted July 8, 2022 (edited) Hi @mksmith Quick example scrolling Left/Right Uridium in MADS Use joystick About 3500 cycles (not optimized) blue line showing CPU usage Uridium scroll lef&right - Link to JS7800 Main code below (sorry for using MADS macros but code is much shorter) https://mads.atari8.info/mads_eng.html edit: ram usage for Uridum (42bytes*17line)+512bytes map lenght+1byte=1227bytes You can use any map up to about 16000 bytes length screen equ $2400+1 NMI phr mva #$a6 BACKGRND ;show CPU time jsr Joystick jsr CalculateOffset jsr UpdateDisplaylist jsr CopyColumnRight jsr CopyColumnLeft mva #$00 BACKGRND plr rti CopyColumnRight mwa #screen+40 Dest adw Dest Temp mwa #map Sour adw Sour Temp CopyColumn ldy #$00 ldx #17 @ lda (sour),y sta (dest),y inc sour+1 inc sour+1 ;2xINC MSB = +512 adw dest #42 dest ;will be easier for 64 bytes wide screen dex bne @- rts CopyColumnLeft mwa #screen-1 Dest adw Dest Temp mwa #map-41 Sour adw Sour Temp jmp CopyColumn CalculateOffset mwa Hscroll Temp clc ror Temp+1 ror Temp clc ror Temp+1 ror Temp lda Hscroll and #$03 eor #$FF sta H_x clc adc #128 sta H_x_2 rts UpdateDisplaylist mwa #Screen Sour adw Sour Temp mwa #line Dest ldx #17 @ ldy #00 ;LSB lda Sour sta (dest),y ldy #02 ;MSB lda Sour+1 sta (dest),y ldy #04 ;X pos lda H_x sta (dest),y adw Sour #32 ;dodaj 32 do adresu ekranu ldy #05 ;LSB lda Sour sta (dest),y ldy #07 ;MSB lda Sour+1 sta (dest),y ldy #09 ;X pos lda H_x_2 sta (dest),y adw Sour #10 adw Dest #16 dex bne @- rts Joystick lda SWCHA and #$F0 :4 lsr @ eor #$0f cmp #$08 ;right bne @+ inw Hscroll ;incrase word rts @ cmp #$04 ;left bne @+ dew Hscroll ;decrase word @ rts uridiumscroll.a78 UridiumScroll.rar Edited July 8, 2022 by Eagle 3 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 9, 2022 Author Share Posted July 9, 2022 Wow @Eagle that's fantastic mate! So this is along the lines of what you were referring to in relation to adjusting the DL reference. Interesting language! Those macros are very nice! 2 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 9, 2022 Share Posted July 9, 2022 Yes. I will add vertical scroll later so you can have 4way scroll. No extra ram needed 1 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 9, 2022 Author Share Posted July 9, 2022 Thanks mate - that would be fantastic! Quote Link to comment Share on other sites More sharing options...
Ecernosoft Posted July 9, 2022 Share Posted July 9, 2022 17 hours ago, mksmith said: Thanks mate - that would be fantastic! 17 hours ago, Eagle said: Yes. I will add vertical scroll later so you can have 4way scroll. No extra ram needed Honestly, all you need to do is with your background, change the heights of 2 DLL's (One on the top, the other on the bottom) in that when you want to go down one pixel, you add one to the top and subtract one from the bottom, and vice versa to go up (Shrink the top, enlarge the bottom) and when there is no more room, you reset it all and move all the background graphics pointers (Each row has it's own pointer) up one row, get rid of the top pointer and make a new one for the bottom. 1 Quote Link to comment Share on other sites More sharing options...
Ecernosoft Posted July 9, 2022 Share Posted July 9, 2022 I hope that made sense... Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 9, 2022 Share Posted July 9, 2022 The trick is to wrap the screen so you don't have to use extra memory. In 8-bit Atari they call this MWP (definitely don't read it ) but Antic DL is little bit better for this. 3 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 10, 2022 Share Posted July 10, 2022 ???? OMG I just realized that in character mode, when scrolling the screen vertically, you need to change the value of the CHBASE register on the last line. I was wondering when I was porting Robbo why I was having a problem with the last line. 2 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 11, 2022 Share Posted July 11, 2022 (edited) VScroll in indirect mode I will provide later full procedure for only Vertical Scroll in charmode You have to update CHBASE on top of the screen ;update just after VBlank lda #>FNT sta CHBASE VScroll .ds 2 ;2bytes zero page Vertical Scroll counter ChbaseOffset .ds 1 ;1byte zero page FNT = $a000 ;chars address ;DisplayListList DLL FirstLine .byte $07,>FirstDlLine,<FirstDlLine .byte ..... next line .byte ..... next line .byte ..... next line LastLine .byte $87,>LastDlLine,<LastDlLine ;$8x Display List Interrupt ;Display List Interrupt NMI pha lda ChbaseOffset sta WSYNC sta CHBASE pla rti UpdateDisplaListListVerticalScroll lda Vscroll ;LSB Vscroll and #$07 ora #$80 ;set bit 7 for Display List Interrupt (NMI) sta LastLine lda Vscroll ;LSB Vscroll and #$07 eor #$07 sta FirstLine clc adc #>FNT ;calculate CHBASE for last line sta ChbaseOffset rts Edited July 11, 2022 by Eagle 2 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 16, 2022 Share Posted July 16, 2022 @mksmith Commando vertical scroll with copy screen + source code (joystick up/down) Next will be vertical wrapping scroll (soon) Commando - emulator link CommandoCopyScreen.a78 CommandoVScrollCopy_SourceCode.zip 5 2 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted July 16, 2022 Author Share Posted July 16, 2022 13 minutes ago, Eagle said: @mksmith Commando vertical scroll with copy screen + source code (joystick up/down) Next will be vertical wrapping scroll (soon) Commando - emulator link CommandoCopyScreen.a78 32.13 kB · 2 downloads CommandoVScrollCopy_SourceCode.zip 7.08 kB · 1 download Jeez mate that's brilliant thank you! I now need to work out how I can fit this into the 7800basic structure - it's amazingly efficient and opens up plenty of doors for adding more scrolling games to the platform! 5 Quote Link to comment Share on other sites More sharing options...
Eagle Posted July 17, 2022 Share Posted July 17, 2022 @mksmith wrapped version VScroll Up/Down. This is really fast! This version is drawing top and bottom row every VBlank to make program less complicated. But really when you scrolling up you need update update only top row, when scrolling down update bottom row. And only every 8th frame (if your zone is 8 height). So if you are scrolling only in one direction (vertical shooter) you need update top row every 8 frame. For 7 frames you need about 200 cycles and on 8th frame when you change zone about 1500-2000 cpu cycles. You don't need any extra ram (640 bytes of RAM used in this example) Source code included, feel free to ask Commando Wrapped VScroll - emulator link CommandoWrapped.a78 CommandoWrappedVScroll_SourceCode.zip 4 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.