diff options
Diffstat (limited to 'src/lib/formats/fs_cbmdos.cpp')
-rw-r--r-- | src/lib/formats/fs_cbmdos.cpp | 433 |
1 files changed, 389 insertions, 44 deletions
diff --git a/src/lib/formats/fs_cbmdos.cpp b/src/lib/formats/fs_cbmdos.cpp index 51d1369b04f..44c810a04a6 100644 --- a/src/lib/formats/fs_cbmdos.cpp +++ b/src/lib/formats/fs_cbmdos.cpp @@ -1,5 +1,5 @@ // license:BSD-3-Clause -// copyright-holders:Nathan Woods +// copyright-holders:Nathan Woods, Wilbert Pol /*************************************************************************** fs_cbmdos.cpp @@ -8,21 +8,30 @@ http://fileformats.archiveteam.org/wiki/CBMFS +Current limitations: +- Writing is limited to the first 35 tracks. +- Determine or select the file type. Currently defaulting to PRG; 0 byte files + will be assigned file type DEL. + ***************************************************************************/ #include "fs_cbmdos.h" + #include "d64_dsk.h" #include "fsblk.h" #include "corestr.h" +#include "multibyte.h" #include "strformat.h" #include <array> #include <optional> +#include <regex> #include <set> #include <string_view> #include <tuple> + namespace fs { const cbmdos_image CBMDOS; }; @@ -33,6 +42,8 @@ namespace { class impl : public filesystem_t { public: + static constexpr u8 SECTOR_DIRECTORY_COUNT = 8; + struct cbmdos_dirent { u8 m_next_directory_track; @@ -55,30 +66,74 @@ public: block_iterator(const impl &fs, u8 first_track, u8 first_sector); bool next(); const void *data() const; - const std::array<cbmdos_dirent, 4> &dirent_data() const; + const std::array<cbmdos_dirent, SECTOR_DIRECTORY_COUNT> &dirent_data() const; u8 size() const; + u8 track() const { return m_track; } + u8 sector() const { return m_sector; } private: const impl & m_fs; - fsblk_t::block_t m_block; + fsblk_t::block_t::ptr m_block; std::set<std::tuple<u8, u8>> m_visited_set; u8 m_track; u8 m_sector; + u8 m_next_track; + u8 m_next_sector; }; impl(fsblk_t &blockdev); virtual ~impl() = default; virtual meta_data volume_metadata() override; - virtual std::pair<err_t, meta_data> metadata(const std::vector<std::string> &path) override; - virtual std::pair<err_t, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override; - virtual std::pair<err_t, std::vector<u8>> file_read(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, meta_data> metadata(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, std::vector<dir_entry>> directory_contents(const std::vector<std::string> &path) override; + virtual std::pair<std::error_condition, std::vector<u8>> file_read(const std::vector<std::string> &path) override; + virtual std::error_condition file_create(const std::vector<std::string> &path, const meta_data &meta) override; + virtual std::error_condition file_write(const std::vector<std::string> &path, const std::vector<u8> &data) override; private: - fsblk_t::block_t read_sector(int track, int sector) const; + static constexpr u32 BLOCK_SIZE = 256; + static constexpr u8 DIRECTORY_ENTRY_SIZE = 0x20; + static constexpr u8 FILE_TYPE_DEL = 0x80; + static constexpr u8 FILE_TYPE_SEQ = 0x81; + static constexpr u8 FILE_TYPE_PRG = 0x82; + static constexpr u8 FILE_TYPE_USR = 0x83; + static constexpr u8 FILE_TYPE_REL = 0x84; + static constexpr u8 TRACK_VARIANTS = 5; + static constexpr u8 MAX_SECTORS = 21; + static constexpr u8 MAX_TRACKS = 40; + static constexpr u8 DIRECTORY_TRACK = 18; + static constexpr u8 BAM_SECTOR = 0; + static constexpr u8 FIRST_DIRECTORY_SECTOR = 1; + static constexpr u8 SECTOR_DATA_BYTES = 254; + static constexpr u8 OFFSET_FILE_TYPE = 0x02; + static constexpr u8 OFFSET_FILE_FIRST_TRACK = 0x03; + static constexpr u8 OFFSET_FILE_FIRST_SECTOR = 0x04; + static constexpr u8 OFFSET_FILE_NAME = 0x05; + static constexpr u8 OFFSET_SECTOR_COUNT = 0x1e; + static constexpr u8 OFFSET_CHAIN_TRACK = 0x00; + static constexpr u8 OFFSET_CHAIN_SECTOR = 0x01; + static constexpr u8 CHAIN_END = 0x00; + + static const struct smap + { + u8 first_track; + u8 last_track; + int sector[MAX_SECTORS]; + } s_track_sector_map[TRACK_VARIANTS]; + static const u8 s_data_track_order[MAX_TRACKS - 1]; + u8 m_max_track; + + fsblk_t::block_t::ptr read_sector(int track, int sector) const; std::optional<cbmdos_dirent> dirent_from_path(const std::vector<std::string> &path) const; - void iterate_directory_entries(const std::function<bool(const cbmdos_dirent &dirent)> &callback) const; + void iterate_directory_entries(const std::function<bool(u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent)> &callback) const; + void iterate_all_directory_entries(const std::function<bool(u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent)> &callback) const; meta_data metadata_from_dirent(const cbmdos_dirent &dirent) const; + bool is_valid_filename(const std::string &filename) const; + std::pair<std::error_condition, u8> claim_track_sector(u8 track) const; + std::tuple<std::error_condition, u8, u8> claim_sector() const; + std::error_condition free_sector(u8 track, u8 sector) const; + u8 determine_file_type(const std::vector<u8> &data) const; }; // methods @@ -145,7 +200,7 @@ bool fs::cbmdos_image::can_read() const bool fs::cbmdos_image::can_write() const { - return false; + return true; } @@ -223,8 +278,22 @@ std::string_view strtrimright_cbm(const char (&str)[N]) // impl ctor //------------------------------------------------- +const u8 impl::s_data_track_order[MAX_TRACKS - 1] = { + 17, 19, 16, 20, 15, 21, 14, 22, 13, 23, 12, 24, 11, 25, 10, 26, 9, 27, 8, 28, 7, 29, 6, 30, 5, 31, 4, 32, 3, 33, 2, 34, 1, 35, 36, 37, 38, 39, 40 +}; + +const impl::smap impl::s_track_sector_map[TRACK_VARIANTS] = { + { 1, 17, { 0, 11, 1, 12, 2, 13, 3, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10 } }, + { 18, 18, { 0, 1, 4, 7, 10, 13, 16, 2, 5, 8, 11, 14, 17, 3, 6, 9, 12, 15, 18, -1, -1 } }, + { 19, 24, { 0, 10, 1, 11, 2, 12, 3, 13, 4, 14, 5, 15, 6, 16, 7, 17, 8, 18, 9, -1, -1 } }, + { 25, 30, { 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, 17, -1, -1, -1 } }, + { 31, 40, { 0, 9, 1, 10, 2, 11, 3, 12, 4, 13, 5, 14, 6, 15, 7, 16, 8, -1, -1, -1, -1 } } +}; + + impl::impl(fsblk_t &blockdev) - : filesystem_t(blockdev, 256) + : filesystem_t(blockdev, BLOCK_SIZE) + , m_max_track(35) { } @@ -235,8 +304,8 @@ impl::impl(fsblk_t &blockdev) meta_data impl::volume_metadata() { - auto bam_block = read_sector(18, 0); - std::string_view disk_name = std::string_view((const char *) bam_block.rodata() + 0x90, 16); + auto bam_block = read_sector(DIRECTORY_TRACK, BAM_SECTOR); + std::string_view disk_name = bam_block->rstr(0x90, 16); meta_data results; results.set(meta_name::name, strtrimright_cbm(disk_name)); @@ -248,13 +317,13 @@ meta_data impl::volume_metadata() // impl::metadata //------------------------------------------------- -std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path) +std::pair<std::error_condition, meta_data> impl::metadata(const std::vector<std::string> &path) { std::optional<cbmdos_dirent> dirent = dirent_from_path(path); if (!dirent) - return std::make_pair(ERR_NOT_FOUND, meta_data()); + return std::make_pair(error::not_found, meta_data()); - return std::make_pair(ERR_OK, metadata_from_dirent(*dirent)); + return std::make_pair(std::error_condition(), metadata_from_dirent(*dirent)); } @@ -262,16 +331,16 @@ std::pair<err_t, meta_data> impl::metadata(const std::vector<std::string> &path) // impl::directory_contents //------------------------------------------------- -std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path) +std::pair<std::error_condition, std::vector<dir_entry>> impl::directory_contents(const std::vector<std::string> &path) { std::vector<dir_entry> results; - auto callback = [this, &results](const cbmdos_dirent &ent) + auto callback = [this, &results](u8 track, u8 sector, u8 file_index, const cbmdos_dirent &ent) { results.emplace_back(dir_entry_type::file, metadata_from_dirent(ent)); return false; }; iterate_directory_entries(callback); - return std::make_pair(ERR_OK, std::move(results)); + return std::make_pair(std::error_condition(), std::move(results)); } @@ -279,12 +348,12 @@ std::pair<err_t, std::vector<dir_entry>> impl::directory_contents(const std::vec // impl::file_read //------------------------------------------------- -std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> &path) +std::pair<std::error_condition, std::vector<u8>> impl::file_read(const std::vector<std::string> &path) { // find the file std::optional<cbmdos_dirent> dirent = dirent_from_path(path); if (!dirent) - return std::make_pair(ERR_NOT_FOUND, std::vector<u8>()); + return std::make_pair(error::not_found, std::vector<u8>()); // and get the data std::vector<u8> result; @@ -292,7 +361,263 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> while (iter.next()) result.insert(result.end(), (const u8 *)iter.data(), (const u8 *)iter.data() + iter.size()); - return std::make_pair(ERR_OK, std::move(result)); + return std::make_pair(std::error_condition(), std::move(result)); +} + + +std::error_condition impl::file_create(const std::vector<std::string> &path, const meta_data &meta) +{ + std::string filename = meta.get_string(meta_name::name, ""); + if (!is_valid_filename(filename)) + return error::invalid_name; + + std::optional<cbmdos_dirent> result; + u8 track = 0; + u8 sector = 0; + u8 file_index = 0; + auto callback = [&result, &track, §or, &file_index](u8 t, u8 s, u8 i, const cbmdos_dirent &dirent) + { + bool found = dirent.m_file_type == 0x00; + if (found) + { + result = dirent; + track = t; + sector = s; + file_index = i; + } + return found; + }; + iterate_all_directory_entries(callback); + + if (!result) + { + // Claim a next directory sector + auto const [err, new_sector] = claim_track_sector(DIRECTORY_TRACK); + if (err) + return err; + auto new_block = read_sector(DIRECTORY_TRACK, new_sector); + for (int i = 2; i < BLOCK_SIZE; i++) + new_block->w8(i, 0); + // Find last directory sector + u8 last_sector = 0; + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); + while (iter.next()) + last_sector = iter.sector(); + // Update chain on last directory sector + auto last_dir_block = read_sector(DIRECTORY_TRACK, last_sector); + last_dir_block->w8(OFFSET_CHAIN_TRACK, DIRECTORY_TRACK); + last_dir_block->w8(OFFSET_CHAIN_SECTOR, new_sector); + track = DIRECTORY_TRACK; + sector = new_sector; + } + + auto const [err, file_track, file_sector] = claim_sector(); + if (err) + return err; + + // Create the file + auto dirblk = read_sector(track, sector); + u32 offset = file_index * DIRECTORY_ENTRY_SIZE; + for (int i = 0; i < DIRECTORY_ENTRY_SIZE; i++) + dirblk->w8(offset + i, (i >= 5 && i < 5 + 16) ? 0xa0 : 0x00); + dirblk->w8(offset + OFFSET_FILE_TYPE, FILE_TYPE_PRG); + dirblk->w8(offset + OFFSET_FILE_FIRST_TRACK, file_track); + dirblk->w8(offset + OFFSET_FILE_FIRST_SECTOR, file_sector); + dirblk->wstr(offset + OFFSET_FILE_NAME, filename); + // TODO set first side sector block track (rel file) + // TODO set first side sector block sector (rel file) + // TODO set rel file record length + // sector count will be set while writing the data + + return std::error_condition(); +} + + +std::error_condition impl::file_write(const std::vector<std::string> &path, const std::vector<u8> &data) +{ + if (path.size() != 1) + return error::not_found; + std::string_view path_part = path[0]; + + std::optional<cbmdos_dirent> result; + u8 dir_track = 0; + u8 dir_sector = 0; + u8 dir_file_index = 0; + auto const callback = [&result, &dir_track, &dir_sector, &dir_file_index, path_part] (u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent) + { + bool found = strtrimright_cbm(dirent.m_file_name) == path_part; + if (found) + { + dir_track = track; + dir_sector = sector; + dir_file_index = file_index; + result = dirent; + } + return found; + }; + iterate_directory_entries(callback); + + if (!result) + return error::not_found; + + u8 data_track = result->m_file_first_track; + u8 data_sector = result->m_file_first_sector; + + const size_t data_length = data.size(); + size_t offset = 0; + u32 sector_count = 0; + while (offset < data_length) + { + auto datablk = read_sector(data_track, data_sector); + u8 bytes = (data_length - offset) > SECTOR_DATA_BYTES ? SECTOR_DATA_BYTES : data_length - offset; + datablk->write(2, data.data() + offset, bytes); + offset += SECTOR_DATA_BYTES; + sector_count++; + if (datablk->r8(OFFSET_CHAIN_TRACK) == CHAIN_END) + { + if (offset < data_length) + { + auto [err, next_track, next_sector] = claim_sector(); + if (err) + return err; + datablk->w8(OFFSET_CHAIN_TRACK, next_track); + datablk->w8(OFFSET_CHAIN_SECTOR, next_sector); + data_track = next_track; + data_sector = next_sector; + } + } + else + { + if (offset < data_length) + { + data_track = datablk->r8(OFFSET_CHAIN_TRACK); + data_sector = datablk->r8(OFFSET_CHAIN_SECTOR); + } + else + { + // Free the rest of the chain + u8 track_to_free = datablk->r8(OFFSET_CHAIN_TRACK); + u8 sector_to_free = datablk->r8(OFFSET_CHAIN_SECTOR); + + while (track_to_free != CHAIN_END) + { + std::error_condition const err = free_sector(track_to_free, sector_to_free); + if (err) + return err; + datablk = read_sector(track_to_free, sector_to_free); + track_to_free = datablk->r8(OFFSET_CHAIN_TRACK); + sector_to_free = datablk->r8(OFFSET_CHAIN_SECTOR); + } + } + } + if (offset >= data_length) + { + datablk->w8(OFFSET_CHAIN_TRACK, CHAIN_END); + datablk->w8(OFFSET_CHAIN_SECTOR, bytes + 1); + } + } + + // Write sector count and file type to directory entry + auto dirblk = read_sector(dir_track, dir_sector); + u8 file_type = determine_file_type(data); + if (file_type == FILE_TYPE_DEL) + { + // Free sector, update first file sector to 00 + u8 file_track = dirblk->r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK); + u8 file_sector = dirblk->r8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR); + std::error_condition err = free_sector(file_track, file_sector); + if (err) + return err; + dirblk->w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_TRACK, 0); + dirblk->w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_FIRST_SECTOR, 0); + sector_count = 0; + } + dirblk->w8(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_FILE_TYPE, file_type); + dirblk->w16l(DIRECTORY_ENTRY_SIZE * dir_file_index + OFFSET_SECTOR_COUNT, sector_count); + + return std::error_condition(); +} + + +u8 impl::determine_file_type(const std::vector<u8> &data) const +{ + // TODO: Determine/set the actual file type, defaulting to PRG for now. + const size_t data_length = data.size(); + if (data_length == 0) + return FILE_TYPE_DEL; + return FILE_TYPE_PRG; +} + + +bool impl::is_valid_filename(const std::string &filename) const +{ + // We only support a subset of the character set supported by Commodore for filenames. + std::regex filename_regex("[A-Z0-9!\"#\\$%&'\\(\\)*+,-./:;<=>?]{1,16}"); + return std::regex_match(filename, filename_regex); +} + + +std::pair<std::error_condition, u8> impl::claim_track_sector(u8 track) const +{ + if (track == 0 || track > m_max_track) + return std::make_pair(error::invalid_block, 0); + + u8 map_index; + for (map_index = 0; map_index < TRACK_VARIANTS && !(s_track_sector_map[map_index].first_track <= track && track <= s_track_sector_map[map_index].last_track) ; map_index++); + if (map_index >= TRACK_VARIANTS) + return std::make_pair(error::invalid_block, 0); + + auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR); + u8 free_count = bamblk->r8(4 * track); + u32 free_bitmap = bamblk->r24l(4 * track + 1); + + for (int s = 0; s < MAX_SECTORS; s++) + { + int sector = s_track_sector_map[map_index].sector[s]; + if (sector >= 0 && free_count > 0 && util::BIT(free_bitmap, sector)) + { + free_bitmap &= ~(1 << sector); + free_count--; + bamblk->w8(4 * track, free_count); + bamblk->w24l(4 * track + 1, free_bitmap); + // Write chain end marker in new sector + auto claimedlk = read_sector(track, sector); + claimedlk->w8(OFFSET_CHAIN_TRACK, CHAIN_END); + claimedlk->w8(OFFSET_CHAIN_SECTOR, 0xff); + return std::make_pair(std::error_condition(), sector); + } + } + return std::make_pair(error::no_space, 0); +} + + +std::tuple<std::error_condition, u8, u8> impl::claim_sector() const +{ + for (int track = 0; track < m_max_track - 1; track++) + { + auto const [err, sector] = claim_track_sector(s_data_track_order[track]); + if (!err) + return std::make_tuple(std::error_condition(), s_data_track_order[track], sector); + if (err != error::no_space) + return std::make_tuple(err, 0, 0); + } + return std::make_tuple(error::no_space, 0, 0); +} + + +std::error_condition impl::free_sector(u8 track, u8 sector) const +{ + if (track == 0 || track > m_max_track) + return error::invalid_block; + + auto bamblk = read_sector(DIRECTORY_TRACK, BAM_SECTOR); + u8 free_count = bamblk->r8(4 * track); + u32 free_bitmap = bamblk->r24l(4 * track + 1); + free_bitmap |= (1 << sector); + free_count++; + bamblk->w8(4 * track, free_count); + bamblk->w24l(4 * track + 1, free_bitmap); + return std::error_condition(); } @@ -300,7 +625,7 @@ std::pair<err_t, std::vector<u8>> impl::file_read(const std::vector<std::string> // impl::read_sector //------------------------------------------------- -fsblk_t::block_t impl::read_sector(int track, int sector) const +fsblk_t::block_t::ptr impl::read_sector(int track, int sector) const { // CBM thinks in terms of tracks/sectors, but we have a block device abstraction u32 block = 0; @@ -320,13 +645,13 @@ fsblk_t::block_t impl::read_sector(int track, int sector) const std::optional<impl::cbmdos_dirent> impl::dirent_from_path(const std::vector<std::string> &path) const { if (path.size() != 1) - return { }; + return std::nullopt; std::string_view path_part = path[0]; std::optional<cbmdos_dirent> result; - auto callback = [&result, path_part](const cbmdos_dirent &dirent) + auto const callback = [&result, path_part] (u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent) { - bool found = strtrimright_cbm(dirent.m_file_name) == path_part; + bool const found = strtrimright_cbm(dirent.m_file_name) == path_part; if (found) result = dirent; return found; @@ -340,22 +665,38 @@ std::optional<impl::cbmdos_dirent> impl::dirent_from_path(const std::vector<std: // impl::iterate_directory_entries //------------------------------------------------- -void impl::iterate_directory_entries(const std::function<bool(const cbmdos_dirent &dirent)> &callback) const +void impl::iterate_directory_entries(const std::function<bool(u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent)> &callback) const { - block_iterator iter(*this, 18, 1); + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); while (iter.next()) { - for (const cbmdos_dirent &ent : iter.dirent_data()) + auto entries = iter.dirent_data(); + + for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++) { - if (ent.m_file_type != 0x00) + if (entries[file_index].m_file_type != 0x00) { - if (callback(ent)) + if (callback(iter.track(), iter.sector(), file_index, entries[file_index])) return; } } } } +void impl::iterate_all_directory_entries(const std::function<bool(u8 track, u8 sector, u8 file_index, const cbmdos_dirent &dirent)> &callback) const +{ + block_iterator iter(*this, DIRECTORY_TRACK, FIRST_DIRECTORY_SECTOR); + while (iter.next()) + { + auto entries = iter.dirent_data(); + + for (int file_index = 0; file_index < SECTOR_DIRECTORY_COUNT; file_index++) + { + if (callback(iter.track(), iter.sector(), file_index, entries[file_index])) + return; + } + } +} //------------------------------------------------- // impl::metadata_from_dirent @@ -366,19 +707,19 @@ meta_data impl::metadata_from_dirent(const cbmdos_dirent &dirent) const std::string file_type; switch (dirent.m_file_type) { - case 0x80: + case FILE_TYPE_DEL: file_type = "DEL"; break; - case 0x81: + case FILE_TYPE_SEQ: file_type = "SEQ"; break; - case 0x82: + case FILE_TYPE_PRG: file_type = "PRG"; break; - case 0x83: + case FILE_TYPE_USR: file_type = "USR"; break; - case 0x84: + case FILE_TYPE_REL: file_type = "REL"; break; default: @@ -409,6 +750,8 @@ impl::block_iterator::block_iterator(const impl &fs, u8 first_track, u8 first_se : m_fs(fs) , m_track(first_track) , m_sector(first_sector) + , m_next_track(first_track) + , m_next_sector(first_sector) { } @@ -420,19 +763,21 @@ impl::block_iterator::block_iterator(const impl &fs, u8 first_track, u8 first_se bool impl::block_iterator::next() { bool result; - if (m_track != 0x00) + m_track = m_next_track; + m_sector = m_next_sector; + if (m_track != CHAIN_END) { // check for the degenerate scenario where we have a cycle (this should not happen // on a non-corrupt disk) - auto visited_tuple = std::make_tuple(m_track, m_sector); + auto visited_tuple = std::make_tuple(m_next_track, m_next_sector); if (m_visited_set.find(visited_tuple) != m_visited_set.end()) return false; m_visited_set.insert(visited_tuple); // with that out of the way, proceed - m_block = m_fs.read_sector(m_track, m_sector); - m_track = m_block.r8(0); - m_sector = m_block.r8(1); + m_block = m_fs.read_sector(m_next_track, m_next_sector); + m_next_track = m_block->r8(OFFSET_CHAIN_TRACK); + m_next_sector = m_block->r8(OFFSET_CHAIN_SECTOR); result = true; } else @@ -450,7 +795,7 @@ bool impl::block_iterator::next() const void *impl::block_iterator::data() const { - return m_block.rodata() + 2; + return m_block->rodata() + 2; } @@ -458,9 +803,9 @@ const void *impl::block_iterator::data() const // impl::block_iterator::dirent_data //------------------------------------------------- -const std::array<impl::cbmdos_dirent, 4> &impl::block_iterator::dirent_data() const +const std::array<impl::cbmdos_dirent, impl::SECTOR_DIRECTORY_COUNT> &impl::block_iterator::dirent_data() const { - return *reinterpret_cast<const std::array<impl::cbmdos_dirent, 4> *>(m_block.rodata()); + return *reinterpret_cast<const std::array<impl::cbmdos_dirent, SECTOR_DIRECTORY_COUNT> *>(m_block->rodata()); } @@ -470,7 +815,7 @@ const std::array<impl::cbmdos_dirent, 4> &impl::block_iterator::dirent_data() co u8 impl::block_iterator::size() const { - return m_track != 0x00 ? 254 : m_sector - 1; + return (m_track != CHAIN_END) ? SECTOR_DATA_BYTES : (m_sector - 1); } } // anonymous namespace |