ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/cwcbm/common.c
(Generate patch)

Comparing cwcbm/common.c (file contents):
Revision 1.1 by cebix, 2004-01-07T16:53:58Z vs.
Revision 1.2 by cebix, 2004-01-10T14:05:59Z

# Line 8 | Line 8
8   #include "common.h"
9  
10  
11 < /* 1541 crystal frequency (16 MHz) */
12 < #define CRYSTAL_FREQ 16000000
11 > /* Effective crystal frequencies */
12 > #define CRYSTAL_FREQ_1541 4000000 // 4 MHz
13 > #define CRYSTAL_FREQ_8050 6000000 // 6 MHz
14  
15 < /* 1541 RPM */
15 > /* CBM drive RPM */
16   #define NOMINAL_RPM 300
17  
18   /* Catweasel frequency (7 MHz) */
19   #define CW_FREQ 7080500.0
20  
21 < /* Bit rate for each speed zone */
22 < const int bps[4] = {
23 <        CRYSTAL_FREQ / 16 / 4, CRYSTAL_FREQ / 15 / 4,
24 <        CRYSTAL_FREQ / 14 / 4, CRYSTAL_FREQ / 13 / 4
21 >
22 > /* 1541 disk format */
23 > static const int bps_1541[4] = {
24 >        CRYSTAL_FREQ_1541 / 16, CRYSTAL_FREQ_1541 / 15,
25 >        CRYSTAL_FREQ_1541 / 14, CRYSTAL_FREQ_1541 / 13
26   };
27  
28 < /* Standard speeds for tracks */
27 < const int std_speed[NUM_TRACKS + 1] = {
28 > static const int std_speed_1541[36] = {
29          0,
30          3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
31          2, 2, 2, 2, 2, 2, 2,
# Line 32 | Line 33 | const int std_speed[NUM_TRACKS + 1] = {
33          0, 0, 0, 0, 0
34   };
35  
36 < /* Number of sectors per track, for all tracks */
36 < const int num_sectors[NUM_TRACKS + 1] = {
36 > static const int num_sectors_1541[36] = {
37          0,
38          21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,
39          19,19,19,19,19,19,19,
# Line 41 | Line 41 | const int num_sectors[NUM_TRACKS + 1] =
41          17,17,17,17,17
42   };
43  
44 + static const struct format_t format_1541 = {
45 +        1,               // sides
46 +        35,              // tracks_per_side
47 +        bps_1541,        // bps
48 +        std_speed_1541,  // std_speed
49 +        num_sectors_1541 // num_sectors
50 + };
51 +
52 + /* 8050 disk format */
53 + static const int bps_8050[4] = {
54 +        CRYSTAL_FREQ_8050 / 16, CRYSTAL_FREQ_8050 / 15,
55 +        CRYSTAL_FREQ_8050 / 14, CRYSTAL_FREQ_8050 / 13
56 + };
57 +
58 + static const int std_speed_8050[78] = {
59 +        0,
60 +        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
61 +        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
62 +        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
63 +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
64 + };
65 +
66 + static const int num_sectors_8050[78] = {
67 +        0,
68 +        29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
69 +        27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
70 +        25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
71 +        23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23
72 + };
73 +
74 + static const struct format_t format_8050 = {
75 +        1,               // sides
76 +        77,              // tracks_per_side
77 +        bps_8050,        // bps
78 +        std_speed_8050,  // std_speed
79 +        num_sectors_8050 // num_sectors
80 + };
81 +
82 + /* 8250 disk format */
83 + static const int std_speed_8250[155] = {
84 +        0,
85 +        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
86 +        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
87 +        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
88 +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
89 +        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
90 +        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
91 +        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
92 +        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
93 + };
94 +
95 + static const int num_sectors_8250[155] = {
96 +        0,
97 +        29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
98 +        27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
99 +        25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
100 +        23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
101 +        29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
102 +        27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
103 +        25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
104 +        23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23
105 + };
106 +
107 + static const struct format_t format_8250 = {
108 +        2,               // sides
109 +        77,              // tracks_per_side
110 +        bps_8050,        // bps
111 +        std_speed_8250,  // std_speed
112 +        num_sectors_8250 // num_sectors
113 + };
114 +
115 + /* Selected format */
116 + const struct format_t *format = NULL;
117 +
118  
119   /* Command line arguments */
120   int drive_num = 0;
121   int drive_rpm = 360;
122   int drive_40tracks = 0;
123 + int steps_per_track = 1;
124   const char *file_name;
125  
126  
# Line 64 | Line 139 | int thresh_table[3] = {0, 0, 0};
139   unsigned char track_buf[MAX_SECTORS * SECTOR_SIZE];
140  
141  
67 /* Delay specified number of milliseconds */
68 void msdelay(int ms)
69 {
70        usleep(ms * 1000);
71 }
72
73
74 /* Set speed zone and tables */
75 static void set_zone(int track)
76 {
77        int zone = std_speed[track];
78        clock_table[0] = 0;
79        clock_table[1] = CW_FREQ * NOMINAL_RPM * 1 / (bps[zone] * drive_rpm);
80        clock_table[2] = CW_FREQ * NOMINAL_RPM * 2 / (bps[zone] * drive_rpm);
81        clock_table[3] = CW_FREQ * NOMINAL_RPM * 3 / (bps[zone] * drive_rpm);
82        thresh_table[0] = (clock_table[0] + clock_table[1]) / 2;
83        thresh_table[1] = (clock_table[1] + clock_table[2]) / 2;
84        thresh_table[2] = (clock_table[2] + clock_table[3]) / 2;
85 }
86
87
88 /* Seek to given CBM track (1..35) and select correct side and speed zone */
89 void seek_to(int drive, int track)
90 {
91        // Set speed zone and tables
92        set_zone(track);
93
94        // Seek to track
95        catweasel_seek(c.drives + drive, (track - 1) * (drive_40tracks ? 1 : 2));
96        msdelay(20);
97 }
98
99
142   /* Print usage information */
143   static void usage(const char *prgname)
144   {
# Line 107 | Line 149 | static void usage(const char *prgname)
149                  "  -h | --help      this text\n"
150                  "  -p | --port n    Catweasel I/O port address (hex, required)\n"
151                  "  -d | --drive n   drive number (0 or 1)\n"
152 +                "  -f | --format n  disk format type (1541, 8050, or 8250)\n"
153                  "  -4 | --40tracks  assume 300RPM 40-track drive\n",
154                  prgname
155          );
# Line 121 | Line 164 | void parse_args(int argc, char **argv)
164                  {"help", 0, 0, 'h'},
165                  {"port", 1, 0, 'p'},
166                  {"drive", 1, 0, 'd'},
167 +                {"format", 1, 0, 'f'},
168                  {"40tracks", 0, 0, '4'},
169                  {NULL, 0, 0, 0}
170          };
171  
172 +        int format_type = 0;
173 +
174          // Init Catweasel struct
175          memset(&c, 0, sizeof(c));
176          c.msdelay = msdelay;
# Line 132 | Line 178 | void parse_args(int argc, char **argv)
178          // Parse arguments
179          for (;;) {
180                  int ch;
181 <                if ((ch = getopt_long(argc, argv, "hp:d:4", long_opts, NULL)) == -1)
181 >                if ((ch = getopt_long(argc, argv, "hp:d:f:4", long_opts, NULL)) == -1)
182                          break;
183  
184                  switch (ch) {
# Line 146 | Line 192 | void parse_args(int argc, char **argv)
192                                  if (drive_num < 0 || drive_num > 1)
193                                          usage(argv[0]);
194                                  break;
195 +                        case 'f':
196 +                                format_type = atoi(optarg);
197 +                                if (format_type == 1541 || format_type == 8050 || format_type == 8250)
198 +                                        select_format(format_type);
199 +                                else
200 +                                        usage(argv[0]);
201 +                                break;
202                          case '4':
203                                  drive_rpm = 300;
204                                  drive_40tracks = 1;
# Line 165 | Line 218 | void parse_args(int argc, char **argv)
218          // Check for consistency
219          if (c.iobase == 0)
220                  usage(argv[0]);
221 +        if (format_type == 0)
222 +                select_format(1541);
223 +        if (format->tracks_per_side >= 40 && drive_40tracks) {
224 +                fprintf(stderr, "Can't use 80 track disk format on 40 track drive\n");
225 +                exit(1);
226 +        }
227 +        if (format->tracks_per_side < 40 && !drive_40tracks)
228 +                steps_per_track = 2; // double step
229  
230          // Set Catweasel type
231          if (c.iobase < 0x1000)
# Line 186 | Line 247 | void ioport_access(void)
247   }
248  
249  
250 + /* Delay specified number of milliseconds */
251 + void msdelay(int ms)
252 + {
253 +        usleep(ms * 1000);
254 + }
255 +
256 +
257 + /* Select disk format */
258 + void select_format(int type)
259 + {
260 +        switch (type) {
261 +                case 1541:
262 +                        format = &format_1541;
263 +                        break;
264 +                case 8050:
265 +                        format = &format_8050;
266 +                        break;
267 +                case 8250:
268 +                        format = &format_8250;
269 +                        break;
270 +                default:
271 +                        fprintf(stderr, "Invalid disk format type\n");
272 +                        exit(1);
273 +        }
274 + }
275 +
276 +
277 + /* Set speed zone and tables */
278 + static void set_zone(int track)
279 + {
280 +        int zone = format->std_speed[track];
281 +        int bps = format->bps[zone];
282 +        clock_table[0] = 0;
283 +        clock_table[1] = CW_FREQ * NOMINAL_RPM * 1 / (bps * drive_rpm);
284 +        clock_table[2] = CW_FREQ * NOMINAL_RPM * 2 / (bps * drive_rpm);
285 +        clock_table[3] = CW_FREQ * NOMINAL_RPM * 3 / (bps * drive_rpm);
286 +        thresh_table[0] = (clock_table[0] + clock_table[1]) / 2;
287 +        thresh_table[1] = (clock_table[1] + clock_table[2]) / 2;
288 +        thresh_table[2] = (clock_table[2] + clock_table[3]) / 2;
289 + }
290 +
291 +
292 + /* Seek to given CBM track (1..35) and select correct side and speed zone */
293 + void seek_to(int drive, int track)
294 + {
295 +        // Set speed zone and tables
296 +        set_zone(track);
297 +
298 +        // Seek to track
299 +        int cw_track = ((track - 1) % format->tracks_per_side) * steps_per_track;
300 + //cw_track -= 3;
301 + //if (cw_track < 0) cw_track = 0;
302 +        catweasel_seek(c.drives + drive, cw_track);
303 +        msdelay(20);
304 + }
305 +
306 +
307   /* Start drive */
308   void start_drive(int drive)
309   {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines