Jump to content
IGNORED

2600 Bankswitch Conversions


Thomas Jentzsch

Recommended Posts

When I first looked at Thwocker, I think I must have been taking drugs when I thought it would be hard. I looked again tonight and it looked easy this time - so easy, I got something working in no time... Well, maybe, I don't know how to play so it's seen very little testing.

Thanks Fred, I've been waiting to play Thwocker on hardware for half a decade. :D I briefly played a round on the emulator, and it looks fine so far.

 

The game itself is playable and ranks high among my favorite prototypes. All you have to do is collect the notes in the order given to you and avoid anything else that moves.

http://www.atariprotos.com/2600/software/t...er/thwocker.htm

Edited by Zach
Link to comment
Share on other sites

I don't have any FE-format ROMs, but it should be pretty easy to use FE banking on an AA or CPUWiz cart. I'm not sure, though, which way the banking should switch in the following cases:

$01FE followed by $01FF
$01FF followed by $01FE
$01FE not followed by $01Fx
$01FF not followed by $01Fx

 

Does anyone know?

Link to comment
Share on other sites

I don't have any FE-format ROMs, but it should be pretty easy to use FE banking on an AA or CPUWiz cart. I'm not sure, though, which way the banking should switch in the following cases:

$01FE followed by $01FF
$01FF followed by $01FE
$01FE not followed by $01Fx
$01FF not followed by $01Fx

 

Does anyone know?

I thought FE worked by bus snooping the high byte of a return address during a stack access. Then you "pretend" that you have two ROMs at, say, $D000 and $F000, and D5 does the bank switch.

Link to comment
Share on other sites

I thought FE worked by bus snooping the high byte of a return address during a stack access. Then you "pretend" that you have two ROMs at, say, $D000 and $F000, and D5 does the bank switch.

 

Much simpler than that, from what I understand. Any top-level JSR will switch to bank 1. Any return to the top level will switch to bank 0. Unfortunately, I don't have any FE-format ROMs to play with, and there are some fun little wrinkles to contend with (e.g. where does the high byte of the JSR's destination address come from?)

Link to comment
Share on other sites

Much simpler than that, from what I understand. Any top-level JSR will switch to bank 1. Any return to the top level will switch to bank 0. Unfortunately, I don't have any FE-format ROMs to play with, and there are some fun little wrinkles to contend with (e.g. where does the high byte of the JSR's destination address come from?)

As I understand it, You jump to one bank by JSR $FXXX and you Jump to the other bank by JSR $DXXX.With RTS you just return to where you came from. So if you came from the D bank you return to the D bank and if you came from the F bank you return to the F bank. AFAIK, one of the two FE roms jumps both within the same bank and to the other bank.

where does the high byte of the JSR's destination address come from?

You need to monitor the databus to get it. Both during RTS and JSR the relevant data can be found on the databus. At least that is how I understood it during some longer discussions with Eckhard :)

Link to comment
Share on other sites

And for what it's worth, I think only Robot Tank and Decathlon used this. It's interesting, but not really worth creating any new games with. After all, even Activision didn't think it was worth the effort once they figured out 1FF8/1FF9.

 

So what was the first game to use 1FF8/1FF9 bankswitching?

Link to comment
Share on other sites

And for what it's worth, I think only Robot Tank and Decathlon used this. It's interesting, but not really worth creating any new games with. After all, even Activision didn't think it was worth the effort once they figured out 1FF8/1FF9.

 

So what was the first game to use 1FF8/1FF9 bankswitching?

 

Asteroids ?

Link to comment
Share on other sites

You need to monitor the databus to get it. Both during RTS and JSR the relevant data can be found on the databus. At least that is how I understood it during some longer discussions with Eckhard :)

 

I've never examined an FE-format ROM, so I'm not sure exactly what they do. If Thwocker is FE format, that would mean there are three of them.

 

My impression had been that an FF followed by FE would trigger banking one way and FE followed by FF would trigger it the other. If the main loop is considered the "upper bank", then FF/FE would trigger the lower bank and FE/EFF would trigger the upper. All JSR's from the main loop would go into the lower bank, and RTS to the upper.

 

Watching D5 would improve one's abilities a little bit, but if one is only watching for FF/FE all it would gain would be the ability to have the main loop to a JSR within the upper bank. Once the main loop has done a JSR, the bank would be stuck until the routine in question returned. All top-level returns should always go to the upper bank, since that's the only place from which a top-level JSR could have been performed.

 

The thing I'm most curious about with the FE format is how the bankswitch timing is handled. On a JSR or RTS to work "ideally" , it would seem the proper bank selection must be latched 419ns-838ns after the address $01FE leaves the bus, but must percolate through to the output 838ns-1.67us after that address left. It is thus necessary to have a significant delay between when the signal is latched and when it is output.

 

