diff options
Diffstat (limited to 'src/tools/imgtool/modules/vzdos.cpp')
-rw-r--r-- | src/tools/imgtool/modules/vzdos.cpp | 211 |
1 files changed, 101 insertions, 110 deletions
diff --git a/src/tools/imgtool/modules/vzdos.cpp b/src/tools/imgtool/modules/vzdos.cpp index bf46863bb28..b7dee751434 100644 --- a/src/tools/imgtool/modules/vzdos.cpp +++ b/src/tools/imgtool/modules/vzdos.cpp @@ -1,4 +1,4 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Dirk Best /**************************************************************************** @@ -8,15 +8,23 @@ ****************************************************************************/ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <math.h> #include "imgtool.h" -#include "formats/imageutl.h" -#include "formats/vt_dsk.h" +#include "filter.h" #include "iflopimg.h" +#include "formats/vt_dsk_legacy.h" + +#include "corestr.h" +#include "hashing.h" +#include "multibyte.h" +#include "opresolv.h" + +#include <algorithm> +#include <cmath> +#include <cstdio> +#include <cstdlib> +#include <cstring> + /* sector format @@ -44,13 +52,22 @@ as track map, with one bit for each sector used. /* vzdos directry entry */ struct vzdos_dirent { - char ftype; - char delimitor; - char fname[8]; + struct { + char ftype; + char delimitor; + char fname[8]; + } node; uint8_t start_track; uint8_t start_sector; uint16_t start_address; uint16_t end_address; + + vzdos_dirent() : + start_track(0), start_sector(0), + start_address(0), end_address(0) + { + memset(&node, 0, sizeof(node)); + } }; struct vz_iterator @@ -80,18 +97,6 @@ static int vzdos_get_fname_len(const char *fname) return len; } -/* calculate checksum-16 of buffer */ -static uint16_t chksum16(uint8_t *buffer, int len) -{ - int i; - uint16_t sum = 0; - - for (i = 0; i < len; i++) - sum += buffer[i]; - - return sum; -} - /* returns the offset where the actual sector data starts */ static imgtoolerr_t vzdos_get_data_start(imgtool::image &img, int track, int sector, int *start) { @@ -127,7 +132,7 @@ static imgtoolerr_t vzdos_read_sector_data(imgtool::image &img, int track, int s if (ret) return (imgtoolerr_t)ret; /* verify sector checksums */ - if (pick_integer_le(buffer, DATA_SIZE + 2, 2) != chksum16(buffer, DATA_SIZE + 2)) + if (get_u16le(&buffer[DATA_SIZE + 2]) != util::sum16_creator::simple(buffer, DATA_SIZE + 2)) return IMGTOOLERR_CORRUPTFILE; memcpy(data, &buffer, DATA_SIZE + 2); @@ -145,7 +150,7 @@ static imgtoolerr_t vzdos_write_sector_data(imgtool::image &img, int track, int if (ret) return (imgtoolerr_t)ret; memcpy(buffer, data, DATA_SIZE + 2); - place_integer_le(buffer, DATA_SIZE + 2, 2, chksum16(data, DATA_SIZE + 2)); + put_u16le(&buffer[DATA_SIZE + 2], util::sum16_creator::simple(data, DATA_SIZE + 2)); ret = floppy_write_sector(imgtool_floppy(img), 0, track, sector_order[sector], data_start, buffer, sizeof(buffer), 0); /* TODO: pass ddam argument from imgtool */ if (ret) return (imgtoolerr_t)ret; @@ -157,8 +162,7 @@ static imgtoolerr_t vzdos_write_sector_data(imgtool::image &img, int track, int static imgtoolerr_t vzdos_clear_sector(imgtool::image &img, int track, int sector) { uint8_t data[DATA_SIZE + 2]; - - memset(data, 0x00, sizeof(data)); + std::fill(std::begin(data), std::end(data), 0x00); return vzdos_write_sector_data(img, track, sector, data); } @@ -166,21 +170,21 @@ static imgtoolerr_t vzdos_clear_sector(imgtool::image &img, int track, int secto /* return a directory entry for an index */ static imgtoolerr_t vzdos_get_dirent(imgtool::image &img, int index, vzdos_dirent *ent) { - int ret, entry; uint8_t buffer[DATA_SIZE + 2]; - ret = vzdos_read_sector_data(img, 0, (int) index / 8, buffer); - if (ret) return (imgtoolerr_t)ret; + imgtoolerr_t const ret = vzdos_read_sector_data(img, 0, int(index) / 8, buffer); + if (IMGTOOLERR_SUCCESS != ret) + return ret; - entry = ((index % 8) * sizeof(vzdos_dirent)); + int const entry = ((index % 8) * sizeof(vzdos_dirent)); - memcpy(ent, &buffer[entry], 10); - ent->start_track = pick_integer_le(&buffer[entry], 10, 1); - ent->start_sector = pick_integer_le(&buffer[entry], 11, 1); - ent->start_address = pick_integer_le(&buffer[entry], 12, 2); - ent->end_address = pick_integer_le(&buffer[entry], 14, 2); + memcpy(&ent->node, &buffer[entry], 10); + ent->start_track = buffer[entry + 10]; + ent->start_sector = buffer[entry + 11]; + ent->start_address = get_u16le(&buffer[entry + 12]); + ent->end_address = get_u16le(&buffer[entry + 14]); - if (ent->ftype == 0x00) + if (ent->node.ftype == 0x00) return IMGTOOLERR_FILENOTFOUND; /* check values */ @@ -206,10 +210,10 @@ static imgtoolerr_t vzdos_set_dirent(imgtool::image &img, int index, vzdos_diren entry = ((index % 8) * sizeof(vzdos_dirent)); memcpy(&buffer[entry], &ent, 10); - place_integer_le(buffer, entry + 10, 1, ent.start_track); - place_integer_le(buffer, entry + 11, 1, ent.start_sector); - place_integer_le(buffer, entry + 12, 2, ent.start_address); - place_integer_le(buffer, entry + 14, 2, ent.end_address); + buffer[entry + 10] = ent.start_track; + buffer[entry + 11] = ent.start_sector; + put_u16le(&buffer[entry + 12], ent.start_address); + put_u16le(&buffer[entry + 14], ent.end_address); /* save new sector */ ret = vzdos_write_sector_data(img, 0, (int) index / 8, buffer); @@ -221,20 +225,12 @@ static imgtoolerr_t vzdos_set_dirent(imgtool::image &img, int index, vzdos_diren /* clear a directory entry */ static imgtoolerr_t vzdos_clear_dirent(imgtool::image &img, int index) { - int ret; vzdos_dirent entry; - - memset(&entry, 0x00, sizeof(vzdos_dirent)); - - ret = vzdos_set_dirent(img, index, entry); - if (ret) return (imgtoolerr_t)ret; - - return IMGTOOLERR_SUCCESS; + return vzdos_set_dirent(img, index, entry); } /* search the index for a directory entry */ static imgtoolerr_t vzdos_searchentry(imgtool::image &image, const char *fname, int *entry) { - int i, len, ret; vzdos_dirent ent; char filename[9]; @@ -246,23 +242,23 @@ static imgtoolerr_t vzdos_searchentry(imgtool::image &image, const char *fname, *entry = -1; - for (i = 0; i < MAX_DIRENTS; i++) { - ret = vzdos_get_dirent(image, i, &ent); - if (ret) return (imgtoolerr_t)ret; + for (int i = 0; i < MAX_DIRENTS; i++) { + imgtoolerr_t const ret = vzdos_get_dirent(image, i, &ent); + if (IMGTOOLERR_SUCCESS != ret) + return ret; - len = vzdos_get_fname_len(ent.fname) + 1; + int const len = vzdos_get_fname_len(ent.node.fname) + 1; if (strlen(fname) != len) continue; - memset(filename, 0x00, sizeof(filename)); - memcpy(filename, ent.fname, len); + std::fill(std::begin(filename), std::end(filename), 0x00); + memcpy(filename, ent.node.fname, len); if (!core_stricmp(fname, filename)) { *entry = i; break; } - } if (*entry == -1) @@ -359,7 +355,6 @@ static imgtoolerr_t vzdos_free_trackmap(imgtool::image &img, int *track, int *se static imgtoolerr_t vzdos_write_formatted_sector(imgtool::image &img, int track, int sector) { - int ret; uint8_t sector_data[DATA_SIZE + 4 + 24]; static const uint8_t sector_header[24] = { @@ -368,15 +363,16 @@ static imgtoolerr_t vzdos_write_formatted_sector(imgtool::image &img, int track, 0x80, 0x80, 0x80, 0x00, 0xC3, 0x18, 0xE7, 0xFE }; - memset(sector_data, 0x00, sizeof(sector_data)); + std::fill(std::begin(sector_data), std::end(sector_data), 0x00); memcpy(sector_data, sector_header, sizeof(sector_header)); sector_data[10] = (uint8_t) track; /* current track */ sector_data[11] = (uint8_t) sector; /* current sector */ sector_data[12] = (uint8_t) track + sector; /* checksum-8 */ - ret = floppy_write_sector(imgtool_floppy(img), 0, track, sector_order[sector], 0, sector_data, sizeof(sector_data), 0); /* TODO: pass ddam argument from imgtool */ - if (ret) return (imgtoolerr_t)ret; + floperr_t const ret = floppy_write_sector(imgtool_floppy(img), 0, track, sector_order[sector], 0, sector_data, sizeof(sector_data), 0); /* TODO: pass ddam argument from imgtool */ + if (FLOPPY_ERROR_SUCCESS != ret) + return IMGTOOLERR_WRITEERROR; return IMGTOOLERR_SUCCESS; } @@ -424,15 +420,15 @@ static imgtoolerr_t vzdos_diskimage_nextenum(imgtool::directory &enumeration, im /* kill trailing spaces */ for (len = 7; len > 0; len--) { - if (dirent.fname[len] != 0x20) { + if (dirent.node.fname[len] != 0x20) { break; } } - memcpy(ent.filename, &dirent.fname, len + 1); + memcpy(ent.filename, &dirent.node.fname, len + 1); ent.filesize = dirent.end_address - dirent.start_address; - switch (dirent.ftype) + switch (dirent.node.ftype) { case 0x01: type = "Deleted"; break; case 'T': type = "Basic"; break; @@ -445,7 +441,7 @@ static imgtoolerr_t vzdos_diskimage_nextenum(imgtool::directory &enumeration, im default: type = "Unknown"; } - snprintf(ent.attr, ARRAY_LENGTH(ent.attr), "%s", type); + snprintf(ent.attr, std::size(ent.attr), "%s", type); iter->index++; } @@ -500,12 +496,12 @@ static imgtoolerr_t vzdos_diskimage_readfile(imgtool::partition &partition, cons if (ret) return ret; /* detect sectors pointing to themselfs */ - if ((track == (int)pick_integer_le(buffer, DATA_SIZE, 1)) && (sector == (int)pick_integer_le(buffer, DATA_SIZE + 1, 1))) + if ((track == (int)buffer[DATA_SIZE]) && (sector == (int)buffer[DATA_SIZE + 1])) return IMGTOOLERR_CORRUPTIMAGE; /* load next track and sector values */ - track = pick_integer_le(buffer, DATA_SIZE, 1); - sector = pick_integer_le(buffer, DATA_SIZE + 1, 1); + track = buffer[DATA_SIZE]; + sector = buffer[DATA_SIZE + 1]; /* track 0 is invalid */ if ((track == 0) && (filesize > DATA_SIZE)) @@ -581,8 +577,8 @@ static imgtoolerr_t vzdos_diskimage_deletefile(imgtool::partition &partition, co if (ret) return ret; /* load next track and sector values */ - next_track = pick_integer_le(buffer, DATA_SIZE, 1); - next_sector = pick_integer_le(buffer, DATA_SIZE + 1, 1); + next_track = buffer[DATA_SIZE]; + next_sector = buffer[DATA_SIZE + 1]; /* overwrite sector with default values */ ret = vzdos_clear_sector(img, track, sector); @@ -617,8 +613,8 @@ static imgtoolerr_t vzdos_writefile(imgtool::partition &partition, int offset, i return IMGTOOLERR_READONLY; /* check for already existing filename -> overwrite */ - strcpy(filename, entry->fname); - filename[vzdos_get_fname_len(entry->fname) + 1] = 0x00; + strcpy(filename, entry->node.fname); + filename[vzdos_get_fname_len(entry->node.fname) + 1] = 0x00; ret = vzdos_get_dirent_fname(img, filename, &temp_entry); if (!ret) { /* file already exists, delete it */ @@ -702,8 +698,6 @@ static imgtoolerr_t vzdos_writefile(imgtool::partition &partition, int offset, i /* create a new file or overwrite a file */ static imgtoolerr_t vzdos_diskimage_writefile(imgtool::partition &partition, const char *filename, const char *fork, imgtool::stream &sourcef, util::option_resolution *opts) { - imgtoolerr_t ret; - int ftype; vzdos_dirent entry; /* TODO: check for leading spaces and strip */ @@ -711,37 +705,34 @@ static imgtoolerr_t vzdos_diskimage_writefile(imgtool::partition &partition, con return IMGTOOLERR_BADFILENAME; /* prepare directory entry */ - ftype = opts->lookup_int('T'); + int const ftype = opts->lookup_int('T'); switch (ftype) { case 0: - entry.ftype = 'T'; + entry.node.ftype = 'T'; entry.start_address = 31465; break; case 1: - entry.ftype = 'B'; + entry.node.ftype = 'B'; entry.start_address = 31465; /* ??? */ break; case 2: - entry.ftype = 'D'; + entry.node.ftype = 'D'; entry.start_address = 31465; /* ??? */ break; default: break; } - entry.delimitor = ':'; - memset(&entry.fname, 0x20, 8); /* pad with spaces */ - memcpy(&entry.fname, filename, strlen(filename)); + entry.node.delimitor = ':'; + memset(&entry.node.fname, 0x20, 8); /* pad with spaces */ + memcpy(&entry.node.fname, filename, strlen(filename)); /* write file to disk */ - ret = vzdos_writefile(partition, 0, sourcef, &entry); - if (ret) return ret; - - return IMGTOOLERR_SUCCESS; + return vzdos_writefile(partition, 0, sourcef, &entry); } -static imgtoolerr_t vzdos_diskimage_suggesttransfer(imgtool::partition &partition, const char *fname, imgtool_transfer_suggestion *suggestions, size_t suggestions_length) +static imgtoolerr_t vzdos_diskimage_suggesttransfer(imgtool::partition &partition, const char *fname, imgtool::transfer_suggestion *suggestions, size_t suggestions_length) { imgtoolerr_t ret; imgtool::image &image(partition.image()); @@ -751,37 +742,37 @@ static imgtoolerr_t vzdos_diskimage_suggesttransfer(imgtool::partition &partitio ret = vzdos_get_dirent_fname(image, fname, &entry); if (ret) return ret; - switch (entry.ftype) { + switch (entry.node.ftype) { case 'B': - suggestions[0].viability = SUGGESTION_RECOMMENDED; + suggestions[0].viability = imgtool::SUGGESTION_RECOMMENDED; suggestions[0].filter = filter_vzsnapshot_getinfo; suggestions[0].description = "VZ Snapshot"; - suggestions[1].viability = SUGGESTION_POSSIBLE; - suggestions[1].filter = NULL; + suggestions[1].viability = imgtool::SUGGESTION_POSSIBLE; + suggestions[1].filter = nullptr; suggestions[1].description = "Raw"; break; case 'T': - suggestions[0].viability = SUGGESTION_RECOMMENDED; + suggestions[0].viability = imgtool::SUGGESTION_RECOMMENDED; suggestions[0].filter = filter_vzsnapshot_getinfo; suggestions[0].description = "VZ Snapshot"; - suggestions[1].viability = SUGGESTION_POSSIBLE; - suggestions[1].filter = NULL; + suggestions[1].viability = imgtool::SUGGESTION_POSSIBLE; + suggestions[1].filter = nullptr; suggestions[1].description = "Raw"; - suggestions[2].viability = SUGGESTION_POSSIBLE; + suggestions[2].viability = imgtool::SUGGESTION_POSSIBLE; suggestions[2].filter = filter_vzbas_getinfo; suggestions[2].description = "Tokenized Basic"; break; default: - suggestions[0].viability = SUGGESTION_RECOMMENDED; - suggestions[0].filter = NULL; + suggestions[0].viability = imgtool::SUGGESTION_RECOMMENDED; + suggestions[0].filter = nullptr; suggestions[0].description = "Raw"; } } else { - suggestions[0].viability = SUGGESTION_RECOMMENDED; - suggestions[0].filter = NULL; + suggestions[0].viability = imgtool::SUGGESTION_RECOMMENDED; + suggestions[0].filter = nullptr; suggestions[0].description = "Raw"; - suggestions[1].viability = SUGGESTION_POSSIBLE; + suggestions[1].viability = imgtool::SUGGESTION_POSSIBLE; suggestions[1].filter = filter_vzsnapshot_getinfo; suggestions[1].description = "VZ Snapshot"; } @@ -824,7 +815,7 @@ static imgtoolerr_t vzsnapshot_readfile(imgtool::partition &partition, const cha header[1] = 'Z'; header[2] = 'F'; - switch (entry.ftype) { + switch (entry.node.ftype) { case 'B': header[3] = '1'; header[21] = 0xF1; @@ -839,8 +830,8 @@ static imgtoolerr_t vzsnapshot_readfile(imgtool::partition &partition, const cha } memset(header + 4, 0x00, 17); - memcpy(header + 4, entry.fname, vzdos_get_fname_len(entry.fname) + 1); - place_integer_le(header, 22, 2, entry.start_address); + memcpy(header + 4, entry.node.fname, vzdos_get_fname_len(entry.node.fname) + 1); + put_u16le(&header[22], entry.start_address); /* write header to file */ destf.write(header, sizeof(header)); @@ -863,21 +854,21 @@ static imgtoolerr_t vzsnapshot_writefile(imgtool::partition &partition, const ch sourcef.read(header, sizeof(header)); /* prepare directory entry */ - entry.ftype = header[21] == 0xF1 ? 'B' : 'T'; - entry.delimitor = ':'; - entry.start_address = pick_integer_le(header, 22, 2); + entry.node.ftype = (header[21] == 0xF1) ? 'B' : 'T'; + entry.node.delimitor = ':'; + entry.start_address = get_u16le(&header[22]); /* filename from header or directly? */ fnameopt = opts->lookup_int('F'); if (fnameopt == 0) { - memcpy(&entry.fname, &header[4], 8); + memcpy(&entry.node.fname, &header[4], 8); } else { /* TODO: check for leading spaces and strip */ if (strlen(filename) > 8 || strlen(filename) < 1) return IMGTOOLERR_BADFILENAME; - memcpy(&entry.fname, filename, strlen(filename) - 3); + memcpy(&entry.node.fname, filename, strlen(filename) - 3); } /* write file to disk */ @@ -887,7 +878,7 @@ static imgtoolerr_t vzsnapshot_writefile(imgtool::partition &partition, const ch return IMGTOOLERR_SUCCESS; } -void filter_vzsnapshot_getinfo(uint32_t state, union filterinfo *info) +void filter_vzsnapshot_getinfo(uint32_t state, imgtool::filterinfo *info) { switch(state) { @@ -936,16 +927,16 @@ void vzdos_get_info(const imgtool_class *imgclass, uint32_t state, union imgtool case IMGTOOLINFO_INT_PREFER_UCASE: info->i = 1; break; case IMGTOOLINFO_INT_DIRECTORY_EXTRA_BYTES: info->i = sizeof(vz_iterator); break; - /* --- the following bits of info are returned as NULL-terminated strings --- */ + /* --- the following bits of info are returned as NUL-terminated strings --- */ case IMGTOOLINFO_STR_NAME: strcpy(info->s = imgtool_temp_str(), "vzdos"); break; case IMGTOOLINFO_STR_DESCRIPTION: strcpy(info->s = imgtool_temp_str(), "VZ-DOS format"); break; case IMGTOOLINFO_STR_FILE: strcpy(info->s = imgtool_temp_str(), __FILE__); break; case IMGTOOLINFO_STR_WRITEFILE_OPTSPEC: strcpy(info->s = imgtool_temp_str(), "T[0]-2;F[0]-1"); break; - case IMGTOOLINFO_STR_EOLN: info->s = NULL; break; + case IMGTOOLINFO_STR_EOLN: info->s = nullptr; break; /* --- the following bits of info are returned as pointers to data or functions --- */ case IMGTOOLINFO_PTR_MAKE_CLASS: info->make_class = imgtool_floppy_make_class; break; - case IMGTOOLINFO_PTR_OPEN: info->open = NULL; break; + case IMGTOOLINFO_PTR_OPEN: info->open = nullptr; break; case IMGTOOLINFO_PTR_BEGIN_ENUM: info->begin_enum = vzdos_diskimage_beginenum; break; case IMGTOOLINFO_PTR_NEXT_ENUM: info->next_enum = vzdos_diskimage_nextenum; break; case IMGTOOLINFO_PTR_FREE_SPACE: info->free_space = vzdos_diskimage_freespace; break; |