More peek/poke refactoring, and improved comments in bankswitching schemes.

This commit is contained in:
Stephen Anthony 2017-08-31 13:01:45 -02:30
parent 68f80f04d9
commit 31907f4be1
28 changed files with 224 additions and 237 deletions

View File

@ -102,7 +102,7 @@ void CartridgeDFSCWidget::saveOldState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFSCWidget::loadConfig() void CartridgeDFSCWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
CartDebugWidget::loadConfig(); CartDebugWidget::loadConfig();
} }
@ -131,8 +131,8 @@ string CartridgeDFSCWidget::bankState()
"$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFE7", "$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFE7",
"$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF" "$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF"
}; };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -89,7 +89,7 @@ CartridgeDFWidget::CartridgeDFWidget(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDFWidget::loadConfig() void CartridgeDFWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
CartDebugWidget::loadConfig(); CartDebugWidget::loadConfig();
} }
@ -118,8 +118,8 @@ string CartridgeDFWidget::bankState()
"$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFD7", "$FFD0", "$FFD1", "$FFD2", "$FFD3", "$FFD4", "$FFD5", "$FFD6", "$FFD7",
"$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF" "$FFD8", "$FFD9", "$FFDA", "$FFDB", "$FFDC", "$FFDD", "$FFDE", "$FFDF"
}; };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -218,7 +218,7 @@ void CartridgeDPCPlusWidget::saveOldState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCPlusWidget::loadConfig() void CartridgeDPCPlusWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
// Get registers, using change tracking // Get registers, using change tracking
IntArray alist; IntArray alist;
@ -327,8 +327,8 @@ string CartridgeDPCPlusWidget::bankState()
static const char* const spot[] = { static const char* const spot[] = {
"$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB" "$FFF6", "$FFF7", "$FFF8", "$FFF9", "$FFFA", "$FFFB"
}; };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -156,7 +156,7 @@ void CartridgeDPCWidget::saveOldState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeDPCWidget::loadConfig() void CartridgeDPCWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
// Get registers, using change tracking // Get registers, using change tracking
IntArray alist; IntArray alist;
@ -228,8 +228,8 @@ string CartridgeDPCWidget::bankState()
ostringstream& buf = buffer(); ostringstream& buf = buffer();
static const char* const spot[] = { "$FFF8", "$FFF9" }; static const char* const spot[] = { "$FFF8", "$FFF9" };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -86,7 +86,7 @@ void CartridgeEFSCWidget::saveOldState()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEFSCWidget::loadConfig() void CartridgeEFSCWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
CartDebugWidget::loadConfig(); CartDebugWidget::loadConfig();
} }
@ -113,8 +113,8 @@ string CartridgeEFSCWidget::bankState()
"$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7", "$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7",
"$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF" "$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF"
}; };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -73,7 +73,7 @@ CartridgeEFWidget::CartridgeEFWidget(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeEFWidget::loadConfig() void CartridgeEFWidget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
CartDebugWidget::loadConfig(); CartDebugWidget::loadConfig();
} }
@ -100,8 +100,8 @@ string CartridgeEFWidget::bankState()
"$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7", "$FFE0", "$FFE1", "$FFE2", "$FFE3", "$FFE4", "$FFE5", "$FFE6", "$FFE7",
"$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF" "$FFE8", "$FFE9", "$FFEA", "$FFEB", "$FFEC", "$FFED", "$FFEE", "$FFEF"
}; };
buf << "Bank = " << std::dec << myCart.myCurrentBank buf << "Bank = " << std::dec << myCart.getBank()
<< ", hotspot = " << spot[myCart.myCurrentBank]; << ", hotspot = " << spot[myCart.getBank()];
return buf.str(); return buf.str();
} }

View File