If there are some restrictions about originating and desgination addresses for JSR's, the timing might not be so bad. I'm curious, though, whether an FE format cart would be able to handle a "JSR $D002" instruction that was located at $F000, when address $D002 holds an LDAimm instruction. In that particular case, the cart would have some latitude over when it grabbed D6 (it would be valid almost immediately after the CPU output address $1002) but it would have to delay the bankswitch until after the CPU had completed its read operation. Note that the CPU would make two consecutive addresses to $1002, and the cart would have to judge the timing between them.

 

There are many things that could be done to simplify the timing. For example, if all JSR's had to be made from odd-numbered addresses to even-numbered ones, then A0 could be used to provide the necessary clocking. Having never looked at an FE-format ROM, though, I have no idea whether the code requires carts to handle the general case, or whether the code is designed to work around some cart limitations.

Link to comment
Share on other sites

You need to monitor the databus to get it. Both during RTS and JSR the relevant data can be found on the databus. At least that is how I understood it during some longer discussions with Eckhard :)

The thing I'm most curious about with the FE format is how the bankswitch timing is handled. On a JSR or RTS to work "ideally" , it would seem the proper bank selection must be latched 419ns-838ns after the address $01FE leaves the bus, but must percolate through to the output 838ns-1.67us after that address left. It is thus necessary to have a significant delay between when the signal is latched and when it is output.

I wonder if the timing requirement is the reason that FE carts don't work on the FB2 and some 7800's?

 

Regardless, I believe it's true about FE, based on what I recall from hacking Decathlon, that it allows one to think of the 2600 as sort of having 8k of program address space in two 4k chunks. Because of this, I think the FE format is ingenious. It's too bad it's not more common such that someone would design a board for it, as I think that programming for it would be easy and bankswitching would be painless and fast. No need to set up jump tables, align banks or do funky stack tricks to deal with differing entry points.

 

That said, the FE format could easily be expanded to 32k, in 8 chunks, if we monitor D5-D7 and switch based on the values therein. This would make management of 32k games so much easier. The timing may still be a big hurdle, but if it's true that one could fall within a relatively wide timing range, maybe an RC network could handle this even with low-tolerance parts.

Link to comment
Share on other sites

  • 1 year later...

Sorry to dredge up this old thread, but: batari did Robot Tank as F8 and The Activision Decathlon as F6 - this leaves only Thwocker as the remaining FE rom without a conversion. He mentioned that he had _something_ working. Any chance at a post of the final conversion?

 

ALSO: Does anyone know if the converted Activision Decathlon is built from the bugged or fixed version (i.e. can you get >5.6 on the Pole Vault?)

Edited by Hornpipe2
Link to comment
Share on other sites

Sorry to dredge up this old thread, but: batari did Robot Tank as F8 and The Activision Decathlon as F6 - this leaves only Thwocker as the remaining FE rom without a conversion. He mentioned that he had _something_ working. Any chance at a post of the final conversion?

 

ALSO: Does anyone know if the converted Activision Decathlon is built from the bugged or fixed version (i.e. can you get >5.6 on the Pole Vault?)

The Decathlon conversion would be built from the bugged version as I dumped the fixed version much later.

 

~Omega

Link to comment
Share on other sites

Sorry to dredge up this old thread, but: batari did Robot Tank as F8 and The Activision Decathlon as F6 - this leaves only Thwocker as the remaining FE rom without a conversion. He mentioned that he had _something_ working. Any chance at a post of the final conversion?

 

ALSO: Does anyone know if the converted Activision Decathlon is built from the bugged or fixed version (i.e. can you get >5.6 on the Pole Vault?)

The converted Thwocker and posted it in this thread, but now it's gone for some reason.

Link to comment
Share on other sites

Sorry to dredge up this old thread, but: batari did Robot Tank as F8 and The Activision Decathlon as F6 - this leaves only Thwocker as the remaining FE rom without a conversion. He mentioned that he had _something_ working. Any chance at a post of the final conversion?

 

Is it fully documented how exactly FE banking works--in particular, how the cart will behave when unpaired stack accesses occur?

Link to comment
Share on other sites

ALSO: Does anyone know if the converted Activision Decathlon is built from the bugged or fixed version (i.e. can you get >5.6 on the Pole Vault?)

The Decathlon conversion would be built from the bugged version as I dumped the fixed version much later.

Well in that case... here's the posted F6 version, modified to match the Fixed dump. In short a polevault bugfixed F6 Decathlon.

 

Try it, I'm curious how well it works.

 

EDIT: Just tried it in Stella, seems to work OK.

Decathlon_Fixed_F6.bin

Edited by Hornpipe2
Link to comment
Share on other sites

Is it fully documented how exactly FE banking works--in particular, how the cart will behave when unpaired stack accesses occur?

Here is my working VHDL for my version of FE which works with Decathalon and Robot Tank. It is formated to fit into my CPLD, but its pretty clear to see how I do it. A simple state machine that looks for A12 - A8 to be '00001' two cycles in a row. On the third cycle, it gets the correct bank from D5 and sets up a temporary register. On cycle four, it applies the change, puts it on the bus in my case.

 

