fultonbot Posted August 28, 2020 Share Posted August 28, 2020 Does anyone have a template or sample of how to properly use bank switching in 128KRAM game (or 128KBANKRAM). I'm not looking for anything fancy, just maybe sample to answer these questions: 1. Which bank is always resident? (the last one? is that bank 8 in 128K?) 2. How many times have a define a bank? If once, do I put all the incgraphic commands inside the bank definition? 3. Is there pattern that puts utility code in single bank to call across banks? 4 Is it common to have to replicate code in multiple banks (or include font multiple times) Thanks in advance to all the great people here. Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted August 28, 2020 Share Posted August 28, 2020 I don't have a template but I'll try to answer as best I can. 1. Yes, with 128kb it's bank 8. With 144k you get both bank 8 and bank 1, but the downside is you can't have 144k with extra RAM. 2. You split up your code with the command 'bank #' to flag everything below that line as belonging to the given bank number until it hits either the end of your source code or another bank command. When you use incgraphic, incbanner, or any other method of importing data, they will be imported to whichever bank you last specified. This is important to consider when it comes to graphics because if you draw graphics that aren't in bank 8, if you change banks the 7800 will draw whatever is at the same spot in the bank you're currently in. This means you may choose to import graphics into multiple banks (in the same order so they're in the same position). 3. I'm not sure what you're asking here, but you can call subroutines from any bank by giving the bank it sits in as a parameter. You have to remember though that it swaps banks to run the code and then swaps back so you can't call a subroutine in bank 5 from bank 3, and expect it to have visibility of data in bank 3. 4. Yes, this is very common across all games on all consoles that have bank switched cartridges. To give you a couple of examples, in Spire of the Ancients I have no way of knowing which bank it will be in when it needs to start drawing the screen so the first thing in every bank is a (for the most part) identical copy of my 'topscreenroutine'. Another example is that I was going through some code and found a spot where I was repeatedly jumping to another bank to run a routine and found that the small amount of setup needed to change banks in the background was eating a surprisingly hefty bit of ROM so I simply duplicated the routine to avoid switching banks which saved space and improved the speed. 2 1 Quote Link to comment Share on other sites More sharing options...
SlidellMan Posted August 28, 2020 Share Posted August 28, 2020 In regards to top_screen_routine, where in the main working file would it be written? Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted August 28, 2020 Share Posted August 28, 2020 For a non-bankswitched game the topscreenroutine can go anywhere. The trick to using it with bankswitching is that you need to realise that a label is just an easy to read representation of a numerical address, and that when you switch banks you're switching the values at those same addresses and not swapping to a different set of addresses. For example, when you compile your game, topscreenroutine might represent address $1234, but what's at $1234 won't be the same in different banks without extra work so you might end up with your code jumping to $1234 expecting to run the topscreenroutine and instead finds itself in the middle of a block of data processing nonsense and ultimately crashing. To get around that we need to make sure that $1234 contains the right code in whichever banks we need and the easiest way to do that is to put the code immediately after the bank # command so it's in the same spot. You still can't have multiple labels with the same name so only one copy is called topscreenroutine and in my code the others are things like topscreenroutinebank2, topscreenroutinebank3, etc. 3 Quote Link to comment Share on other sites More sharing options...
fultonbot Posted August 28, 2020 Author Share Posted August 28, 2020 (edited) 53 minutes ago, SmittyB said: I don't have a template but I'll try to answer as best I can. 1. Yes, with 128kb it's bank 8. With 144k you get both bank 8 and bank 1, but the downside is you can't have 144k with extra RAM. This all was wildly helpful. A couple more questions if I dare: 1. Is it common pattern to put graphics used often in bank 8 of 128KRAM game? 2. I plan to have one tight engine for main levels and one for boss fights, both reply on data stored in ROM which would mostly likely be in additional banks that store only data. Is it possible to load data into an array structure in RAM from different bank than the one you are currently using? 3. Do things like dim, font, alphachars, and palette settings need to be defined in a specific bank. It feels like these are mostly directives and peek/pokes/registers settings, but I could be wrong. Thanks, Steve Edited August 29, 2020 by fultonbot 1 Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted August 29, 2020 Share Posted August 29, 2020 1. Yes, generally anything that gets shared throughout your game would go in bank 8. If you have something that only gets used once or twice that might be a good candidate for duplicating between banks. 2. Yes, you can jump to one bank, put some data in RAM, and then jump back to run whatever code you need to. That goes for both the normal RAM on the console and RAM on the cart (and if you have banked RAM then the RAM you copied the data to needs to be the RAM that's enabled). One way to think of how the larger cartridge sizes work is as if there are 3 16k slots that they can fill. 128K and up keeps one filled with the last bank, swaps around what's in another, and either leaves the third empty of fills it with extra RAM. 144K, 272K, and 528K would be the same except instead of RAM in the third slot or leaving it empty it keeps bank 1 in it. 2 1 Quote Link to comment Share on other sites More sharing options...
SlidellMan Posted August 29, 2020 Share Posted August 29, 2020 Thanks for the clarification, that means a lot. Quote Link to comment Share on other sites More sharing options...
+SmittyB Posted August 29, 2020 Share Posted August 29, 2020 To answer your amendment - 3. Palettes can be set anywhere as those are held in RAM on the console so always visible. Dimensioning memory I think can be done anywhere. As for the font and alphachars, your font graphics could be anywhere but would need to be in a selected bank for it to draw properly, and as for alphachars I don't know as I've not used it much. 1 Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 10, 2022 Share Posted March 10, 2022 (edited) I'm looking to convert Wizard's Dungeon from a 48k game to a larger bank switched ROM size as a starting point for another project. Just changing rom size, without changing any other code, gives me this: Is this because instead of one 48k contiguous block you've got 3 16k banks? I'd have to basically separate it into 3 16k banks to get the existing code to compile? Given the spaghetti mess of code that WD turned into it might be easier to start fresh, but I'd like to better understand how to manage the space. [Edit] Yep, just separating out the code with bank # statements seems to work. That did it. Duh. Thanks for being my rubber duck! Edited March 10, 2022 by BydoEmpire 5 Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 12, 2022 Share Posted March 12, 2022 While my basic bank switching is working, I'm wondering if there's a way to use graphics stored in different banks on the same screen. Doesn't *seem* like it, but I haven't quite wrapped my head around what's actually happening under the hood. Without a frame buffer to copy the sprites into, it'd seem like whatever is being plotted just points to a location and whatever is at that location in the current bank gets drawn. The code below work, I can cycle through the banks and display whatever sprite is in whatever bank, but seems kinda wasteful to have to copy the tileset in each bank. In terms of how to organize everything, I guess I'd have to have all of the graphics for a given level in one bank, 16k limit, along with whatever code does the drawing. An common graphics would have to be copied in each bank. Any generic game code could be anywhere. Is that correct, or am I missing something? Seems awfully restrictive, given how amazing some of the homebrews are. Either you all are wizards at squeezing great art into 16k or I'm missing something. Bank1_MainLoop ;'main game loop for gameplay frame=frame+1 rem ** restore background first restorescreen rem ** draw sprites if cur_bank=1 then gosub Bank1_DrawElements bank1 if cur_bank=2 then gosub Bank2_DrawElements bank2 if cur_bank=3 then gosub Bank3_DrawElements bank3 if cur_bank=4 then gosub Bank4_DrawElements bank4 rem ** now actually display the screen drawscreen .. code to change cur_bank here ... goto Bank1_MainLoop_Return /***********************************************/ bank 1 incgraphic gfx/tileset_wd_lvl1_alt.png 160A 0 1 2 3 incgraphic gfx/scoredigits_8_wide_centered.png incgraphic gfx/alphabet_wd.png 160A 0 2 1 3 rem ** up left down right incgraphic gfx/wiz_new_l.png incgraphic gfx/wiz_new_l2.png incgraphic gfx/wiz_new_r.png incgraphic gfx/wiz_new_r2.png ... bank 1 code here... /***********************************************/ bank 2 incgraphic gfx/tileset_wd_lvl1_alt.png 160A 0 1 2 3 incgraphic gfx/scoredigits_8_wide_centered.png incgraphic gfx/alphabet_wd.png 160A 0 2 1 3 incgraphic gfx/spider1.png incgraphic gfx/spider2.png incgraphic gfx/spider3.png incgraphic gfx/spider4.png ... bank 2 code here... /***********************************************/ bank 3 incgraphic gfx/tileset_wd_lvl1_alt.png 160A 0 1 2 3 incgraphic gfx/scoredigits_8_wide_centered.png incgraphic gfx/alphabet_wd.png 160A 0 2 1 3 incgraphic gfx/bat1.png incgraphic gfx/bat2.png incgraphic gfx/bat3.png incgraphic gfx/bat4.png ... bank 3 code here ... I'm thinking about how to best organize things before I get too deep so any advice appreciated. Quote Link to comment Share on other sites More sharing options...
+karri Posted March 12, 2022 Share Posted March 12, 2022 The best scenario is to only have the bytes you need for this level in memory. It does not matter if you need to duplicate some data between banks. Copying to RAM sounds like a bad choice. 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 12, 2022 Share Posted March 12, 2022 Yes, everybody runs across their personal "oh my god, I need to copy my sprites/routines/whatever between several ephemeral banks" moment when they first start using bankswitching. It's a natural part of it, and an expected consequence of the banks having to share limited address space. You want to organise your graphics in terms of common stuff going in the last bank, and graphics that change depending on game context (e.g. enemy graphics that change due to level progression) into those ephemeral banks. (with some duplication of things that don't change) You might also look at a 144k format, if you don't need cart ram, as that gives you another permanent bank. (asm folks can also stick the second-last bank at $4000, but for now 7800basic needs to use 144k to get a permanent bank at $4000.) 1 Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 12, 2022 Share Posted March 12, 2022 1 hour ago, RevEng said: You want to organise your graphics in terms of common stuff going in the last bank, and graphics that change depending on game context (e.g. enemy graphics that change due to level progression) into those ephemeral banks. (with some duplication of things that don't change) You might also look at a 144k format, if you don't need cart ram, as that gives you another permanent bank. (asm folks can also stick the second-last bank at $4000, but for now 7800basic needs to use 144k to get a permanent bank at $4000.) Ah, cool, so for all formants the last bank is always resident? Quote Link to comment Share on other sites More sharing options...
RevEng Posted March 12, 2022 Share Posted March 12, 2022 3 minutes ago, BydoEmpire said: Ah, cool, so for all formants the last bank is always resident? Correct 1 Quote Link to comment Share on other sites More sharing options...
+mksmith Posted March 15, 2022 Share Posted March 15, 2022 On 3/13/2022 at 6:46 AM, RevEng said: Yes, everybody runs across their personal "oh my god, I need to copy my sprites/routines/whatever between several ephemeral banks" moment when they first start using bankswitching. It's a natural part of it, and an expected consequence of the banks having to share limited address space. When Mike first explained this to me it seemed counterproductive but I've used it regularly since. In Millie & Molly due to the way I designed the levels, banks 2 & 3 contain essentially the same code - all it did was tag the method names with BankX and as I made changes I could copy/rename/paste into the other bank. Made it very simple to keep insync. 5 Quote Link to comment Share on other sites More sharing options...
+Muddyfunster Posted March 15, 2022 Share Posted March 15, 2022 51 minutes ago, mksmith said: When Mike first explained this to me it seemed counterproductive but I've used it regularly since. In Millie & Molly due to the way I designed the levels, banks 2 & 3 contain essentially the same code - all it did was tag the method names with BankX and as I made changes I could copy/rename/paste into the other bank. Made it very simple to keep insync. I used the exact same method for EXO after Mike and Matt's great advice. 4 Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 15, 2022 Share Posted March 15, 2022 (edited) It hasn't been too bad once I started from scratch. Trying to convert an existing game, which had a lot of hackery put in it squeeze it down to 48k, was messy. Now I know what I'm shooting for in each bank and can think about organization, adding (and testing) each piece at a time. Much easier. The advice on this thread is much appreciated, it got me going way faster than it would have been otherwise. Quote all it did was tag the method names with BankX and as I made changes I could copy/rename/paste into the other bank Hah, I did the exact same thing. Good to know it's a proven approach. Edited March 15, 2022 by BydoEmpire 4 Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 19, 2022 Share Posted March 19, 2022 (edited) How frequently can you realistically gosub to different banks while building the screen? I'm seeing the top row of tiles get cut off, but I'm jumping back and forth between bank 1 (the loop this is in), bank 2 & 3 (the level's tiles and sprites) and bank 16 (resident bank w/ default text, the hero character, etc). I'm trying to avoid as much duplicate code as possible but maybe that's the price you pay... clearscreen rem ** each level sets up the default room if cur_level <> 3 then gosub Bank2_InitRoom bank2 if cur_level = 3 then gosub Bank3_InitRoom bank3 ; for now, just two levels to test rem ** generically read the map and poke NSEW doors gosub Bank16_MakeDoors rem ** now draw room details if cur_level <> 3 then gosub Bank2_DrawRoomDetails bank2 if cur_level = 3 then gosub Bank3_DrawRoomDetails bank3 ; for now, just two levels to test rem ** draw any common room details (like text) gosub Bank16_DrawRoomDetails rem ** this way we don't setup the background over and over again. savescreen drawscreen Edited March 19, 2022 by BydoEmpire Quote Link to comment Share on other sites More sharing options...
BydoEmpire Posted March 19, 2022 Share Posted March 19, 2022 (edited) Hm, I think the bug is elsewhere (though perhaps related). I moved all the Bank16_* code into bank 2 and it still happens. I noticed when I move the hero character sprite around the top row of tiles gets cut off more, which I assume means it's not really related to building the screen (as in the above code)... I am wondering how valid it is to do this kind of thing, but I'll keep digging around. [edit] Wait a minute, if banks 1 and 16 are always resident, then it really shouldn't matter if I jump to at least one other bank in between... I think I answered my own question. Probably a bug elsewhere as I moved code around. Edited March 19, 2022 by BydoEmpire Quote Link to comment Share on other sites More sharing options...
Ecernosoft Posted May 22, 2022 Share Posted May 22, 2022 In a way, you can use the multiple banks to do continiuous animation. The more banks you have (Ex: 12 4K banks) the more freedom you have. For example, let's make a made up mapper where you get 11 4K banks at once. $4000-$5000 is RAM plus some controll variables. You can only "See" 11 4K banks but there could be 16 possible 4K banks for each 4K of ROM above $5000. So that would mean, 11*16*4 = 704 kilobytes of ROM, plus 4K of RAM, or maybe even SRAM. 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.