From bd2db8dcc6c14638c02b8f88e691ae94a3a28f3d Mon Sep 17 00:00:00 2001 From: Olivier Galibert Date: Thu, 21 Jan 2021 15:08:56 +0100 Subject: flopimg: Change the extracted bitstreams into vector flopimg: Change the extracted sectors into vector> flopimg: Add a Mac sector extraction apple 3.5 gcr: Generalize track creation/extraction apple 3.5 gcr: Add a pure sector format --- src/devices/machine/applefdintf.cpp | 1 + src/lib/formats/ami_dsk.cpp | 49 ++-- src/lib/formats/ami_dsk.h | 4 +- src/lib/formats/ap2_dsk.cpp | 121 ++------ src/lib/formats/ap2_dsk.h | 4 +- src/lib/formats/ap_dsk35.cpp | 262 ++++++++--------- src/lib/formats/ap_dsk35.h | 21 +- src/lib/formats/d64_dsk.cpp | 20 +- src/lib/formats/flopimg.cpp | 561 +++++++++++++++++++++++++----------- src/lib/formats/flopimg.h | 50 ++-- src/lib/formats/g64_dsk.cpp | 25 +- src/lib/formats/g64_dsk.h | 2 +- src/lib/formats/hpi_dsk.cpp | 27 +- src/lib/formats/hpi_dsk.h | 4 +- src/lib/formats/hxcmfm_dsk.cpp | 16 +- src/lib/formats/imd_dsk.cpp | 24 +- src/lib/formats/img_dsk.cpp | 32 +- src/lib/formats/img_dsk.h | 4 +- src/lib/formats/jvc_dsk.cpp | 16 +- src/lib/formats/m20_dsk.cpp | 16 +- src/lib/formats/svi_dsk.cpp | 16 +- src/lib/formats/ti99_dsk.cpp | 19 +- src/lib/formats/ti99_dsk.h | 3 +- src/lib/formats/upd765_dsk.cpp | 44 ++- src/lib/formats/vdk_dsk.cpp | 10 +- src/lib/formats/victor9k_dsk.cpp | 21 +- src/lib/formats/wd177x_dsk.cpp | 41 ++- src/tools/floptool.cpp | 1 + 28 files changed, 743 insertions(+), 671 deletions(-) diff --git a/src/devices/machine/applefdintf.cpp b/src/devices/machine/applefdintf.cpp index be77f5d56b2..e21c33230eb 100755 --- a/src/devices/machine/applefdintf.cpp +++ b/src/devices/machine/applefdintf.cpp @@ -21,6 +21,7 @@ FLOPPY_FORMATS_END FLOPPY_FORMATS_MEMBER(applefdintf_device::formats_35) FLOPPY_DC42_FORMAT, + FLOPPY_APPLE_GCR_FORMAT, FLOPPY_PC_FORMAT FLOPPY_FORMATS_END diff --git a/src/lib/formats/ami_dsk.cpp b/src/lib/formats/ami_dsk.cpp index d231de9e20a..5973bc69dab 100644 --- a/src/lib/formats/ami_dsk.cpp +++ b/src/lib/formats/ami_dsk.cpp @@ -97,40 +97,30 @@ bool adf_format::load(io_generic *io, uint32_t form_factor, const std::vector &trackbuf, uint32_t pos) { - if(pos >= 0 && track_size-pos >= 40) { - int pp = pos >> 3; - int dp = pos & 7; - return - (trackbuf[pp] << (24+dp)) | - (trackbuf[pp+1] << (16+dp)) | - (trackbuf[pp+2] << (8+dp)) | - (trackbuf[pp+3] << dp) | - (trackbuf[pp+4] >> (8-dp)); - } else { - uint32_t res = 0; - for(int i=0; i<32; i++) { - int pp = (pos+i) % track_size; - if(trackbuf[pp>>3] & (0x80 >> (pp & 7))) - res |= 0x80000000 >> i; - } - return res; + uint32_t res = 0; + for(int i=0; i != 32; i++) { + if(trackbuf[pos]) + res |= 0x80000000 >> i; + pos ++; + if(pos == trackbuf.size()) + pos = 0; } + return res; } -uint32_t adf_format::checksum(const uint8_t *trackbuf, int track_size, int pos, int long_count) +uint32_t adf_format::checksum(const std::vector &trackbuf, uint32_t pos, int long_count) { uint32_t check = 0; for(int i=0; i &variants, floppy_image *image) { uint8_t sectdata[512*22]; - uint8_t trackbuf[300000/8]; bool hd = image->get_variant() == floppy_image::DSHD; @@ -138,21 +128,20 @@ bool adf_format::save(io_generic *io, const std::vector &variants, flo for(int track=0; track < 80; track++) { for(int side=0; side < 2; side++) { - int track_size; - generate_bitstream_from_track(track, side, hd ? 1000 : 2000, trackbuf, track_size, image); - - for(int i=0; i> 8) & 0xff; if(sect > (hd ? 22 : 11)) continue; uint8_t *dest = sectdata + 512*sect; for(int j=0; j<128; j++) { - uint32_t val = ((g32(trackbuf, track_size, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, track_size, i+4576+32*j) & 0x55555555); + uint32_t val = ((g32(trackbuf, i+480+32*j) & 0x55555555) << 1) | (g32(trackbuf, i+4576+32*j) & 0x55555555); *dest++ = val >> 24; *dest++ = val >> 16; *dest++ = val >> 8; diff --git a/src/lib/formats/ami_dsk.h b/src/lib/formats/ami_dsk.h index cde8d28a810..d25fd45a210 100644 --- a/src/lib/formats/ami_dsk.h +++ b/src/lib/formats/ami_dsk.h @@ -29,8 +29,8 @@ public: virtual bool supports_save() const override; private: - static uint32_t g32(const uint8_t *trackbuf, int track_size, int pos); - static uint32_t checksum(const uint8_t *trackbuf, int track_size, int pos, int long_count); + static uint32_t g32(const std::vector &bitsteam, uint32_t pos); + static uint32_t checksum(const std::vector &bitsteam, uint32_t pos, int long_count); }; extern const floppy_format_type FLOPPY_ADF_FORMAT; diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp index 89776eb52f1..374ecc4a060 100644 --- a/src/lib/formats/ap2_dsk.cpp +++ b/src/lib/formats/ap2_dsk.cpp @@ -574,36 +574,6 @@ int a2_16sect_format::identify(io_generic *io, uint32_t form_factor, const std:: return 0; } -// following is placeholder, is completely wrong. -const floppy_image_format_t::desc_e a2_16sect_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 a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { uint64_t size = io_generic_size(io); @@ -747,14 +717,14 @@ bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, const std::vec return true; } -uint8_t a2_16sect_format::gb(const uint8_t *buf, int ts, int &pos, int &wrap) +uint8_t a2_16sect_format::gb(const std::vector &buf, 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); + v = (v << 1) | buf[pos]; pos++; - if(pos == ts) { + if(pos == buf.size()) { pos = 0; wrap++; } @@ -806,12 +776,10 @@ bool a2_16sect_format::save(io_generic *io, const std::vector &variant uint8_t sectdata[(256)*16]; memset(sectdata, 0, sizeof(sectdata)); int nsect = 16; - uint8_t buf[10000]; // normal is 51090 cells, e.g. 6387 bytes, add 50% and round up for denser than normal disks - int ts; #ifdef VERBOSE_SAVE fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from track %d...", track); #endif - generate_bitstream_from_track(track, head, 3915, buf, ts, image); + auto buf = generate_bitstream_from_track(track, head, 3915, image); #ifdef VERBOSE_SAVE fprintf(stderr,"done.\n"); #endif @@ -820,7 +788,7 @@ bool a2_16sect_format::save(io_generic *io, const std::vector &variant int hb = 0; int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3 for(;;) { - uint8_t v = gb(buf, ts, pos, wrap); + uint8_t v = gb(buf, pos, wrap); if(v == 0xff) { hb = 1; } @@ -840,7 +808,7 @@ bool a2_16sect_format::save(io_generic *io, const std::vector &variant if(hb == 4) { uint8_t h[11]; for(auto & elem : h) - elem = gb(buf, ts, pos, wrap); + elem = gb(buf, pos, wrap); //uint8_t v2 = gcr6bw_tb[h[2]]; uint8_t vl = gcr4_decode(h[0],h[1]); uint8_t tr = gcr4_decode(h[2],h[3]); @@ -863,7 +831,7 @@ bool a2_16sect_format::save(io_generic *io, const std::vector &variant int owrap = wrap; hb = 0; for(int i=0; i<20 && hb != 4; i++) { - v = gb(buf, ts, pos, wrap); + v = gb(buf, pos, wrap); if(v == 0xff) hb = 1; else if(hb == 1 && v == 0xd5) @@ -893,17 +861,17 @@ bool a2_16sect_format::save(io_generic *io, const std::vector &variant // first read in sector and decode to 6bit form for(int i=0; i<0x156; i++) { - data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ^ c; + data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ^ c; c = data[i]; // printf("%02x ", c); // if (((i&0xf)+1)==0x10) printf("\n"); } // read the checksum byte - data[0x156] = gcr6bw_tb[gb(buf,ts,pos,wrap)]; + data[0x156] = gcr6bw_tb[gb(buf,pos,wrap)]; // now read the postamble bytes for(int i=0; i<3; i++) { dpost <<= 8; - dpost |= gb(buf, ts, pos, wrap); + dpost |= gb(buf, pos, wrap); } // next combine in the upper 2 bits of each byte uint8_t bit_swap[4] = { 0, 2, 1, 3 }; @@ -1053,37 +1021,6 @@ int a2_rwts18_format::identify(io_generic *io, uint32_t form_factor, const std:: return size == expected_size; } -// following is placeholder, is completely wrong. -const floppy_image_format_t::desc_e a2_rwts18_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 a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { /* TODO: rewrite me properly @@ -1114,14 +1051,14 @@ bool a2_rwts18_format::load(io_generic *io, uint32_t form_factor, const std::vec return false; // I hope that throws an error... } -uint8_t a2_rwts18_format::gb(const uint8_t *buf, int ts, int &pos, int &wrap) +uint8_t a2_rwts18_format::gb(const std::vector &buf, 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); + v = (v << 1) | buf[pos]; pos++; - if(pos == ts) { + if(pos == buf.size()) { pos = 0; wrap++; } @@ -1172,18 +1109,16 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant uint8_t sectdata[(768)*6]; memset(sectdata, 0, sizeof(sectdata)); int nsect = 18; - uint8_t buf[130000]; // originally 13000, multiread dfi disks need larger - int ts; //fprintf(stderr,"DEBUG: a2_rwts18_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2); //~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected - generate_bitstream_from_track(0, head, 200000000/((3004*nsect*6)/2), buf, ts, image); // 3104 needs tweaking + auto buf = generate_bitstream_from_track(0, head, 200000000/((3004*nsect*6)/2), image); // 3104 needs tweaking //fprintf(stderr,"done.\n"); int pos = 0; int wrap = 0; int hb = 0; int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3 for(;;) { - uint8_t v = gb(buf, ts, pos, wrap); + uint8_t v = gb(buf, pos, wrap); if(v == 0xff) hb = 1; else if(hb == 1 && v == 0xd5) @@ -1200,7 +1135,7 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant if(hb == 4) { uint8_t h[11]; for(auto & elem : h) - elem = gb(buf, ts, pos, wrap); + elem = gb(buf, pos, wrap); //uint8_t v2 = gcr6bw_tb[h[2]]; uint8_t vl = gcr4_decode(h[0],h[1]); uint8_t tr = gcr4_decode(h[2],h[3]); @@ -1221,7 +1156,7 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant int owrap = wrap; hb = 0; for(int i=0; i<20 && hb != 4; i++) { - v = gb(buf, ts, pos, wrap); + v = gb(buf, pos, wrap); if(v == 0xff) hb = 1; else if(hb == 1 && v == 0xd5) @@ -1256,17 +1191,17 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant uint8_t c = 0; // first read in sector and decode to 6bit form for(int i=0; i<0x156; i++) { - data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ^ c; + data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ^ c; c = data[i]; // printf("%02x ", c); // if (((i&0xf)+1)==0x10) printf("\n"); } // read the checksum byte - data[0x156] = gcr6bw_tb[gb(buf,ts,pos,wrap)]; + data[0x156] = gcr6bw_tb[gb(buf,pos,wrap)]; // now read the postamble bytes for(int i=0; i<3; i++) { dpost <<= 8; - dpost |= gb(buf, ts, pos, wrap); + dpost |= gb(buf, pos, wrap); } // next combine in the upper 2 bits of each byte uint8_t bit_swap[4] = { 0, 2, 1, 3 }; @@ -1336,18 +1271,16 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant uint8_t sectdata[(768)*6]; memset(sectdata, 0, sizeof(sectdata)); int nsect = 18; - uint8_t buf[130000]; // originally 13000, multiread dfi disks need larger - int ts; //fprintf(stderr,"DEBUG: a2_rwts18_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2); //~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected - generate_bitstream_from_track(track, head, 200000000/((3004*nsect*6)/2), buf, ts, image); // 3104 needs tweaking + auto buf = generate_bitstream_from_track(track, head, 200000000/((3004*nsect*6)/2), image); // 3104 needs tweaking //fprintf(stderr,"done.\n"); int oldpos = 0; // DEBUG int pos = 0; int wrap = 0; int hb = 0; for(;;) { - uint8_t v = gb(buf, ts, pos, wrap); + uint8_t v = gb(buf, pos, wrap); if((v == 0xff) || (v == 0x9a)) // note 0x9a varies per title! this is an LFSR? generated value intended to throw off copiers, and only appears after the track splice (before sector 5) hb = 1; else if(hb == 1 && v == 0xd5) @@ -1363,7 +1296,7 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant uint8_t h[7]; // grab exactly 7 bytes: should be Track, Sector, Checksum, AA, FF and FF and the Br0derbund Title ID for(auto & elem : h) - elem = gb(buf, ts, pos, wrap); + elem = gb(buf, pos, wrap); uint8_t tr = gcr6bw_tb[h[0]]; uint8_t se = gcr6bw_tb[h[1]]; uint8_t chk = gcr6bw_tb[h[2]]; @@ -1390,7 +1323,7 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant //dest = sectdata+(768)*se; // now read in the sector and decode to 6bit form for(int i=0; i<0x400; i++) { - data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ;//^ c; + data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ;//^ c; c ^= data[i]; /*if (((i&0x3)+1)==0x04) { printf("%c", ((((data[i-3]&0x30)<<2)|((data[i-2]&0x3F)>>0))&0x3F)+0x40); @@ -1404,18 +1337,18 @@ bool a2_rwts18_format::save(io_generic *io, const std::vector &variant // if (((i&0xf)+1)==0x10) printf("\n"); } // read the checksum byte (checksum is calced by xoring all data together) - data[0x400] = gcr6bw_tb[gb(buf,ts,pos,wrap)]; + data[0x400] = gcr6bw_tb[gb(buf,pos,wrap)]; // now read the postamble bytes for(int i=0; i<4; i++) { dpost <<= 8; - dpost |= gb(buf, ts, pos, wrap); + dpost |= gb(buf, pos, wrap); } /*if (se == 0) // dump some debug data to help find the lfsr before sector 5 { printf("Data Postamble was 0x%08x\n", dpost); for(int i=0; i<0x400; i++) { - data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ;//^ c; + data[i] = gcr6bw_tb[gb(buf, pos, wrap)] ;//^ c; c ^= data[i]; printf("%02x ", data[i]); if (((i&0xf)+1)==0x10) printf("\n"); diff --git a/src/lib/formats/ap2_dsk.h b/src/lib/formats/ap2_dsk.h index 1a250e5e110..a12994f3755 100644 --- a/src/lib/formats/ap2_dsk.h +++ b/src/lib/formats/ap2_dsk.h @@ -53,7 +53,7 @@ public: private: static const desc_e mac_gcr[]; - uint8_t gb(const uint8_t *buf, int ts, int &pos, int &wrap); + uint8_t gb(const std::vector &buf, int &pos, int &wrap); void update_chk(const uint8_t *data, int size, uint32_t &chk); bool m_prodos_order; @@ -80,7 +80,7 @@ public: private: static const desc_e mac_gcr[]; - uint8_t gb(const uint8_t *buf, int ts, int &pos, int &wrap); + uint8_t gb(const std::vector &buf, int &pos, int &wrap); void update_chk(const uint8_t *data, int size, uint32_t &chk); }; 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 &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> 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 &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 &variants, fl } const floppy_format_type FLOPPY_DC42_FORMAT = &floppy_image_format_creator; + + +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 &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 &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 &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; diff --git a/src/lib/formats/ap_dsk35.h b/src/lib/formats/ap_dsk35.h index 67043e5bf6c..b2679df7546 100644 --- a/src/lib/formats/ap_dsk35.h +++ b/src/lib/formats/ap_dsk35.h @@ -39,13 +39,26 @@ public: virtual bool supports_save() const override; private: - static const desc_e mac_gcr[]; - static const int cell_count[5]; - - uint8_t gb(const uint8_t *buf, int ts, int &pos, int &wrap); void update_chk(const uint8_t *data, int size, uint32_t &chk); }; extern const floppy_format_type FLOPPY_DC42_FORMAT; +class apple_gcr_format : public floppy_image_format_t +{ +public: + apple_gcr_format(); + + virtual int identify(io_generic *io, uint32_t form_factor, const std::vector &variants) override; + virtual bool load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) override; + virtual bool save(io_generic *io, const std::vector &variants, floppy_image *image) override; + + virtual const char *name() const override; + virtual const char *description() const override; + virtual const char *extensions() const override; + virtual bool supports_save() const override; +}; + +extern const floppy_format_type FLOPPY_APPLE_GCR_FORMAT; + #endif // MAME_FORMATS_AP_DSK35_H diff --git a/src/lib/formats/d64_dsk.cpp b/src/lib/formats/d64_dsk.cpp index 46090580056..70c85b039d6 100644 --- a/src/lib/formats/d64_dsk.cpp +++ b/src/lib/formats/d64_dsk.cpp @@ -289,27 +289,23 @@ bool d64_format::save(io_generic *io, const std::vector &variants, flo void d64_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; int physical_track = this->get_physical_track(f, head, track); int cell_size = this->get_cell_size(f, track); - int track_size; // Extract the sectors - generate_bitstream_from_track(physical_track, head, cell_size, bitstream, track_size, image); - extract_sectors_from_bitstream_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata), head, f.track_count); + auto bitstream = generate_bitstream_from_track(physical_track, head, cell_size, image); + auto sectors = extract_sectors_from_bitstream_gcr5(bitstream, head, f.track_count); for(int i=0; i floppy_image_format_t::generate_bitstream_from_track(int track, int head, int cell_size, floppy_image *image, int subtrack) { + std::vector trackbuf; std::vector &tbuf = image->get_buffer(track, head, subtrack); if(tbuf.size() <= 1) { // Unformatted track - track_size = 200000000/cell_size; - memset(trackbuf, 0, (track_size+7)/8); - return; + int track_size = 200000000/cell_size; + trackbuf.resize(track_size, false); + return trackbuf; } // Start at the write splice @@ -2279,8 +2280,6 @@ void floppy_image_format_t::generate_bitstream_from_track(int track, int head, i while(cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry+1] & floppy_image::TIME_MASK) < cur_pos) cur_entry++; - int cur_bit = 0; - int period = cell_size; int period_adjust_base = period * 0.05; @@ -2301,14 +2300,12 @@ void floppy_image_format_t::generate_bitstream_from_track(int track, int head, i if(edge >= next) { // No transition in the window means 0 and pll in free run mode - trackbuf[cur_bit >> 3] &= ~(0x80 >> (cur_bit & 7)); - cur_bit++; + trackbuf.push_back(false); phase_adjust = 0; } else { // Transition in the window means 1, and the pll is adjusted - trackbuf[cur_bit >> 3] |= 0x80 >> (cur_bit & 7); - cur_bit++; + trackbuf.push_back(true); int delta = edge - (next - period/2); @@ -2359,80 +2356,112 @@ void floppy_image_format_t::generate_bitstream_from_track(int track, int head, i 0 : 1; } } - // Clean the leftover bottom bits just in case - trackbuf[cur_bit >> 3] &= ~(0x7f >> (cur_bit & 7)); - track_size = cur_bit; + return trackbuf; } -int floppy_image_format_t::sbit_r(const uint8_t *bitstream, int pos) +std::vector floppy_image_format_t::generate_nibbles_from_bitstream(const std::vector &bitstream) { - return (bitstream[pos >> 3] & (0x80 >> (pos & 7))) != 0; + std::vector res; + uint32_t pos = 0; + while(pos < bitstream.size()) { + while(pos < bitstream.size() && bitstream[pos] == 0) + pos++; + if(pos == bitstream.size()) { + pos = 0; + while(pos < bitstream.size() && bitstream[pos] == 0) + pos++; + if(pos == bitstream.size()) + return res; + goto found; + } + pos += 8; + } + pos -= bitstream.size(); + while(pos < bitstream.size() && bitstream[pos] == 0) + pos++; + found: + for(;;) { + uint8_t v = 0; + for(uint32_t i=0; i != 8; i++) { + if(bitstream[pos++]) + v |= 0x80 >> i; + if(pos == bitstream.size()) + pos = 0; + } + res.push_back(v); + if(pos < 8) + return res; + while(pos < bitstream.size() && bitstream[pos] == 0) + pos++; + if(pos == bitstream.size()) + return res; + } } -int floppy_image_format_t::sbit_rp(const uint8_t *bitstream, int &pos, int track_size) +int floppy_image_format_t::sbit_rp(const std::vector &bitstream, uint32_t &pos) { - int res = sbit_r(bitstream, pos); + int res = bitstream[pos]; pos ++; - if(pos == track_size) + if(pos == bitstream.size()) pos = 0; return res; } -uint8_t floppy_image_format_t::sbyte_mfm_r(const uint8_t *bitstream, int &pos, int track_size) +uint8_t floppy_image_format_t::sbyte_mfm_r(const std::vector &bitstream, uint32_t &pos) { uint8_t res = 0; for(int i=0; i<8; i++) { - sbit_rp(bitstream, pos, track_size); - if(sbit_rp(bitstream, pos, track_size)) + sbit_rp(bitstream, pos); + if(sbit_rp(bitstream, pos)) res |= 0x80 >> i; } return res; } -uint8_t floppy_image_format_t::sbyte_gcr5_r(const uint8_t *bitstream, int &pos, int track_size) +uint8_t floppy_image_format_t::sbyte_gcr5_r(const std::vector &bitstream, uint32_t &pos) { uint16_t gcr = 0; for(int i=0; i<10; i++) { - if(sbit_rp(bitstream, pos, track_size)) + if(sbit_rp(bitstream, pos)) gcr |= 0x200 >> i; } return (gcr5bw_tb[gcr >> 5] << 4) | gcr5bw_tb[gcr & 0x1f]; } -void floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size) +std::vector> floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const std::vector &bitstream) { - memset(sectors, 0, 256*sizeof(desc_xs)); + std::vector> sectors; // Don't bother if it's just too small - if(track_size < 100) - return; + if(bitstream.size() < 100) + return sectors; // Start by detecting all id and data blocks // If 100 is not enough, that track is too funky to be worth // bothering anyway - int idblk[100], dblk[100]; - int idblk_count = 0, dblk_count = 0; + uint32_t idblk[100], dblk[100]; + uint32_t idblk_count = 0, dblk_count = 0; // Precharge the shift register to detect over-the-index stuff uint16_t shift_reg = 0; - for(int i=0; i<16; i++) - if(sbit_r(bitstream, track_size-16+i)) + for(uint32_t i=0; i<16; i++) + if(bitstream[bitstream.size()-16+i]) shift_reg |= 0x8000 >> i; // Scan the bitstream for sync marks and follow them to check for // blocks - for(int i=0; i> j; // Accept strings of sync marks as long and they're not wrapping @@ -2456,22 +2485,17 @@ void floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const uint8_t } // Then extract the sectors - int sectdata_pos = 0; for(int i=0; i= 8) continue; int ssize = 128 << size; - // If we don't have enough space for a sector's data, skip it - if(ssize + sectdata_pos > sectdata_size) - continue; - // Start of IDAM and DAM are supposed to be exactly 704 cells // apart in normal format or 1008 cells apart in perpendicular // format. Of course the hardware is tolerant. Accept +/- @@ -2488,13 +2512,15 @@ void floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const uint8_t pos = dblk[d_index]; - sectors[sector].track = track; - sectors[sector].head = head; - sectors[sector].size = ssize; - sectors[sector].data = sectdata + sectdata_pos; + if(sectors.size() <= sector) + sectors.resize(sector+1); + auto &sdata = sectors[sector]; + sdata.resize(ssize); for(int j=0; j 20 ? 20 : 0, 0, cell_size, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); - - for(sector_count = 44; sector_count > 0 && !sectors[sector_count].data; sector_count--); + auto buf = generate_bitstream_from_track(track_count > 20 ? 20 : 0, 0, cell_size, image); + auto sectors = extract_sectors_from_bitstream_mfm_pc(buf); + sector_count = sectors.size(); } void floppy_image_format_t::get_track_data_mfm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, uint8_t *sectdata) { - uint8_t bitstream[500000/8]; - uint8_t sectbuf[50000]; - desc_xs sectors[256]; - int track_size; - - generate_bitstream_from_track(track, head, cell_size, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectbuf, sizeof(sectbuf)); + auto bitstream = generate_bitstream_from_track(track, head, cell_size, image); + auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for(int sector=1; sector <= sector_count; sector++) { uint8_t *sd = sectdata + (sector-1)*sector_size; - if(sectors[sector].data && sectors[sector].track == track && sectors[sector].head == head) { - int asize = sectors[sector].size; + if(sector < sectors.size() && !sectors[sector].empty()) { + unsigned int asize = sectors[sector].size(); if(asize > sector_size) asize = sector_size; - memcpy(sd, sectors[sector].data, asize); + memcpy(sd, sectors[sector].data(), asize); if(asize < sector_size) memset(sd+asize, 0, sector_size-asize); } else @@ -2549,26 +2564,26 @@ void floppy_image_format_t::get_track_data_mfm_pc(int track, int head, floppy_im } -void floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size) +std::vector> floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const std::vector &bitstream) { - memset(sectors, 0, 256*sizeof(desc_xs)); + std::vector> sectors; // Don't bother if it's just too small - if(track_size < 100) - return; + if(bitstream.size() < 100) + return sectors; // Start by detecting all id and data blocks // If 100 is not enough, that track is too funky to be worth // bothering anyway - int idblk[100], dblk[100]; - int idblk_count = 0, dblk_count = 0; + uint32_t idblk[100], dblk[100]; + uint32_t idblk_count = 0, dblk_count = 0; // Precharge the shift register to detect over-the-index stuff uint16_t shift_reg = 0; for(int i=0; i<16; i++) - if(sbit_r(bitstream, track_size-16+i)) + if(bitstream[bitstream.size()-16+i]) shift_reg |= 0x8000 >> i; // Scan the bitstream for sync marks and follow them to check for @@ -2576,8 +2591,8 @@ void floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const uint8_t * // We scan for address marks only, as index marks are not mandatory, // and many formats actually do not use them - for(int i=0; i= 8) continue; int ssize = 128 << size; - // If we don't have enough space for a sector's data, skip it - if(ssize + sectdata_pos > sectdata_size) - continue; - // Start of IDAM and DAM are supposed to be exactly 384 cells // apart. Of course the hardware is tolerant. Accept +/- 128 // cells of shift. @@ -2623,13 +2633,15 @@ void floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const uint8_t * pos = dblk[d_index]; - sectors[sector].track = track; - sectors[sector].head = head; - sectors[sector].size = ssize; - sectors[sector].data = sectdata + sectdata_pos; + if(sectors.size() <= sector) + sectors.resize(sector+1); + auto &sdata = sectors[sector]; + sdata.resize(ssize); for(int j=0; j 20 ? 20 : 0, 0, cell_size, bitstream, track_size, image); - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); - - for(sector_count = 44; sector_count > 0 && !sectors[sector_count].data; sector_count--); + auto bitstream = generate_bitstream_from_track(track_count > 20 ? 20 : 0, 0, cell_size, image); + auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream); + sector_count = sectors.size(); } void floppy_image_format_t::get_track_data_fm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, uint8_t *sectdata) { - uint8_t bitstream[500000/8]; - uint8_t sectbuf[50000]; - desc_xs sectors[256]; - int track_size; - - generate_bitstream_from_track(track, head, cell_size, bitstream, track_size, image); - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectbuf, sizeof(sectbuf)); - for(int sector=1; sector <= sector_count; sector++) { + auto bitstream = generate_bitstream_from_track(track, head, cell_size, image); + auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream); + for(unsigned int sector=1; sector < sector_count; sector++) { uint8_t *sd = sectdata + (sector-1)*sector_size; - if(sectors[sector].data && sectors[sector].track == track && sectors[sector].head == head) { - int asize = sectors[sector].size; + if(sector < sectors.size() && !sectors[sector].empty()) { + unsigned int asize = sectors[sector].size(); if(asize > sector_size) asize = sector_size; - memcpy(sd, sectors[sector].data, asize); + memcpy(sd, sectors[sector].data(), asize); if(asize < sector_size) memset(sd+asize, 0, sector_size-asize); } else @@ -2706,7 +2707,7 @@ void floppy_image_format_t::build_pc_track_fm(int track, int head, floppy_image { std::vector track_data; - // gap 4a , IAM and gap 1 + // gap 4a, IAM and gap 1 if(gap_4a != -1) { for(int i=0; i track_data; - // gap 4a , IAM and gap 1 + // gap 4a, IAM and gap 1 if(gap_4a != -1) { for(int i=0; i notag{}; + + uint32_t speed_zone = track/16; + if(speed_zone > 4) + speed_zone = 4; + + uint32_t sectors = 12 - speed_zone; + uint32_t pregap = cells_per_speed_zone[speed_zone] - 6208 * sectors; + + std::vector buffer; + + uint32_t prepregap = pregap % 48; + if(prepregap >= 24) { + raw_w(buffer, prepregap - 24, 0xff3fcf); + raw_w(buffer, 24, 0xf3fcff); + } else + raw_w(buffer, prepregap, 0xf3fcff); + + for(uint32_t i = 0; i != pregap / 48; i++) { + raw_w(buffer, 24, 0xff3fcf); + raw_w(buffer, 24, 0xf3fcff); + } + + for(uint32_t s = 0; s != sectors; s++) { + for(uint32_t i=0; i != 8; i++) { + raw_w(buffer, 24, 0xff3fcf); + raw_w(buffer, 24, 0xf3fcff); + } + + raw_w(buffer, 24, 0xd5aa96); + raw_w(buffer, 8, gcr6fw_tb[sects[s].track & 0x3f]); + raw_w(buffer, 8, gcr6fw_tb[sects[s].sector & 0x3f]); + raw_w(buffer, 8, gcr6fw_tb[(sects[s].track & 0x40 ? 1 : 0) | (sects[s].head ? 0x20 : 0)]); + raw_w(buffer, 8, gcr6fw_tb[sects[s].info & 0x3f]); + uint8_t check = sects[s].track ^ sects[s].sector ^ ((sects[s].track & 0x40 ? 1 : 0) | (sects[s].head ? 0x20 : 0)) ^ sects[s].info; + raw_w(buffer, 8, gcr6fw_tb[check & 0x3f]); + raw_w(buffer, 24, 0xdeaaff); + + raw_w(buffer, 24, 0xff3fcf); + raw_w(buffer, 24, 0xf3fcff); + + raw_w(buffer, 24, 0xd5aaad); + raw_w(buffer, 8, gcr6fw_tb[sects[s].sector & 0x3f]); + + const uint8_t *data = sects[s].tag; + if(!data) + data = notag.data(); + + uint8_t ca = 0, cb = 0, cc = 0; + for(int i=0; i < 175; i ++) { + if(i == 4) + data = sects[s].data - 3*4; + + uint8_t va = data[3*i]; + uint8_t vb = data[3*i+1]; + uint8_t vc = i != 174 ? data[3*i+2] : 0; + + cc = (cc << 1) | (cc >> 7); + uint16_t suma = ca + va + (cc & 1); + ca = suma; + va = va ^ cc; + uint16_t sumb = cb + vb + (suma >> 8); + cb = sumb; + vb = vb ^ ca; + cc = cc + vc + (sumb >> 8); + vc = vc ^ cb; + + uint32_t nb = i != 174 ? 32 : 24; + raw_w(buffer, nb, gcr6_encode(va, vb, vc) >> (32-nb)); + } + raw_w(buffer, 32, gcr6_encode(ca, cb, cc)); + raw_w(buffer, 32, 0xdeaaffff); + } + + generate_track_from_levels(track, head, buffer, 0, image); +} + +std::vector> floppy_image_format_t::extract_sectors_from_track_mac_gcr6(int head, int track, floppy_image *image) +{ + // 200000000 / 60.0 * 1.979e-6 ~= 6.5967 + static const int cell_size_per_speed_zone[5] = { + 394 * 65967 / 10000, + 429 * 65967 / 10000, + 472 * 65967 / 10000, + 525 * 65967 / 10000, + 590 * 65967 / 10000 + }; + + uint32_t speed_zone = track/16; + if(speed_zone > 4) + speed_zone = 4; + + uint32_t sectors = 12 - speed_zone; + + std::vector> sector_data(sectors); + + auto buf = generate_bitstream_from_track(track, head, cell_size_per_speed_zone[speed_zone], image); + auto nib = generate_nibbles_from_bitstream(buf); + + if(nib.size() < 300) + return sector_data; + + std::vector hpos; + + uint32_t hstate = (nib[nib.size() - 2] << 8) | nib[nib.size() - 1]; + for(uint32_t pos = 0; pos != nib.size(); pos++) { + hstate = ((hstate << 8) | nib[pos]) & 0xffffff; + if(hstate == 0xd5aa96) + hpos.push_back(pos == nib.size() - 1 ? 0 : pos+1); + } + + for(uint32_t pos : hpos) { + uint8_t h[7]; + + for(auto &e : h) { + e = nib[pos]; + pos ++; + if(pos == nib.size()) + pos = 0; + } + + 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 || se >= sectors || h[5] != 0xde || h[6] != 0xaa) + continue; + + auto &sdata = sector_data[se]; + uint8_t ca = 0, cb = 0, cc = 0; + + uint32_t hstate = (nib[pos] << 8) | nib[pos + 1]; + pos += 2; + for(;;) { + hstate = ((hstate << 8) | nib[pos]) & 0xffffff; + pos ++; + if(pos == nib.size()) + pos = 0; + if(hstate == 0xd5aa96) + goto no_data_field; + if(hstate == 0xd5aaad) + break; + } + pos ++; // skip the sector byte + if(pos == nib.size()) + pos = 0; + + sdata.resize(512+12); + for(int i=0; i < 175; i++) { + uint8_t e0 = nib[pos++]; + if(pos == nib.size()) + pos = 0; + uint8_t e1 = nib[pos++]; + if(pos == nib.size()) + pos = 0; + uint8_t e2 = nib[pos++]; + if(pos == nib.size()) + pos = 0; + uint8_t e3 = i < 174 ? nib[pos++] : 0x96; + if(pos == nib.size()) + pos = 0; + + uint8_t va, vb, vc; + gcr6_decode(e0, e1, e2, e3, va, vb, vc); + cc = (cc << 1) | (cc >> 7); + va = va ^ cc; + uint16_t suma = ca + va + (cc & 1); + ca = suma; + vb = vb ^ ca; + uint16_t sumb = cb + vb + (suma >> 8); + cb = sumb; + vc = vc ^ cb; + + if(i == 174) + vc = 0; + + cc = cc + vc + (sumb >> 8); + + sdata[3*i] = va; + sdata[3*i+1] = vb; + if(i != 174) + sdata[3*i+2] = vc; + } + for(auto &e : h) { + e = nib[pos]; + pos ++; + if(pos == nib.size()) + pos = 0; + } + uint8_t va, vb, vc; + gcr6_decode(h[0], h[1], h[2], h[3], va, vb, vc); + if(va != ca || vb != cb || vc != cc || h[4] != 0xde || h[5] != 0xaa) + sdata.clear(); + no_data_field: + ; + } + + return sector_data; +} + + +std::vector> floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const std::vector &bitstream, int head, int tracks) +{ + std::vector> sectors; // Don't bother if it's just too small - if(track_size < 100) - return; + if(bitstream.size() < 100) + return sectors; // Start by detecting all id and data blocks - int hblk[100], dblk[100]; - int hblk_count = 0, dblk_count = 0; + uint32_t hblk[100], dblk[100]; + uint32_t hblk_count = 0, dblk_count = 0; // Precharge the shift register to detect over-the-index stuff uint16_t shift_reg = 0; - for(int i=0; i<16; i++) - if(sbit_r(bitstream, track_size-16+i)) + for(uint32_t i=0; i<16; i++) + if(bitstream[bitstream.size()-16+i]) shift_reg |= 0x8000 >> i; // Scan the bitstream for sync marks and follow them to check for blocks bool sync = false; - for(int i=0; i tracks) track -= tracks; - sectors[sector].track = track; - sectors[sector].head = head; - sectors[sector].size = 256; - sectors[sector].data = sectdata + sectdata_pos; + if(sectors.size() <= sector) + sectors.resize(sector+1); + auto &sdata = sectors[sector]; + sdata.resize(256); uint8_t data_crc = 0; - for(int j=0; j> floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const std::vector &bitstream) { - memset(sectors, 0, 256*sizeof(desc_xs)); + std::vector> sectors; // Don't bother if it's just too small - if(track_size < 100) - return; + if(bitstream.size() < 100) + return sectors; // Start by detecting all id and data blocks - int hblk[100], dblk[100]; - int hblk_count = 0, dblk_count = 0; + uint32_t hblk[100], dblk[100]; + uint32_t hblk_count = 0, dblk_count = 0; // Precharge the shift register to detect over-the-index stuff uint16_t shift_reg = 0; - for(int i=0; i<16; i++) - if(sbit_r(bitstream, track_size-16+i)) + for(uint32_t i=0; i<16; i++) + if(bitstream[bitstream.size()-16+i]) shift_reg |= 0x8000 >> i; // Scan the bitstream for sync marks and follow them to check for blocks bool sync = false; - for(int i=0; i generate_bitstream_from_track(int track, int head, int cell_size, floppy_image *image, int subtrack = 0); + std::vector generate_nibbles_from_bitstream(const std::vector &bitstream); struct desc_pc_sector { @@ -524,30 +516,37 @@ protected: bool bad_crc; }; + struct desc_gcr_sector + { + uint8_t track, head, sector, info; + uint8_t *tag; + uint8_t *data; + }; + int calc_default_pc_gap3_size(uint32_t form_factor, int sector_size); void build_wd_track_fm(int track, int head, floppy_image *image, int cell_count, int sector_count, const desc_pc_sector *sects, int gap_3, int gap_1, int gap_2); void build_wd_track_mfm(int track, int head, floppy_image *image, int cell_count, int sector_count, const desc_pc_sector *sects, int gap_3, int gap_1, int gap_2=22); void build_pc_track_fm(int track, int head, floppy_image *image, int cell_count, int sector_count, const desc_pc_sector *sects, int gap_3, int gap_4a=40, int gap_1=26, int gap_2=11); void build_pc_track_mfm(int track, int head, floppy_image *image, int cell_count, int sector_count, const desc_pc_sector *sects, int gap_3, int gap_4a=80, int gap_1=50, int gap_2=22); - + void build_mac_track_gcr(int track, int head, floppy_image *image, const desc_gcr_sector *sects); //! @brief Extract standard sectors from a regenerated bitstream. - //! Sectors must point to an array of 256 desc_xs. - - //! An existing sector is recognizable by having ->data non-null. - //! Sector data is written in sectdata up to sectdata_size bytes. - - //! The ones implemented here are the ones used by multiple - //! systems. + //! Returns a vector of the vector contents, indexed by the sector id. Missing sectors have size zero. //! PC-type sectors with MFM encoding, sector size can go from 128 bytes to 16K. - void extract_sectors_from_bitstream_mfm_pc(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size); + std::vector> extract_sectors_from_bitstream_mfm_pc(const std::vector &bitstream); + //! PC-type sectors with FM encoding - void extract_sectors_from_bitstream_fm_pc(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size); + std::vector> extract_sectors_from_bitstream_fm_pc(const std::vector &bitstream); + //! Commodore type sectors with GCR5 encoding - void extract_sectors_from_bitstream_gcr5(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size, int head, int tracks); + std::vector> extract_sectors_from_bitstream_gcr5(const std::vector &bitstream, int head, int tracks); + //! Victor 9000 type sectors with GCR5 encoding - void extract_sectors_from_bitstream_victor_gcr5(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size); + std::vector> extract_sectors_from_bitstream_victor_gcr5(const std::vector &bitstream); + + //! Mac type sectors with GCR6 encoding + std::vector> extract_sectors_from_track_mac_gcr6(int head, int track, floppy_image *image); //! @brief Get a geometry (including sectors) from an image. @@ -600,8 +599,8 @@ protected: //! GCR6 decode void gcr6_decode(uint8_t e0, uint8_t e1, uint8_t e2, uint8_t e3, uint8_t &va, uint8_t &vb, uint8_t &vc); - uint8_t sbyte_mfm_r(const uint8_t *bitstream, int &pos, int track_size); - uint8_t sbyte_gcr5_r(const uint8_t *bitstream, int &pos, int track_size); + uint8_t sbyte_mfm_r(const std::vector &bitstream, uint32_t &pos); + uint8_t sbyte_gcr5_r(const std::vector &bitstream, uint32_t &pos); //! Max number of excess tracks to be discarded from disk image to fit floppy drive enum { DUMP_THRESHOLD = 2 }; @@ -635,8 +634,7 @@ private: void fixup_crcs(std::vector &buffer, gen_crc_info *crcs); void collect_crcs(const desc_e *desc, gen_crc_info *crcs) const; - int sbit_r(const uint8_t *bitstream, int pos); - int sbit_rp(const uint8_t *bitstream, int &pos, int track_size); + int sbit_rp(const std::vector &bitstream, uint32_t &pos); int calc_sector_index(int num, int interleave, int skew, int total_sectors, int track_head); }; diff --git a/src/lib/formats/g64_dsk.cpp b/src/lib/formats/g64_dsk.cpp index ed97486f08d..02098db88e0 100644 --- a/src/lib/formats/g64_dsk.cpp +++ b/src/lib/formats/g64_dsk.cpp @@ -97,13 +97,13 @@ bool g64_format::load(io_generic *io, uint32_t form_factor, const std::vector &trackbuf, floppy_image *image) { int cell_size = c1541_cell_size[speed_zone]; - generate_bitstream_from_track(track, head, cell_size, trackbuf, track_size, image); + trackbuf = generate_bitstream_from_track(track, head, cell_size, image); - int actual_cell_size = 200000000L/track_size; + int actual_cell_size = 200000000L/trackbuf.size(); // allow a tolerance of +- 10 us (3990..4010 -> 4000) return ((actual_cell_size >= cell_size-10) && (actual_cell_size <= cell_size+10)) ? speed_zone : -1; @@ -123,7 +123,7 @@ bool g64_format::save(io_generic *io, const std::vector &variants, flo for (int head = 0; head < heads; head++) { int tracks_written = 0; - std::vector trackbuf(TRACK_LENGTH-2); + std::vector trackbuf; for (int track = 0; track < TRACK_COUNT; track++) { uint32_t tpos = POS_TRACK_OFFSET + (track * 4); @@ -140,29 +140,34 @@ bool g64_format::save(io_generic *io, const std::vector &variants, flo int speed_zone; // figure out the cell size and speed zone from the track data - if ((speed_zone = generate_bitstream(track, head, 3, &trackbuf[0], track_size, image)) == -1) - if ((speed_zone = generate_bitstream(track, head, 2, &trackbuf[0], track_size, image)) == -1) - if ((speed_zone = generate_bitstream(track, head, 1, &trackbuf[0], track_size, image)) == -1) - if ((speed_zone = generate_bitstream(track, head, 0, &trackbuf[0], track_size, image)) == -1) { + if ((speed_zone = generate_bitstream(track, head, 3, trackbuf, image)) == -1) + if ((speed_zone = generate_bitstream(track, head, 2, trackbuf, image)) == -1) + if ((speed_zone = generate_bitstream(track, head, 1, trackbuf, image)) == -1) + if ((speed_zone = generate_bitstream(track, head, 0, trackbuf, image)) == -1) { osd_printf_error("g64_format: Cannot determine speed zone for track %u\n", track); return false; } LOG_FORMATS("head %u track %u size %u cell %u\n", head, track, track_size, c1541_cell_size[speed_zone]); + std::vector packed((trackbuf.size() + 7) >> 3, 0); + for(uint32_t i = 0; i != trackbuf.size(); i++) + if(trackbuf[i]) + packed[i >> 3] |= 0x80 >> (i & 7); + uint8_t track_offset[4]; uint8_t speed_offset[4]; uint8_t track_length[2]; place_integer_le(track_offset, 0, 4, dpos); place_integer_le(speed_offset, 0, 4, speed_zone); - place_integer_le(track_length, 0, 2, track_size/8); + place_integer_le(track_length, 0, 2, packed.size()); io_generic_write(io, track_offset, tpos, 4); io_generic_write(io, speed_offset, spos, 4); io_generic_write_filler(io, 0xff, dpos, TRACK_LENGTH); io_generic_write(io, track_length, dpos, 2); - io_generic_write(io, &trackbuf[0], dpos + 2, track_size); + io_generic_write(io, packed.data(), dpos + 2, packed.size()); tracks_written++; } diff --git a/src/lib/formats/g64_dsk.h b/src/lib/formats/g64_dsk.h index 533a80ee266..6691146c70e 100644 --- a/src/lib/formats/g64_dsk.h +++ b/src/lib/formats/g64_dsk.h @@ -47,7 +47,7 @@ protected: static const uint32_t c1541_cell_size[]; - int generate_bitstream(int track, int head, int speed_zone, uint8_t *trackbuf, int &track_size, floppy_image *image); + int generate_bitstream(int track, int head, int speed_zone, std::vector &trackbuf, floppy_image *image); }; extern const floppy_format_type FLOPPY_G64_FORMAT; diff --git a/src/lib/formats/hpi_dsk.cpp b/src/lib/formats/hpi_dsk.cpp index 996ab60c941..d9fc788fd45 100644 --- a/src/lib/formats/hpi_dsk.cpp +++ b/src/lib/formats/hpi_dsk.cpp @@ -199,13 +199,11 @@ bool hpi_format::save(io_generic *io, const std::vector &variants, flo for (int cyl = 0; cyl < tracks; cyl++) { for (int head = 0; head < heads; head++) { - uint8_t bitstream[ 21000 ]; - int bitstream_size; - generate_bitstream_from_track(cyl , head , CELL_SIZE , bitstream , bitstream_size , image , 0); + auto bitstream = generate_bitstream_from_track(cyl , head , CELL_SIZE , image , 0); int pos = 0; unsigned track_no , head_no , sector_no; uint8_t sector_data[ HPI_SECTOR_SIZE ]; - while (get_next_sector(bitstream , bitstream_size , pos , track_no , head_no , sector_no , sector_data)) { + while (get_next_sector(bitstream , pos , track_no , head_no , sector_no , sector_data)) { if (track_no == cyl && head_no == head && sector_no < HPI_SECTORS) { unsigned offset_in_image = chs_to_lba(cyl, head, sector_no, heads) * HPI_SECTOR_SIZE; io_generic_write(io, sector_data, offset_in_image, HPI_SECTOR_SIZE); @@ -367,17 +365,16 @@ unsigned hpi_format::chs_to_lba(unsigned cylinder , unsigned head , unsigned sec return sector + (head + cylinder * heads) * HPI_SECTORS; } -std::vector hpi_format::get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos) +std::vector hpi_format::get_next_id_n_block(const std::vector &bitstream , int& pos , int& start_pos) { std::vector res; uint32_t sr = 0; // Look for either sync + ID AM or sync + DATA AM - while (pos < bitstream_size && sr != ID_CD_PATTERN && sr != DATA_CD_PATTERN) { - bool bit = util::BIT(bitstream[ pos >> 3 ] , 7 - (pos & 7)); + while (pos < bitstream.size() && sr != ID_CD_PATTERN && sr != DATA_CD_PATTERN) { + sr = (sr << 1) | bitstream[pos]; pos++; - sr = (sr << 1) | bit; } - if (pos == bitstream_size) { + if (pos == bitstream.size()) { // End of track reached return res; } @@ -394,11 +391,11 @@ std::vector hpi_format::get_next_id_n_block(const uint8_t *bitstream , } // Align to data cells pos++; - for (unsigned i = 0; i < to_dump && pos < bitstream_size; i++) { + for (unsigned i = 0; i < to_dump && pos < bitstream.size(); i++) { uint8_t byte = 0; unsigned j; - for (j = 0; j < 8 && pos < bitstream_size; j++) { - bool bit = util::BIT(bitstream[ pos >> 3 ] , 7 - (pos & 7)); + for (j = 0; j < 8 && pos < bitstream.size(); j++) { + bool bit = bitstream[pos]; pos += 2; byte >>= 1; if (bit) { @@ -412,7 +409,7 @@ std::vector hpi_format::get_next_id_n_block(const uint8_t *bitstream , return res; } -bool hpi_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , int& pos , unsigned& track , unsigned& head , unsigned& sector , uint8_t *sector_data) +bool hpi_format::get_next_sector(const std::vector &bitstream , int& pos , unsigned& track , unsigned& head , unsigned& sector , uint8_t *sector_data) { std::vector block; while (true) { @@ -420,7 +417,7 @@ bool hpi_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , int id_pos = 0; while (true) { if (block.size() == 0) { - block = get_next_id_n_block(bitstream , bitstream_size , pos , id_pos); + block = get_next_id_n_block(bitstream , pos , id_pos); if (block.size() == 0) { return false; } @@ -436,7 +433,7 @@ bool hpi_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , } // Then for DATA block int data_pos = 0; - block = get_next_id_n_block(bitstream , bitstream_size , pos , data_pos); + block = get_next_id_n_block(bitstream , pos , data_pos); if (block.size() == 0) { return false; } diff --git a/src/lib/formats/hpi_dsk.h b/src/lib/formats/hpi_dsk.h index 0ce5d1e0422..38c70e91c33 100644 --- a/src/lib/formats/hpi_dsk.h +++ b/src/lib/formats/hpi_dsk.h @@ -47,8 +47,8 @@ private: void write_sector(std::vector &buffer , uint8_t track_no , uint8_t sect_head_no , const uint8_t *sect_data); void fill_with_gap3(std::vector &buffer); static unsigned chs_to_lba(unsigned cylinder , unsigned head , unsigned sector , unsigned heads); - std::vector get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos); - bool get_next_sector(const uint8_t *bitstream , int bitstream_size , int& pos , unsigned& track , unsigned& head , unsigned& sector , uint8_t *sector_data); + std::vector get_next_id_n_block(const std::vector &bitstream , int& pos , int& start_pos); + bool get_next_sector(const std::vector &bitstream , int& pos , unsigned& track , unsigned& head , unsigned& sector , uint8_t *sector_data); static const uint8_t m_track_skew[ HPI_SECTORS - 1 ][ HPI_HEADS ]; }; diff --git a/src/lib/formats/hxcmfm_dsk.cpp b/src/lib/formats/hxcmfm_dsk.cpp index d7cace590e7..b6845b28e4a 100644 --- a/src/lib/formats/hxcmfm_dsk.cpp +++ b/src/lib/formats/hxcmfm_dsk.cpp @@ -129,25 +129,25 @@ bool mfm_format::save(io_generic *io, const std::vector &variants, flo int tpos = sizeof(MFMIMG); int dpos = tpos + track_count*head_count*sizeof(MFMTRACKIMG); - uint8_t trackbuf[150000/8]; - for(int track=0; track < track_count; track++) { for(int side=0; side < head_count; side++) { - int track_size; - generate_bitstream_from_track(track, side, 2000, trackbuf, track_size, image); - track_size = (track_size+7)/8; + auto trackbuf = generate_bitstream_from_track(track, side, 2000, image); + std::vector packed((trackbuf.size() + 7) >> 3, 0); + for(uint32_t i = 0; i != trackbuf.size(); i++) + if(trackbuf[i]) + packed[i >> 3] |= 0x80 >> (i & 7); MFMTRACKIMG trackdesc; trackdesc.track_number = track; trackdesc.side_number = side; - trackdesc.mfmtracksize = track_size; + trackdesc.mfmtracksize = packed.size(); trackdesc.mfmtrackoffset = dpos; io_generic_write(io, &trackdesc, tpos, sizeof(MFMTRACKIMG)); - io_generic_write(io, trackbuf, dpos, track_size); + io_generic_write(io, packed.data(), dpos, packed.size()); tpos += sizeof(MFMTRACKIMG); - dpos += track_size; + dpos += packed.size(); } } diff --git a/src/lib/formats/imd_dsk.cpp b/src/lib/formats/imd_dsk.cpp index 2e987b73c16..2e26c5f4079 100644 --- a/src/lib/formats/imd_dsk.cpp +++ b/src/lib/formats/imd_dsk.cpp @@ -655,34 +655,32 @@ bool imd_format::save(io_generic *io, const std::vector &variants, flo bool fm = m_mode[i]< 3; - uint8_t bitstream[500000 / 8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; - int track_size; - generate_bitstream_from_track(m_track[i]*m_trackmult, head, 2000, bitstream, track_size, image); + auto bitstream = generate_bitstream_from_track(m_track[i]*m_trackmult, head, 2000, image); + std::vector> sectors; + if (fm) - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + sectors = extract_sectors_from_bitstream_fm_pc(bitstream); else - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); uint8_t sdata[8192]; for (int j = 0; j < m_sector_count[i]; j++) { - desc_xs& xs = sectors[m_snum[i][j]]; + const auto &data = sectors[m_snum[i][j]]; uint8_t mode; - if (!xs.data) + if (data.empty()) { mode = 0; io_generic_write(io, &mode, pos++, 1); continue; } - else if (xs.size < actual_size) { - memcpy((void*)sdata, xs.data, xs.size); - memset((uint8_t*)sdata + xs.size, 0, xs.size - actual_size); + else if (data.size() < actual_size) { + memcpy((void*)sdata, data.data(), data.size()); + memset((uint8_t*)sdata + data.size(), 0, data.size() - actual_size); } else - memcpy((void*)sdata, xs.data, actual_size); + memcpy((void*)sdata, data.data(), actual_size); if (can_compress(sdata, sdata[0], actual_size)) { diff --git a/src/lib/formats/img_dsk.cpp b/src/lib/formats/img_dsk.cpp index fd31ca37e87..4de5e199751 100644 --- a/src/lib/formats/img_dsk.cpp +++ b/src/lib/formats/img_dsk.cpp @@ -99,13 +99,11 @@ bool img_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { for (int cyl = 0; cyl < TRACKS; cyl++) { - uint8_t bitstream[ 21000 ]; - int bitstream_size; - generate_bitstream_from_track(cyl , 0 , CELL_SIZE , bitstream , bitstream_size , image , 0); + auto bitstream = generate_bitstream_from_track(cyl , 0 , CELL_SIZE , image , 0); int pos = 0; unsigned track_no , sector_no; uint8_t sector_data[ SECTOR_SIZE ]; - while (get_next_sector(bitstream , bitstream_size , pos , track_no , sector_no , sector_data)) { + while (get_next_sector(bitstream , pos , track_no , sector_no , sector_data)) { if (track_no == cyl && sector_no >= 1 && sector_no <= SECTORS) { unsigned offset_in_image = (cyl * SECTORS + sector_no - 1) * SECTOR_SIZE; io_generic_write(io, sector_data, offset_in_image, SECTOR_SIZE); @@ -260,7 +258,7 @@ void img_format::fill_with_gap4(std::vector &buffer) } } -std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos) +std::vector img_format::get_next_id_n_block(const std::vector &bitstream , int& pos , int& start_pos) { std::vector res; uint8_t data_sr; @@ -269,8 +267,8 @@ std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , // Look for either sync + ID AM or sync + DATA AM do { unsigned cnt_trans = 0; - while (pos < bitstream_size && cnt_trans < 34) { - bool bit = util::BIT(bitstream[ pos >> 3 ] , ~pos & 7); + while (pos < bitstream.size() && cnt_trans < 34) { + bool bit = bitstream[pos]; pos++; if (cnt_trans < 32) { if (!(util::BIT(cnt_trans , 0) ^ bit)) { @@ -292,7 +290,7 @@ std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , } } - if (pos == bitstream_size) { + if (pos == bitstream.size()) { // End of track reached return res; } @@ -300,14 +298,14 @@ std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , // Get AM data_sr = clock_sr = 0; for (unsigned i = 0; i < 7; ++i) { - bool bit = util::BIT(bitstream[ pos >> 3 ] , ~pos & 7); + bool bit = bitstream[pos]; pos++; clock_sr = (clock_sr << 1) | bit; - bit = util::BIT(bitstream[ pos >> 3 ] , ~pos & 7); + bit = bitstream[pos]; pos++; data_sr = (data_sr << 1) | bit; } - if (pos >= bitstream_size) { + if (pos >= bitstream.size()) { return res; } } while (clock_sr != AM_CLOCK); @@ -325,11 +323,11 @@ std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , } pos++; - for (unsigned i = 0; i < to_dump && pos < bitstream_size; i++) { + for (unsigned i = 0; i < to_dump && pos < bitstream.size(); i++) { data_sr = 0; unsigned j; - for (j = 0; j < 8 && pos < bitstream_size; j++) { - bool bit = util::BIT(bitstream[ pos >> 3 ] , ~pos & 7); + for (j = 0; j < 8 && pos < bitstream.size(); j++) { + bool bit = bitstream[pos]; pos += 2; data_sr = (data_sr << 1) | bit; } @@ -340,7 +338,7 @@ std::vector img_format::get_next_id_n_block(const uint8_t *bitstream , return res; } -bool img_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , int& pos , unsigned& track , unsigned& sector , uint8_t *sector_data) +bool img_format::get_next_sector(const std::vector &bitstream , int& pos , unsigned& track , unsigned& sector , uint8_t *sector_data) { std::vector block; while (true) { @@ -348,7 +346,7 @@ bool img_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , int id_pos = 0; while (true) { if (block.size() == 0) { - block = get_next_id_n_block(bitstream , bitstream_size , pos , id_pos); + block = get_next_id_n_block(bitstream , pos , id_pos); if (block.size() == 0) { return false; } @@ -363,7 +361,7 @@ bool img_format::get_next_sector(const uint8_t *bitstream , int bitstream_size , } // Then for DATA block int data_pos = 0; - block = get_next_id_n_block(bitstream , bitstream_size , pos , data_pos); + block = get_next_id_n_block(bitstream , pos , data_pos); if (block.size() == 0) { return false; } diff --git a/src/lib/formats/img_dsk.h b/src/lib/formats/img_dsk.h index f35e9eb00c0..af9a2d62466 100644 --- a/src/lib/formats/img_dsk.h +++ b/src/lib/formats/img_dsk.h @@ -46,8 +46,8 @@ private: void write_gap(std::vector &buffer , unsigned size_00 , unsigned size_ff); void write_sector(std::vector &buffer , uint8_t track_no , uint8_t sect_no , const uint8_t *sect_data); void fill_with_gap4(std::vector &buffer); - std::vector get_next_id_n_block(const uint8_t *bitstream , int bitstream_size , int& pos , int& start_pos); - bool get_next_sector(const uint8_t *bitstream , int bitstream_size , int& pos , unsigned& track , unsigned& sector , uint8_t *sector_data); + std::vector get_next_id_n_block(const std::vector &bitstream , int& pos , int& start_pos); + bool get_next_sector(const std::vector &bitstream , int& pos , unsigned& track , unsigned& sector , uint8_t *sector_data); }; extern const floppy_format_type FLOPPY_IMG_FORMAT; diff --git a/src/lib/formats/jvc_dsk.cpp b/src/lib/formats/jvc_dsk.cpp index 42bb26899d1..8332f86bace 100644 --- a/src/lib/formats/jvc_dsk.cpp +++ b/src/lib/formats/jvc_dsk.cpp @@ -225,9 +225,6 @@ bool jvc_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { - uint8_t bitstream[500000/8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; uint64_t file_offset = 0; int track_count, head_count; @@ -248,20 +245,19 @@ bool jvc_format::save(io_generic *io, const std::vector &variants, flo { for (int head = 0; head < head_count; head++) { - int track_size; - generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + auto bitstream = generate_bitstream_from_track(track, head, 2000, image); + auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < 18; i++) { - if (sectors[1 + i].size != 256) + if (sectors[1 + i].size() != 256) { - osd_printf_error("jvc_format: invalid sector size: %d\n", sectors[1 + i].size); + osd_printf_error("jvc_format: invalid sector size: %d\n", sectors[1 + i].size()); return false; } - io_generic_write(io, sectors[1 + i].data, file_offset, sectors[1 + i].size); - file_offset += sectors[1 + i].size; + io_generic_write(io, sectors[1 + i].data(), file_offset, 256); + file_offset += 256; } } } diff --git a/src/lib/formats/m20_dsk.cpp b/src/lib/formats/m20_dsk.cpp index 871e721b1bb..60b2ae58176 100644 --- a/src/lib/formats/m20_dsk.cpp +++ b/src/lib/formats/m20_dsk.cpp @@ -78,22 +78,18 @@ bool m20_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { - uint8_t bitstream[500000/8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; - int track_size; uint64_t file_offset = 0; int track_count, head_count; track_count = 35; head_count = 2; //FIXME: use image->get_actual_geometry(track_count, head_count) instead // initial fm track - generate_bitstream_from_track(0, 0, 4000, bitstream, track_size, image); - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + auto bitstream = generate_bitstream_from_track(0, 0, 4000, image); + auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream); for (int i = 0; i < 16; i++) { - io_generic_write(io, sectors[i + 1].data, file_offset, 128); + io_generic_write(io, sectors[i + 1].data(), file_offset, 128); file_offset += 256; //128; } @@ -105,12 +101,12 @@ bool m20_format::save(io_generic *io, const std::vector &variants, flo // skip track 0, head 0 if (track == 0) { if (head_count == 1) break; else head++; } - generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + bitstream = generate_bitstream_from_track(track, head, 2000, image); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < 16; i++) { - io_generic_write(io, sectors[i + 1].data, file_offset, 256); + io_generic_write(io, sectors[i + 1].data(), file_offset, 256); file_offset += 256; } } diff --git a/src/lib/formats/svi_dsk.cpp b/src/lib/formats/svi_dsk.cpp index c67ef0cd95d..e3cfa294fcb 100644 --- a/src/lib/formats/svi_dsk.cpp +++ b/src/lib/formats/svi_dsk.cpp @@ -93,22 +93,18 @@ bool svi_format::load(io_generic *io, uint32_t form_factor, const std::vector &variants, floppy_image *image) { - uint8_t bitstream[500000/8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; - int track_size; uint64_t file_offset = 0; int track_count, head_count; image->get_actual_geometry(track_count, head_count); // initial fm track - generate_bitstream_from_track(0, 0, 4000, bitstream, track_size, image); - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + auto bitstream = generate_bitstream_from_track(0, 0, 4000, image); + auto sectors = extract_sectors_from_bitstream_fm_pc(bitstream); for (int i = 0; i < 18; i++) { - io_generic_write(io, sectors[i + 1].data, file_offset, 128); + io_generic_write(io, sectors[i + 1].data(), file_offset, 128); file_offset += 128; } @@ -120,12 +116,12 @@ bool svi_format::save(io_generic *io, const std::vector &variants, flo // skip track 0, head 0 if (track == 0) { if (head_count == 1) break; else head++; } - generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + bitstream = generate_bitstream_from_track(track, head, 2000, image); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < 17; i++) { - io_generic_write(io, sectors[i + 1].data, file_offset, 256); + io_generic_write(io, sectors[i + 1].data(), file_offset, 256); file_offset += 256; } } diff --git a/src/lib/formats/ti99_dsk.cpp b/src/lib/formats/ti99_dsk.cpp index 00925a0feb7..723bd218b81 100644 --- a/src/lib/formats/ti99_dsk.cpp +++ b/src/lib/formats/ti99_dsk.cpp @@ -213,9 +213,6 @@ bool ti99_floppy_format::load(io_generic *io, uint32_t form_factor, const std::v */ bool ti99_floppy_format::save(io_generic *io, const std::vector &variants, floppy_image *image) { - int act_track_size = 0; - - uint8_t bitstream[500000/8]; uint8_t sectordata[9216]; // max size (36*256) int cellsizes[] = { 2000, 4000, 1000, 2000 }; @@ -246,13 +243,10 @@ bool ti99_floppy_format::save(io_generic *io, const std::vector &varia for (int track = 0; track < track_count; track++) { // Retrieve the cells from the flux sequence. This also delivers the actual track size. - generate_bitstream_from_track(track, head, cell_size, bitstream, act_track_size, image); - - // Maybe the track has become longer due to moving splices - if (act_track_size > 200000000/cell_size) act_track_size = 200000000/cell_size; + auto bitstream = generate_bitstream_from_track(track, head, cell_size, image); LOGMASKED(LOG_DETAIL, "[ti99_dsk] Getting sectors from track %d, head %d\n", track, head); - seccount = get_sectors(bitstream, act_track_size, encoding, track, head, expected_sectors, sectordata, sector); + seccount = get_sectors(bitstream, encoding, track, head, expected_sectors, sectordata, sector); LOGMASKED(LOG_DETAIL, "[ti99_dsk] Seccount = %d\n", seccount); // We may have more sectors in MFM (18). This is OK in track 0; otherwise we need to restart the process. @@ -564,14 +558,13 @@ enum The sectors are assumed to have a length of 256 byte, and their sequence is stored in the secnumber array. */ -int ti99_floppy_format::get_sectors(const uint8_t *bitstream, int cell_count, int encoding, int track, int head, int sectors, uint8_t *sectordata, int *secnumber) +int ti99_floppy_format::get_sectors(const std::vector &bitstream, int encoding, int track, int head, int sectors, uint8_t *sectordata, int *secnumber) { int bitpos = 0; int lastpos = 0; int spos = 0; int seccount = 0; uint16_t shift_reg = 0; - int bytepos = 0; uint8_t databyte = 0; uint8_t curbyte = 0; int rep = 0; @@ -584,12 +577,10 @@ int ti99_floppy_format::get_sectors(const uint8_t *bitstream, int cell_count, in int first = (encoding==floppy_image::MFM)? A1IDAM1 : FMIDAM; int state = first; - while (bitpos < cell_count) + while (bitpos < bitstream.size()) { LOGMASKED(LOG_SHIFT, "[ti99_dsk] shift = %04x\n", shift_reg); - shift_reg = (shift_reg << 1) & 0xffff; - if ((bitpos & 0x07)==0) curbyte = bitstream[bytepos++]; - if ((curbyte & 0x80) != 0) shift_reg |= 1; + shift_reg = (shift_reg << 1) | bitstream[bitpos]; if (((bitpos - lastpos) & 1)==0) { diff --git a/src/lib/formats/ti99_dsk.h b/src/lib/formats/ti99_dsk.h index d15a71c62ac..5b59b164344 100644 --- a/src/lib/formats/ti99_dsk.h +++ b/src/lib/formats/ti99_dsk.h @@ -27,9 +27,8 @@ public: bool save(io_generic *io, const std::vector &variants, floppy_image *image) override; protected: - int decode_bitstream(const uint8_t *bitstream, uint8_t *trackdata, int *sector, int cell_count, int encoding, uint8_t gapbytes, int track_size); uint8_t get_data_from_encoding(uint16_t raw); - int get_sectors(const uint8_t *bitstream, int cell_count, int encoding, int track, int head, int sectors, uint8_t *sectordata, int *secnumber); + int get_sectors(const std::vector &bitstream, int encoding, int track, int head, int sectors, uint8_t *sectordata, int *secnumber); virtual int min_heads() =0; diff --git a/src/lib/formats/upd765_dsk.cpp b/src/lib/formats/upd765_dsk.cpp index 8676c4b9f63..ce17bd1c4f2 100644 --- a/src/lib/formats/upd765_dsk.cpp +++ b/src/lib/formats/upd765_dsk.cpp @@ -352,21 +352,17 @@ bool upd765_format::save(io_generic *io, const std::vector &variants, void upd765_format::check_compatibility(floppy_image *image, std::vector &candidates) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; - // Extract the sectors - generate_bitstream_from_track(0, 0, formats[candidates[0]].cell_size, bitstream, track_size, image); + auto bitstream = generate_bitstream_from_track(0, 0, formats[candidates[0]].cell_size, image); + std::vector> sectors; switch (formats[candidates[0]].encoding) { case floppy_image::FM: - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_fm_pc(bitstream); break; case floppy_image::MFM: - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); break; } @@ -375,8 +371,8 @@ void upd765_format::check_compatibility(floppy_image *image, std::vector &c for(unsigned int i=0; i != candidates.size(); i++) { const format &f = formats[candidates[i]]; int ns = 0; - for(int j=0; j<256; j++) - if(sectors[j].data) { + for(unsigned int j=0; j != sectors.size(); j++) + if(!sectors[j].empty()) { int sid; if(f.sector_base_id == -1) { for(sid=0; sid < f.sector_count; sid++) @@ -387,10 +383,10 @@ void upd765_format::check_compatibility(floppy_image *image, std::vector &c if(sid < 0 || sid > f.sector_count) goto fail; if(f.sector_base_size) { - if(sectors[j].size != f.sector_base_size) + if(sectors[j].size() != f.sector_base_size) goto fail; } else { - if(sectors[j].size != f.per_sector_size[sid]) + if(sectors[j].size() != f.per_sector_size[sid]) goto fail; } ns++; @@ -406,33 +402,29 @@ void upd765_format::check_compatibility(floppy_image *image, std::vector &c void upd765_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; - // Extract the sectors - generate_bitstream_from_track(track, head, f.cell_size, bitstream, track_size, image); + auto bitstream = generate_bitstream_from_track(track, head, f.cell_size, image); + std::vector> sectors; switch (f.encoding) { case floppy_image::FM: - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_fm_pc(bitstream); break; case floppy_image::MFM: - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); break; } for(int i=0; i &variants, floppy_image *image) { - uint8_t bitstream[500000/8]; - uint8_t sector_data[50000]; - desc_xs sectors[256]; uint64_t file_offset = 0; int track_count, head_count; @@ -119,13 +116,12 @@ bool vdk_format::save(io_generic *io, const std::vector &variants, flo { for (int head = 0; head < head_count; head++) { - int track_size; - generate_bitstream_from_track(track, head, 2000, bitstream, track_size, image); - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sector_data, sizeof(sector_data)); + auto bitstream = generate_bitstream_from_track(track, head, 2000, image); + auto sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); for (int i = 0; i < SECTOR_COUNT; i++) { - io_generic_write(io, sectors[FIRST_SECTOR_ID + i].data, file_offset, SECTOR_SIZE); + io_generic_write(io, sectors[FIRST_SECTOR_ID + i].data(), file_offset, SECTOR_SIZE); file_offset += SECTOR_SIZE; } } diff --git a/src/lib/formats/victor9k_dsk.cpp b/src/lib/formats/victor9k_dsk.cpp index b9ae3d89a72..ace1ec50933 100644 --- a/src/lib/formats/victor9k_dsk.cpp +++ b/src/lib/formats/victor9k_dsk.cpp @@ -415,25 +415,20 @@ bool victor9k_format::save(io_generic *io, const std::vector &variants void victor9k_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head, int sector_count) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; - // Extract the sectors - generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], bitstream, track_size, image); - extract_sectors_from_bitstream_victor_gcr5(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + auto bitstream = generate_bitstream_from_track(track, head, cell_size[speed_zone[head][track]], image); + auto sectors = extract_sectors_from_bitstream_victor_gcr5(bitstream); for(int i=0; i &c const format &f = formats[candidates[i]]; for(int track=0; track < f.track_count; track++) { for(int head=0; head < f.head_count; head++) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; const format &tf = get_track_format(f, head, track); - generate_bitstream_from_track(track, head, tf.cell_size, bitstream, track_size, image); + auto bitstream = generate_bitstream_from_track(track, head, tf.cell_size, image); + std::vector> sectors; switch (tf.encoding) { case floppy_image::FM: - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_fm_pc(bitstream); break; case floppy_image::MFM: - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); break; } int ns = 0; for(int j=0; j<256; j++) - if(sectors[j].data) { + if(!sectors[j].empty()) { int sid; if(tf.sector_base_id == -1) { for(sid=0; sid < tf.sector_count; sid++) @@ -452,10 +449,10 @@ void wd177x_format::check_compatibility(floppy_image *image, std::vector &c if(sid < 0 || sid > tf.sector_count) goto fail; if(tf.sector_base_size) { - if(sectors[j].size != tf.sector_base_size) + if(sectors[j].size() != tf.sector_base_size) goto fail; } else { - if(sectors[j].size != tf.per_sector_size[sid]) + if(sectors[j].size() != tf.per_sector_size[sid]) goto fail; } ns++; @@ -479,33 +476,29 @@ void wd177x_format::check_compatibility(floppy_image *image, std::vector &c // A track specific format is to be supplied. void wd177x_format::extract_sectors(floppy_image *image, const format &f, desc_s *sdesc, int track, int head) { - uint8_t bitstream[500000/8]; - uint8_t sectdata[50000]; - desc_xs sectors[256]; - int track_size; - // Extract the sectors - generate_bitstream_from_track(track, head, f.cell_size, bitstream, track_size, image); + auto bitstream = generate_bitstream_from_track(track, head, f.cell_size, image); + std::vector> sectors; switch (f.encoding) { case floppy_image::FM: - extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_fm_pc(bitstream); break; case floppy_image::MFM: - extract_sectors_from_bitstream_mfm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); + sectors = extract_sectors_from_bitstream_mfm_pc(bitstream); break; } for(int i=0; i