Previous 199869 Revisions Next

r31567 Saturday 9th August, 2014 at 12:36:09 UTC by O. Galibert
floppy: Handle half and quarter tracks [O. Galibert]
[src/emu/imagedev]floppy.c floppy.h
[src/emu/machine]wozfdc.c wozfdc.h
[src/lib/formats]flopimg.c flopimg.h mfi_dsk.c mfi_dsk.h

trunk/src/emu/machine/wozfdc.c
r31566r31567
7272
7373void wozfdc_device::device_reset()
7474{
75   current_cyl = 0;
7675   floppy = NULL;
7776   active = MODE_IDLE;
7877   phases = 0x00;
r31566r31567
199198   else
200199      phases &= ~(1 << ph);
201200
202   if(floppy && active) {
203      int cph = current_cyl & 3;
204      int pcyl = current_cyl;
205      if(!(phases & (1 << cph))) {
206         if(current_cyl < 70 && (phases & (1 << ((cph+1) & 3))))
207            current_cyl++;
208         if(current_cyl && (phases & (1 << ((cph+3) & 3))))
209            current_cyl--;
210         if(current_cyl != pcyl && !(current_cyl & 1)) {
211            floppy->dir_w(current_cyl < pcyl);
212            floppy->stp_w(true);
213            floppy->stp_w(false);
214            floppy->stp_w(true);
215         }
216      }
217   }
201   if(floppy && active)
202      floppy->seek_phase_w(phases);
218203}
219204
220205void wozfdc_device::control(int offset)
r31566r31567
238223      case 0x9:
239224         switch(active) {
240225         case MODE_IDLE:
241            if(floppy) {
226            if(floppy)
242227               floppy->mon_w(false);
243               current_cyl = floppy->get_cyl() << 1;
244            }
245228            active = MODE_ACTIVE;
246229            if(floppy)
247230               lss_start();
trunk/src/emu/machine/wozfdc.h
r31566r31567
6060   };
6161
6262   const UINT8 *m_rom_p6;
63   UINT8 current_cyl, last_6502_write;
63   UINT8 last_6502_write;
6464   bool mode_write, mode_load;
6565   int active;
6666   UINT8 phases;
trunk/src/emu/imagedev/floppy.c
r31566r31567
273273   mon = 1;
274274
275275   cyl = 0;
276   subcyl = 0;
276277   ss  = 0;
277278   stp = 1;
278279   wpt = 0;
r31566r31567
535536            if (dskchg==0) dskchg = 1;
536537         }
537538      }
539      subcyl = 0;
538540   }
539541}
540542
543void floppy_image_device::seek_phase_w(int phases)
544{
545   int cur_pos = (cyl << 2) | subcyl;
546   int req_pos;
547   switch(phases) {
548   case 0x1: req_pos = 0; break;
549   case 0x3: req_pos = 1; break;
550   case 0x2: req_pos = 2; break;
551   case 0x6: req_pos = 3; break;
552   case 0x4: req_pos = 4; break;
553   case 0xc: req_pos = 5; break;
554   case 0x8: req_pos = 6; break;
555   case 0x9: req_pos = 7; break;
556   default: return;
557   }
558
559   // Opposite phase, don't move
560   if(((cur_pos ^ req_pos) & 7) == 4)
561      return;
562
563   int next_pos = (cur_pos & ~7) | req_pos;
564   if(next_pos < cur_pos-4)
565      next_pos += 8;
566   else if(next_pos > cur_pos+4)
567      next_pos -= 8;
568   if(next_pos < 0)
569      next_pos = 0;
570   else if(next_pos > (tracks-1)*4)
571      next_pos = (tracks-1)*4;
572   cyl = next_pos >> 2;
573   subcyl = next_pos & 3;
574
575   if(TRACE_STEP && (next_pos != cur_pos))
576      logerror("%s: track %d.%d\n", tag(), cyl, subcyl);
577
578   /* Update disk detection if applicable */
579   if (exists())
580      if (dskchg==0)
581         dskchg = 1;
582}
583
541584int floppy_image_device::find_index(UINT32 position, const UINT32 *buf, int buf_size)
542585{
543586   int spos = (buf_size >> 1)-1;
trunk/src/emu/imagedev/floppy.h
r31566r31567
105105   bool ss_r() { return ss; }
106106   bool twosid_r();
107107
108   void seek_phase_w(int phases);
108109   void stp_w(int state);
109110   void dir_w(int state) { dir = state; }
110111   void ss_w(int state) { ss = state; }
r31566r31567
164165
165166   attotime revolution_start_time, rev_time;
166167   UINT32 revolution_count;
167   int cyl;
168   int cyl, subcyl;
168169
169170   bool image_dirty;
170171   int ready_counter;
trunk/src/lib/formats/mfi_dsk.c
r31566r31567
88  Mess floppy image structure:
99
1010  - header with signature, number of cylinders, number of heads.  Min
11    track and min head are considered to always be 0.
11    track and min head are considered to always be 0.  The two top bits
12    of the cylinder count is the resolution: 0=tracks, 1=half tracks,
13    2=quarter tracks.
1214
13  - vector of track descriptions, looping on cylinders and sub-lopping
14    on heads, each description composed of:
15  - vector of track descriptions, looping on cylinders with the given
16    resolution and sub-lopping on heads, each description composed of:
1517    - offset of the track data in bytes from the start of the file
1618    - size of the compressed track data in bytes (0 for unformatted)
1719    - size of the uncompressed track data in bytes (0 for unformatted)
r31566r31567
9799
98100   io_generic_read(io, &h, 0, sizeof(header));
99101   if(memcmp( h.sign, sign, 16 ) == 0 &&
100      h.cyl_count <= 160 &&
102      (h.cyl_count & CYLINDER_MASK) <= 84 &&
103      (h.cyl_count >> RESOLUTION_SHIFT) < 3 &&
101104      h.head_count <= 2 &&
102105      (!form_factor || !h.form_factor || h.form_factor == form_factor))
103106      return 100;
r31566r31567
107110bool mfi_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
108111{
109112   header h;
110   entry entries[84*2];
113   entry entries[84*2*4];
111114   io_generic_read(io, &h, 0, sizeof(header));
112   io_generic_read(io, &entries, sizeof(header), h.cyl_count*h.head_count*sizeof(entry));
115   int resolution = h.cyl_count >> RESOLUTION_SHIFT;
116   h.cyl_count &= CYLINDER_MASK;
117   io_generic_read(io, &entries, sizeof(header), (h.cyl_count << resolution)*h.head_count*sizeof(entry));
113118
114119   image->set_variant(h.variant);
115120
116121   dynamic_buffer compressed;
117122
118123   entry *ent = entries;
119   for(unsigned int cyl=0; cyl != h.cyl_count; cyl++)
124   for(unsigned int cyl=0; cyl <= (h.cyl_count - 1) << 2; cyl += 4 >> resolution)
120125      for(unsigned int head=0; head != h.head_count; head++) {
121         image->set_write_splice_position(cyl, head, ent->write_splice);
126         image->set_write_splice_position(cyl >> 2, head, ent->write_splice, cyl & 3);
122127
123128         if(ent->uncompressed_size == 0) {
124129            // Unformatted track
125            image->set_track_size(cyl, head, 0);
130            image->set_track_size(cyl >> 2, head, 0, cyl & 3);
126131            ent++;
127132            continue;
128133         }
r31566r31567
132137         io_generic_read(io, compressed, ent->offset, ent->compressed_size);
133138
134139         unsigned int cell_count = ent->uncompressed_size/4;
135         image->set_track_size(cyl, head, cell_count);
136         UINT32 *trackbuf = image->get_buffer(cyl, head);
140         image->set_track_size(cyl >> 2, head, cell_count, cyl & 3);
141         UINT32 *trackbuf = image->get_buffer(cyl >> 2, head, cyl & 3);
137142
138143         uLongf size = ent->uncompressed_size;
139144         if(uncompress((Bytef *)trackbuf, &size, compressed, ent->compressed_size) != Z_OK)
r31566r31567
158163{
159164   int tracks, heads;
160165   image->get_actual_geometry(tracks, heads);
166   int resolution = image->get_resolution();
161167   int max_track_size = 0;
162   for(int track=0; track<tracks; track++)
168   for(int track=0; track <= (tracks-1) << 2; track += 4 >> resolution)
163169      for(int head=0; head<heads; head++) {
164         int tsize = image->get_track_size(track, head);
170         int tsize = image->get_track_size(track >> 2, head, track & 3);
165171         if(tsize > max_track_size)
166172               max_track_size = tsize;
167173      }
168174
169175   header h;
170   entry entries[84*2];
176   entry entries[84*2*4];
171177   memcpy(h.sign, sign, 16);
172   h.cyl_count = tracks;
178   h.cyl_count = tracks | (resolution << RESOLUTION_SHIFT);
173179   h.head_count = heads;
174180   h.form_factor = image->get_form_factor();
175181   h.variant = image->get_variant();
r31566r31567
178184
179185   memset(entries, 0, sizeof(entries));
180186
181   int pos = sizeof(header) + tracks*heads*sizeof(entry);
187   int pos = sizeof(header) + (tracks << resolution)*heads*sizeof(entry);
182188   int epos = 0;
183189   UINT32 *precomp = global_alloc_array(UINT32, max_track_size);
184190   UINT8 *postcomp = global_alloc_array(UINT8, max_track_size*4 + 1000);
185191
186   for(int track=0; track<tracks; track++)
192   for(int track=0; track <= (tracks-1) << 2; track += 4 >> resolution)
187193      for(int head=0; head<heads; head++) {
188         int tsize = image->get_track_size(track, head);
194         int tsize = image->get_track_size(track >> 2, head, track & 3);
189195         if(!tsize) {
190196            epos++;
191197            continue;
192198         }
193199
194         memcpy(precomp, image->get_buffer(track, head), tsize*4);
200         memcpy(precomp, image->get_buffer(track >> 2, head, track & 3), tsize*4);
195201         for(int j=0; j<tsize-1; j++)
196202            precomp[j] = (precomp[j] & floppy_image::MG_MASK) |
197203               ((precomp[j+1] & floppy_image::TIME_MASK) -
r31566r31567
206212         entries[epos].offset = pos;
207213         entries[epos].uncompressed_size = tsize*4;
208214         entries[epos].compressed_size = csize;
209         entries[epos].write_splice = image->get_write_splice_position(track, head);
215         entries[epos].write_splice = image->get_write_splice_position(track >> 2, head, track & 3);
210216         epos++;
211217
212218         io_generic_write(io, postcomp, pos, csize);
213219         pos += csize;
214220      }
215221
216   io_generic_write(io, entries, sizeof(header), tracks*heads*sizeof(entry));
222   io_generic_write(io, entries, sizeof(header), (tracks << resolution)*heads*sizeof(entry));
217223   return true;
218224}
219225
trunk/src/lib/formats/mfi_dsk.h
r31566r31567
2626      MG_A      = (0 << MG_SHIFT),
2727      MG_B      = (1 << MG_SHIFT),
2828      MG_N      = (2 << MG_SHIFT),
29      MG_D      = (3 << MG_SHIFT)
29      MG_D      = (3 << MG_SHIFT),
30
31      RESOLUTION_SHIFT = 30,
32      CYLINDER_MASK = 0x3fffffff
3033   };
3134
3235   static const char sign[16];
trunk/src/lib/formats/flopimg.c
r31566r31567
947947   form_factor = _form_factor;
948948   variant = 0;
949949
950   memset(cell_data, 0, sizeof(cell_data));
951   memset(track_size, 0, sizeof(track_size));
952   memset(track_alloc_size, 0, sizeof(track_alloc_size));
953   memset(write_splice, 0, sizeof(write_splice));
950   track_array.resize(tracks*4+1);
951   for(int i=0; i<tracks*4+1; i++)
952      track_array[i].resize(heads);
954953}
955954
956955floppy_image::~floppy_image()
957956{
958   for (int i=0;i<MAX_FLOPPY_TRACKS;i++) {
959      for (int j=0;j<MAX_FLOPPY_HEADS;j++) {
960         global_free_array(cell_data[i][j]);
961      }
962   }
963957}
964958
965959void floppy_image::get_maximal_geometry(int &_tracks, int &_heads)
r31566r31567
970964
971965void floppy_image::get_actual_geometry(int &_tracks, int &_heads)
972966{
973   int maxt = tracks-1, maxh = heads-1;
967   int maxt = tracks*4, maxh = heads-1;
974968
975969   while(maxt >= 0) {
976970      for(int i=0; i<=maxh; i++)
r31566r31567
987981         maxh--;
988982      }
989983   head_done:
990   _tracks = maxt+1;
984   _tracks = (maxt+4)/4;
991985   _heads = maxh+1;
992986}
993987
988int floppy_image::get_resolution() const
989{
990   int mask = 0;
991   for(int i=0; i<tracks*4+1; i++)
992      for(int j=0; j<heads; j++)
993         if(track_array[i][j].track_size)
994            mask |= 1 << (i & 3);
995   if(mask & 0xa)
996      return 2;
997   if(mask & 0x4)
998      return 1;
999   return 0;
1000}
1001
9941002void floppy_image::ensure_alloc(int track, int head)
9951003{
996   if(track_size[track][head] > track_alloc_size[track][head]) {
997      UINT32 new_size = track_size[track][head]*11/10;
998      UINT32 *new_array = global_alloc_array(UINT32, new_size);
999      if(track_alloc_size[track][head]) {
1000         memcpy(new_array, cell_data[track][head], track_alloc_size[track][head]*4);
1001         global_free_array(cell_data[track][head]);
1002      }
1003      cell_data[track][head] = new_array;
1004      track_alloc_size[track][head] = new_size;
1005   }
1004   track_info &tr = track_array[track][head];
1005   if(tr.track_size > tr.cell_data.count())
1006      tr.cell_data.resize_keep_and_clear_new(tr.track_size);
10061007}
10071008
10081009const char *floppy_image::get_variant_name(UINT32 form_factor, UINT32 variant)
trunk/src/lib/formats/flopimg.h
r31566r31567
1212#include "osdcore.h"
1313#include "ioprocs.h"
1414#include "opresolv.h"
15#include "coretmpl.h"
1516
1617#ifndef LOG_FORMATS
1718#define LOG_FORMATS if (0) printf
r31566r31567
637638//! form factor can be physically inserted in a reader that handles
638639//! it.  The second half indicates the variants which are usually
639640//! detectable by the reader, such as density and number of sides.
641//!
642//! Resolution is quarter-track.  The optional subtrack parameter is
643//! 0-3:
644//! - 0 = Track itself
645//! - 1 = 1st quarter track
646//! - 2 = Half track
647//! - 3 = 2nd quarter track
640648
641
642649class floppy_image
643650{
644651public:
r31566r31567
682689      M2FM = 0x4D32464D, //!< "M2FM", modified modified frequency modulation
683690   };
684691
685// construction/destruction
692   // construction/destruction
686693
687694
688695   //! floppy_image constructor
r31566r31567
703710
704711   /*!
705712     @param track
713     @param subtrack
706714     @param head
707715     @param size size of this track
708716   */
709   void set_track_size(int track, int head, UINT32 size) { track_size[track][head] = size; ensure_alloc(track, head); }
717   void set_track_size(int track, int head, UINT32 size, int subtrack = 0) { track_array[track*4+subtrack][head].track_size = size; ensure_alloc(track*4+subtrack, head); }
710718
711719   /*!
712     @param track track number
720     @param track
721     @param subtrack
713722     @param head head number
714723     @return a pointer to the data buffer for this track and head
715724   */
716   UINT32 *get_buffer(int track, int head) { return cell_data[track][head]; }
725   UINT32 *get_buffer(int track, int head, int subtrack = 0) { return track_array[track*4+subtrack][head].cell_data; }
726
717727   //! @return the track size
718728   //! @param track
729   //! @param subtrack
719730   //! @param head
720   UINT32 get_track_size(int track, int head) { return track_size[track][head]; }
731   UINT32 get_track_size(int track, int head, int subtrack = 0) { return track_array[track*4+subtrack][head].track_size; }
721732
722733   //! Sets the write splice position.
723734   //! The "track splice" information indicates where to start writing
r31566r31567
727738   //! representation is the angular position relative to the index.
728739
729740   /*! @param track
741       @param subtrack
730742       @param head
731743       @param pos the position
732744   */
733   void set_write_splice_position(int track, int head, UINT32 pos) { write_splice[track][head] = pos; }
745   void set_write_splice_position(int track, int head, UINT32 pos, int subtrack = 0) { track_array[track*4+subtrack][head].write_splice = pos; }
734746   //! @return the current write splice position.
735   UINT32 get_write_splice_position(int track, int head) const { return write_splice[track][head]; }
747   UINT32 get_write_splice_position(int track, int head, int subtrack = 0) const { return track_array[track*4+subtrack][head].write_splice; }
736748   //! @return the maximal geometry supported by this format.
737749   void get_maximal_geometry(int &tracks, int &heads);
738750
739751   //! @return the current geometry of the loaded image.
740752   void get_actual_geometry(int &tracks, int &heads);
741753
754   //! @return the track resolution (0=full track, 1 = half-track, 2 = quarter track)
755   int get_resolution() const;
756
742757   //! Returns the variant name for the particular disk form factor/variant
743758   //! @param form_factor
744759   //! @param variant
r31566r31567
746761   static const char *get_variant_name(UINT32 form_factor, UINT32 variant);
747762
748763private:
749
750   enum {
751      MAX_FLOPPY_HEADS = 2,
752      MAX_FLOPPY_TRACKS = 84
753   };
754
755764   int tracks, heads;
756765
757766   UINT32 form_factor, variant;
758767
759   UINT32 *cell_data[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
760   UINT32 track_size[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
761   UINT32 track_alloc_size[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
762   UINT32 write_splice[MAX_FLOPPY_TRACKS][MAX_FLOPPY_HEADS];
768   struct track_info {
769      dynamic_array<UINT32> cell_data;
770      UINT32 track_size;
771      UINT32 write_splice;
763772
773      track_info() { track_size = write_splice = 0; }
774   };
775
776   // track number multiplied by 4 then head
777   // last array size may be bigger than actual track size
778   dynamic_array<dynamic_array<track_info> > track_array;
779
764780   void ensure_alloc(int track, int head);
765781};
766782

Previous 199869 Revisions Next


© 1997-2024 The MAME Team