1
0
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:
Thomas Harte 2016-08-31 20:24:13 -04:00
parent d8c0da7ccb
commit 9d7962d6c0
2 changed files with 46 additions and 4 deletions

View File

@ -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);
} }

View File

@ -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);