Эх сурвалжийг харах

Support flippy drive access to cylinder -8

Keir Fraser 4 жил өмнө
parent
commit
b7ddee0bda

+ 1 - 0
inc/cdc_acm_protocol.h

@@ -84,6 +84,7 @@
 #define ACK_NO_BUS          8
 #define ACK_BAD_UNIT        9
 #define ACK_BAD_PIN        10
+#define ACK_BAD_CYLINDER   11
 
 
 /*

+ 14 - 3
scripts/greaseweazle/tools/seek.py

@@ -9,7 +9,7 @@
 
 description = "Seek to the specified cylinder."
 
-import sys
+import struct, sys
 
 from greaseweazle.tools import util
 from greaseweazle import error
@@ -29,16 +29,27 @@ def main(argv):
     parser.add_argument("--device", help="greaseweazle device name")
     parser.add_argument("--drive", type=util.drive_letter, default='A',
                         help="drive to read (A,B,0,1,2)")
+    parser.add_argument("--force", action="store_true",
+                        help="allow extreme cylinders with no prompt")
     parser.add_argument("cylinder", type=int, help="cylinder to seek")
     parser.description = description
     parser.prog += ' ' + argv[1]
     args = parser.parse_args(argv[2:])
 
+    try:
+        struct.pack('b', args.cylinder)
+    except struct.error:
+        raise error.Fatal("Cylinder %d out of range" % args.cylinder)
+    if not 0 <= args.cylinder <= 83 and not args.force:
+        answer = input("Seek to extreme cylinder %d, Yes/No? " % args.cylinder)
+        if answer != "Yes":
+            return
+    
     try:
         usb = util.usb_open(args.device)
         util.with_drive_selected(seek, usb, args, motor=False)
-    except USB.CmdError as error:
-        print("Command Failed: %s" % error)
+    except USB.CmdError as err:
+        print("Command Failed: %s" % err)
 
 
 if __name__ == "__main__":

+ 16 - 7
scripts/greaseweazle/usb.py

@@ -76,6 +76,7 @@ class Ack:
     NoBus           =  8
     BadUnit         =  9
     BadPin          = 10
+    BadCylinder     = 11
     str = {
         Okay: "Okay",
         BadCommand: "Bad Command",
@@ -86,8 +87,9 @@ class Ack:
         Wrprot: "Disk is Write Protected",
         NoUnit: "No drive unit selected",
         NoBus: "No bus type (eg. Shugart, IBM/PC) specified",
-        BadUnit: "Bad unit number",
-        BadPin: "Not a modifiable pin"
+        BadUnit: "Invalid unit number",
+        BadPin: "Not a modifiable pin",
+        BadCylinder: "Invalid cylinder"
     }
 
 
@@ -124,10 +126,17 @@ class CmdError(Exception):
         self.cmd = cmd
         self.code = code
 
+    def cmd_str(self):
+        return Cmd.str.get(self.cmd[0], "UnknownCmd")
+        
+    def errcode_str(self):
+        if self.code == Ack.BadCylinder:
+            s = Ack.str[Ack.BadCylinder]
+            return s + " %d" % struct.unpack('2Bb', self.cmd)[2]
+        return Ack.str.get(self.code, "Unknown Error (%u)" % self.code)
+
     def __str__(self):
-        return "%s: %s" % (Cmd.str.get(self.cmd, "UnknownCmd"),
-                           Ack.str.get(self.code, "Unknown Error (%u)"
-                                       % self.code))
+        return "%s: %s" % (self.cmd_str(), self.errcode_str())
 
 
 class Unit:
@@ -189,13 +198,13 @@ class Unit:
         error.check(c == cmd[0], "Command returned garbage (%02x != %02x)"
                     % (c, cmd[0]))
         if r != 0:
-            raise CmdError(c, r)
+            raise CmdError(cmd, r)
 
 
     ## seek:
     ## Seek the selected drive's heads to the specified track (cyl, side).
     def seek(self, cyl, side):
-        self._send_cmd(struct.pack("3B", Cmd.Seek, 3, cyl))
+        self._send_cmd(struct.pack("2Bb", Cmd.Seek, 3, cyl))
         self._send_cmd(struct.pack("3B", Cmd.Side, 3, side))
 
 

+ 5 - 0
src/f1/floppy.c

@@ -192,6 +192,11 @@ static void reset_user_pins(void)
     write_pin(densel, FALSE);
 }
 
+/* No Flippy-modded drive support on F1 boards. */
+#define flippy_trk0_sensor_disable() ((void)0)
+#define flippy_trk0_sensor_enable() ((void)0)
+#define flippy_detect() FALSE
+
 /*
  * Local variables:
  * mode: C

+ 2 - 2
src/f7/board.c

@@ -184,9 +184,9 @@ static void mcu_board_init(void)
         pu[upin->gpio_bank] &= ~(1u << upin->gpio_pin);
     }
 
-    /* Lightning Plus /FLIPPY output. Unused for now. Tie LOW. */
+    /* Lightning Plus TRK0_DISABLE output: Set inactive (LOW). */
     if (gw_info.hw_submodel == F7SM_lightning_plus) {
-        gpio_configure_pin(gpioc, 1, GPI_pull_down);
+        gpio_configure_pin(gpioc, 1, GPO_pushpull(IOSPD_LOW, LOW));
         pu[_C] &= ~(1u << 1);
     }
 

+ 20 - 0
src/f7/floppy.c

