mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
hfe: Remove write support for now, it has issues (sharing data between read and write, copy/pasting the pll code, not supporting v3). May be rewritten once the other changes are in
This commit is contained in:
parent
5029b5ffb6
commit
66c0222c69
@ -111,21 +111,7 @@
|
||||
#define HEADER_LENGTH 512
|
||||
#define TRACK_TABLE_LENGTH 1024
|
||||
|
||||
hfe_format::hfe_format() : floppy_image_format_t(),
|
||||
m_cylinders(0),
|
||||
m_heads(0),
|
||||
m_track_encoding(UNKNOWN_ENCODING),
|
||||
m_bit_rate(0),
|
||||
m_floppy_rpm(0),
|
||||
m_interface_mode(DISABLE_FLOPPYMODE),
|
||||
m_write_allowed(true),
|
||||
m_single_step(true),
|
||||
m_track0s0_has_altencoding(false),
|
||||
m_track0s0_encoding(UNKNOWN_ENCODING),
|
||||
m_track0s1_has_altencoding(false),
|
||||
m_track0s1_encoding(UNKNOWN_ENCODING),
|
||||
m_selected_mode(DISABLE_FLOPPYMODE),
|
||||
m_selected_encoding(UNKNOWN_ENCODING)
|
||||
hfe_format::hfe_format() : floppy_image_format_t()
|
||||
{
|
||||
}
|
||||
|
||||
@ -146,7 +132,7 @@ const char *hfe_format::extensions() const
|
||||
|
||||
bool hfe_format::supports_save() const
|
||||
{
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
int hfe_format::identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants)
|
||||
@ -166,6 +152,7 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve
|
||||
size_t actual;
|
||||
uint8_t header[HEADER_LENGTH];
|
||||
uint8_t track_table[TRACK_TABLE_LENGTH];
|
||||
header_info info;
|
||||
|
||||
int drivecyl, driveheads;
|
||||
image->get_maximal_geometry(drivecyl, driveheads);
|
||||
@ -181,101 +168,101 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve
|
||||
return false;
|
||||
}
|
||||
|
||||
m_cylinders = header[9] & 0xff;
|
||||
m_heads = header[10] & 0xff;
|
||||
info.m_cylinders = header[9] & 0xff;
|
||||
info.m_heads = header[10] & 0xff;
|
||||
|
||||
if (drivecyl < m_cylinders)
|
||||
if (drivecyl < info.m_cylinders)
|
||||
{
|
||||
if (m_cylinders - drivecyl > DUMP_THRESHOLD)
|
||||
if (info.m_cylinders - drivecyl > DUMP_THRESHOLD)
|
||||
{
|
||||
osd_printf_error("hxchfe: Floppy disk has too many tracks for this drive (floppy tracks=%d, drive tracks=%d).\n", m_cylinders, drivecyl);
|
||||
osd_printf_error("hxchfe: Floppy disk has too many tracks for this drive (floppy tracks=%d, drive tracks=%d).\n", info.m_cylinders, drivecyl);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some dumps has a few excess tracks to be safe,
|
||||
// lets be nice and just skip those tracks
|
||||
osd_printf_warning("hxchfe: Floppy disk has a slight excess of tracks for this drive that will be discarded (floppy tracks=%d, drive tracks=%d).\n", m_cylinders, drivecyl);
|
||||
m_cylinders = drivecyl;
|
||||
osd_printf_warning("hxchfe: Floppy disk has a slight excess of tracks for this drive that will be discarded (floppy tracks=%d, drive tracks=%d).\n", info.m_cylinders, drivecyl);
|
||||
info.m_cylinders = drivecyl;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_cylinders <= drivecyl/2)
|
||||
if (info.m_cylinders <= drivecyl/2)
|
||||
{
|
||||
osd_printf_error("hxchfe: Double stepping not yet supported (floppy tracks=%d, drive tracks=%d).\n", m_cylinders, drivecyl);
|
||||
osd_printf_error("hxchfe: Double stepping not yet supported (floppy tracks=%d, drive tracks=%d).\n", info.m_cylinders, drivecyl);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_track_encoding = (encoding_t)(header[11] & 0xff);
|
||||
info.m_track_encoding = (encoding_t)(header[11] & 0xff);
|
||||
|
||||
if (m_track_encoding > EMU_FM_ENCODING)
|
||||
if (info.m_track_encoding > EMU_FM_ENCODING)
|
||||
{
|
||||
osd_printf_error("hxchfe: Unknown track encoding %d.\n", m_track_encoding);
|
||||
osd_printf_error("hxchfe: Unknown track encoding %d.\n", info.m_track_encoding);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_bit_rate = (header[12] & 0xff) | ((header[13] & 0xff)<<8);
|
||||
info.m_bit_rate = (header[12] & 0xff) | ((header[13] & 0xff)<<8);
|
||||
|
||||
if (m_bit_rate > 500)
|
||||
if (info.m_bit_rate > 500)
|
||||
{
|
||||
osd_printf_error("hxchfe: Unsupported bit rate %d.\n", m_bit_rate);
|
||||
osd_printf_error("hxchfe: Unsupported bit rate %d.\n", info.m_bit_rate);
|
||||
return false;
|
||||
}
|
||||
int samplelength = 500000 / m_bit_rate;
|
||||
int samplelength = 500000 / info.m_bit_rate;
|
||||
|
||||
// Not used in the HxC emulator
|
||||
m_floppy_rpm = (header[14] & 0xff) | ((header[15] & 0xff)<<8);
|
||||
info.m_floppy_rpm = (header[14] & 0xff) | ((header[15] & 0xff)<<8);
|
||||
|
||||
m_interface_mode = (floppymode_t)(header[16] & 0xff);
|
||||
if (m_interface_mode > S950_HD_FLOPPYMODE)
|
||||
info.m_interface_mode = (floppymode_t)(header[16] & 0xff);
|
||||
if (info.m_interface_mode > S950_HD_FLOPPYMODE)
|
||||
{
|
||||
osd_printf_error("hxchfe: Unknown interface mode %d.\n", m_interface_mode);
|
||||
osd_printf_error("hxchfe: Unknown interface mode %d.\n", info.m_interface_mode);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_write_allowed = (header[20] != 0);
|
||||
m_single_step = (header[21] != 0);
|
||||
m_track0s0_has_altencoding = (header[22] == 0x00);
|
||||
m_track0s0_encoding = (encoding_t)(header[23] & 0xff);
|
||||
m_track0s1_has_altencoding = (header[24] == 0x00);
|
||||
m_track0s1_encoding = (encoding_t)(header[25] & 0xff);
|
||||
info.m_write_allowed = (header[20] != 0);
|
||||
info.m_single_step = (header[21] != 0);
|
||||
info.m_track0s0_has_altencoding = (header[22] == 0x00);
|
||||
info.m_track0s0_encoding = (encoding_t)(header[23] & 0xff);
|
||||
info.m_track0s1_has_altencoding = (header[24] == 0x00);
|
||||
info.m_track0s1_encoding = (encoding_t)(header[25] & 0xff);
|
||||
|
||||
// read track lookup table (multiple of 512)
|
||||
int table_offset = (header[18] & 0xff) | ((header[19] & 0xff)<<8);
|
||||
|
||||
io.read_at(table_offset<<9, track_table, TRACK_TABLE_LENGTH, actual);
|
||||
|
||||
for (int i=0; i < m_cylinders; i++)
|
||||
for (int i=0; i < info.m_cylinders; i++)
|
||||
{
|
||||
m_cyl_offset[i] = (track_table[4*i] & 0xff) | ((track_table[4*i+1] & 0xff)<<8);
|
||||
m_cyl_length[i] = (track_table[4*i+2] & 0xff) | ((track_table[4*i+3] & 0xff)<<8);
|
||||
info.m_cyl_offset[i] = (track_table[4*i] & 0xff) | ((track_table[4*i+1] & 0xff)<<8);
|
||||
info.m_cyl_length[i] = (track_table[4*i+2] & 0xff) | ((track_table[4*i+3] & 0xff)<<8);
|
||||
}
|
||||
|
||||
// Load the tracks
|
||||
std::vector<uint8_t> cylinder_buffer;
|
||||
for(int cyl=0; cyl < m_cylinders; cyl++)
|
||||
for(int cyl=0; cyl < info.m_cylinders; cyl++)
|
||||
{
|
||||
// actual data read
|
||||
// The HFE format defines an interleave of the two sides per cylinder
|
||||
// at every 256 bytes
|
||||
cylinder_buffer.resize(m_cyl_length[cyl]);
|
||||
io.read_at(m_cyl_offset[cyl]<<9, &cylinder_buffer[0], m_cyl_length[cyl], actual);
|
||||
cylinder_buffer.resize(info.m_cyl_length[cyl]);
|
||||
io.read_at(info.m_cyl_offset[cyl]<<9, &cylinder_buffer[0], info.m_cyl_length[cyl], actual);
|
||||
|
||||
generate_track_from_hfe_bitstream(cyl, 0, samplelength, &cylinder_buffer[0], m_cyl_length[cyl], image);
|
||||
if (m_heads == 2)
|
||||
generate_track_from_hfe_bitstream(cyl, 1, samplelength, &cylinder_buffer[0], m_cyl_length[cyl], image);
|
||||
generate_track_from_hfe_bitstream(cyl, 0, samplelength, &cylinder_buffer[0], info.m_cyl_length[cyl], image);
|
||||
if (info.m_heads == 2)
|
||||
generate_track_from_hfe_bitstream(cyl, 1, samplelength, &cylinder_buffer[0], info.m_cyl_length[cyl], image);
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
// Find variant
|
||||
if (m_track_encoding == ISOIBM_FM_ENCODING || m_track_encoding == EMU_FM_ENCODING)
|
||||
if (info.m_track_encoding == ISOIBM_FM_ENCODING || info.m_track_encoding == EMU_FM_ENCODING)
|
||||
// FM is for single density
|
||||
image->set_variant((m_heads==1)? floppy_image::SSSD : floppy_image::DSSD);
|
||||
image->set_variant((info.m_heads==1)? floppy_image::SSSD : floppy_image::DSSD);
|
||||
else
|
||||
{
|
||||
// MFM encoding is for everything else
|
||||
if (m_track_encoding == ISOIBM_MFM_ENCODING || m_track_encoding == AMIGA_MFM_ENCODING)
|
||||
if (info.m_track_encoding == ISOIBM_MFM_ENCODING || info.m_track_encoding == AMIGA_MFM_ENCODING)
|
||||
{
|
||||
// Each cylinder contains the samples of both sides, 8 samples per
|
||||
// byte; the bitRate determines how many samples constitute a cell
|
||||
@ -286,7 +273,7 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve
|
||||
// DSED: 2.8 MiB = 2*80*36*512 bytes; 400000 cells/track, 500 ns, 1 Mbit/s
|
||||
|
||||
// Use cylinder 1 (cyl 0 may have special encodings)
|
||||
int cellcount = (m_cyl_length[1] * 8 / 2) * 250 / m_bit_rate;
|
||||
int cellcount = (info.m_cyl_length[1] * 8 / 2) * 250 / info.m_bit_rate;
|
||||
if (cellcount > 300000)
|
||||
image->set_variant(floppy_image::DSED);
|
||||
else
|
||||
@ -297,7 +284,7 @@ bool hfe_format::load(util::random_read &io, uint32_t form_factor, const std::ve
|
||||
{
|
||||
if (cellcount > 90000)
|
||||
// We cannot distinguish DSDD from DSQD without knowing the size of the floppy disk
|
||||
image->set_variant((m_heads==1)? floppy_image::SSDD : floppy_image::DSDD);
|
||||
image->set_variant((info.m_heads==1)? floppy_image::SSDD : floppy_image::DSDD);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,292 +406,6 @@ void hfe_format::generate_track_from_hfe_bitstream(int cyl, int head, int sample
|
||||
image->set_write_splice_position(cyl, head, 0, 0);
|
||||
}
|
||||
|
||||
bool hfe_format::save(util::random_read_write &io, const std::vector<uint32_t> &variants, floppy_image *image)
|
||||
{
|
||||
size_t actual;
|
||||
std::vector<uint8_t> cylbuf;
|
||||
|
||||
// Create a buffer that is big enough to handle HD formats. We don't
|
||||
// know the track length until we generate the HFE bitstream.
|
||||
cylbuf.resize(0x10000);
|
||||
|
||||
uint8_t header[HEADER_LENGTH];
|
||||
uint8_t track_table[TRACK_TABLE_LENGTH];
|
||||
|
||||
int track_end = 0x61c0;
|
||||
int samplelength = 2000;
|
||||
|
||||
// Set up header
|
||||
const char* sig = "HXCPICFE";
|
||||
memcpy(header, sig, 8);
|
||||
|
||||
header[8] = 0;
|
||||
// Can we change the number of tracks or heads?
|
||||
image->get_actual_geometry(m_cylinders, m_heads);
|
||||
|
||||
header[9] = m_cylinders;
|
||||
header[10] = m_heads;
|
||||
// Floppy RPM is not used
|
||||
header[14] = 0;
|
||||
header[15] = 0;
|
||||
|
||||
// Bit rate and encoding will be set later, they may have changed by
|
||||
// reformatting. The selected encoding is UNKNOWN_ENCODING unless
|
||||
// explicitly set
|
||||
m_track_encoding = m_selected_encoding;
|
||||
|
||||
// Take the old mode, unless we have specified a mode
|
||||
header[16] = (m_selected_mode != DISABLE_FLOPPYMODE)? m_selected_mode : m_interface_mode;
|
||||
header[17] = 0;
|
||||
|
||||
// The track lookup table is located at offset 0x200 (as 512 multiple)
|
||||
header[18] = 1;
|
||||
header[19] = 0;
|
||||
|
||||
header[20] = m_write_allowed? 0xff : 0x00;
|
||||
header[21] = m_single_step? 0xff : 0x00;
|
||||
|
||||
// TODO: Allow for divergent track 0 format
|
||||
header[22] = m_track0s0_has_altencoding? 0x00 : 0xff;
|
||||
header[23] = m_track0s0_encoding;
|
||||
header[24] = m_track0s1_has_altencoding? 0x00 : 0xff;
|
||||
header[25] = m_track0s1_encoding;
|
||||
|
||||
// Fill the remaining bytes with 0xff
|
||||
for (int i=26; i < HEADER_LENGTH; i++) header[i] = 0xff;
|
||||
|
||||
// Don't write yet; we still have to find out the bit rate.
|
||||
|
||||
// We won't have more than 200000 cells on the track
|
||||
for (int cyl=0; cyl < m_cylinders; cyl++)
|
||||
{
|
||||
// After the call, the encoding will be set to FM or MFM
|
||||
generate_hfe_bitstream_from_track(cyl, 0, samplelength, m_track_encoding, &cylbuf[0], track_end, image);
|
||||
if (m_heads == 2)
|
||||
generate_hfe_bitstream_from_track(cyl, 1, samplelength, m_track_encoding, &cylbuf[0], track_end, image);
|
||||
|
||||
if (cyl==0)
|
||||
{
|
||||
// Complete the header and write it
|
||||
header[11] = m_track_encoding;
|
||||
m_bit_rate = 500000/samplelength;
|
||||
header[12] = m_bit_rate & 0xff;
|
||||
header[13] = (m_bit_rate >> 8) & 0xff;
|
||||
|
||||
// Now write the header
|
||||
io.write_at(0, header, HEADER_LENGTH, actual);
|
||||
|
||||
// Set up the track lookup table
|
||||
// We need the encoding value to be sure about the track length
|
||||
int len = (m_track_encoding==ISOIBM_FM_ENCODING)? 0x61b0 : 0x61c0;
|
||||
int pos = 0x400;
|
||||
|
||||
for (int i=0; i < m_cylinders; i++)
|
||||
{
|
||||
m_cyl_offset[i] = (pos >> 9);
|
||||
m_cyl_length[i] = len;
|
||||
pos += (len + 0x1ff) & 0xfe00;
|
||||
track_table[i*4] = m_cyl_offset[i] & 0xff;
|
||||
track_table[i*4+1] = (m_cyl_offset[i]>>8) & 0xff;
|
||||
track_table[i*4+2] = len & 0xff;
|
||||
track_table[i*4+3] = (len>>8) & 0xff;
|
||||
}
|
||||
// Set the remainder to 0xff
|
||||
for (int i=m_cylinders*4; i < TRACK_TABLE_LENGTH; i++)
|
||||
track_table[i] = 0xff;
|
||||
|
||||
io.write_at(0x200, track_table, TRACK_TABLE_LENGTH, actual);
|
||||
}
|
||||
// Write the current cylinder
|
||||
io.write_at(m_cyl_offset[cyl]<<9, &cylbuf[0], (m_cyl_length[cyl] + 0x1ff) & 0xfe00, actual);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void hfe_format::generate_hfe_bitstream_from_track(int cyl, int head, int& samplelength, encoding_t& encoding, uint8_t *cylinder_buffer, int track_end, floppy_image *image)
|
||||
{
|
||||
// We are using an own implementation here because the result of the
|
||||
// parent class method would require some post-processing that we
|
||||
// can easily avoid.
|
||||
|
||||
// See floppy_image_format_t::generate_bitstream_from_track
|
||||
// as the original code
|
||||
|
||||
// No subtracks definded
|
||||
std::vector<uint32_t> &tbuf = image->get_buffer(cyl, head, 0);
|
||||
if (tbuf.size() <= 1)
|
||||
{
|
||||
// Unformatted track
|
||||
// TODO must handle that according to HFE
|
||||
int track_size = 200000000/samplelength;
|
||||
memset(cylinder_buffer, 0, (track_size+7)/8);
|
||||
return;
|
||||
}
|
||||
|
||||
// Find out whether we have FM or MFM recording, and determine the bit rate.
|
||||
// This is needed for the format header.
|
||||
//
|
||||
// The encoding may have changed by reformatting; we cannot rely on the
|
||||
// header when loading.
|
||||
//
|
||||
// FM: encoding 1 -> flux length = 4 us (min) ambivalent
|
||||
// encoding 10 -> flux length = 8 us (max) ambivalent
|
||||
// MFM: encoding 10 -> flux length = 4 us (min, DD) ambivalent
|
||||
// encoding 100 -> flux length = 6 us (DD) significant
|
||||
// encoding 1000 -> flux length = 8 us (max, DD) ambivalent
|
||||
// encoding 10 -> flux length = 2 us (min, HD) significant
|
||||
// encoding 100 -> flux length = 3 us (max, HD) significant
|
||||
|
||||
// If we have MFM, we should very soon detect a flux length of 6 us.
|
||||
// But if we have FM, how long should we search to be sure?
|
||||
// We assume that after 2000 us we should have reached the first IDAM,
|
||||
// which contains a sequence 1001, implying a flux length of 6 us.
|
||||
// If there was no such flux in that area, this can safely be assumed to be FM.
|
||||
|
||||
// Do it only for the first track; the format only supports one encoding.
|
||||
if (encoding == UNKNOWN_ENCODING)
|
||||
{
|
||||
bool mfm_recording = false;
|
||||
int time0 = 0;
|
||||
int minflux = 4000;
|
||||
int fluxlen = 0;
|
||||
// Skip the beginning (may have a short cell)
|
||||
for (int i=2; (i < tbuf.size()-1) && (time0 < 2000000) && !mfm_recording; i++)
|
||||
{
|
||||
time0 = tbuf[i] & floppy_image::TIME_MASK;
|
||||
fluxlen = (tbuf[i+1] & floppy_image::TIME_MASK) - time0;
|
||||
if ((fluxlen < 3500) || (fluxlen > 5500 && fluxlen < 6500))
|
||||
mfm_recording = true;
|
||||
if (fluxlen < minflux) minflux = fluxlen;
|
||||
}
|
||||
encoding = mfm_recording? ISOIBM_MFM_ENCODING : ISOIBM_FM_ENCODING;
|
||||
|
||||
// samplelength = 1000ns => 10^6 cells/sec => 500 kbit/s
|
||||
// samplelength = 2000ns => 250 kbit/s
|
||||
// We stay with double sampling at 250 kbit/s for FM
|
||||
if (minflux < 3500) samplelength = 1000;
|
||||
else samplelength = 2000;
|
||||
}
|
||||
|
||||
// Start at the write splice
|
||||
uint32_t splice = image->get_write_splice_position(cyl, head, 0);
|
||||
|
||||
int cur_pos = splice;
|
||||
int cur_entry = 0;
|
||||
|
||||
// Fast-forward to the write splice position (always 0 in this format)
|
||||
while (cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry+1] & floppy_image::TIME_MASK) < cur_pos)
|
||||
cur_entry++;
|
||||
|
||||
int period = samplelength;
|
||||
int period_adjust_base = period * 0.05;
|
||||
|
||||
int min_period = int(samplelength*0.75);
|
||||
int max_period = int(samplelength*1.25);
|
||||
int phase_adjust = 0;
|
||||
int freq_hist = 0;
|
||||
uint32_t next = 0;
|
||||
|
||||
int offset = 0x100;
|
||||
|
||||
// Prepare offset for the format storage
|
||||
if (head==0)
|
||||
{
|
||||
offset = 0;
|
||||
track_end -= 0x0100;
|
||||
}
|
||||
|
||||
uint8_t bit = 0x01;
|
||||
uint8_t current = 0;
|
||||
|
||||
while (next < 200000000) {
|
||||
int edge = tbuf[cur_entry] & floppy_image::TIME_MASK;
|
||||
|
||||
// Start of track? Use next entry.
|
||||
if (edge==0)
|
||||
{
|
||||
edge = tbuf[++cur_entry] & floppy_image::TIME_MASK;
|
||||
}
|
||||
|
||||
// Wrapped over end?
|
||||
if (edge < cur_pos) edge += 200000000;
|
||||
|
||||
// End of cell
|
||||
next = cur_pos + period + phase_adjust;
|
||||
|
||||
// End of the window is at next; edge is the actual transition
|
||||
if (edge >= next)
|
||||
{
|
||||
// No transition in the window -> 0
|
||||
phase_adjust = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transition in the window -> 1
|
||||
current |= bit;
|
||||
int delta = edge - (next - period/2);
|
||||
|
||||
phase_adjust = 0.65*delta;
|
||||
|
||||
if (delta < 0)
|
||||
{
|
||||
if (freq_hist < 0) freq_hist--;
|
||||
else freq_hist = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta > 0)
|
||||
{
|
||||
if(freq_hist > 0) freq_hist++;
|
||||
else freq_hist = 1;
|
||||
}
|
||||
else freq_hist = 0;
|
||||
}
|
||||
|
||||
if (freq_hist)
|
||||
{
|
||||
int afh = freq_hist < 0 ? -freq_hist : freq_hist;
|
||||
if (afh > 1)
|
||||
{
|
||||
int aper = period_adjust_base*delta/period;
|
||||
if (!aper)
|
||||
aper = freq_hist < 0 ? -1 : 1;
|
||||
period += aper;
|
||||
|
||||
if (period < min_period) period = min_period;
|
||||
else if (period > max_period) period = max_period;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_pos = next;
|
||||
|
||||
bit = (bit << 1) & 0xff;
|
||||
if (bit == 0)
|
||||
{
|
||||
bit = 0x01;
|
||||
cylinder_buffer[offset++] = current;
|
||||
if ((offset & 0xff)==0) offset += 0x100;
|
||||
current = 0;
|
||||
}
|
||||
|
||||
// Fast-forward to next cell
|
||||
while (cur_entry < int(tbuf.size())-1 && (tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
||||
cur_entry++;
|
||||
|
||||
// Reaching the end of the track
|
||||
if (cur_entry == int(tbuf.size())-1 && (tbuf[cur_entry] & floppy_image::TIME_MASK) < cur_pos)
|
||||
{
|
||||
// Wrap to index 0 or 1 depending on whether there is a transition exactly at the index hole
|
||||
cur_entry = (tbuf[int(tbuf.size())-1] & floppy_image::MG_MASK) != (tbuf[0] & floppy_image::MG_MASK) ?
|
||||
0 : 1;
|
||||
}
|
||||
}
|
||||
// Write the current byte when not done
|
||||
if (bit != 0x01)
|
||||
cylinder_buffer[offset] = current;
|
||||
}
|
||||
|
||||
const floppy_format_type FLOPPY_HFE_FORMAT = &floppy_image_format_creator<hfe_format>;
|
||||
|
||||
|
||||
|
@ -49,40 +49,40 @@ public:
|
||||
|
||||
virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants) override;
|
||||
virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector<uint32_t> &variants, floppy_image *image) override;
|
||||
virtual bool save(util::random_read_write &io, const std::vector<uint32_t> &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;
|
||||
|
||||
void set_floppy_mode(floppymode_t mode) { m_selected_mode = mode; }
|
||||
void set_encoding(encoding_t enc) { m_selected_encoding = enc; }
|
||||
|
||||
private:
|
||||
void generate_track_from_hfe_bitstream(int track, int head, int samplelength, const uint8_t *trackbuf, int track_end, floppy_image *image);
|
||||
void generate_hfe_bitstream_from_track(int track, int head, int& samplelength, encoding_t& encoding, uint8_t *trackbuf, int track_end, floppy_image *image);
|
||||
|
||||
// Header fields from the HFE format
|
||||
int m_cylinders; // Number of track in the file
|
||||
int m_heads; // Number of valid side
|
||||
encoding_t m_track_encoding; // Track Encoding mode
|
||||
int m_bit_rate; // Bitrate in Kbit/s (max: 500)
|
||||
int m_floppy_rpm; // Rotation per minute
|
||||
floppymode_t m_interface_mode; // Floppy interface mode.
|
||||
struct header_info {
|
||||
int m_cylinders = 0; // Number of track in the file
|
||||
int m_heads = 0; // Number of valid side
|
||||
encoding_t m_track_encoding = UNKNOWN_ENCODING; // Track Encoding mode
|
||||
int m_bit_rate = 0; // Bitrate in Kbit/s (max: 500)
|
||||
int m_floppy_rpm = 0; // Rotation per minute
|
||||
floppymode_t m_interface_mode = DISABLE_FLOPPYMODE; // Floppy interface mode.
|
||||
|
||||
bool m_write_allowed;
|
||||
bool m_single_step;
|
||||
bool m_track0s0_has_altencoding;
|
||||
encoding_t m_track0s0_encoding; // alternate track_encoding for track 0 Side 0
|
||||
bool m_track0s1_has_altencoding;
|
||||
encoding_t m_track0s1_encoding; // alternate track_encoding for track 0 Side 1
|
||||
bool m_write_allowed = true;
|
||||
bool m_single_step = true;
|
||||
bool m_track0s0_has_altencoding = false;
|
||||
encoding_t m_track0s0_encoding = UNKNOWN_ENCODING; // alternate track_encoding for track 0 Side 0
|
||||
bool m_track0s1_has_altencoding = false;
|
||||
encoding_t m_track0s1_encoding = UNKNOWN_ENCODING; // alternate track_encoding for track 0 Side 1
|
||||
|
||||
int m_cyl_offset[256];
|
||||
int m_cyl_length[256];
|
||||
int m_cyl_offset[256];
|
||||
int m_cyl_length[256];
|
||||
|
||||
floppymode_t m_selected_mode;
|
||||
encoding_t m_selected_encoding;
|
||||
floppymode_t m_selected_mode = DISABLE_FLOPPYMODE;
|
||||
encoding_t m_selected_encoding = UNKNOWN_ENCODING;
|
||||
};
|
||||
|
||||
void set_floppy_mode(header_info &info, floppymode_t mode) { info.m_selected_mode = mode; }
|
||||
void set_encoding(header_info &info, encoding_t enc) { info.m_selected_encoding = enc; }
|
||||
};
|
||||
|
||||
extern const floppy_format_type FLOPPY_HFE_FORMAT;
|
||||
|
Loading…
Reference in New Issue
Block a user