diff options
author | 2015-11-08 12:56:12 +0100 | |
---|---|---|
committer | 2015-11-08 12:56:12 +0100 | |
commit | 7c19aac60e12d6f5ea301bdb34d7826a01e0b06f (patch) | |
tree | f310d86aa2c6bfc19d115307dedde4eb0cd52dad /src/lib/formats/apridisk.cpp | |
parent | a57b46ae933badd7441ce1644711dbb851e2b504 (diff) |
Rename *.c -> *.cpp in our source (nw)
Diffstat (limited to 'src/lib/formats/apridisk.cpp')
-rw-r--r-- | src/lib/formats/apridisk.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/lib/formats/apridisk.cpp b/src/lib/formats/apridisk.cpp new file mode 100644 index 00000000000..b19e2c26bd7 --- /dev/null +++ b/src/lib/formats/apridisk.cpp @@ -0,0 +1,148 @@ +// license:GPL-2.0+ +// copyright-holders:Dirk Best +/*************************************************************************** + + APRIDISK + + Disk image format for the ACT Apricot + +***************************************************************************/ + +#include "emu.h" +#include "imageutl.h" +#include "apridisk.h" + +apridisk_format::apridisk_format() +{ +} + +const char *apridisk_format::name() const +{ + return "apridisk"; +} + +const char *apridisk_format::description() const +{ + return "APRIDISK disk image"; +} + +const char *apridisk_format::extensions() const +{ + return "dsk"; +} + +int apridisk_format::identify(io_generic *io, UINT32 form_factor) +{ + UINT8 header[APR_HEADER_SIZE]; + io_generic_read(io, header, 0, APR_HEADER_SIZE); + + const char magic[] = "ACT Apricot disk image\x1a\x04"; + + if (memcmp(header, magic, sizeof(magic) - 1) == 0) + return 100; + else + return 0; +} + +bool apridisk_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) +{ + desc_pc_sector sectors[80][2][18]; + UINT8 sector_data[MAX_SECTORS * SECTOR_SIZE]; + UINT8 *data_ptr = sector_data; + int track_count = 0, head_count = 0, sector_count = 0; + + UINT64 file_size = io_generic_size(io); + UINT64 file_offset = APR_HEADER_SIZE; + + while (file_offset < file_size) + { + // read sector header + UINT8 sector_header[16]; + io_generic_read(io, sector_header, file_offset, 16); + + UINT32 type = pick_integer_le(§or_header, 0, 4); + UINT16 compression = pick_integer_le(§or_header, 4, 2); + UINT16 header_size = pick_integer_le(§or_header, 6, 2); + UINT32 data_size = pick_integer_le(§or_header, 8, 4); + + file_offset += header_size; + + switch (type) + { + case APR_SECTOR: + UINT8 head = pick_integer_le(§or_header, 12, 1); + UINT8 sector = pick_integer_le(§or_header, 13, 1); + UINT8 track = (UINT8) pick_integer_le(§or_header, 14, 2); + + track_count = MAX(track_count, track); + head_count = MAX(head_count, head); + sector_count = MAX(sector_count, sector); + + // build sector info + sectors[track][head][sector - 1].head = head; + sectors[track][head][sector - 1].sector = sector; + sectors[track][head][sector - 1].track = track; + sectors[track][head][sector - 1].size = SECTOR_SIZE >> 8; + sectors[track][head][sector - 1].actual_size = SECTOR_SIZE; + sectors[track][head][sector - 1].deleted = false; + sectors[track][head][sector - 1].bad_crc = false; + + // read sector data + switch (compression) + { + case APR_COMPRESSED: + { + UINT8 comp[3]; + io_generic_read(io, comp, file_offset, 3); + UINT16 length = pick_integer_le(comp, 0, 2); + + if (length != SECTOR_SIZE) + fatalerror("apridisk_format: Invalid compression length %04x\n", length); + + memset(data_ptr, comp[2], SECTOR_SIZE); + } + break; + + case APR_UNCOMPRESSED: + io_generic_read(io, data_ptr, file_offset, SECTOR_SIZE); + break; + + default: + fatalerror("apridisk_format: Invalid compression %04x\n", compression); + } + + sectors[track][head][sector - 1].data = data_ptr; + data_ptr += SECTOR_SIZE; + + break; + + } + + file_offset += data_size; + } + + // track/head index are zero-based, so increase the final count by 1 + track_count++; + head_count++; + + int cell_count = (sector_count == 18 ? 200000 : 100000); + + // now build our final track info + for (int track = 0; track < track_count; track++) + for (int head = 0; head < head_count; head++) + build_pc_track_mfm(track, head, image, cell_count, sector_count, sectors[track][head], 84, 80, 50, 22); + + return true; +} + +bool apridisk_format::save(io_generic *io, floppy_image *image) +{ + return false; +} + +bool apridisk_format::supports_save() const +{ + return false; +} + +const floppy_format_type FLOPPY_APRIDISK_FORMAT = &floppy_image_format_creator<apridisk_format>; |