mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-01 11:49:58 +00:00
Adds output for modified CPC DSKs.
This commit is contained in:
parent
e384c50580
commit
5a3ca0e447
@ -18,6 +18,7 @@
|
|||||||
using namespace Storage::Disk;
|
using namespace Storage::Disk;
|
||||||
|
|
||||||
CPCDSK::CPCDSK(const char *file_name) :
|
CPCDSK::CPCDSK(const char *file_name) :
|
||||||
|
file_name_(file_name),
|
||||||
is_extended_(false) {
|
is_extended_(false) {
|
||||||
FileHolder file(file_name);
|
FileHolder file(file_name);
|
||||||
is_read_only_ = file.get_is_known_read_only();
|
is_read_only_ = file.get_is_known_read_only();
|
||||||
@ -230,6 +231,7 @@ void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::sha
|
|||||||
size_t chronological_track = index_for_track(pair.first);
|
size_t chronological_track = index_for_track(pair.first);
|
||||||
if(chronological_track >= tracks_.size()) {
|
if(chronological_track >= tracks_.size()) {
|
||||||
tracks_.resize(chronological_track+1);
|
tracks_.resize(chronological_track+1);
|
||||||
|
head_position_count_ = pair.first.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the track, or create it if necessary.
|
// Get the track, or create it if necessary.
|
||||||
@ -263,6 +265,113 @@ void CPCDSK::set_tracks(const std::map<::Storage::Disk::Track::Address, std::sha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the entire disk image, in extended form.
|
// Rewrite the entire disk image, in extended form.
|
||||||
|
Storage::FileHolder output(file_name_, Storage::FileHolder::FileMode::Rewrite);
|
||||||
|
output.write(reinterpret_cast<const uint8_t *>("EXTENDED CPC DSK File\r\nDisk-Info\r\n"), 34);
|
||||||
|
output.write(reinterpret_cast<const uint8_t *>("Clock Signal "), 14);
|
||||||
|
output.put8(static_cast<uint8_t>(head_position_count_));
|
||||||
|
output.put8(static_cast<uint8_t>(head_count_));
|
||||||
|
output.putn(2, 0);
|
||||||
|
|
||||||
|
// Output size table.
|
||||||
|
for(size_t index = 0; index < static_cast<size_t>(head_position_count_ * head_count_); ++index) {
|
||||||
|
if(index >= tracks_.size()) {
|
||||||
|
output.put8(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Track *track = tracks_[index].get();
|
||||||
|
if(!track) {
|
||||||
|
output.put8(0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate size of track.
|
||||||
|
size_t track_size = 256;
|
||||||
|
for(auto §or: track->sectors) {
|
||||||
|
for(auto &sample: sector.samples) {
|
||||||
|
track_size += sample.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round upward and output.
|
||||||
|
track_size += (256 - (track_size & 255)) & 255;
|
||||||
|
output.put8(static_cast<uint8_t>(track_size >> 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Advance to offset 256.
|
||||||
|
output.putn(static_cast<size_t>(256 - output.tell()), 0);
|
||||||
|
|
||||||
|
// Output each track.
|
||||||
|
for(size_t index = 0; index < static_cast<size_t>(head_position_count_ * head_count_); ++index) {
|
||||||
|
if(index >= tracks_.size()) continue;
|
||||||
|
Track *track = tracks_[index].get();
|
||||||
|
if(!track) continue;
|
||||||
|
|
||||||
|
// Output track header.
|
||||||
|
output.write(reinterpret_cast<const uint8_t *>("Track-Info\r\n"), 13);
|
||||||
|
output.putn(3, 0);
|
||||||
|
output.put8(track->track);
|
||||||
|
output.put8(track->side);
|
||||||
|
switch (track->data_rate) {
|
||||||
|
default:
|
||||||
|
output.put8(0);
|
||||||
|
break;
|
||||||
|
case Track::DataRate::SingleOrDoubleDensity:
|
||||||
|
output.put8(1);
|
||||||
|
break;
|
||||||
|
case Track::DataRate::HighDensity:
|
||||||
|
output.put8(2);
|
||||||
|
break;
|
||||||
|
case Track::DataRate::ExtendedDensity:
|
||||||
|
output.put8(3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (track->data_encoding) {
|
||||||
|
default:
|
||||||
|
output.put8(0);
|
||||||
|
break;
|
||||||
|
case Track::DataEncoding::FM:
|
||||||
|
output.put8(1);
|
||||||
|
break;
|
||||||
|
case Track::DataEncoding::MFM:
|
||||||
|
output.put8(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
output.put8(track->sector_length);
|
||||||
|
output.put8(static_cast<uint8_t>(track->sectors.size()));
|
||||||
|
output.put8(track->gap3_length);
|
||||||
|
output.put8(track->filler_byte);
|
||||||
|
|
||||||
|
// Output sector information list.
|
||||||
|
for(auto §or: track->sectors) {
|
||||||
|
output.put8(sector.address.track);
|
||||||
|
output.put8(sector.address.side);
|
||||||
|
output.put8(sector.address.sector);
|
||||||
|
output.put8(sector.size);
|
||||||
|
output.put8(sector.fdc_status1);
|
||||||
|
output.put8(sector.fdc_status2);
|
||||||
|
|
||||||
|
size_t data_size = 0;
|
||||||
|
for(auto &sample: sector.samples) {
|
||||||
|
data_size += sample.size();
|
||||||
|
}
|
||||||
|
output.put16le(static_cast<uint16_t>(data_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to next 256-byte boundary.
|
||||||
|
long distance = (256 - output.tell()&255)&255;
|
||||||
|
output.putn(static_cast<size_t>(distance), 0);
|
||||||
|
|
||||||
|
// Output sector contents.
|
||||||
|
for(auto §or: track->sectors) {
|
||||||
|
for(auto &sample: sector.samples) {
|
||||||
|
output.write(sample);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to next 256-byte boundary.
|
||||||
|
distance = (256 - output.tell()&255)&255;
|
||||||
|
output.putn(static_cast<size_t>(distance), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPCDSK::get_is_read_only() {
|
bool CPCDSK::get_is_read_only() {
|
||||||
|
@ -64,6 +64,7 @@ class CPCDSK: public DiskImage {
|
|||||||
|
|
||||||
std::vector<Sector> sectors;
|
std::vector<Sector> sectors;
|
||||||
};
|
};
|
||||||
|
std::string file_name_;
|
||||||
std::vector<std::unique_ptr<Track>> tracks_;
|
std::vector<std::unique_ptr<Track>> tracks_;
|
||||||
size_t index_for_track(::Storage::Disk::Track::Address address);
|
size_t index_for_track(::Storage::Disk::Track::Address address);
|
||||||
|
|
||||||
|
@ -92,6 +92,24 @@ uint8_t FileHolder::get8() {
|
|||||||
return static_cast<uint8_t>(fgetc(file_));
|
return static_cast<uint8_t>(fgetc(file_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileHolder::put16be(uint16_t value) {
|
||||||
|
fputc(value >> 8, file_);
|
||||||
|
fputc(value, file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileHolder::put16le(uint16_t value) {
|
||||||
|
fputc(value, file_);
|
||||||
|
fputc(value >> 8, file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileHolder::put8(uint8_t value) {
|
||||||
|
fputc(value, file_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileHolder::putn(size_t repeats, uint8_t value) {
|
||||||
|
while(repeats--) put8(value);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> FileHolder::read(size_t size) {
|
std::vector<uint8_t> FileHolder::read(size_t size) {
|
||||||
std::vector<uint8_t> result(size);
|
std::vector<uint8_t> result(size);
|
||||||
fread(result.data(), 1, size, file_);
|
fread(result.data(), 1, size, file_);
|
||||||
|
@ -62,16 +62,22 @@ class FileHolder final {
|
|||||||
and returning the two assembled in little endian order.
|
and returning the two assembled in little endian order.
|
||||||
*/
|
*/
|
||||||
uint16_t get16le();
|
uint16_t get16le();
|
||||||
|
void put16le(uint16_t value);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Performs @c get8 two times on @c file, casting each result to a @c uint32_t
|
Performs @c get8 two times on @c file, casting each result to a @c uint32_t
|
||||||
and returning the two assembled in big endian order.
|
and returning the two assembled in big endian order.
|
||||||
*/
|
*/
|
||||||
uint16_t get16be();
|
uint16_t get16be();
|
||||||
|
void put16be(uint16_t value);
|
||||||
|
|
||||||
/*! Reads a single byte from @c file */
|
/*! Reads a single byte from @c file. */
|
||||||
uint8_t get8();
|
uint8_t get8();
|
||||||
|
|
||||||
|
/*! Writes a single byte from @c file. */
|
||||||
|
void put8(uint8_t value);
|
||||||
|
void putn(size_t repeats, uint8_t value);
|
||||||
|
|
||||||
std::vector<uint8_t> read(size_t size);
|
std::vector<uint8_t> read(size_t size);
|
||||||
size_t read(uint8_t *buffer, size_t size);
|
size_t read(uint8_t *buffer, size_t size);
|
||||||
size_t write(const std::vector<uint8_t> &);
|
size_t write(const std::vector<uint8_t> &);
|
||||||
|
Loading…
Reference in New Issue
Block a user