mirror of https://github.com/stella-emu/stella.git
Added 'EF' (Homestar Runner) bankswitch support as well as autodetection.
Improved 'UA' bankswitch format autodetection. Bumped version number. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1690 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
0e8571fc01
commit
b0eff89002
|
@ -12,6 +12,16 @@
|
|||
Release History
|
||||
===============================================================================
|
||||
|
||||
2.7.5 to XXXXX: (2009)
|
||||
|
||||
* Added support for 'EF' bankswitching (Paul Slocum Homestar Runner),
|
||||
as well as auto-detection of this format.
|
||||
|
||||
* Improved autodetection for 'UA' bankswitching format.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
2.7.3 to 2.7.5: (Mar. 27, 2009)
|
||||
|
||||
* After about 2 years, finally fixed the infamous 'red screen' issue when
|
||||
|
@ -35,8 +45,6 @@
|
|||
bytes when using this resolution. This should allow it to work
|
||||
better on devices with small displays.
|
||||
|
||||
-Have fun!
|
||||
|
||||
|
||||
2.7.2 to 2.7.3: (Feb. 9, 2009)
|
||||
|
||||
|
|
|
@ -2570,6 +2570,7 @@ Ms Pac-Man (Stella extended codes):
|
|||
<tr><td>DPC </td><td>Pitfall II </td></tr>
|
||||
<tr><td>E0 </td><td>8K Parker Bros </td></tr>
|
||||
<tr><td>E7 </td><td>16K M-network </td></tr>
|
||||
<tr><td>EF </td><td>64K Homestar Runner </td></tr>
|
||||
<tr><td>F4 </td><td>32K Atari </td></tr>
|
||||
<tr><td>F4SC </td><td>32K Atari + ram </td></tr>
|
||||
<tr><td>F6 </td><td>16K Atari </td></tr>
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: Version.hxx,v 1.54 2009-03-27 15:28:31 stephena Exp $
|
||||
// $Id: Version.hxx,v 1.55 2009-04-05 18:59:56 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef VERSION_HXX
|
||||
#define VERSION_HXX
|
||||
|
||||
#define STELLA_BASE_VERSION "2.7.5"
|
||||
#define STELLA_BASE_VERSION "2.7.6_cvs"
|
||||
|
||||
#ifdef NIGHTLY_BUILD
|
||||
#define STELLA_VERSION STELLA_BASE_VERSION "pre-" NIGHTLY_BUILD
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: Cart.cxx,v 1.48 2009-02-07 21:50:05 stephena Exp $
|
||||
// $Id: Cart.cxx,v 1.49 2009-04-05 18:59:56 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include "CartDPC.hxx"
|
||||
#include "CartE0.hxx"
|
||||
#include "CartE7.hxx"
|
||||
#include "CartEF.hxx"
|
||||
#include "CartF4.hxx"
|
||||
#include "CartF4SC.hxx"
|
||||
#include "CartF6.hxx"
|
||||
|
@ -108,6 +109,8 @@ Cartridge* Cartridge::create(const uInt8* image, uInt32 size,
|
|||
cartridge = new CartridgeE0(image);
|
||||
else if(type == "E7")
|
||||
cartridge = new CartridgeE7(image);
|
||||
else if(type == "EF")
|
||||
cartridge = new CartridgeEF(image);
|
||||
else if(type == "F4")
|
||||
cartridge = new CartridgeF4(image);
|
||||
else if(type == "F4SC")
|
||||
|
@ -265,6 +268,8 @@ string Cartridge::autodetectType(const uInt8* image, uInt32 size)
|
|||
type = "3F";
|
||||
else if(isProbably4A50(image, size))
|
||||
type = "4A50";
|
||||
else if(isProbablyEF(image, size))
|
||||
type = "EF";
|
||||
else
|
||||
type = "MB";
|
||||
}
|
||||
|
@ -408,13 +413,35 @@ bool Cartridge::isProbablyE7(const uInt8* image, uInt32 size)
|
|||
return false;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge::isProbablyEF(const uInt8* image, uInt32 size)
|
||||
{
|
||||
// EF cart bankswitching switches banks by accessing addresses 0xFE0
|
||||
// to 0xFEF, usually with either a NOP or LDA
|
||||
// It's likely that the code will switch to bank 0, so that's what is tested
|
||||
uInt8 signature[2][3] = {
|
||||
{ 0x0C, 0xE0, 0xFF }, // NOP $FFE0
|
||||
{ 0xAD, 0xE0, 0xFF } // LDA $FFE0
|
||||
};
|
||||
if(searchForBytes(image, size, signature[0], 3, 1))
|
||||
return true;
|
||||
else
|
||||
return searchForBytes(image, size, signature[1], 3, 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Cartridge::isProbablyUA(const uInt8* image, uInt32 size)
|
||||
{
|
||||
// UA cart bankswitching switches to bank 1 by accessing address 0x240
|
||||
// using 'STA $240'
|
||||
uInt8 signature[] = { 0x8D, 0x40, 0x02 }; // STA $240
|
||||
return searchForBytes(image, size, signature, 3, 1);
|
||||
// using 'STA $240' or 'LDA $240'
|
||||
uInt8 signature[2][3] = {
|
||||
{ 0x8D, 0x40, 0x02 }, // STA $240
|
||||
{ 0xAD, 0x40, 0x02 } // LDA $240
|
||||
};
|
||||
if(searchForBytes(image, size, signature[0], 3, 1))
|
||||
return true;
|
||||
else
|
||||
return searchForBytes(image, size, signature[1], 3, 1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: Cart.hxx,v 1.25 2009-01-01 18:13:35 stephena Exp $
|
||||
// $Id: Cart.hxx,v 1.26 2009-04-05 18:59:56 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef CARTRIDGE_HXX
|
||||
|
@ -34,7 +34,7 @@ class Settings;
|
|||
game and handles any bankswitching performed by the cartridge.
|
||||
|
||||
@author Bradford W. Mott
|
||||
@version $Id: Cart.hxx,v 1.25 2009-01-01 18:13:35 stephena Exp $
|
||||
@version $Id: Cart.hxx,v 1.26 2009-04-05 18:59:56 stephena Exp $
|
||||
*/
|
||||
class Cartridge : public Device
|
||||
{
|
||||
|
@ -197,6 +197,11 @@ class Cartridge : public Device
|
|||
*/
|
||||
static bool isProbablyE7(const uInt8* image, uInt32 size);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably a EF bankswitching cartridge
|
||||
*/
|
||||
static bool isProbablyEF(const uInt8* image, uInt32 size);
|
||||
|
||||
/**
|
||||
Returns true if the image is probably a UA bankswitching cartridge
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2009 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: CartEF.cxx,v 1.1 2009-04-05 18:59:56 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "System.hxx"
|
||||
#include "CartEF.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeEF::CartridgeEF(const uInt8* image)
|
||||
{
|
||||
// Copy the ROM image into my buffer
|
||||
memcpy(myImage, image, 65536);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CartridgeEF::~CartridgeEF()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEF::reset()
|
||||
{
|
||||
// Upon reset we switch to bank 1
|
||||
myCurrentBank = 1;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEF::install(System& system)
|
||||
{
|
||||
mySystem = &system;
|
||||
uInt16 shift = mySystem->pageShift();
|
||||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Make sure the system we're being installed in has a page size that'll work
|
||||
assert((0x1000 & mask) == 0);
|
||||
|
||||
// Set the page accessing methods for the hot spots
|
||||
System::PageAccess access;
|
||||
for(uInt32 i = (0x1FE0 & ~mask); i < 0x2000; i += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = 0;
|
||||
access.directPokeBase = 0;
|
||||
access.device = this;
|
||||
mySystem->setPageAccess(i >> shift, access);
|
||||
}
|
||||
|
||||
// Install pages for bank 1
|
||||
bank(1);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 CartridgeEF::peek(uInt16 address)
|
||||
{
|
||||
address = address & 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
if((address >= 0x0FE0) && (address <= 0x0FEF))
|
||||
bank(address - 0x0FE0);
|
||||
|
||||
return myImage[myCurrentBank * 4096 + address];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEF::poke(uInt16 address, uInt8)
|
||||
{
|
||||
// TODO - determine if writes will switch banks
|
||||
/*
|
||||
address = address & 0x0FFF;
|
||||
|
||||
// Switch banks if necessary
|
||||
if((address >= 0x0FE0) && (address <= 0x0FEF))
|
||||
bank(address - 0x0FE0);
|
||||
*/
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeEF::bank(uInt16 bank)
|
||||
{
|
||||
if(myBankLocked) return;
|
||||
|
||||
// Remember what bank we're in
|
||||
myCurrentBank = bank;
|
||||
uInt16 offset = myCurrentBank * 4096;
|
||||
uInt16 shift = mySystem->pageShift();
|
||||
uInt16 mask = mySystem->pageMask();
|
||||
|
||||
// Setup the page access methods for the current bank
|
||||
System::PageAccess access;
|
||||
access.device = this;
|
||||
access.directPokeBase = 0;
|
||||
|
||||
// Map ROM image into the system
|
||||
for(uInt32 address = 0x1000; address < (0x1FE0U & ~mask);
|
||||
address += (1 << shift))
|
||||
{
|
||||
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
|
||||
mySystem->setPageAccess(address >> shift, access);
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int CartridgeEF::bank()
|
||||
{
|
||||
return myCurrentBank;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
int CartridgeEF::bankCount()
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEF::patch(uInt16 address, uInt8 value)
|
||||
{
|
||||
address = address & 0x0FFF;
|
||||
myImage[myCurrentBank * 4096 + address] = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8* CartridgeEF::getImage(int& size)
|
||||
{
|
||||
size = 65536;
|
||||
return &myImage[0];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEF::save(Serializer& out) const
|
||||
{
|
||||
string cart = name();
|
||||
|
||||
try
|
||||
{
|
||||
out.putString(cart);
|
||||
|
||||
out.putInt(myCurrentBank);
|
||||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
cerr << msg << endl;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "Unknown error in save state for " << cart << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool CartridgeEF::load(Deserializer& in)
|
||||
{
|
||||
string cart = name();
|
||||
|
||||
try
|
||||
{
|
||||
if(in.getString() != cart)
|
||||
return false;
|
||||
|
||||
myCurrentBank = (uInt16) in.getInt();
|
||||
}
|
||||
catch(const char* msg)
|
||||
{
|
||||
cerr << msg << endl;
|
||||
return false;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
cerr << "Unknown error in load state for " << cart << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remember what bank we were in
|
||||
bank(myCurrentBank);
|
||||
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
//============================================================================
|
||||
//
|
||||
// SSSS tt lll lll
|
||||
// SS SS tt ll ll
|
||||
// SS tttttt eeee ll ll aaaa
|
||||
// SSSS tt ee ee ll ll aa
|
||||
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
|
||||
// SS SS tt ee ll ll aa aa
|
||||
// SSSS ttt eeeee llll llll aaaaa
|
||||
//
|
||||
// Copyright (c) 1995-2009 by Bradford W. Mott and the Stella team
|
||||
//
|
||||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: CartEF.hxx,v 1.1 2009-04-05 18:59:56 stephena Exp $
|
||||
//============================================================================
|
||||
|
||||
#ifndef CARTRIDGEEF_HXX
|
||||
#define CARTRIDGEEF_HXX
|
||||
|
||||
class System;
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Cart.hxx"
|
||||
|
||||
/**
|
||||
Cartridge class used for Homestar Runner by Paul Slocum.
|
||||
There are 16 4K banks (total of 64K ROM).
|
||||
Accessing $1FE0 - $1FEF switches to each bank.
|
||||
|
||||
This interpretation is based on analysis of the z26 assembly code,
|
||||
as this scheme doesn't seem to be documented anywhere.
|
||||
|
||||
@author Stephen Anthony
|
||||
@version $Id: CartEF.hxx,v 1.1 2009-04-05 18:59:56 stephena Exp $
|
||||
*/
|
||||
class CartridgeEF : public Cartridge
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new cartridge using the specified image
|
||||
|
||||
@param image Pointer to the ROM image
|
||||
*/
|
||||
CartridgeEF(const uInt8* image);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~CartridgeEF();
|
||||
|
||||
public:
|
||||
/**
|
||||
Reset device to its power-on state
|
||||
*/
|
||||
virtual void reset();
|
||||
|
||||
/**
|
||||
Install cartridge in the specified system. Invoked by the system
|
||||
when the cartridge is attached to it.
|
||||
|
||||
@param system The system the device should install itself in
|
||||
*/
|
||||
virtual void install(System& system);
|
||||
|
||||
/**
|
||||
Install pages for the specified bank in the system.
|
||||
|
||||
@param bank The bank that should be installed in the system
|
||||
*/
|
||||
virtual void bank(uInt16 bank);
|
||||
|
||||
/**
|
||||
Get the current bank.
|
||||
|
||||
@return The current bank, or -1 if bankswitching not supported
|
||||
*/
|
||||
virtual int bank();
|
||||
|
||||
/**
|
||||
Query the number of banks supported by the cartridge.
|
||||
*/
|
||||
virtual int bankCount();
|
||||
|
||||
/**
|
||||
Patch the cartridge ROM.
|
||||
|
||||
@param address The ROM address to patch
|
||||
@param value The value to place into the address
|
||||
@return Success or failure of the patch operation
|
||||
*/
|
||||
virtual bool patch(uInt16 address, uInt8 value);
|
||||
|
||||
/**
|
||||
Access the internal ROM image for this cartridge.
|
||||
|
||||
@param size Set to the size of the internal ROM image data
|
||||
@return A pointer to the internal ROM image data
|
||||
*/
|
||||
virtual uInt8* getImage(int& size);
|
||||
|
||||
/**
|
||||
Save the current state of this cart to the given Serializer.
|
||||
|
||||
@param out The Serializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
virtual bool save(Serializer& out) const;
|
||||
|
||||
/**
|
||||
Load the current state of this cart from the given Deserializer.
|
||||
|
||||
@param in The Deserializer object to use
|
||||
@return False on any errors, else true
|
||||
*/
|
||||
virtual bool load(Deserializer& in);
|
||||
|
||||
/**
|
||||
Get a descriptor for the device name (used in error checking).
|
||||
|
||||
@return The name of the object
|
||||
*/
|
||||
virtual string name() const { return "CartridgeEF"; }
|
||||
|
||||
public:
|
||||
/**
|
||||
Get the byte at the specified address.
|
||||
|
||||
@return The byte at the specified address
|
||||
*/
|
||||
virtual uInt8 peek(uInt16 address);
|
||||
|
||||
/**
|
||||
Change the byte at the specified address to the given value
|
||||
|
||||
@param address The address where the value should be stored
|
||||
@param value The value to be stored at the address
|
||||
*/
|
||||
virtual void poke(uInt16 address, uInt8 value);
|
||||
|
||||
private:
|
||||
// Indicates which bank is currently active
|
||||
uInt16 myCurrentBank;
|
||||
|
||||
// The 64K ROM image of the cartridge
|
||||
uInt8 myImage[65536];
|
||||
};
|
||||
|
||||
#endif
|
|
@ -21,6 +21,7 @@ MODULE_OBJS := \
|
|||
src/emucore/CartF8.o \
|
||||
src/emucore/CartF8SC.o \
|
||||
src/emucore/CartFASC.o \
|
||||
src/emucore/CartEF.o \
|
||||
src/emucore/CartFE.o \
|
||||
src/emucore/CartMB.o \
|
||||
src/emucore/CartMC.o \
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: GameInfoDialog.cxx,v 1.68 2009-03-19 15:03:50 stephena Exp $
|
||||
// $Id: GameInfoDialog.cxx,v 1.69 2009-04-05 18:59:56 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -145,6 +145,7 @@ GameInfoDialog::GameInfoDialog(
|
|||
items.push_back("DPC (Pitfall II)", "DPC" );
|
||||
items.push_back("E0 (8K Parker Bros)", "E0" );
|
||||
items.push_back("E7 (16K M-network)", "E7" );
|
||||
items.push_back("EF (64K Homestar Runner)", "EF" );
|
||||
items.push_back("F4 (32K Atari)", "F4" );
|
||||
items.push_back("F4SC (32K Atari + ram)", "F4SC" );
|
||||
items.push_back("F6 (16K Atari)", "F6" );
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
// See the file "license" for information on usage and redistribution of
|
||||
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
//
|
||||
// $Id: GlobalPropsDialog.cxx,v 1.4 2009-01-15 18:45:23 stephena Exp $
|
||||
// $Id: GlobalPropsDialog.cxx,v 1.5 2009-04-05 18:59:56 stephena Exp $
|
||||
//
|
||||
// Based on code from ScummVM - Scumm Interpreter
|
||||
// Copyright (C) 2002-2004 The ScummVM project
|
||||
|
@ -76,6 +76,7 @@ GlobalPropsDialog::
|
|||
items.push_back("DPC (Pitfall II)", "DPC" );
|
||||
items.push_back("E0 (8K Parker Bros)", "E0" );
|
||||
items.push_back("E7 (16K M-network)", "E7" );
|
||||
items.push_back("EF (64K Homestar Runner)", "EF" );
|
||||
items.push_back("F4 (32K Atari)", "F4" );
|
||||
items.push_back("F4SC (32K Atari + ram)", "F4SC" );
|
||||
items.push_back("F6 (16K Atari)", "F6" );
|
||||
|
|
Loading…
Reference in New Issue