mirror of
https://github.com/keirf/greaseweazle-firmware.git
synced 2025-10-31 11:06:44 -07:00
Support flippy drive access to cylinder -8
This commit is contained in:
@@ -84,6 +84,7 @@
|
||||
#define ACK_NO_BUS 8
|
||||
#define ACK_BAD_UNIT 9
|
||||
#define ACK_BAD_PIN 10
|
||||
#define ACK_BAD_CYLINDER 11
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -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__":
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
92
src/floppy.c
92
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) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user