I have never had a problem with it running either of the two games I mentioned. I have not tried Thwocker.

 

Hope this helps,

 

Vern

 

 

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity cart_fe is
 port(
   vcs_a : in  STD_LOGIC_VECTOR (12 downto 0);
   vcs_d_in : in  STD_LOGIC_VECTOR (7 downto 0);
   vcs_d_out : out  STD_LOGIC_VECTOR (7 downto 0);
   vcs_d_enable : out STD_LOGIC;
   vcs_a_clk : in  STD_LOGIC;
   vcs_z_clk : in  STD_LOGIC;
   vcs_d_clk : in  STD_LOGIC;

   cart_a : out  STD_LOGIC_VECTOR (16 downto 0);
   cart_d_in : in  STD_LOGIC_VECTOR (7 downto 0);
   cart_rw : out  STD_LOGIC;
   cart_rdy : out  STD_LOGIC;

   int : out STD_LOGIC;
   
   options : in std_logic_vector(1 downto 0);
   enable : in STD_LOGIC
 );
end entity cart_fe;


architecture Behavioral of cart_fe is

 constant FILL  : STD_LOGIC_VECTOR(3 downto 0) := "0000";

 constant BANK0 : STD_LOGIC := '0';
 constant BANK1 : STD_LOGIC := '1';

 signal bank_ptr : STD_LOGIC;
 signal temp_ptr : STD_LOGIC;

 type tstates is (IDLE, ONE, TWO, GET, PUT);
 
 signal cs : tstates;
 
begin

 process (vcs_a_clk)
 begin

   if (vcs_a_clk'event and vcs_a_clk = '1') then
     if (enable = '1') then

       case cs is
           when IDLE => if vcs_a = "00001--------" then
                           cs <= ONE; 
                             end if;
            when ONE => if vcs_a = "00001--------" then
                         cs <= TWO;
                           else
                             cs <= IDLE;
                           end if;          
            when TWO => cs <= GET;
            when GET => cs <= PUT;
            when PUT => cs <= IDLE;
         end case;

     else
         cs <= IDLE;
     end if;
   end if;
       
 end process;


 process (cs)
 begin
   if (enable = '1') then

     case cs is
        when GET =>
         if (vcs_d_clk'event and vcs_d_clk = '1') then
             temp_ptr <= not vcs_d_in(5);
         end if;
        when PUT => bank_ptr <= temp_ptr;
         when others => NULL;
      end case;
    
    else
      bank_ptr <= BANK0;
    end if;
 end process;


 vcs_d_out <= cart_d_in;
 vcs_d_enable <= vcs_a(12);

 cart_a <= FILL & bank_ptr & vcs_a(11 downto 0);
 cart_rw <= '0';
 cart_rdy <= not vcs_a_clk;

 int <= '0';

end Behavioral;

Link to comment
Share on other sites

  • 5 months later...
  • 15 years later...
On 5/18/2005 at 9:47 AM, batari said:

I've finally got Decathlon working as F6. This one was VERY hard, as it used FE bankswitching and switched dozens of times throughout the kernel. Therefore I had to rewrite and/or relocate much of the kernel to tweak the timing so that everything would work. I had to use dirty tricks to get this working such as relying on the value obtained with a LDA $1FFx and dummy fetches after an RTS, so I would appreciate a test of all events on real hardware.

 

Also, the game had graphics data at FFF0-FFFB, accessed with indirect indexing, which was actually quite hard to track down and fix.

 

I will do the PAL version only if the kernel is essentially the same, and I haven't checked for this yet.

Decathlon_F6.zip 6.8 kB · 186 downloads

Is the source code/disassembly for this conversion publicly available?

 

Link to comment
Share on other sites

12 hours ago, Al_Nafuur said:

Is the source code/disassembly for this conversion publicly available?

thwocker_f8.bin

 

No source, it was a binary hack.

 

I think I know who deleted it and I'm pretty sure reasons were because they thought that prototype carts might "lose value." I mean, the FE version is already out there, so it's not like you can't already play this game in many different ways.

 

It's been 18 years and much has changed since then so I'll just post it again. If any mods still don't want it here for some reason I guess they can delete it again.

  • Thanks 1
Link to comment
Share on other sites

On 2/5/2024 at 5:14 AM, Al_Nafuur said:

Is the source code/disassembly for this conversion publicly available?

 

Admittedly, I didn't actually read your reply, and I assumed you were referring to Thwocker, because there was concern that it wasn't available. But it looks like you were after Decathlon!

 

Decathlon was also a binary hack, so there was no source. Although I recall creating some notes that documented the changes, apparently these are long gone. On this one, if you want to figure out what I did, it would be best to compare the two binaries side-by-side.

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...