diff options
author | 2021-01-21 15:08:56 +0100 | |
---|---|---|
committer | 2021-01-22 00:02:30 +0100 | |
commit | bd2db8dcc6c14638c02b8f88e691ae94a3a28f3d (patch) | |
tree | 8a31c8993323cf09185666f0fba09c651057c60e /src/lib/formats/ap_dsk35.cpp | |
parent | 1a76ae1e0a53ad6658c195b6e38d1a1d0ad477fe (diff) |
flopimg: Change the extracted bitstreams into vector<bool>
flopimg: Change the extracted sectors into vector<vector<uint8_t>>
flopimg: Add a Mac sector extraction
apple 3.5 gcr: Generalize track creation/extraction
apple 3.5 gcr: Add a pure sector format
Diffstat (limited to 'src/lib/formats/ap_dsk35.cpp')
-rw-r--r-- | src/lib/formats/ap_dsk35.cpp | 262 |
1 files changed, 115 insertions, 147 deletions
diff --git a/src/lib/formats/ap_dsk35.cpp b/src/lib/formats/ap_dsk35.cpp index 580133b1844..8b76097211c 100644 --- a/src/lib/formats/ap_dsk35.cpp +++ b/src/lib/formats/ap_dsk35.cpp @@ -1209,8 +1209,6 @@ LEGACY_FLOPPY_OPTIONS_END // license:BSD-3-Clause // copyright-holders:Olivier Galibert -const int dc42_format::cell_count[5] = { 76950, 70672, 64244, 57739, 51387 }; - dc42_format::dc42_format() : floppy_image_format_t() { } @@ -1249,36 +1247,6 @@ int dc42_format::identify(io_generic *io, uint32_t form_factor, const std::vecto return 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_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) { uint8_t h[0x54]; @@ -1297,7 +1265,7 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u uint8_t sector_data[(512+12)*12]; memset(sector_data, 0, sizeof(sector_data)); - desc_s sectors[12]; + desc_gcr_sector sectors[12]; int pos_data = 0x54; int pos_tag = 0x54+dsize; @@ -1310,41 +1278,29 @@ bool dc42_format::load(io_generic *io, uint32_t form_factor, const std::vector<u int si = 0; for(int i=0; i<ns; i++) { uint8_t *data = sector_data + (512+12)*i; - sectors[si].data = data; - sectors[si].size = 512+12; - sectors[si].sector_id = i; - sectors[si].sector_info = format; + sectors[si].track = track; + sectors[si].head = head; + sectors[si].sector = i; + sectors[si].info = format; if(tsize) { io_generic_read(io, data, pos_tag, 12); + sectors[si].tag = data; pos_tag += 12; - } + } else + sectors[si].tag = nullptr; + sectors[si].data = data+12; io_generic_read(io, data+12, pos_data, 512); pos_data += 512; si = (si + 2) % ns; if(si == 0) si++; } - generate_track(mac_gcr, track, head, sectors, ns, 6208*ns, image); + build_mac_track_gcr(track, head, image, sectors); } } return true; } -uint8_t dc42_format::gb(const uint8_t *buf, int ts, int &pos, int &wrap) -{ - uint8_t v = 0; - int w1 = wrap; - while(wrap != w1+2 && !(v & 0x80)) { - v = v << 1 | ((buf[pos >> 3] >> (7-(pos & 7))) & 1); - pos++; - if(pos == ts) { - pos = 0; - wrap++; - } - } - return v; -} - void dc42_format::update_chk(const uint8_t *data, int size, uint32_t &chk) { for(int i=0; i<size; i+=2) { @@ -1389,102 +1345,17 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl for(int track=0; track < 80; track++) { for(int head=0; head < g_heads; head++) { - uint8_t sectdata[(512+12)*12]; - memset(sectdata, 0, sizeof(sectdata)); - int nsect = 12-(track/16); - uint8_t buf[20000]; - int ts; - generate_bitstream_from_track(track, head, 200000000 / cell_count[track/16], buf, ts, image); - int pos = 0; - int wrap = 0; - int hb = 0; - for(;;) { - uint8_t 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_t h[7]; - for(auto & elem : h) - elem = gb(buf, ts, pos, wrap); - uint8_t v2 = gcr6bw_tb[h[2]]; - uint8_t v3 = gcr6bw_tb[h[3]]; - uint8_t tr = gcr6bw_tb[h[0]] | (v2 & 1 ? 0x40 : 0x00); - uint8_t se = gcr6bw_tb[h[1]]; - uint8_t si = v2 & 0x20 ? 1 : 0; - // uint8_t ds = v3 & 0x20 ? 1 : 0; - // uint8_t fmt = v3 & 0x1f; - uint8_t c1 = (tr^se^v2^v3) & 0x3f; - uint8_t 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_t *dest = sectdata+(512+12)*se; - gb(buf, ts, pos, wrap); // Ignore the sector byte - uint8_t ca = 0, cb = 0, cc = 0; - for(int i=0; i<522/3+1; i++) { - uint8_t e0 = gb(buf, ts, pos, wrap); - uint8_t e1 = gb(buf, ts, pos, wrap); - uint8_t e2 = gb(buf, ts, pos, wrap); - uint8_t e3 = i == 522/3 ? 0x96 : gb(buf, ts, pos, wrap); - uint8_t 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<nsect; i++) { - uint8_t *data = sectdata + (512+12)*i; - io_generic_write(io, data, pos_tag, 12); - io_generic_write(io, data+12, pos_data, 512); + auto sectors = extract_sectors_from_track_mac_gcr6(head, track, image); + for(unsigned int i=0; i < sectors.size(); i++) { + auto &sdata = sectors[i]; + sdata.resize(512+12); + io_generic_write(io, &sdata[0], pos_tag, 12); + io_generic_write(io, &sdata[12], pos_data, 512); pos_tag += 12; pos_data += 512; if(track || head || i) - update_chk(data, 12, tchk); - update_chk(data+12, 512, dchk); + update_chk(&sdata[0], 12, tchk); + update_chk(&sdata[12], 512, dchk); } } } @@ -1503,3 +1374,100 @@ bool dc42_format::save(io_generic *io, const std::vector<uint32_t> &variants, fl } const floppy_format_type FLOPPY_DC42_FORMAT = &floppy_image_format_creator<dc42_format>; + + +apple_gcr_format::apple_gcr_format() : floppy_image_format_t() +{ +} + +const char *apple_gcr_format::name() const +{ + return "apple_gcr"; +} + +const char *apple_gcr_format::description() const +{ + return "Apple GCR 400/800K raw sector image"; +} + +const char *apple_gcr_format::extensions() const +{ + return "img"; +} + +bool apple_gcr_format::supports_save() const +{ + return true; +} + +int apple_gcr_format::identify(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants) +{ + uint64_t size = io_generic_size(io); + if(size == 409600 || size == 819200) + return 50; + return 0; +} + +bool apple_gcr_format::load(io_generic *io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) +{ + desc_gcr_sector sectors[12]; + uint8_t sdata[512*12]; + + int pos_data = 0; + + uint64_t size = io_generic_size(io); + int head_count = size == 409600 ? 1 : size == 819200 ? 2 : 0; + + if(!head_count) + return false; + + for(int track=0; track < 80; track++) { + for(int head=0; head < head_count; head++) { + int ns = 12 - (track/16); + io_generic_read(io, sdata, pos_data, 512*ns); + pos_data += 512*ns; + + int si = 0; + for(int i=0; i<ns; i++) { + sectors[si].track = track; + sectors[si].head = head; + sectors[si].sector = si; + sectors[si].info = head_count == 2 ? 0x22 : 0x02; + sectors[si].tag = nullptr; + sectors[si].data = sdata + 512*si; + si = (si + 2) % ns; + if(si == 0) + si++; + } + build_mac_track_gcr(track, head, image, sectors); + } + } + return true; +} + +bool apple_gcr_format::save(io_generic *io, const std::vector<uint32_t> &variants, floppy_image *image) +{ + int g_tracks, g_heads; + image->get_actual_geometry(g_tracks, g_heads); + + if(g_heads == 0) + g_heads = 1; + + int pos_data = 0; + + for(int track=0; track < 80; track++) { + for(int head=0; head < g_heads; head++) { + auto sectors = extract_sectors_from_track_mac_gcr6(head, track, image); + for(unsigned int i=0; i < sectors.size(); i++) { + auto &sdata = sectors[i]; + sdata.resize(512+12); + io_generic_write(io, &sdata[12], pos_data, 512); + pos_data += 512; + } + } + } + + return true; +} + +const floppy_format_type FLOPPY_APPLE_GCR_FORMAT = &floppy_image_format_creator<apple_gcr_format>; |