mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
moof_dsk: write support
This commit is contained in:
parent
2cfeaa9ebe
commit
348d384ef5
@ -120,134 +120,6 @@ void as_format::load_flux_track(const std::vector<uint8_t> &img, floppy_image *i
|
||||
}
|
||||
|
||||
|
||||
|
||||
woz_format::woz_format() : as_format()
|
||||
{
|
||||
}
|
||||
|
||||
const char *woz_format::name() const
|
||||
{
|
||||
return "woz";
|
||||
}
|
||||
|
||||
const char *woz_format::description() const
|
||||
{
|
||||
return "Apple II WOZ Image";
|
||||
}
|
||||
|
||||
const char *woz_format::extensions() const
|
||||
{
|
||||
return "woz";
|
||||
}
|
||||
|
||||
bool woz_format::supports_save() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t woz_format::signature[8] = { 0x57, 0x4f, 0x5a, 0x31, 0xff, 0x0a, 0x0d, 0x0a };
|
||||
const uint8_t woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, 0x0d, 0x0a };
|
||||
|
||||
int woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
|
||||
{
|
||||
uint8_t header[8];
|
||||
size_t actual;
|
||||
io.read_at(0, header, 8, actual);
|
||||
if (!memcmp(header, signature, 8)) return FIFID_SIGN;
|
||||
if (!memcmp(header, signature2, 8)) return FIFID_SIGN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) const
|
||||
{
|
||||
uint64_t image_size;
|
||||
if(io.length(image_size))
|
||||
return false;
|
||||
std::vector<uint8_t> img(image_size);
|
||||
size_t actual;
|
||||
io.read_at(0, &img[0], img.size(), actual);
|
||||
|
||||
// Check signature
|
||||
if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8)))
|
||||
return false;
|
||||
|
||||
uint32_t woz_vers = 1;
|
||||
if(!memcmp(&img[0], signature2, 8)) woz_vers = 2;
|
||||
|
||||
// Check integrity
|
||||
uint32_t crc = crc32r(&img[12], img.size() - 12);
|
||||
if(crc != r32(img, 8))
|
||||
return false;
|
||||
|
||||
uint32_t off_info = find_tag(img, 0x4f464e49);
|
||||
uint32_t off_tmap = find_tag(img, 0x50414d54);
|
||||
uint32_t off_trks = find_tag(img, 0x534b5254);
|
||||
// uint32_t off_writ = find_tag(img, 0x54495257);
|
||||
|
||||
if(!off_info || !off_tmap || !off_trks)
|
||||
return false;
|
||||
|
||||
uint32_t info_vers = r8(img, off_info + 0);
|
||||
if(info_vers < 1 || info_vers > 3)
|
||||
return false;
|
||||
|
||||
uint16_t off_flux = info_vers < 3 ? 0 : r16(img, off_info + 46);
|
||||
uint16_t flux_size = info_vers < 3 ? 0 : r16(img, off_info + 48);
|
||||
|
||||
if(!flux_size)
|
||||
off_flux = 0;
|
||||
|
||||
bool is_35 = r8(img, off_info + 1) == 2;
|
||||
|
||||
if((form_factor == floppy_image::FF_35 && !is_35) || (form_factor == floppy_image::FF_525 && is_35))
|
||||
return false;
|
||||
|
||||
unsigned int limit = is_35 ? 160 : 141;
|
||||
|
||||
if(is_35)
|
||||
image->set_form_variant(floppy_image::FF_35, floppy_image::SSDD);
|
||||
else
|
||||
image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD);
|
||||
|
||||
if (woz_vers == 1) {
|
||||
for (unsigned int trkid = 0; trkid != limit; trkid++) {
|
||||
int head = is_35 && trkid >= 80 ? 1 : 0;
|
||||
int track = is_35 ? trkid % 80 : trkid / 4;
|
||||
int subtrack = is_35 ? 0 : trkid & 3;
|
||||
|
||||
uint8_t idx = r8(img, off_tmap + trkid);
|
||||
if(idx != 0xff) {
|
||||
uint32_t boff = off_trks + 6656*idx;
|
||||
if (r16(img, boff + 6648) == 0)
|
||||
return false;
|
||||
generate_track_from_bitstream(track, head, &img[boff], r16(img, boff + 6648), image, subtrack, r16(img, boff + 6650));
|
||||
if(is_35 && !track && head)
|
||||
image->set_variant(floppy_image::DSDD);
|
||||
}
|
||||
}
|
||||
} else if (woz_vers == 2) {
|
||||
for (unsigned int trkid = 0; trkid != limit; trkid++) {
|
||||
int head = is_35 && trkid & 1 ? 1 : 0;
|
||||
int track = is_35 ? trkid >> 1 : trkid / 4;
|
||||
int subtrack = is_35 ? 0 : trkid & 3;
|
||||
|
||||
uint8_t idx = r8(img, off_tmap + trkid);
|
||||
uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff;
|
||||
|
||||
if(fidx != 0xff)
|
||||
load_flux_track(img, image, head, track, subtrack, fidx, off_trks);
|
||||
|
||||
else if(idx != 0xff) {
|
||||
if(!load_bitstream_track(img, image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
as_format::tdata as_format::analyze_for_save(floppy_image *image, int head, int track, int subtrack, int speed_zone)
|
||||
{
|
||||
// 200000000 / 60.0 * 1.979e-6 ~= 6.5967
|
||||
@ -413,6 +285,135 @@ void as_format::save_tracks(std::vector<uint8_t> &data, const std::vector<tdata>
|
||||
}
|
||||
|
||||
|
||||
|
||||
woz_format::woz_format() : as_format()
|
||||
{
|
||||
}
|
||||
|
||||
const char *woz_format::name() const
|
||||
{
|
||||
return "woz";
|
||||
}
|
||||
|
||||
const char *woz_format::description() const
|
||||
{
|
||||
return "Apple II WOZ Image";
|
||||
}
|
||||
|
||||
const char *woz_format::extensions() const
|
||||
{
|
||||
return "woz";
|
||||
}
|
||||
|
||||
bool woz_format::supports_save() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t woz_format::signature[8] = { 0x57, 0x4f, 0x5a, 0x31, 0xff, 0x0a, 0x0d, 0x0a };
|
||||
const uint8_t woz_format::signature2[8] = { 0x57, 0x4f, 0x5a, 0x32, 0xff, 0x0a, 0x0d, 0x0a };
|
||||
|
||||
int woz_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const
|
||||
{
|
||||
uint8_t header[8];
|
||||
size_t actual;
|
||||
io.read_at(0, header, 8, actual);
|
||||
if (!memcmp(header, signature, 8)) return FIFID_SIGN;
|
||||
if (!memcmp(header, signature2, 8)) return FIFID_SIGN;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool woz_format::load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) const
|
||||
{
|
||||
uint64_t image_size;
|
||||
if(io.length(image_size))
|
||||
return false;
|
||||
std::vector<uint8_t> img(image_size);
|
||||
size_t actual;
|
||||
io.read_at(0, &img[0], img.size(), actual);
|
||||
|
||||
// Check signature
|
||||
if((memcmp(&img[0], signature, 8)) && (memcmp(&img[0], signature2, 8)))
|
||||
return false;
|
||||
|
||||
uint32_t woz_vers = 1;
|
||||
if(!memcmp(&img[0], signature2, 8)) woz_vers = 2;
|
||||
|
||||
// Check integrity
|
||||
uint32_t crc = crc32r(&img[12], img.size() - 12);
|
||||
if(crc != r32(img, 8))
|
||||
return false;
|
||||
|
||||
uint32_t off_info = find_tag(img, 0x4f464e49);
|
||||
uint32_t off_tmap = find_tag(img, 0x50414d54);
|
||||
uint32_t off_trks = find_tag(img, 0x534b5254);
|
||||
// uint32_t off_writ = find_tag(img, 0x54495257);
|
||||
|
||||
if(!off_info || !off_tmap || !off_trks)
|
||||
return false;
|
||||
|
||||
uint32_t info_vers = r8(img, off_info + 0);
|
||||
if(info_vers < 1 || info_vers > 3)
|
||||
return false;
|
||||
|
||||
uint16_t off_flux = info_vers < 3 ? 0 : r16(img, off_info + 46);
|
||||
uint16_t flux_size = info_vers < 3 ? 0 : r16(img, off_info + 48);
|
||||
|
||||
if(!flux_size)
|
||||
off_flux = 0;
|
||||
|
||||
bool is_35 = r8(img, off_info + 1) == 2;
|
||||
|
||||
if((form_factor == floppy_image::FF_35 && !is_35) || (form_factor == floppy_image::FF_525 && is_35))
|
||||
return false;
|
||||
|
||||
unsigned int limit = is_35 ? 160 : 141;
|
||||
|
||||
if(is_35)
|
||||
image->set_form_variant(floppy_image::FF_35, floppy_image::SSDD);
|
||||
else
|
||||
image->set_form_variant(floppy_image::FF_525, floppy_image::SSSD);
|
||||
|
||||
if (woz_vers == 1) {
|
||||
for (unsigned int trkid = 0; trkid != limit; trkid++) {
|
||||
int head = is_35 && trkid >= 80 ? 1 : 0;
|
||||
int track = is_35 ? trkid % 80 : trkid / 4;
|
||||
int subtrack = is_35 ? 0 : trkid & 3;
|
||||
|
||||
uint8_t idx = r8(img, off_tmap + trkid);
|
||||
if(idx != 0xff) {
|
||||
uint32_t boff = off_trks + 6656*idx;
|
||||
if (r16(img, boff + 6648) == 0)
|
||||
return false;
|
||||
generate_track_from_bitstream(track, head, &img[boff], r16(img, boff + 6648), image, subtrack, r16(img, boff + 6650));
|
||||
if(is_35 && !track && head)
|
||||
image->set_variant(floppy_image::DSDD);
|
||||
}
|
||||
}
|
||||
} else if (woz_vers == 2) {
|
||||
for (unsigned int trkid = 0; trkid != limit; trkid++) {
|
||||
int head = is_35 && trkid & 1 ? 1 : 0;
|
||||
int track = is_35 ? trkid >> 1 : trkid / 4;
|
||||
int subtrack = is_35 ? 0 : trkid & 3;
|
||||
|
||||
uint8_t idx = r8(img, off_tmap + trkid);
|
||||
uint8_t fidx = off_flux ? r8(img, off_flux*512 + 8 + trkid) : 0xff;
|
||||
|
||||
if(fidx != 0xff)
|
||||
load_flux_track(img, image, head, track, subtrack, fidx, off_trks);
|
||||
|
||||
else if(idx != 0xff) {
|
||||
if(!load_bitstream_track(img, image, head, track, subtrack, idx, off_trks, !is_35, is_35 && !track && head))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool woz_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) const
|
||||
{
|
||||
std::vector<tdata> tracks(160);
|
||||
@ -496,7 +497,7 @@ const char *moof_format::extensions() const
|
||||
|
||||
bool moof_format::supports_save() const
|
||||
{
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
const uint8_t moof_format::signature[8] = { 0x4d, 0x4f, 0x4f, 0x46, 0xff, 0x0a, 0x0d, 0x0a };
|
||||
@ -578,4 +579,55 @@ bool moof_format::load(util::random_read &io, uint32_t form_factor, const std::v
|
||||
return true;
|
||||
}
|
||||
|
||||
bool moof_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) const
|
||||
{
|
||||
std::vector<tdata> tracks(160);
|
||||
bool twosided = false;
|
||||
bool is_hd = false;
|
||||
|
||||
if(image->get_variant() == floppy_image::DSHD) {
|
||||
twosided = true;
|
||||
is_hd = true;
|
||||
for(unsigned int i=0; i != 160; i++)
|
||||
tracks[i] = analyze_for_save(image, i & 1, i >> 1, 0, 6);
|
||||
|
||||
} else {
|
||||
for(unsigned int i=0; i != 160; i++) {
|
||||
tracks[i] = analyze_for_save(image, i & 1, i >> 1, 0, i / (2*16));
|
||||
if((i & 1) && tracks[i].track_size)
|
||||
twosided = true;
|
||||
}
|
||||
}
|
||||
|
||||
auto [total_blocks, max_blocks] = count_blocks(tracks);
|
||||
bool has_flux = test_flux(tracks);
|
||||
|
||||
std::vector<uint8_t> data(1536 + total_blocks*512 + (has_flux ? 512 : 0), 0);
|
||||
|
||||
memcpy(&data[0], signature, 8);
|
||||
|
||||
w32(data, 12, 0x4F464E49); // INFO
|
||||
w32(data, 16, 60); // size
|
||||
data[20] = 1; // chunk version
|
||||
data[21] = is_hd ? 3 : twosided ? 2 : 1; // variant
|
||||
data[22] = 0; // not write protected
|
||||
data[23] = 1; // synchronized, since our internal format is
|
||||
data[24] = is_hd ? 8 : 16; // optimal timing
|
||||
data[25] = 'M';
|
||||
data[26] = 'A';
|
||||
data[27] = 'M';
|
||||
data[28] = 'E';
|
||||
memset(&data[29], ' ', 32-4);
|
||||
data[57] = 0; // pad
|
||||
w16(data, 58, max_blocks);
|
||||
w16(data, 60, has_flux ? total_blocks+3 : 0);
|
||||
w16(data, 62, max_blocks);
|
||||
|
||||
save_tracks(data, tracks, total_blocks, has_flux);
|
||||
|
||||
size_t actual;
|
||||
io.write_at(0, data.data(), data.size(), actual);
|
||||
return true;
|
||||
}
|
||||
|
||||
const moof_format FLOPPY_MOOF_FORMAT;
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
|
||||
virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) const override;
|
||||
virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) const override;
|
||||
virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image) const override;
|
||||
virtual bool supports_save() const override;
|
||||
|
||||
virtual const char *name() const override;
|
||||
|
Loading…
Reference in New Issue
Block a user