summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/formats/flopimg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/formats/flopimg.cpp')
-rw-r--r--src/lib/formats/flopimg.cpp561
1 files changed, 391 insertions, 170 deletions
diff --git a/src/lib/formats/flopimg.cpp b/src/lib/formats/flopimg.cpp
index d6bd264906d..63bd6421261 100644
--- a/src/lib/formats/flopimg.cpp
+++ b/src/lib/formats/flopimg.cpp
@@ -2262,14 +2262,15 @@ const floppy_image_format_t::desc_e floppy_image_format_t::amiga_22[] = {
{ END }
};
-void floppy_image_format_t::generate_bitstream_from_track(int track, int head, int cell_size, uint8_t *trackbuf, int &track_size, floppy_image *image, int subtrack)
+std::vector<bool> floppy_image_format_t::generate_bitstream_from_track(int track, int head, int cell_size, floppy_image *image, int subtrack)
{
+ std::vector<bool> trackbuf;
std::vector<uint32_t> &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<uint8_t> floppy_image_format_t::generate_nibbles_from_bitstream(const std::vector<bool> &bitstream)
{
- return (bitstream[pos >> 3] & (0x80 >> (pos & 7))) != 0;
+ std::vector<uint8_t> 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<bool> &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<bool> &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<bool> &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<std::vector<uint8_t>> floppy_image_format_t::extract_sectors_from_bitstream_mfm_pc(const std::vector<bool> &bitstream)
{
- memset(sectors, 0, 256*sizeof(desc_xs));
+ std::vector<std::vector<uint8_t>> 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<track_size; i++) {
- shift_reg = (shift_reg << 1) | sbit_r(bitstream, i);
+ for(uint32_t i=0; i<bitstream.size(); i++) {
+ shift_reg = (shift_reg << 1) | bitstream[i];
if(shift_reg == 0x4489) {
uint16_t header;
- int pos = i+1;
+ uint32_t pos = i+1;
do {
header = 0;
for(int j=0; j<16; j++)
- if(sbit_rp(bitstream, pos, track_size))
+ if(sbit_rp(bitstream, pos))
header |= 0x8000 >> 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<idblk_count; i++) {
- int pos = idblk[i];
- uint8_t track = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t head = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t sector = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t size = sbyte_mfm_r(bitstream, pos, track_size);
+ uint32_t pos = idblk[i];
+ ATTR_UNUSED uint8_t track = sbyte_mfm_r(bitstream, pos);
+ ATTR_UNUSED uint8_t head = sbyte_mfm_r(bitstream, pos);
+ uint8_t sector = sbyte_mfm_r(bitstream, pos);
+ uint8_t size = sbyte_mfm_r(bitstream, pos);
if(size >= 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<ssize; j++)
- sectdata[sectdata_pos++] = sbyte_mfm_r(bitstream, pos, track_size);
+ sdata[j] = sbyte_mfm_r(bitstream, pos);
}
+
+ return sectors;
}
void floppy_image_format_t::get_geometry_mfm_pc(floppy_image *image, int cell_size, int &track_count, int &head_count, int &sector_count)
@@ -2506,11 +2532,6 @@ void floppy_image_format_t::get_geometry_mfm_pc(floppy_image *image, int cell_si
return;
}
- uint8_t bitstream[500000/8];
- uint8_t sectdata[50000];
- desc_xs sectors[256];
- int track_size;
-
// Extract an arbitrary track to get an idea of the number of
// sectors
@@ -2518,29 +2539,23 @@ void floppy_image_format_t::get_geometry_mfm_pc(floppy_image *image, int cell_si
// 0-10, not near the end like 70+, no special effects on sync
// like 33
- generate_bitstream_from_track(track_count > 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<std::vector<uint8_t>> floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const std::vector<bool> &bitstream)
{
- memset(sectors, 0, 256*sizeof(desc_xs));
+ std::vector<std::vector<uint8_t>> 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<track_size; i++) {
- shift_reg = (shift_reg << 1) | sbit_r(bitstream, i);
+ for(uint32_t i=0; i<bitstream.size(); i++) {
+ shift_reg = (shift_reg << 1) | bitstream[i];
// fe
if(shift_reg == 0xf57e) { // address mark
@@ -2593,21 +2608,16 @@ void floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const uint8_t *
}
// Then extract the sectors
- int sectdata_pos = 0;
- for(int i=0; i<idblk_count; i++) {
- int pos = idblk[i];
- uint8_t track = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t head = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t sector = sbyte_mfm_r(bitstream, pos, track_size);
- uint8_t size = sbyte_mfm_r(bitstream, pos, track_size);
+ for(uint32_t i=0; i<idblk_count; i++) {
+ uint32_t pos = idblk[i];
+ ATTR_UNUSED uint8_t track = sbyte_mfm_r(bitstream, pos);
+ ATTR_UNUSED uint8_t head = sbyte_mfm_r(bitstream, pos);
+ uint8_t sector = sbyte_mfm_r(bitstream, pos);
+ uint8_t size = sbyte_mfm_r(bitstream, pos);
if(size >= 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<ssize; j++)
- sectdata[sectdata_pos++] = sbyte_mfm_r(bitstream, pos, track_size);
+ sdata[j] = sbyte_mfm_r(bitstream, pos);
}
+
+ return sectors;
}
void floppy_image_format_t::get_geometry_fm_pc(floppy_image *image, int cell_size, int &track_count, int &head_count, int &sector_count)
@@ -2641,11 +2653,6 @@ void floppy_image_format_t::get_geometry_fm_pc(floppy_image *image, int cell_siz
return;
}
- uint8_t bitstream[500000/8];
- uint8_t sectdata[50000];
- desc_xs sectors[256];
- int track_size;
-
// Extract an arbitrary track to get an idea of the number of
// sectors
@@ -2653,29 +2660,23 @@ void floppy_image_format_t::get_geometry_fm_pc(floppy_image *image, int cell_siz
// 0-10, not near the end like 70+, no special effects on sync
// like 33
- generate_bitstream_from_track(track_count > 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<uint32_t> track_data;
- // gap 4a , IAM and gap 1
+ // gap 4a, IAM and gap 1
if(gap_4a != -1) {
for(int i=0; i<gap_4a; i++) fm_w(track_data, 8, 0xff);
for(int i=0; i< 6; i++) fm_w(track_data, 8, 0x00);
@@ -2772,7 +2773,7 @@ void floppy_image_format_t::build_pc_track_mfm(int track, int head, floppy_image
{
std::vector<uint32_t> track_data;
- // gap 4a , IAM and gap 1
+ // gap 4a, IAM and gap 1
if(gap_4a != -1) {
for(int i=0; i<gap_4a; i++) mfm_w(track_data, 8, 0x4e);
for(int i=0; i<12; i++) mfm_w(track_data, 8, 0x00);
@@ -2836,32 +2837,249 @@ void floppy_image_format_t::build_pc_track_mfm(int track, int head, floppy_image
generate_track_from_levels(track, head, track_data, 0, image);
}
-void floppy_image_format_t::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)
+void floppy_image_format_t::build_mac_track_gcr(int track, int head, floppy_image *image, const desc_gcr_sector *sects)
{
- memset(sectors, 0, 256*sizeof(desc_xs));
+ // 30318342 = 60.0 / 1.979e-6
+ static const uint32_t cells_per_speed_zone[5] = {
+ 30318342 / 394,
+ 30318342 / 429,
+ 30318342 / 472,
+ 30318342 / 525,
+ 30318342 / 590
+ };
+
+ static const std::array<uint8_t, 12> 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<uint32_t> 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<std::vector<uint8_t>> 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<std::vector<uint8_t>> 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<uint32_t> 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<std::vector<uint8_t>> floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const std::vector<bool> &bitstream, int head, int tracks)
+{
+ std::vector<std::vector<uint8_t>> 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<track_size; i++) {
- int bit = sbit_r(bitstream, i);
+ for(uint32_t i=0; i<bitstream.size(); i++) {
+ int bit = bitstream[i];
shift_reg = ((shift_reg << 1) | bit) & 0x3ff;
if (sync && !bit) {
- uint8_t id = sbyte_gcr5_r(bitstream, i, track_size);
+ uint8_t id = sbyte_gcr5_r(bitstream, i);
switch (id) {
case 0x08:
@@ -2880,67 +3098,70 @@ void floppy_image_format_t::extract_sectors_from_bitstream_gcr5(const uint8_t *b
}
// Then extract the sectors
- int sectdata_pos = 0;
for(int i=0; i<hblk_count; i++) {
- int pos = hblk[i];
- ATTR_UNUSED uint8_t block_id = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t crc = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t sector = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t track = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t id2 = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t id1 = sbyte_gcr5_r(bitstream, pos, track_size);
+ uint32_t pos = hblk[i];
+ ATTR_UNUSED uint8_t block_id = sbyte_gcr5_r(bitstream, pos);
+ uint8_t crc = sbyte_gcr5_r(bitstream, pos);
+ uint8_t sector = sbyte_gcr5_r(bitstream, pos);
+ uint8_t track = sbyte_gcr5_r(bitstream, pos);
+ uint8_t id2 = sbyte_gcr5_r(bitstream, pos);
+ uint8_t id1 = sbyte_gcr5_r(bitstream, pos);
if (crc ^ sector ^ track ^ id2 ^ id1) {
// header crc mismatch
+ continue;
}
pos = dblk[i];
- block_id = sbyte_gcr5_r(bitstream, pos, track_size);
+ block_id = sbyte_gcr5_r(bitstream, pos);
if (track > 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<sectors[sector].size; j++) {
- uint8_t data = sbyte_gcr5_r(bitstream, pos, track_size);
+ for(int j=0; j<256; j++) {
+ uint8_t data = sbyte_gcr5_r(bitstream, pos);
data_crc ^= data;
- sectdata[sectdata_pos++] = data;
+ sdata[j] = data;
}
- data_crc ^= sbyte_gcr5_r(bitstream, pos, track_size);
+ data_crc ^= sbyte_gcr5_r(bitstream, pos);
if (data_crc) {
// data crc mismatch
+ sdata.clear();
}
}
+
+ return sectors;
}
-void floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const uint8_t *bitstream, int track_size, desc_xs *sectors, uint8_t *sectdata, int sectdata_size)
+std::vector<std::vector<uint8_t>> floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const std::vector<bool> &bitstream)
{
- memset(sectors, 0, 256*sizeof(desc_xs));
+ std::vector<std::vector<uint8_t>> 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<track_size; i++) {
- int bit = sbit_r(bitstream, i);
+ for(uint32_t i=0; i<bitstream.size(); i++) {
+ int bit = bitstream[i];
shift_reg = ((shift_reg << 1) | bit) & 0x3ff;
if (sync && !bit) {
- uint8_t id = sbyte_gcr5_r(bitstream, i, track_size);
+ uint8_t id = sbyte_gcr5_r(bitstream, i);
switch (id) {
case 0x07:
@@ -2959,23 +3180,23 @@ void floppy_image_format_t::extract_sectors_from_bitstream_victor_gcr5(const uin
}
// Then extract the sectors
- int sectdata_pos = 0;
for(int i=0; i<hblk_count; i++) {
- int pos = hblk[i];
- ATTR_UNUSED uint8_t block_id = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t track = sbyte_gcr5_r(bitstream, pos, track_size);
- uint8_t sector = sbyte_gcr5_r(bitstream, pos, track_size);
+ uint32_t pos = hblk[i];
+ ATTR_UNUSED uint8_t block_id = sbyte_gcr5_r(bitstream, pos);
+ ATTR_UNUSED uint8_t track = sbyte_gcr5_r(bitstream, pos);
+ uint8_t sector = sbyte_gcr5_r(bitstream, pos);
pos = dblk[i];
- block_id = sbyte_gcr5_r(bitstream, pos, track_size);
-
- sectors[sector].track = track & 0x7f;
- sectors[sector].head = BIT(track, 7);
- sectors[sector].size = 512;
- sectors[sector].data = sectdata + sectdata_pos;
- for(int j=0; j<sectors[sector].size; j++) {
- uint8_t data = sbyte_gcr5_r(bitstream, pos, track_size);
- sectdata[sectdata_pos++] = data;
- }
+ block_id = sbyte_gcr5_r(bitstream, pos);
+
+ if(sectors.size() <= sector)
+ sectors.resize(sector+1);
+ auto &sdata = sectors[sector];
+ sdata.resize(512);
+
+ for(int j=0; j<512; j++)
+ sdata[j] = sbyte_gcr5_r(bitstream, pos);
}
+
+ return sectors;
}