First real pass at 4A50 support. It still doesn't compile yet, and may

not even work when it does :)


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1393 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2008-01-24 20:43:41 +00:00
parent 5da06ccdca
commit 34665d7f40
3 changed files with 177 additions and 154 deletions

View File

@ -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: Cart4A50.cxx,v 1.6 2007-10-09 23:56:57 stephena Exp $
// $Id: Cart4A50.cxx,v 1.7 2008-01-24 20:43:41 stephena Exp $
//============================================================================
#include <cassert>
@ -47,178 +47,212 @@ Cartridge4A50::~Cartridge4A50()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::reset()
{
/*
// Setup segments to some default slices
segmentZero(4);
segmentOne(5);
segmentTwo(6);
*/
mySliceLow = mySliceMiddle = mySliceHigh = 0;
myIsRomLow = myIsRomMiddle = myIsRomHigh = true;
myLastData = 0xff;
myLastAddress = 0xffff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::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) && ((0x1400 & mask) == 0) &&
((0x1800 & mask) == 0) && ((0x1C00 & mask) == 0));
assert((0x1000 & mask) == 0);
// Set the page acessing methods for the first part of the last segment
// Map all of the accesses to call peek and poke
System::PageAccess access;
access.directPokeBase = 0;
access.device = this;
for(uInt32 i = 0x1C00; i < (0x1FE0U & ~mask); i += (1 << shift))
for(uInt32 i = 0x1000; i < 0x2000; i += (1 << shift))
{
access.directPeekBase = &myImage[7168 + (i & 0x03FF)];
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
mySystem->setPageAccess(i >> shift, access);
}
myCurrentSlice[3] = 7;
// Set the page accessing methods for the hot spots in the last segment
access.directPeekBase = 0;
access.directPokeBase = 0;
access.device = this;
for(uInt32 j = (0x1FE0 & ~mask); j < 0x2000; j += (1 << shift))
{
mySystem->setPageAccess(j >> shift, access);
}
// Install some default slices for the other segments
segmentZero(4);
segmentOne(5);
segmentTwo(6);
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Cartridge4A50::peek(uInt16 address)
{
/*
address = address & 0x0FFF;
uInt8 value = 0;
if(!bankLocked) {
// Switch banks if necessary
if((address >= 0x0FE0) && (address <= 0x0FE7))
if(!(address & 0x1000))
{
// ReadHardware();
bank(address);
}
else
{
if((address & 0x1800) == 0x1000)
{
segmentZero(address & 0x0007);
value = myIsRomLow ?
myImage[(address & 0x7ff) + mySliceLow] :
myRAM[(address & 0x7ff) + mySliceLow];
}
else if((address >= 0x0FE8) && (address <= 0x0FEF))
else if(((address & 0x1fff) >= 0x1800) && ((address & 0x1fff) <= 0x1dff))
{
segmentOne(address & 0x0007);
value = myIsRomMiddle ?
myImage[(address & 0x7ff) + mySliceMiddle] :
myRAM[(address & 0x7ff) + mySliceMiddle];
}
else if((address >= 0x0FF0) && (address <= 0x0FF7))
else if((address & 0x1f00) == 0x1e00)
{
segmentTwo(address & 0x0007);
value = myIsRomHigh ?
myImage[(address & 0xff) + mySliceHigh] :
myRAM[(address & 0xff) + mySliceHigh];
}
else if((address & 0x1f00) == 0x1f00)
{
value = myImage[(address & 0xff) + 0xff00];
if(((myLastData & 0xe0) == 0x60) &&
((myLastAddress >= 0x1000) || (myLastAddress < 0x200)))
mySliceHigh = (mySliceHigh & 0xf0ff) | ((address & 0x8) << 8) |
((address & 0x70) << 4);
}
}
myLastData = value;
myLastAddress = address & 0x1fff;
return myImage[(myCurrentSlice[address >> 10] << 10) + (address & 0x03FF)];
*/
return 0;
return value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::poke(uInt16, uInt8)
void Cartridge4A50::poke(uInt16 address, uInt8 value)
{
/*
address = address & 0x0FFF;
if(!bankLocked) {
// Switch banks if necessary
if((address >= 0x0FE0) && (address <= 0x0FE7))
if(!(address & 0x1000))
{
// WriteHardware();
bank(address);
}
else
{
if((address & 0x1800) == 0x1000)
{
segmentZero(address & 0x0007);
if(!myIsRomLow)
myRAM[(address & 0x7ff) + mySliceLow] = value;
}
else if((address >= 0x0FE8) && (address <= 0x0FEF))
else if(((address & 0x1fff) >= 0x1800) && ((address & 0x1fff) <= 0x1dff))
{
segmentOne(address & 0x0007);
if(!myIsRomMiddle)
myRAM[(address & 0x7ff) + mySliceMiddle] = value;
}
else if((address >= 0x0FF0) && (address <= 0x0FF7))
else if((address & 0x1f00) == 0x1e00)
{
segmentTwo(address & 0x0007);
if(!myIsRomHigh)
myRAM[(address & 0xff) + mySliceHigh] = value;
}
else if((address & 0x1f00) == 0x1f00)
{
if(((myLastData & 0xe0) == 0x60) &&
((myLastAddress >= 0x1000) || (myLastAddress < 0x200)))
mySliceHigh = (mySliceHigh & 0xf0ff) | ((address & 0x8) << 8) | ((address & 0x70) << 4);
}
}
*/
myLastData = value;
myLastAddress = address & 0x1fff;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::segmentZero(uInt16 slice)
{
/*
// Remember the new slice
myCurrentSlice[0] = slice;
uInt16 offset = slice << 10;
uInt16 shift = mySystem->pageShift();
// Setup the page access methods for the current bank
System::PageAccess access;
access.device = this;
access.directPokeBase = 0;
for(uInt32 address = 0x1000; address < 0x1400; address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::segmentOne(uInt16 slice)
{
/*
// Remember the new slice
myCurrentSlice[1] = slice;
uInt16 offset = slice << 10;
uInt16 shift = mySystem->pageShift();
// Setup the page access methods for the current bank
System::PageAccess access;
access.device = this;
access.directPokeBase = 0;
for(uInt32 address = 0x1400; address < 0x1800; address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::segmentTwo(uInt16 slice)
{
/*
// Remember the new slice
myCurrentSlice[2] = slice;
uInt16 offset = slice << 10;
uInt16 shift = mySystem->pageShift();
// Setup the page access methods for the current bank
System::PageAccess access;
access.device = this;
access.directPokeBase = 0;
for(uInt32 address = 0x1800; address < 0x1C00; address += (1 << shift))
{
access.directPeekBase = &myImage[offset + (address & 0x03FF)];
mySystem->setPageAccess(address >> shift, access);
}
*/
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Cartridge4A50::bank(uInt16 b)
void Cartridge4A50::bank(uInt16 address)
{
// Not bankswitching in the normal sense
// This scheme contains so many hotspots that it's easier to just check
// all of them
if(((myLastData & 0xe0) == 0x60) &&
((myLastAddress >= 0x1000) || (myLastAddress < 0x200)))
{
if((address & 0x0f00) == 0x0c00)
{
myIsRomHigh = true;
mySliceHigh = (address & 0xff) << 8;
}
else if((address & 0x0f00) == 0x0d00)
{
myIsRomHigh = false;
mySliceHigh = (address & 0x7f) << 8;
}
else if((address & 0x0f40) == 0x0e00)
{
myIsRomLow = true;
mySliceLow = (address & 0x1f) << 11;
}
else if((address & 0x0f40) == 0x0e40)
{
myIsRomLow = false;
mySliceLow = (address & 0xf) << 11;
}
else if((address & 0x0f40) == 0x0f00)
{
myIsRomMiddle = true;
mySliceMiddle = (address & 0x1f) << 11;
}
else if((address & 0x0f50) == 0x0f40)
{
myIsRomMiddle = false;
mySliceMiddle = (address & 0xf) << 11;
}
else if((address & 0x0f00) == 0x0400)
{
mySliceLow = mySliceLow ^ 0x800;
}
else if((address & 0x0f00) == 0x0500)
{
mySliceLow = mySliceLow ^ 0x1000;
}
else if((address & 0x0f00) == 0x0800)
{
mySliceMiddle = mySliceMiddle ^ 0x800;
}
else if((address & 0x0f00) == 0x0900)
{
mySliceMiddle = mySliceMiddle ^ 0x1000;
}
}
if((address & 0xf75) == 0x74)
{
myIsRomHigh = true;
mySliceHigh = value << 8;
}
else if((address & 0xf75) == 0x75)
{
myIsRomHigh = false;
mySliceHigh = (value & 0x7f) << 8;
}
else if((address & 0xf7c) == 0x78)
{
if((value & 0xf0) == 0)
{
myIsRomLow = true;
mySliceLow = (value & 0xf) << 11;
}
else if((value & 0xf0) == 0x40)
{
myIsRomLow = false;
mySliceLow = (value & 0xf) << 11;
}
else if((value & 0xf0) == 0x90)
{
myIsRomMiddle = true;
mySliceMiddle = ((value & 0xf) | 0x10) << 11;
}
else if((value & 0xf0) == 0xc0)
{
myIsRomMiddle = false;
mySliceMiddle = (value & 0xf) << 11;
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int Cartridge4A50::bank()
{
// Doesn't support bankswitching in the normal sense
return 0;
}

View File

@ -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: Cart4A50.hxx,v 1.7 2007-10-09 23:56:57 stephena Exp $
// $Id: Cart4A50.hxx,v 1.8 2008-01-24 20:43:41 stephena Exp $
//============================================================================
#ifndef CARTRIDGE4A50_HXX
@ -37,7 +37,7 @@ class System;
bytes of ROM.
@author Stephen Anthony
@version $Id: Cart4A50.hxx,v 1.7 2007-10-09 23:56:57 stephena Exp $
@version $Id: Cart4A50.hxx,v 1.8 2008-01-24 20:43:41 stephena Exp $
*/
class Cartridge4A50 : public Cartridge
{
@ -144,36 +144,25 @@ class Cartridge4A50 : public Cartridge
virtual void poke(uInt16 address, uInt8 value);
private:
/**
Install the specified slice for segment zero
@param slice The slice to map into the segment
*/
void segmentZero(uInt16 slice);
/**
Install the specified slice for segment one
@param slice The slice to map into the segment
*/
void segmentOne(uInt16 slice);
/**
Install the specified slice for segment two
@param slice The slice to map into the segment
*/
void segmentTwo(uInt16 slice);
private:
// Indicates the slice mapped into each of the four segments
uInt16 myCurrentSlice[4];
// The 64K ROM image of the cartridge
uInt8 myImage[65536];
// The 32K of RAM on the cartridge
uInt8 myRAM[32768];
// Indicates the slice mapped into each of the three segments
uInt16 mySliceLow; /* index pointer for $1000-$17ff slice */
uInt16 mySliceMiddle; /* index pointer for $1800-$1dff slice */
uInt16 mySliceHigh; /* index pointer for $1e00-$1eff slice */
// Indicates whether the given slice is mapped to ROM or RAM
bool myIsRomLow; /* true = ROM -- false = RAM at $1000-$17ff */
bool myIsRomMiddle; /* true = ROM -- false = RAM at $1800-$1dff */
bool myIsRomHigh; /* true = ROM -- false = RAM at $1e00-$1eFF */
// The previous address and data values (from peek and poke)
uInt16 myLastAddress;
uInt8 myLastData;
};
#endif

View File

@ -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: OSystem.cxx,v 1.112 2007-10-09 23:56:57 stephena Exp $
// $Id: OSystem.cxx,v 1.113 2008-01-24 20:43:41 stephena Exp $
//============================================================================
#include <cassert>
@ -769,8 +769,8 @@ void OSystem::queryVideoHardware()
// First get the maximum windowed desktop resolution
const SDL_VideoInfo* info = SDL_GetVideoInfo();
myDesktopWidth = info->current_w;
myDesktopHeight = info->current_h;
myDesktopWidth = 1024;//info->current_w;
myDesktopHeight = 768;//info->current_h;
// Then get the valid fullscreen modes
// If there are any errors, just use the desktop resolution