Previous 199869 Revisions Next

r20263 Monday 14th January, 2013 at 16:27:52 UTC by Curt Coder
(MESS) flopimg: Added support for Commodore GCR encoding. [Curt Coder]
(MESS) d64/g64 floppy modernization WIP. (nw)
[src/lib/formats]d64_dsk.c d64_dsk.h flopimg.c flopimg.h g64_dsk.c g64_dsk.h

trunk/src/lib/formats/flopimg.c
r20262r20263
11041104   return type == CRC_CCITT_START ||
11051105      type == CRC_CCITT_FM_START ||
11061106      type == CRC_AMIGA_START ||
1107      type == CRC_CBM_START ||
11071108      type == CRC_MACHEAD_START ||
11081109      type == CRC_END ||
11091110      type == SECTOR_LOOP_START ||
r20262r20263
11361137      case CRC_AMIGA_START:
11371138         crcs[desc[i].p1].type = CRC_AMIGA;
11381139         break;
1140      case CRC_CBM_START:
1141         crcs[desc[i].p1].type = CRC_CBM;
1142         break;
11391143      case CRC_MACHEAD_START:
11401144         crcs[desc[i].p1].type = CRC_MACHEAD;
11411145         break;
r20262r20263
11551159   case CRC_CCITT: return 32;
11561160   case CRC_CCITT_FM: return 32;
11571161   case CRC_AMIGA: return 64;
1162   case CRC_CBM: return 10;
11581163   case CRC_MACHEAD: return 8;
11591164   default: return 0;
11601165   }
r20262r20263
12151220   }
12161221}
12171222
1223void floppy_image_format_t::gcr5_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size)
1224{
1225   UINT32 e0 = gcr5fw_tb[val >> 4];
1226   UINT32 e1 = gcr5fw_tb[val & 0x0f];
1227   raw_w(buffer, offset, 5, e0, size);
1228   raw_w(buffer, offset, 5, e1, size);
1229}
1230
12181231void floppy_image_format_t::fixup_crc_amiga(UINT32 *buffer, const gen_crc_info *crc)
12191232{
12201233   UINT16 res = 0;
r20262r20263
12271240   mfm_w(buffer, offset, 16, res);
12281241}
12291242
1243void floppy_image_format_t::fixup_crc_cbm(UINT32 *buffer, const gen_crc_info *crc)
1244{
1245   UINT8 v = 0;
1246   for(int o = crc->start; o < crc->end; o+=10) {
1247      v = v ^ (gcr5bw_tb[bitn_r(buffer, o, 5)] << 4);
1248      v = v ^ gcr5bw_tb[bitn_r(buffer, o+5, 5)];
1249   }
1250   int offset = crc->write;
1251   gcr5_w(buffer, offset, 8, v);
1252}
1253
12301254UINT16 floppy_image_format_t::calc_crc_ccitt(const UINT32 *buffer, int start, int end)
12311255{
12321256   UINT32 res = 0xffff;
r20262r20263
12681292      if(crcs[i].write != -1) {
12691293         switch(crcs[i].type) {
12701294         case CRC_AMIGA:   fixup_crc_amiga(buffer, crcs+i); break;
1295         case CRC_CBM:     fixup_crc_cbm(buffer, crcs+i); break;
12711296         case CRC_CCITT:   fixup_crc_ccitt(buffer, crcs+i); break;
12721297         case CRC_CCITT_FM:fixup_crc_ccitt_fm(buffer, crcs+i); break;
12731298         case CRC_MACHEAD: fixup_crc_machead(buffer, crcs+i); break;
r20262r20263
13651390         mfm_w(buffer, offset, desc[index].p2, desc[index].p1);
13661391         break;
13671392
1393      case GCR5:
1394         for(int i=0; i<desc[index].p2; i++)
1395            gcr5_w(buffer, offset, 8, desc[index].p1);
1396         break;
1397
13681398      case RAW:
13691399         for(int i=0; i<desc[index].p2; i++)
13701400            raw_w(buffer, offset, 16, desc[index].p1);
13711401         break;
13721402
1403      case RAWBYTE:
1404         for(int i=0; i<desc[index].p2; i++)
1405            raw_w(buffer, offset, 8, desc[index].p1);
1406         break;
1407
13731408      case RAWBITS:
13741409         raw_w(buffer, offset, desc[index].p2, desc[index].p1);
13751410         break;
r20262r20263
14101445         fm_w(buffer, offset, 8, sect[sector_idx].sector_id);
14111446         break;
14121447
1448      case SECTOR_ID_GCR5:
1449         gcr5_w(buffer, offset, 8, sect[sector_idx].sector_id);
1450         break;
1451
14131452      case SECTOR_ID_GCR6:
14141453         raw_w(buffer, offset, 8, gcr6fw_tb[sect[sector_idx].sector_id]);
14151454         break;
r20262r20263
14821521         break;
14831522
14841523      case CRC_AMIGA_START:
1524      case CRC_CBM_START:
14851525      case CRC_CCITT_START:
14861526      case CRC_CCITT_FM_START:
14871527      case CRC_MACHEAD_START:
r20262r20263
15251565         break;
15261566      }
15271567
1568      case SECTOR_DATA_GCR5: {
1569         const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
1570         for(int i=0; i != csect->size; i++)
1571            gcr5_w(buffer, offset, 8, csect->data[i]);
1572         break;
1573      }
1574
15281575      case SECTOR_DATA_MAC: {
15291576         const desc_s *csect = sect + (desc[index].p1 >= 0 ? desc[index].p1 : sector_idx);
15301577         const UINT8 *data = csect->data;
r20262r20263
16961743   image->set_write_splice_position(track, head, splice_angular_pos);
16971744}
16981745
1746const UINT8 floppy_image_format_t::gcr5fw_tb[0x10] =
1747{
1748   0x0a, 0x0b, 0x12, 0x13, 0x0e, 0x0f, 0x16, 0x17,
1749   0x09, 0x19, 0x1a, 0x1b, 0x0d, 0x1d, 0x1e, 0x15
1750};
1751
1752const UINT8 floppy_image_format_t::gcr5bw_tb[0x20] =
1753{
1754   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1755   0x00, 0x08, 0x00, 0x01, 0x00, 0x0c, 0x04, 0x05,
1756   0x00, 0x00, 0x02, 0x03, 0x00, 0x0f, 0x06, 0x07,
1757   0x00, 0x09, 0x0a, 0x0b, 0x00, 0x0d, 0x0e, 0x00
1758};
1759
16991760const UINT8 floppy_image_format_t::gcr6fw_tb[0x40] =
17001761{
17011762   0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
trunk/src/lib/formats/flopimg.h
r20262r20263
301301      FM,                     //!< One byte in p1 to be fm-encoded, msb first, repeated p2 times
302302      MFM,                    //!< One byte in p1 to be mfm-encoded, msb first, repeated p2 times
303303      MFMBITS,                //!< A value of p2 bits in p1 to be mfm-encoded, msb first
304      GCR5,               //!< One byte in p1 to be gcr5-encoded, repeated p2 times
304305      RAW,                    //!< One 16 bits word in p1 to be written raw, msb first, repeated p2 times
306      RAWBYTE,                //!< One 8 bit byte in p1 to be written raw, msb first, repeated p2 times
305307      RAWBITS,                //!< A value of p2 bits in p1 to be copied as-is, msb first
306308      TRACK_ID,               //!< Track id byte, mfm-encoded
307309      TRACK_ID_FM,            //!< Track id byte, fm-encoded
r20262r20263
312314      TRACK_HEAD_ID_GCR6,     //!< Track id 7th bit + head, gc6-encoded
313315      SECTOR_ID,              //!< Sector id byte, mfm-encoded
314316      SECTOR_ID_FM,           //!< Sector id byte, fm-encoded
317      SECTOR_ID_GCR5,         //!< Sector id byte, gcr5-encoded
315318      SECTOR_ID_GCR6,         //!< Sector id byte, gcr6-encoded
316319      SIZE_ID,                //!< Sector size code on one byte [log2(size/128)], mfm-encoded
317320      SIZE_ID_FM,             //!< Sector size code on one byte [log2(size/128)], fm-encoded
r20262r20263
327330      SECTOR_DATA_FM,         //!< Sector data to fm-encode, which in p1, -1 for the current one per the sector id
328331      SECTOR_DATA_O,          //!< Sector data to mfm-encode, odd bits only, which in p1, -1 for the current one per the sector id
329332      SECTOR_DATA_E,          //!< Sector data to mfm-encode, even bits only, which in p1, -1 for the current one per the sector id
333      SECTOR_DATA_GCR5,      //!< Sector data to gcr5-encode, which in p1, -1 for the current one per the sector id
330334      SECTOR_DATA_MAC,        //!< Transformed sector data + checksum, mac style, id in p1, -1 for the current one per the sector id
331335
332336      CRC_CCITT_START,        //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
333337      CRC_CCITT_FM_START,     //!< Start a CCITT CRC calculation, with the usual x^16 + x^12 + x^5 + 1 (11021) polynomial, p1 = crc id
334338      CRC_AMIGA_START,        //!< Start an amiga checksum calculation, p1 = crc id
339      CRC_CBM_START,         //<! Start a CBM checksum calculation (xor of original data values, gcr5-encoded), p1 = crc id
335340      CRC_MACHEAD_START,      //!< Start of the mac gcr6 sector header checksum calculation (xor of pre-encode 6-bits values, gcr6-encoded)
336341      CRC_END,                //!< End the checksum, p1 = crc id
337342      CRC,                    //!< Write a checksum in the apporpriate format, p1 = crc id
r20262r20263
391396   void normalize_times(UINT32 *buffer, int bitlen);
392397
393398   // Some conversion tables for gcr
394   static const UINT8 gcr5fw_tb[0x20], gcr5bw_tb[0x100];
399   static const UINT8 gcr5fw_tb[0x10], gcr5bw_tb[0x20];
395400   static const UINT8 gcr6fw_tb[0x40], gcr6bw_tb[0x100];
396401
397402   // Some useful descriptions shared by multiple formats
r20262r20263
536541   void mfm_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
537542   //! MFM-encode every two bits and write
538543   void mfm_half_w(UINT32 *buffer, int &offset, int start_bit, UINT32 val, UINT32 size = 1000);
544   //! GCR5-encode and write a series of bits
545   void gcr5_w(UINT32 *buffer, int &offset, int n, UINT32 val, UINT32 size = 1000);
539546   //! GCR4 encode (Apple II sector header)
540547   UINT16 gcr4_encode(UINT8 va);
541548   //! GCR4 decode
r20262r20263
546553   void gcr6_decode(UINT8 e0, UINT8 e1, UINT8 e2, UINT8 e3, UINT8 &va, UINT8 &vb, UINT8 &vc);
547554
548555private:
549   enum { CRC_NONE, CRC_AMIGA, CRC_CCITT, CRC_CCITT_FM, CRC_MACHEAD };
556   enum { CRC_NONE, CRC_AMIGA, CRC_CBM, CRC_CCITT, CRC_CCITT_FM, CRC_MACHEAD };
550557   enum { MAX_CRC_COUNT = 64 };
551558
552559   //! Holds data used internally for generating CRCs.
r20262r20263
563570
564571   int crc_cells_size(int type) const;
565572   void fixup_crc_amiga(UINT32 *buffer, const gen_crc_info *crc);
573   void fixup_crc_cbm(UINT32 *buffer, const gen_crc_info *crc);
566574   void fixup_crc_ccitt(UINT32 *buffer, const gen_crc_info *crc);
567575   void fixup_crc_ccitt_fm(UINT32 *buffer, const gen_crc_info *crc);
568576   void fixup_crc_machead(UINT32 *buffer, const gen_crc_info *crc);
trunk/src/lib/formats/d64_dsk.c
r20262r20263
1/***************************************************************************
2
3    Copyright Olivier Galibert
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions are
8    met:
9
10        * Redistributions of source code must retain the above copyright
11          notice, this list of conditions and the following disclaimer.
12        * Redistributions in binary form must reproduce the above copyright
13          notice, this list of conditions and the following disclaimer in
14          the documentation and/or other materials provided with the
15          distribution.
16        * Neither the name 'MAME' nor the names of its contributors may be
17          used to endorse or promote products derived from this software
18          without specific prior written permission.
19
20    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
21    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
24    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    POSSIBILITY OF SUCH DAMAGE.
31
32****************************************************************************/
33
134/*********************************************************************
235
336    formats/d64_dsk.c
r20262r20263
235
36    Commodore 2040/8050/1541 sector disk image format
37
38*********************************************************************/
39
40#include "emu.h"
41#include "formats/d64_dsk.h"
42
43d64_format::d64_format()
44{
45}
46
47const char *d64_format::name() const
48{
49   return "d64";
50}
51
52const char *d64_format::description() const
53{
54   return "Commodore 2040/8050/1541 disk image";
55}
56
57const char *d64_format::extensions() const
58{
59   return "d64,d67,d71,d80,d82";
60}
61
62const d64_format::format d64_format::formats[] = {
63   { // d67, dos 1, 35 tracks
64      floppy_image::FF_525, floppy_image::SSSD, DOS_1, 690, 35, 1, 9, 8
65   },
66   { // d64, dos 2, 35 tracks
67      floppy_image::FF_525, floppy_image::SSSD, DOS_2, 683, 35, 1, 9, 8
68   },
69   { // d64, dos 2, 40 tracks
70      floppy_image::FF_525, floppy_image::SSSD, DOS_2, 768, 35, 1, 9, 8
71   },
72   { // d64, dos 2, 42 tracks
73      floppy_image::FF_525, floppy_image::SSSD, DOS_2, 802, 35, 1, 9, 8
74   },
75   { // d71, dos 2, 35 tracks, 2 heads
76      floppy_image::FF_525, floppy_image::DSSD, DOS_2, 683, 35, 2, 9, 8
77   },
78   { // d80, dos 2.5, 77 tracks
79      floppy_image::FF_525, floppy_image::SSQD, DOS_25, 2083, 77, 15, 9, 8
80   },
81   { // d82, dos 2.5, 77 tracks, 2 heads
82      floppy_image::FF_525, floppy_image::DSQD, DOS_25, 2083, 77, 15, 9, 8
83   },
84   {}
85};
86
87const UINT32 d64_format::dos1_cell_size[] =
88{
89   4000, // 16MHz/16/4
90   3750, // 16MHz/15/4
91   3500, // 16MHz/14/4
92   3250  // 16MHz/13/4
93};
94
95const UINT32 d64_format::dos25_cell_size[] =
96{
97   2667, // 12MHz/16/2
98   2500, // 12MHz/15/2
99   2333, // 12MHz/14/2
100   2167  // 12MHz/13/2
101};
102
103const int d64_format::dos1_sectors_per_track[] =
104{
105   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, //  1-17
106   20, 20, 20, 20, 20, 20, 20,                                         // 18-24
107   18, 18, 18, 18, 18, 18,                                             // 25-30
108   17, 17, 17, 17, 17,                                                 // 31-35
109   17, 17, 17, 17, 17,                                                 // 36-40
110   17, 17                                                              // 41-42
111};
112
113const int d64_format::dos2_sectors_per_track[] =
114{
115   21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, //  1-17
116   19, 19, 19, 19, 19, 19, 19,                                         // 18-24
117   18, 18, 18, 18, 18, 18,                                             // 25-30
118   17, 17, 17, 17, 17,                                                 // 31-35
119   17, 17, 17, 17, 17,                                                 // 36-40
120   17, 17                                                              // 41-42
121};
122
123const int d64_format::dos25_sectors_per_track[] =
124{
125   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, //  1-39
126   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
127   27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,                         // 40-53
128   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,                                     // 54-64
129   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,                             // 65-77
130   23, 23, 23, 23, 23, 23, 23                                                      // 78-84
131};
132
133const int d64_format::dos1_speed_zone[] =
134{
135   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, //  1-17
136   2, 2, 2, 2, 2, 2, 2,                               // 18-24
137   1, 1, 1, 1, 1, 1,                                  // 25-30
138   0, 0, 0, 0, 0,                                     // 31-35
139   0, 0, 0, 0, 0,                                     // 36-40
140   0, 0                                               // 41-42
141};
142
143const int d64_format::dos25_speed_zone[] =
144{
145   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, //  1-39
146   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
147   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,                   // 40-53
148   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,                            // 54-64
149   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,                      // 65-77
150   0, 0, 0, 0, 0, 0, 0                                         // 78-84
151};
152
153int d64_format::find_size(io_generic *io, UINT32 form_factor)
154{
155   int size = io_generic_size(io);
156   for(int i=0; formats[i].sector_count; i++) {
157      const format &f = formats[i];
158      if(size == f.sector_count*SECTOR_SIZE)
159         return i;
160      if(size == (f.sector_count*SECTOR_SIZE) + f.sector_count)
161         return i;
162   }
163   return -1;
164}
165
166int d64_format::identify(io_generic *io, UINT32 form_factor)
167{
168   int type = find_size(io, form_factor);
169
170   if(type != -1)
171      return 50;
172   return 0;
173}
174
175int d64_format::get_physical_track(const format &f, int track)
176{
177   int physical_track = 0;
178
179   switch (f.dos) {
180   case DOS_1: physical_track = track*2; break; // skip halftracks
181   case DOS_2: physical_track = track*2; break; // skip halftracks
182   case DOS_25: physical_track = track; break;
183   }
184
185   return physical_track;
186}
187
188void d64_format::get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 &id2)
189{
190   int offset = 0;
191
192   switch (f.dos) {
193   case DOS_1: offset = DOS1_DISK_ID_OFFSET; break;
194   case DOS_2: offset = DOS1_DISK_ID_OFFSET; break;
195   case DOS_25: offset = DOS25_DISK_ID_OFFSET; break;
196   }
197
198   UINT8 id[2];
199   io_generic_read(io, id, offset, 2);
200   id1 = id[0];
201   id2 = id[1];
202}
203
204UINT32 d64_format::get_cell_size(const format &f, int track)
205{
206   int cell_size = 0;
207
208   switch (f.dos) {
209   case DOS_1: cell_size = dos1_cell_size[dos1_speed_zone[track]]; break;
210   case DOS_2: cell_size = dos1_cell_size[dos1_speed_zone[track]]; break;
211   case DOS_25: cell_size = dos25_cell_size[dos25_speed_zone[track]]; break;
212   }
213
214   return cell_size;
215}
216
217int d64_format::get_sectors_per_track(const format &f, int track)
218{
219   int sector_count = 0;
220
221   switch (f.dos) {
222   case DOS_1: sector_count = dos1_sectors_per_track[track]; break;
223   case DOS_2: sector_count = dos1_sectors_per_track[track]; break;
224   case DOS_25: sector_count = dos25_sectors_per_track[track]; break;
225   }
226
227   return sector_count;
228}
229
230floppy_image_format_t::desc_e* d64_format::get_sector_desc(const format &f, int &current_size, int track, int sector_count, UINT8 id1, UINT8 id2, int gap_2)
231{
232   static floppy_image_format_t::desc_e desc[] = {
233      /* 00 */ { SECTOR_LOOP_START, 0, sector_count-1 },
234      /* 01 */ {   RAWBYTE, 0xff, 5 },
235      /* 02 */ {   GCR5, 0x08, 1 },
236      /* 03 */ {   CRC, 1 },
237      /* 04 */ {   CRC_CBM_START, 1 },
238      /* 05 */ {     SECTOR_ID_GCR5 },
239      /* 06 */ {     GCR5, track, 1 },
240      /* 07 */ {     GCR5, id2, 1 },
241      /* 08 */ {     GCR5, id1, 1 },
242      /* 09 */ {   CRC_END, 1 },
243      /* 10 */ {   GCR5, 0x0f, 2 },
244      /* 11 */ {   RAWBYTE, 0x55, f.gap_1 },
245      /* 12 */ {   RAWBYTE, 0xff, 5 },
246      /* 13 */ {   GCR5, 0x07, 1 },
247      /* 14 */ {   CRC_CBM_START, 2 },
248      /* 15 */ {     SECTOR_DATA_GCR5, -1 },
249      /* 16 */ {   CRC_END, 2 },
250      /* 17 */ {   CRC, 2 },
251      /* 18 */ {   GCR5, 0x00, 2 },
252      /* 19 */ {   RAWBYTE, 0x55, gap_2 },
253      /* 20 */ { SECTOR_LOOP_END },
254      /* 21 */ { RAWBYTE, 0x55, 0 },
255      /* 22 */ { RAWBITS, 0xffff, 0 },
256      /* 23 */ { END }
257   };
258
259   current_size = 40 + (1+1+4+2)*10 + (f.gap_1)*8 + 40 + (1+SECTOR_SIZE+1+2)*10 + gap_2*8;
260   current_size *= sector_count;
261
262   return desc;
263}
264
265void d64_format::build_sector_description(const format &f, UINT8 *sectdata, desc_s *sectors, int sector_count, UINT8 *errordata) const
266{
267   int cur_offset = 0;
268
269   for(int i=0; i<f.sector_count; i++) {
270      sectors[i].data = sectdata + cur_offset;
271      sectors[i].size = SECTOR_SIZE;
272      sectors[i].sector_id = i;
273      sectors[i].sector_info = errordata[i];
274
275      cur_offset += sectors[i].size;
276   }
277}
278
279bool d64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
280{
281   int type = find_size(io, form_factor);
282   if(type == -1)
283      return false;
284
285   const format &f = formats[type];
286   int size = io_generic_size(io);
287   UINT8 *img;
288
289   if(size == f.sector_count*SECTOR_SIZE) {
290      img = global_alloc_array(UINT8, size + f.sector_count);
291      memset(&img[size + f.sector_count], ERROR_00, f.sector_count);
292   }
293   else {
294      img = global_alloc_array(UINT8, size);
295   }
296
297   io_generic_read(io, img, 0, size);
298
299   floppy_image_format_t::desc_e *desc;
300   desc_s sectors[40];
301   int track_offset = 0, error_offset = 0;
302   
303   UINT8 id1 = 0, id2 = 0;
304   get_disk_id(f, io, id1, id2);
305
306   for(int head=0; head < f.head_count; head++) {
307      for(int track=0; track < f.track_count; track++) {
308         int current_size = 0;
309         int total_size = 200000000/get_cell_size(f, track);
310
311         int physical_track = get_physical_track(f, track);
312         int sector_count = get_sectors_per_track(f, track);
313         int track_size = sector_count*SECTOR_SIZE;
314
315         desc = get_sector_desc(f, current_size, track+1, sector_count, id1, id2, f.gap_2);
316
317         int remaining_size = total_size - current_size;
318         if(remaining_size < 0)
319            throw emu_fatalerror("d64_format: Incorrect track layout, max_size=%d, current_size=%d", total_size, current_size);
320         
321         // Fixup the end gap
322         desc[21].p2 = remaining_size / 8;
323         desc[22].p2 = remaining_size & 7;
324         desc[22].p1 >>= 8-(remaining_size & 7);
325
326         printf("track %u cursize %u totsize %u phystrack %u secnt %u trksize %u trkofs %u\n", track,current_size,total_size,physical_track,sector_count,track_size,track_offset);
327
328         build_sector_description(f, &img[track_offset], sectors, sector_count, &img[f.sector_count*SECTOR_SIZE + error_offset]);
329         generate_track(desc, physical_track, head, sectors, sector_count, total_size, image);
330         
331         track_offset += track_size;
332         error_offset += sector_count;
333      }
334   }
335
336   image->set_variant(f.variant);
337
338   return true;
339}
340
341bool d64_format::save(io_generic *io, floppy_image *image)
342{
343   return false;
344}
345
346bool d64_format::supports_save() const
347{
348   return false;
349}
350
351const floppy_format_type FLOPPY_D64_FORMAT = &floppy_image_format_creator<d64_format>;
352
353
354// ------ LEGACY -----
355
356
357/*********************************************************************
358
359    formats/d64_dsk.c
360
3361    Floppy format code for Commodore 1541/2040/8050 disk images
r20262r20263
8091167   for d80 & d82 they are at track 39 bytes 0x18 & 0x19
8101168   */
8111169   if (dos == DOS25)
1170   {
1171      printf("dos25 id offset %u\n", tag->track_offset[0][38] + 0x18);
8121172      floppy_image_read(floppy, id, tag->track_offset[0][38] + 0x18, 2);
1173   }
8131174   else
1175   {
1176      printf("dos2 id offset %u\n", tag->track_offset[0][38] + 0x18);
8141177      floppy_image_read(floppy, id, tag->track_offset[0][34] + 0xa2, 2);
1178   }
8151179
8161180   tag->id1 = id[0];
8171181   tag->id2 = id[1];
trunk/src/lib/formats/g64_dsk.c
r20262r20263
1/***************************************************************************
2
3    Copyright Olivier Galibert
4    All rights reserved.
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions are
8    met:
9
10        * Redistributions of source code must retain the above copyright
11          notice, this list of conditions and the following disclaimer.
12        * Redistributions in binary form must reproduce the above copyright
13          notice, this list of conditions and the following disclaimer in
14          the documentation and/or other materials provided with the
15          distribution.
16        * Neither the name 'MAME' nor the names of its contributors may be
17          used to endorse or promote products derived from this software
18          without specific prior written permission.
19
20    THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR
21    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23    DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT,
24    INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28    STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
29    IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30    POSSIBILITY OF SUCH DAMAGE.
31
32****************************************************************************/
33
134/*********************************************************************
235
336    formats/g64_dsk.c
r20262r20263
235
36    Commodore 1541 GCR disk image format
37
38*********************************************************************/
39
40#include "emu.h"
41#include "formats/g64_dsk.h"
42
43#define G64_FORMAT_HEADER    "GCR-1541"
44
45g64_format::g64_format()
46{
47}
48
49const char *g64_format::name() const
50{
51   return "g64";
52}
53
54const char *g64_format::description() const
55{
56   return "Commodore 1541 GCR disk image";
57}
58
59const char *g64_format::extensions() const
60{
61   return "g64";
62}
63
64const UINT32 g64_format::c1541_cell_size[] =
65{
66   4000, // 16MHz/16/4
67   3750, // 16MHz/15/4
68   3500, // 16MHz/14/4
69   3250  // 16MHz/13/4
70};
71
72int g64_format::identify(io_generic *io, UINT32 form_factor)
73{
74   UINT8 header[8];
75
76   io_generic_read(io, &header, 0, sizeof(header));
77   if ( memcmp( header, G64_FORMAT_HEADER, 8 ) ==0) {
78      return 100;
79   }
80   return 0;
81}
82
83bool g64_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
84{
85   int size = io_generic_size(io);
86   UINT8 *img = global_alloc_array(UINT8, size);
87   io_generic_read(io, img, 0, size);
88
89   int track_count = pick_integer_le(img, 9, 2);
90
91   int pos = 0x0c;
92   int track_offset[track_count];
93   for(int track = 0; track < track_count; track++) {
94      track_offset[track] = pick_integer_le(img, pos, 4);
95      pos += 4;
96   }
97
98   int speed_zone_offset[track_count];
99   for(int track = 0; track < track_count; track++) {
100      speed_zone_offset[track] = pick_integer_le(img, pos, 4);
101      pos += 4;
102   }
103
104   for(int track = 0; track < track_count; track++) {
105      int track_size = 0;
106      pos = track_offset[track];
107      if (pos > 0) {
108         track_size = pick_integer_le(img, pos, 2);
109         pos +=2;
110      }
111     
112      if (speed_zone_offset[track] > 3)
113         throw emu_fatalerror("g64_format: Unsupported variable speed zones on track %d", track);
114
115      UINT32 cell_size = c1541_cell_size[speed_zone_offset[track]];
116      int total_size = 200000000/cell_size;
117      UINT32 *buffer = global_alloc_array_clear(UINT32, total_size);
118      int offset = 0;
119
120      if (pos > 0) {
121         for (int i=0; i<track_size; i++) {
122            raw_w(buffer, offset, 8, img[pos++], cell_size);
123         }
124
125         if (offset >= total_size)
126            throw emu_fatalerror("g64_format: Too many cells for track %d", track);
127      }
128
129      generate_track_from_levels(track, 0, buffer, total_size, 0, image);
130      global_free(buffer);
131   }
132
133   image->set_variant(floppy_image::SSSD);
134
135   return true;
136}
137
138bool g64_format::save(io_generic *io, floppy_image *image)
139{
140   return false;
141}
142
143bool g64_format::supports_save() const
144{
145   return false;
146}
147
148const floppy_format_type FLOPPY_G64_FORMAT = &floppy_image_format_creator<g64_format>;
149
150
151// ------ LEGACY -----
152
153
154/*********************************************************************
155
156    formats/g64_dsk.c
157
3158    Floppy format code for Commodore 1541 GCR disk images
trunk/src/lib/formats/d64_dsk.h
r20262r20263
22
33    formats/d64_dsk.h
44
5    Floppy format code for Commodore 1541/2040/8050 disk images
5    Commodore 2040/8050/1541 sector disk image format
66
77*********************************************************************/
88
9#ifndef __D64_DSK__
10#define __D64_DSK__
9#ifndef D64_DSK_H_
10#define D64_DSK_H_
1111
1212#include "flopimg.h"
1313
14/***************************************************************************
15    PROTOTYPES
16***************************************************************************/
14class d64_format : public floppy_image_format_t {
15public:
16   struct format {
17      UINT32 form_factor;      // See floppy_image for possible values
18      UINT32 variant;          // See floppy_image for possible values
1719
20      int dos;
21      int sector_count;
22      int track_count;
23      int head_count;
24      int gap_1;
25      int gap_2;
26   };
27
28   d64_format();
29
30   virtual const char *name() const;
31   virtual const char *description() const;
32   virtual const char *extensions() const;
33
34   virtual int identify(io_generic *io, UINT32 form_factor);
35   virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
36   virtual bool save(io_generic *io, floppy_image *image);
37   virtual bool supports_save() const;
38
39protected:
40   enum
41   {
42      DOS_1,
43      DOS_2,
44      DOS_25
45   };
46
47   enum
48   {
49      ERROR_00 = 1,
50      ERROR_20,       /* header block not found */
51      ERROR_21,       /* no sync character */
52      ERROR_22,       /* data block not present */
53      ERROR_23,       /* checksum error in data block */
54      ERROR_24,       /* write verify (on format) UNIMPLEMENTED */
55      ERROR_25,       /* write verify error UNIMPLEMENTED */
56      ERROR_26,       /* write protect on UNIMPLEMENTED */
57      ERROR_27,       /* checksum error in header block */
58      ERROR_28,       /* write error UNIMPLEMENTED */
59      ERROR_29,       /* disk ID mismatch */
60      ERROR_74,       /* disk not ready (no device 1) UNIMPLEMENTED */
61   };
62
63   static const int SECTOR_SIZE = 256;
64
65   static const int DOS1_DISK_ID_OFFSET = 101144;
66   static const int DOS25_DISK_ID_OFFSET = 282136;
67
68   floppy_image_format_t::desc_e* get_sector_desc(const format &f, int &current_size, int track, int sector_count, UINT8 id1, UINT8 id2, int gap_2);
69
70   int find_size(io_generic *io, UINT32 form_factor);
71   int get_physical_track(const format &f, int track);
72   UINT32 get_cell_size(const format &f, int track);
73   int get_sectors_per_track(const format &f, int track);
74   void get_disk_id(const format &f, io_generic *io, UINT8 &id1, UINT8 &id2);
75   void build_sector_description(const format &f, UINT8 *sectdata, desc_s *sectors, int sector_count, UINT8 *errordata) const;
76
77   static const format formats[];
78
79   static const UINT32 dos1_cell_size[];
80   static const UINT32 dos25_cell_size[];
81   
82   static const int dos1_speed_zone[];
83   static const int dos25_speed_zone[];
84
85   static const int dos1_sectors_per_track[];
86   static const int dos2_sectors_per_track[];
87   static const int dos25_sectors_per_track[];
88};
89
90extern const floppy_format_type FLOPPY_D64_FORMAT;
91
92
1893FLOPPY_IDENTIFY( d64_dsk_identify );
1994FLOPPY_IDENTIFY( d67_dsk_identify );
2095FLOPPY_IDENTIFY( d71_dsk_identify );
trunk/src/lib/formats/g64_dsk.h
r20262r20263
22
33    formats/g64_dsk.h
44
5    Floppy format code for Commodore 1541 GCR disk images
5    Commodore 1541 GCR disk image format
66
77*********************************************************************/
88
9#ifndef __G64_DSK__
10#define __G64_DSK__
9#ifndef G64_DSK_H_
10#define G64_DSK_H_
1111
1212#include "flopimg.h"
13#include "imageutl.h"
1314
14/***************************************************************************
15    MACROS / CONSTANTS
16***************************************************************************/
15class g64_format : public floppy_image_format_t {
16public:
17   g64_format();
1718
19   virtual const char *name() const;
20   virtual const char *description() const;
21   virtual const char *extensions() const;
22
23   virtual int identify(io_generic *io, UINT32 form_factor);
24   virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
25   virtual bool save(io_generic *io, floppy_image *image);
26   virtual bool supports_save() const;
27
28protected:
29   static const UINT32 c1541_cell_size[];
30};
31
32extern const floppy_format_type FLOPPY_G64_FORMAT;
33
34
35// legacy
1836#define G64_SYNC_MARK           0x3ff       /* 10 consecutive 1-bits */
1937
2038#define G64_BUFFER_SIZE         16384
r20262r20263
3654   XTAL_12MHz/2/13     /* tracks 65-84 */
3755};
3856
39/***************************************************************************
40    PROTOTYPES
41***************************************************************************/
42
4357FLOPPY_IDENTIFY( g64_dsk_identify );
4458FLOPPY_CONSTRUCT( g64_dsk_construct );
4559

Previous 199869 Revisions Next


© 1997-2024 The MAME Team