2018-01-07 21:35:57 +00:00
|
|
|
//
|
|
|
|
// MSXDSK.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 07/01/2018.
|
2018-05-13 19:19:52 +00:00
|
|
|
// Copyright 2018 Thomas Harte. All rights reserved.
|
2018-01-07 21:35:57 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#include "MSXDSK.hpp"
|
|
|
|
|
|
|
|
#include "Utility/ImplicitSectors.hpp"
|
|
|
|
|
|
|
|
namespace {
|
2019-12-22 05:22:17 +00:00
|
|
|
constexpr int sectors_per_track = 9;
|
|
|
|
constexpr int sector_size = 2;
|
|
|
|
constexpr off_t track_size = (128 << sector_size)*sectors_per_track;
|
2018-01-07 21:35:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
using namespace Storage::Disk;
|
|
|
|
|
2018-04-06 21:42:24 +00:00
|
|
|
MSXDSK::MSXDSK(const std::string &file_name) :
|
2018-01-07 21:35:57 +00:00
|
|
|
MFMSectorDump(file_name) {
|
|
|
|
// The only sanity check here is whether a sensible
|
|
|
|
// geometry can be guessed.
|
|
|
|
off_t file_size = file_.stats().st_size;
|
|
|
|
|
|
|
|
// Throw if there would seemingly be an incomplete track.
|
2018-04-28 03:18:45 +00:00
|
|
|
if(file_size % track_size) throw Error::InvalidFormat;
|
2018-01-07 21:35:57 +00:00
|
|
|
|
2020-05-10 03:00:39 +00:00
|
|
|
track_count_ = int(file_size / track_size);
|
2018-01-07 21:35:57 +00:00
|
|
|
head_count_ = 1;
|
|
|
|
|
|
|
|
// Throw if too large or too small or too large for single sided and
|
|
|
|
// clearly not double sided.
|
2018-04-28 03:18:45 +00:00
|
|
|
if(track_count_ < 40) throw Error::InvalidFormat;
|
|
|
|
if(track_count_ > 82*2) throw Error::InvalidFormat;
|
|
|
|
if(track_count_ > 82 && track_count_&1) throw Error::InvalidFormat;
|
2018-01-07 21:35:57 +00:00
|
|
|
|
|
|
|
// The below effectively prefers the idea of a single-sided 80-track disk
|
|
|
|
// to a double-sided 40-track disk. Emulators have to guess.
|
|
|
|
if(track_count_ > 82) {
|
|
|
|
track_count_ /= 2;
|
|
|
|
head_count_ = 2;
|
|
|
|
}
|
|
|
|
|
2018-01-08 02:59:18 +00:00
|
|
|
set_geometry(sectors_per_track, sector_size, 1, true);
|
2018-01-07 21:35:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-07 03:17:36 +00:00
|
|
|
HeadPosition MSXDSK::get_maximum_head_position() {
|
|
|
|
return HeadPosition(track_count_);
|
2018-01-07 21:35:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int MSXDSK::get_head_count() {
|
|
|
|
return head_count_;
|
|
|
|
}
|
|
|
|
|
|
|
|
long MSXDSK::get_file_offset_for_position(Track::Address address) {
|
2018-05-07 03:17:36 +00:00
|
|
|
return (address.position.as_int()*head_count_ + address.head) * 512 * 9;
|
2018-01-07 21:35:57 +00:00
|
|
|
}
|