1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-18 04:28:57 +00:00

Merge pull request #696 from TomHarte/make_shared

Makes a variety of minor style improvements
This commit is contained in:
Thomas Harte 2019-12-22 00:27:57 -05:00 committed by GitHub
commit 66d9b60b98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
71 changed files with 262 additions and 351 deletions

View File

@ -18,7 +18,7 @@ using namespace Analyser::Static::Acorn;
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) { std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
// c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format // c.f. http://beebwiki.mdfs.net/Acorn_DFS_disc_format
std::unique_ptr<Catalogue> catalogue(new Catalogue); auto catalogue = std::make_unique<Catalogue>();
Storage::Encodings::MFM::Parser parser(false, disk); Storage::Encodings::MFM::Parser parser(false, disk);
Storage::Encodings::MFM::Sector *names = parser.get_sector(0, 0, 0); Storage::Encodings::MFM::Sector *names = parser.get_sector(0, 0, 0);
@ -75,7 +75,7 @@ std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetDFSCatalogue(const std::s
return catalogue; return catalogue;
} }
std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetADFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) { std::unique_ptr<Catalogue> Analyser::Static::Acorn::GetADFSCatalogue(const std::shared_ptr<Storage::Disk::Disk> &disk) {
std::unique_ptr<Catalogue> catalogue(new Catalogue); auto catalogue = std::make_unique<Catalogue>();
Storage::Encodings::MFM::Parser parser(true, disk); Storage::Encodings::MFM::Parser parser(true, disk);
Storage::Encodings::MFM::Sector *free_space_map_second_half = parser.get_sector(0, 0, 1); Storage::Encodings::MFM::Sector *free_space_map_second_half = parser.get_sector(0, 0, 1);

View File

@ -58,7 +58,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
} }
Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::Acorn::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::Electron; target->machine = Machine::Electron;
target->confidence = 0.5; // TODO: a proper estimation target->confidence = 0.5; // TODO: a proper estimation
target->has_dfs = false; target->has_dfs = false;

View File

