mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
Closed the loop on Electron analysis for now. Including loading command detection.
This commit is contained in:
parent
d8c0da7ccb
commit
9d7962d6c0
@ -63,14 +63,54 @@ void StaticAnalyser::Acorn::AddTargets(
|
|||||||
const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges,
|
const std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> &cartridges,
|
||||||
std::list<StaticAnalyser::Target> &destination)
|
std::list<StaticAnalyser::Target> &destination)
|
||||||
{
|
{
|
||||||
|
Target target;
|
||||||
|
target.machine = Target::Electron;
|
||||||
|
target.probability = 1.0; // TODO: a proper estimation
|
||||||
|
|
||||||
// strip out inappropriate cartridges
|
// strip out inappropriate cartridges
|
||||||
std::list<std::shared_ptr<Storage::Cartridge::Cartridge>> acornCartridges = AcornCartridgesFrom(cartridges);
|
target.cartridges = AcornCartridgesFrom(cartridges);
|
||||||
|
|
||||||
// if there are any tapes, attempt to get data from the first
|
// if there are any tapes, attempt to get data from the first
|
||||||
if(tapes.size() > 0)
|
if(tapes.size() > 0)
|
||||||
{
|
{
|
||||||
std::shared_ptr<Storage::Tape::Tape> tape = tapes.front();
|
std::shared_ptr<Storage::Tape::Tape> tape = tapes.front();
|
||||||
tape->reset();
|
tape->reset();
|
||||||
GetFiles(tape);
|
|
||||||
|
// continue if there are any files
|
||||||
|
std::list<File> files = GetFiles(tape);
|
||||||
|
if(files.size())
|
||||||
|
{
|
||||||
|
bool is_basic = true;
|
||||||
|
|
||||||
|
// protected files are always for *RUNning only
|
||||||
|
if(files.front().is_protected) is_basic = false;
|
||||||
|
|
||||||
|
// check also for a continuous threading of BASIC lines; if none then this probably isn't BASIC code,
|
||||||
|
// so that's also justification to *RUN
|
||||||
|
size_t pointer = 0;
|
||||||
|
uint8_t *data = &files.front().data[0];
|
||||||
|
size_t data_size = files.front().data.size();
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
if(pointer >= data_size-1 || data[pointer] != 13)
|
||||||
|
{
|
||||||
|
is_basic = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if((data[pointer+1]&0x7f) == 0x7f) break;
|
||||||
|
pointer += data[pointer+3];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inspect first file. If it's protected or doesn't look like BASIC
|
||||||
|
// then the loading command is *RUN. Otherwise it's CHAIN"".
|
||||||
|
target.loadingCommand = is_basic ? "CHAIN\"\"\n" : "*RUN\n";
|
||||||
|
|
||||||
|
target.tapes = tapes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: disks
|
||||||
|
|
||||||
|
if(target.tapes.size() || target.cartridges.size())
|
||||||
|
destination.push_back(target);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ struct TapeParser {
|
|||||||
{
|
{
|
||||||
// skip any gaps
|
// skip any gaps
|
||||||
Storage::Tape::Tape::Pulse next_pulse = _tape->get_next_pulse();
|
Storage::Tape::Tape::Pulse next_pulse = _tape->get_next_pulse();
|
||||||
while(next_pulse.type == Storage::Tape::Tape::Pulse::Zero)
|
while(!_tape->is_at_end() && next_pulse.type == Storage::Tape::Tape::Pulse::Zero)
|
||||||
{
|
{
|
||||||
next_pulse = _tape->get_next_pulse();
|
next_pulse = _tape->get_next_pulse();
|
||||||
}
|
}
|
||||||
@ -231,9 +231,11 @@ std::unique_ptr<File> GetNextFile(TapeParser &parser)
|
|||||||
{
|
{
|
||||||
chunk = GetNextChunk(parser);
|
chunk = GetNextChunk(parser);
|
||||||
if(!chunk) continue;
|
if(!chunk) continue;
|
||||||
if(chunk->block_number) continue;
|
if(!chunk->block_number) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!chunk) 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);
|
std::unique_ptr<File> file(new File);
|
||||||
file->chunks.push_back(*chunk);
|
file->chunks.push_back(*chunk);
|
||||||
|
Loading…
Reference in New Issue
Block a user