@ -74,7 +74,7 @@ CartridgeF0Widget::CartridgeF0Widget(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF0Widget::loadConfig() void CartridgeF0Widget::loadConfig()
{ {
myBank->setSelectedIndex(myCart.myCurrentBank); myBank->setSelectedIndex(myCart.getBank());
CartDebugWidget::loadConfig(); CartDebugWidget::loadConfig();
} }
@ -97,7 +97,7 @@ string CartridgeF0Widget::bankState()
{ {
ostringstream& buf = buffer(); ostringstream& buf = buffer();
buf << "Bank = " << std::dec << myCart.myCurrentBank << ", hotspot = $FFF0"; buf << "Bank = " << std::dec << myCart.getBank() << ", hotspot = $FFF0";
return buf.str(); return buf.str();
} }

View File

@ -31,11 +31,8 @@ Cartridge2K::Cartridge2K(const BytePtr& image, uInt32 size,
while(mySize < size) while(mySize < size)
mySize <<= 1; mySize <<= 1;
// The smallest addressable area by Stella is 64 bytes // We can't use a size smaller than the minimum page size in Stella
// This should really be read from the System, but for now I'm going mySize = std::max(mySize, 1u << System::PAGE_SHIFT);
// to cheat a little and hard-code it to 64 (aka 2^6)
if(mySize < 64)
mySize = 64;
// Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam // Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam
myImage = make_unique<uInt8[]>(mySize); myImage = make_unique<uInt8[]>(mySize);
@ -62,6 +59,8 @@ void Cartridge2K::install(System& system)
mySystem = &system; mySystem = &system;
// Map ROM image into the system // Map ROM image into the system
// Note that we don't need our own peek/poke methods, since the mapping
// takes care of the entire address space
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
for(uInt32 address = 0x1000; address < 0x2000; address += (1 << System::PAGE_SHIFT)) for(uInt32 address = 0x1000; address < 0x2000; address += (1 << System::PAGE_SHIFT))
{ {

View File

@ -27,11 +27,12 @@ class System;
#endif #endif
/** /**
This is the standard Atari 2K cartridge. These cartridges This is the standard Atari 2K cartridge. These cartridges are not
are not bankswitched, however, the data repeats twice in the bankswitched, however, the data repeats twice in the 2600's 4K cartridge
2600's 4K cartridge addressing space. addressing space. For 'Sub2K' ROMs (ROMs less than 2K in size), the
data repeats in intervals based on the size of the ROM.
@author Bradford W. Mott @author Stephen Anthony
*/ */
class Cartridge2K : public Cartridge class Cartridge2K : public Cartridge
{ {

View File

@ -40,6 +40,8 @@ void Cartridge4K::install(System& system)
mySystem = &system; mySystem = &system;
// Map ROM image into the system // Map ROM image into the system
// Note that we don't need our own peek/poke methods, since the mapping
// takes care of the entire address space
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
for(uInt32 address = 0x1000; address < 0x2000; for(uInt32 address = 0x1000; address < 0x2000;
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))

View File

@ -28,6 +28,7 @@ class System;
/** /**
Cartridge class used for 4K games with 128 bytes of RAM. Cartridge class used for 4K games with 128 bytes of RAM.
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
*/ */
class Cartridge4KSC : public Cartridge class Cartridge4KSC : public Cartridge

View File

@ -29,6 +29,7 @@ class System;
/** /**
There are 64 4K banks (total of 256K ROM) with 128 bytes of RAM. There are 64 4K banks (total of 256K ROM) with 128 bytes of RAM.
Accessing $1F80 - $1FBF switches to each bank. Accessing $1F80 - $1FBF switches to each bank.
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
@author Stephen Anthony @author Stephen Anthony
*/ */

View File

@ -29,98 +29,98 @@ class CartridgeDASHWidget;
#endif #endif
/** /**
Cartridge class for new tiling engine "Boulder Dash" format games with RAM. Cartridge class for new tiling engine "Boulder Dash" format games with RAM.
Kind of a combination of 3F and 3E, with better switchability. Kind of a combination of 3F and 3E, with better switchability.
B.Watson's Cart3E was used as a template for building this implementation. B.Watson's Cart3E was used as a template for building this implementation.
The destination bank (0-3) is held in the top bits of the value written to The destination bank (0-3) is held in the top bits of the value written to
$3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give $3E (for RAM switching) or $3F (for ROM switching). The low 6 bits give
the actual bank number (0-63) corresponding to 512 byte blocks for RAM and the actual bank number (0-63) corresponding to 512 byte blocks for RAM and
1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM. 1024 byte blocks for ROM. The maximum size is therefore 32K RAM and 64K ROM.
D7D6 indicate the bank number (0-3) D7D6 indicate the bank number (0-3)
D5D4D3D2D1D0 indicate the actual # (0-63) from the image/ram D5D4D3D2D1D0 indicate the actual # (0-63) from the image/ram
ROM: ROM:
Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal Note: in descriptions $F000 is equivalent to $1000 -- that is, we only deal
with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000 with the low 13 bits of addressing. Stella code uses $1000, I'm used to $F000
So, mask with top bits clear :) when reading this document. So, mask with top bits clear :) when reading this document.
In this scheme, the 4K address space is broken into four 1K ROM segments. In this scheme, the 4K address space is broken into four 1K ROM segments.
living at 0x1000, 0x1400, 0x1800, 0x1C00 (or, same thing, 0xF000... etc.), living at 0x1000, 0x1400, 0x1800, 0x1C00 (or, same thing, 0xF000... etc.),
and four 512 byte RAM segments, living at 0x1000, 0x1200, 0x1400, 0x1600 and four 512 byte RAM segments, living at 0x1000, 0x1200, 0x1400, 0x1600
with write-mirrors +0x800 of these. The last 1K ROM ($FC00-$FFFF) segment with write-mirrors +0x800 of these. The last 1K ROM ($FC00-$FFFF) segment
in the 6502 address space (ie: $1C00-$1FFF) is initialised to point to the in the 6502 address space (ie: $1C00-$1FFF) is initialised to point to the
FIRST 1K of the ROM image, so the reset vectors must be placed at the FIRST 1K of the ROM image, so the reset vectors must be placed at the
end of the first 1K in the ROM image. Note, this is DIFFERENT to 3E which end of the first 1K in the ROM image. Note, this is DIFFERENT to 3E which
switches in the UPPER bank and this bank is fixed. This allows variable sized switches in the UPPER bank and this bank is fixed. This allows variable sized
ROM without having to detect size. First bank (0) in ROM is the default fixed ROM without having to detect size. First bank (0) in ROM is the default fixed
bank mapped to $FC00. bank mapped to $FC00.
The system requires the reset vectors to be valid on a reset, so either the The system requires the reset vectors to be valid on a reset, so either the
hardware first switches in the first bank, or the programmer must ensure hardware first switches in the first bank, or the programmer must ensure
that the reset vector is present in ALL ROM banks which might be switched that the reset vector is present in ALL ROM banks which might be switched
into the last bank area. Currently the latter (programmer onus) is required, into the last bank area. Currently the latter (programmer onus) is required,
but it would be nice for the cartridge hardware to auto-switch on reset. but it would be nice for the cartridge hardware to auto-switch on reset.
ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank # ROM switching (write of block+bank number to $3F) D7D6 upper 2 bits of bank #
indicates the destination segment (0-3, corresponding to $F000, $F400, $F800, indicates the destination segment (0-3, corresponding to $F000, $F400, $F800,
$FC00), and lower 6 bits indicate the 1K bank to switch in. Can handle 64 $FC00), and lower 6 bits indicate the 1K bank to switch in. Can handle 64
x 1K ROM banks (64K total). x 1K ROM banks (64K total).
D7 D6 D5D4D3D2D1D0 D7 D6 D5D4D3D2D1D0
0 0 x x x x x x switch a 1K ROM bank xxxxx to $F000 0 0 x x x x x x switch a 1K ROM bank xxxxx to $F000
0 1 switch a 1K ROM bank xxxxx to $F400 0 1 switch a 1K ROM bank xxxxx to $F400
1 0 switch a 1K ROM bank xxxxx to $F800 1 0 switch a 1K ROM bank xxxxx to $F800
1 1 switch a 1K ROM bank xxxxx to $FC00 1 1 switch a 1K ROM bank xxxxx to $FC00
RAM switching (write of segment+bank number to $3E) with D7D6 upper 2 bits of RAM switching (write of segment+bank number to $3E) with D7D6 upper 2 bits of
bank # indicates the destination RAM segment (0-3, corresponding to $F000, bank # indicates the destination RAM segment (0-3, corresponding to $F000,
$F200, $F400, $F600). Note that this allows contiguous 2K of RAM to be $F200, $F400, $F600). Note that this allows contiguous 2K of RAM to be
configured by setting 4 consecutive RAM segments each 512 bytes with configured by setting 4 consecutive RAM segments each 512 bytes with
consecutive addresses. However, as the write address of RAM is +0x800, this consecutive addresses. However, as the write address of RAM is +0x800, this
invalidates ROM access as described below. invalidates ROM access as described below.
can handle 64 x 512 byte RAM banks (32K total) can handle 64 x 512 byte RAM banks (32K total)
D7 D6 D5D4D3D2D1D0 D7 D6 D5D4D3D2D1D0
0 0 x x x x x x switch a 512 byte RAM bank xxxxx to $F000 with write @ $F800 0 0 x x x x x x switch a 512 byte RAM bank xxxxx to $F000 with write @ $F800
0 1 switch a 512 byte RAM bank xxxxx to $F200 with write @ $FA00 0 1 switch a 512 byte RAM bank xxxxx to $F200 with write @ $FA00
1 0 switch a 512 byte RAM bank xxxxx to $F400 with write @ $FC00 1 0 switch a 512 byte RAM bank xxxxx to $F400 with write @ $FC00
1 1 switch a 512 byte RAM bank xxxxx to $F600 with write @ $FE00 1 1 switch a 512 byte RAM bank xxxxx to $F600 with write @ $FE00
It is possible to switch multiple RAM banks and ROM banks together It is possible to switch multiple RAM banks and ROM banks together
For example, For example,
F000-F1FF RAM bank A (512 byte READ) F000-F1FF RAM bank A (512 byte READ)
F200-F3FF high 512 bytes of ROM bank previously loaded at F000 F200-F3FF high 512 bytes of ROM bank previously loaded at F000
F400 ROM bank 0 (1K) F400 ROM bank 0 (1K)
F800 RAM bank A (512 byte WRITE) F800 RAM bank A (512 byte WRITE)
FA00-FBFF high 512 bytes of ROM bank previously loaded at F400 FA00-FBFF high 512 bytes of ROM bank previously loaded at F400
FC00 ROM bank 1 FC00 ROM bank 1
This example shows 512 bytes of RAM, and 2 1K ROM banks and two 512 byte ROM This example shows 512 bytes of RAM, and 2 1K ROM banks and two 512 byte ROM
bank halves. bank halves.
Switching RAM blocks (D7D6 of $3E) partially invalidates ROM blocks, as below... Switching RAM blocks (D7D6 of $3E) partially invalidates ROM blocks, as below...
RAM block Invalidates ROM block RAM block Invalidates ROM block
0 0 (lower half), 2 (lower half) 0 0 (lower half), 2 (lower half)
1 0 (upper half), 2 (upper half) 1 0 (upper half), 2 (upper half)
2 1 (lower half), 3 (upper half) 2 1 (lower half), 3 (upper half)
3 1 (upper half), 3 (lower half) 3 1 (upper half), 3 (lower half)
For example, RAM block 1 uses address $F200-$F3FF and $FA00-$FBFF For example, RAM block 1 uses address $F200-$F3FF and $FA00-$FBFF
ROM block 0 uses address $F000-$F3FF, and ROM block 2 uses address $F800-$FBFF ROM block 0 uses address $F000-$F3FF, and ROM block 2 uses address $F800-$FBFF
Switching in RAM block 1 makes F200-F3FF ROM inaccessible, however F000-F1FF is Switching in RAM block 1 makes F200-F3FF ROM inaccessible, however F000-F1FF is
still readable. So, care must be paid. still readable. So, care must be paid.
This crazy RAM layout is useful as it allows contiguous RAM to be switched in, This crazy RAM layout is useful as it allows contiguous RAM to be switched in,
up to 2K in one sequentially accessible block. This means you CAN have 2K of up to 2K in one sequentially accessible block. This means you CAN have 2K of
consecutive RAM (don't forget to copy your reset vectors!) consecutive RAM (don't forget to copy your reset vectors!)
@author Andrew Davie @author Andrew Davie
*/ */
class CartridgeDASH: public Cartridge class CartridgeDASH: public Cartridge

View File

@ -22,7 +22,7 @@
CartridgeDF::CartridgeDF(const BytePtr& image, uInt32 size, CartridgeDF::CartridgeDF(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
myCurrentBank(0) myBankOffset(0)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(131072u, size)); memcpy(myImage, image.get(), std::min(131072u, size));
@ -57,7 +57,7 @@ uInt8 CartridgeDF::peek(uInt16 address)
if((address >= 0x0FC0) && (address <= 0x0FDF)) if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0); bank(address - 0x0FC0);
return myImage[(myCurrentBank << 12) + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -78,8 +78,7 @@ bool CartridgeDF::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt32 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -87,7 +86,7 @@ bool CartridgeDF::bank(uInt16 bank)
for(uInt32 i = (0x1FC0 & ~System::PAGE_MASK); i < 0x2000; for(uInt32 i = (0x1FC0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT)) i += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
} }
@ -95,8 +94,8 @@ bool CartridgeDF::bank(uInt16 bank)
for(uInt32 address = 0x1000; address < (0x1FC0U & ~System::PAGE_MASK); for(uInt32 address = 0x1000; address < (0x1FC0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.directPeekBase = &myImage[offset + (address & 0x0FFF)]; access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -105,7 +104,7 @@ bool CartridgeDF::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDF::getBank() const uInt16 CartridgeDF::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -117,7 +116,7 @@ uInt16 CartridgeDF::bankCount() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeDF::patch(uInt16 address, uInt8 value) bool CartridgeDF::patch(uInt16 address, uInt8 value)
{ {
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; myImage[myBankOffset + (address & 0x0FFF)] = value;
return myBankChanged = true; return myBankChanged = true;
} }
@ -134,7 +133,7 @@ bool CartridgeDF::save(Serializer& out) const
try try
{ {
out.putString(name()); out.putString(name());
out.putShort(myCurrentBank); out.putInt(myBankOffset);
} }
catch(...) catch(...)
{ {
@ -153,7 +152,7 @@ bool CartridgeDF::load(Serializer& in)
if(in.getString() != name()) if(in.getString() != name())
return false; return false;
myCurrentBank = in.getShort(); myBankOffset = in.getInt();
} }
catch(...) catch(...)
{ {
@ -162,7 +161,7 @@ bool CartridgeDF::load(Serializer& in)
} }
// Remember what bank we were in // Remember what bank we were in
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -152,8 +152,8 @@ class CartridgeDF : public Cartridge
// The 128K ROM image of the cartridge // The 128K ROM image of the cartridge
uInt8 myImage[32 * 4096]; uInt8 myImage[32 * 4096];
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt32 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -22,7 +22,7 @@
CartridgeDFSC::CartridgeDFSC(const BytePtr& image, uInt32 size, CartridgeDFSC::CartridgeDFSC(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
myCurrentBank(0) myBankOffset(0)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(131072u, size)); memcpy(myImage, image.get(), std::min(131072u, size));
@ -95,7 +95,7 @@ uInt8 CartridgeDFSC::peek(uInt16 address)
} }
} }
else else
return myImage[(myCurrentBank << 12) + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -107,7 +107,7 @@ bool CartridgeDFSC::poke(uInt16 address, uInt8)
if((address >= 0x0FC0) && (address <= 0x0FDF)) if((address >= 0x0FC0) && (address <= 0x0FDF))
bank(address - 0x0FC0); bank(address - 0x0FC0);
// NOTE: This does not handle accessing RAM, however, this function // NOTE: This does not handle accessing RAM, however, this method
// should never be called for RAM because of the way page accessing // should never be called for RAM because of the way page accessing
// has been setup // has been setup
return false; return false;
@ -119,8 +119,7 @@ bool CartridgeDFSC::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt32 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -128,7 +127,7 @@ bool CartridgeDFSC::bank(uInt16 bank)
for(uInt32 i = (0x1FC0 & ~System::PAGE_MASK); i < 0x2000; for(uInt32 i = (0x1FC0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT)) i += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
} }
@ -136,8 +135,8 @@ bool CartridgeDFSC::bank(uInt16 bank)
for(uInt32 address = 0x1100; address < (0x1FC0U & ~System::PAGE_MASK); for(uInt32 address = 0x1100; address < (0x1FC0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.directPeekBase = &myImage[offset + (address & 0x0FFF)]; access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -146,7 +145,7 @@ bool CartridgeDFSC::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDFSC::getBank() const uInt16 CartridgeDFSC::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -168,7 +167,7 @@ bool CartridgeDFSC::patch(uInt16 address, uInt8 value)
myRAM[address & 0x007F] = value; myRAM[address & 0x007F] = value;
} }
else else
myImage[(myCurrentBank << 12) + address] = value; myImage[myBankOffset + address] = value;
return myBankChanged = true; return myBankChanged = true;
} }
@ -186,7 +185,7 @@ bool CartridgeDFSC::save(Serializer& out) const
try try
{ {
out.putString(name()); out.putString(name());
out.putShort(myCurrentBank); out.putInt(myBankOffset);
out.putByteArray(myRAM, 128); out.putByteArray(myRAM, 128);
} }
catch(...) catch(...)
@ -206,7 +205,7 @@ bool CartridgeDFSC::load(Serializer& in)
if(in.getString() != name()) if(in.getString() != name())
return false; return false;
myCurrentBank = in.getShort(); myBankOffset = in.getInt();
in.getByteArray(myRAM, 128); in.getByteArray(myRAM, 128);
} }
catch(...) catch(...)
@ -216,7 +215,7 @@ bool CartridgeDFSC::load(Serializer& in)
} }
// Remember what bank we were in // Remember what bank we were in
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -29,6 +29,7 @@ class System;
/** /**
There are 32 4K banks (total of 128K ROM) with 128 bytes of RAM. There are 32 4K banks (total of 128K ROM) with 128 bytes of RAM.
Accessing $1FC0 - $1FDF switches to each bank. Accessing $1FC0 - $1FDF switches to each bank.
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
@author Stephen Anthony @author Stephen Anthony
*/ */
@ -154,8 +155,8 @@ class CartridgeDFSC : public Cartridge
// The 128 bytes of RAM // The 128 bytes of RAM
uInt8 myRAM[128]; uInt8 myRAM[128];
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt32 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -25,7 +25,7 @@ CartridgeDPC::CartridgeDPC(const BytePtr& image, uInt32 size,
mySize(size), mySize(size),
mySystemCycles(0), mySystemCycles(0),
myFractionalClocks(0.0), myFractionalClocks(0.0),
myCurrentBank(0) myBankOffset(0)
{ {
// Make a copy of the entire image // Make a copy of the entire image
memcpy(myImage, image.get(), std::min(size, 8192u + 2048u + 256u)); memcpy(myImage, image.get(), std::min(size, 8192u + 2048u + 256u));
@ -163,7 +163,7 @@ uInt8 CartridgeDPC::peek(uInt16 address)
// In debugger/bank-locked mode, we ignore all hotspots and in general // In debugger/bank-locked mode, we ignore all hotspots and in general
// anything that can change the internal state of the cart // anything that can change the internal state of the cart
if(bankLocked()) if(bankLocked())
return myProgramImage[(myCurrentBank << 12) + address]; return myProgramImage[myBankOffset + address];
// Clock the random number generator. This should be done for every // Clock the random number generator. This should be done for every
// cartridge access, however, we're only doing it for the DPC and // cartridge access, however, we're only doing it for the DPC and
@ -279,7 +279,7 @@ uInt8 CartridgeDPC::peek(uInt16 address)
default: default:
break; break;
} }
return myProgramImage[(myCurrentBank << 12) + address]; return myProgramImage[myBankOffset + address];
} }
} }
@ -395,8 +395,7 @@ bool CartridgeDPC::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt16 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -404,7 +403,7 @@ bool CartridgeDPC::bank(uInt16 bank)
for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000; for(uInt32 i = (0x1FF8 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT)) i += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
} }
@ -412,8 +411,8 @@ bool CartridgeDPC::bank(uInt16 bank)
for(uInt32 address = 0x1080; address < (0x1FF8U & ~System::PAGE_MASK); for(uInt32 address = 0x1080; address < (0x1FF8U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.directPeekBase = &myProgramImage[offset + (address & 0x0FFF)]; access.directPeekBase = &myProgramImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -422,7 +421,7 @@ bool CartridgeDPC::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDPC::getBank() const uInt16 CartridgeDPC::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -439,7 +438,7 @@ bool CartridgeDPC::patch(uInt16 address, uInt8 value)
// For now, we ignore attempts to patch the DPC address space // For now, we ignore attempts to patch the DPC address space
if(address >= 0x0080) if(address >= 0x0080)
{ {
myProgramImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; myProgramImage[myBankOffset + (address & 0x0FFF)] = value;
return myBankChanged = true; return myBankChanged = true;
} }
else else
@ -461,7 +460,7 @@ bool CartridgeDPC::save(Serializer& out) const
out.putString(name()); out.putString(name());
// Indicates which bank is currently active // Indicates which bank is currently active
out.putShort(myCurrentBank); out.putShort(myBankOffset);
// The top registers for the data fetchers // The top registers for the data fetchers
out.putByteArray(myTops, 8); out.putByteArray(myTops, 8);
@ -503,7 +502,7 @@ bool CartridgeDPC::load(Serializer& in)
return false; return false;
// Indicates which bank is currently active // Indicates which bank is currently active
myCurrentBank = in.getShort(); myBankOffset = in.getShort();
// The top registers for the data fetchers // The top registers for the data fetchers
in.getByteArray(myTops, 8); in.getByteArray(myTops, 8);
@ -535,7 +534,7 @@ bool CartridgeDPC::load(Serializer& in)
} }
// Now, go to the current bank // Now, go to the current bank
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -208,8 +208,8 @@ class CartridgeDPC : public Cartridge
// Fractional DPC music OSC clocks unused during the last update // Fractional DPC music OSC clocks unused during the last update
double myFractionalClocks; double myFractionalClocks;
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt16 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -33,7 +33,7 @@ CartridgeDPCPlus::CartridgeDPCPlus(const BytePtr& image, uInt32 size,
mySystemCycles(0), mySystemCycles(0),
myFractionalClocks(0.0), myFractionalClocks(0.0),
myARMCycles(0), myARMCycles(0),
myCurrentBank(0) myBankOffset(0)
{ {
// Image is always 32K, but in the case of ROM > 29K, the image is // Image is always 32K, but in the case of ROM > 29K, the image is
// copied to the end of the buffer // copied to the end of the buffer
@ -221,7 +221,7 @@ uInt8 CartridgeDPCPlus::peek(uInt16 address)
{ {
address &= 0x0FFF; address &= 0x0FFF;
uInt8 peekvalue = myProgramImage[(myCurrentBank << 12) + address]; uInt8 peekvalue = myProgramImage[myBankOffset + address];
uInt8 flag; uInt8 flag;
// In debugger/bank-locked mode, we ignore all hotspots and in general // In debugger/bank-locked mode, we ignore all hotspots and in general
@ -593,8 +593,7 @@ bool CartridgeDPCPlus::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt16 offset = myCurrentBank << 12;
// Setup the page access methods for the current bank // Setup the page access methods for the current bank
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -603,7 +602,7 @@ bool CartridgeDPCPlus::bank(uInt16 bank)
for(uInt32 address = 0x1080; address < 0x2000; for(uInt32 address = 0x1080; address < 0x2000;
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -612,7 +611,7 @@ bool CartridgeDPCPlus::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeDPCPlus::getBank() const uInt16 CartridgeDPCPlus::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -629,7 +628,7 @@ bool CartridgeDPCPlus::patch(uInt16 address, uInt8 value)
// For now, we ignore attempts to patch the DPC address space // For now, we ignore attempts to patch the DPC address space
if(address >= 0x0080) if(address >= 0x0080)
{ {
myProgramImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; myProgramImage[myBankOffset + (address & 0x0FFF)] = value;
return myBankChanged = true; return myBankChanged = true;
} }
else else
@ -651,7 +650,7 @@ bool CartridgeDPCPlus::save(Serializer& out) const
out.putString(name()); out.putString(name());
// Indicates which bank is currently active // Indicates which bank is currently active
out.putShort(myCurrentBank); out.putShort(myBankOffset);
// Harmony RAM // Harmony RAM
out.putByteArray(myDPCRAM, 8192); out.putByteArray(myDPCRAM, 8192);
@ -715,7 +714,7 @@ bool CartridgeDPCPlus::load(Serializer& in)
return false; return false;
// Indicates which bank is currently active // Indicates which bank is currently active
myCurrentBank = in.getShort(); myBankOffset = in.getShort();
// Harmony RAM // Harmony RAM
in.getByteArray(myDPCRAM, 8192); in.getByteArray(myDPCRAM, 8192);
@ -768,7 +767,7 @@ bool CartridgeDPCPlus::load(Serializer& in)
} }
// Now, go to the current bank // Now, go to the current bank
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -272,8 +272,8 @@ class CartridgeDPCPlus : public Cartridge
// System cycle count when the last Thumbulator::run() occurred // System cycle count when the last Thumbulator::run() occurred
Int32 myARMCycles; Int32 myARMCycles;
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt16 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -136,7 +136,7 @@ bool CartridgeE7::poke(uInt16 address, uInt8)
} }
// NOTE: This does not handle writing to RAM, however, this // NOTE: This does not handle writing to RAM, however, this
// function should never be called for RAM because of the // method should never be called for RAM because of the
// way page accessing has been setup // way page accessing has been setup
return false; return false;
} }

View File

@ -22,7 +22,7 @@
CartridgeEF::CartridgeEF(const BytePtr& image, uInt32 size, CartridgeEF::CartridgeEF(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
myCurrentBank(0) myBankOffset(0)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(65536u, size)); memcpy(myImage, image.get(), std::min(65536u, size));
@ -57,7 +57,7 @@ uInt8 CartridgeEF::peek(uInt16 address)
if((address >= 0x0FE0) && (address <= 0x0FEF)) if((address >= 0x0FE0) && (address <= 0x0FEF))
bank(address - 0x0FE0); bank(address - 0x0FE0);
return myImage[(myCurrentBank << 12) + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -78,8 +78,7 @@ bool CartridgeEF::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt16 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -87,7 +86,7 @@ bool CartridgeEF::bank(uInt16 bank)
for(uInt32 i = (0x1FE0 & ~System::PAGE_MASK); i < 0x2000; for(uInt32 i = (0x1FE0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT)) i += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
} }
@ -95,8 +94,8 @@ bool CartridgeEF::bank(uInt16 bank)
for(uInt32 address = 0x1000; address < (0x1FE0U & ~System::PAGE_MASK); for(uInt32 address = 0x1000; address < (0x1FE0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.directPeekBase = &myImage[offset + (address & 0x0FFF)]; access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -105,7 +104,7 @@ bool CartridgeEF::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeEF::getBank() const uInt16 CartridgeEF::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -117,7 +116,7 @@ uInt16 CartridgeEF::bankCount() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeEF::patch(uInt16 address, uInt8 value) bool CartridgeEF::patch(uInt16 address, uInt8 value)
{ {
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; myImage[myBankOffset + (address & 0x0FFF)] = value;
return myBankChanged = true; return myBankChanged = true;
} }
@ -134,7 +133,7 @@ bool CartridgeEF::save(Serializer& out) const
try try
{ {
out.putString(name()); out.putString(name());
out.putShort(myCurrentBank); out.putShort(myBankOffset);
} }
catch(...) catch(...)
{ {
@ -153,7 +152,7 @@ bool CartridgeEF::load(Serializer& in)
if(in.getString() != name()) if(in.getString() != name())
return false; return false;
myCurrentBank = in.getShort(); myBankOffset = in.getShort();
} }
catch(...) catch(...)
{ {
@ -162,7 +161,7 @@ bool CartridgeEF::load(Serializer& in)
} }
// Remember what bank we were in // Remember what bank we were in
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -31,9 +31,6 @@ class System;
There are 16 4K banks (total of 64K ROM). There are 16 4K banks (total of 64K ROM).
Accessing $1FE0 - $1FEF switches to each bank. 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 @author Stephen Anthony
*/ */
class CartridgeEF : public Cartridge class CartridgeEF : public Cartridge
@ -155,8 +152,8 @@ class CartridgeEF : public Cartridge
// The 64K ROM image of the cartridge // The 64K ROM image of the cartridge
uInt8 myImage[65536]; uInt8 myImage[65536];
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt16 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -22,7 +22,7 @@
CartridgeEFSC::CartridgeEFSC(const BytePtr& image, uInt32 size, CartridgeEFSC::CartridgeEFSC(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
myCurrentBank(0) myBankOffset(0)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(65536u, size)); memcpy(myImage, image.get(), std::min(65536u, size));
@ -95,7 +95,7 @@ uInt8 CartridgeEFSC::peek(uInt16 address)
} }
} }
else else
return myImage[(myCurrentBank << 12) + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -119,8 +119,7 @@ bool CartridgeEFSC::bank(uInt16 bank)
if(bankLocked()) return false; if(bankLocked()) return false;
// Remember what bank we're in // Remember what bank we're in
myCurrentBank = bank; myBankOffset = bank << 12;
uInt16 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ); System::PageAccess access(this, System::PA_READ);
@ -128,7 +127,7 @@ bool CartridgeEFSC::bank(uInt16 bank)
for(uInt32 i = (0x1FE0 & ~System::PAGE_MASK); i < 0x2000; for(uInt32 i = (0x1FE0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT)) i += (1 << System::PAGE_SHIFT))
{ {
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access); mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
} }
@ -136,8 +135,8 @@ bool CartridgeEFSC::bank(uInt16 bank)
for(uInt32 address = 0x1100; address < (0x1FE0U & ~System::PAGE_MASK); for(uInt32 address = 0x1100; address < (0x1FE0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT)) address += (1 << System::PAGE_SHIFT))
{ {
access.directPeekBase = &myImage[offset + (address & 0x0FFF)]; access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)]; access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access); mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
} }
return myBankChanged = true; return myBankChanged = true;
@ -146,7 +145,7 @@ bool CartridgeEFSC::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeEFSC::getBank() const uInt16 CartridgeEFSC::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -168,7 +167,7 @@ bool CartridgeEFSC::patch(uInt16 address, uInt8 value)
myRAM[address & 0x007F] = value; myRAM[address & 0x007F] = value;
} }
else else
myImage[(myCurrentBank << 12) + address] = value; myImage[myBankOffset + address] = value;
return myBankChanged = true; return myBankChanged = true;
} }
@ -186,7 +185,7 @@ bool CartridgeEFSC::save(Serializer& out) const
try try
{ {
out.putString(name()); out.putString(name());
out.putShort(myCurrentBank); out.putShort(myBankOffset);
out.putByteArray(myRAM, 128); out.putByteArray(myRAM, 128);
} }
catch(...) catch(...)
@ -206,7 +205,7 @@ bool CartridgeEFSC::load(Serializer& in)
if(in.getString() != name()) if(in.getString() != name())
return false; return false;
myCurrentBank = in.getShort(); myBankOffset = in.getShort();
in.getByteArray(myRAM, 128); in.getByteArray(myRAM, 128);
} }
catch(...) catch(...)
@ -216,7 +215,7 @@ bool CartridgeEFSC::load(Serializer& in)
} }
// Remember what bank we were in // Remember what bank we were in
bank(myCurrentBank); bank(myBankOffset >> 12);
return true; return true;
} }

