Jump to content
  • entries
    334
  • comments
    900
  • views
    258,315

advanced un-bankswitching idea


EricBall

492 views

One thing I find amazing about the 2600 homebrew scene is the strong interest in creating new bankswitching hardware, often with advanced capabilities. I think, very soon, the only remaining VCS limitations will be the capabilities of the TIA and that there are only 76 CPU cycles per line to update the TIA (hmm... shades of the GTIA/ANTIC).

 

Anyway, one idea which occurred to me is whether it would be possible for the cartridge to automatically bankswitch the 64K (32K usable) address space. Basically, the cartridge would snoop the address & data buses and pull the missing 3 address bits out of the data stream.

 

I've done some looking at the 6502 addressing modes and some intelligence & heuristics would be required. The cartridge would have to shadow the PC register so it can determine which data bytes are opcodes (for the correct addressing mode) and which are address MSBs. The tricky bit would be handling the extra fetch when indexed addressing goes over page boundaries and handling branches.

6 Comments


Recommended Comments

If one were willing to accept certain limitations, it would be entirely possible and not difficult using an extended FE scheme. As I understand, FE works by checking for accesses to $01FE and automatically switches to the bank indicated by D5, giving the feel of 8k of actual address space. Extending FE so it switches to the bank indicated by D5-D7 would give the feel of 32k. The main limitation, of course, is that one bank cannot access another bank's data.

Link to comment

My idea is for truely seamless bankswitching. So you would have eight 4K banks located at $1xxx, $3xxx etc. No hotspots to switch between banks, so not just JSR, but also JMP and the ability to load data stored in a different bank than the code.

 

Though I'd forgotten about FE's automated JSR/RTS bankswitching.

Link to comment

My idea is for truely seamless bankswitching. So you would have eight 4K banks located at $1xxx, $3xxx etc. No hotspots to switch between banks, so not just JSR, but also JMP and the ability to load data stored in a different bank than the code.

 

Though I'd forgotten about FE's automated JSR/RTS bankswitching.

I know what you were proposing, I just don't see how it could be done without error unless one put an actual 6502 chip or 6502 simulator on the cart itself, so it could run code in tandem and keep track of which bank to access when. I don't think heuristics would be adequate unless one could know the exact conditions under which they would fail.

Link to comment

Unless one is willing to emulate a 6502 well enough to track register contents, there's no way to tell with certainty what is represented by a series of memory fetches.

 

For example, imagine that one sees the sequence of memory fetches:

 10A2 - 69  (ADC#imm)
 10A3 - 04  (imm operand)
 10A4 - B0  (BCS)
 10A5 - 01  (address 3003)
 10A6 - AD (LDAabs or dummy fetch)
 10A7 - A9 (lsb of abs operand, or LDA#imm)
 10A8 - 50 (msb of abs operand, or imm operand)
 ?0A9 - ??

The only way of knowing whether that last address is really 10A9 or 50A9 would be to know whether the add operation produced a carry. And that would require an absurd amount of logic.

 

Further, even if bus snooping logic was perfect, one would still be restricted to using odd-numbered 4K banks ($1000, $3000, $5000, etc.) because of the 2600's internal hardware. Much nicer instead to design a banking scheme which is even more versatile than a flat address space. And that one's been done. ;)

Link to comment

Yeah, branches are a bugger to handle. But I think it still may be possible with heuristics. The first thing to realize is the 6502 always fetches the next address following an opcode. Thus, if the PC has incremented, then we can assume the previous data was the opcode.

 

Not taken:

1000 branch 
1001 offset
1002 opcode
1003 lsb

Taken :
1000 branch
1001 offset
1002 ignored
1010 opcode
1011 lsb

Taken over page :
10F0 branch
10F1 offset
10F2 ignored
1010 ignored
1110 opcode
1111 lsb

So the logic simply has to wait until the address bus starts incrementing, then take the previous data bus result and use it as the opcode. It also helps that during all those ignored reads A[13..15] remain the same.

 

Limitations:

1. Indexed addressing (i.e. ABS,X or (ZP),Y) over page boundaries won't work because it's impossible to predict whether the MSB comes from the code or data pointer.

2. Branches which skip the next 1 byte instruction since a taken branch would look the same as untaken (for the next two cycles at least). It might be possible to extend out the logic to handle everything but the 1 byte stack instructions. (And maybe those too since the MSB will be ignored anyway.)

 

The value of such an "un-bankswitching" is it would allow data in bank bank to be directly accessible by code running in any bank. 4A50 allows for read/modify/write to cartridge RAM, why not also do away with the 4K cartridge address space restriction as well?

 

 

Of course, talk & thoughts are cheap. But sometimes a "think" exercise can still produce things of value.

Link to comment
The value of such an "un-bankswitching" is it would allow data in bank bank to be directly accessible by code running in any bank. 4A50 allows for read/modify/write to cartridge RAM, why not also do away with the 4K cartridge address space restriction as well?

 

With 4A50, it's really easy for code in one bank to access data in any page of RAM, or any page in the second 64K of flash. Accessing two different pages of data within the code is a little harder, but there are a number of ways to do it and none of them are particularly hard. Indeed, in many cases 4A50 can provide faster RAM access than a linear address space. In many cases, it avoids the chunked-up address space that would be necessary even with a perfect address-snooping cart (under 4A50, one can easily access 32K of RAM by splitting each address into two parts (MSB and LSB) and the range of usable MSB's is continuous; under a linear addressing space, one would use MSB values of 16-31, 48-63, 80-95, etc. while skipping over the rest. Much more nuisancesome.

Link to comment
Guest
Add a comment...

×   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...