diff options
author | Olivier Galibert <galibert@pobox.com> | 2011-09-03 20:51:10 +0000 |
---|---|---|
committer | Olivier Galibert <galibert@pobox.com> | 2011-09-03 20:51:10 +0000 |
commit | 19b0135c3019e14d1ee7948ebf3f9abd485bb24c (patch) | |
tree | a350c8d38040f57aa9c058f97865d811efcad663 | |
parent | 45ca5483743452764f948db66d1d646e283181ed (diff) |
floppy: Change the internal format to use magnetic cells. Temporarily
move the full-track pll bit extraction in the amiga fdc. [O. Galibert]
-rw-r--r-- | src/emu/imagedev/floppy.h | 3 | ||||
-rw-r--r-- | src/lib/formats/ami_dsk.c | 8 | ||||
-rw-r--r-- | src/lib/formats/flopimg.c | 76 | ||||
-rw-r--r-- | src/lib/formats/flopimg.h | 64 | ||||
-rw-r--r-- | src/lib/formats/hxcmfm_dsk.c | 21 | ||||
-rw-r--r-- | src/lib/formats/mfi_dsk.c | 99 | ||||
-rw-r--r-- | src/lib/formats/mfi_dsk.h | 3 |
7 files changed, 147 insertions, 127 deletions
diff --git a/src/emu/imagedev/floppy.h b/src/emu/imagedev/floppy.h index 487bfd47930..a06a4375c30 100644 --- a/src/emu/imagedev/floppy.h +++ b/src/emu/imagedev/floppy.h @@ -61,7 +61,8 @@ public: void setup_unload_cb(unload_cb cb); void setup_index_pulse_cb(index_pulse_cb cb); - UINT8* get_buffer() { return m_image->get_buffer(m_cyl,m_ss ^ 1); } + UINT32* get_buffer() { return m_image->get_buffer(m_cyl,m_ss ^ 1); } + UINT32 get_len() { return m_image->get_track_size(m_cyl,m_ss ^ 1); } void mon_w(int state); void index_func(); diff --git a/src/lib/formats/ami_dsk.c b/src/lib/formats/ami_dsk.c index b12b561d780..df04c178b68 100644 --- a/src/lib/formats/ami_dsk.c +++ b/src/lib/formats/ami_dsk.c @@ -37,7 +37,7 @@ int adf_format::identify(floppy_image *image) UINT64 size = image->image_size(); if ((size == 901120) || (size == 1802240)) { - return 100; + return 50; } return 0; } @@ -78,13 +78,11 @@ bool adf_format::load(floppy_image *image) } UINT8 *mfm = NULL; - image->set_meta_data(80,2,300,(UINT16)253360); + image->set_meta_data(80, 2); for(int track=0; track < 80; track++) { for(int side=0; side < 2; side++) { - mfm = image->get_buffer(track,side); - image->set_track_size(track, side, 16384); image->image_read(sectdata, (track*2 + side)*512*11, 512*11); - generate_track(desc, track, side, sectors, 11, 100000, mfm); + generate_track(desc, track, side, sectors, 11, 100000, image); } } diff --git a/src/lib/formats/flopimg.c b/src/lib/formats/flopimg.c index 66150e44295..c9eccef5881 100644 --- a/src/lib/formats/flopimg.c +++ b/src/lib/formats/flopimg.c @@ -13,6 +13,7 @@ #include <assert.h> #include <limits.h> +#include "emu.h" #include "osdcore.h" #include "ioprocs.h" #include "flopimg.h" @@ -955,15 +956,32 @@ floppy_image::floppy_image(void *fp, const struct io_procs *procs, const floppy_ else m_formats = fif; } + + memset(cell_data, 0, sizeof(cell_data)); + memset(track_size, 0, sizeof(track_size)); + memset(track_alloc_size, 0, sizeof(track_alloc_size)); } floppy_image::~floppy_image() { - if(m_formats) - delete m_formats; close(); } +void floppy_image::ensure_alloc(UINT16 track, UINT8 side) +{ + int idx = (track << 1) + side; + if(track_size[idx] > track_alloc_size[idx]) { + UINT32 new_size = track_size[idx]*11/10; + UINT32 *new_array = global_alloc_array(UINT32, new_size); + if(track_alloc_size[idx]) { + memcpy(new_array, cell_data[idx], track_alloc_size[idx]*4); + global_free(cell_data[idx]); + } + cell_data[idx] = new_array; + track_alloc_size[idx] = new_size; + } +} + void floppy_image::image_read(void *buffer, UINT64 offset, size_t length) { io_generic_read(&m_io, buffer, offset, length); @@ -995,12 +1013,10 @@ void floppy_image::close() close_internal(TRUE); } -void floppy_image::set_meta_data(UINT16 tracks, UINT8 sides, UINT16 rpm, UINT16 bitrate) +void floppy_image::set_meta_data(UINT16 _tracks, UINT8 _sides) { - m_tracks = tracks; - m_sides = sides; - m_rpm = rpm; - m_bitrate= bitrate; + tracks = _tracks; + sides = _sides; } floppy_image_format_t *floppy_image::identify(int *best) @@ -1181,9 +1197,9 @@ void floppy_image_format_t::fixup_crcs(UINT8 *buffer, gen_crc_info *crcs) } } -void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, UINT8 *buffer) +void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, floppy_image *image) { - memset(buffer, 0, (track_size+7)/8); + UINT8 *buffer = global_alloc_array_clear(UINT8, (track_size+7)/8); gen_crc_info crcs[MAX_CRC_COUNT]; collect_crcs(desc, crcs); @@ -1317,5 +1333,47 @@ void floppy_image_format_t::generate_track(const desc_e *desc, UINT8 track, UINT } fixup_crcs(buffer, crcs); + + generate_track_from_bitstream(track, head, buffer, track_size, image); + global_free(buffer); +} + +void floppy_image_format_t::normalize_times(UINT32 *buffer, int bitlen) +{ + unsigned int total_sum = 0; + for(int i=0; i != bitlen; i++) + total_sum += buffer[i] & floppy_image::TIME_MASK; + + unsigned int current_sum = 0; + for(int i=0; i != bitlen; i++) { + UINT32 time = buffer[i] & floppy_image::TIME_MASK; + buffer[i] = (buffer[i] & floppy_image::MG_MASK) | (200000000ULL * current_sum / total_sum); + current_sum += time; + } +} + +void floppy_image_format_t::generate_track_from_bitstream(UINT8 track, UINT8 head, const UINT8 *trackbuf, int track_size, floppy_image *image) +{ + // Maximal number of cells which happens when the buffer is all 1 + image->set_track_size(track, head, track_size+1); + UINT32 *dest = image->get_buffer(track, head); + UINT32 *base = dest; + + UINT32 cbit = floppy_image::MG_A; + UINT32 count = 0; + for(int i=0; i != track_size; i++) + if(trackbuf[i >> 3] & (0x80 >> (i & 7))) { + *dest++ = cbit | (count+1); + cbit = cbit == floppy_image::MG_A ? floppy_image::MG_B : floppy_image::MG_A; + count = 1; + } else + count += 2; + + if(count) + *dest++ = cbit | count; + + int size = dest - base; + normalize_times(base, size); + image->set_track_size(track, head, size); } diff --git a/src/lib/formats/flopimg.h b/src/lib/formats/flopimg.h index 5a2dff6616c..2827e67ba76 100644 --- a/src/lib/formats/flopimg.h +++ b/src/lib/formats/flopimg.h @@ -287,7 +287,9 @@ protected: // "sect" is a vector indexed by sector id // "track_size" is in _cells_, i.e. 100000 for a usual 2us-per-cell track at 300rpm - void generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, UINT8 *buffer); + void generate_track(const desc_e *desc, UINT8 track, UINT8 head, const desc_s *sect, int sect_count, int track_size, floppy_image *image); + void generate_track_from_bitstream(UINT8 track, UINT8 head, const UINT8 *trackbuf, int track_size, floppy_image *image); + void normalize_times(UINT32 *buffer, int bitlen); private: enum { CRC_NONE, CRC_AMIGA, CRC_CCITT }; @@ -325,14 +327,38 @@ floppy_image_format_t *floppy_image_format_creator() // ======================> floppy_image -#define MAX_FLOPPY_SIDES 2 -#define MAX_FLOPPY_TRACKS 84 -#define MAX_TRACK_DATA 16384 - // class representing floppy image class floppy_image { public: + // Internal format is close but not identical to the mfi format. + // + // + // Track data consists of a series of 32-bits lsb-first values + // representing magnetic cells. Bits 0-27 indicate the absolute + // position of the start of the cell (not the size), and bits + // 28-31 the type. Type can be: + // - 0, MG_A -> Magnetic orientation A + // - 1, MG_B -> Magnetic orientation B + // - 2, MG_N -> Non-magnetized zone (neutral) + // - 3, MG_D -> Damaged zone, reads as neutral but cannot be changed by writing + // + // The position is in angular units of 1/200,000,000th of a turn. + // The last cell implicit end position is of course 200,000,000. + // + // Unformatted tracks are encoded as zero-size. + + enum { + TIME_MASK = 0x0fffffff, + MG_MASK = 0xf0000000, + MG_SHIFT = 28, + + MG_A = (0 << MG_SHIFT), + MG_B = (1 << MG_SHIFT), + MG_N = (2 << MG_SHIFT), + MG_D = (3 << MG_SHIFT) + }; + // construction/destruction floppy_image(void *fp, const struct io_procs *procs, const floppy_format_type *formats); virtual ~floppy_image(); @@ -343,23 +369,31 @@ public: UINT64 image_size(); void close(); - void set_meta_data(UINT16 tracks, UINT8 sides, UINT16 rpm, UINT16 bitrate); - void set_track_size(UINT16 track, UINT8 side, UINT16 size) { m_track_size[(track << 1) + side] = size; } + void set_meta_data(UINT16 tracks, UINT8 sides); + void set_track_size(UINT16 track, UINT8 side, UINT32 size) { track_size[(track << 1) + side] = size; ensure_alloc(track, side); } floppy_image_format_t *identify(int *best); - UINT8* get_buffer(UINT16 track, UINT8 side) { return m_native_data[(track << 1) + side]; } - UINT16 get_track_size(UINT16 track, UINT8 side) { return m_track_size[(track << 1) + side]; } + UINT32 *get_buffer(UINT16 track, UINT8 side) { return cell_data[(track << 1) + side]; } + UINT32 get_track_size(UINT16 track, UINT8 side) { return track_size[(track << 1) + side]; } private: + enum { + MAX_FLOPPY_SIDES = 2, + MAX_FLOPPY_TRACKS = 84 + }; + void close_internal(bool close_file); struct io_generic m_io; floppy_image_format_t *m_formats; - UINT16 m_tracks; - UINT8 m_sides; - UINT16 m_rpm; - UINT16 m_bitrate; - UINT8 m_native_data[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS][MAX_TRACK_DATA]; - UINT16 m_track_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; + UINT16 tracks; + UINT8 sides; + UINT16 rpm; + + UINT32 *cell_data[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; + UINT32 track_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; + UINT32 track_alloc_size[MAX_FLOPPY_SIDES * MAX_FLOPPY_TRACKS]; + + void ensure_alloc(UINT16 track, UINT8 side); }; #endif /* FLOPIMG_H */ diff --git a/src/lib/formats/hxcmfm_dsk.c b/src/lib/formats/hxcmfm_dsk.c index f1b7a2c3195..f2ef79ba901 100644 --- a/src/lib/formats/hxcmfm_dsk.c +++ b/src/lib/formats/hxcmfm_dsk.c @@ -1,3 +1,5 @@ +#include "emu.h" + #include "hxcmfm_dsk.h" #define MFM_FORMAT_HEADER "HXCMFM" @@ -67,22 +69,35 @@ bool mfm_format::load(floppy_image *image) { MFMIMG header; MFMTRACKIMG trackdesc; + UINT8 *trackbuf = 0; + int trackbuf_size = 0; // read header image->image_read(&header,0, sizeof(header)); - image->set_meta_data(header.number_of_track,header.number_of_side,header.floppyRPM,header.floppyBitRate); + image->set_meta_data(header.number_of_track, header.number_of_side); for(int track=0; track < header.number_of_track; track++) { for(int side=0; side < header.number_of_side; side++) { // read location of image->image_read(&trackdesc,(header.mfmtracklistoffset)+((( track << 1 ) + side)*sizeof(trackdesc)),sizeof(trackdesc)); - image->set_track_size(track, side, trackdesc.mfmtracksize); + if(trackdesc.mfmtracksize > trackbuf_size) { + if(trackbuf) + global_free(trackbuf); + trackbuf_size = trackdesc.mfmtracksize; + trackbuf = global_alloc_array(UINT8, trackbuf_size); + } + // actual data read - image->image_read(image->get_buffer(track,side), trackdesc.mfmtrackoffset, trackdesc.mfmtracksize); + image->image_read(trackbuf, trackdesc.mfmtrackoffset, trackdesc.mfmtracksize); + + generate_track_from_bitstream(track, side, trackbuf, trackdesc.mfmtracksize*8, image); } } + if(trackbuf) + global_free(trackbuf); + return FALSE; } diff --git a/src/lib/formats/mfi_dsk.c b/src/lib/formats/mfi_dsk.c index 7f55fa68748..6b631a70978 100644 --- a/src/lib/formats/mfi_dsk.c +++ b/src/lib/formats/mfi_dsk.c @@ -89,41 +89,14 @@ int mfi_format::identify(floppy_image *image) return 0; } -void mfi_format::advance(const UINT32 *trackbuf, UINT32 &cur_cell, UINT32 cell_count, UINT32 time) -{ - if(time >= 200000000) { - cur_cell = cell_count; - return; - } - - while(cur_cell != cell_count-1 && (trackbuf[cur_cell+1] & TIME_MASK) < time) - cur_cell++; -} - -UINT32 mfi_format::get_next_edge(const UINT32 *trackbuf, UINT32 cur_cell, UINT32 cell_count) -{ - if(cur_cell == cell_count) - return 200000000; - UINT32 cur_bit = trackbuf[cur_cell] & MG_MASK; - cur_cell++; - while(cur_cell != cell_count) { - UINT32 next_bit = trackbuf[cur_cell] & MG_MASK; - if(next_bit != cur_bit) - break; - } - return cur_cell == cell_count ? 200000000 : trackbuf[cur_cell] & TIME_MASK; -} - bool mfi_format::load(floppy_image *image) { header h; entry entries[84*2]; image->image_read(&h, 0, sizeof(header)); image->image_read(&entries, sizeof(header), h.cyl_count*h.head_count*sizeof(entry)); - image->set_meta_data(h.cyl_count, h.head_count, 300, (UINT16)253360); + image->set_meta_data(h.cyl_count, h.head_count); - UINT32 *trackbuf = 0; - int trackbuf_size = 0; UINT8 *compressed = 0; int compressed_size = 0; @@ -143,34 +116,16 @@ bool mfi_format::load(floppy_image *image) compressed = global_alloc_array(UINT8, compressed_size); } - if(ent->uncompressed_size > trackbuf_size) { - if(trackbuf) - global_free(trackbuf); - trackbuf_size = ent->uncompressed_size; - trackbuf = global_alloc_array(UINT32, trackbuf_size/4); - } - image->image_read(compressed, ent->offset, ent->compressed_size); + unsigned int cell_count = ent->uncompressed_size/4; + image->set_track_size(cyl, head, cell_count); + UINT32 *trackbuf = image->get_buffer(cyl, head); + uLongf size = ent->uncompressed_size; if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK) return true; - UINT8 *mfm = image->get_buffer(cyl, head); - image->set_track_size(cyl, head, 16384); - memset(mfm, 0, 16384); - int bit = 0; - - // Extract the bits using a quick-n-dirty software pll - // expecting mfm 2us data. Eventually the plls will end - // up in the fdc simulations themselves. - - // Neutral/damaged bits are not really taken into account - - // Start by turning the cell times into absolute - // positions, it's easier to use that way. - - unsigned int cell_count = ent->uncompressed_size/4; UINT32 cur_time = 0; for(unsigned int i=0; i != cell_count; i++) { UINT32 next_cur_time = cur_time + (trackbuf[i] & TIME_MASK); @@ -180,50 +135,12 @@ bool mfi_format::load(floppy_image *image) if(cur_time != 200000000) return true; - // Then pll the hell out of the bits - - UINT32 cur_cell = 0; - UINT32 pll_period = 2000; - UINT32 pll_phase = 0; - for(;;) { - advance(trackbuf, cur_cell, cell_count, pll_phase); - if(cur_cell == cell_count) - break; - -#if 0 - printf("%09d: (%d, %09d) - (%d, %09d) - (%d, %09d)\n", - pll_phase, - trackbuf[cur_cell] >> MG_SHIFT, trackbuf[cur_cell] & TIME_MASK, - trackbuf[cur_cell+1] >> MG_SHIFT, trackbuf[cur_cell+1] & TIME_MASK, - trackbuf[cur_cell+2] >> MG_SHIFT, trackbuf[cur_cell+2] & TIME_MASK); -#endif - - UINT32 next_edge = get_next_edge(trackbuf, cur_cell, cell_count); - - if(next_edge > pll_phase + pll_period) { - // free run, zero bit - // printf("%09d: %4d - Free run\n", pll_phase, pll_period); - pll_phase += pll_period; - } else { - // Transition in the window, one bit, adjust the period - - mfm[bit >> 3] |= 0x80 >> (bit & 7); - - INT32 delta = next_edge - (pll_phase + pll_period/2); - // printf("%09d: %4d - Delta = %d\n", pll_phase, pll_period, delta); - - // The deltas should be lowpassed, the amplification factor tuned... - pll_period += delta/2; - pll_phase += pll_period; - } - - bit++; - } - image->set_track_size(cyl, head, (bit+7)/8); - ent++; } + if(compressed) + global_free(compressed); + return false; } diff --git a/src/lib/formats/mfi_dsk.h b/src/lib/formats/mfi_dsk.h index 3983b8aead6..797b662f46d 100644 --- a/src/lib/formats/mfi_dsk.h +++ b/src/lib/formats/mfi_dsk.h @@ -38,9 +38,6 @@ private: struct entry { unsigned int offset, compressed_size, uncompressed_size; }; - - void advance(const UINT32 *trackbuf, UINT32 &cur_cell, UINT32 cell_count, UINT32 time); - UINT32 get_next_edge(const UINT32 *trackbuf, UINT32 cur_cell, UINT32 cell_count); }; extern const floppy_format_type FLOPPY_MFI_FORMAT; |