View File

@ -30,9 +30,7 @@ class System;
Cartridge class used for Homestar Runner by Paul Slocum. Cartridge class used for Homestar Runner by Paul Slocum.
There are 16 4K banks (total of 64K ROM) with 128 bytes of RAM. There are 16 4K banks (total of 64K ROM) with 128 bytes of RAM.
Accessing $1FE0 - $1FEF switches to each bank. Accessing $1FE0 - $1FEF switches to each bank.
RAM read port is $1080 - $10FF, write port is $1000 - $107F.
This interpretation is based on analysis of the z26 assembly code,
as this scheme doesn't seem to be documented anywhere.
@author Stephen Anthony @author Stephen Anthony
*/ */
@ -158,8 +156,8 @@ class CartridgeEFSC : public Cartridge
// The 128 bytes of RAM // The 128 bytes of RAM
uInt8 myRAM[128]; uInt8 myRAM[128];
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt16 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -22,7 +22,7 @@
CartridgeF0::CartridgeF0(const BytePtr& image, uInt32 size, CartridgeF0::CartridgeF0(const BytePtr& image, uInt32 size,
const Settings& settings) const Settings& settings)
: Cartridge(settings), : Cartridge(settings),
myCurrentBank(0) myBankOffset(0)
{ {
// Copy the ROM image into my buffer // Copy the ROM image into my buffer
memcpy(myImage, image.get(), std::min(65536u, size)); memcpy(myImage, image.get(), std::min(65536u, size));
@ -35,9 +35,8 @@ CartridgeF0::CartridgeF0(const BytePtr& image, uInt32 size,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF0::reset() void CartridgeF0::reset()
{ {
// Upon reset we switch to bank 15 // Upon reset we switch to the startup bank
myCurrentBank = 14; bank(myStartBank);
incbank();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -45,9 +44,8 @@ void CartridgeF0::install(System& system)
{ {
mySystem = &system; mySystem = &system;
// Install pages for bank 1 // Install pages for the startup bank
myCurrentBank = 0; bank(myStartBank);
incbank();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -59,7 +57,7 @@ uInt8 CartridgeF0::peek(uInt16 address)
if(address == 0x0FF0) if(address == 0x0FF0)
incbank(); incbank();
return myImage[(myCurrentBank << 12) + address]; return myImage[myBankOffset + address];
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,32 +75,9 @@ bool CartridgeF0::poke(uInt16 address, uInt8)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartridgeF0::incbank() void CartridgeF0::incbank()
{ {
if(bankLocked()) return; // Determine current bank, and increment to the next one
uInt8 nextBank = ((myBankOffset >> 12) + 1) & 0x0F;
// Remember what bank we're in bank(nextBank);
myCurrentBank++;
myCurrentBank &= 0x0F;
uInt16 offset = myCurrentBank << 12;
System::PageAccess access(this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT))
{
access.codeAccessBase = &myCodeAccessBase[offset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT))
{
access.directPeekBase = &myImage[offset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[offset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
}
myBankChanged = true;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -110,8 +85,27 @@ bool CartridgeF0::bank(uInt16 bank)
{ {
if(bankLocked()) return false; if(bankLocked()) return false;
myCurrentBank = bank - 1; // Remember what bank we're in
incbank(); myBankOffset = bank << 12;
System::PageAccess access(this, System::PA_READ);
// Set the page accessing methods for the hot spots
for(uInt32 i = (0x1FF0 & ~System::PAGE_MASK); i < 0x2000;
i += (1 << System::PAGE_SHIFT))
{
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (i & 0x0FFF)];
mySystem->setPageAccess(i >> System::PAGE_SHIFT, access);
}
// Setup the page access methods for the current bank
for(uInt32 address = 0x1000; address < (0x1FF0U & ~System::PAGE_MASK);
address += (1 << System::PAGE_SHIFT))
{
access.directPeekBase = &myImage[myBankOffset + (address & 0x0FFF)];
access.codeAccessBase = &myCodeAccessBase[myBankOffset + (address & 0x0FFF)];
mySystem->setPageAccess(address >> System::PAGE_SHIFT, access);
}
return myBankChanged = true; return myBankChanged = true;
} }
@ -119,7 +113,7 @@ bool CartridgeF0::bank(uInt16 bank)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 CartridgeF0::getBank() const uInt16 CartridgeF0::getBank() const
{ {
return myCurrentBank; return myBankOffset >> 12;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -131,7 +125,7 @@ uInt16 CartridgeF0::bankCount() const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool CartridgeF0::patch(uInt16 address, uInt8 value) bool CartridgeF0::patch(uInt16 address, uInt8 value)
{ {
myImage[(myCurrentBank << 12) + (address & 0x0FFF)] = value; myImage[myBankOffset + (address & 0x0FFF)] = value;
return myBankChanged = true; return myBankChanged = true;
} }
@ -148,7 +142,7 @@ bool CartridgeF0::save(Serializer& out) const
try try
{ {
out.putString(name()); out.putString(name());
out.putShort(myCurrentBank); out.putShort(myBankOffset);
} }
catch(...) catch(...)
{ {
@ -167,7 +161,7 @@ bool CartridgeF0::load(Serializer& in)
if(in.getString() != name()) if(in.getString() != name())
return false; return false;
myCurrentBank = in.getShort(); myBankOffset = in.getShort();
} }
catch(...) catch(...)
{ {
@ -176,8 +170,7 @@ bool CartridgeF0::load(Serializer& in)
} }
// Remember what bank we were in // Remember what bank we were in
--myCurrentBank; bank(myBankOffset >> 12);
incbank();
return true; return true;
} }

View File

@ -158,8 +158,8 @@ class CartridgeF0 : public Cartridge
// The 64K ROM image of the cartridge // The 64K ROM image of the cartridge
uInt8 myImage[65536]; uInt8 myImage[65536];
// Indicates which bank is currently active // Indicates the offset into the ROM image (aligns to current bank)
uInt16 myCurrentBank; uInt16 myBankOffset;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported