diff --git a/src/lib/formats/ap_dsk35.c b/src/lib/formats/ap_dsk35.c index f76e9c1606a..a94d76e95c2 100644 --- a/src/lib/formats/ap_dsk35.c +++ b/src/lib/formats/ap_dsk35.c @@ -99,7 +99,8 @@ #include #include -#include "formats/ap_dsk35.h" +#include "emu.h" +#include "ap_dsk35.h" struct apple35_tag { @@ -1185,3 +1186,297 @@ LEGACY_FLOPPY_OPTIONS_START( apple35_iigs ) SECTOR_LENGTH([512]) FIRST_SECTOR_ID([0])) LEGACY_FLOPPY_OPTIONS_END + + +dc42_format::dc42_format() : floppy_image_format_t() +{ +} + +const char *dc42_format::name() const +{ + return "dc42"; +} + +const char *dc42_format::description() const +{ + return "DiskCopy 4.2 image"; +} + +const char *dc42_format::extensions() const +{ + return "dc42"; +} + +bool dc42_format::supports_save() const +{ + return true; +} + +int dc42_format::identify(io_generic *io, UINT32 form_factor) +{ + UINT8 h[0x54]; + int size = io_generic_size(io); + if(size < 0x54) + return 0; + + io_generic_read(io, h, 0, 0x54); + int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43]; + int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47]; + + return dsize > 0 && tsize >= 0 && size == 0x54+tsize+dsize && h[0] < 64 && h[0x52] == 1 && h[0x53] == 0 ? 100 : 0; +} + +const floppy_image_format_t::desc_e dc42_format::mac_gcr[] = { + { SECTOR_LOOP_START, 0, -1 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xd5aa96, 24 }, + { CRC_MACHEAD_START, 0 }, + { TRACK_ID_GCR6 }, + { SECTOR_ID_GCR6 }, + { TRACK_HEAD_ID_GCR6 }, + { SECTOR_INFO_GCR6 }, + { CRC_END, 0 }, + { CRC, 0 }, + { RAWBITS, 0xdeaaff, 24 }, + { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, + { RAWBITS, 0xd5aaad, 24 }, + { SECTOR_ID_GCR6 }, + { SECTOR_DATA_MAC, -1 }, + { RAWBITS, 0xdeaaff, 24 }, + { RAWBITS, 0xff, 8 }, + { SECTOR_LOOP_END }, + { END }, +}; + + +bool dc42_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) +{ + UINT8 h[0x54]; + io_generic_read(io, h, 0, 0x54); + int dsize = (h[0x40] << 24) | (h[0x41] << 16) | (h[0x42] << 8) | h[0x43]; + int tsize = (h[0x44] << 24) | (h[0x45] << 16) | (h[0x46] << 8) | h[0x47]; + + UINT8 encoding = h[0x50]; + UINT8 format = h[0x51]; + + if((encoding != 0x00 || format != 0x02) && (encoding != 0x01 || format != 0x22)) { + logerror("dc42: Unsupported encoding/format combination %02x\%02x\n", encoding, format); + return false; + } + + UINT8 sector_data[(512+12)*12]; + memset(sector_data, 0, sizeof(sector_data)); + + desc_s sectors[12]; + + int pos_data = 0x54; + int pos_tag = 0x54+dsize; + + int head_count = encoding == 1 ? 2 : 1; + + for(int track=0; track < 80; track++) { + for(int head=0; head < head_count; head++) { + int ns = 12 - (track/16); + int si = 0; + for(int i=0; i> 3] >> (7-(pos & 7))) & 1); + pos++; + if(pos == ts) { + pos = 0; + wrap++; + } + } + return v; +} + +void dc42_format::update_chk(const UINT8 *data, int size, UINT32 &chk) +{ + for(int i=0; i> 1) | (chk << 31); + } +} + +bool dc42_format::save(io_generic *io, floppy_image *image) +{ + int g_tracks, g_heads; + image->get_actual_geometry(g_tracks, g_heads); + + if(g_heads == 0) + g_heads = 1; + + UINT8 h[0x54]; + memset(h, 0, 0x54); + strcpy((char *)h+1, "Unnamed"); + h[0] = 7; + int nsect = 16*(12+11+10+9+8)*g_heads; + UINT32 dsize = nsect*512; + UINT32 tsize = nsect*12; + h[0x40] = dsize >> 24; + h[0x41] = dsize >> 16; + h[0x42] = dsize >> 8; + h[0x43] = dsize; + h[0x44] = tsize >> 24; + h[0x45] = tsize >> 16; + h[0x46] = tsize >> 8; + h[0x47] = tsize; + h[0x50] = g_heads == 2 ? 0x01 : 0x00; + h[0x51] = g_heads == 2 ? 0x22 : 0x02; + h[0x52] = 0x01; + h[0x53] = 0x00; + + UINT32 dchk = 0; + UINT32 tchk = 0; + + int pos_data = 0x54; + int pos_tag = 0x54+dsize; + + for(int track=0; track < 80; track++) { + for(int head=0; head < g_heads; head++) { + UINT8 sectdata[(512+12)*12]; + memset(sectdata, 0, sizeof(sectdata)); + int nsect = 12-(track/16); + UINT8 buf[13000]; + int ts; + generate_bitstream_from_track(track, head, 200000000/(6208*nsect), buf, ts, image); + int pos = 0; + int wrap = 0; + int hb = 0; + for(;;) { + UINT8 v = gb(buf, ts, pos, wrap); + if(v == 0xff) + hb = 1; + else if(hb == 1 && v == 0xd5) + hb = 2; + else if(hb == 2 && v == 0xaa) + hb = 3; + else if(hb == 3 && v == 0x96) + hb = 4; + else + hb = 0; + + if(hb == 4) { + UINT8 h[7]; + for(int i=0; i<7; i++) + h[i] = gb(buf, ts, pos, wrap); + UINT8 v2 = gcr6bw_tb[h[2]]; + UINT8 v3 = gcr6bw_tb[h[3]]; + UINT8 tr = gcr6bw_tb[h[0]] | (v2 & 1 ? 0x40 : 0x00); + UINT8 se = gcr6bw_tb[h[1]]; + UINT8 si = v2 & 0x20 ? 1 : 0; + // UINT8 ds = v3 & 0x20 ? 1 : 0; + // UINT8 fmt = v3 & 0x1f; + UINT8 c1 = (tr^se^v2^v3) & 0x3f; + UINT8 chk = gcr6bw_tb[h[4]]; + if(chk == c1 && tr == track && si == head && se < nsect) { + int opos = pos; + int owrap = wrap; + hb = 0; + for(int i=0; i<20 && hb != 4; i++) { + v = gb(buf, ts, pos, wrap); + if(v == 0xff) + hb = 1; + else if(hb == 1 && v == 0xd5) + hb = 2; + else if(hb == 2 && v == 0xaa) + hb = 3; + else if(hb == 3 && v == 0xad) + hb = 4; + else + hb = 0; + } + if(hb == 4) { + UINT8 *dest = sectdata+(512+12)*se; + gb(buf, ts, pos, wrap); // Ignore the sector byte + UINT8 ca = 0, cb = 0, cc = 0; + for(int i=0; i<522/3+1; i++) { + UINT8 e0 = gb(buf, ts, pos, wrap); + UINT8 e1 = gb(buf, ts, pos, wrap); + UINT8 e2 = gb(buf, ts, pos, wrap); + UINT8 e3 = i == 522/3 ? 0x96 : gb(buf, ts, pos, wrap); + UINT8 va, vb, vc; + gcr6_decode(e0, e1, e2, e3, va, vb, vc); + cc = (cc << 1) | (cc >> 7); + va = va ^ cc; + int suma = ca + va + (cc & 1); + ca = suma; + vb = vb ^ ca; + int sumb = cb + vb + (suma >> 8); + cb = sumb; + vc = vc ^ cb; + cc = cc + vc + (sumb >> 8); + *dest++ = va; + *dest++ = vb; + if(i != 522/3) + *dest++ = vc; + } + } else { + pos = opos; + wrap = owrap; + } + } + hb = 0; + } + if(wrap) + break; + } + for(int i=0; i> 24; + h[0x49] = dchk >> 16; + h[0x4a] = dchk >> 8; + h[0x4b] = dchk; + h[0x4c] = tchk >> 24; + h[0x4d] = tchk >> 16; + h[0x4e] = tchk >> 8; + h[0x4f] = tchk; + + io_generic_write(io, h, 0, 0x54); + return true; +} + +const floppy_format_type FLOPPY_DC42_FORMAT = &floppy_image_format_creator; diff --git a/src/lib/formats/ap_dsk35.h b/src/lib/formats/ap_dsk35.h index e1d308f0f4c..d113d3481a0 100644 --- a/src/lib/formats/ap_dsk35.h +++ b/src/lib/formats/ap_dsk35.h @@ -21,5 +21,27 @@ int apple35_sectors_per_track(floppy_image_legacy *image, int track); LEGACY_FLOPPY_OPTIONS_EXTERN(apple35_mac); LEGACY_FLOPPY_OPTIONS_EXTERN(apple35_iigs); +class dc42_format : public floppy_image_format_t +{ +public: + dc42_format(); + + virtual int identify(io_generic *io, UINT32 form_factor); + virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); + virtual bool save(io_generic *io, floppy_image *image); + + virtual const char *name() const; + virtual const char *description() const; + virtual const char *extensions() const; + virtual bool supports_save() const; + +private: + static const desc_e mac_gcr[]; + + UINT8 gb(const UINT8 *buf, int ts, int &pos, int &wrap); + void update_chk(const UINT8 *data, int size, UINT32 &chk); +}; + +extern const floppy_format_type FLOPPY_DC42_FORMAT; #endif /* AP_DSK35_H */ diff --git a/src/lib/formats/dfi_dsk.c b/src/lib/formats/dfi_dsk.c index 4020f9b8a21..18ec4785aa6 100644 --- a/src/lib/formats/dfi_dsk.c +++ b/src/lib/formats/dfi_dsk.c @@ -75,7 +75,7 @@ bool dfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) total_time += v & 0x7f; if((v & 0x80) && !index_time) index_time = total_time; - } + } } if(!index_time) diff --git a/src/lib/formats/dfi_dsk.h b/src/lib/formats/dfi_dsk.h index c645372ea6b..97ae4e3deb8 100644 --- a/src/lib/formats/dfi_dsk.h +++ b/src/lib/formats/dfi_dsk.h @@ -10,7 +10,7 @@ public: virtual int identify(io_generic *io, UINT32 form_factor); virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image); - // virtual bool save(io_generic *io, floppy_image *image); + // virtual bool save(io_generic *io, floppy_image *image); virtual const char *name() const; virtual const char *description() const; diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c index 2c6c0a5bf1f..24a1aa7f0f9 100644 --- a/src/lib/formats/flopimg.c +++ b/src/lib/formats/flopimg.c @@ -1034,6 +1034,7 @@ bool floppy_image_format_t::type_no_data(int type) const { return type == CRC_CCITT_START || type == CRC_AMIGA_START || + type == CRC_MACHEAD_START || type == CRC_END || type == SECTOR_LOOP_START || type == SECTOR_LOOP_END || @@ -1062,6 +1063,9 @@ void floppy_image_format_t::collect_crcs(const desc_e *desc, gen_crc_info *crcs) case CRC_AMIGA_START: crcs[desc[i].p1].type = CRC_AMIGA; break; + case CRC_MACHEAD_START: + crcs[desc[i].p1].type = CRC_MACHEAD; + break; } for(int i=0; desc[i].type != END; i++) @@ -1077,6 +1081,7 @@ int floppy_image_format_t::crc_cells_size(int type) const switch(type) { case CRC_CCITT: return 32; case CRC_AMIGA: return 64; + case CRC_MACHEAD: return 8; default: return 0; } } @@ -1086,6 +1091,14 @@ bool floppy_image_format_t::bit_r(const UINT32 *buffer, int offset) return (buffer[offset] & floppy_image::MG_MASK) == MG_1; } +UINT32 floppy_image_format_t::bitn_r(const UINT32 *buffer, int offset, int count) +{ + UINT32 r = 0; + for(int i=0; istart, crc->end)); } +void floppy_image_format_t::fixup_crc_machead(UINT32 *buffer, const gen_crc_info *crc) +{ + UINT8 v = 0; + for(int o = crc->start; o < crc->end; o+=8) + v = v ^ gcr6bw_tb[bitn_r(buffer, o, 8)]; + int offset = crc->write; + raw_w(buffer, offset, 8, gcr6fw_tb[v]); +} + void floppy_image_format_t::fixup_crcs(UINT32 *buffer, gen_crc_info *crcs) { for(int i=0; i != MAX_CRC_COUNT; i++) if(crcs[i].write != -1) { switch(crcs[i].type) { - case CRC_AMIGA: fixup_crc_amiga(buffer, crcs+i); break; - case CRC_CCITT: fixup_crc_ccitt(buffer, crcs+i); break; + case CRC_AMIGA: fixup_crc_amiga(buffer, crcs+i); break; + case CRC_CCITT: fixup_crc_ccitt(buffer, crcs+i); break; + case CRC_MACHEAD: fixup_crc_machead(buffer, crcs+i); break; } if(crcs[i].fixup_mfm_clock) { int offset = crcs[i].write + crc_cells_size(crcs[i].type); @@ -1167,6 +1190,28 @@ void floppy_image_format_t::fixup_crcs(UINT32 *buffer, gen_crc_info *crcs) } } +UINT32 floppy_image_format_t::gcr6_encode(UINT8 va, UINT8 vb, UINT8 vc) +{ + UINT32 r; + r = gcr6fw_tb[((va >> 2) & 0x30) | ((vb >> 4) & 0x0c) | ((vc >> 6) & 0x03)] << 24; + r |= gcr6fw_tb[va & 0x3f] << 16; + r |= gcr6fw_tb[vb & 0x3f] << 8; + r |= gcr6fw_tb[vc & 0x3f]; + return r; +} + +void floppy_image_format_t::gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc) +{ + e0 = gcr6bw_tb[e0]; + e1 = gcr6bw_tb[e1]; + e2 = gcr6bw_tb[e2]; + e3 = gcr6bw_tb[e3]; + + va = ((e0 << 2) & 0xc0) | e1; + vb = ((e0 << 4) & 0xc0) | e2; + vc = ((e0 << 6) & 0xc0) | e3; +} + int floppy_image_format_t::calc_sector_index(int num, int interleave, int skew, int total_sectors, int track_head) { int i = 0; @@ -1227,14 +1272,26 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he mfm_w(buffer, offset, 8, track); break; + case TRACK_ID_GCR6: + raw_w(buffer, offset, 8, gcr6fw_tb[track & 0x3f]); + break; + case HEAD_ID: mfm_w(buffer, offset, 8, head); break; + case TRACK_HEAD_ID_GCR6: + raw_w(buffer, offset, 8, gcr6fw_tb[(track & 0x40 ? 1 : 0) | (head ? 0x20 : 0)]); + break; + case SECTOR_ID: mfm_w(buffer, offset, 8, sect[sector_idx].sector_id); break; + case SECTOR_ID_GCR6: + raw_w(buffer, offset, 8, gcr6fw_tb[sect[sector_idx].sector_id]); + break; + case SIZE_ID: { int size = sect[sector_idx].size; int id; @@ -1243,6 +1300,10 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he break; } + case SECTOR_INFO_GCR6: + raw_w(buffer, offset, 8, gcr6fw_tb[sect[sector_idx].sector_info]); + break; + case OFFSET_ID_O: mfm_half_w(buffer, offset, 7, track*2+head); break; @@ -1272,7 +1333,7 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he sector_loop_start = index; sector_idx = desc[index].p1; sector_cnt = sector_idx; - sector_limit = desc[index].p2; + sector_limit = desc[index].p2 == -1 ? sector_idx+sect_count-1 : desc[index].p2; sector_idx = calc_sector_index(sector_cnt,sector_interleave,sector_skew,sector_limit+1,track*2 + head); break; @@ -1292,6 +1353,7 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he case CRC_AMIGA_START: case CRC_CCITT_START: + case CRC_MACHEAD_START: crcs[desc[index].p1].start = offset; break; @@ -1325,6 +1387,34 @@ void floppy_image_format_t::generate_track(const desc_e *desc, int track, int he break; } + case SECTOR_DATA_MAC: { + const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx); + const UINT8 *data = csect->data; + int size = csect->size; + UINT8 ca = 0, cb = 0, cc = 0; + for(int i=0; i < size; i+=3) { + int dt = size-i; + UINT8 va = data[i]; + UINT8 vb = dt > 1 ? data[i+1] : 0; + UINT8 vc = dt > 2 ? data[i+2] : 0; + + cc = (cc << 1) | (cc >> 7); + int suma = ca + va + (cc & 1); + ca = suma; + va = va ^ cc; + int sumb = cb + vb + (suma >> 8); + cb = sumb; + vb = vb ^ ca; + cc = cc + vc + (sumb >> 8); + vc = vc ^ cb; + + int nb = dt > 2 ? 32 : dt > 1 ? 24 : 16; + raw_w(buffer, offset, nb, gcr6_encode(va, vb, vc) >> (32-nb)); + } + raw_w(buffer, offset, 32, gcr6_encode(ca, cb, cc)); + break; + } + default: printf("%d.%d.%d (%d) unhandled\n", desc[index].type, desc[index].p1, desc[index].p2, index); break; @@ -1467,6 +1557,39 @@ void floppy_image_format_t::generate_track_from_levels(int track, int head, UINT image->set_write_splice_position(track, head, splice_angular_pos); } +const UINT8 floppy_image_format_t::gcr6fw_tb[0x40] = +{ + 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, + 0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc, + 0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3, + 0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, + 0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec, + 0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, + 0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, +}; + +const UINT8 floppy_image_format_t::gcr6bw_tb[0x100] = +{ + // 0 1 2 3 4 5 6 7 8 9 a b c d e f + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x03, 0x00, 0x04, 0x05, 0x06, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x00, 0x00, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x00, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x1c, 0x1d, 0x1e, + 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x21, 0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x2a, 0x2b, 0x00, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x00, 0x00, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +}; + // Atari ST Fastcopy Pro layouts #define SECTOR_42_HEADER(cid) \ diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index 004d7ba8418..40467798539 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -258,33 +258,39 @@ protected: }; enum { - END, // End of description - MFM, // One byte in p1 to be mfm-encoded, msb first, repeated p2 times - MFMBITS, // A value of p2 bits in p1 to be mfm-encoded, msb first - RAW, // One 16 bits word in p1 to be written raw, msb first, repeated p2 times - RAWBITS, // A value of p2 bits in p1 to be copied as-is, msb first - TRACK_ID, // Track id byte, mfm-encoded - HEAD_ID, // Head id byte, mfm-encoded - SECTOR_ID, // Sector id byte, mfm-encoded - SIZE_ID, // Sector size code on one byte [log2(size/128)], mfm-encoded - OFFSET_ID_O, // Offset (track*2+head) byte, odd bits, mfm-encoded - OFFSET_ID_E, // Offset (track*2+head) byte, even bits, mfm-encoded - SECTOR_ID_O, // Sector id byte, odd bits, mfm-encoded - SECTOR_ID_E, // Sector id byte, even bits, mfm-encoded - REMAIN_O, // Remaining sector count, odd bits, mfm-encoded, total sector count in p1 - REMAIN_E, // Remaining sector count, even bits, mfm-encoded, total sector count in p1 + END, // End of description + MFM, // One byte in p1 to be mfm-encoded, msb first, repeated p2 times + MFMBITS, // A value of p2 bits in p1 to be mfm-encoded, msb first + RAW, // One 16 bits word in p1 to be written raw, msb first, repeated p2 times + RAWBITS, // A value of p2 bits in p1 to be copied as-is, msb first + TRACK_ID, // Track id byte, mfm-encoded + TRACK_ID_GCR6, // Track id low 6 bits, gcr6-encoded + HEAD_ID, // Head id byte, mfm-encoded + TRACK_HEAD_ID_GCR6, // Track id 7th bit + head, gc6-encoded + SECTOR_ID, // Sector id byte, mfm-encoded + SECTOR_ID_GCR6, // Sector id byte, gcr6-encoded + SIZE_ID, // Sector size code on one byte [log2(size/128)], mfm-encoded + SECTOR_INFO_GCR6, // Sector info byte, gcr6-encoded + OFFSET_ID_O, // Offset (track*2+head) byte, odd bits, mfm-encoded + OFFSET_ID_E, // Offset (track*2+head) byte, even bits, mfm-encoded + SECTOR_ID_O, // Sector id byte, odd bits, mfm-encoded + SECTOR_ID_E, // Sector id byte, even bits, mfm-encoded + REMAIN_O, // Remaining sector count, odd bits, mfm-encoded, total sector count in p1 + REMAIN_E, // Remaining sector count, even bits, mfm-encoded, total sector count in p1 - SECTOR_DATA, // Sector data to mfm-encode, which in p1, -1 for the current one per the sector id - SECTOR_DATA_O, // Sector data to mfm-encode, odd bits only, which in p1, -1 for the current one per the sector id - SECTOR_DATA_E, // Sector data to mfm-encode, even bits only, which in p1, -1 for the current one per the sector id + SECTOR_DATA, // Sector data to mfm-encode, which in p1, -1 for the current one per the sector id + SECTOR_DATA_O, // Sector data to mfm-encode, odd bits only, which in p1, -1 for the current one per the sector id + SECTOR_DATA_E, // Sector data to mfm-encode, even bits only, which in p1, -1 for the current one per the sector id + SECTOR_DATA_MAC, // Transformed sector data + checksum, mac style, id in p1, -1 for the current one per the sector id - CRC_CCITT_START, // Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id - CRC_AMIGA_START, // Start an amiga checksum calculation, p1 = crc id - CRC_END, // End the checksum, p1 = crc id - CRC, // Write a checksum in the apporpriate format, p1 = crc id + CRC_CCITT_START, // Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id + CRC_AMIGA_START, // Start an amiga checksum calculation, p1 = crc id + CRC_MACHEAD_START, // Start of the mac gcr6 sector header checksum calculation (xor of pre-encode 6-bits values, gcr6-encoded) + CRC_END, // End the checksum, p1 = crc id + CRC, // Write a checksum in the apporpriate format, p1 = crc id - SECTOR_LOOP_START, // Start of the per-sector loop, sector number goes from p1 to p2 inclusive - SECTOR_LOOP_END, // End of the per-sector loop + SECTOR_LOOP_START, // Start of the per-sector loop, sector number goes from p1 to p2 inclusive + SECTOR_LOOP_END, // End of the per-sector loop SECTOR_INTERLEAVE_SKEW, // Defines interleave and skew for sector counting }; @@ -293,6 +299,7 @@ protected: int size; // Sector size, int bytes const UINT8 *data; // Sector data UINT8 sector_id; // Sector ID + UINT8 sector_info; // Sector free byte }; @@ -320,6 +327,8 @@ protected: // Normalize the times in a cell buffer to sum up to 200000000 void normalize_times(UINT32 *buffer, int bitlen); + // Some conversion tables + static const UINT8 gcr6fw_tb[0x40], gcr6bw_tb[0x100]; // Some useful descriptions shared by multiple formats @@ -414,14 +423,17 @@ protected: void get_track_data_mfm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, UINT8 *sectdata); bool bit_r(const UINT32 *buffer, int offset); + UINT32 bitn_r(const UINT32 *buffer, int offset, int count); void bit_w(UINT32 *buffer, int offset, bool val, UINT32 size = 1000); UINT16 calc_crc_ccitt(const UINT32 *buffer, int start, int end); void raw_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000); void mfm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000); void mfm_half_w(UINT32 *buffer, int &offset, int start_bit, UINT32 val, UINT32 size = 1000); + UINT32 gcr6_encode(UINT8 va, UINT8 vb, UINT8 vc); + void gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc); private: - enum { CRC_NONE, CRC_AMIGA, CRC_CCITT }; + enum { CRC_NONE, CRC_AMIGA, CRC_CCITT, CRC_MACHEAD }; enum { MAX_CRC_COUNT = 64 }; struct gen_crc_info { int type, start, end, write; @@ -434,6 +446,7 @@ private: int crc_cells_size(int type) const; void fixup_crc_amiga(UINT32 *buffer, const gen_crc_info *crc); void fixup_crc_ccitt(UINT32 *buffer, const gen_crc_info *crc); + void fixup_crc_machead(UINT32 *buffer, const gen_crc_info *crc); void fixup_crcs(UINT32 *buffer, gen_crc_info *crcs); void collect_crcs(const desc_e *desc, gen_crc_info *crcs);