@ -16,7 +16,7 @@
using namespace Analyser::Static::Acorn; using namespace Analyser::Static::Acorn;
static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::Tape::Tape> &tape, Storage::Tape::Acorn::Parser &parser) { static std::unique_ptr<File::Chunk> GetNextChunk(const std::shared_ptr<Storage::Tape::Tape> &tape, Storage::Tape::Acorn::Parser &parser) {
std::unique_ptr<File::Chunk> new_chunk(new File::Chunk); auto new_chunk = std::make_unique<File::Chunk>();
int shift_register = 0; int shift_register = 0;
// TODO: move this into the parser // TODO: move this into the parser
@ -90,7 +90,7 @@ static std::unique_ptr<File> GetNextFile(std::deque<File::Chunk> &chunks) {
if(!chunks.size()) return nullptr; if(!chunks.size()) return nullptr;
// accumulate chunks for as long as block number is sequential and the end-of-file bit isn't set // accumulate chunks for as long as block number is sequential and the end-of-file bit isn't set
std::unique_ptr<File> file(new File); auto file = std::make_unique<File>();
uint16_t block_number = 0; uint16_t block_number = 0;

View File

@ -181,7 +181,7 @@ static bool CheckBootSector(const std::shared_ptr<Storage::Disk::Disk> &disk, co
Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::AmstradCPC::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
TargetList destination; TargetList destination;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::AmstradCPC; target->machine = Machine::AmstradCPC;
target->confidence = 0.5; target->confidence = 0.5;

View File

@ -10,7 +10,7 @@
#include "Target.hpp" #include "Target.hpp"
Analyser::Static::TargetList Analyser::Static::AppleII::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::AppleII::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
auto target = std::unique_ptr<Target>(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::AppleII; target->machine = Machine::AppleII;
target->media = media; target->media = media;

View File

@ -183,7 +183,7 @@ static void DeterminePagingForCartridge(Target &target, const Storage::Cartridge
Analyser::Static::TargetList Analyser::Static::Atari2600::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::Atari2600::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
// TODO: sanity checking; is this image really for an Atari 2600? // TODO: sanity checking; is this image really for an Atari 2600?
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::Atari2600; target->machine = Machine::Atari2600;
target->confidence = 0.5; target->confidence = 0.5;
target->media.cartridges = media.cartridges; target->media.cartridges = media.cartridges;

View File

@ -54,7 +54,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
Analyser::Static::TargetList Analyser::Static::Coleco::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::Coleco::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
TargetList targets; TargetList targets;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::ColecoVision; target->machine = Machine::ColecoVision;
target->confidence = 1.0f - 1.0f / 32768.0f; target->confidence = 1.0f - 1.0f / 32768.0f;
target->media.cartridges = ColecoCartridgesFrom(media.cartridges); target->media.cartridges = ColecoCartridgesFrom(media.cartridges);

View File

@ -125,7 +125,7 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
} }
std::shared_ptr<Sector> get_next_sector() { std::shared_ptr<Sector> get_next_sector() {
std::shared_ptr<Sector> sector(new Sector); auto sector = std::make_shared<Sector>();
const int max_index_count = index_count_ + 2; const int max_index_count = index_count_ + 2;
while(index_count_ < max_index_count) { while(index_count_ < max_index_count) {

View File

@ -44,7 +44,7 @@ static std::vector<std::shared_ptr<Storage::Cartridge::Cartridge>>
Analyser::Static::TargetList Analyser::Static::Commodore::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::Commodore::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
TargetList destination; TargetList destination;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::Vic20; // TODO: machine estimation target->machine = Machine::Vic20; // TODO: machine estimation
target->confidence = 0.5; // TODO: a proper estimation target->confidence = 0.5; // TODO: a proper estimation

View File

@ -34,7 +34,7 @@ static std::unique_ptr<Analyser::Static::Target> CartridgeTarget(
output_segments.emplace_back(start_address, segment.data); output_segments.emplace_back(start_address, segment.data);
} }
std::unique_ptr<Analyser::Static::MSX::Target> target(new Analyser::Static::MSX::Target); auto target = std::make_unique<Analyser::Static::MSX::Target>();
target->machine = Analyser::Machine::MSX; target->machine = Analyser::Machine::MSX;
target->confidence = confidence; target->confidence = confidence;
@ -269,7 +269,7 @@ Analyser::Static::TargetList Analyser::Static::MSX::GetTargets(const Media &medi
std::move(cartridge_targets.begin(), cartridge_targets.end(), std::back_inserter(destination)); std::move(cartridge_targets.begin(), cartridge_targets.end(), std::back_inserter(destination));
// Consider building a target for disks and/or tapes. // Consider building a target for disks and/or tapes.
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
// Check tapes for loadable files. // Check tapes for loadable files.
for(auto &tape : media.tapes) { for(auto &tape : media.tapes) {

View File

@ -101,7 +101,7 @@ static bool IsMicrodisc(Storage::Encodings::MFM::Parser &parser) {
} }
Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) { Analyser::Static::TargetList Analyser::Static::Oric::GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms) {
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::Oric; target->machine = Machine::Oric;
target->confidence = 0.5; target->confidence = 0.5;

View File

@ -18,7 +18,7 @@ Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &med
return {}; return {};
TargetList targets; TargetList targets;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Machine::MasterSystem; target->machine = Machine::MasterSystem;

View File

@ -100,7 +100,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
} parity_ = Parity::None; } parity_ = Parity::None;
int data_bits_ = 7, stop_bits_ = 2; int data_bits_ = 7, stop_bits_ = 2;
static const int NoValueMask = 0x100; static constexpr int NoValueMask = 0x100;
int next_transmission_ = NoValueMask; int next_transmission_ = NoValueMask;
int received_data_ = NoValueMask; int received_data_ = NoValueMask;

View File

@ -110,7 +110,7 @@ void MFP68901::write(int address, uint8_t value) {
return; return;
} }
const int timer_prescales[] = { constexpr int timer_prescales[] = {
1, 4, 10, 16, 50, 64, 100, 200 1, 4, 10, 16, 50, 64, 100, 200
}; };

View File

@ -61,7 +61,7 @@ class MFP68901: public ClockingHint::Source {
/// @returns @c true if the interrupt output is currently active; @c false otherwise.s /// @returns @c true if the interrupt output is currently active; @c false otherwise.s
bool get_interrupt_line(); bool get_interrupt_line();
static const int NoAcknowledgement = 0x100; static constexpr int NoAcknowledgement = 0x100;
/// Communicates an interrupt acknowledge cycle. /// Communicates an interrupt acknowledge cycle.
/// ///

View File

@ -292,7 +292,7 @@ void i8272::posit_event(int event_type) {
WAIT_FOR_EVENT(Event8272::CommandByte) WAIT_FOR_EVENT(Event8272::CommandByte)
SetBusy(); SetBusy();
static const std::size_t required_lengths[32] = { static constexpr std::size_t required_lengths[32] = {
0, 0, 9, 3, 2, 9, 9, 2, 0, 0, 9, 3, 2, 9, 9, 2,
1, 9, 2, 0, 9, 6, 0, 3, 1, 9, 2, 0, 9, 6, 0, 3,
0, 9, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0,

View File

@ -17,16 +17,16 @@ using namespace TI::TMS;
namespace { namespace {
const uint8_t StatusInterrupt = 0x80; constexpr uint8_t StatusInterrupt = 0x80;
const uint8_t StatusSpriteOverflow = 0x40; constexpr uint8_t StatusSpriteOverflow = 0x40;
const int StatusSpriteCollisionShift = 5; constexpr int StatusSpriteCollisionShift = 5;
const uint8_t StatusSpriteCollision = 0x20; constexpr uint8_t StatusSpriteCollision = 0x20;
// 342 internal cycles are 228/227.5ths of a line, so 341.25 cycles should be a whole // 342 internal cycles are 228/227.5ths of a line, so 341.25 cycles should be a whole
// line. Therefore multiply everything by four, but set line length to 1365 rather than 342*4 = 1368. // line. Therefore multiply everything by four, but set line length to 1365 rather than 342*4 = 1368.
const unsigned int CRTCyclesPerLine = 1365; constexpr unsigned int CRTCyclesPerLine = 1365;
const unsigned int CRTCyclesDivider = 4; constexpr unsigned int CRTCyclesDivider = 4;
struct ReverseTable { struct ReverseTable {
std::uint8_t map[256]; std::uint8_t map[256];
@ -352,8 +352,7 @@ void TMS9918::run_for(const HalfCycles cycles) {
// Output video stream. // Output video stream.
// -------------------- // --------------------
#define intersect(left, right, code) \ #define intersect(left, right, code) { \
{ \
const int start = std::max(read_pointer_.column, left); \ const int start = std::max(read_pointer_.column, left); \
const int end = std::min(end_column, right); \ const int end = std::min(end_column, right); \
if(end > start) {\ if(end > start) {\
@ -625,7 +624,7 @@ void TMS9918::set_register(int address, uint8_t value) {
uint8_t TMS9918::get_current_line() { uint8_t TMS9918::get_current_line() {
// Determine the row to return. // Determine the row to return.
static const int row_change_position = 63; // This is the proper Master System value; substitute if any other VDPs turn out to have this functionality. constexpr int row_change_position = 63; // This is the proper Master System value; substitute if any other VDPs turn out to have this functionality.
int source_row = int source_row =
(write_pointer_.column < row_change_position) (write_pointer_.column < row_change_position)
? (write_pointer_.row + mode_timing_.total_lines - 1)%mode_timing_.total_lines ? (write_pointer_.row + mode_timing_.total_lines - 1)%mode_timing_.total_lines
@ -830,8 +829,8 @@ void Base::draw_tms_character(int start, int end) {
int sprite_collision = 0; int sprite_collision = 0;
memset(&sprite_buffer[start], 0, size_t(end - start)*sizeof(sprite_buffer[0])); memset(&sprite_buffer[start], 0, size_t(end - start)*sizeof(sprite_buffer[0]));
static const uint32_t sprite_colour_selection_masks[2] = {0x00000000, 0xffffffff}; constexpr uint32_t sprite_colour_selection_masks[2] = {0x00000000, 0xffffffff};
static const int colour_masks[16] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; constexpr int colour_masks[16] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
// Draw all sprites into the sprite buffer. // Draw all sprites into the sprite buffer.
const int shifter_target = sprites_16x16_ ? 32 : 16; const int shifter_target = sprites_16x16_ ? 32 : 16;

View File

@ -72,8 +72,8 @@ AY38910::AY38910(Personality personality, Concurrency::DeferringAsyncTaskQueue &
void AY38910::set_sample_volume_range(std::int16_t range) { void AY38910::set_sample_volume_range(std::int16_t range) {
// set up volume lookup table // set up volume lookup table
const float max_volume = static_cast<float>(range) / 3.0f; // As there are three channels. const float max_volume = float(range) / 3.0f; // As there are three channels.
const float root_two = sqrtf(2.0f); constexpr float root_two = 1.414213562373095f;
for(int v = 0; v < 32; v++) { for(int v = 0; v < 32; v++) {
volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 2.0f)); volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 2.0f));
} }

View File

@ -48,7 +48,7 @@ class DiskII final:
The value returned by @c read_address if accessing that address The value returned by @c read_address if accessing that address
didn't cause the disk II to place anything onto the bus. didn't cause the disk II to place anything onto the bus.
*/ */
const int DidNotLoad = -1; static constexpr int DidNotLoad = -1;
/// Advances the controller by @c cycles. /// Advances the controller by @c cycles.
void run_for(const Cycles cycles); void run_for(const Cycles cycles);

View File

@ -13,15 +13,15 @@
using namespace Apple; using namespace Apple;
namespace { namespace {
const int CA0 = 1 << 0; constexpr int CA0 = 1 << 0;
const int CA1 = 1 << 1; constexpr int CA1 = 1 << 1;
const int CA2 = 1 << 2; constexpr int CA2 = 1 << 2;
const int LSTRB = 1 << 3; constexpr int LSTRB = 1 << 3;
const int ENABLE = 1 << 4; constexpr int ENABLE = 1 << 4;
const int DRIVESEL = 1 << 5; /* This means drive select, like on the original Disk II. */ constexpr int DRIVESEL = 1 << 5; /* This means drive select, like on the original Disk II. */
const int Q6 = 1 << 6; constexpr int Q6 = 1 << 6;
const int Q7 = 1 << 7; constexpr int Q7 = 1 << 7;
const int SEL = 1 << 8; /* This is an additional input, not available on a Disk II, with a confusingly-similar name to SELECT but a distinct purpose. */ constexpr int SEL = 1 << 8; /* This is an additional input, not available on a Disk II, with a confusingly-similar name to SELECT but a distinct purpose. */
} }
IWM::IWM(int clock_rate) : IWM::IWM(int clock_rate) :

View File

@ -70,8 +70,8 @@ void AsyncTaskQueue::flush() {
#ifdef __APPLE__ #ifdef __APPLE__
dispatch_sync(serial_dispatch_queue_, ^{}); dispatch_sync(serial_dispatch_queue_, ^{});
#else #else
std::shared_ptr<std::mutex> flush_mutex(new std::mutex); auto flush_mutex = std::make_shared<std::mutex>();
std::shared_ptr<std::condition_variable> flush_condition(new std::condition_variable); auto flush_condition = std::make_shared<std::condition_variable>();
std::unique_lock<std::mutex> lock(*flush_mutex); std::unique_lock<std::mutex> lock(*flush_mutex);
enqueue([=] () { enqueue([=] () {
std::unique_lock<std::mutex> inner_lock(*flush_mutex); std::unique_lock<std::mutex> inner_lock(*flush_mutex);

View File

@ -14,7 +14,7 @@ namespace {
Appends a Boolean selection of @c selection for option @c name to @c selection_set. Appends a Boolean selection of @c selection for option @c name to @c selection_set.
*/ */
void append_bool(Configurable::SelectionSet &selection_set, const std::string &name, bool selection) { void append_bool(Configurable::SelectionSet &selection_set, const std::string &name, bool selection) {
selection_set[name] = std::unique_ptr<Configurable::Selection>(new Configurable::BooleanSelection(selection)); selection_set[name] = std::make_unique<Configurable::BooleanSelection>(selection);
} }
/*! /*!
@ -64,7 +64,7 @@ void Configurable::append_display_selection(Configurable::SelectionSet &selectio
case Display::CompositeMonochrome: string_selection = "composite-mono"; break; case Display::CompositeMonochrome: string_selection = "composite-mono"; break;
case Display::CompositeColour: string_selection = "composite"; break; case Display::CompositeColour: string_selection = "composite"; break;
} }
selection_set["display"] = std::unique_ptr<Configurable::Selection>(new Configurable::ListSelection(string_selection)); selection_set["display"] = std::make_unique<Configurable::ListSelection>(string_selection);
} }
void Configurable::append_quick_boot_selection(Configurable::SelectionSet &selection_set, bool selection) { void Configurable::append_quick_boot_selection(Configurable::SelectionSet &selection_set, bool selection) {

View File

@ -509,7 +509,7 @@ class CRTCBusHandler {
uint8_t mapped_palette_value(uint8_t colour) { uint8_t mapped_palette_value(uint8_t colour) {
#define COL(r, g, b) (r << 4) | (g << 2) | b #define COL(r, g, b) (r << 4) | (g << 2) | b
static const uint8_t mapping[32] = { constexpr uint8_t mapping[32] = {
COL(1, 1, 1), COL(1, 1, 1), COL(0, 2, 1), COL(2, 2, 1), COL(1, 1, 1), COL(1, 1, 1), COL(0, 2, 1), COL(2, 2, 1),
COL(0, 0, 1), COL(2, 0, 1), COL(0, 1, 1), COL(2, 1, 1), COL(0, 0, 1), COL(2, 0, 1), COL(0, 1, 1), COL(2, 1, 1),
COL(2, 0, 1), COL(2, 2, 1), COL(2, 2, 0), COL(2, 2, 2), COL(2, 0, 1), COL(2, 2, 1), COL(2, 2, 0), COL(2, 2, 2),

View File

@ -79,7 +79,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
void update_video() { void update_video() {
video_.run_for(cycles_since_video_update_.flush<Cycles>()); video_.run_for(cycles_since_video_update_.flush<Cycles>());
} }
static const int audio_divider = 8; static constexpr int audio_divider = 8;
void update_audio() { void update_audio() {
speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(audio_divider))); speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide(Cycles(audio_divider)));
} }
@ -329,7 +329,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
audio_toggle_(audio_queue_), audio_toggle_(audio_queue_),
speaker_(audio_toggle_) { speaker_(audio_toggle_) {
// The system's master clock rate. // The system's master clock rate.
const float master_clock = 14318180.0; constexpr float master_clock = 14318180.0;
// This is where things get slightly convoluted: establish the machine as having a clock rate // This is where things get slightly convoluted: establish the machine as having a clock rate
// equal to the number of cycles of work the 6502 will actually achieve. Which is less than // equal to the number of cycles of work the 6502 will actually achieve. Which is less than

View File

@ -203,7 +203,7 @@ class VideoBase {
std::array<uint8_t, 40> auxiliary_stream_; std::array<uint8_t, 40> auxiliary_stream_;
bool is_iie_ = false; bool is_iie_ = false;
static const int flash_length = 8406; static constexpr int flash_length = 8406;
// Describes the current text mode mapping from in-memory character index // Describes the current text mode mapping from in-memory character index
// to output character. // to output character.
@ -339,9 +339,9 @@ template <class BusHandler, bool is_iie> class Video: public VideoBase {
A frame is oriented around 65 cycles across, 262 lines down. A frame is oriented around 65 cycles across, 262 lines down.
*/ */
static const int first_sync_line = 220; // A complete guess. Information needed. constexpr int first_sync_line = 220; // A complete guess. Information needed.
static const int first_sync_column = 49; // Also a guess. constexpr int first_sync_column = 49; // Also a guess.
static const int sync_length = 4; // One of the two likely candidates. constexpr int sync_length = 4; // One of the two likely candidates.
int int_cycles = int(cycles.as_integral()); int int_cycles = int(cycles.as_integral());
while(int_cycles) { while(int_cycles) {

View File

@ -18,7 +18,7 @@
namespace Apple { namespace Apple {
namespace Macintosh { namespace Macintosh {
static const uint16_t KeypadMask = 0x100; static constexpr uint16_t KeypadMask = 0x100;
/*! /*!
Defines the keycodes that could be passed directly to a Macintosh via set_key_pressed. Defines the keycodes that could be passed directly to a Macintosh via set_key_pressed.

View File

@ -49,7 +49,7 @@
namespace { namespace {
const int CLOCK_RATE = 7833600; constexpr int CLOCK_RATE = 7833600;
} }

View File

@ -17,11 +17,11 @@
namespace Apple { namespace Apple {
namespace Macintosh { namespace Macintosh {
static const HalfCycles line_length(704); static constexpr HalfCycles line_length(704);
static const int number_of_lines = 370; static constexpr int number_of_lines = 370;
static const HalfCycles frame_length(line_length * HalfCycles(number_of_lines)); static constexpr HalfCycles frame_length(line_length * HalfCycles(number_of_lines));
static const int sync_start = 36; static constexpr int sync_start = 36;
static const int sync_end = 38; static constexpr int sync_end = 38;
/*! /*!
Models the 68000-era Macintosh video hardware, producing a 512x348 pixel image, Models the 68000-era Macintosh video hardware, producing a 512x348 pixel image,

View File

@ -13,11 +13,11 @@
using namespace Atari2600; using namespace Atari2600;
namespace { namespace {
const int cycles_per_line = 228; constexpr int cycles_per_line = 228;
const int first_pixel_cycle = 68; constexpr int first_pixel_cycle = 68;
const int sync_flag = 0x1; constexpr int sync_flag = 0x1;
const int blank_flag = 0x2; constexpr int blank_flag = 0x2;
uint8_t reverse_table[256]; uint8_t reverse_table[256];
} }

View File

@ -16,7 +16,7 @@ namespace Atari2600 {
// This should be a divisor of 38; audio counters are updated every 38 cycles, though lesser dividers // This should be a divisor of 38; audio counters are updated every 38 cycles, though lesser dividers
// will give greater resolution to changes in audio state. 1, 2 and 19 are the only divisors of 38. // will give greater resolution to changes in audio state. 1, 2 and 19 are the only divisors of 38.
const int CPUTicksPerAudioTick = 2; constexpr int CPUTicksPerAudioTick = 2;
class TIASound: public Outputs::Speaker::SampleSource { class TIASound: public Outputs::Speaker::SampleSource {
public: public:

View File

@ -47,7 +47,7 @@ std::vector<std::unique_ptr<Configurable::Option>> get_options() {
); );
} }
const int CLOCK_RATE = 8021247; constexpr int CLOCK_RATE = 8021247;
using Target = Analyser::Static::Target; using Target = Analyser::Static::Target;
class ConcreteMachine: class ConcreteMachine:

View File

@ -626,9 +626,9 @@ void Video::Shifter::output_pixels(int duration, OutputBpp bpp) {
} break; } break;
case OutputBpp::Two: { case OutputBpp::Two: {
#if TARGET_RT_BIG_ENDIAN #if TARGET_RT_BIG_ENDIAN
const int upper = 0; constexpr int upper = 0;
#else #else
const int upper = 1; constexpr int upper = 1;
#endif #endif
if(pixel_buffer_) { if(pixel_buffer_) {
while(duration--) { while(duration--) {

View File

@ -27,7 +27,7 @@
#include "../../Analyser/Dynamic/ConfidenceCounter.hpp" #include "../../Analyser/Dynamic/ConfidenceCounter.hpp"
namespace { namespace {
const int sn76489_divider = 2; constexpr int sn76489_divider = 2;
} }
namespace Coleco { namespace Coleco {

View File

@ -646,8 +646,7 @@ class ConcreteMachine:
} }
void type_string(const std::string &string) override final { void type_string(const std::string &string) override final {
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper()); Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
Utility::TypeRecipient::add_typer(string, std::move(mapper));
} }
void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final { void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final {

View File

@ -409,8 +409,7 @@ class ConcreteMachine:
} }
void type_string(const std::string &string) override final { void type_string(const std::string &string) override final {
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper()); Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
Utility::TypeRecipient::add_typer(string, std::move(mapper));
} }
KeyboardMapper *get_keyboard_mapper() override { KeyboardMapper *get_keyboard_mapper() override {

View File

@ -22,7 +22,7 @@ class SoundGenerator: public ::Outputs::Speaker::SampleSource {
void set_is_enabled(bool is_enabled); void set_is_enabled(bool is_enabled);
static const unsigned int clock_rate_divider = 8; static constexpr unsigned int clock_rate_divider = 8;
// To satisfy ::SampleSource. // To satisfy ::SampleSource.
void get_samples(std::size_t number_of_samples, int16_t *target); void get_samples(std::size_t number_of_samples, int16_t *target);

View File

@ -16,24 +16,24 @@ using namespace Electron;
#define graphics_column(v) ((((v) & 127) - first_graphics_cycle + 128) & 127) #define graphics_column(v) ((((v) & 127) - first_graphics_cycle + 128) & 127)
namespace { namespace {
static const int cycles_per_line = 128; static constexpr int cycles_per_line = 128;
static const int lines_per_frame = 625; static constexpr int lines_per_frame = 625;
static const int cycles_per_frame = lines_per_frame * cycles_per_line; static constexpr int cycles_per_frame = lines_per_frame * cycles_per_line;
static const int crt_cycles_multiplier = 8; static constexpr int crt_cycles_multiplier = 8;
static const int crt_cycles_per_line = crt_cycles_multiplier * cycles_per_line; static constexpr int crt_cycles_per_line = crt_cycles_multiplier * cycles_per_line;
static const int field_divider_line = 312; // i.e. the line, simultaneous with which, the first field's sync ends. So if static constexpr int field_divider_line = 312; // i.e. the line, simultaneous with which, the first field's sync ends. So if
// the first line with pixels in field 1 is the 20th in the frame, the first line // the first line with pixels in field 1 is the 20th in the frame, the first line
// with pixels in field 2 will be 20+field_divider_line // with pixels in field 2 will be 20+field_divider_line
static const int first_graphics_line = 31; static constexpr int first_graphics_line = 31;
static const int first_graphics_cycle = 33; static constexpr int first_graphics_cycle = 33;
static const int display_end_interrupt_line = 256; static constexpr int display_end_interrupt_line = 256;
static const int real_time_clock_interrupt_1 = 16704; static constexpr int real_time_clock_interrupt_1 = 16704;
static const int real_time_clock_interrupt_2 = 56704; static constexpr int real_time_clock_interrupt_2 = 56704;
static const int display_end_interrupt_1 = (first_graphics_line + display_end_interrupt_line)*cycles_per_line; static constexpr int display_end_interrupt_1 = (first_graphics_line + display_end_interrupt_line)*cycles_per_line;
static const int display_end_interrupt_2 = (first_graphics_line + field_divider_line + display_end_interrupt_line)*cycles_per_line; static constexpr int display_end_interrupt_2 = (first_graphics_line + field_divider_line + display_end_interrupt_line)*cycles_per_line;
} }
// MARK: - Lifecycle // MARK: - Lifecycle
@ -272,7 +272,7 @@ void VideoOutput::set_register(int address, uint8_t value) {
break; break;
case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x08: case 0x09: case 0x0a: case 0x0b:
case 0x0c: case 0x0d: case 0x0e: case 0x0f: { case 0x0c: case 0x0d: case 0x0e: case 0x0f: {
static const int registers[4][4] = { constexpr int registers[4][4] = {
{10, 8, 2, 0}, {10, 8, 2, 0},
{14, 12, 6, 4}, {14, 12, 6, 4},
{15, 13, 7, 5}, {15, 13, 7, 5},

View File

@ -29,7 +29,7 @@
#include <iostream> #include <iostream>
namespace { namespace {
const int sn76489_divider = 2; constexpr int sn76489_divider = 2;
} }
namespace Sega { namespace Sega {

View File

@ -336,8 +336,7 @@ template<bool is_zx81> class ConcreteMachine:
} }
void type_string(const std::string &string) override final { void type_string(const std::string &string) override final {
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper(is_zx81)); Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>(is_zx81));
Utility::TypeRecipient::add_typer(string, std::move(mapper));
} }
// MARK: - Keyboard // MARK: - Keyboard

View File

@ -67,7 +67,7 @@
</Testables> </Testables>
</TestAction> </TestAction>
<LaunchAction <LaunchAction
buildConfiguration = "Release" buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES" enableASanStackUseAfterReturn = "YES"

View File

@ -48,7 +48,7 @@ ROMMachine::ROMFetcher CSROMFetcher(std::vector<ROMMachine::ROM> *missing_roms)
} }
} }
else { else {
std::unique_ptr<std::vector<std::uint8_t>> data(new std::vector<std::uint8_t>); auto data = std::make_unique<std::vector<std::uint8_t>>();
*data = fileData.stdVector8; *data = fileData.stdVector8;
results.emplace_back(std::move(data)); results.emplace_back(std::move(data));
} }

View File

@ -10,8 +10,7 @@
@implementation NSData (StdVector) @implementation NSData (StdVector)
- (std::vector<uint8_t>)stdVector8 - (std::vector<uint8_t>)stdVector8 {
{
uint8_t *bytes8 = (uint8_t *)self.bytes; uint8_t *bytes8 = (uint8_t *)self.bytes;
return std::vector<uint8_t>(bytes8, bytes8 + self.length); return std::vector<uint8_t>(bytes8, bytes8 + self.length);
} }

View File

@ -45,7 +45,7 @@
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::Acorn::Target; using Target = Analyser::Static::Acorn::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::Electron; target->machine = Analyser::Machine::Electron;
target->has_dfs = !!dfs; target->has_dfs = !!dfs;
target->has_adfs = !!adfs; target->has_adfs = !!adfs;
@ -58,7 +58,7 @@
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::AmstradCPC::Target; using Target = Analyser::Static::AmstradCPC::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::AmstradCPC; target->machine = Analyser::Machine::AmstradCPC;
switch(model) { switch(model) {
case CSMachineCPCModel464: target->model = Analyser::Static::AmstradCPC::Target::Model::CPC464; break; case CSMachineCPCModel464: target->model = Analyser::Static::AmstradCPC::Target::Model::CPC464; break;
@ -74,7 +74,7 @@
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::MSX::Target; using Target = Analyser::Static::MSX::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::MSX; target->machine = Analyser::Machine::MSX;
target->has_disk_drive = !!hasDiskDrive; target->has_disk_drive = !!hasDiskDrive;
switch(region) { switch(region) {
@ -91,7 +91,7 @@
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::Oric::Target; using Target = Analyser::Static::Oric::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::Oric; target->machine = Analyser::Machine::Oric;
switch(model) { switch(model) {
case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break; case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break;
@ -112,7 +112,7 @@
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::Commodore::Target; using Target = Analyser::Static::Commodore::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::Vic20; target->machine = Analyser::Machine::Vic20;
switch(region) { switch(region) {
case CSMachineVic20RegionDanish: target->region = Target::Region::Danish; break; case CSMachineVic20RegionDanish: target->region = Target::Region::Danish; break;
@ -145,7 +145,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::ZX8081::Target; using Target = Analyser::Static::ZX8081::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::ZX8081; target->machine = Analyser::Machine::ZX8081;
target->is_ZX81 = false; target->is_ZX81 = false;
target->ZX80_uses_ZX81_ROM = !!useZX81ROM; target->ZX80_uses_ZX81_ROM = !!useZX81ROM;
@ -159,7 +159,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::ZX8081::Target; using Target = Analyser::Static::ZX8081::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::ZX8081; target->machine = Analyser::Machine::ZX8081;
target->is_ZX81 = true; target->is_ZX81 = true;
target->memory_model = ZX8081MemoryModelFromSize(memorySize); target->memory_model = ZX8081MemoryModelFromSize(memorySize);
@ -172,7 +172,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::AppleII::Target; using Target = Analyser::Static::AppleII::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::AppleII; target->machine = Analyser::Machine::AppleII;
switch(model) { switch(model) {
default: target->model = Target::Model::II; break; default: target->model = Target::Model::II; break;
@ -195,7 +195,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::Macintosh::Target; using Target = Analyser::Static::Macintosh::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::Macintosh; target->machine = Analyser::Machine::Macintosh;
using Model = Target::Model; using Model = Target::Model;
@ -216,7 +216,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
self = [super init]; self = [super init];
if(self) { if(self) {
using Target = Analyser::Static::Macintosh::Target; using Target = Analyser::Static::Macintosh::Target;
std::unique_ptr<Target> target(new Target); auto target = std::make_unique<Target>();
target->machine = Analyser::Machine::AtariST; target->machine = Analyser::Machine::AtariST;
_targets.push_back(std::move(target)); _targets.push_back(std::move(target));
} }

View File

@ -21,8 +21,7 @@ using PagingModel = Analyser::Static::Atari2600::Target::PagingModel;
@end @end
@implementation AtariROMRecord @implementation AtariROMRecord
+ (instancetype)recordWithPagingModel:(PagingModel)pagingModel usesSuperchip:(BOOL)usesSuperchip + (instancetype)recordWithPagingModel:(PagingModel)pagingModel usesSuperchip:(BOOL)usesSuperchip {
{
AtariROMRecord *record = [[AtariROMRecord alloc] init]; AtariROMRecord *record = [[AtariROMRecord alloc] init];
record->_pagingModel = pagingModel; record->_pagingModel = pagingModel;
record->_usesSuperchip = usesSuperchip; record->_usesSuperchip = usesSuperchip;
@ -578,11 +577,9 @@ static NSDictionary<NSString *, AtariROMRecord *> *romRecordsBySHA1 = @{
@implementation AtariStaticAnalyserTests @implementation AtariStaticAnalyserTests
- (void)testROMsOfSize:(NSInteger)size - (void)testROMsOfSize:(NSInteger)size {
{
NSString *basePath = [[[NSBundle bundleForClass:[self class]] resourcePath] stringByAppendingPathComponent:@"Atari ROMs"]; NSString *basePath = [[[NSBundle bundleForClass:[self class]] resourcePath] stringByAppendingPathComponent:@"Atari ROMs"];
for(NSString *testFile in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:basePath error:nil]) for(NSString *testFile in [[NSFileManager defaultManager] contentsOfDirectoryAtPath:basePath error:nil]) {
{
NSString *fullPath = [basePath stringByAppendingPathComponent:testFile]; NSString *fullPath = [basePath stringByAppendingPathComponent:testFile];
// get a SHA1 for the file // get a SHA1 for the file

View File

@ -15,18 +15,15 @@
@implementation CRCTests @implementation CRCTests
- (uint16_t)crcOfData:(uint8_t *)data length:(size_t)length generator:(CRC::CCITT &)generator - (uint16_t)crcOfData:(uint8_t *)data length:(size_t)length generator:(CRC::CCITT &)generator {
{
generator.reset(); generator.reset();
for(size_t c = 0; c < length; c++) for(size_t c = 0; c < length; c++)
generator.add(data[c]); generator.add(data[c]);
return generator.get_value(); return generator.get_value();
} }
- (void)testIDMark - (void)testIDMark {
{ uint8_t IDMark[] = {
uint8_t IDMark[] =
{
0xa1, 0xa1, 0xa1, 0xfe, 0x00, 0x00, 0x01, 0x01 0xa1, 0xa1, 0xa1, 0xfe, 0x00, 0x00, 0x01, 0x01
}; };
uint16_t crc = 0xfa0c; uint16_t crc = 0xfa0c;
@ -36,10 +33,8 @@
XCTAssert(computedCRC == crc, @"Calculated CRC should have been %04x, was %04x", crc, computedCRC); XCTAssert(computedCRC == crc, @"Calculated CRC should have been %04x, was %04x", crc, computedCRC);
} }
- (void)testData - (void)testData {
{ uint8_t sectorData[] = {
uint8_t sectorData[] =
{
0xa1, 0xa1, 0xa1, 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0xa1, 0xa1, 0xa1, 0xfb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x45, 0x44, 0x4f, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x53, 0x45, 0x44, 0x4f,
0x52, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x52, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,

View File

@ -22,8 +22,7 @@
[super setUp]; [super setUp];
// Create a valid OpenGL context, so that a VDP can be constructed. // Create a valid OpenGL context, so that a VDP can be constructed.
NSOpenGLPixelFormatAttribute attributes[] = NSOpenGLPixelFormatAttribute attributes[] = {
{
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
0 0
}; };

View File

@ -15,21 +15,18 @@
@implementation PCMSegmentEventSourceTests @implementation PCMSegmentEventSourceTests
- (Storage::Disk::PCMSegmentEventSource)segmentSource - (Storage::Disk::PCMSegmentEventSource)segmentSource {
{
std::vector<uint8_t> data = {0xff, 0x00, 0xff, 0x00}; std::vector<uint8_t> data = {0xff, 0x00, 0xff, 0x00};
Storage::Disk::PCMSegment alternatingFFs(Storage::Time(1, 10), data.size()*8, data); Storage::Disk::PCMSegment alternatingFFs(Storage::Time(1, 10), data.size()*8, data);
return Storage::Disk::PCMSegmentEventSource(alternatingFFs); return Storage::Disk::PCMSegmentEventSource(alternatingFFs);
} }
- (void)testCentring - (void)testCentring {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
[self assertFirstTwoEventLengthsForSource:segmentSource]; [self assertFirstTwoEventLengthsForSource:segmentSource];
} }
- (void)assertFirstTwoEventLengthsForSource:(Storage::Disk::PCMSegmentEventSource &)segmentSource - (void)assertFirstTwoEventLengthsForSource:(Storage::Disk::PCMSegmentEventSource &)segmentSource {
{
Storage::Disk::Track::Event first_event = segmentSource.get_next_event(); Storage::Disk::Track::Event first_event = segmentSource.get_next_event();
Storage::Disk::Track::Event second_event = segmentSource.get_next_event(); Storage::Disk::Track::Event second_event = segmentSource.get_next_event();
@ -39,8 +36,7 @@
XCTAssertTrue(second_event.length.length == 1 && second_event.length.clock_rate == 10, @"Second event should occur a whole bit's length after the first"); XCTAssertTrue(second_event.length.length == 1 && second_event.length.clock_rate == 10, @"Second event should occur a whole bit's length after the first");
} }
- (void)testLongerGap - (void)testLongerGap {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
// skip first eight flux transitions // skip first eight flux transitions
@ -52,8 +48,7 @@
XCTAssertTrue(next_event.length.length == 9 && next_event.length.clock_rate == 10, @"Zero byte should give a nine bit length event gap"); XCTAssertTrue(next_event.length.length == 9 && next_event.length.clock_rate == 10, @"Zero byte should give a nine bit length event gap");
} }
- (void)testTermination - (void)testTermination {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
Storage::Time total_time; Storage::Time total_time;
for(int c = 0; c < 16; c++) total_time += segmentSource.get_next_event().length; for(int c = 0; c < 16; c++) total_time += segmentSource.get_next_event().length;
@ -66,16 +61,14 @@
XCTAssertTrue(total_time.length == 16 && total_time.clock_rate == 5, @"Should have taken 32 bit lengths to finish the segment"); XCTAssertTrue(total_time.length == 16 && total_time.clock_rate == 5, @"Should have taken 32 bit lengths to finish the segment");
} }
- (void)testReset - (void)testReset {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
for(int c = 0; c < 8; c++) segmentSource.get_next_event(); for(int c = 0; c < 8; c++) segmentSource.get_next_event();
segmentSource.reset(); segmentSource.reset();
[self assertFirstTwoEventLengthsForSource:segmentSource]; [self assertFirstTwoEventLengthsForSource:segmentSource];
} }
- (void)testSeekToSecondBit - (void)testSeekToSecondBit {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
Storage::Time target_time(1, 10); Storage::Time target_time(1, 10);
@ -90,8 +83,7 @@
XCTAssertTrue(next_event.length.length == 1 && next_event.length.clock_rate == 10, @"Next event should be 1/10th later"); XCTAssertTrue(next_event.length.length == 1 && next_event.length.clock_rate == 10, @"Next event should be 1/10th later");
} }
- (void)testSeekBeyondFinalBit - (void)testSeekBeyondFinalBit {
{
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource; Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
Storage::Time target_time(24, 10); Storage::Time target_time(24, 10);

View File

@ -43,7 +43,7 @@ struct BestEffortUpdaterDelegate: public Concurrency::BestEffortUpdater::Delegat
struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate { struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate {
// This is set to a relatively large number for now. // This is set to a relatively large number for now.
static const int buffer_size = 1024; static constexpr int buffer_size = 1024;
void speaker_did_complete_samples(Outputs::Speaker::Speaker *speaker, const std::vector<int16_t> &buffer) override { void speaker_did_complete_samples(Outputs::Speaker::Speaker *speaker, const std::vector<int16_t> &buffer) override {
std::lock_guard<std::mutex> lock_guard(audio_buffer_mutex_); std::lock_guard<std::mutex> lock_guard(audio_buffer_mutex_);
@ -106,13 +106,12 @@ class ActivityObserver: public Activity::Observer {
lights_.clear(); lights_.clear();
// Generate a bunch of LEDs for connected drives. // Generate a bunch of LEDs for connected drives.
const float height = 0.05f; constexpr float height = 0.05f;
const float width = height / aspect_ratio; const float width = height / aspect_ratio;
const float right_x = 1.0f - 2.0f * width; const float right_x = 1.0f - 2.0f * width;
float y = 1.0f - 2.0f * height; float y = 1.0f - 2.0f * height;
for(const auto &drive: drives_) { for(const auto &drive: drives_) {
// TODO: use std::make_unique as below, if/when formally embracing C++14. lights_.emplace(std::make_pair(drive, std::make_unique<Outputs::Display::OpenGL::Rectangle>(right_x, y, width, height)));
lights_.emplace(std::make_pair(drive, std::unique_ptr<Outputs::Display::OpenGL::Rectangle>(new Outputs::Display::OpenGL::Rectangle(right_x, y, width, height))));
y -= height * 2.0f; y -= height * 2.0f;
} }
@ -424,7 +423,7 @@ int main(int argc, char *argv[]) {
continue; continue;
} }
std::unique_ptr<std::vector<uint8_t>> data(new std::vector<uint8_t>); auto data = std::make_unique<std::vector<uint8_t>>();
std::fseek(file, 0, SEEK_END); std::fseek(file, 0, SEEK_END);
data->resize(std::ftell(file)); data->resize(std::ftell(file));

View File

@ -17,8 +17,8 @@ using namespace Outputs::CRT;
void CRT::set_new_timing(int cycles_per_line, int height_of_display, Outputs::Display::ColourSpace colour_space, int colour_cycle_numerator, int colour_cycle_denominator, int vertical_sync_half_lines, bool should_alternate) { void CRT::set_new_timing(int cycles_per_line, int height_of_display, Outputs::Display::ColourSpace colour_space, int colour_cycle_numerator, int colour_cycle_denominator, int vertical_sync_half_lines, bool should_alternate) {
const int millisecondsHorizontalRetraceTime = 7; // Source: Dictionary of Video and Television Technology, p. 234. constexpr int millisecondsHorizontalRetraceTime = 7; // Source: Dictionary of Video and Television Technology, p. 234.
const int scanlinesVerticalRetraceTime = 8; // Source: ibid. constexpr int scanlinesVerticalRetraceTime = 8; // Source: ibid.
// To quote: // To quote:
// //

View File

@ -470,11 +470,11 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader() const {
"fragColour = vec4(fragColour3, 0.64);" "fragColour = vec4(fragColour3, 0.64);"
"}"; "}";
return std::unique_ptr<Shader>(new Shader( return std::make_unique<Shader>(
vertex_shader, vertex_shader,
fragment_shader, fragment_shader,
bindings(ShaderType::Conversion) bindings(ShaderType::Conversion)
)); );
} }
std::unique_ptr<Shader> ScanTarget::composition_shader() const { std::unique_ptr<Shader> ScanTarget::composition_shader() const {
@ -544,11 +544,11 @@ std::unique_ptr<Shader> ScanTarget::composition_shader() const {
break; break;
} }
return std::unique_ptr<Shader>(new Shader( return std::make_unique<Shader>(
vertex_shader, vertex_shader,
fragment_shader + "}", fragment_shader + "}",
bindings(ShaderType::Composition) bindings(ShaderType::Composition)
)); );
} }
std::unique_ptr<Shader> ScanTarget::qam_separation_shader() const { std::unique_ptr<Shader> ScanTarget::qam_separation_shader() const {
@ -656,9 +656,9 @@ std::unique_ptr<Shader> ScanTarget::qam_separation_shader() const {
"fragColour = fragColour*0.5 + vec4(0.5);" "fragColour = fragColour*0.5 + vec4(0.5);"
"}"; "}";
return std::unique_ptr<Shader>(new Shader( return std::make_unique<Shader>(
vertex_shader, vertex_shader,
fragment_shader, fragment_shader,
bindings(ShaderType::QAMSeparation) bindings(ShaderType::QAMSeparation)
)); );
} }

View File

@ -51,45 +51,45 @@ namespace MC68000 {
struct Microcycle { struct Microcycle {
/// Indicates that the address strobe and exactly one of the data strobes are active; you can determine /// Indicates that the address strobe and exactly one of the data strobes are active; you can determine
/// which by inspecting the low bit of the provided address. The RW line indicates a read. /// which by inspecting the low bit of the provided address. The RW line indicates a read.
static const int SelectByte = 1 << 0; static constexpr int SelectByte = 1 << 0;
// Maintenance note: this is bit 0 to reduce the cost of getting a host-endian // Maintenance note: this is bit 0 to reduce the cost of getting a host-endian
// bytewise address. The assumption that it is bit 0 is also used for branchless // bytewise address. The assumption that it is bit 0 is also used for branchless
// selection in a few places. See implementation of host_endian_byte_address(), // selection in a few places. See implementation of host_endian_byte_address(),
// value8_high(), value8_low() and value16(). // value8_high(), value8_low() and value16().
/// Indicates that the address and both data select strobes are active. /// Indicates that the address and both data select strobes are active.
static const int SelectWord = 1 << 1; static constexpr int SelectWord = 1 << 1;
/// A NewAddress cycle is one in which the address strobe is initially low but becomes high; /// A NewAddress cycle is one in which the address strobe is initially low but becomes high;
/// this correlates to states 0 to 5 of a standard read/write cycle. /// this correlates to states 0 to 5 of a standard read/write cycle.
static const int NewAddress = 1 << 2; static constexpr int NewAddress = 1 << 2;
/// A SameAddress cycle is one in which the address strobe is continuously asserted, but neither /// A SameAddress cycle is one in which the address strobe is continuously asserted, but neither
/// of the data strobes are. /// of the data strobes are.
static const int SameAddress = 1 << 3; static constexpr int SameAddress = 1 << 3;
/// A Reset cycle is one in which the RESET output is asserted. /// A Reset cycle is one in which the RESET output is asserted.
static const int Reset = 1 << 4; static constexpr int Reset = 1 << 4;
/// If set, indicates a read. Otherwise, a write. /// If set, indicates a read. Otherwise, a write.
static const int Read = 1 << 5; static constexpr int Read = 1 << 5;
/// Contains the value of line FC0 if it is not implicit via InterruptAcknowledge. /// Contains the value of line FC0 if it is not implicit via InterruptAcknowledge.
static const int IsData = 1 << 6; static constexpr int IsData = 1 << 6;
/// Contains the value of line FC1 if it is not implicit via InterruptAcknowledge. /// Contains the value of line FC1 if it is not implicit via InterruptAcknowledge.
static const int IsProgram = 1 << 7; static constexpr int IsProgram = 1 << 7;
/// The interrupt acknowledge cycle is that during which the 68000 seeks to obtain the vector for /// The interrupt acknowledge cycle is that during which the 68000 seeks to obtain the vector for
/// an interrupt it plans to observe. Noted on a real 68000 by all FCs being set to 1. /// an interrupt it plans to observe. Noted on a real 68000 by all FCs being set to 1.
static const int InterruptAcknowledge = 1 << 8; static constexpr int InterruptAcknowledge = 1 << 8;
/// Represents the state of the 68000's valid memory address line — indicating whether this microcycle /// Represents the state of the 68000's valid memory address line — indicating whether this microcycle
/// is synchronised with the E clock to satisfy a valid peripheral address request. /// is synchronised with the E clock to satisfy a valid peripheral address request.
static const int IsPeripheral = 1 << 9; static constexpr int IsPeripheral = 1 << 9;
/// Provides the 68000's bus grant line — indicating whether a bus request has been acknowledged. /// Provides the 68000's bus grant line — indicating whether a bus request has been acknowledged.
static const int BusGrant = 1 << 10; static constexpr int BusGrant = 1 << 10;
/// Contains a valid combination of the various static const int flags, describing the operation /// Contains a valid combination of the various static const int flags, describing the operation
/// performed by this Microcycle. /// performed by this Microcycle.

View File

@ -317,8 +317,8 @@ class ProcessorStorage {
// steps detail appropriately. // steps detail appropriately.
PrepareINTVector, PrepareINTVector,
}; };
static const int SourceMask = 1 << 7; static constexpr int SourceMask = 1 << 7;
static const int DestinationMask = 1 << 6; static constexpr int DestinationMask = 1 << 6;
uint8_t action = uint8_t(Action::None); uint8_t action = uint8_t(Action::None);
static const uint16_t NoBusProgram = std::numeric_limits<uint16_t>::max(); static const uint16_t NoBusProgram = std::numeric_limits<uint16_t>::max();

View File

@ -39,7 +39,7 @@ static std::shared_ptr<File> ZX80FileFromData(const std::vector<uint8_t> &data)
// TODO: check that the line numbers declared above exist (?) // TODO: check that the line numbers declared above exist (?)
std::shared_ptr<File> file(new File); auto file = std::make_shared<File>();
file->data = data; file->data = data;
file->isZX81 = false; file->isZX81 = false;
return file; return file;
@ -81,7 +81,7 @@ static std::shared_ptr<File> ZX81FileFromData(const std::vector<uint8_t> &data)
// TODO: check that the line numbers declared above exist (?) // TODO: check that the line numbers declared above exist (?)
std::shared_ptr<File> file(new File); auto file = std::make_shared<File>();
file->name = StringFromData(name_data, true); file->name = StringFromData(name_data, true);
file->data = data; file->data = data;
file->isZX81 = true; file->isZX81 = true;

View File

@ -11,8 +11,8 @@
#include "Utility/ImplicitSectors.hpp" #include "Utility/ImplicitSectors.hpp"
namespace { namespace {
static const int sectors_per_track = 16; constexpr int sectors_per_track = 16;
static const int sector_size = 1; constexpr int sector_size = 1;
} }
using namespace Storage::Disk; using namespace Storage::Disk;

View File

@ -18,8 +18,8 @@
using namespace Storage::Disk; using namespace Storage::Disk;
namespace { namespace {
const int number_of_tracks = 35; constexpr int number_of_tracks = 35;
const int bytes_per_sector = 256; constexpr int bytes_per_sector = 256;
} }
AppleDSK::AppleDSK(const std::string &file_name) : AppleDSK::AppleDSK(const std::string &file_name) :

View File

@ -136,5 +136,5 @@ std::shared_ptr<Track> D64::get_track_at_position(Track::Address address) {
Encodings::CommodoreGCR::encode_block(&sector_data[target_data_offset], end_of_data); Encodings::CommodoreGCR::encode_block(&sector_data[target_data_offset], end_of_data);
} }
return std::shared_ptr<Track>(new PCMTrack(PCMSegment(data))); return std::make_shared<PCMTrack>(PCMSegment(data));
} }

View File

@ -11,9 +11,9 @@
#include "Utility/ImplicitSectors.hpp" #include "Utility/ImplicitSectors.hpp"
namespace { namespace {
const int sectors_per_track = 9; constexpr int sectors_per_track = 9;
const int sector_size = 2; constexpr int sector_size = 2;
const off_t track_size = (128 << sector_size)*sectors_per_track; constexpr off_t track_size = (128 << sector_size)*sectors_per_track;
} }
using namespace Storage::Disk; using namespace Storage::Disk;

View File

@ -9,8 +9,8 @@
#include "SSD.hpp" #include "SSD.hpp"
namespace { namespace {
static const int sectors_per_track = 10; constexpr int sectors_per_track = 10;
static const int sector_size = 1; constexpr int sector_size = 1;
} }
using namespace Storage::Disk; using namespace Storage::Disk;

View File

@ -9,8 +9,8 @@
#include "ST.hpp" #include "ST.hpp"
namespace { namespace {
static const int sectors_per_track = 10; constexpr int sectors_per_track = 10;
static const int sector_size = 2; constexpr int sector_size = 2;
} }
using namespace Storage::Disk; using namespace Storage::Disk;

View File

@ -121,7 +121,7 @@ std::shared_ptr<Track> WOZ::get_track_at_position(Track::Address address) {
number_of_bits = std::min(file_.get16le(), static_cast<uint16_t>(6646*8)); number_of_bits = std::min(file_.get16le(), static_cast<uint16_t>(6646*8));
} }
return std::shared_ptr<PCMTrack>(new PCMTrack(PCMSegment(number_of_bits, track_contents))); return std::make_shared<PCMTrack>(PCMSegment(number_of_bits, track_contents));
} }
void WOZ::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) { void WOZ::set_tracks(const std::map<Track::Address, std::shared_ptr<Track>> &tracks) {

View File

@ -122,7 +122,7 @@ bool Drive::get_tachometer() {
// I have made a guess here that the tachometer is a symmetric square wave; // I have made a guess here that the tachometer is a symmetric square wave;
// if that is correct then around 60 beats per rotation appears to be correct // if that is correct then around 60 beats per rotation appears to be correct
// to proceed beyond the speed checks I've so far uncovered. // to proceed beyond the speed checks I've so far uncovered.
const float ticks_per_rotation = 60.0f; // 56 was too low; 64 too high. constexpr float ticks_per_rotation = 60.0f; // 56 was too low; 64 too high.
return int(get_rotation() * 2.0f * ticks_per_rotation) & 1; return int(get_rotation() * 2.0f * ticks_per_rotation) & 1;
} }
@ -264,7 +264,7 @@ void Drive::get_next_event(float duration_already_passed) {
// An interval greater than 15ms => adjust gain up the point where noise starts happening. // An interval greater than 15ms => adjust gain up the point where noise starts happening.
// Seed that up and leave a 15ms gap until it starts. // Seed that up and leave a 15ms gap until it starts.
const float safe_gain_period = 15.0f / 1000000.0f; constexpr float safe_gain_period = 15.0f / 1000000.0f;
if(interval >= safe_gain_period) { if(interval >= safe_gain_period) {
random_interval_ = interval - safe_gain_period; random_interval_ = interval - safe_gain_period;
interval = safe_gain_period; interval = safe_gain_period;

View File

@ -236,7 +236,7 @@ template<class T> std::shared_ptr<Storage::Disk::Track>
// Allow the amount of data written to be up to 10% more than the expected size. Which is generous. // Allow the amount of data written to be up to 10% more than the expected size. Which is generous.
if(segment.data.size() > max_size) segment.data.resize(max_size); if(segment.data.size() > max_size) segment.data.resize(max_size);
return std::shared_ptr<Storage::Disk::Track>(new Storage::Disk::PCMTrack(std::move(segment))); return std::make_shared<Storage::Disk::PCMTrack>(std::move(segment));
} }
Encoder::Encoder(std::vector<bool> &target) : Encoder::Encoder(std::vector<bool> &target) :
@ -311,9 +311,9 @@ std::shared_ptr<Storage::Disk::Track> Storage::Encodings::MFM::GetMFMTrackWithSe
} }
std::unique_ptr<Encoder> Storage::Encodings::MFM::GetMFMEncoder(std::vector<bool> &target) { std::unique_ptr<Encoder> Storage::Encodings::MFM::GetMFMEncoder(std::vector<bool> &target) {
return std::unique_ptr<Encoder>(new MFMEncoder(target)); return std::make_unique<MFMEncoder>(target);
} }
std::unique_ptr<Encoder> Storage::Encodings::MFM::GetFMEncoder(std::vector<bool> &target) { std::unique_ptr<Encoder> Storage::Encodings::MFM::GetFMEncoder(std::vector<bool> &target) {
return std::unique_ptr<Encoder>(new FMEncoder(target)); return std::make_unique<FMEncoder>(target);
} }

View File

@ -21,7 +21,7 @@ namespace SCSI {
typedef int BusState; typedef int BusState;
static const BusState DefaultBusState = 0; static constexpr BusState DefaultBusState = 0;
/*! /*!
SCSI bus state is encoded entirely within an int. SCSI bus state is encoded entirely within an int.

View File

@ -19,8 +19,7 @@ CommodoreTAP::CommodoreTAP(const std::string &file_name) :
throw ErrorNotCommodoreTAP; throw ErrorNotCommodoreTAP;
// check the file version // check the file version
switch(file_.get8()) switch(file_.get8()) {
{
case 0: updated_layout_ = false; break; case 0: updated_layout_ = false; break;
case 1: updated_layout_ = true; break; case 1: updated_layout_ = true; break;
default: throw ErrorNotCommodoreTAP; default: throw ErrorNotCommodoreTAP;
@ -40,52 +39,41 @@ CommodoreTAP::CommodoreTAP(const std::string &file_name) :
current_pulse_.type = Pulse::High; current_pulse_.type = Pulse::High;
} }
void CommodoreTAP::virtual_reset() void CommodoreTAP::virtual_reset() {
{
file_.seek(0x14, SEEK_SET); file_.seek(0x14, SEEK_SET);
current_pulse_.type = Pulse::High; current_pulse_.type = Pulse::High;
is_at_end_ = false; is_at_end_ = false;
} }
bool CommodoreTAP::is_at_end() bool CommodoreTAP::is_at_end() {
{
return is_at_end_; return is_at_end_;
} }
Storage::Tape::Tape::Pulse CommodoreTAP::virtual_get_next_pulse() Storage::Tape::Tape::Pulse CommodoreTAP::virtual_get_next_pulse() {
{ if(is_at_end_) {
if(is_at_end_)
{
return current_pulse_; return current_pulse_;
} }
if(current_pulse_.type == Pulse::High) if(current_pulse_.type == Pulse::High) {
{
uint32_t next_length; uint32_t next_length;
uint8_t next_byte = file_.get8(); uint8_t next_byte = file_.get8();
if(!updated_layout_ || next_byte > 0) if(!updated_layout_ || next_byte > 0) {
{
next_length = (uint32_t)next_byte << 3; next_length = (uint32_t)next_byte << 3;
} } else {
else
{
next_length = file_.get24le(); next_length = file_.get24le();
} }
if(file_.eof()) if(file_.eof()) {
{
is_at_end_ = true; is_at_end_ = true;
current_pulse_.length.length = current_pulse_.length.clock_rate; current_pulse_.length.length = current_pulse_.length.clock_rate;
current_pulse_.type = Pulse::Zero; current_pulse_.type = Pulse::Zero;
} } else {
else
{
current_pulse_.length.length = next_length; current_pulse_.length.length = next_length;
current_pulse_.type = Pulse::Low; current_pulse_.type = Pulse::Low;
} }
} } else {
else
current_pulse_.type = Pulse::High; current_pulse_.type = Pulse::High;
}
return current_pulse_; return current_pulse_;
} }

View File

@ -65,10 +65,10 @@ PRG::PRG(const std::string &file_name) :
Storage::Tape::Tape::Pulse PRG::virtual_get_next_pulse() { Storage::Tape::Tape::Pulse PRG::virtual_get_next_pulse() {
// these are all microseconds per pole // these are all microseconds per pole
static const unsigned int leader_zero_length = 179; constexpr unsigned int leader_zero_length = 179;
static const unsigned int zero_length = 169; constexpr unsigned int zero_length = 169;
static const unsigned int one_length = 247; constexpr unsigned int one_length = 247;
static const unsigned int marker_length = 328; constexpr unsigned int marker_length = 328;
bit_phase_ = (bit_phase_+1)&3; bit_phase_ = (bit_phase_+1)&3;
if(!bit_phase_) get_next_output_token(); if(!bit_phase_) get_next_output_token();
@ -100,10 +100,10 @@ bool PRG::is_at_end() {
} }
void PRG::get_next_output_token() { void PRG::get_next_output_token() {
static const int block_length = 192; // not counting the checksum constexpr int block_length = 192; // not counting the checksum
static const int countdown_bytes = 9; constexpr int countdown_bytes = 9;
static const int leadin_length = 20000; constexpr int leadin_length = 20000;
static const int block_leadin_length = 5000; constexpr int block_leadin_length = 5000;
if(file_phase_ == FilePhaseHeaderDataGap || file_phase_ == FilePhaseAtEnd) { if(file_phase_ == FilePhaseHeaderDataGap || file_phase_ == FilePhaseAtEnd) {
output_token_ = Silence; output_token_ = Silence;

View File

@ -11,7 +11,7 @@
using namespace Storage::Tape::Acorn; using namespace Storage::Tape::Acorn;
namespace { namespace {
const int PLLClockRate = 1920000; constexpr int PLLClockRate = 1920000;
} }
Parser::Parser(): crc_(0x1021) { Parser::Parser(): crc_(0x1021) {

View File

@ -20,8 +20,7 @@ Parser::Parser() :
Advances to the next block on the tape, treating it as a header, then consumes, parses, and returns it. Advances to the next block on the tape, treating it as a header, then consumes, parses, and returns it.
Returns @c nullptr if any wave-encoding level errors are encountered. Returns @c nullptr if any wave-encoding level errors are encountered.
*/ */
std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::Tape::Tape> &tape) std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
return duplicate_match<Header>( return duplicate_match<Header>(
get_next_header_body(tape, true), get_next_header_body(tape, true),
get_next_header_body(tape, false) get_next_header_body(tape, false)
@ -32,8 +31,7 @@ std::unique_ptr<Header> Parser::get_next_header(const std::shared_ptr<Storage::T
Advances to the next block on the tape, treating it as data, then consumes, parses, and returns it. Advances to the next block on the tape, treating it as data, then consumes, parses, and returns it.
Returns @c nullptr if any wave-encoding level errors are encountered. Returns @c nullptr if any wave-encoding level errors are encountered.
*/ */
std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape::Tape> &tape) std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
return duplicate_match<Data>( return duplicate_match<Data>(
get_next_data_body(tape, true), get_next_data_body(tape, true),
get_next_data_body(tape, false) get_next_data_body(tape, false)
@ -45,8 +43,7 @@ std::unique_ptr<Data> Parser::get_next_data(const std::shared_ptr<Storage::Tape:
including setting the duplicate_matched flag. including setting the duplicate_matched flag.
*/ */
template<class ObjectType> template<class ObjectType>
std::unique_ptr<ObjectType> Parser::duplicate_match(std::unique_ptr<ObjectType> first_copy, std::unique_ptr<ObjectType> second_copy) std::unique_ptr<ObjectType> Parser::duplicate_match(std::unique_ptr<ObjectType> first_copy, std::unique_ptr<ObjectType> second_copy) {
{
// if only one copy was parsed successfully, return it // if only one copy was parsed successfully, return it
if(!first_copy) return second_copy; if(!first_copy) return second_copy;
if(!second_copy) return first_copy; if(!second_copy) return first_copy;
@ -67,9 +64,8 @@ template<class ObjectType>
return std::move(*copy_to_return); return std::move(*copy_to_return);
} }
std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
{ auto header = std::make_unique<Header>();
std::unique_ptr<Header> header(new Header);
reset_error_flag(); reset_error_flag();
// find and proceed beyond lead-in tone // find and proceed beyond lead-in tone
@ -81,8 +77,7 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
// get header type // get header type
uint8_t header_type = get_next_byte(tape); uint8_t header_type = get_next_byte(tape);
switch(header_type) switch(header_type) {
{
default: header->type = Header::Unknown; break; default: header->type = Header::Unknown; break;
case 0x01: header->type = Header::RelocatableProgram; break; case 0x01: header->type = Header::RelocatableProgram; break;
case 0x02: header->type = Header::DataBlock; break; case 0x02: header->type = Header::DataBlock; break;
@ -93,8 +88,7 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
// grab rest of data // grab rest of data
header->data.reserve(191); header->data.reserve(191);
for(std::size_t c = 0; c < 191; c++) for(std::size_t c = 0; c < 191; c++) {
{
header->data.push_back(get_next_byte(tape)); header->data.push_back(get_next_byte(tape));
} }
@ -102,13 +96,11 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
header->parity_was_valid = get_next_byte(tape) == parity_byte; header->parity_was_valid = get_next_byte(tape) == parity_byte;
// parse if this is not pure data // parse if this is not pure data
if(header->type != Header::DataBlock) if(header->type != Header::DataBlock) {
{
header->starting_address = static_cast<uint16_t>(header->data[0] | (header->data[1] << 8)); header->starting_address = static_cast<uint16_t>(header->data[0] | (header->data[1] << 8));
header->ending_address = static_cast<uint16_t>(header->data[2] | (header->data[3] << 8)); header->ending_address = static_cast<uint16_t>(header->data[2] | (header->data[3] << 8));
for(std::size_t c = 0; c < 16; c++) for(std::size_t c = 0; c < 16; c++) {
{
header->raw_name.push_back(header->data[4 + c]); header->raw_name.push_back(header->data[4 + c]);
} }
header->name = Storage::Data::Commodore::petscii_from_bytes(&header->raw_name[0], 16, false); header->name = Storage::Data::Commodore::petscii_from_bytes(&header->raw_name[0], 16, false);
@ -119,8 +111,7 @@ std::unique_ptr<Header> Parser::get_next_header_body(const std::shared_ptr<Stora
} }
void Header::serialise(uint8_t *target, uint16_t length) { void Header::serialise(uint8_t *target, uint16_t length) {
switch(type) switch(type) {
{
default: target[0] = 0xff; break; default: target[0] = 0xff; break;
case Header::RelocatableProgram: target[0] = 0x01; break; case Header::RelocatableProgram: target[0] = 0x01; break;
case Header::DataBlock: target[0] = 0x02; break; case Header::DataBlock: target[0] = 0x02; break;
@ -132,9 +123,8 @@ void Header::serialise(uint8_t *target, uint16_t length) {
std::memcpy(&target[1], data.data(), 191); std::memcpy(&target[1], data.data(), 191);
} }
std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
{ auto data = std::make_unique<Data>();
std::unique_ptr<Data> data(new Data);
reset_error_flag(); reset_error_flag();
// find and proceed beyond lead-in tone to the next landing zone // find and proceed beyond lead-in tone to the next landing zone
@ -143,8 +133,7 @@ std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::
reset_parity_byte(); reset_parity_byte();
// accumulate until the next non-word marker is hit // accumulate until the next non-word marker is hit
while(!tape->is_at_end()) while(!tape->is_at_end()) {
{
SymbolType start_symbol = get_next_symbol(tape); SymbolType start_symbol = get_next_symbol(tape);
if(start_symbol != SymbolType::Word) break; if(start_symbol != SymbolType::Word) break;
data->data.push_back(get_next_byte_contents(tape)); data->data.push_back(get_next_byte_contents(tape));
@ -163,19 +152,15 @@ std::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::
/*! /*!
Finds and completes the next landing zone. Finds and completes the next landing zone.
*/ */
void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original) {
{
uint8_t landing_zone[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t landing_zone[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
while(!tape->is_at_end()) while(!tape->is_at_end()) {
{
memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8); memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8);
landing_zone[8] = get_next_byte(tape); landing_zone[8] = get_next_byte(tape);
bool is_landing_zone = true; bool is_landing_zone = true;
for(int c = 0; c < 9; c++) for(int c = 0; c < 9; c++) {
{ if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c) {
if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c)
{
is_landing_zone = false; is_landing_zone = false;
break; break;
} }
@ -188,10 +173,8 @@ void Parser::proceed_to_landing_zone(const std::shared_ptr<Storage::Tape::Tape>
Swallows symbols until it reaches the first instance of the required symbol, swallows that Swallows symbols until it reaches the first instance of the required symbol, swallows that
and returns. and returns.
*/ */
void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol) void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol) {
{ while(!tape->is_at_end()) {
while(!tape->is_at_end())
{
SymbolType symbol = get_next_symbol(tape); SymbolType symbol = get_next_symbol(tape);
if(symbol == required_symbol) return; if(symbol == required_symbol) return;
} }
@ -200,8 +183,7 @@ void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape,
/*! /*!
Swallows the next byte; sets the error flag if it is not equal to @c value. Swallows the next byte; sets the error flag if it is not equal to @c value.
*/ */
void Parser::expect_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, uint8_t value) void Parser::expect_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, uint8_t value) {
{
uint8_t next_byte = get_next_byte(tape); uint8_t next_byte = get_next_byte(tape);
if(next_byte != value) set_error_flag(); if(next_byte != value) set_error_flag();
} }
@ -213,8 +195,7 @@ void Parser::add_parity_byte(uint8_t byte) { parity_byte_ ^= byte; }
/*! /*!
Proceeds to the next word marker then returns the result of @c get_next_byte_contents. Proceeds to the next word marker then returns the result of @c get_next_byte_contents.
*/ */
uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape) uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
proceed_to_symbol(tape, SymbolType::Word); proceed_to_symbol(tape, SymbolType::Word);
return get_next_byte_contents(tape); return get_next_byte_contents(tape);
} }
@ -224,12 +205,10 @@ uint8_t Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape)
Returns a byte composed of the first eight of those as bits; sets the error flag if any symbol is not Returns a byte composed of the first eight of those as bits; sets the error flag if any symbol is not
::One and not ::Zero, or if the ninth bit is not equal to the odd parity of the other eight. ::One and not ::Zero, or if the ninth bit is not equal to the odd parity of the other eight.
*/ */
uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape> &tape) uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
int byte_plus_parity = 0; int byte_plus_parity = 0;
int c = 9; int c = 9;
while(c--) while(c--) {
{
SymbolType next_symbol = get_next_symbol(tape); SymbolType next_symbol = get_next_symbol(tape);
if((next_symbol != SymbolType::One) && (next_symbol != SymbolType::Zero)) set_error_flag(); if((next_symbol != SymbolType::One) && (next_symbol != SymbolType::Zero)) set_error_flag();
byte_plus_parity = (byte_plus_parity >> 1) | (((next_symbol == SymbolType::One) ? 1 : 0) << 8); byte_plus_parity = (byte_plus_parity >> 1) | (((next_symbol == SymbolType::One) ? 1 : 0) << 8);
@ -249,8 +228,7 @@ uint8_t Parser::get_next_byte_contents(const std::shared_ptr<Storage::Tape::Tape
/*! /*!
Returns the result of two consecutive @c get_next_byte calls, arranged in little-endian format. Returns the result of two consecutive @c get_next_byte calls, arranged in little-endian format.
*/ */
uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape) uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
uint16_t value = get_next_byte(tape); uint16_t value = get_next_byte(tape);
value |= get_next_byte(tape) << 8; value |= get_next_byte(tape) << 8;
return value; return value;
@ -261,15 +239,13 @@ uint16_t Parser::get_next_short(const std::shared_ptr<Storage::Tape::Tape> &tape
indicates a high to low transition, inspects the time since the last transition, to produce indicates a high to low transition, inspects the time since the last transition, to produce
a long, medium, short or unrecognised wave period. a long, medium, short or unrecognised wave period.
*/ */
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
{
// The Complete Commodore Inner Space Anthology, P 97, gives half-cycle lengths of: // The Complete Commodore Inner Space Anthology, P 97, gives half-cycle lengths of:
// short: 182us => 0.000364s cycle // short: 182us => 0.000364s cycle
// medium: 262us => 0.000524s cycle // medium: 262us => 0.000524s cycle
// long: 342us => 0.000684s cycle // long: 342us => 0.000684s cycle
bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High; bool is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
if(!is_high && previous_was_high_) if(!is_high && previous_was_high_) {
{
if(wave_period_ >= 0.000764) push_wave(WaveType::Unrecognised); if(wave_period_ >= 0.000764) push_wave(WaveType::Unrecognised);
else if(wave_period_ >= 0.000604) push_wave(WaveType::Long); else if(wave_period_ >= 0.000604) push_wave(WaveType::Long);
else if(wave_period_ >= 0.000444) push_wave(WaveType::Medium); else if(wave_period_ >= 0.000444) push_wave(WaveType::Medium);
@ -287,36 +263,30 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse)
Per the contract with Analyser::Static::TapeParser; produces any of a word marker, an end-of-block marker, Per the contract with Analyser::Static::TapeParser; produces any of a word marker, an end-of-block marker,
a zero, a one or a lead-in symbol based on the currently captured waves. a zero, a one or a lead-in symbol based on the currently captured waves.
*/ */
void Parser::inspect_waves(const std::vector<WaveType> &waves) void Parser::inspect_waves(const std::vector<WaveType> &waves) {
{
if(waves.size() < 2) return; if(waves.size() < 2) return;
if(waves[0] == WaveType::Long && waves[1] == WaveType::Medium) if(waves[0] == WaveType::Long && waves[1] == WaveType::Medium) {
{
push_symbol(SymbolType::Word, 2); push_symbol(SymbolType::Word, 2);
return; return;
} }
if(waves[0] == WaveType::Long && waves[1] == WaveType::Short) if(waves[0] == WaveType::Long && waves[1] == WaveType::Short) {
{
push_symbol(SymbolType::EndOfBlock, 2); push_symbol(SymbolType::EndOfBlock, 2);
return; return;
} }
if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium) if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium) {
{
push_symbol(SymbolType::Zero, 2); push_symbol(SymbolType::Zero, 2);
return; return;
} }
if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short) if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short) {
{
push_symbol(SymbolType::One, 2); push_symbol(SymbolType::One, 2);
return; return;
} }
if(waves[0] == WaveType::Short) if(waves[0] == WaveType::Short) {
{
push_symbol(SymbolType::LeadIn, 1); push_symbol(SymbolType::LeadIn, 1);
return; return;
} }

View File

@ -71,7 +71,7 @@ std::unique_ptr<Parser::FileSpeed> Parser::find_header(Storage::Tape::BinaryTape
// To convert to the loop count format used by the MSX BIOS. // To convert to the loop count format used by the MSX BIOS.
uint8_t int_result = static_cast<uint8_t>(total_length / (0.00001145f * 0.75f)); uint8_t int_result = static_cast<uint8_t>(total_length / (0.00001145f * 0.75f));
std::unique_ptr<FileSpeed> result(new FileSpeed); auto result = std::make_unique<FileSpeed>();
result->minimum_start_bit_duration = int_result; result->minimum_start_bit_duration = int_result;
result->low_high_disrimination_duration = (int_result * 3) >> 2; result->low_high_disrimination_duration = (int_result * 3) >> 2;
@ -101,7 +101,7 @@ int Parser::get_byte(const FileSpeed &speed, Storage::Tape::BinaryTapePlayer &ta
So I'm going to look for the next two consecutive pulses that are each big So I'm going to look for the next two consecutive pulses that are each big
enough to be half of a zero. enough to be half of a zero.
*/ */
const float minimum_start_bit_duration = static_cast<float>(speed.minimum_start_bit_duration) * 0.00001145f * 0.5f; const float minimum_start_bit_duration = float(speed.minimum_start_bit_duration) * 0.00001145f * 0.5f;
int input = 0; int input = 0;
while(!tape_player.get_tape()->is_at_end()) { while(!tape_player.get_tape()->is_at_end()) {
// Find next transition. // Find next transition.
@ -126,9 +126,9 @@ int Parser::get_byte(const FileSpeed &speed, Storage::Tape::BinaryTapePlayer &ta
int result = 0; int result = 0;
const int cycles_per_window = static_cast<int>( const int cycles_per_window = static_cast<int>(
0.5f + 0.5f +
static_cast<float>(speed.low_high_disrimination_duration) * float(speed.low_high_disrimination_duration) *
0.0000173f * 0.0000173f *
static_cast<float>(tape_player.get_input_clock_rate()) float(tape_player.get_input_clock_rate())
); );
int bits_left = 8; int bits_left = 8;
bool level = tape_player.get_input(); bool level = tape_player.get_input();
@ -137,7 +137,7 @@ int Parser::get_byte(const FileSpeed &speed, Storage::Tape::BinaryTapePlayer &ta
int transitions = 0; int transitions = 0;
int cycles_remaining = cycles_per_window; int cycles_remaining = cycles_per_window;
while(!tape_player.get_tape()->is_at_end() && cycles_remaining) { while(!tape_player.get_tape()->is_at_end() && cycles_remaining) {
const int cycles_until_next_event = static_cast<int>(tape_player.get_cycles_until_next_event()); const int cycles_until_next_event = int(tape_player.get_cycles_until_next_event());
const int cycles_to_run_for = std::min(cycles_until_next_event, cycles_remaining); const int cycles_to_run_for = std::min(cycles_until_next_event, cycles_remaining);
cycles_remaining -= cycles_to_run_for; cycles_remaining -= cycles_to_run_for;

View File

@ -10,15 +10,13 @@
using namespace Storage::Tape::Oric; using namespace Storage::Tape::Oric;
int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding) int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool use_fast_encoding) {
{
detection_mode_ = use_fast_encoding ? FastZero : SlowZero; detection_mode_ = use_fast_encoding ? FastZero : SlowZero;
cycle_length_ = 0.0f; cycle_length_ = 0.0f;
int result = 0; int result = 0;
int bit_count = 0; int bit_count = 0;
while(bit_count < 11 && !tape->is_at_end()) while(bit_count < 11 && !tape->is_at_end()) {
{
SymbolType symbol = get_next_symbol(tape); SymbolType symbol = get_next_symbol(tape);
if(!bit_count && symbol != SymbolType::Zero) continue; if(!bit_count && symbol != SymbolType::Zero) continue;
detection_mode_ = use_fast_encoding ? FastData : SlowData; detection_mode_ = use_fast_encoding ? FastData : SlowData;
@ -29,14 +27,11 @@ int Parser::get_next_byte(const std::shared_ptr<Storage::Tape::Tape> &tape, bool
return tape->is_at_end() ? -1 : ((result >> 1)&0xff); return tape->is_at_end() ? -1 : ((result >> 1)&0xff);
} }
bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Tape> &tape) bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Tape> &tape) {
{
detection_mode_ = Sync; detection_mode_ = Sync;
while(!tape->is_at_end()) while(!tape->is_at_end()) {
{ const SymbolType symbol = get_next_symbol(tape);
SymbolType symbol = get_next_symbol(tape); switch(symbol) {
switch(symbol)
{
case SymbolType::FoundSlow: return false; case SymbolType::FoundSlow: return false;
case SymbolType::FoundFast: return true; case SymbolType::FoundFast: return true;
default: break; default: break;
@ -45,15 +40,13 @@ bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Ta
return false; return false;
} }
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
{ constexpr float maximum_short_length = 0.000512f;
const float maximum_short_length = 0.000512f; constexpr float maximum_medium_length = 0.000728f;
const float maximum_medium_length = 0.000728f; constexpr float maximum_long_length = 0.001456f;
const float maximum_long_length = 0.001456f;
bool wave_is_high = pulse.type == Storage::Tape::Tape::Pulse::High; bool wave_is_high = pulse.type == Storage::Tape::Tape::Pulse::High;
if(!wave_was_high_ && wave_is_high != wave_was_high_) if(!wave_was_high_ && wave_is_high != wave_was_high_) {
{
if(cycle_length_ < maximum_short_length) push_wave(WaveType::Short); if(cycle_length_ < maximum_short_length) push_wave(WaveType::Short);
else if(cycle_length_ < maximum_medium_length) push_wave(WaveType::Medium); else if(cycle_length_ < maximum_medium_length) push_wave(WaveType::Medium);
else if(cycle_length_ < maximum_long_length) push_wave(WaveType::Long); else if(cycle_length_ < maximum_long_length) push_wave(WaveType::Long);
@ -65,14 +58,11 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse)
cycle_length_ += pulse.length.get<float>(); cycle_length_ += pulse.length.get<float>();
} }
void Parser::inspect_waves(const std::vector<WaveType> &waves) void Parser::inspect_waves(const std::vector<WaveType> &waves) {
{ switch(detection_mode_) {
switch(detection_mode_)
{
case FastZero: case FastZero:
if(waves.empty()) return; if(waves.empty()) return;
if(waves[0] == WaveType::Medium) if(waves[0] == WaveType::Medium) {
{
push_symbol(SymbolType::Zero, 1); push_symbol(SymbolType::Zero, 1);
return; return;
} }
@ -80,13 +70,11 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
case FastData: case FastData:
if(waves.empty()) return; if(waves.empty()) return;
if(waves[0] == WaveType::Medium) if(waves[0] == WaveType::Medium) {
{
push_symbol(SymbolType::Zero, 1); push_symbol(SymbolType::Zero, 1);
return; return;
} }
if(waves[0] == WaveType::Short) if(waves[0] == WaveType::Short) {
{
push_symbol(SymbolType::One, 1); push_symbol(SymbolType::One, 1);
return; return;
} }
@ -94,8 +82,7 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
case SlowZero: case SlowZero:
if(waves.size() < 4) return; if(waves.size() < 4) return;
if(waves[0] == WaveType::Long && waves[1] == WaveType::Long && waves[2] == WaveType::Long && waves[3] == WaveType::Long) if(waves[0] == WaveType::Long && waves[1] == WaveType::Long && waves[2] == WaveType::Long && waves[3] == WaveType::Long) {
{
push_symbol(SymbolType::Zero, 4); push_symbol(SymbolType::Zero, 4);
return; return;
} }
@ -103,12 +90,10 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
case SlowData: case SlowData:
#define CHECK_RUN(length, type, symbol) \ #define CHECK_RUN(length, type, symbol) \
if(waves.size() >= length)\ if(waves.size() >= length) {\
{\
std::size_t c;\ std::size_t c;\
for(c = 0; c < length; c++) if(waves[c] != type) break;\ for(c = 0; c < length; c++) if(waves[c] != type) break;\
if(c == length)\ if(c == length) {\
{\
push_symbol(symbol, length);\ push_symbol(symbol, length);\
return;\ return;\
}\ }\
@ -120,11 +105,9 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
if(waves.size() < 16) return; // TODO, maybe: if there are any inconsistencies in the first 8, don't return if(waves.size() < 16) return; // TODO, maybe: if there are any inconsistencies in the first 8, don't return
break; break;
case Sync: case Sync: {
{
// Sync is 0x16, either encoded fast or slow; i.e. 0 0110 1000 1 // Sync is 0x16, either encoded fast or slow; i.e. 0 0110 1000 1
Pattern slow_sync[] = const Pattern slow_sync[] = {
{
{WaveType::Long, 8}, {WaveType::Long, 8},
{WaveType::Short, 16}, {WaveType::Short, 16},
{WaveType::Long, 4}, {WaveType::Long, 4},
@ -133,8 +116,7 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
{WaveType::Short, 8}, {WaveType::Short, 8},
{WaveType::Unrecognised} {WaveType::Unrecognised}
}; };
Pattern fast_sync[] = const Pattern fast_sync[] = {
{
{WaveType::Medium, 2}, {WaveType::Medium, 2},
{WaveType::Short, 2}, {WaveType::Short, 2},
{WaveType::Medium, 1}, {WaveType::Medium, 1},
@ -147,18 +129,15 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
std::size_t slow_sync_matching_depth = pattern_matching_depth(waves, slow_sync); std::size_t slow_sync_matching_depth = pattern_matching_depth(waves, slow_sync);
std::size_t fast_sync_matching_depth = pattern_matching_depth(waves, fast_sync); std::size_t fast_sync_matching_depth = pattern_matching_depth(waves, fast_sync);
if(slow_sync_matching_depth == 52) if(slow_sync_matching_depth == 52) {
{
push_symbol(SymbolType::FoundSlow, 52); push_symbol(SymbolType::FoundSlow, 52);
return; return;
} }
if(fast_sync_matching_depth == 10) if(fast_sync_matching_depth == 10) {
{
push_symbol(SymbolType::FoundFast, 10); push_symbol(SymbolType::FoundFast, 10);
return; return;
} }
if(slow_sync_matching_depth < waves.size() && fast_sync_matching_depth < waves.size()) if(slow_sync_matching_depth < waves.size() && fast_sync_matching_depth < waves.size()) {
{
int least_depth = static_cast<int>(std::min(slow_sync_matching_depth, fast_sync_matching_depth)); int least_depth = static_cast<int>(std::min(slow_sync_matching_depth, fast_sync_matching_depth));
remove_waves(least_depth ? least_depth : 1); remove_waves(least_depth ? least_depth : 1);
} }
@ -171,17 +150,14 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
remove_waves(1); remove_waves(1);
} }
std::size_t Parser::pattern_matching_depth(const std::vector<WaveType> &waves, Pattern *pattern) std::size_t Parser::pattern_matching_depth(const std::vector<WaveType> &waves, const Pattern *pattern) {
{
std::size_t depth = 0; std::size_t depth = 0;
int pattern_depth = 0; int pattern_depth = 0;
while(depth < waves.size() && pattern->type != WaveType::Unrecognised) while(depth < waves.size() && pattern->type != WaveType::Unrecognised) {
{
if(waves[depth] != pattern->type) break; if(waves[depth] != pattern->type) break;
depth++; depth++;
pattern_depth++; pattern_depth++;
if(pattern_depth == pattern->count) if(pattern_depth == pattern->count) {
{
pattern_depth = 0; pattern_depth = 0;
pattern++; pattern++;
} }

View File

@ -50,7 +50,7 @@ class Parser: public Storage::Tape::PulseClassificationParser<WaveType, SymbolTy
WaveType type; WaveType type;
int count; int count;
}; };
std::size_t pattern_matching_depth(const std::vector<WaveType> &waves, Pattern *pattern); std::size_t pattern_matching_depth(const std::vector<WaveType> &waves, const Pattern *pattern);
}; };

View File

@ -29,9 +29,9 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
} }
void Parser::post_pulse() { void Parser::post_pulse() {
const float expected_pulse_length = 300.0f / 1000000.0f; constexpr float expected_pulse_length = 300.0f / 1000000.0f;
const float expected_gap_length = 1300.0f / 1000000.0f; constexpr float expected_gap_length = 1300.0f / 1000000.0f;
float pulse_time = pulse_time_.get<float>(); auto pulse_time = pulse_time_.get<float>();
if(pulse_time > expected_gap_length * 1.25f) { if(pulse_time > expected_gap_length * 1.25f) {
push_wave(WaveType::LongGap); push_wave(WaveType::LongGap);
@ -120,7 +120,7 @@ std::shared_ptr<std::vector<uint8_t>> Parser::get_next_file_data(const std::shar
if(is_at_end(tape)) return nullptr; if(is_at_end(tape)) return nullptr;
return_symbol(symbol); return_symbol(symbol);
std::shared_ptr<std::vector<uint8_t>> result(new std::vector<uint8_t>); auto result = std::make_shared<std::vector<uint8_t>>();
int byte; int byte;
while(!is_at_end(tape)) { while(!is_at_end(tape)) {
byte = get_next_byte(tape); byte = get_next_byte(tape);