17dd7cddfSDavid du Colombier typedef struct FController FController;
27dd7cddfSDavid du Colombier typedef struct FDrive FDrive;
37dd7cddfSDavid du Colombier typedef struct FType FType;
47dd7cddfSDavid du Colombier
57dd7cddfSDavid du Colombier static void floppyintr(Ureg*);
6*59cc4ca5SDavid du Colombier static int floppyon(FDrive*);
77dd7cddfSDavid du Colombier static void floppyoff(FDrive*);
87dd7cddfSDavid du Colombier static void floppysetdef(FDrive*);
97dd7cddfSDavid du Colombier
107dd7cddfSDavid du Colombier /*
117dd7cddfSDavid du Colombier * a floppy drive
127dd7cddfSDavid du Colombier */
137dd7cddfSDavid du Colombier struct FDrive
147dd7cddfSDavid du Colombier {
157dd7cddfSDavid du Colombier FType *t; /* floppy type */
167dd7cddfSDavid du Colombier int dt; /* drive type */
177dd7cddfSDavid du Colombier int dev;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier ulong lasttouched; /* time last touched */
207dd7cddfSDavid du Colombier int cyl; /* current arm position */
217dd7cddfSDavid du Colombier int confused; /* needs to be recalibrated */
227dd7cddfSDavid du Colombier int vers;
23*59cc4ca5SDavid du Colombier int maxtries; /* max read attempts before Eio */
247dd7cddfSDavid du Colombier
257dd7cddfSDavid du Colombier int tcyl; /* target cylinder */
267dd7cddfSDavid du Colombier int thead; /* target head */
277dd7cddfSDavid du Colombier int tsec; /* target sector */
287dd7cddfSDavid du Colombier long len; /* size of xfer */
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier uchar *cache; /* track cache */
317dd7cddfSDavid du Colombier int ccyl;
327dd7cddfSDavid du Colombier int chead;
337dd7cddfSDavid du Colombier };
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier /*
367dd7cddfSDavid du Colombier * controller for 4 floppys
377dd7cddfSDavid du Colombier */
387dd7cddfSDavid du Colombier struct FController
397dd7cddfSDavid du Colombier {
407dd7cddfSDavid du Colombier QLock; /* exclusive access to the contoller */
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier int ndrive;
437dd7cddfSDavid du Colombier FDrive *d; /* the floppy drives */
447dd7cddfSDavid du Colombier FDrive *selected;
457dd7cddfSDavid du Colombier int rate; /* current rate selected */
467dd7cddfSDavid du Colombier uchar cmd[14]; /* command */
477dd7cddfSDavid du Colombier int ncmd; /* # command bytes */
487dd7cddfSDavid du Colombier uchar stat[14]; /* command status */
497dd7cddfSDavid du Colombier int nstat; /* # status bytes */
507dd7cddfSDavid du Colombier int confused; /* controler needs to be reset */
517dd7cddfSDavid du Colombier Rendez r; /* wait here for command termination */
527dd7cddfSDavid du Colombier int motor; /* bit mask of spinning disks */
537dd7cddfSDavid du Colombier };
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier /*
567dd7cddfSDavid du Colombier * floppy types (all MFM encoding)
577dd7cddfSDavid du Colombier */
587dd7cddfSDavid du Colombier struct FType
597dd7cddfSDavid du Colombier {
607dd7cddfSDavid du Colombier char *name;
617dd7cddfSDavid du Colombier int dt; /* compatible drive type */
627dd7cddfSDavid du Colombier int bytes; /* bytes/sector */
637dd7cddfSDavid du Colombier int sectors; /* sectors/track */
647dd7cddfSDavid du Colombier int heads; /* number of heads */
657dd7cddfSDavid du Colombier int steps; /* steps per cylinder */
667dd7cddfSDavid du Colombier int tracks; /* tracks/disk */
677dd7cddfSDavid du Colombier int gpl; /* intersector gap length for read/write */
687dd7cddfSDavid du Colombier int fgpl; /* intersector gap length for format */
697dd7cddfSDavid du Colombier int rate; /* rate code */
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier /*
727dd7cddfSDavid du Colombier * these depend on previous entries and are set filled in
737dd7cddfSDavid du Colombier * by floppyinit
747dd7cddfSDavid du Colombier */
757dd7cddfSDavid du Colombier int bcode; /* coded version of bytes for the controller */
767dd7cddfSDavid du Colombier long cap; /* drive capacity in bytes */
777dd7cddfSDavid du Colombier long tsize; /* track size in bytes */
787dd7cddfSDavid du Colombier };
797dd7cddfSDavid du Colombier /* bits in the registers */
807dd7cddfSDavid du Colombier enum
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier /* status registers a & b */
837dd7cddfSDavid du Colombier Psra= 0x3f0,
847dd7cddfSDavid du Colombier Psrb= 0x3f1,
857dd7cddfSDavid du Colombier
867dd7cddfSDavid du Colombier /* digital output register */
877dd7cddfSDavid du Colombier Pdor= 0x3f2,
887dd7cddfSDavid du Colombier Fintena= 0x8, /* enable floppy interrupt */
897dd7cddfSDavid du Colombier Fena= 0x4, /* 0 == reset controller */
907dd7cddfSDavid du Colombier
917dd7cddfSDavid du Colombier /* main status register */
927dd7cddfSDavid du Colombier Pmsr= 0x3f4,
937dd7cddfSDavid du Colombier Fready= 0x80, /* ready to be touched */
947dd7cddfSDavid du Colombier Ffrom= 0x40, /* data from controller */
957dd7cddfSDavid du Colombier Ffloppybusy= 0x10, /* operation not over */
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier /* data register */
987dd7cddfSDavid du Colombier Pfdata= 0x3f5,
997dd7cddfSDavid du Colombier Frecal= 0x07, /* recalibrate cmd */
1007dd7cddfSDavid du Colombier Fseek= 0x0f, /* seek cmd */
1017dd7cddfSDavid du Colombier Fsense= 0x08, /* sense cmd */
1027dd7cddfSDavid du Colombier Fread= 0x66, /* read cmd */
1037dd7cddfSDavid du Colombier Freadid= 0x4a, /* read track id */
1047dd7cddfSDavid du Colombier Fspec= 0x03, /* set hold times */
1057dd7cddfSDavid du Colombier Fwrite= 0x45, /* write cmd */
1067dd7cddfSDavid du Colombier Fformat= 0x4d, /* format cmd */
1077dd7cddfSDavid du Colombier Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
1087dd7cddfSDavid du Colombier Fdumpreg= 0x0e, /* dump internal registers */
1097dd7cddfSDavid du Colombier
1107dd7cddfSDavid du Colombier /* digital input register */
1117dd7cddfSDavid du Colombier Pdir= 0x3F7, /* disk changed port (read only) */
1127dd7cddfSDavid du Colombier Pdsr= 0x3F7, /* data rate select port (write only) */
1137dd7cddfSDavid du Colombier Fchange= 0x80, /* disk has changed */
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier /* status 0 byte */
1167dd7cddfSDavid du Colombier Drivemask= 3<<0,
1177dd7cddfSDavid du Colombier Seekend= 1<<5,
1187dd7cddfSDavid du Colombier Codemask= (3<<6)|(3<<3),
1197dd7cddfSDavid du Colombier Cmdexec= 1<<6,
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier /* status 1 byte */
1227dd7cddfSDavid du Colombier Overrun= 0x10,
1237dd7cddfSDavid du Colombier };
1247dd7cddfSDavid du Colombier
1257dd7cddfSDavid du Colombier
1267dd7cddfSDavid du Colombier static void
pcfloppyintr(Ureg * ur,void * a)1277dd7cddfSDavid du Colombier pcfloppyintr(Ureg *ur, void *a)
1287dd7cddfSDavid du Colombier {
1297dd7cddfSDavid du Colombier USED(a);
1307dd7cddfSDavid du Colombier
1317dd7cddfSDavid du Colombier floppyintr(ur);
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier
1347dd7cddfSDavid du Colombier void
floppysetup0(FController * fl)1357dd7cddfSDavid du Colombier floppysetup0(FController *fl)
1367dd7cddfSDavid du Colombier {
1377dd7cddfSDavid du Colombier fl->ndrive = 0;
1387dd7cddfSDavid du Colombier if(ioalloc(Psra, 6, 0, "floppy") < 0)
1397dd7cddfSDavid du Colombier return;
1407dd7cddfSDavid du Colombier if(ioalloc(Pdir, 1, 0, "floppy") < 0){
1417dd7cddfSDavid du Colombier iofree(Psra);
1427dd7cddfSDavid du Colombier return;
1437dd7cddfSDavid du Colombier }
1447dd7cddfSDavid du Colombier fl->ndrive = 2;
1457dd7cddfSDavid du Colombier }
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier void
floppysetup1(FController * fl)1487dd7cddfSDavid du Colombier floppysetup1(FController *fl)
1497dd7cddfSDavid du Colombier {
1507dd7cddfSDavid du Colombier uchar equip;
1517dd7cddfSDavid du Colombier
1527dd7cddfSDavid du Colombier /*
1537dd7cddfSDavid du Colombier * read nvram for types of floppies 0 & 1
1547dd7cddfSDavid du Colombier */
1557dd7cddfSDavid du Colombier equip = nvramread(0x10);
1567dd7cddfSDavid du Colombier if(fl->ndrive > 0){
1577dd7cddfSDavid du Colombier fl->d[0].dt = (equip >> 4) & 0xf;
1587dd7cddfSDavid du Colombier floppysetdef(&fl->d[0]);
1597dd7cddfSDavid du Colombier }
1607dd7cddfSDavid du Colombier if(fl->ndrive > 1){
1617dd7cddfSDavid du Colombier fl->d[1].dt = equip & 0xf;
1627dd7cddfSDavid du Colombier floppysetdef(&fl->d[1]);
1637dd7cddfSDavid du Colombier }
1647dd7cddfSDavid du Colombier intrenable(IrqFLOPPY, pcfloppyintr, fl, BUSUNKNOWN, "floppy");
1657dd7cddfSDavid du Colombier }
1667dd7cddfSDavid du Colombier
1677dd7cddfSDavid du Colombier /*
1687dd7cddfSDavid du Colombier * eject disk ( unknown on safari )
1697dd7cddfSDavid du Colombier */
1707dd7cddfSDavid du Colombier void
floppyeject(FDrive * dp)1717dd7cddfSDavid du Colombier floppyeject(FDrive *dp)
1727dd7cddfSDavid du Colombier {
1737dd7cddfSDavid du Colombier floppyon(dp);
1747dd7cddfSDavid du Colombier dp->vers++;
1757dd7cddfSDavid du Colombier floppyoff(dp);
1767dd7cddfSDavid du Colombier }
1777dd7cddfSDavid du Colombier
1787dd7cddfSDavid du Colombier int
floppyexec(char * a,long b,int c)1797dd7cddfSDavid du Colombier floppyexec(char *a, long b, int c)
1807dd7cddfSDavid du Colombier {
1817dd7cddfSDavid du Colombier USED(a, b, c);
1827dd7cddfSDavid du Colombier return b;
1837dd7cddfSDavid du Colombier }
184