Jinroh Posted August 7, 2018 Share Posted August 7, 2018 Since I am re-writing the bankswitching for Carrot Kingdom™, I am curious if there is an optimal generic way in the past 30 years to use direct/indirect addressing of data from another bank within my display kernel. This would really help speed up development being more well organized and generic maintainable code. I would like to keep all the graphics data in one bank (right now it is mirrored in each bank) like I do with the level data currently. The level data only needs to be used in one section of code so it is easy to have one hot spot to jump back and forth between the banks as it executes. For the graphics data it needs to be more generic since it is used in many more places, and the best I can think is to have multiple hot spot points to jump back and forth but this seems irritating as it would add more to keep track of and more overhead. Any suggestions for this? Thanks my friends! But time to get back to homework. =.= For reference something like this. | | V Bank 1 Kernel: DrawStuff: lda GraphicCarrot,x or (GraphicCarrot),y ;Load from Bank Graphics sta GRPx Bank 2 Graphics: GraphicCarrot: blah, blah, blah, blah, blah Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 7, 2018 Share Posted August 7, 2018 Yes, the 2k bank size memory schemes are ideal for this because once switched in all the data is visible from the other bank with no additional hot-spotting overhead. With 4K bank sizes I use an identical switchboard at the top of each bank so I don't have to calculate anything. 1 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted August 8, 2018 Author Share Posted August 8, 2018 (edited) Thanks Mr SQL. Well I do know how to Bankswitch so maybe I misspeak in my post. I am trying to figure out a good way that is low overhead as possible to switch banks mid-kernel to draw graphics stored in. I have been doing similarly things to this with a Jump Table I use to jump into various places in various banks and jump back. This works well for some special cases, but not so much in this case. The jump table would become crazy annoying and a pain to maintain all the hot spot points. I do like your idea of having a Subroutine in the same spot in the two banks to jump between them. This lends itself very well to making it generic so it can jump mid-kernel with a JSR and then RTS back to that spot. It made me the idea for something like this (Excuse the Messy Pseudo-Code), still doesn't feel super optimal as it wastes some cycles in a kernel (and some bytes of overhead in the Graphics Bank though that may be unavoidable.), but it is a reusable way to do what I am thinking at least in my head I haven't tested it yet. Unless someone has a better idea I am not thinking. ^^ What do you guys think? Variables: GraphicsPtr - 2 bytes Bank 1 (Kernels): ;Top of bank Put SetGraphicPointer and DrawGraphicFromPointer SetGraphicPointer: sta SwitchToBank2 rts DrawGraphicFromPointer: sta SwitchToBank2 rts PreKernel: ldx NumberOfGraphicYouWant jsr SetGraphicPointer Kernel: ;Do Some Stuff .... ;Time To Draw Graphic ;y contains index to graphic data for P0 jsr DrawGraphicFromPointer Bank 2 (Graphics Data): ;Top of bank 2 Put SetGraphicPointer and DrawGraphicFromPointer 2nd versions SetGraphicPointer: lda GraphicsPtrHi,x sta GraphicsPtr lda GraphicsPtrLow,x sta GraphicsPtr+1 sta Bank1 ;Return to bank 1 rts DrawGraphicFromPointer: lda (GraphicsPtr),y sta GRP0 ;Draw P0 sta Bank1 ;Return to Bank1 rts ;Following Data ;GraphicsPtrHi/Low Tables. ;Tons of Data for graphics. Edited August 8, 2018 by Jinroh 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 9, 2018 Share Posted August 9, 2018 You're welcome Jinroh! Yes having the subroutine in the same spot in all banks is great for universal access from any bank with a single JSR and RTS which is also good for saving code, but there is a second JSR and RTS taking place once it reaches the subroutine at the top of the bank to reach the actual code. SvOlli and I did an interesting analysis somewhere of the method as being more or less efficient than other optimized methods depending upon how large the switchboard grows. Looking at your pseudocode two things I would add to implement it are adding the second hop so the actual routines are not in the switchboard, and appending a suffix to the labels in the second banks switchboard so the Assembler doesn't get confused unless the : allows duplicate labels which would be fine since they point to the same spots. 1 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted August 9, 2018 Author Share Posted August 9, 2018 (edited) Oh very interesting Mr. SQL and thanks. I wrote up the pseudo-code right before bed so I was leaving things out just to get the general idea across, but those are definitely things I missed. Since you and SvOllie looked at the efficiencies of these routines do you think this particular one is the best way to go about fetching this data in a kernel? Or is there an alternative that might give me less cycles to fetch it? After my re-organization I have ~800 bytes left in the graphics bank (which would be nice to add some more code graphics but we'll see) so I could put the time sensitive base kernel code that just processes the graphics data in there. Since it is not so many bytes. That may be a better alternative. Though if I could I would like to keep them separate if I needed to have as much graphics data in a bank as possible. Still kicking around ideas, but the code will be more organized and have less redundancy in the long run. So I appreciate bouncing ideas off of you. Edited August 9, 2018 by Jinroh 1 Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 9, 2018 Share Posted August 9, 2018 Oh very interesting Mr. SQL and thanks. I wrote up the pseudo-code right before bed so I was leaving things out just to get the general idea across, but those are definitely things I missed. Since you and SvOllie looked at the efficiencies of these routines do you think this particular one is the best way to go about fetching this data in a kernel? Or is there an alternative that might give me less cycles to fetch it? After my re-organization I have ~800 bytes left in the graphics bank (which would be nice to add some more code graphics but we'll see) so I could put the time sensitive base kernel code that just processes the graphics data in there. Since it is not so many bytes. That may be a better alternative. Though if I could I would like to keep them separate if I needed to have as much graphics data in a bank as possible. Still kicking around ideas, but the code will be more organized and have less redundancy in the long run. So I appreciate bouncing ideas off of you. Sure bounce some ideas and I'll help if I can - Carrot Kingdom is an awesome game! Here's the thread, it's a pretty interesting discussion. Turns out spacewise the switchboard method starts to become less space efficient after 4 routines, but I think speed wise it still saves a cycle. There's also an interesting programmer perspective article on using macro based bank switching routines that are slow and large. I generally avoid macro's for that tendency. You are pushing the 6502 pretty hard with the scrolling in Carrot Kingdom - I think for this game the fastest bankswitching method is the best, space efficient not as important. 1 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted August 10, 2018 Author Share Posted August 10, 2018 Awesome! I appreciate the support MrSQL I am going to code up a small test with my idea and see if I get my title and scrolling kernels working with the method I psuedo-coded above since it will be nice and re-usable. Not sure if I have any more cycle time in the Kernel, but I'm sure it can be optimized a bit. If not I could remove 'PF5' which might free some up. Not ideal, but a lot of similar scrolling games do the same. 1 Quote Link to comment Share on other sites More sharing options...
Jinroh Posted August 24, 2018 Author Share Posted August 24, 2018 So I got a good base setup for Carrot Kingdom with some macros and things to help out the more complicated bits. However, so we can have a very simple (stupidly simple) bit of code on the books that is easy to follow. I took one of SpiceWare's template files and coded up a really simple example of loading and using graphics data during a kernel to draw a sprite. BANK_DEMO_GRAPHICS_DATA.asm 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.