Jump to content

Photo

Bankswitching


5 replies to this topic

#1 cvga OFFLINE  

cvga

    River Patroller

  • 3,132 posts
  • Location:Sector 36

Posted Wed Jan 30, 2008 3:24 PM

OK, I've been working on an application and I'm pleased with how it's coming along. However, I only have 99 bytes of ROM space left but a few features yet to implement. I know there's a couple of places where I can go back and tweak my code but I won't be able to do that to the point that would be needed to incorporate everything. Variable-wise, I'm fine (I'm using about 16 of the 26 available variables) so I'm thinking that I'll need to bankswitch. There's not too much written about this in the batari Basic manual. I know I need to include the command...

set romsize 8k

Any advice on what else I should be aware of to help ensure my program runs smoothly?

#2 cvga OFFLINE  

cvga

    River Patroller

  • Topic Starter
  • 3,132 posts
  • Location:Sector 36

Posted Wed Jan 30, 2008 7:13 PM

I've added the bank 2 statement and tried to compile but I get a "Branch out of range (-216 bytes) error.

Suggestions?

#3 Fort Apocalypse OFFLINE  

Fort Apocalypse

    Stargunner

  • 1,593 posts

Posted Wed Jan 30, 2008 7:14 PM

Look at http://www.randomter...c-commands.html
if you haven't already. You can use 8k without having to do anything else though, maybe. Include/inline may need different placement (I forget). I should probably shut up. Not much experience with it > 4k yet.

#4 cvga OFFLINE  

cvga

    River Patroller

  • Topic Starter
  • 3,132 posts
  • Location:Sector 36

Posted Wed Jan 30, 2008 8:09 PM

Look at http://www.randomter...c-commands.html
if you haven't already. You can use 8k without having to do anything else though, maybe. Include/inline may need different placement (I forget). I should probably shut up. Not much experience with it > 4k yet.


I've been using the manual on randomterrain extensively along with the search function on AtariAge. I also thought that I could go 8k without too much trouble. I originally put the "set romsize 8k" statement near the top of my program and thought that bB might free up enough space by automatically moving the graphics and kernal to bank 2. That didn't compile (different branch error) so I defined bank 2 and made sure that my gosubs referred to bank2 when appropriate. Now I get a different compiling error.

Looking back through my code, I noticed that I am defining player0 near the top of my program in bank 1 (which isn't named). I'm thinking maybe the program is looking for a player0 defined in bank 2 and not comiling since it isn't there. I'll be testing that theory in a bit.

#5 cvga OFFLINE  

cvga

    River Patroller

  • Topic Starter
  • 3,132 posts
  • Location:Sector 36

Posted Wed Jan 30, 2008 9:01 PM

Got it working! Along with moving my player0 to bank2, I needed to include a statement that turns smartbranching on.

Thanks me!

#6 SeaGtGruff OFFLINE  

SeaGtGruff

    Quadrunner

  • 5,359 posts
  • Location:Georgia, USA

Posted Wed Jan 30, 2008 10:25 PM

batari Basic can compile Atari 2600 game ROMs that use the following cartridge types:

- 2K non-bankswitched
- 4K non-bankswitched
- 8K bankswitched (using either the "F8" or "F8SC" methods)
- 16K bankswitched (using either the "F6" or "F6SC" methods)
- 32K bankswitched (using either the "F4" or "F4SC" methods)

You use the "set romsize" statement to tell batari Basic which of these ROM types you want your game to use:

- "set romsize 2k"
- "set romsize 4k"
- "set romsize 8k"
- "set romsize 8kSC"
- "set romsize 16k"
- "set romsize 16kSC
- "set romsize 32k"
- "set romsize 32kSC"

The bankswitched ROM types that batari Basic supports all use banks that are 4K in size, so you can determine the number of banks by dividing the total ROM size by 4K:

- 2K ROM = half of a bank
- 4K ROM = 1 bank
- 8K ROM = 2 banks
- 16K ROM = 4 banks
- 32K ROM = 8 banks

To code a batari Basic game that's 8K or larger, you must declare the point in your program where each *additional* bank begins. In other words, you do *not* need to declare where bank 1 begins. You use the "bank" statement to declare the beginning of a new bank:

- "bank 2"
- "bank 3"
- "bank 4"
- "bank 5"
- "bank 6"
- "bank 7"
- "bank 8"

Note that you *must* put a space between the "bank" keyword and the number of the bank when declaring a new bank.

You can put code in any of the available banks (as determined by the chosen ROM size), but your program will *not* flow from one bank to the next automatically. Instead, you must jump from one bank to another by using a "goto" or "gosub" statement, and you must tell batari Basic which bank you're jumping to:

- "goto routine_name bank1"
- "goto routine_name bank2"
- "goto routine_name bank3"
- "goto routine_name bank4"
- "goto routine_name bank5"
- "goto routine_name bank6"
- "goto routine_name bank7"
- "goto routine_name bank8"

- "gosub subroutine_name bank1"
- "gosub subroutine_name bank2"
- "gosub subroutine_name bank3"
- "gosub subroutine_name bank4"
- "gosub subroutine_name bank5"
- "gosub subroutine_name bank6"
- "gosub subroutine_name bank7"
- "gosub subroutine_name bank8"

Note that when you're specifying the target bank in this fashion, you must *not* put a space between the "bank" keyword and the number of the bank.

Also, note that you do *not* need to specify the target bank if you're jumping to a routine or subroutine that's in the same bank where you already are:

- "goto routine_name"
- "gosub subroutine_name"

In fact, it takes extra ROM and extra machine cycles to jump to a routine or subroutine that's in a different bank, so you should *never* include the target bank when you're already in that bank (or you'll just waste ROM and cycles)-- and in general, you should try to organize your code so you keep the number of bank jumps to a minimum (to avoid adding any more ROM or cycles to your code than is absolutely necessary).

When you jump to a subroutine in a bankswitched game, there are three types of "return" statements that you can use to go back to where you came from once the subroutine is finished:

- "return"
- "return thisbank"
- "return otherbank"

The "return" and "return otherbank" statements will *always* work, regardless of whether you're returning to the same bank or to a different bank. On the other hand, the "return thisbank" will crash your program if you try to use it to return to a different bank.

Each of these three types of "return" statements can take a different amount of ROM or number of cycles to execute, and each one works best (as far as the number of cycles used) within a specific situation:

+-----------------+------------+-----------------+------------------+
|				 |   return   | return thisbank | return otherbank |
+-----------------+------------+-----------------+------------------+
| gosub		   |  25 cycles |	12 cycles	|	 57 cycles	|
+-----------------+------------+-----------------+------------------+
| gosub thisbank  |  78 cycles |	65 cycles	|	110 cycles	|
+-----------------+------------+-----------------+------------------+
| gosub otherbank | 122 cycles | CRASH THE 2600  |	110 cycles	|
+-----------------+------------+-----------------+------------------+
In the table shown above, note that "gosub thisbank" and "gosub otherbank" are *not* the proper command formats, but refer to use of the "gosub subroutine_name bank#" format, depending on whether you're jumping to a subroutine that's in the same bank ("thisbank") or in a different bank ("otherbank"). For example, if you use "gosub process_joystick0 bank2," and you are *already* in bank 2, then it would be a "gosub thisbank" situation; but if you are in a *different* bank, then it would be a "gosub otherbank" situation. Keep in mind that the "gosub thisbank" format should be avoided anyway, because it justs wastes ROM and cycles to specify the target bank when you're already in that bank. The only reason I included it in the table was for the sake of completeness.

Also, note that the number of cycles shown in the table refer to the "overhead," meaning they do *not* include any of the cycles that must be spent performing the actual subroutine, just the number of cycles needed to *jump* to the subroutine and then *return* from it.

From the preceding table, you can see that you want to use "gosub ... return thisbank" as much as possible, because it will take up the smallest number of cycles (as well as the smallest amount of ROM).

However, if you have a subroutine that you're calling from a number of different banks in your program, then you should use "gosub ... return" when calling it from within the *same* bank, or "gosub otherbank ... return" when calling it from within a *different* bank.

Finally, if you have a subroutine that you'll *always* be calling from within a *different* bank, then you should use "gosub otherbank ... return otherbank."

By the way, if you use "goto routine_name" or "gosub subroutine_name" (i.e., *without* specifying the target bank), and you are *not* already in the bank where the routine or subroutine is located, you will crash your program.

When using bankswitching, keep in mind that batari Basic will be switching the entire 4K cartridge area to a new bank when you jump from bank to bank, so that means any ROM data tables which you've stored in a particular bank will *not* be accessible to any routines or subroutines which are located in *other* banks.

As far as "upgrading" a 4K game to a bankswitched game, you should also keep in mind that a certain amount of ROM must be set aside in each bank for bankswitching logic. That means if you're working on a 4K game that has only a few bytes of ROM free, and you decide to move it up to an 8K game, then you will probably *not* be able to start out by putting all of your existing code in bank 2, since you may run out of ROM in bank 2 right off the bat!

Besides, a bankswitched batari Basic program will automatically start up in bank 1, and will begin executing any code that's at the very beginning of bank 1. If for some reason you want the start of your program to be in bank 2 (or bank 3, etc.), then you'll need to put a "goto routine_name bank2" statement at the beginning of bank 1, to tell the Atari to immediately jump to bank 2 as soon as your program begins.

Also, batari Basic will always put its own "system routines"-- including its builtin display kernel-- in the last bank, so that means you'll always have less ROM space for your own stuff in the last bank. Additionally, batari Basic needs to store most of the graphics data in the last bank, so it can access the graphics data while executing its display kernel. Even if you put your "player0:" or "player1:" graphics statements in one of the other banks, the actual graphics data will be stored in the last bank anyway.

Michael

Edited by SeaGtGruff, Wed Jan 30, 2008 10:27 PM.





0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users