From 22de4815577a41785487beeb722dc09367fae4c6 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 12 Jun 2017 19:41:59 -0400 Subject: [PATCH] Made an attempt to get .p/.80 checked and as far as the emulated machine. --- Storage/Data/ZX8081.cpp | 44 +++++++++++++++++++++++++++++-- Storage/Tape/Formats/ZX80O81P.cpp | 17 +++++++----- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/Storage/Data/ZX8081.cpp b/Storage/Data/ZX8081.cpp index 0bf6049d7..7df811cc6 100644 --- a/Storage/Data/ZX8081.cpp +++ b/Storage/Data/ZX8081.cpp @@ -45,8 +45,48 @@ static std::shared_ptr ZX80FileFromData(const std::vector &data) return file; } +static std::shared_ptr ZX81FileFromData(const std::vector &data) { + // Does this look like a ZX81 file? + + // Look for a file name. + size_t data_pointer = 0; + int c = 11; + while(c--) { + if(data[data_pointer] & 0x80) break; + data_pointer++; + } + if(!c) return nullptr; + data_pointer++; + + if(data.size() < data_pointer + 0x405e - 0x4009) return nullptr; + + if(data[data_pointer]) return nullptr; + + uint16_t vars = short_at(data_pointer + 0x4010 - 0x4009, data); + uint16_t end_of_file = short_at(data_pointer + 0x4014 - 0x4009, data); +// uint16_t display_address = short_at(0x400c - 0x4009, data); + + // check that the end of file is contained within the supplied data + if(data_pointer + end_of_file - 0x4009 > data.size()) return nullptr; + + // check for the proper ordering of buffers + if(vars > end_of_file) return nullptr; +// if(end_of_file > display_address) return nullptr; + + // TODO: does it make sense to inspect the tokenised BASIC? + // It starts at 0x4028 and proceeds as [16-bit line number] [tokens] [0x76], + // but I'm as yet unable to find documentation of the tokens. + + // TODO: check that the line numbers declared above exist (?) + + std::shared_ptr file(new File); + file->data = data; + file->isZX81 = true; + return file; +} + std::shared_ptr Storage::Data::ZX8081::FileFromData(const std::vector &data) { std::shared_ptr result = ZX80FileFromData(data); - - return result; + if(result) return result; + return ZX81FileFromData(data); } diff --git a/Storage/Tape/Formats/ZX80O81P.cpp b/Storage/Tape/Formats/ZX80O81P.cpp index 83fa6273f..53b64222b 100644 --- a/Storage/Tape/Formats/ZX80O81P.cpp +++ b/Storage/Tape/Formats/ZX80O81P.cpp @@ -14,14 +14,19 @@ using namespace Storage::Tape; ZX80O81P::ZX80O81P(const char *file_name) : Storage::FileHolder(file_name) { - // Check that contents look like a ZX80 file - std::vector whole_file((size_t)file_stats_.st_size); - fread(whole_file.data(), 1, (size_t)file_stats_.st_size, file_); - std::shared_ptr<::Storage::Data::ZX8081::File> file = Storage::Data::ZX8081::FileFromData(whole_file); + // Grab the actual file contents + data_.resize((size_t)file_stats_.st_size); + fread(data_.data(), 1, (size_t)file_stats_.st_size, file_); - if(!file || file->isZX81) throw ErrorNotZX80O81P; + // If it's a ZX81 file, prepend a file name. + char type = (char)tolower(file_name[strlen(file_name) - 1]); + if(type == 'p' || type == '1') { + // TODO, maybe: prefix a proper file name; this is leaving the file nameless. + data_.insert(data_.begin(), 0x80); + } - data_ = file->data; + std::shared_ptr<::Storage::Data::ZX8081::File> file = Storage::Data::ZX8081::FileFromData(data_); + if(!file) throw ErrorNotZX80O81P; // then rewind and start again virtual_reset();