Support flippy drive access to cylinder -8

This commit is contained in:
Keir Fraser
2020-11-19 08:49:33 +00:00
parent 15f4feed14
commit b7ddee0bda
7 changed files with 112 additions and 50 deletions

View File

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

View File

@@ -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__":

View File

@@ -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))

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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) {