mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 08:49:37 +00:00
Sketched out just enough classes to get through the get-contents-into-memory step of static analysis.
This commit is contained in:
parent
24938326ac
commit
d9f0065154
@ -26,6 +26,8 @@
|
|||||||
4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; };
|
4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; };
|
||||||
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; };
|
4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; };
|
||||||
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
|
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; };
|
||||||
|
4B37EE7F1D734596006A09A4 /* A26.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE7D1D734596006A09A4 /* A26.cpp */; };
|
||||||
|
4B37EE821D7345A6006A09A4 /* AcornROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE801D7345A6006A09A4 /* AcornROM.cpp */; };
|
||||||
4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; };
|
4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; };
|
||||||
4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; };
|
4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; };
|
||||||
4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */; };
|
4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */; };
|
||||||
@ -406,6 +408,10 @@
|
|||||||
4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = "<group>"; };
|
4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = "<group>"; };
|
||||||
4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = "<group>"; };
|
4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = "<group>"; };
|
||||||
4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = "<group>"; };
|
4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = "<group>"; };
|
||||||
|
4B37EE7D1D734596006A09A4 /* A26.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = A26.cpp; sourceTree = "<group>"; };
|
||||||
|
4B37EE7E1D734596006A09A4 /* A26.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = A26.hpp; sourceTree = "<group>"; };
|
||||||
|
4B37EE801D7345A6006A09A4 /* AcornROM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AcornROM.cpp; sourceTree = "<group>"; };
|
||||||
|
4B37EE811D7345A6006A09A4 /* AcornROM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AcornROM.hpp; sourceTree = "<group>"; };
|
||||||
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = "<group>"; };
|
4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = "<group>"; };
|
||||||
4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = "<group>"; };
|
4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = "<group>"; };
|
||||||
4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = "<group>"; };
|
4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = "<group>"; };
|
||||||
@ -1545,6 +1551,10 @@
|
|||||||
children = (
|
children = (
|
||||||
4BEE0A6D1D72496600532C7B /* PRG.cpp */,
|
4BEE0A6D1D72496600532C7B /* PRG.cpp */,
|
||||||
4BEE0A6E1D72496600532C7B /* PRG.hpp */,
|
4BEE0A6E1D72496600532C7B /* PRG.hpp */,
|
||||||
|
4B37EE7D1D734596006A09A4 /* A26.cpp */,
|
||||||
|
4B37EE7E1D734596006A09A4 /* A26.hpp */,
|
||||||
|
4B37EE801D7345A6006A09A4 /* AcornROM.cpp */,
|
||||||
|
4B37EE811D7345A6006A09A4 /* AcornROM.hpp */,
|
||||||
);
|
);
|
||||||
path = Formats;
|
path = Formats;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1972,6 +1982,7 @@
|
|||||||
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */,
|
4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */,
|
||||||
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
|
4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */,
|
||||||
4BB697C71D4B558F00248BDF /* Factors.cpp in Sources */,
|
4BB697C71D4B558F00248BDF /* Factors.cpp in Sources */,
|
||||||
|
4B37EE7F1D734596006A09A4 /* A26.cpp in Sources */,
|
||||||
4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */,
|
4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */,
|
||||||
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
|
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
|
||||||
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
|
4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */,
|
||||||
@ -2010,6 +2021,7 @@
|
|||||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */,
|
||||||
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
|
4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */,
|
||||||
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */,
|
||||||
|
4B37EE821D7345A6006A09A4 /* AcornROM.cpp in Sources */,
|
||||||
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
|
4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "../Storage/Cartridge/Formats/A26.hpp"
|
||||||
|
#include "../Storage/Cartridge/Formats/AcornROM.hpp"
|
||||||
#include "../Storage/Cartridge/Formats/PRG.hpp"
|
#include "../Storage/Cartridge/Formats/PRG.hpp"
|
||||||
|
|
||||||
#include "../Storage/Disk/Formats/D64.hpp"
|
#include "../Storage/Disk/Formats/D64.hpp"
|
||||||
@ -26,7 +28,6 @@ enum class TargetPlatform: TargetPlatformType {
|
|||||||
Commodore = 1 << 2
|
Commodore = 1 << 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
using namespace StaticAnalyser;
|
using namespace StaticAnalyser;
|
||||||
|
|
||||||
std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
||||||
@ -59,27 +60,21 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
list.emplace_back(new Storage::class(file_name));\
|
list.emplace_back(new Storage::class(file_name));\
|
||||||
potential_platforms |= (TargetPlatformType)(platforms);\
|
potential_platforms |= (TargetPlatformType)(platforms);\
|
||||||
|
|
||||||
|
#define TryInsert(list, class, platforms) \
|
||||||
|
try {\
|
||||||
|
Insert(list, class, platforms) \
|
||||||
|
} catch(...) {}
|
||||||
|
|
||||||
#define Format(extension, list, class, platforms) \
|
#define Format(extension, list, class, platforms) \
|
||||||
if(!strcmp(lowercase_extension, extension)) \
|
if(!strcmp(lowercase_extension, extension)) \
|
||||||
{ \
|
{ \
|
||||||
try { \
|
TryInsert(list, class, platforms) \
|
||||||
list.emplace_back(new Storage::class(file_name));\
|
|
||||||
potential_platforms |= (TargetPlatformType)(platforms);\
|
|
||||||
} catch(...) {}\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// A26
|
Format("a26", cartridges, Cartridge::A26, TargetPlatform::Atari2600) // A26
|
||||||
if(!strcmp(lowercase_extension, "a26"))
|
Format("bin", cartridges, Cartridge::A26, TargetPlatform::Atari2600) // BIN
|
||||||
{
|
Format("d64", disks, Disk::D64, TargetPlatform::Commodore) // D64
|
||||||
}
|
Format("g64", disks, Disk::G64, TargetPlatform::Commodore) // G64
|
||||||
|
|
||||||
// BIN
|
|
||||||
if(!strcmp(lowercase_extension, "bin"))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Format("d64", disks, Disk::D64, TargetPlatform::Commodore) // D64
|
|
||||||
Format("g64", disks, Disk::G64, TargetPlatform::Commodore) // G64
|
|
||||||
|
|
||||||
// PRG
|
// PRG
|
||||||
if(!strcmp(lowercase_extension, "prg"))
|
if(!strcmp(lowercase_extension, "prg"))
|
||||||
@ -97,12 +92,9 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ROM
|
// ROM
|
||||||
if(!strcmp(lowercase_extension, "rom"))
|
Format("rom", cartridges, Cartridge::AcornROM, TargetPlatform::Acorn) // ROM
|
||||||
{
|
Format("tap", tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP
|
||||||
}
|
Format("uef", tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape)
|
||||||
|
|
||||||
Format("tap", tapes, Tape::CommodoreTAP, TargetPlatform::Commodore) // TAP
|
|
||||||
Format("uef", tapes, Tape::UEF, TargetPlatform::Acorn) // UEF (tape)
|
|
||||||
|
|
||||||
#undef Format
|
#undef Format
|
||||||
#undef Insert
|
#undef Insert
|
||||||
@ -110,8 +102,6 @@ std::list<Target> StaticAnalyser::GetTargets(const char *file_name)
|
|||||||
// Hand off to platform-specific determination of whether these things are actually compatible and,
|
// Hand off to platform-specific determination of whether these things are actually compatible and,
|
||||||
// if so, how to load them. (TODO)
|
// if so, how to load them. (TODO)
|
||||||
|
|
||||||
printf("Lowercase extension: %s", lowercase_extension);
|
|
||||||
|
|
||||||
free(lowercase_extension);
|
free(lowercase_extension);
|
||||||
return targets;
|
return targets;
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,16 @@
|
|||||||
|
|
||||||
namespace StaticAnalyser {
|
namespace StaticAnalyser {
|
||||||
|
|
||||||
enum Machine {
|
/*!
|
||||||
Atari2600,
|
A list of disks, tapes and cartridges plus information about the machine to which to attach them and its configuration,
|
||||||
Electron,
|
and instructions on how to launch the software attached, plus a measure of confidence in this target's correctness.
|
||||||
Vic20
|
*/
|
||||||
};
|
|
||||||
|
|
||||||
struct Target {
|
struct Target {
|
||||||
Machine machine;
|
enum {
|
||||||
|
Atari2600,
|
||||||
|
Electron,
|
||||||
|
Vic20
|
||||||
|
} machine;
|
||||||
float probability;
|
float probability;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
@ -59,6 +61,11 @@ struct Target {
|
|||||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> cartridges;
|
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> cartridges;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Attempts, through any available means, to return a list of potential targets for the file with the given name.
|
||||||
|
|
||||||
|
@returns The list of potential targets, sorted from most to least probable.
|
||||||
|
*/
|
||||||
std::list<Target> GetTargets(const char *file_name);
|
std::list<Target> GetTargets(const char *file_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,10 +9,53 @@
|
|||||||
#ifndef Storage_Cartridge_hpp
|
#ifndef Storage_Cartridge_hpp
|
||||||
#define Storage_Cartridge_hpp
|
#define Storage_Cartridge_hpp
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
namespace Cartridge {
|
namespace Cartridge {
|
||||||
|
|
||||||
class Cartridge {};
|
/*!
|
||||||
|
Provides a base class for cartridges; the bus provided to cartridges and therefore
|
||||||
|
the interface they support is extremely machine-dependent so unlike disks and tapes,
|
||||||
|
no model is imposed; this class seeks merely to be a base class for fully-descriptive
|
||||||
|
summaries of the contents of emulator files that themselves describe cartridges.
|
||||||
|
|
||||||
|
Consumers will almost certainly seek to dynamic_cast to something more appropriate,
|
||||||
|
however some cartridge container formats have no exposition beyond the ROM dump,
|
||||||
|
making the base class 100% descriptive.
|
||||||
|
*/
|
||||||
|
class Cartridge {
|
||||||
|
public:
|
||||||
|
struct Segment {
|
||||||
|
Segment(int start_address, int end_address, std::vector<uint8_t> data) :
|
||||||
|
start_address(start_address), end_address(end_address), data(std::move(data)) {}
|
||||||
|
|
||||||
|
/// Indicates that an address is unknown.
|
||||||
|
static const int UnknownAddress;
|
||||||
|
|
||||||
|
/// The initial CPU-exposed starting address for this segment; may be @c UnknownAddress.
|
||||||
|
int start_address;
|
||||||
|
/*!
|
||||||
|
The initial CPU-exposed ending address for this segment; may be @c UnknownAddress. Not necessarily equal
|
||||||
|
to start_address + data_length due to potential paging.
|
||||||
|
*/
|
||||||
|
int end_address;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
The data contents for this segment. If @c start_address and @c end_address are suppled then
|
||||||
|
the first end_address - start_address bytes will be those initially visible. The size will
|
||||||
|
not necessarily be the same as @c end_address - @c start_address due to potential paging.
|
||||||
|
*/
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::list<Segment> &get_segments() { return _segments; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::list<Segment> _segments;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
Storage/Cartridge/Formats/A26.cpp
Normal file
15
Storage/Cartridge/Formats/A26.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// A26.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/08/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "A26.hpp"
|
||||||
|
|
||||||
|
using namespace Storage::Cartridge;
|
||||||
|
|
||||||
|
A26::A26(const char *file_name)
|
||||||
|
{
|
||||||
|
}
|
30
Storage/Cartridge/Formats/A26.hpp
Normal file
30
Storage/Cartridge/Formats/A26.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// A26.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/08/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Storage_Cartridge_A26_hpp
|
||||||
|
#define Storage_Cartridge_A26_hpp
|
||||||
|
|
||||||
|
#include "../Cartridge.hpp"
|
||||||
|
|
||||||
|
namespace Storage {
|
||||||
|
namespace Cartridge {
|
||||||
|
|
||||||
|
class A26 : public Cartridge {
|
||||||
|
public:
|
||||||
|
A26(const char *file_name);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ErrorNotAcornROM
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* A26_hpp */
|
15
Storage/Cartridge/Formats/AcornROM.cpp
Normal file
15
Storage/Cartridge/Formats/AcornROM.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// AcornROM.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/08/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AcornROM.hpp"
|
||||||
|
|
||||||
|
using namespace Storage::Cartridge;
|
||||||
|
|
||||||
|
AcornROM::AcornROM(const char *file_name)
|
||||||
|
{
|
||||||
|
}
|
29
Storage/Cartridge/Formats/AcornROM.hpp
Normal file
29
Storage/Cartridge/Formats/AcornROM.hpp
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// AcornROM.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 28/08/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Storage_Cartridge_AcornROM_hpp
|
||||||
|
#define Storage_Cartridge_AcornROM_hpp
|
||||||
|
|
||||||
|
#include "../Cartridge.hpp"
|
||||||
|
|
||||||
|
namespace Storage {
|
||||||
|
namespace Cartridge {
|
||||||
|
|
||||||
|
class AcornROM : public Cartridge {
|
||||||
|
public:
|
||||||
|
AcornROM(const char *file_name);
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ErrorNotAcornROM
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* AcornROM_hpp */
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
using namespace Storage::Cartridge;
|
using namespace Storage::Cartridge;
|
||||||
|
|
||||||
PRG::PRG(const char *file_name) : _contents(nullptr)
|
PRG::PRG(const char *file_name)
|
||||||
{
|
{
|
||||||
struct stat file_stats;
|
struct stat file_stats;
|
||||||
stat(file_name, &file_stats);
|
stat(file_name, &file_stats);
|
||||||
@ -32,8 +32,9 @@ PRG::PRG(const char *file_name) : _contents(nullptr)
|
|||||||
int loading_address = fgetc(file);
|
int loading_address = fgetc(file);
|
||||||
loading_address |= fgetc(file) << 8;
|
loading_address |= fgetc(file) << 8;
|
||||||
|
|
||||||
_contents = new uint8_t[file_stats.st_size - 2];
|
size_t data_length = (size_t)file_stats.st_size - 2;
|
||||||
fread(_contents, 1, (size_t)(file_stats.st_size - 2), file);
|
std::vector<uint8_t> contents(data_length);
|
||||||
|
fread(&contents[0], 1, (size_t)(data_length), file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
// accept only files intended to load at 0xa000
|
// accept only files intended to load at 0xa000
|
||||||
@ -42,15 +43,12 @@ PRG::PRG(const char *file_name) : _contents(nullptr)
|
|||||||
|
|
||||||
// also accept only cartridges with the proper signature
|
// also accept only cartridges with the proper signature
|
||||||
if(
|
if(
|
||||||
_contents[4] != 0x41 ||
|
contents[4] != 0x41 ||
|
||||||
_contents[5] != 0x30 ||
|
contents[5] != 0x30 ||
|
||||||
_contents[6] != 0xc3 ||
|
contents[6] != 0xc3 ||
|
||||||
_contents[7] != 0xc2 ||
|
contents[7] != 0xc2 ||
|
||||||
_contents[8] != 0xcd)
|
contents[8] != 0xcd)
|
||||||
throw ErrorNotROM;
|
throw ErrorNotROM;
|
||||||
}
|
|
||||||
|
|
||||||
PRG::~PRG()
|
_segments.emplace_back(0xa000, 0xa000 + data_length, std::move(contents));
|
||||||
{
|
|
||||||
delete[] _contents;
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#ifndef Storage_Cartridge_PRG_hpp
|
#ifndef Storage_Cartridge_PRG_hpp
|
||||||
#define Storage_Cartridge_PRG_hpp
|
#define Storage_Cartridge_PRG_hpp
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "../Cartridge.hpp"
|
#include "../Cartridge.hpp"
|
||||||
|
|
||||||
namespace Storage {
|
namespace Storage {
|
||||||
@ -18,15 +17,10 @@ namespace Cartridge {
|
|||||||
class PRG : public Cartridge {
|
class PRG : public Cartridge {
|
||||||
public:
|
public:
|
||||||
PRG(const char *file_name);
|
PRG(const char *file_name);
|
||||||
~PRG();
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ErrorNotROM
|
ErrorNotROM
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t *_contents;
|
|
||||||
uint16_t _size;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user