mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +00:00
50ea56e908
This is now in addition to the single-partition images previously supported.
60 lines
1.9 KiB
C++
60 lines
1.9 KiB
C++
//
|
|
// HFV.cpp
|
|
// Clock Signal
|
|
//
|
|
// Created by Thomas Harte on 25/08/2019.
|
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
|
//
|
|
|
|
#include "HFV.hpp"
|
|
|
|
using namespace Storage::MassStorage;
|
|
|
|
HFV::HFV(const std::string &file_name) : file_(file_name) {
|
|
// Is the file a multiple of 512 bytes in size and larger than a floppy disk?
|
|
const auto file_size = file_.stats().st_size;
|
|
if(file_size & 511 || file_size <= 800*1024) throw std::exception();
|
|
|
|
// Is this an HFS volume?
|
|
// TODO: check filing system for MFS or HFS+.
|
|
const auto prefix = file_.read(2);
|
|
if(prefix[0] != 'L' || prefix[1] != 'K') throw std::exception();
|
|
}
|
|
|
|
size_t HFV::get_block_size() {
|
|
return 512;
|
|
}
|
|
|
|
size_t HFV::get_number_of_blocks() {
|
|
return mapper_.get_number_of_blocks();
|
|
}
|
|
|
|
std::vector<uint8_t> HFV::get_block(size_t address) {
|
|
const auto written = writes_.find(address);
|
|
if(written != writes_.end()) return written->second;
|
|
|
|
const auto source_address = mapper_.to_source_address(address);
|
|
if(source_address >= 0 && size_t(source_address)*get_block_size() < size_t(file_.stats().st_size)) {
|
|
const long file_offset = long(get_block_size()) * long(source_address);
|
|
file_.seek(file_offset, SEEK_SET);
|
|
return mapper_.convert_source_block(source_address, file_.read(get_block_size()));
|
|
} else {
|
|
return mapper_.convert_source_block(source_address);
|
|
}
|
|
}
|
|
|
|
void HFV::set_block(size_t address, const std::vector<uint8_t> &contents) {
|
|
const auto source_address = mapper_.to_source_address(address);
|
|
if(source_address >= 0 && size_t(source_address)*get_block_size() < size_t(file_.stats().st_size)) {
|
|
const long file_offset = long(get_block_size()) * long(source_address);
|
|
file_.seek(file_offset, SEEK_SET);
|
|
file_.write(contents);
|
|
} else {
|
|
writes_[address] = contents;
|
|
}
|
|
}
|
|
|
|
void HFV::set_drive_type(Encodings::Macintosh::DriveType drive_type) {
|
|
mapper_.set_drive_type(drive_type, size_t(file_.stats().st_size) / get_block_size());
|
|
}
|