@@ -283,6 +283,26 @@ static void reset_user_pins(void)
         gpio_write_pin(gpio_from_id(upin->gpio_bank), upin->gpio_pin, O_FALSE);
 }
 
+static void flippy_trk0_sensor(bool_t level)
+{
+    if (gw_info.hw_submodel == F7SM_lightning_plus) {
+        gpio_write_pin(gpioc, 1, level);
+        delay_us(10);
+    }
+}
+
+#define flippy_trk0_sensor_disable() flippy_trk0_sensor(HIGH)
+#define flippy_trk0_sensor_enable() flippy_trk0_sensor(LOW)
+
+static bool_t flippy_detect(void)
+{
+    bool_t is_flippy;
+    flippy_trk0_sensor_disable();
+    is_flippy = (get_trk0() == HIGH);
+    flippy_trk0_sensor_enable();
+    return is_flippy;
+}
+
 /*
  * Local variables:
  * mode: C

+ 54 - 38
src/floppy.c

@@ -29,8 +29,10 @@
 
 static int bus_type = -1;
 static int unit_nr = -1;
-static struct {
+static struct unit {
     int cyl;
+    bool_t initialised;
+    bool_t is_flippy;
     bool_t motor;
 } unit[3];
 
@@ -140,13 +142,9 @@ static void step_one_in(void)
 
 static void _set_bus_type(uint8_t type)
 {
-    int i;
     bus_type = type;
     unit_nr = -1;
-    for (i = 0; i < ARRAY_SIZE(unit); i++) {
-        unit[i].cyl = -1;
-        unit[i].motor = FALSE;
-    }
+    memset(unit, 0, sizeof(unit));
     reset_bus();
 }
 
@@ -163,48 +161,51 @@ static bool_t set_bus_type(uint8_t type)
     return TRUE;
 }
 
-static uint8_t floppy_seek(unsigned int cyl)
+static uint8_t floppy_seek(int cyl)
 {
-    int cur_cyl;
+    struct unit *u;
 
     if (unit_nr < 0)
         return ACK_NO_UNIT;
-    cur_cyl = unit[unit_nr].cyl;
-
-    if ((cyl == 0) || (cur_cyl < 0)) {
+    u = &unit[unit_nr];
 
+    if (!u->initialised) {
         unsigned int i;
         for (i = 0; i < 256; i++) {
             if (get_trk0() == LOW)
-                break;
+                goto found_trk0;
             step_one_out();
         }
-        cur_cyl = 0;
-        if (get_trk0() == HIGH) {
-            unit[unit_nr].cyl = -1;
-            return ACK_NO_TRK0;
-        }
-
+        return ACK_NO_TRK0;
+    found_trk0:
+        u->is_flippy = flippy_detect();
+        u->initialised = TRUE;
+        u->cyl = 0;
     }
 
-    if (cur_cyl < 0) {
+    if ((cyl < (u->is_flippy ? -8 : 0)) || (cyl > 100))
+        return ACK_BAD_CYLINDER;
 
-    } else if (cur_cyl <= cyl) {
+    flippy_trk0_sensor_disable();
 
-        unsigned int nr = cyl - cur_cyl;
+    if (u->cyl <= cyl) {
+
+        int nr = cyl - u->cyl;
         while (nr--)
             step_one_in();
 
     } else {
 
-        unsigned int nr = cur_cyl - cyl;
+        int nr = u->cyl - cyl;
         while (nr--)
             step_one_out();
 
     }
 
+    flippy_trk0_sensor_enable();
+
     delay_ms(delay_params.seek_settle);
-    unit[unit_nr].cyl = cyl;
+    u->cyl = cyl;
 
     return ACK_OKAY;
 }
@@ -230,15 +231,37 @@ static void floppy_flux_end(void)
         continue;
 }
 
-static void floppy_reset(void)
+static void do_auto_off(void)
 {
-    floppy_state = ST_inactive;
-    auto_off.armed = FALSE;
+    int i;
 
     floppy_flux_end();
 
+    for (i = 0; i < ARRAY_SIZE(unit); i++) {
+
+        struct unit *u = &unit[i];
+        if (!u->initialised)
+            continue;
+
+        if (u->cyl < 0) {
+            drive_select(i);
+            floppy_seek(0);
+        }
+
+        if (u->motor)
+            drive_motor(i, FALSE);
+
+    }
+
     drive_deselect();
 
+    auto_off.armed = FALSE;
+}
+
+static void floppy_reset(void)
+{
+    floppy_state = ST_inactive;
+    do_auto_off();
     act_led(FALSE);
 }
 
@@ -1089,8 +1112,8 @@ static void process_command(void)
         break;
     }
     case CMD_SEEK: {
-        uint8_t cyl = u_buf[2];
-        if ((len != 3) || (cyl > 85))
+        int8_t cyl = u_buf[2];
+        if (len != 3)
             goto bad_command;
         u_buf[1] = floppy_seek(cyl);
         goto out;
@@ -1244,17 +1267,10 @@ static void floppy_configure(void)
 
 void floppy_process(void)
 {
-    int i, len;
+    int len;
 
-    if (auto_off.armed && (time_since(auto_off.deadline) >= 0)) {
-        floppy_flux_end();
-        for (i = 0; i < ARRAY_SIZE(unit); i++) {
-            if (unit[i].motor)
-                drive_motor(i, FALSE);
-        }
-        drive_deselect();
-        auto_off.armed = FALSE;
-    }
+    if (auto_off.armed && (time_since(auto_off.deadline) >= 0))
+        do_auto_off();
 
     switch (floppy_state) {