More space for scripts?

So I filled my bank 14 up really fast with custom code. I only have room to add maybe 5-10 lines before it causes a crash now.

I have seen the map of what is in what memory bank and I am curious.
Bank 18 is listed as an extra data bank, but it is currently unused.

Does anybody know how we might put some of our code into bank 18 so that there is more room for custom user code?
 
I would be willing to work on this problem myself. Not afraid of a bit of code experimentation. But I would like to know more about how banks work.

If I start adding things into bank 18, will the labels/subroutines be 'visible' if I call them from scripts that are in bank 14?

If not, can I store extra large scripts in bank 18.
Then while in a script that is stored in 14, bankswitch to 18, call the script, and then switch back to 14?
 
Ok, so by messing around I figured out how to store scripts in bank 18, however when I try to switch to bank 18 I just get a freeze.

Using this code:
Code:
    ;; Store X and Y
   	TXA
    	STA tempx
   	TYA
    	STA tempy
    
    ;; Switch the bank
	LDA currentBank
	STA prevBank
	LDY #$18
	JSR bankswitchY
	LDY tempy

	JSR enemySubroutine_testReset

   ;; Restore previous bank
	LDY prevBank
	JSR bankswitchY
    
    ;; Restore x and y
    	LDX tempx
	LDY tempy

I have an enemy action that calls this code.
The moment that the code runs, the player sprite and enemy sprites disappear (but not the background).
I cannot do anything else at that point besides close the game window.
 

Kasumi

New member
Imagine you have 31 drawbridges laid out parallel to each other. Unlike traditional drawbridges which slowly go up and down to alternate between allowing boats or cars to pass, your drawbridges disappear completely and instantly when "up", and reappear completely and instantly when down.

Now imagine you are holding the control for the bridges. Now imagine exactly one bridge can be down at a time. Now imagine you are standing on a bridge, and change which bridge is down. You fall and die, because you are not standing on the bridge that is about to reappear completely and instantly, and you are standing on a bridge that will disappear completely and instantly the second you press the button.

The drawbridges are banks. When you swap banks, you are making new information available yes, but in order to do this other information must become unavailable. When you say a new bridge should be down (swap in a new bank), the old bridge that is currently down disappears completely. If you happen to be standing on that bridge (running code in that bank) when you swap, you fall and die. (Usually! You don't necessarily die, but something you don't want to happen will probably happen.)

So, while you are in a script in bank $14, when you bankswitch to $18 you have already fallen and died full stop. There are ways to swap banks while you're in them, but it's usually something you don't want to do, and it requires very deep understanding of how bank switching works. Read this post/topic if you're curious about the theory: https://forums.nesdev.com/viewtopic.php?f=2&t=16781#p209452 But still, it's something you'd not do in a practical case if you can avoid it (and you can).

Since you can't swap banks while you're in the bank you're about to swap, you can do it two other ways.
1. I said to imagine 31 drawbridges, but there are really 32. And the last one is ALWAYS down (safe to walk on). That's bank $1F. So if you are in bank $14, and want to swap to bank $18. You jmp to code in bank $1F. Now you're not standing on drawbridge $14. So when you make it disappear and put drawbridge $18 down (swap in bank $18), you don't fall and die. You then jmp from bank $1F to bank $18 and do what you want to do there.
2. You put bankswitch code in RAM. RAM is also always there, and you can totally put code there. But that's also advanced.

Suppose you're in bank $18. And you call a NES Maker subroutine that does a bank swap. You fall and die when it returns. Suppose you're in bank $18, and you call a NES Maker subroutine that you read to check to make sure it doesn't do a bank swap. But it turns out, the subroutine calls a subroutine that does a bankswap. You fall and die when it returns. It can be very difficult to keep track of this even in code you wrote. You have to read everything you call, and everything that what you call calls, etc looking for bank swaps if you wanna make sure calling it is safe while you're standing on that bridge. It is the same for tempx, and tempy, and currentBank and prevBank if something that you call calls something that changes those values, and you are relying on what they were, you fall and die.

This is the reason bank $1F is prime real estate. It's always down. While you're there you'll never fall and die.
 

baardbi

Well-known member
Kasumi said:
Imagine you have 31 drawbridges laid out parallel to each other. Unlike traditional drawbridges which slowly go up and down to alternate between allowing boats or cars to pass, your drawbridges disappear completely and instantly when "up", and reappear completely and instantly when down.

Now imagine you are holding the control for the bridges. Now imagine exactly one bridge can be down at a time. Now imagine you are standing on a bridge, and change which bridge is down. You fall and die, because you are not standing on the bridge that is about to reappear completely and instantly, and you are standing on a bridge that will disappear completely and instantly the second you press the button.

The drawbridges are banks. When you swap banks, you are making new information available yes, but in order to do this other information must become unavailable. When you say a new bridge should be down (swap in a new bank), the old bridge that is currently down disappears completely. If you happen to be standing on that bridge (running code in that bank) when you swap, you fall and die. (Usually! You don't necessarily die, but something you don't want to happen will probably happen.)

So, while you are in a script in bank $14, when you bankswitch to $18 you have already fallen and died full stop. There are ways to swap banks while you're in them, but it's usually something you don't want to do, and it requires very deep understanding of how bank switching works. Read this post/topic if you're curious about the theory: https://forums.nesdev.com/viewtopic.php?f=2&t=16781#p209452 But still, it's something you'd not do in a practical case if you can avoid it (and you can).

Since you can't swap banks while you're in the bank you're about to swap, you can do it two other ways.
1. I said to imagine 31 drawbridges, but there are really 32. And the last one is ALWAYS down (safe to walk on). That's bank $1F. So if you are in bank $14, and want to swap to bank $18. You jmp to code in bank $1F. Now you're not standing on drawbridge $14. So when you make it disappear and put drawbridge $18 down (swap in bank $18), you don't fall and die. You then jmp from bank $1F to bank $18 and do what you want to do there.
2. You put bankswitch code in RAM. RAM is also always there, and you can totally put code there. But that's also advanced.

Suppose you're in bank $18. And you call a NES Maker subroutine that does a bank swap. You fall and die when it returns. Suppose you're in bank $18, and you call a NES Maker subroutine that you read to check to make sure it doesn't do a bank swap. But it turns out, the subroutine calls a subroutine that does a bankswap. You fall and die when it returns. It can be very difficult to keep track of this even in code you wrote. You have to read everything you call, and everything that what you call calls, etc looking for bank swaps if you wanna make sure calling it is safe while you're standing on that bridge. It is the same for tempx, and tempy, and currentBank and prevBank if something that you call calls something that changes those values, and you are relying on what they were, you fall and die.

This is the reason bank $1F is prime real estate. It's always down. While you're there you'll never fall and die.

This is a great explanation of the banks. Thanks a lot :)
 
Top Bottom