diff --git a/Analyser/Static/Thomson/StaticAnalyser.cpp b/Analyser/Static/Thomson/StaticAnalyser.cpp index 625ebc305..b2ab8aaed 100644 --- a/Analyser/Static/Thomson/StaticAnalyser.cpp +++ b/Analyser/Static/Thomson/StaticAnalyser.cpp @@ -78,31 +78,22 @@ Analyser::Static::TargetList Analyser::Static::Thomson::GetTargets( } if(!media.tapes.empty()) { - Storage::Tape::Thomson::MO::Parser parser; + using namespace Storage::Tape::Thomson::MO; + + Parser parser; auto &tape = media.tapes.front(); const auto serialiser = tape->serialiser(); const auto first = parser.file(*serialiser); if(first && first->checksums_valid) { target->media.tapes = media.tapes; - - // Cf. https://pulkomandy.tk/wiki/doku.php?id=documentations:monitor:tape.format for leader block format; - // my parser provides block type separately and length implicitly so the type at offset 0xd is at 0xb - // in ->data. - const auto command = [&]() -> std::wstring { - if(!first->type) { // File type; 0 = BASIC, 1 = DATA; 2 = binary. - return L"RUN\""; - } else { - return L"LOADM\"\",,R"; - } - }; + target->loading_command = first->type != File::Type::BASIC ? L"LOADM\"\",,R" : L"RUN\""; // TODO: determine whether BASIC 1 or BASIC 128 is appropriate. if(DefaultMO6) { - target->loading_command = std::wstring(L"2 ") + command() + L"\n"; - } else { - target->loading_command = command() + L"\n"; + target->loading_command = std::wstring(L"2 ") + target->loading_command; } + target->loading_command += '\n'; } } diff --git a/Storage/Tape/Parsers/ThomsonMO.cpp b/Storage/Tape/Parsers/ThomsonMO.cpp index 35897585c..e0336acff 100644 --- a/Storage/Tape/Parsers/ThomsonMO.cpp +++ b/Storage/Tape/Parsers/ThomsonMO.cpp @@ -116,8 +116,8 @@ std::optional Parser::file(Storage::Tape::TapeSerialiser &serialiser) { copy_string(result->name, 0); copy_string(result->extension, 8); - result->type = leader->data[11]; - result->mode = uint16_t((leader->data[12] << 8) | leader->data[13]); + result->type = File::Type(leader->data[11]); + result->mode = File::Mode((leader->data[12] << 8) | leader->data[13]); // Accumulate data for as long as it comes. while(true) { @@ -133,3 +133,19 @@ std::optional Parser::file(Storage::Tape::TapeSerialiser &serialiser) { uint8_t Block::check_digit() const { return uint8_t(checksum - std::accumulate(data.begin(), data.end(), 0)); } + +// +// Notes on file contents, as I figure them out: +// +// File type: 0 = BASIC, 1 = data (saved by BASIC); 2 = binary. +// +// BASIC file modes: 0 = tokenised; 1 = ASCII. +// +// Binary contents: +// +// byte 0: ??? +// bytes 1 & 2: length of data; +// bytes 3 & 4: loading address; +// ... data itself ... +// five more bytes: ??? +// diff --git a/Storage/Tape/Parsers/ThomsonMO.hpp b/Storage/Tape/Parsers/ThomsonMO.hpp index ae4ea1cef..484e8b8b6 100644 --- a/Storage/Tape/Parsers/ThomsonMO.hpp +++ b/Storage/Tape/Parsers/ThomsonMO.hpp @@ -34,8 +34,19 @@ struct File { return std::string(name) + '.' + extension; } - uint8_t type = 0; - uint16_t mode = 0; + enum class Type: uint8_t { + BASIC = 0, + Data = 1, + Binary = 2, + }; + Type type{}; + + enum class Mode: uint16_t { + // Modes that apply when type is BASIC. + BASICTokenised = 0, + BASICASCII = 1, + }; + Mode mode{}; std::vector data; bool checksums_valid = true;