Atari - put descriptions at the top of each mapper file

This commit is contained in:
adelikat 2012-04-29 21:01:06 +00:00
parent fffe30f4f9
commit e0a6ae5264
14 changed files with 304 additions and 1 deletions

View File

@ -5,6 +5,25 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
This is another 8K bankswitching method with two 4K banks. The rationale is that it's
cheap and easy to implement with only a single 74HC153 or 253 dual 4:1 multiplexer.
This multiplexer can act as a 1 bit latch AND the inverter for A12.
To bankswitch, the following mask it used:
A13 A0
----------------
0 1xxx xBxx xxxx
Each bit corresponds to one of the 13 address lines. a 0 or 1 means that bit must be
0 or 1 to trigger the bankswitch. x is a bit that is not concidered (it can be either
0 or 1 and is thus a "don't care" bit).
B is the bank we will select. sooo, accessing 0800 will select bank 0, and 0840
will select bank 1.
*/
class m0840 : MapperBase
{

View File

@ -5,6 +5,24 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
3E (Boulderdash
-----
This works similar to 3F (Tigervision) above, except RAM has been added. The range of
addresses has been restricted, too. Only 3E and 3F can be written to now.
1000-17FF - this bank is selectable
1800-1FFF - this bank is the last 2K of the ROM
To select a particular 2K ROM bank, its number is poked into address 3F. Because there's
8 bits, there's enough for 256 2K banks, or a maximum of 512K of ROM.
Writing to 3E, however, is what's new. Writing here selects a 1K RAM bank into
1000-17FF. The example (Boulderdash) uses 16K of RAM, however there's theoretically
enough space for 256K of RAM. When RAM is selected, 1000-13FF is the read port while
1400-17FF is the write port.
*/
class m3E : MapperBase
{

View File

@ -5,6 +5,25 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
3F (Tigervision)
-----
Traditionally, this method was used on the Tigervision games. The ROMs were all 8K, and
there's two 2K pages in the 4K of address space. The upper bank is fixed to the last 2K
of the ROM.
The first 2K is selectable by writing to any location between 0000 and 003F. Yes, this
overlaps the TIA, but this is not a big deal. You simply use the mirrors of the TIA at
40-7F instead! To select a bank, the games write to 3Fh, because it's not implemented
on the TIA.
The homebrew community has decided that if 8K is good, more ROM is better! This mapper
can support up to 512K bytes of ROM just by implementing all 8 bits on the mapper
register, and this has been done... however I do not think 512K ROMs have been made just
yet.
*/
class m3F :MapperBase
{

View File

@ -5,6 +5,31 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
4A50 (no name)
-----
Upon review, I don't think this method is terribly workable on real
hardware. There's so many problems that I kinda gave up trying to
count them all. Seems that this is more of a "pony" method than something
actually usable. ("pony" referring to "I want this, and that, and that, and
a pony too!")
One major problem is that it specifies that memory can be read and written
to at the same address, but this is nearly impossible to detect on a 2600
cartridge. You'd almost have to try and figure out what opcodes are being
run, and what cycle it's on somehow, all just by watching address and
data bus state. Not very practical.
The other problem is just the sheer volume of things it is supposed to do.
There's just tons and tons of unnecessary things like attempting to detect
BIT instructions, handling page wraps and other silly things.
This all supposidly fit into a Xilinx XC9536XL but I am not sure how the
chip could handle the RAM issue above at all. It almost needs to see R/W
and M2 (clock) to be able to properly do most of the things it's doing.
*/
class m4A50 : MapperBase
{

View File

@ -5,6 +5,20 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
This was used by Commavid. It allowed for both ROM and RAM on the cartridge,
without using bankswitching. There's 2K of ROM and 1K of RAM.
2K of ROM is mapped at 1800-1FFF.
1K of RAM is mapped in at 1000-17FF.
The read port is at 1000-13FF.
The write port is at 1400-17FF.
Example games:
Magicard
*/
class mCV: MapperBase
{
ByteBuffer aux_ram = new ByteBuffer(1024);

View File

@ -5,6 +5,27 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
E0 (Parker Bros)
-----
Parker Brothers used this, and it was used on one other game (Tooth Protectors). It
uses 8K of ROM and can map 1K sections of it.
This mapper has 4 1K banks of ROM in the address space. The address space is broken up
into the following locations:
1000-13FF : To select a 1K ROM bank here, access 1FE0-1FE7 (1FE0 = select first 1K, etc)
1400-17FF : To select a 1K ROM bank, access 1FE8-1FEF
1800-1BFF : To select a 1K ROM bank, access 1FF0-1FF7
1C00-1FFF : This is fixed to the last 1K ROM bank of the 8K
Like F8, F6, etc. accessing one of the locations indicated will perform the switch.
Example Games:
Frogger II - Threedeep! (1983) (Parker Bros)
*/
class mE0 : MapperBase
{
int toggle1 = 0;

View File

@ -5,6 +5,16 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
EF (no name?)
-----
This is a fairly simple method that allows for up to 64K of ROM, using 16 4K banks.
It works similar to F8, F6, etc. Only the addresses to perform the switch is
1FE0-1FEF. Accessing one of these will select the desired bank. 1FE0 = bank 0,
1FE1 = bank 1, etc.
*/
class mEF : MapperBase
{

View File

@ -6,7 +6,7 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
* F0 (Megaboy)
F0 (Megaboy)
-----
This was used on one game, "megaboy".. Some kind of educational cartridge. It supports

View File

@ -5,6 +5,14 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
F4 (Atari style 32K)
-----
Again, this works like F8 and F6 except now there's 8 4K banks. Selection is performed
by accessing 1FF4 through 1FFB.
*/
class mF4 :MapperBase
{
int toggle = 0;

View File

@ -5,6 +5,15 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
F6 (Atari style 16K)
-----
This is a fairly standard 16K bankswitching method. It works like F8, except there's
four 4K banks of ROM, selected by accessing 1FF6 through 1FF9. These sequentially
select one of the 4 banks. i.e. 1FF6 selects bank 0, 1FF7 selects bank 1, etc.
*/
class mF6 : MapperBase
{
int toggle = 0;

View File

@ -8,6 +8,23 @@ namespace BizHawk
{
partial class Atari2600
{
/*
F8 (Atari style 8K)
-----
This is the fairly standard way 8K of cartridge ROM was implemented. There are two
4K ROM banks, which get mapped into the 4K of cartridge space. Accessing 1FF8 or
1FF9 selects one of the two 4K banks. When one of these two addresses are accessed,
the banks switch spontaniously.
ANY kind of access will trigger the switching- reading or writing. Usually games use
LDA or BIT on 1FF8/1FF9 to perform the switch.
When the switch occurs, the entire 4K ROM bank switches, including the code that is
reading the 1FF8/1FF9 location. Usually, games put a small stub of code in BOTH banks
so when the switch occurs, the code won't crash.
*/
class mF8 : MapperBase
{
int toggle = 0;

View File

@ -5,6 +5,61 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
FE (Activision special)
-----
Activision used this method on only three games: Decathlon, Robot Tank, and the
prototype Thwocker. This mapper is one of the more interesting ones in that it uses
stack access to select banks. It is composed of two 4K banks, similar to F8.
Unlike F8, however, switching occurs when the stack is accessed.
This mapper allows for "automatic" bankswitching to occur, using JSR and RTS. The
addresses for all JSRs and RTS' are either Fxxx or Dxxx, and the mapper uses this to
figure out which bank it should be going to.
The cycles of a JSR are as such:
1: opcode fetch
2: fetch low byte of address
3: read 100,s : garbage fetch
4: write 100,s : PCH, decrement S
5: write 100,s : PCL, decrement S
6: fetch high byte of address
The cycles of an RTS are as such:
1: opcode fetch
2: fetch next opcode (and throw it away)
3: read 100,S : increment S
4: read 100,S : pull PCL from stack, increment S
5: read 100,S : pull PCH from stack
The chip can determine what instruction is being executed by watching the data and
address bus.
It watches for 20 (JSR) and 60 (RTS), and accesses to 100-1ff:
(opcode cycles)
20 (opcode)
add low (new add low)
stack (garbage read)
stack (push PCH)
stack (push PCL)
add high (new add hi) : latch D5. This is the NEW bank we need to be in.
60 (opcode)
xx (garbage fetch)
stack
stack (pull PCL)
stack (pull PCH) : latch D5. This is the NEW bank we need to be in.
Using emulators or similar there is a large cheat that can be used. A13 can be used
to simply select which 8K bank to be in.
*/
class mFE : MapperBase
{

View File

@ -5,6 +5,63 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
MC (Megacart)
-----
This is the mapper for the "Chris Wilkson's Megacart".
Only four addresses are used to bankswitch on this one.
Up to 128K of ROM and 64K of RAM can be accessed.
1000-13FF is selected by address 3C
1400-17FF is selected by address 3D
1800-1BFF is selected by address 3E
1C00-1FFF is selected by address 3F
The value written determines what will be selected:
00-7F written will select one of the 128 1K ROM banks
80-FF written will select one of the 128 512 byte RAM banks
When a RAM bank is selected, the lower 512 bytes is the write port, while
the upper 512 bytes is the read port.
On accessing address FFFC or FFFD, the last 1K bank points to the last bank in ROM,
to allow for system initialization. Jumping out of the last bank disables this.
It's debatable how easy this system would be to implement on a real system.
Detecting when to disable the last bank fixing is difficult. The documentation
says:
"
Megacart Specification, Rev1.1
(c) 1997 Chris Wilkson
cwilkson@mit.edu
Because the console's memory is randomized at powerup, there is no way to
predict the data initially contained in the "hot addresses". Therefore,
hardware will force slot 3 to always point to ROM block $FF immediately
after any read or write to the RESET vector at $FFFC-$FFFD. Block $FF
must contain code to initialize the 4 memory slots to point to the desired
physical memory blocks before any other code can be executed. After program
execution jumps out of the boot code, the hardware will release slot 3 and
it will function just like any other slot.
"
Unfortunately, there's not an easy way to detect this. Just watching the address
bus won't work easily: Writing anywhere outside the bank 1C00-1FFF (i.e. bank
registers, RAM, TIA registers) will cause the switching to revert bank 3, crashing
the system.
The only way I can see it working is to disregard any access to addresses 3C-3F.
Emulators have it easier: they can simply watch the program counter, vs. the
address bus. An actual system doesn't have that luxury, unfortunately, so it must
disregard accesses to 3C-3F instead.
*/
class mMC : MapperBase
{

View File

@ -5,6 +5,37 @@ using System.Text;
namespace BizHawk.Emulation.Consoles.Atari._2600
{
/*
X07 (Atariage)
-----
Apparently, this was only used on one cart: Stella's Stocking.
Similar to EF, there are 16 4K banks, for a total of up to 64K of ROM.
The addresses to select banks is below the ROM area, however.
The following TWO masks are used:
A13 A0
----------------
0 1xxx nnnn 1101
This means the address 80B selects bank 0, 81B selects bank 1, etc.
In addition to this, there is another way:
A13 A0
----------------
0 0xxx 0nxx xxxx
This is somewhat special purpose: Accessing here does nothing, unless one of the
last two banks are selected (banks 14 or 15). In that case, the new bank is:
111n i.e. accessing 0000 will select bank 14 (Eh, 1110b) while accessing 0040
will select bank 15 (Fh, 1111b). This allows for bankswitching by accessing
TIA registers at 00-3F or 40-7F without incurring any overhead.
*/
class mX07 : MapperBase
{