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 <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "TIA.hxx"
|
||||
#include "Cart3E.hxx"
|
||||
|
@ -50,9 +49,8 @@ Cartridge3E::~Cartridge3E()
|
|||
void Cartridge3E::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
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
|
||||
bank(0);
|
||||
|
@ -97,13 +95,14 @@ void Cartridge3E::install(System& system)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Cartridge3E::peek(uInt16 address)
|
||||
{
|
||||
// TODO - determine what really happens when you read from the write port
|
||||
address &= 0x0FFF;
|
||||
|
||||
if(address < 0x0800)
|
||||
{
|
||||
if(myCurrentBank < 256)
|
||||
return myImage[(address & 0x07FF) + (myCurrentBank << 11)];
|
||||
else if(address < 0x400) // Read from write port gives undefined values
|
||||
return myRandGenerator.next();
|
||||
else
|
||||
return myRam[(address & 0x03FF) + ((myCurrentBank - 256) << 10)];
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "M6532.hxx"
|
||||
#include "TIA.hxx"
|
||||
|
@ -46,9 +45,8 @@ Cartridge4A50::~Cartridge4A50()
|
|||
void Cartridge4A50::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 32768; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
mySliceLow = mySliceMiddle = mySliceHigh = 0;
|
||||
myIsRomLow = myIsRomMiddle = myIsRomHigh = true;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "M6502.hxx"
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartAR.hxx"
|
||||
|
||||
|
@ -53,9 +52,8 @@ CartridgeAR::~CartridgeAR()
|
|||
void CartridgeAR::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 6 * 1024; ++i)
|
||||
myImage[i] = random.next();
|
||||
myImage[i] = myRandGenerator.next();
|
||||
|
||||
// Initialize SC BIOS ROM
|
||||
initializeROM();
|
||||
|
@ -302,8 +300,7 @@ void CartridgeAR::initializeROM()
|
|||
|
||||
// The accumulator should contain a random value after exiting the
|
||||
// SC BIOS code - a value placed in offset 281 will be stored in A
|
||||
class Random random;
|
||||
ourDummyROMCode[281] = random.next();
|
||||
ourDummyROMCode[281] = myRandGenerator.next();
|
||||
|
||||
// Initialize ROM with illegal 6502 opcode that causes a real 6502 to jam
|
||||
for(uInt32 i = 0; i < 2048; ++i)
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartCV.hxx"
|
||||
|
||||
|
@ -52,9 +51,8 @@ void CartridgeCV::reset()
|
|||
memcpy(myImage, myROM, 2048);
|
||||
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 1024; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
}
|
||||
else if(mySize == 4096)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartE7.hxx"
|
||||
|
||||
|
@ -46,9 +45,8 @@ CartridgeE7::~CartridgeE7()
|
|||
void CartridgeE7::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
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
|
||||
bankRAM(0);
|
||||
|
@ -109,8 +107,10 @@ uInt8 CartridgeE7::peek(uInt16 address)
|
|||
// NOTE: The following does not handle reading from RAM, however,
|
||||
// this function should never be called for RAM because of the
|
||||
// way page accessing has been setup
|
||||
// TODO - determine what really happens when you read from the write port
|
||||
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
|
||||
if((bank() == 7) && (address < 0x400))
|
||||
return myRandGenerator.next(); // Read from write port gives undefined values
|
||||
else
|
||||
return myImage[(myCurrentSlice[address >> 11] << 11) + (address & 0x07FF)];
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -136,6 +136,8 @@ void CartridgeE7::poke(uInt16 address, uInt8)
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CartridgeE7::bankRAM(uInt16 bank)
|
||||
{
|
||||
if(myBankLocked) return;
|
||||
|
||||
// Remember what bank we're in
|
||||
myCurrentRAM = bank;
|
||||
uInt16 offset = bank << 8;
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartEFSC.hxx"
|
||||
|
||||
|
@ -42,9 +41,8 @@ CartridgeEFSC::~CartridgeEFSC()
|
|||
void CartridgeEFSC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 128; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
// Upon reset we switch to bank 1
|
||||
bank(1);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartF4SC.hxx"
|
||||
|
||||
|
@ -42,9 +41,8 @@ CartridgeF4SC::~CartridgeF4SC()
|
|||
void CartridgeF4SC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 128; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
// Upon reset we switch to bank 0
|
||||
bank(0);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartF6SC.hxx"
|
||||
|
||||
|
@ -42,9 +41,8 @@ CartridgeF6SC::~CartridgeF6SC()
|
|||
void CartridgeF6SC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 128; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
// Upon reset we switch to bank 0
|
||||
bank(0);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartF8SC.hxx"
|
||||
|
||||
|
@ -42,9 +41,8 @@ CartridgeF8SC::~CartridgeF8SC()
|
|||
void CartridgeF8SC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 128; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
// Upon reset we switch to bank 1
|
||||
bank(1);
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartFASC.hxx"
|
||||
|
||||
|
@ -42,9 +41,8 @@ CartridgeFASC::~CartridgeFASC()
|
|||
void CartridgeFASC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 256; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
|
||||
// Upon reset we switch to bank 2
|
||||
bank(2);
|
||||
|
@ -124,8 +122,12 @@ uInt8 CartridgeFASC::peek(uInt16 address)
|
|||
// Thanks to Kroko of AtariAge for this advice and code idea
|
||||
if(address < 0x0100) // Write port is at 0xF000 - 0xF100 (256 bytes)
|
||||
{
|
||||
if(myBankLocked) return 0;
|
||||
else return myRAM[address] = 0;
|
||||
if(!myBankLocked)
|
||||
{
|
||||
return myRAM[address] = 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "System.hxx"
|
||||
#include "CartMC.hxx"
|
||||
|
||||
|
@ -46,9 +45,8 @@ CartridgeMC::~CartridgeMC()
|
|||
void CartridgeMC::reset()
|
||||
{
|
||||
// Initialize RAM with random values
|
||||
class Random random;
|
||||
for(uInt32 i = 0; i < 32768; ++i)
|
||||
myRAM[i] = random.next();
|
||||
myRAM[i] = myRandGenerator.next();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "Console.hxx"
|
||||
#include "Random.hxx"
|
||||
#include "Switches.hxx"
|
||||
#include "System.hxx"
|
||||
|
||||
|
@ -41,15 +40,13 @@ M6532::~M6532()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void M6532::reset()
|
||||
{
|
||||
class Random random;
|
||||
|
||||
// Randomize the 128 bytes of memory
|
||||
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
|
||||
// loop or hang (notably Solaris and H.E.R.O.)
|
||||
myTimer = (0xff - (random.next() % 0xfe)) << 10;
|
||||
myTimer = (0xff - (myRandGenerator.next() % 0xfe)) << 10;
|
||||
myIntervalShift = 10;
|
||||
myCyclesWhenTimerSet = 0;
|
||||
myInterruptEnabled = false;
|
||||
|
|
|
@ -17,18 +17,25 @@
|
|||
//============================================================================
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "OSystem.hxx"
|
||||
#include "Random.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Random::Random()
|
||||
{
|
||||
initSeed();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Random::initSeed()
|
||||
{
|
||||
if(ourSystem)
|
||||
myValue = ourSystem->getTicks();
|
||||
else
|
||||
myValue = (uInt32)time(0);
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt32 Random::next()
|
||||
{
|
||||
|
|
|
@ -40,6 +40,12 @@ class Random
|
|||
Random();
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
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
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Random Device::myRandGenerator;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
class System;
|
||||
|
||||
#include "Random.hxx"
|
||||
#include "Serializable.hxx"
|
||||
#include "bspf.hxx"
|
||||
|
||||
|
@ -107,6 +108,10 @@ class Device : public Serializable
|
|||
protected:
|
||||
/// Pointer to the system the device is installed in or the null pointer
|
||||
System* mySystem;
|
||||
|
||||
/// Many devices need a source of random numbers, usually for emulating
|
||||
/// unknown/undefined behaviour
|
||||
static class Random myRandGenerator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue