123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- /*
- * This file is part of the UCB release of Plan 9. It is subject to the license
- * terms in the LICENSE file found in the top-level directory of this
- * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
- * part of the UCB release of Plan 9, including this file, may be copied,
- * modified, propagated, or distributed except according to the terms contained
- * in the LICENSE file.
- */
- typedef struct FController FController;
- typedef struct FDrive FDrive;
- typedef struct FType FType;
- static void floppyintr(Ureg*);
- static int floppyon(FDrive*);
- static void floppyoff(FDrive*);
- static void floppysetdef(FDrive*);
- /*
- * a floppy drive
- */
- struct FDrive
- {
- FType *t; /* floppy type */
- int dt; /* drive type */
- int dev;
- uint32_t lasttouched; /* time last touched */
- int cyl; /* current arm position */
- int confused; /* needs to be recalibrated */
- int offset; /* current offset */
- int vers;
- int maxtries;
- int tcyl; /* target cylinder */
- int thead; /* target head */
- int tsec; /* target sector */
- long len; /* size of xfer */
- uchar *cache; /* track cache */
- int ccyl;
- int chead;
- // Rendez r; /* waiting here for motor to spin up */
- void *aux;
- };
- /*
- * controller for 4 floppys
- */
- struct FController
- {
- // QLock; /* exclusive access to the contoller */
- int ndrive;
- FDrive *d; /* the floppy drives */
- FDrive *selected;
- int rate; /* current rate selected */
- uchar cmd[14]; /* command */
- int ncmd; /* # command bytes */
- uchar stat[14]; /* command status */
- int nstat; /* # status bytes */
- int confused; /* controler needs to be reset */
- // Rendez r; /* wait here for command termination */
- int motor; /* bit mask of spinning disks */
- // Rendez kr; /* for motor watcher */
- };
- /*
- * floppy types (all MFM encoding)
- */
- struct FType
- {
- char *name;
- int dt; /* compatible drive type */
- int bytes; /* bytes/sector */
- int sectors; /* sectors/track */
- int heads; /* number of heads */
- int steps; /* steps per cylinder */
- int tracks; /* tracks/disk */
- int gpl; /* intersector gap length for read/write */
- int fgpl; /* intersector gap length for format */
- int rate; /* rate code */
- /*
- * these depend on previous entries and are set filled in
- * by floppyinit
- */
- int bcode; /* coded version of bytes for the controller */
- long cap; /* drive capacity in bytes */
- long tsize; /* track size in bytes */
- };
- /* bits in the registers */
- enum
- {
- /* status registers a & b */
- Psra= 0x3f0,
- Psrb= 0x3f1,
- /* digital output register */
- Pdor= 0x3f2,
- Fintena= 0x8, /* enable floppy interrupt */
- Fena= 0x4, /* 0 == reset controller */
- /* main status register */
- Pmsr= 0x3f4,
- Fready= 0x80, /* ready to be touched */
- Ffrom= 0x40, /* data from controller */
- Ffloppybusy= 0x10, /* operation not over */
- /* data register */
- Pfdata= 0x3f5,
- Frecal= 0x07, /* recalibrate cmd */
- Fseek= 0x0f, /* seek cmd */
- Fsense= 0x08, /* sense cmd */
- Fread= 0x66, /* read cmd */
- Freadid= 0x4a, /* read track id */
- Fspec= 0x03, /* set hold times */
- Fwrite= 0x45, /* write cmd */
- Fformat= 0x4d, /* format cmd */
- Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
- Fdumpreg= 0x0e, /* dump internal registers */
- /* digital input register */
- Pdir= 0x3F7, /* disk changed port (read only) */
- Pdsr= 0x3F7, /* data rate select port (write only) */
- Fchange= 0x80, /* disk has changed */
- /* status 0 byte */
- Drivemask= 3<<0,
- Seekend= 1<<5,
- Codemask= (3<<6)|(3<<3),
- Cmdexec= 1<<6,
- /* status 1 byte */
- Overrun= 0x10,
- };
- /*
- * types of drive (from PC equipment byte)
- */
- enum
- {
- Tnone= 0,
- T360kb= 1,
- T1200kb= 2,
- T720kb= 3,
- T1440kb= 4,
- };
- static void
- pcfloppyintr(Ureg *ur, void *a)
- {
- USED(a);
- floppyintr(ur);
- }
- void
- floppysetup0(FController *fl)
- {
- uchar equip;
- /*
- * Read nvram for types of floppies 0 & 1.
- * Always try floppy 0.
- */
- equip = nvramread(0x10);
- fl->ndrive = 1;
- if(equip & 0xf)
- fl->ndrive++;
- /*
- * Allocate the drive storage.
- * There's always one.
- */
- fl->d = xalloc(fl->ndrive*sizeof(FDrive));
- fl->d[0].dt = (equip >> 4) & 0xf;
- if(fl->d[0].dt == Tnone)
- fl->d[0].dt = T1440kb;
- if(fl->ndrive == 2)
- fl->d[1].dt = equip & 0xf;
- }
- void
- floppysetup1(FController*)
- {
- // intrenable(VectorFLOPPY, pcfloppyintr, fl, BUSUNKNOWN);
- setvec(VectorFLOPPY, pcfloppyintr, 0);
- }
- static vlong pcfloppyseek(FDrive*, vlong);
- FController fl;
- vlong
- floppyseek(Fs *fs, vlong off)
- {
- FDrive *dp;
- dp = &fl.d[fs->dev];
- return pcfloppyseek(dp, off);
- }
|