mirror of
https://github.com/TomHarte/CLK.git
synced 2024-08-17 07:29:04 +00:00
Merge pull request #696 from TomHarte/make_shared
Makes a variety of minor style improvements
This commit is contained in:
commit
66d9b60b98
@ -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) {
|
||||
// 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::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;
|
||||
}
|
||||
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::Sector *free_space_map_second_half = parser.get_sector(0, 0, 1);
|
||||
|
@ -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) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Machine::Electron;
|
||||
target->confidence = 0.5; // TODO: a proper estimation
|
||||
target->has_dfs = false;
|
||||
|
@ -16,7 +16,7 @@
|
||||
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) {
|
||||
std::unique_ptr<File::Chunk> new_chunk(new File::Chunk);
|
||||
auto new_chunk = std::make_unique<File::Chunk>();
|
||||
int shift_register = 0;
|
||||
|
||||
// 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;
|
||||
|
||||
// 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;
|
||||
|
||||
|
@ -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) {
|
||||
TargetList destination;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Machine::AmstradCPC;
|
||||
target->confidence = 0.5;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "Target.hpp"
|
||||
|
||||
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->media = media;
|
||||
|
||||
|
@ -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) {
|
||||
// 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->confidence = 0.5;
|
||||
target->media.cartridges = media.cartridges;
|
||||
|
@ -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) {
|
||||
TargetList targets;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Machine::ColecoVision;
|
||||
target->confidence = 1.0f - 1.0f / 32768.0f;
|
||||
target->media.cartridges = ColecoCartridgesFrom(media.cartridges);
|
||||
|
@ -125,7 +125,7 @@ class CommodoreGCRParser: public Storage::Disk::Controller {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
while(index_count_ < max_index_count) {
|
||||
|
@ -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) {
|
||||
TargetList destination;
|
||||
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Machine::Vic20; // TODO: machine estimation
|
||||
target->confidence = 0.5; // TODO: a proper estimation
|
||||
|
||||
|
@ -34,7 +34,7 @@ static std::unique_ptr<Analyser::Static::Target> CartridgeTarget(
|
||||
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->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));
|
||||
|
||||
// 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.
|
||||
for(auto &tape : media.tapes) {
|
||||
|
@ -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) {
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Machine::Oric;
|
||||
target->confidence = 0.5;
|
||||
|
||||
|
@ -18,7 +18,7 @@ Analyser::Static::TargetList Analyser::Static::Sega::GetTargets(const Media &med
|
||||
return {};
|
||||
|
||||
TargetList targets;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
|
||||
target->machine = Machine::MasterSystem;
|
||||
|
||||
|
@ -100,7 +100,7 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate {
|
||||
} parity_ = Parity::None;
|
||||
int data_bits_ = 7, stop_bits_ = 2;
|
||||
|
||||
static const int NoValueMask = 0x100;
|
||||
static constexpr int NoValueMask = 0x100;
|
||||
int next_transmission_ = NoValueMask;
|
||||
int received_data_ = NoValueMask;
|
||||
|
||||
|
@ -110,7 +110,7 @@ void MFP68901::write(int address, uint8_t value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int timer_prescales[] = {
|
||||
constexpr int timer_prescales[] = {
|
||||
1, 4, 10, 16, 50, 64, 100, 200
|
||||
};
|
||||
|
||||
|
@ -61,7 +61,7 @@ class MFP68901: public ClockingHint::Source {
|
||||
/// @returns @c true if the interrupt output is currently active; @c false otherwise.s
|
||||
bool get_interrupt_line();
|
||||
|
||||
static const int NoAcknowledgement = 0x100;
|
||||
static constexpr int NoAcknowledgement = 0x100;
|
||||
|
||||
/// Communicates an interrupt acknowledge cycle.
|
||||
///
|
||||
|
@ -292,7 +292,7 @@ void i8272::posit_event(int event_type) {
|
||||
WAIT_FOR_EVENT(Event8272::CommandByte)
|
||||
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,
|
||||
1, 9, 2, 0, 9, 6, 0, 3,
|
||||
0, 9, 0, 0, 0, 0, 0, 0,
|
||||
|
@ -17,16 +17,16 @@ using namespace TI::TMS;
|
||||
|
||||
namespace {
|
||||
|
||||
const uint8_t StatusInterrupt = 0x80;
|
||||
const uint8_t StatusSpriteOverflow = 0x40;
|
||||
constexpr uint8_t StatusInterrupt = 0x80;
|
||||
constexpr uint8_t StatusSpriteOverflow = 0x40;
|
||||
|
||||
const int StatusSpriteCollisionShift = 5;
|
||||
const uint8_t StatusSpriteCollision = 0x20;
|
||||
constexpr int StatusSpriteCollisionShift = 5;
|
||||
constexpr uint8_t StatusSpriteCollision = 0x20;
|
||||
|
||||
// 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.
|
||||
const unsigned int CRTCyclesPerLine = 1365;
|
||||
const unsigned int CRTCyclesDivider = 4;
|
||||
constexpr unsigned int CRTCyclesPerLine = 1365;
|
||||
constexpr unsigned int CRTCyclesDivider = 4;
|
||||
|
||||
struct ReverseTable {
|
||||
std::uint8_t map[256];
|
||||
@ -352,8 +352,7 @@ void TMS9918::run_for(const HalfCycles cycles) {
|
||||
// Output video stream.
|
||||
// --------------------
|
||||
|
||||
#define intersect(left, right, code) \
|
||||
{ \
|
||||
#define intersect(left, right, code) { \
|
||||
const int start = std::max(read_pointer_.column, left); \
|
||||
const int end = std::min(end_column, right); \
|
||||
if(end > start) {\
|
||||
@ -625,7 +624,7 @@ void TMS9918::set_register(int address, uint8_t value) {
|
||||
|
||||
uint8_t TMS9918::get_current_line() {
|
||||
// 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 =
|
||||
(write_pointer_.column < row_change_position)
|
||||
? (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;
|
||||
memset(&sprite_buffer[start], 0, size_t(end - start)*sizeof(sprite_buffer[0]));
|
||||
|
||||
static const 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 uint32_t sprite_colour_selection_masks[2] = {0x00000000, 0xffffffff};
|
||||
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.
|
||||
const int shifter_target = sprites_16x16_ ? 32 : 16;
|
||||
|
@ -72,8 +72,8 @@ AY38910::AY38910(Personality personality, Concurrency::DeferringAsyncTaskQueue &
|
||||
|
||||
void AY38910::set_sample_volume_range(std::int16_t range) {
|
||||
// set up volume lookup table
|
||||
const float max_volume = static_cast<float>(range) / 3.0f; // As there are three channels.
|
||||
const float root_two = sqrtf(2.0f);
|
||||
const float max_volume = float(range) / 3.0f; // As there are three channels.
|
||||
constexpr float root_two = 1.414213562373095f;
|
||||
for(int v = 0; v < 32; v++) {
|
||||
volumes_[v] = int(max_volume / powf(root_two, float(v ^ 0x1f) / 2.0f));
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ class DiskII final:
|
||||
The value returned by @c read_address if accessing that address
|
||||
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.
|
||||
void run_for(const Cycles cycles);
|
||||
|
@ -13,15 +13,15 @@
|
||||
using namespace Apple;
|
||||
|
||||
namespace {
|
||||
const int CA0 = 1 << 0;
|
||||
const int CA1 = 1 << 1;
|
||||
const int CA2 = 1 << 2;
|
||||
const int LSTRB = 1 << 3;
|
||||
const int ENABLE = 1 << 4;
|
||||
const int DRIVESEL = 1 << 5; /* This means drive select, like on the original Disk II. */
|
||||
const int Q6 = 1 << 6;
|
||||
const 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 CA0 = 1 << 0;
|
||||
constexpr int CA1 = 1 << 1;
|
||||
constexpr int CA2 = 1 << 2;
|
||||
constexpr int LSTRB = 1 << 3;
|
||||
constexpr int ENABLE = 1 << 4;
|
||||
constexpr int DRIVESEL = 1 << 5; /* This means drive select, like on the original Disk II. */
|
||||
constexpr int Q6 = 1 << 6;
|
||||
constexpr int Q7 = 1 << 7;
|
||||
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) :
|
||||
|
@ -70,8 +70,8 @@ void AsyncTaskQueue::flush() {
|
||||
#ifdef __APPLE__
|
||||
dispatch_sync(serial_dispatch_queue_, ^{});
|
||||
#else
|
||||
std::shared_ptr<std::mutex> flush_mutex(new std::mutex);
|
||||
std::shared_ptr<std::condition_variable> flush_condition(new std::condition_variable);
|
||||
auto flush_mutex = std::make_shared<std::mutex>();
|
||||
auto flush_condition = std::make_shared<std::condition_variable>();
|
||||
std::unique_lock<std::mutex> lock(*flush_mutex);
|
||||
enqueue([=] () {
|
||||
std::unique_lock<std::mutex> inner_lock(*flush_mutex);
|
||||
|
@ -14,7 +14,7 @@ namespace {
|
||||
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) {
|
||||
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::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) {
|
||||
|
@ -509,7 +509,7 @@ class CRTCBusHandler {
|
||||
|
||||
uint8_t mapped_palette_value(uint8_t colour) {
|
||||
#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(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),
|
||||
|
@ -79,7 +79,7 @@ template <Analyser::Static::AppleII::Target::Model model> class ConcreteMachine:
|
||||
void update_video() {
|
||||
video_.run_for(cycles_since_video_update_.flush<Cycles>());
|
||||
}
|
||||
static const int audio_divider = 8;
|
||||
static constexpr int audio_divider = 8;
|
||||
void update_audio() {
|
||||
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_),
|
||||
speaker_(audio_toggle_) {
|
||||
// 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
|
||||
// equal to the number of cycles of work the 6502 will actually achieve. Which is less than
|
||||
|
@ -203,7 +203,7 @@ class VideoBase {
|
||||
std::array<uint8_t, 40> auxiliary_stream_;
|
||||
|
||||
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
|
||||
// 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.
|
||||
*/
|
||||
static const int first_sync_line = 220; // A complete guess. Information needed.
|
||||
static const int first_sync_column = 49; // Also a guess.
|
||||
static const int sync_length = 4; // One of the two likely candidates.
|
||||
constexpr int first_sync_line = 220; // A complete guess. Information needed.
|
||||
constexpr int first_sync_column = 49; // Also a guess.
|
||||
constexpr int sync_length = 4; // One of the two likely candidates.
|
||||
|
||||
int int_cycles = int(cycles.as_integral());
|
||||
while(int_cycles) {
|
||||
|
@ -18,7 +18,7 @@
|
||||
namespace Apple {
|
||||
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.
|
||||
|
@ -49,7 +49,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
const int CLOCK_RATE = 7833600;
|
||||
constexpr int CLOCK_RATE = 7833600;
|
||||
|
||||
}
|
||||
|
||||
|
@ -17,11 +17,11 @@
|
||||
namespace Apple {
|
||||
namespace Macintosh {
|
||||
|
||||
static const HalfCycles line_length(704);
|
||||
static const int number_of_lines = 370;
|
||||
static const HalfCycles frame_length(line_length * HalfCycles(number_of_lines));
|
||||
static const int sync_start = 36;
|
||||
static const int sync_end = 38;
|
||||
static constexpr HalfCycles line_length(704);
|
||||
static constexpr int number_of_lines = 370;
|
||||
static constexpr HalfCycles frame_length(line_length * HalfCycles(number_of_lines));
|
||||
static constexpr int sync_start = 36;
|
||||
static constexpr int sync_end = 38;
|
||||
|
||||
/*!
|
||||
Models the 68000-era Macintosh video hardware, producing a 512x348 pixel image,
|
||||
|
@ -13,11 +13,11 @@
|
||||
|
||||
using namespace Atari2600;
|
||||
namespace {
|
||||
const int cycles_per_line = 228;
|
||||
const int first_pixel_cycle = 68;
|
||||
constexpr int cycles_per_line = 228;
|
||||
constexpr int first_pixel_cycle = 68;
|
||||
|
||||
const int sync_flag = 0x1;
|
||||
const int blank_flag = 0x2;
|
||||
constexpr int sync_flag = 0x1;
|
||||
constexpr int blank_flag = 0x2;
|
||||
|
||||
uint8_t reverse_table[256];
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ namespace Atari2600 {
|
||||
|
||||
// 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.
|
||||
const int CPUTicksPerAudioTick = 2;
|
||||
constexpr int CPUTicksPerAudioTick = 2;
|
||||
|
||||
class TIASound: public Outputs::Speaker::SampleSource {
|
||||
public:
|
||||
|
@ -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;
|
||||
class ConcreteMachine:
|
||||
|
@ -626,9 +626,9 @@ void Video::Shifter::output_pixels(int duration, OutputBpp bpp) {
|
||||
} break;
|
||||
case OutputBpp::Two: {
|
||||
#if TARGET_RT_BIG_ENDIAN
|
||||
const int upper = 0;
|
||||
constexpr int upper = 0;
|
||||
#else
|
||||
const int upper = 1;
|
||||
constexpr int upper = 1;
|
||||
#endif
|
||||
if(pixel_buffer_) {
|
||||
while(duration--) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "../../Analyser/Dynamic/ConfidenceCounter.hpp"
|
||||
|
||||
namespace {
|
||||
const int sn76489_divider = 2;
|
||||
constexpr int sn76489_divider = 2;
|
||||
}
|
||||
|
||||
namespace Coleco {
|
||||
|
@ -646,8 +646,7 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
void type_string(const std::string &string) override final {
|
||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper());
|
||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
||||
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
|
||||
}
|
||||
|
||||
void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape) override final {
|
||||
|
@ -409,8 +409,7 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
void type_string(const std::string &string) override final {
|
||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper());
|
||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
||||
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>());
|
||||
}
|
||||
|
||||
KeyboardMapper *get_keyboard_mapper() override {
|
||||
|
@ -22,7 +22,7 @@ class SoundGenerator: public ::Outputs::Speaker::SampleSource {
|
||||
|
||||
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.
|
||||
void get_samples(std::size_t number_of_samples, int16_t *target);
|
||||
|
@ -16,24 +16,24 @@ using namespace Electron;
|
||||
#define graphics_column(v) ((((v) & 127) - first_graphics_cycle + 128) & 127)
|
||||
|
||||
namespace {
|
||||
static const int cycles_per_line = 128;
|
||||
static const int lines_per_frame = 625;
|
||||
static const int cycles_per_frame = lines_per_frame * cycles_per_line;
|
||||
static const int crt_cycles_multiplier = 8;
|
||||
static const int crt_cycles_per_line = crt_cycles_multiplier * cycles_per_line;
|
||||
static constexpr int cycles_per_line = 128;
|
||||
static constexpr int lines_per_frame = 625;
|
||||
static constexpr int cycles_per_frame = lines_per_frame * cycles_per_line;
|
||||
static constexpr int crt_cycles_multiplier = 8;
|
||||
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
|
||||
// with pixels in field 2 will be 20+field_divider_line
|
||||
static const int first_graphics_line = 31;
|
||||
static const int first_graphics_cycle = 33;
|
||||
static constexpr int first_graphics_line = 31;
|
||||
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 const 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 const int display_end_interrupt_2 = (first_graphics_line + field_divider_line + display_end_interrupt_line)*cycles_per_line;
|
||||
static constexpr int real_time_clock_interrupt_1 = 16704;
|
||||
static constexpr int real_time_clock_interrupt_2 = 56704;
|
||||
static constexpr int display_end_interrupt_1 = (first_graphics_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
|
||||
@ -272,7 +272,7 @@ void VideoOutput::set_register(int address, uint8_t value) {
|
||||
break;
|
||||
case 0x08: case 0x09: case 0x0a: case 0x0b:
|
||||
case 0x0c: case 0x0d: case 0x0e: case 0x0f: {
|
||||
static const int registers[4][4] = {
|
||||
constexpr int registers[4][4] = {
|
||||
{10, 8, 2, 0},
|
||||
{14, 12, 6, 4},
|
||||
{15, 13, 7, 5},
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <iostream>
|
||||
|
||||
namespace {
|
||||
const int sn76489_divider = 2;
|
||||
constexpr int sn76489_divider = 2;
|
||||
}
|
||||
|
||||
namespace Sega {
|
||||
|
@ -336,8 +336,7 @@ template<bool is_zx81> class ConcreteMachine:
|
||||
}
|
||||
|
||||
void type_string(const std::string &string) override final {
|
||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper(is_zx81));
|
||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
||||
Utility::TypeRecipient::add_typer(string, std::make_unique<CharacterMapper>(is_zx81));
|
||||
}
|
||||
|
||||
// MARK: - Keyboard
|
||||
|
@ -67,7 +67,7 @@
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Release"
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
enableASanStackUseAfterReturn = "YES"
|
||||
|
@ -48,7 +48,7 @@ ROMMachine::ROMFetcher CSROMFetcher(std::vector<ROMMachine::ROM> *missing_roms)
|
||||
}
|
||||
}
|
||||
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;
|
||||
results.emplace_back(std::move(data));
|
||||
}
|
||||
|
@ -10,8 +10,7 @@
|
||||
|
||||
@implementation NSData (StdVector)
|
||||
|
||||
- (std::vector<uint8_t>)stdVector8
|
||||
{
|
||||
- (std::vector<uint8_t>)stdVector8 {
|
||||
uint8_t *bytes8 = (uint8_t *)self.bytes;
|
||||
return std::vector<uint8_t>(bytes8, bytes8 + self.length);
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
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->has_dfs = !!dfs;
|
||||
target->has_adfs = !!adfs;
|
||||
@ -58,7 +58,7 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::AmstradCPC::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::AmstradCPC;
|
||||
switch(model) {
|
||||
case CSMachineCPCModel464: target->model = Analyser::Static::AmstradCPC::Target::Model::CPC464; break;
|
||||
@ -74,7 +74,7 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
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->has_disk_drive = !!hasDiskDrive;
|
||||
switch(region) {
|
||||
@ -91,7 +91,7 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Oric::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::Oric;
|
||||
switch(model) {
|
||||
case CSMachineOricModelOric1: target->rom = Target::ROM::BASIC10; break;
|
||||
@ -112,7 +112,7 @@
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Commodore::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::Vic20;
|
||||
switch(region) {
|
||||
case CSMachineVic20RegionDanish: target->region = Target::Region::Danish; break;
|
||||
@ -145,7 +145,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
self = [super init];
|
||||
if(self) {
|
||||
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->is_ZX81 = false;
|
||||
target->ZX80_uses_ZX81_ROM = !!useZX81ROM;
|
||||
@ -159,7 +159,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
self = [super init];
|
||||
if(self) {
|
||||
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->is_ZX81 = true;
|
||||
target->memory_model = ZX8081MemoryModelFromSize(memorySize);
|
||||
@ -172,7 +172,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::AppleII::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::AppleII;
|
||||
switch(model) {
|
||||
default: target->model = Target::Model::II; break;
|
||||
@ -195,7 +195,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Macintosh::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::Macintosh;
|
||||
|
||||
using Model = Target::Model;
|
||||
@ -216,7 +216,7 @@ static Analyser::Static::ZX8081::Target::MemoryModel ZX8081MemoryModelFromSize(K
|
||||
self = [super init];
|
||||
if(self) {
|
||||
using Target = Analyser::Static::Macintosh::Target;
|
||||
std::unique_ptr<Target> target(new Target);
|
||||
auto target = std::make_unique<Target>();
|
||||
target->machine = Analyser::Machine::AtariST;
|
||||
_targets.push_back(std::move(target));
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ using PagingModel = Analyser::Static::Atari2600::Target::PagingModel;
|
||||
@end
|
||||
|
||||
@implementation AtariROMRecord
|
||||
+ (instancetype)recordWithPagingModel:(PagingModel)pagingModel usesSuperchip:(BOOL)usesSuperchip
|
||||
{
|
||||
+ (instancetype)recordWithPagingModel:(PagingModel)pagingModel usesSuperchip:(BOOL)usesSuperchip {
|
||||
AtariROMRecord *record = [[AtariROMRecord alloc] init];
|
||||
record->_pagingModel = pagingModel;
|
||||
record->_usesSuperchip = usesSuperchip;
|
||||
@ -578,11 +577,9 @@ static NSDictionary<NSString *, AtariROMRecord *> *romRecordsBySHA1 = @{
|
||||
|
||||
@implementation AtariStaticAnalyserTests
|
||||
|
||||
- (void)testROMsOfSize:(NSInteger)size
|
||||
{
|
||||
- (void)testROMsOfSize:(NSInteger)size {
|
||||
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];
|
||||
|
||||
// get a SHA1 for the file
|
||||
|
@ -15,18 +15,15 @@
|
||||
|
||||
@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();
|
||||
for(size_t c = 0; c < length; c++)
|
||||
generator.add(data[c]);
|
||||
return generator.get_value();
|
||||
}
|
||||
|
||||
- (void)testIDMark
|
||||
{
|
||||
uint8_t IDMark[] =
|
||||
{
|
||||
- (void)testIDMark {
|
||||
uint8_t IDMark[] = {
|
||||
0xa1, 0xa1, 0xa1, 0xfe, 0x00, 0x00, 0x01, 0x01
|
||||
};
|
||||
uint16_t crc = 0xfa0c;
|
||||
@ -36,10 +33,8 @@
|
||||
XCTAssert(computedCRC == crc, @"Calculated CRC should have been %04x, was %04x", crc, computedCRC);
|
||||
}
|
||||
|
||||
- (void)testData
|
||||
{
|
||||
uint8_t sectorData[] =
|
||||
{
|
||||
- (void)testData {
|
||||
uint8_t sectorData[] = {
|
||||
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,
|
||||
0x52, 0x49, 0x43, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
|
@ -22,8 +22,7 @@
|
||||
[super setUp];
|
||||
|
||||
// Create a valid OpenGL context, so that a VDP can be constructed.
|
||||
NSOpenGLPixelFormatAttribute attributes[] =
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attributes[] = {
|
||||
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||
0
|
||||
};
|
||||
|
@ -15,21 +15,18 @@
|
||||
|
||||
@implementation PCMSegmentEventSourceTests
|
||||
|
||||
- (Storage::Disk::PCMSegmentEventSource)segmentSource
|
||||
{
|
||||
- (Storage::Disk::PCMSegmentEventSource)segmentSource {
|
||||
std::vector<uint8_t> data = {0xff, 0x00, 0xff, 0x00};
|
||||
Storage::Disk::PCMSegment alternatingFFs(Storage::Time(1, 10), data.size()*8, data);
|
||||
return Storage::Disk::PCMSegmentEventSource(alternatingFFs);
|
||||
}
|
||||
|
||||
- (void)testCentring
|
||||
{
|
||||
- (void)testCentring {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.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 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");
|
||||
}
|
||||
|
||||
- (void)testLongerGap
|
||||
{
|
||||
- (void)testLongerGap {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
- (void)testTermination
|
||||
{
|
||||
- (void)testTermination {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
|
||||
Storage::Time total_time;
|
||||
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");
|
||||
}
|
||||
|
||||
- (void)testReset
|
||||
{
|
||||
- (void)testReset {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
|
||||
for(int c = 0; c < 8; c++) segmentSource.get_next_event();
|
||||
segmentSource.reset();
|
||||
[self assertFirstTwoEventLengthsForSource:segmentSource];
|
||||
}
|
||||
|
||||
- (void)testSeekToSecondBit
|
||||
{
|
||||
- (void)testSeekToSecondBit {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
|
||||
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");
|
||||
}
|
||||
|
||||
- (void)testSeekBeyondFinalBit
|
||||
{
|
||||
- (void)testSeekBeyondFinalBit {
|
||||
Storage::Disk::PCMSegmentEventSource segmentSource = self.segmentSource;
|
||||
Storage::Time target_time(24, 10);
|
||||
|
||||
|
@ -43,7 +43,7 @@ struct BestEffortUpdaterDelegate: public Concurrency::BestEffortUpdater::Delegat
|
||||
|
||||
struct SpeakerDelegate: public Outputs::Speaker::Speaker::Delegate {
|
||||
// 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 {
|
||||
std::lock_guard<std::mutex> lock_guard(audio_buffer_mutex_);
|
||||
@ -106,13 +106,12 @@ class ActivityObserver: public Activity::Observer {
|
||||
lights_.clear();
|
||||
|
||||
// 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 right_x = 1.0f - 2.0f * width;
|
||||
float y = 1.0f - 2.0f * height;
|
||||
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::unique_ptr<Outputs::Display::OpenGL::Rectangle>(new Outputs::Display::OpenGL::Rectangle(right_x, y, width, height))));
|
||||
lights_.emplace(std::make_pair(drive, std::make_unique<Outputs::Display::OpenGL::Rectangle>(right_x, y, width, height)));
|
||||
y -= height * 2.0f;
|
||||
}
|
||||
|
||||
@ -424,7 +423,7 @@ int main(int argc, char *argv[]) {
|
||||
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);
|
||||
data->resize(std::ftell(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) {
|
||||
|
||||
const int millisecondsHorizontalRetraceTime = 7; // Source: Dictionary of Video and Television Technology, p. 234.
|
||||
const int scanlinesVerticalRetraceTime = 8; // Source: ibid.
|
||||
constexpr int millisecondsHorizontalRetraceTime = 7; // Source: Dictionary of Video and Television Technology, p. 234.
|
||||
constexpr int scanlinesVerticalRetraceTime = 8; // Source: ibid.
|
||||
|
||||
// To quote:
|
||||
//
|
||||
|
@ -470,11 +470,11 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader() const {
|
||||
"fragColour = vec4(fragColour3, 0.64);"
|
||||
"}";
|
||||
|
||||
return std::unique_ptr<Shader>(new Shader(
|
||||
return std::make_unique<Shader>(
|
||||
vertex_shader,
|
||||
fragment_shader,
|
||||
bindings(ShaderType::Conversion)
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
std::unique_ptr<Shader> ScanTarget::composition_shader() const {
|
||||
@ -544,11 +544,11 @@ std::unique_ptr<Shader> ScanTarget::composition_shader() const {
|
||||
break;
|
||||
}
|
||||
|
||||
return std::unique_ptr<Shader>(new Shader(
|
||||
return std::make_unique<Shader>(
|
||||
vertex_shader,
|
||||
fragment_shader + "}",
|
||||
bindings(ShaderType::Composition)
|
||||
));
|
||||
);
|
||||
}
|
||||
|
||||
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);"
|
||||
"}";
|
||||
|
||||
return std::unique_ptr<Shader>(new Shader(
|
||||
return std::make_unique<Shader>(
|
||||
vertex_shader,
|
||||
fragment_shader,
|
||||
bindings(ShaderType::QAMSeparation)
|
||||
));
|
||||
);
|
||||
}
|
||||
|
@ -51,45 +51,45 @@ namespace MC68000 {
|
||||
struct Microcycle {
|
||||
/// 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.
|
||||
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
|
||||
// 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(),
|
||||
// value8_high(), value8_low() and value16().
|
||||
|
||||
/// 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;
|
||||
/// 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
|
||||
/// 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.
|
||||
static const int Reset = 1 << 4;
|
||||
static constexpr int Reset = 1 << 4;
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
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
|
||||
/// 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
|
||||
/// 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.
|
||||
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
|
||||
/// performed by this Microcycle.
|
||||
|
@ -317,8 +317,8 @@ class ProcessorStorage {
|
||||
// steps detail appropriately.
|
||||
PrepareINTVector,
|
||||
};
|
||||
static const int SourceMask = 1 << 7;
|
||||
static const int DestinationMask = 1 << 6;
|
||||
static constexpr int SourceMask = 1 << 7;
|
||||
static constexpr int DestinationMask = 1 << 6;
|
||||
uint8_t action = uint8_t(Action::None);
|
||||
|
||||
static const uint16_t NoBusProgram = std::numeric_limits<uint16_t>::max();
|
||||
|
@ -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 (?)
|
||||
|
||||
std::shared_ptr<File> file(new File);
|
||||
auto file = std::make_shared<File>();
|
||||
file->data = data;
|
||||
file->isZX81 = false;
|
||||
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 (?)
|
||||
|
||||
std::shared_ptr<File> file(new File);
|
||||
auto file = std::make_shared<File>();
|
||||
file->name = StringFromData(name_data, true);
|
||||
file->data = data;
|
||||
file->isZX81 = true;
|
||||
|
@ -11,8 +11,8 @@
|
||||
#include "Utility/ImplicitSectors.hpp"
|
||||
|
||||
namespace {
|
||||
static const int sectors_per_track = 16;
|
||||
static const int sector_size = 1;
|
||||
constexpr int sectors_per_track = 16;
|
||||
constexpr int sector_size = 1;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
@ -18,8 +18,8 @@
|
||||
using namespace Storage::Disk;
|
||||
|
||||
namespace {
|
||||
const int number_of_tracks = 35;
|
||||
const int bytes_per_sector = 256;
|
||||
constexpr int number_of_tracks = 35;
|
||||
constexpr int bytes_per_sector = 256;
|
||||
}
|
||||
|
||||
AppleDSK::AppleDSK(const std::string &file_name) :
|
||||
|
@ -136,5 +136,5 @@ std::shared_ptr<Track> D64::get_track_at_position(Track::Address address) {
|
||||
Encodings::CommodoreGCR::encode_block(§or_data[target_data_offset], end_of_data);
|
||||
}
|
||||
|
||||
return std::shared_ptr<Track>(new PCMTrack(PCMSegment(data)));
|
||||
return std::make_shared<PCMTrack>(PCMSegment(data));
|
||||
}
|
||||
|
@ -11,9 +11,9 @@
|
||||
#include "Utility/ImplicitSectors.hpp"
|
||||
|
||||
namespace {
|
||||
const int sectors_per_track = 9;
|
||||
const int sector_size = 2;
|
||||
const off_t track_size = (128 << sector_size)*sectors_per_track;
|
||||
constexpr int sectors_per_track = 9;
|
||||
constexpr int sector_size = 2;
|
||||
constexpr off_t track_size = (128 << sector_size)*sectors_per_track;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include "SSD.hpp"
|
||||
|
||||
namespace {
|
||||
static const int sectors_per_track = 10;
|
||||
static const int sector_size = 1;
|
||||
constexpr int sectors_per_track = 10;
|
||||
constexpr int sector_size = 1;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
@ -9,8 +9,8 @@
|
||||
#include "ST.hpp"
|
||||
|
||||
namespace {
|
||||
static const int sectors_per_track = 10;
|
||||
static const int sector_size = 2;
|
||||
constexpr int sectors_per_track = 10;
|
||||
constexpr int sector_size = 2;
|
||||
}
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
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) {
|
||||
|
@ -122,7 +122,7 @@ bool Drive::get_tachometer() {
|
||||
// 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
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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.
|
||||
// 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) {
|
||||
random_interval_ = interval - safe_gain_period;
|
||||
interval = safe_gain_period;
|
||||
|
@ -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.
|
||||
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) :
|
||||
@ -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) {
|
||||
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) {
|
||||
return std::unique_ptr<Encoder>(new FMEncoder(target));
|
||||
return std::make_unique<FMEncoder>(target);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ namespace SCSI {
|
||||
|
||||
typedef int BusState;
|
||||
|
||||
static const BusState DefaultBusState = 0;
|
||||
static constexpr BusState DefaultBusState = 0;
|
||||
|
||||
/*!
|
||||
SCSI bus state is encoded entirely within an int.
|
||||
|
@ -19,8 +19,7 @@ CommodoreTAP::CommodoreTAP(const std::string &file_name) :
|
||||
throw ErrorNotCommodoreTAP;
|
||||
|
||||
// check the file version
|
||||
switch(file_.get8())
|
||||
{
|
||||
switch(file_.get8()) {
|
||||
case 0: updated_layout_ = false; break;
|
||||
case 1: updated_layout_ = true; break;
|
||||
default: throw ErrorNotCommodoreTAP;
|
||||
@ -40,52 +39,41 @@ CommodoreTAP::CommodoreTAP(const std::string &file_name) :
|
||||
current_pulse_.type = Pulse::High;
|
||||
}
|
||||
|
||||
void CommodoreTAP::virtual_reset()
|
||||
{
|
||||
void CommodoreTAP::virtual_reset() {
|
||||
file_.seek(0x14, SEEK_SET);
|
||||
current_pulse_.type = Pulse::High;
|
||||
is_at_end_ = false;
|
||||
}
|
||||
|
||||
bool CommodoreTAP::is_at_end()
|
||||
{
|
||||
bool CommodoreTAP::is_at_end() {
|
||||
return is_at_end_;
|
||||
}
|
||||
|
||||
Storage::Tape::Tape::Pulse CommodoreTAP::virtual_get_next_pulse()
|
||||
{
|
||||
if(is_at_end_)
|
||||
{
|
||||
Storage::Tape::Tape::Pulse CommodoreTAP::virtual_get_next_pulse() {
|
||||
if(is_at_end_) {
|
||||
return current_pulse_;
|
||||
}
|
||||
|
||||
if(current_pulse_.type == Pulse::High)
|
||||
{
|
||||
if(current_pulse_.type == Pulse::High) {
|
||||
uint32_t next_length;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
next_length = file_.get24le();
|
||||
}
|
||||
|
||||
if(file_.eof())
|
||||
{
|
||||
if(file_.eof()) {
|
||||
is_at_end_ = true;
|
||||
current_pulse_.length.length = current_pulse_.length.clock_rate;
|
||||
current_pulse_.type = Pulse::Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
current_pulse_.length.length = next_length;
|
||||
current_pulse_.type = Pulse::Low;
|
||||
}
|
||||
}
|
||||
else
|
||||
} else {
|
||||
current_pulse_.type = Pulse::High;
|
||||
}
|
||||
|
||||
return current_pulse_;
|
||||
}
|
||||
|
@ -65,10 +65,10 @@ PRG::PRG(const std::string &file_name) :
|
||||
|
||||
Storage::Tape::Tape::Pulse PRG::virtual_get_next_pulse() {
|
||||
// these are all microseconds per pole
|
||||
static const unsigned int leader_zero_length = 179;
|
||||
static const unsigned int zero_length = 169;
|
||||
static const unsigned int one_length = 247;
|
||||
static const unsigned int marker_length = 328;
|
||||
constexpr unsigned int leader_zero_length = 179;
|
||||
constexpr unsigned int zero_length = 169;
|
||||
constexpr unsigned int one_length = 247;
|
||||
constexpr unsigned int marker_length = 328;
|
||||
|
||||
bit_phase_ = (bit_phase_+1)&3;
|
||||
if(!bit_phase_) get_next_output_token();
|
||||
@ -100,10 +100,10 @@ bool PRG::is_at_end() {
|
||||
}
|
||||
|
||||
void PRG::get_next_output_token() {
|
||||
static const int block_length = 192; // not counting the checksum
|
||||
static const int countdown_bytes = 9;
|
||||
static const int leadin_length = 20000;
|
||||
static const int block_leadin_length = 5000;
|
||||
constexpr int block_length = 192; // not counting the checksum
|
||||
constexpr int countdown_bytes = 9;
|
||||
constexpr int leadin_length = 20000;
|
||||
constexpr int block_leadin_length = 5000;
|
||||
|
||||
if(file_phase_ == FilePhaseHeaderDataGap || file_phase_ == FilePhaseAtEnd) {
|
||||
output_token_ = Silence;
|
||||
|
@ -11,7 +11,7 @@
|
||||
using namespace Storage::Tape::Acorn;
|
||||
|
||||
namespace {
|
||||
const int PLLClockRate = 1920000;
|
||||
constexpr int PLLClockRate = 1920000;
|
||||
}
|
||||
|
||||
Parser::Parser(): crc_(0x1021) {
|
||||
|
@ -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.
|
||||
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>(
|
||||
get_next_header_body(tape, true),
|
||||
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.
|
||||
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>(
|
||||
get_next_data_body(tape, true),
|
||||
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.
|
||||
*/
|
||||
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(!first_copy) return second_copy;
|
||||
if(!second_copy) return first_copy;
|
||||
@ -67,9 +64,8 @@ template<class ObjectType>
|
||||
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> header(new Header);
|
||||
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>();
|
||||
reset_error_flag();
|
||||
|
||||
// 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
|
||||
uint8_t header_type = get_next_byte(tape);
|
||||
switch(header_type)
|
||||
{
|
||||
switch(header_type) {
|
||||
default: header->type = Header::Unknown; break;
|
||||
case 0x01: header->type = Header::RelocatableProgram; 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
|
||||
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));
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
// 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->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->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) {
|
||||
switch(type)
|
||||
{
|
||||
switch(type) {
|
||||
default: target[0] = 0xff; break;
|
||||
case Header::RelocatableProgram: target[0] = 0x01; 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::unique_ptr<Data> Parser::get_next_data_body(const std::shared_ptr<Storage::Tape::Tape> &tape, bool is_original)
|
||||
{
|
||||
std::unique_ptr<Data> data(new Data);
|
||||
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>();
|
||||
reset_error_flag();
|
||||
|
||||
// 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();
|
||||
|
||||
// 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);
|
||||
if(start_symbol != SymbolType::Word) break;
|
||||
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.
|
||||
*/
|
||||
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};
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
while(!tape->is_at_end()) {
|
||||
memmove(landing_zone, &landing_zone[1], sizeof(uint8_t) * 8);
|
||||
landing_zone[8] = get_next_byte(tape);
|
||||
|
||||
bool is_landing_zone = true;
|
||||
for(int c = 0; c < 9; c++)
|
||||
{
|
||||
if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c)
|
||||
{
|
||||
for(int c = 0; c < 9; c++) {
|
||||
if(landing_zone[c] != ((is_original ? 0x80 : 0x00) | 0x9) - c) {
|
||||
is_landing_zone = false;
|
||||
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
|
||||
and returns.
|
||||
*/
|
||||
void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol)
|
||||
{
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
void Parser::proceed_to_symbol(const std::shared_ptr<Storage::Tape::Tape> &tape, SymbolType required_symbol) {
|
||||
while(!tape->is_at_end()) {
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
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.
|
||||
*/
|
||||
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);
|
||||
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
|
||||
::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 c = 9;
|
||||
while(c--)
|
||||
{
|
||||
while(c--) {
|
||||
SymbolType next_symbol = get_next_symbol(tape);
|
||||
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);
|
||||
@ -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.
|
||||
*/
|
||||
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);
|
||||
value |= get_next_byte(tape) << 8;
|
||||
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
|
||||
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:
|
||||
// short: 182us => 0.000364s cycle
|
||||
// medium: 262us => 0.000524s cycle
|
||||
// long: 342us => 0.000684s cycle
|
||||
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);
|
||||
else if(wave_period_ >= 0.000604) push_wave(WaveType::Long);
|
||||
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,
|
||||
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[0] == WaveType::Long && waves[1] == WaveType::Medium)
|
||||
{
|
||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Medium) {
|
||||
push_symbol(SymbolType::Word, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Short)
|
||||
{
|
||||
if(waves[0] == WaveType::Long && waves[1] == WaveType::Short) {
|
||||
push_symbol(SymbolType::EndOfBlock, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium)
|
||||
{
|
||||
if(waves[0] == WaveType::Short && waves[1] == WaveType::Medium) {
|
||||
push_symbol(SymbolType::Zero, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short)
|
||||
{
|
||||
if(waves[0] == WaveType::Medium && waves[1] == WaveType::Short) {
|
||||
push_symbol(SymbolType::One, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
if(waves[0] == WaveType::Short)
|
||||
{
|
||||
if(waves[0] == WaveType::Short) {
|
||||
push_symbol(SymbolType::LeadIn, 1);
|
||||
return;
|
||||
}
|
||||
|
@ -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.
|
||||
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->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
|
||||
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;
|
||||
while(!tape_player.get_tape()->is_at_end()) {
|
||||
// Find next transition.
|
||||
@ -126,9 +126,9 @@ int Parser::get_byte(const FileSpeed &speed, Storage::Tape::BinaryTapePlayer &ta
|
||||
int result = 0;
|
||||
const int cycles_per_window = static_cast<int>(
|
||||
0.5f +
|
||||
static_cast<float>(speed.low_high_disrimination_duration) *
|
||||
float(speed.low_high_disrimination_duration) *
|
||||
0.0000173f *
|
||||
static_cast<float>(tape_player.get_input_clock_rate())
|
||||
float(tape_player.get_input_clock_rate())
|
||||
);
|
||||
int bits_left = 8;
|
||||
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 cycles_remaining = cycles_per_window;
|
||||
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);
|
||||
|
||||
cycles_remaining -= cycles_to_run_for;
|
||||
|
@ -10,15 +10,13 @@
|
||||
|
||||
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;
|
||||
cycle_length_ = 0.0f;
|
||||
|
||||
int result = 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);
|
||||
if(!bit_count && symbol != SymbolType::Zero) continue;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
while(!tape->is_at_end())
|
||||
{
|
||||
SymbolType symbol = get_next_symbol(tape);
|
||||
switch(symbol)
|
||||
{
|
||||
while(!tape->is_at_end()) {
|
||||
const SymbolType symbol = get_next_symbol(tape);
|
||||
switch(symbol) {
|
||||
case SymbolType::FoundSlow: return false;
|
||||
case SymbolType::FoundFast: return true;
|
||||
default: break;
|
||||
@ -45,15 +40,13 @@ bool Parser::sync_and_get_encoding_speed(const std::shared_ptr<Storage::Tape::Ta
|
||||
return false;
|
||||
}
|
||||
|
||||
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse)
|
||||
{
|
||||
const float maximum_short_length = 0.000512f;
|
||||
const float maximum_medium_length = 0.000728f;
|
||||
const float maximum_long_length = 0.001456f;
|
||||
void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
|
||||
constexpr float maximum_short_length = 0.000512f;
|
||||
constexpr float maximum_medium_length = 0.000728f;
|
||||
constexpr float maximum_long_length = 0.001456f;
|
||||
|
||||
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);
|
||||
else if(cycle_length_ < maximum_medium_length) push_wave(WaveType::Medium);
|
||||
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>();
|
||||
}
|
||||
|
||||
void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
{
|
||||
switch(detection_mode_)
|
||||
{
|
||||
void Parser::inspect_waves(const std::vector<WaveType> &waves) {
|
||||
switch(detection_mode_) {
|
||||
case FastZero:
|
||||
if(waves.empty()) return;
|
||||
if(waves[0] == WaveType::Medium)
|
||||
{
|
||||
if(waves[0] == WaveType::Medium) {
|
||||
push_symbol(SymbolType::Zero, 1);
|
||||
return;
|
||||
}
|
||||
@ -80,13 +70,11 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
|
||||
case FastData:
|
||||
if(waves.empty()) return;
|
||||
if(waves[0] == WaveType::Medium)
|
||||
{
|
||||
if(waves[0] == WaveType::Medium) {
|
||||
push_symbol(SymbolType::Zero, 1);
|
||||
return;
|
||||
}
|
||||
if(waves[0] == WaveType::Short)
|
||||
{
|
||||
if(waves[0] == WaveType::Short) {
|
||||
push_symbol(SymbolType::One, 1);
|
||||
return;
|
||||
}
|
||||
@ -94,8 +82,7 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
|
||||
case SlowZero:
|
||||
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);
|
||||
return;
|
||||
}
|
||||
@ -103,12 +90,10 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
|
||||
case SlowData:
|
||||
#define CHECK_RUN(length, type, symbol) \
|
||||
if(waves.size() >= length)\
|
||||
{\
|
||||
if(waves.size() >= length) {\
|
||||
std::size_t c;\
|
||||
for(c = 0; c < length; c++) if(waves[c] != type) break;\
|
||||
if(c == length)\
|
||||
{\
|
||||
if(c == length) {\
|
||||
push_symbol(symbol, length);\
|
||||
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
|
||||
break;
|
||||
|
||||
case Sync:
|
||||
{
|
||||
case Sync: {
|
||||
// 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::Short, 16},
|
||||
{WaveType::Long, 4},
|
||||
@ -133,8 +116,7 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
{WaveType::Short, 8},
|
||||
{WaveType::Unrecognised}
|
||||
};
|
||||
Pattern fast_sync[] =
|
||||
{
|
||||
const Pattern fast_sync[] = {
|
||||
{WaveType::Medium, 2},
|
||||
{WaveType::Short, 2},
|
||||
{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 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);
|
||||
return;
|
||||
}
|
||||
if(fast_sync_matching_depth == 10)
|
||||
{
|
||||
if(fast_sync_matching_depth == 10) {
|
||||
push_symbol(SymbolType::FoundFast, 10);
|
||||
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));
|
||||
remove_waves(least_depth ? least_depth : 1);
|
||||
}
|
||||
@ -171,17 +150,14 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves)
|
||||
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;
|
||||
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;
|
||||
depth++;
|
||||
pattern_depth++;
|
||||
if(pattern_depth == pattern->count)
|
||||
{
|
||||
if(pattern_depth == pattern->count) {
|
||||
pattern_depth = 0;
|
||||
pattern++;
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ class Parser: public Storage::Tape::PulseClassificationParser<WaveType, SymbolTy
|
||||
WaveType type;
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
|
@ -29,9 +29,9 @@ void Parser::process_pulse(const Storage::Tape::Tape::Pulse &pulse) {
|
||||
}
|
||||
|
||||
void Parser::post_pulse() {
|
||||
const float expected_pulse_length = 300.0f / 1000000.0f;
|
||||
const float expected_gap_length = 1300.0f / 1000000.0f;
|
||||
float pulse_time = pulse_time_.get<float>();
|
||||
constexpr float expected_pulse_length = 300.0f / 1000000.0f;
|
||||
constexpr float expected_gap_length = 1300.0f / 1000000.0f;
|
||||
auto pulse_time = pulse_time_.get<float>();
|
||||
|
||||
if(pulse_time > expected_gap_length * 1.25f) {
|
||||
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;
|
||||
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;
|
||||
while(!is_at_end(tape)) {
|
||||
byte = get_next_byte(tape);
|
||||
|
Loading…
Reference in New Issue
Block a user