mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Added enough logic to produce some sort of version of a completely unprotected DSK. So enough to start bootstrapping an FDC emulation, at least.
This commit is contained in:
parent
8eda24261c
commit
6e4d3b8a77
@ -8,6 +8,8 @@
|
||||
|
||||
#include "CPCDSK.hpp"
|
||||
|
||||
#include "../Encodings/MFM.hpp"
|
||||
|
||||
using namespace Storage::Disk;
|
||||
|
||||
CPCDSK::CPCDSK(const char *file_name) :
|
||||
@ -22,6 +24,14 @@ CPCDSK::CPCDSK(const char *file_name) :
|
||||
fseek(file_, 0x30, SEEK_SET);
|
||||
head_position_count_ = (unsigned int)fgetc(file_);
|
||||
head_count_ = (unsigned int)fgetc(file_);
|
||||
|
||||
if(is_extended_) {
|
||||
for(unsigned int c = 0; c < head_position_count_ * head_count_; c++) {
|
||||
track_sizes_.push_back((size_t)(fgetc(file_) << 8));
|
||||
}
|
||||
} else {
|
||||
size_of_a_track_ = fgetc16le();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int CPCDSK::get_head_position_count() {
|
||||
@ -38,5 +48,79 @@ bool CPCDSK::get_is_read_only() {
|
||||
}
|
||||
|
||||
std::shared_ptr<Track> CPCDSK::get_uncached_track_at_position(unsigned int head, unsigned int position) {
|
||||
// Given that thesea are interleaved images, determine which track, chronologically, is being requested.
|
||||
unsigned int chronological_track = (position * head_count_) + head;
|
||||
|
||||
// All DSK images reserve 0x100 bytes for their headers.
|
||||
long file_offset = 0x100;
|
||||
if(is_extended_) {
|
||||
// Tracks are a variable size in the original DSK file format; sum the lengths
|
||||
// of all tracks prior to the interesting one to get a file offset.
|
||||
unsigned int t = 0;
|
||||
while(t < chronological_track && t < track_sizes_.size()) {
|
||||
file_offset += track_sizes_[t];
|
||||
}
|
||||
} else {
|
||||
// Tracks are a fixed size in the original DSK file format.
|
||||
file_offset += size_of_a_track_ * chronological_track;
|
||||
}
|
||||
|
||||
// Find the track, and skip the unused part of track information.
|
||||
fseek(file_, file_offset + 16, SEEK_SET);
|
||||
|
||||
// Grab the track information.
|
||||
fseek(file_, 5, SEEK_CUR); // skip track number, side number, sector size — each is given per sector
|
||||
int number_of_sectors = fgetc(file_);
|
||||
uint8_t gap3_length = (uint8_t)fgetc(file_);
|
||||
uint8_t filler_byte = (uint8_t)fgetc(file_);
|
||||
|
||||
// Grab the sector information
|
||||
struct SectorInfo {
|
||||
uint8_t track;
|
||||
uint8_t side;
|
||||
uint8_t sector;
|
||||
size_t length;
|
||||
uint8_t status1;
|
||||
uint8_t status2;
|
||||
};
|
||||
std::vector<SectorInfo> sector_infos;
|
||||
while(number_of_sectors--) {
|
||||
SectorInfo new_sector;
|
||||
|
||||
new_sector.track = (uint8_t)fgetc(file_);
|
||||
new_sector.side = (uint8_t)fgetc(file_);
|
||||
new_sector.sector = (uint8_t)fgetc(file_);
|
||||
new_sector.length = (size_t)(128 << fgetc(file_));
|
||||
if(new_sector.length == 0x2000) new_sector.length = 0x1800;
|
||||
new_sector.status1 = (uint8_t)fgetc(file_);
|
||||
new_sector.status2 = (uint8_t)fgetc(file_);
|
||||
fseek(file_, 2, SEEK_CUR);
|
||||
|
||||
sector_infos.push_back(new_sector);
|
||||
}
|
||||
|
||||
// Get the sectors.
|
||||
fseek(file_, file_offset + 0x100, SEEK_SET);
|
||||
if(is_extended_) {
|
||||
// TODO: everything about extended disk images
|
||||
} else {
|
||||
std::vector<Storage::Encodings::MFM::Sector> sectors;
|
||||
for(auto §or_info : sector_infos) {
|
||||
Storage::Encodings::MFM::Sector new_sector;
|
||||
new_sector.track = sector_info.track;
|
||||
new_sector.side = sector_info.side;
|
||||
new_sector.sector = sector_info.sector;
|
||||
new_sector.data.resize(sector_info.length);
|
||||
fread(new_sector.data.data(), sizeof(uint8_t), sector_info.length, file_);
|
||||
|
||||
// TODO: obey the status bytes, somehow (?)
|
||||
|
||||
sectors.push_back(std::move(new_sector));
|
||||
}
|
||||
|
||||
// TODO: supply gay 3 length and filler byte
|
||||
if(sectors.size()) return Storage::Encodings::MFM::GetMFMTrackWithSectors(sectors);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -12,6 +12,8 @@
|
||||
#include "../Disk.hpp"
|
||||
#include "../../FileHolder.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Storage {
|
||||
namespace Disk {
|
||||
|
||||
@ -43,6 +45,12 @@ class CPCDSK: public Disk, public Storage::FileHolder {
|
||||
unsigned int head_count_;
|
||||
unsigned int head_position_count_;
|
||||
bool is_extended_;
|
||||
|
||||
// Used only for non-extended disks.
|
||||
long size_of_a_track_;
|
||||
|
||||
// Used only for extended disks.
|
||||
std::vector<size_t> track_sizes_;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user