mirror of https://github.com/stella-emu/stella.git
Reorganized random number generation code in each Cart class. There
was duplicate code in many Cart classes and in M6532 class, and since all these classes are subclasses of Device, it made sense to move the functionality there instead. Carts 3E and E7 now return a random value when attempting to read from the write port. Still TODO is determine what happens to the value at that address (is it randomized or zeroed?). Thanks to Batari for suggestions and sample code. Fixed bug in E7 carts when entering the debugger; bankswitch was being inadvertantly triggered which caused emulation to fail. Overall, I need to figure out exactly what happens when reading from the write port for all carts with extended RAM. There are two things to consider: what value is written to the address, and what value is returned. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1892 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
917f766a6d
commit
5ce401e6a4
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
#include "Cart3E.hxx"
|
#include "Cart3E.hxx"
|
||||||
|
@ -50,9 +49,8 @@ Cartridge3E::~Cartridge3E()
|
||||||
void Cartridge3E::reset()
|
void Cartridge3E::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 32768; ++i)
|
for(uInt32 i = 0; i < 32768; ++i)
|
||||||
myRam[i] = random.next();
|
myRam[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// We'll map bank 0 into the first segment upon reset
|
// We'll map bank 0 into the first segment upon reset
|
||||||
bank(0);
|
bank(0);
|
||||||
|
@ -97,13 +95,14 @@ void Cartridge3E::install(System& system)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 Cartridge3E::peek(uInt16 address)
|
uInt8 Cartridge3E::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
// TODO - determine what really happens when you read from the write port
|
|
||||||
address &= 0x0FFF;
|
address &= 0x0FFF;
|
||||||
|
|
||||||
if(address < 0x0800)
|
if(address < 0x0800)
|
||||||
{
|
{
|
||||||
if(myCurrentBank < 256)
|
if(myCurrentBank < 256)
|
||||||
return myImage[(address & 0x07FF) + (myCurrentBank << 11)];
|
return myImage[(address & 0x07FF) + (myCurrentBank << 11)];
|
||||||
|
else if(address < 0x400) // Read from write port gives undefined values
|
||||||
|
return myRandGenerator.next();
|
||||||
else
|
else
|
||||||
return myRam[(address & 0x03FF) + ((myCurrentBank - 256) << 10)];
|
return myRam[(address & 0x03FF) + ((myCurrentBank - 256) << 10)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "M6532.hxx"
|
#include "M6532.hxx"
|
||||||
#include "TIA.hxx"
|
#include "TIA.hxx"
|
||||||
|
@ -46,9 +45,8 @@ Cartridge4A50::~Cartridge4A50()
|
||||||
void Cartridge4A50::reset()
|
void Cartridge4A50::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 32768; ++i)
|
for(uInt32 i = 0; i < 32768; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
mySliceLow = mySliceMiddle = mySliceHigh = 0;
|
mySliceLow = mySliceMiddle = mySliceHigh = 0;
|
||||||
myIsRomLow = myIsRomMiddle = myIsRomHigh = true;
|
myIsRomLow = myIsRomMiddle = myIsRomHigh = true;
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "M6502.hxx"
|
#include "M6502.hxx"
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartAR.hxx"
|
#include "CartAR.hxx"
|
||||||
|
|
||||||
|
@ -53,9 +52,8 @@ CartridgeAR::~CartridgeAR()
|
||||||
void CartridgeAR::reset()
|
void CartridgeAR::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 6 * 1024; ++i)
|
for(uInt32 i = 0; i < 6 * 1024; ++i)
|
||||||
myImage[i] = random.next();
|
myImage[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Initialize SC BIOS ROM
|
// Initialize SC BIOS ROM
|
||||||
initializeROM();
|
initializeROM();
|
||||||
|
@ -302,8 +300,7 @@ void CartridgeAR::initializeROM()
|
||||||
|
|
||||||
// The accumulator should contain a random value after exiting the
|
// The accumulator should contain a random value after exiting the
|
||||||
// SC BIOS code - a value placed in offset 281 will be stored in A
|
// SC BIOS code - a value placed in offset 281 will be stored in A
|
||||||
class Random random;
|
ourDummyROMCode[281] = myRandGenerator.next();
|
||||||
ourDummyROMCode[281] = random.next();
|
|
||||||
|
|
||||||
// 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
|
||||||
for(uInt32 i = 0; i < 2048; ++i)
|
for(uInt32 i = 0; i < 2048; ++i)
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartCV.hxx"
|
#include "CartCV.hxx"
|
||||||
|
|
||||||
|
@ -52,9 +51,8 @@ void CartridgeCV::reset()
|
||||||
memcpy(myImage, myROM, 2048);
|
memcpy(myImage, myROM, 2048);
|
||||||
|
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 1024; ++i)
|
for(uInt32 i = 0; i < 1024; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
}
|
}
|
||||||
else if(mySize == 4096)
|
else if(mySize == 4096)
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartE7.hxx"
|
#include "CartE7.hxx"
|
||||||
|
|
||||||
|
@ -46,9 +45,8 @@ CartridgeE7::~CartridgeE7()
|
||||||
void CartridgeE7::reset()
|
void CartridgeE7::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 2048; ++i)
|
for(uInt32 i = 0; i < 2048; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Install some default banks for the RAM and first segment
|
// Install some default banks for the RAM and first segment
|
||||||
bankRAM(0);
|
bankRAM(0);
|
||||||
|
@ -109,7 +107,9 @@ uInt8 CartridgeE7::peek(uInt16 address)
|
||||||
// NOTE: The following does not handle reading from RAM, however,
|
// NOTE: The following does not handle reading from RAM, however,
|
||||||
// this function should never be called for RAM because of the
|
// this function should never be called for RAM because of the
|
||||||
// way page accessing has been setup
|
// way page accessing has been setup
|
||||||
// TODO - determine what really happens when you read from the write port
|
if((bank() == 7) && (address < 0x400))
|
||||||
|
return myRandGenerator.next(); // Read from write port gives undefined values
|
||||||
|
else
|
||||||
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
|
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,6 +136,8 @@ void CartridgeE7::poke(uInt16 address, uInt8)
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void CartridgeE7::bankRAM(uInt16 bank)
|
void CartridgeE7::bankRAM(uInt16 bank)
|
||||||
{
|
{
|
||||||
|
if(myBankLocked) return;
|
||||||
|
|
||||||
// Remember what bank we're in
|
// Remember what bank we're in
|
||||||
myCurrentRAM = bank;
|
myCurrentRAM = bank;
|
||||||
uInt16 offset = bank << 8;
|
uInt16 offset = bank << 8;
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartEFSC.hxx"
|
#include "CartEFSC.hxx"
|
||||||
|
|
||||||
|
@ -42,9 +41,8 @@ CartridgeEFSC::~CartridgeEFSC()
|
||||||
void CartridgeEFSC::reset()
|
void CartridgeEFSC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 128; ++i)
|
for(uInt32 i = 0; i < 128; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Upon reset we switch to bank 1
|
// Upon reset we switch to bank 1
|
||||||
bank(1);
|
bank(1);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartF4SC.hxx"
|
#include "CartF4SC.hxx"
|
||||||
|
|
||||||
|
@ -42,9 +41,8 @@ CartridgeF4SC::~CartridgeF4SC()
|
||||||
void CartridgeF4SC::reset()
|
void CartridgeF4SC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 128; ++i)
|
for(uInt32 i = 0; i < 128; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Upon reset we switch to bank 0
|
// Upon reset we switch to bank 0
|
||||||
bank(0);
|
bank(0);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartF6SC.hxx"
|
#include "CartF6SC.hxx"
|
||||||
|
|
||||||
|
@ -42,9 +41,8 @@ CartridgeF6SC::~CartridgeF6SC()
|
||||||
void CartridgeF6SC::reset()
|
void CartridgeF6SC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 128; ++i)
|
for(uInt32 i = 0; i < 128; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Upon reset we switch to bank 0
|
// Upon reset we switch to bank 0
|
||||||
bank(0);
|
bank(0);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartF8SC.hxx"
|
#include "CartF8SC.hxx"
|
||||||
|
|
||||||
|
@ -42,9 +41,8 @@ CartridgeF8SC::~CartridgeF8SC()
|
||||||
void CartridgeF8SC::reset()
|
void CartridgeF8SC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 128; ++i)
|
for(uInt32 i = 0; i < 128; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Upon reset we switch to bank 1
|
// Upon reset we switch to bank 1
|
||||||
bank(1);
|
bank(1);
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartFASC.hxx"
|
#include "CartFASC.hxx"
|
||||||
|
|
||||||
|
@ -42,9 +41,8 @@ CartridgeFASC::~CartridgeFASC()
|
||||||
void CartridgeFASC::reset()
|
void CartridgeFASC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 256; ++i)
|
for(uInt32 i = 0; i < 256; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
|
|
||||||
// Upon reset we switch to bank 2
|
// Upon reset we switch to bank 2
|
||||||
bank(2);
|
bank(2);
|
||||||
|
@ -124,8 +122,12 @@ uInt8 CartridgeFASC::peek(uInt16 address)
|
||||||
// Thanks to Kroko of AtariAge for this advice and code idea
|
// Thanks to Kroko of AtariAge for this advice and code idea
|
||||||
if(address < 0x0100) // Write port is at 0xF000 - 0xF100 (256 bytes)
|
if(address < 0x0100) // Write port is at 0xF000 - 0xF100 (256 bytes)
|
||||||
{
|
{
|
||||||
if(myBankLocked) return 0;
|
if(!myBankLocked)
|
||||||
else return myRAM[address] = 0;
|
{
|
||||||
|
return myRAM[address] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "Random.hxx"
|
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
#include "CartMC.hxx"
|
#include "CartMC.hxx"
|
||||||
|
|
||||||
|
@ -46,9 +45,8 @@ CartridgeMC::~CartridgeMC()
|
||||||
void CartridgeMC::reset()
|
void CartridgeMC::reset()
|
||||||
{
|
{
|
||||||
// Initialize RAM with random values
|
// Initialize RAM with random values
|
||||||
class Random random;
|
|
||||||
for(uInt32 i = 0; i < 32768; ++i)
|
for(uInt32 i = 0; i < 32768; ++i)
|
||||||
myRAM[i] = random.next();
|
myRAM[i] = myRandGenerator.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "Console.hxx"
|
#include "Console.hxx"
|
||||||
#include "Random.hxx"
|
|
||||||
#include "Switches.hxx"
|
#include "Switches.hxx"
|
||||||
#include "System.hxx"
|
#include "System.hxx"
|
||||||
|
|
||||||
|
@ -41,15 +40,13 @@ M6532::~M6532()
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void M6532::reset()
|
void M6532::reset()
|
||||||
{
|
{
|
||||||
class Random random;
|
|
||||||
|
|
||||||
// Randomize the 128 bytes of memory
|
// Randomize the 128 bytes of memory
|
||||||
for(uInt32 t = 0; t < 128; ++t)
|
for(uInt32 t = 0; t < 128; ++t)
|
||||||
myRAM[t] = random.next();
|
myRAM[t] = myRandGenerator.next();
|
||||||
|
|
||||||
// The timer absolutely cannot be initialized to zero; some games will
|
// The timer absolutely cannot be initialized to zero; some games will
|
||||||
// loop or hang (notably Solaris and H.E.R.O.)
|
// loop or hang (notably Solaris and H.E.R.O.)
|
||||||
myTimer = (0xff - (random.next() % 0xfe)) << 10;
|
myTimer = (0xff - (myRandGenerator.next() % 0xfe)) << 10;
|
||||||
myIntervalShift = 10;
|
myIntervalShift = 10;
|
||||||
myCyclesWhenTimerSet = 0;
|
myCyclesWhenTimerSet = 0;
|
||||||
myInterruptEnabled = false;
|
myInterruptEnabled = false;
|
||||||
|
|
|
@ -17,11 +17,18 @@
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#include "OSystem.hxx"
|
#include "OSystem.hxx"
|
||||||
#include "Random.hxx"
|
#include "Random.hxx"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Random::Random()
|
Random::Random()
|
||||||
|
{
|
||||||
|
initSeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Random::initSeed()
|
||||||
{
|
{
|
||||||
if(ourSystem)
|
if(ourSystem)
|
||||||
myValue = ourSystem->getTicks();
|
myValue = ourSystem->getTicks();
|
||||||
|
|
|
@ -40,6 +40,12 @@ class Random
|
||||||
Random();
|
Random();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
Re-initialize the random number generator with a new seed,
|
||||||
|
to generate a different set of random numbers.
|
||||||
|
*/
|
||||||
|
void initSeed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Answer the next random number from the random number generator
|
Answer the next random number from the random number generator
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
Device::Device()
|
Device::Device()
|
||||||
: mySystem(0)
|
: mySystem(0)
|
||||||
{
|
{
|
||||||
|
myRandGenerator.initSeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -35,3 +36,5 @@ void Device::systemCyclesReset()
|
||||||
// By default I do nothing when my system resets its cycle counter
|
// By default I do nothing when my system resets its cycle counter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
Random Device::myRandGenerator;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
|
#include "Random.hxx"
|
||||||
#include "Serializable.hxx"
|
#include "Serializable.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
@ -107,6 +108,10 @@ class Device : public Serializable
|
||||||
protected:
|
protected:
|
||||||
/// Pointer to the system the device is installed in or the null pointer
|
/// Pointer to the system the device is installed in or the null pointer
|
||||||
System* mySystem;
|
System* mySystem;
|
||||||
|
|
||||||
|
/// Many devices need a source of random numbers, usually for emulating
|
||||||
|
/// unknown/undefined behaviour
|
||||||
|
static class Random myRandGenerator;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue