floppy.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include <rtthread.h>
  2. #include <rthw.h>
  3. #include <bsp.h>
  4. typedef rt_uint8_t u8;
  5. typedef rt_uint16_t u16;
  6. typedef rt_uint32_t u32;
  7. typedef rt_int8_t s8;
  8. typedef rt_int16_t s16;
  9. typedef rt_int32_t s32;
  10. #include "floppy.h"
  11. #include "dma.h"
  12. #define panic(str) rt_kprintf("panic::" str)
  13. #define _local_irq_save(level) level = rt_hw_interrupt_disable()
  14. #define _local_irq_restore(level) rt_hw_interrupt_enable(level)
  15. static u8 floppy_buffer[512]; /* 软盘高速缓冲区地址指针 */
  16. #define MAX_REPLIES 7
  17. static u8 floppy_reply_buffer[MAX_REPLIES]; /* 软驱回应缓冲区 */
  18. #define ST0 (floppy_reply_buffer[0]) /* 软驱回应0号字节 */
  19. #define ST1 (floppy_reply_buffer[1]) /* 软驱回应1号字节 */
  20. #define ST2 (floppy_reply_buffer[2]) /* 软驱回应2号字节 */
  21. #define ST3 (floppy_reply_buffer[3]) /* 软驱回应3号字节 */
  22. static char *floppy_inc_name; /* 软驱型号名 */
  23. static char *floppy_type;
  24. static u32 floppy_motor=0; /* 软驱马达状态字节 */
  25. /**********************功能函数***************************/
  26. static void floppy_result(void); /* 获得软驱响应状态 */
  27. static u32 floppy_sendbyte(u32); /* 向软驱控制寄存器发送一个控制字节 */
  28. static u32 floppy_getbyte(void); /* 从软驱数据寄存器得到一个数据字节 */
  29. static u32 floppy_get_info(void); /* 得到软驱信息 */
  30. static void floppy_motorOn(void); /* 打开软驱马达 */
  31. static void floppy_motorOff(void); /* 关闭软驱马达 */
  32. static void floppy_setmode(void); /* 软驱模式设置 */
  33. static void block_to_hts(u32, u32*, u32*, u32*); /* 逻辑块转为磁盘头、磁道号和扇区号 */
  34. static void floppy_setupDMA(void); /* 设置软驱DMA通道 */
  35. static void floppy_read_cmd(u32 blk); /* 从软盘上读取指定的逻辑块到缓冲区 */
  36. void floppy_result(void)
  37. {
  38. u8 stat, i,count;
  39. i=0;
  40. for(count=0; count<0xFF; count++)
  41. {
  42. stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
  43. if (stat == STATUS_READY)
  44. return;
  45. if (stat == (STATUS_READY|STATUS_DIR|STATUS_BUSY))
  46. {
  47. if(i>7) break;
  48. floppy_reply_buffer[i++]=inb_p(FD_DATA);
  49. }
  50. }
  51. panic("Get floppy status times out !\n");
  52. }
  53. u32 floppy_sendbyte( u32 value )
  54. {
  55. u8 stat, i;
  56. for ( i = 0; i < 128; i++ ) {
  57. stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR); //读取状态寄存器
  58. if ( stat == STATUS_READY )
  59. {
  60. outb( value ,FD_DATA); //将参数写入数据寄存器
  61. return 1;
  62. }
  63. io_delay(); // 作一些延迟
  64. }
  65. return 0;
  66. }
  67. u32 floppy_getbyte(void)
  68. {
  69. u8 stat, i;
  70. for ( i = 0; i < 128; i++ ) {
  71. stat = inb( FD_STATUS ) & (STATUS_READY|STATUS_DIR|STATUS_BUSY); //读取状态寄存器
  72. if (stat == STATUS_READY)
  73. return -1;
  74. if ( stat == 0xD0 )
  75. return inb(FD_DATA);
  76. io_delay();
  77. }
  78. return 0;
  79. }
  80. u32 floppy_get_info(void)
  81. {
  82. u32 i;
  83. u8 CmType, FdType;
  84. floppy_sendbyte(0x10);
  85. i = floppy_getbyte();
  86. switch (i)
  87. {
  88. case 0x80: floppy_inc_name = "NEC765A controller"; break;
  89. case 0x90: floppy_inc_name = "NEC765B controller"; break;
  90. default: floppy_inc_name = "Enhanced controller"; break;
  91. }
  92. CmType = readcmos(0x10); //read floppy type from cmos
  93. FdType = (CmType>>4) & 0x07;
  94. if ( FdType == 0 )
  95. panic("Floppy driver not found!");
  96. switch( FdType )
  97. {
  98. case 0x02: // 1.2MB
  99. floppy_type = "1.2MB";
  100. break;
  101. case 0x04: // 1.44MB 标准软盘
  102. floppy_type = "1.44MB";
  103. break;
  104. case 0x05: // 2.88MB
  105. floppy_type = "2.88MB";
  106. break;
  107. }
  108. return 1;
  109. }
  110. void floppy_motorOn( void )
  111. {
  112. u32 eflags;
  113. if (!floppy_motor)
  114. {
  115. _local_irq_save(eflags);
  116. outb(28,FD_DOR);
  117. floppy_motor = 1;
  118. _local_irq_restore(eflags);
  119. }
  120. return;
  121. }
  122. void floppy_motorOff( void )
  123. {
  124. u32 eflags;
  125. if (floppy_motor)
  126. {
  127. _local_irq_save(eflags);
  128. outb(12,FD_DOR);
  129. floppy_motor = 0;
  130. _local_irq_restore(eflags);
  131. }
  132. return;
  133. }
  134. void floppy_setmode(void)
  135. {
  136. floppy_sendbyte (FD_SPECIFY);
  137. floppy_sendbyte (0xcf);
  138. floppy_sendbyte (0x06);
  139. outb (0,FD_DCR);
  140. }
  141. void block_to_hts(u32 block, u32 *head, u32 *track, u32 *sector )
  142. {
  143. *head = ( block % ( 18 * 2 ) ) /18;
  144. *track = block / ( 18 * 2 );
  145. *sector = block % 18 + 1;
  146. }
  147. void floppy_setupDMA(void)
  148. {
  149. u32 eflags;
  150. _local_irq_save(eflags);
  151. DisableDma(2);
  152. ClearDmaFF(2);
  153. SetDmaMode(2,DMA_MODE_READ);
  154. SetDmaAddr(2,(unsigned long)floppy_buffer);
  155. SetDmaCount(2,512);
  156. EnableDma(2);
  157. _local_irq_restore(eflags);
  158. }
  159. void floppy_read_cmd(u32 blk)
  160. {
  161. u32 head;
  162. u32 track;
  163. u32 sector;
  164. block_to_hts(blk,&head,&track,&sector);
  165. floppy_motorOn();
  166. io_delay();
  167. floppy_setupDMA();
  168. io_delay();
  169. floppy_setmode();
  170. io_delay();
  171. floppy_sendbyte (FD_READ); //send read command
  172. floppy_sendbyte (head*4 + 0);
  173. floppy_sendbyte (track); /* Cylinder */
  174. floppy_sendbyte (head); /* Head */
  175. floppy_sendbyte (sector); /* Sector */
  176. floppy_sendbyte (2); /* 0=128, 1=256, 2=512, 3=1024, ... */
  177. floppy_sendbyte (18);
  178. //floppy_sendbyte (sector+secs-1); /* Last sector in track:here are sectors count */
  179. floppy_sendbyte (0x1B);
  180. floppy_sendbyte (0xff);
  181. return;
  182. }
  183. void init_fd(void)
  184. {
  185. floppy_get_info();
  186. rt_kprintf("Floppy Inc : %s Floppy Type : %s",floppy_inc_name,floppy_type);
  187. }