2021-03-17 16:38:37 +00:00
|
|
|
//
|
|
|
|
// StaticAnalyser.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 17/03/2021.
|
|
|
|
// Copyright © 2021 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "StaticAnalyser.hpp"
|
|
|
|
|
2021-03-22 23:53:51 +00:00
|
|
|
#include "../../../Storage/Disk/Encodings/MFM/Parser.hpp"
|
2021-03-18 02:09:44 +00:00
|
|
|
#include "../../../Storage/Tape/Parsers/Spectrum.hpp"
|
2021-03-22 23:53:51 +00:00
|
|
|
|
2021-03-18 14:18:17 +00:00
|
|
|
#include "Target.hpp"
|
2021-03-18 02:09:44 +00:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
bool IsSpectrumTape(const std::shared_ptr<Storage::Tape::Tape> &tape) {
|
|
|
|
using Parser = Storage::Tape::ZXSpectrum::Parser;
|
|
|
|
Parser parser(Parser::MachineType::ZXSpectrum);
|
|
|
|
|
|
|
|
while(true) {
|
|
|
|
const auto block = parser.find_block(tape);
|
|
|
|
if(!block) break;
|
|
|
|
|
|
|
|
// Check for a Spectrum header block.
|
|
|
|
if(block->type == 0x00) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-03-22 23:53:51 +00:00
|
|
|
bool IsSpectrumDisk(const std::shared_ptr<Storage::Disk::Disk> &disk) {
|
|
|
|
Storage::Encodings::MFM::Parser parser(true, disk);
|
|
|
|
|
|
|
|
// Get logical sector 1; the Spectrum appears to support various physical
|
|
|
|
// sectors as sector 1.
|
|
|
|
Storage::Encodings::MFM::Sector *boot_sector = nullptr;
|
|
|
|
uint8_t sector_mask = 0;
|
|
|
|
while(!boot_sector) {
|
|
|
|
boot_sector = parser.get_sector(0, 0, sector_mask + 1);
|
|
|
|
sector_mask += 0x40;
|
|
|
|
if(!sector_mask) break;
|
|
|
|
}
|
|
|
|
if(!boot_sector) return false;
|
|
|
|
|
|
|
|
// Test that the contents of the boot sector sum to 3, modulo 256.
|
|
|
|
uint8_t byte_sum = 0;
|
|
|
|
for(auto byte: boot_sector->samples[0]) {
|
|
|
|
byte_sum += byte;
|
|
|
|
}
|
|
|
|
return byte_sum == 3;
|
|
|
|
}
|
|
|
|
|
2021-03-18 02:09:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Analyser::Static::TargetList Analyser::Static::ZXSpectrum::GetTargets(const Media &media, const std::string &, TargetPlatform::IntType) {
|
|
|
|
TargetList destination;
|
2021-03-18 14:18:17 +00:00
|
|
|
auto target = std::make_unique<Target>();
|
2021-03-18 02:09:44 +00:00
|
|
|
target->confidence = 0.5;
|
|
|
|
|
|
|
|
if(!media.tapes.empty()) {
|
|
|
|
bool has_spectrum_tape = false;
|
|
|
|
for(auto &tape: media.tapes) {
|
|
|
|
has_spectrum_tape |= IsSpectrumTape(tape);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(has_spectrum_tape) {
|
|
|
|
target->media.tapes = media.tapes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-22 23:53:51 +00:00
|
|
|
if(!media.disks.empty()) {
|
|
|
|
bool has_spectrum_disk = false;
|
|
|
|
|
|
|
|
for(auto &disk: media.disks) {
|
|
|
|
has_spectrum_disk |= IsSpectrumDisk(disk);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(has_spectrum_disk) {
|
|
|
|
target->media.disks = media.disks;
|
|
|
|
target->model = Target::Model::Plus3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-18 02:09:44 +00:00
|
|
|
// If any media survived, add the target.
|
2021-03-23 00:12:03 +00:00
|
|
|
if(!target->media.empty()) {
|
|
|
|
target->should_hold_enter = true; // To force entry into the 'loader' and thereby load the media.
|
2021-03-18 02:09:44 +00:00
|
|
|
destination.push_back(std::move(target));
|
2021-03-23 00:12:03 +00:00
|
|
|
}
|
2021-03-18 02:09:44 +00:00
|
|
|
|
|
|
|
return destination;
|
2021-03-17 16:38:37 +00:00
|
|
|
}
|