devfloppy.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. typedef struct FController FController;
  10. typedef struct FDrive FDrive;
  11. typedef struct FType FType;
  12. static void floppyintr(Ureg*);
  13. static int floppyon(FDrive*);
  14. static void floppyoff(FDrive*);
  15. static void floppysetdef(FDrive*);
  16. /*
  17. * a floppy drive
  18. */
  19. struct FDrive
  20. {
  21. FType *t; /* floppy type */
  22. int dt; /* drive type */
  23. int dev;
  24. uint32_t lasttouched; /* time last touched */
  25. int cyl; /* current arm position */
  26. int confused; /* needs to be recalibrated */
  27. int offset; /* current offset */
  28. int vers;
  29. int maxtries;
  30. int tcyl; /* target cylinder */
  31. int thead; /* target head */
  32. int tsec; /* target sector */
  33. long len; /* size of xfer */
  34. uchar *cache; /* track cache */
  35. int ccyl;
  36. int chead;
  37. // Rendez r; /* waiting here for motor to spin up */
  38. void *aux;
  39. };
  40. /*
  41. * controller for 4 floppys
  42. */
  43. struct FController
  44. {
  45. // QLock; /* exclusive access to the contoller */
  46. int ndrive;
  47. FDrive *d; /* the floppy drives */
  48. FDrive *selected;
  49. int rate; /* current rate selected */
  50. uchar cmd[14]; /* command */
  51. int ncmd; /* # command bytes */
  52. uchar stat[14]; /* command status */
  53. int nstat; /* # status bytes */
  54. int confused; /* controler needs to be reset */
  55. // Rendez r; /* wait here for command termination */
  56. int motor; /* bit mask of spinning disks */
  57. // Rendez kr; /* for motor watcher */
  58. };
  59. /*
  60. * floppy types (all MFM encoding)
  61. */
  62. struct FType
  63. {
  64. char *name;
  65. int dt; /* compatible drive type */
  66. int bytes; /* bytes/sector */
  67. int sectors; /* sectors/track */
  68. int heads; /* number of heads */
  69. int steps; /* steps per cylinder */
  70. int tracks; /* tracks/disk */
  71. int gpl; /* intersector gap length for read/write */
  72. int fgpl; /* intersector gap length for format */
  73. int rate; /* rate code */
  74. /*
  75. * these depend on previous entries and are set filled in
  76. * by floppyinit
  77. */
  78. int bcode; /* coded version of bytes for the controller */
  79. long cap; /* drive capacity in bytes */
  80. long tsize; /* track size in bytes */
  81. };
  82. /* bits in the registers */
  83. enum
  84. {
  85. /* status registers a & b */
  86. Psra= 0x3f0,
  87. Psrb= 0x3f1,
  88. /* digital output register */
  89. Pdor= 0x3f2,
  90. Fintena= 0x8, /* enable floppy interrupt */
  91. Fena= 0x4, /* 0 == reset controller */
  92. /* main status register */
  93. Pmsr= 0x3f4,
  94. Fready= 0x80, /* ready to be touched */
  95. Ffrom= 0x40, /* data from controller */
  96. Ffloppybusy= 0x10, /* operation not over */
  97. /* data register */
  98. Pfdata= 0x3f5,
  99. Frecal= 0x07, /* recalibrate cmd */
  100. Fseek= 0x0f, /* seek cmd */
  101. Fsense= 0x08, /* sense cmd */
  102. Fread= 0x66, /* read cmd */
  103. Freadid= 0x4a, /* read track id */
  104. Fspec= 0x03, /* set hold times */
  105. Fwrite= 0x45, /* write cmd */
  106. Fformat= 0x4d, /* format cmd */
  107. Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
  108. Fdumpreg= 0x0e, /* dump internal registers */
  109. /* digital input register */
  110. Pdir= 0x3F7, /* disk changed port (read only) */
  111. Pdsr= 0x3F7, /* data rate select port (write only) */
  112. Fchange= 0x80, /* disk has changed */
  113. /* status 0 byte */
  114. Drivemask= 3<<0,
  115. Seekend= 1<<5,
  116. Codemask= (3<<6)|(3<<3),
  117. Cmdexec= 1<<6,
  118. /* status 1 byte */
  119. Overrun= 0x10,
  120. };
  121. /*
  122. * types of drive (from PC equipment byte)
  123. */
  124. enum
  125. {
  126. Tnone= 0,
  127. T360kb= 1,
  128. T1200kb= 2,
  129. T720kb= 3,
  130. T1440kb= 4,
  131. };
  132. static void
  133. pcfloppyintr(Ureg *ur, void *a)
  134. {
  135. USED(a);
  136. floppyintr(ur);
  137. }
  138. void
  139. floppysetup0(FController *fl)
  140. {
  141. uchar equip;
  142. /*
  143. * Read nvram for types of floppies 0 & 1.
  144. * Always try floppy 0.
  145. */
  146. equip = nvramread(0x10);
  147. fl->ndrive = 1;
  148. if(equip & 0xf)
  149. fl->ndrive++;
  150. /*
  151. * Allocate the drive storage.
  152. * There's always one.
  153. */
  154. fl->d = xalloc(fl->ndrive*sizeof(FDrive));
  155. fl->d[0].dt = (equip >> 4) & 0xf;
  156. if(fl->d[0].dt == Tnone)
  157. fl->d[0].dt = T1440kb;
  158. if(fl->ndrive == 2)
  159. fl->d[1].dt = equip & 0xf;
  160. }
  161. void
  162. floppysetup1(FController*)
  163. {
  164. // intrenable(VectorFLOPPY, pcfloppyintr, fl, BUSUNKNOWN);
  165. setvec(VectorFLOPPY, pcfloppyintr, 0);
  166. }
  167. static vlong pcfloppyseek(FDrive*, vlong);
  168. FController fl;
  169. vlong
  170. floppyseek(Fs *fs, vlong off)
  171. {
  172. FDrive *dp;
  173. dp = &fl.d[fs->dev];
  174. return pcfloppyseek(dp, off);
  175. }