COBE 0.1 ALPHA
|
00001 #include <cmos.h> 00002 #include <stdint.h> 00003 #include <fdc.h> 00004 #include <stdio.h> 00005 #include <io.h> 00006 #include <dma.h> 00007 00012 00013 static uint8_t f_drive; 00015 uint16_t curr_cylinder; 00016 00018 00022 void set_drive(uint8_t drive) { f_drive = drive; } 00023 00025 00029 void fdc_start_motor(uint8_t drive) { 00030 outb(CCR, 0); 00031 outb(DOR, drive | (1 << (drive+4)) | DOR_DMA_ON | DOR_NO_RESET); //----------Setze das Dribe, die DMA und kein Reset, das MotorBIT für das jeweilige Drive wird gesetzt---------- 00033 sleep(305); 00034 } 00035 00037 00041 void fdc_stop_motor(uint8_t drive) { 00042 outb(DOR, drive | DOR_DMA_ON | DOR_NO_RESET); //----------Setze das Drive, die DMA, und auf kein Reset, die MotorBITS werden auf Null gesetzt---------- 00043 } 00044 00046 00050 void fdc_send_command(uint8_t cmd) { 00051 fdc_send_data(cmd); //----------Sende den Befehl direkt weiter---------- 00052 } 00053 00055 00062 uint32_t fdc_send_data(uint8_t data) { 00063 irq6_fdc = 0; 00064 for(uint32_t i = 0; i < 10; i++) //----------Diskettenlaufwerke sind fehleranfällig, deswegen lieber öfter ausführen---------- 00065 { 00066 if((inb(MSR) & (MSR_IO_WRITE | MSR_DR_READY)) == MSR_DR_READY) //----------Sobald das IO-Bit gelöscht ist und das DataRegister-Bit gesetzt ist, kann begonnen werden---------- 00067 { 00068 outb(DR, data); //----------Sende den Befehl---------- 00069 return 0; 00070 } 00071 sleep(2); //----------2ms warten---------- 00072 } 00073 return 1; 00074 } 00075 00077 00083 uint32_t fdc_read_data() { 00084 irq6_fdc = 0; //----------Interrupt 6 zurücksetzen---------- 00085 for(uint32_t i = 0; i < 10; i++) { 00086 if((inb(MSR) & (MSR_IO_WRITE | MSR_DR_READY)) == (MSR_DR_READY | MSR_IO_WRITE)) { //----------Wenn das IO-Bit und das DataRegister Bit gesetzt, kann begonnen werden---------- 00087 return inb(DR); //----------Den Inhalt vom Dataregister zurückgeben---------- 00088 } 00089 sleep(2); 00090 } 00091 return 1; 00092 } 00093 00095 00114 uint8_t copy_sector(uint8_t drive, uint8_t head, uint8_t cylinder, uint8_t sector, void* buffer, bool write) { 00115 00116 fdc_start_motor(drive); //----------Den Motor des Floppy für das angegebene Laufwerk starten---------- 00117 fdc_seek(cylinder, head, drive); //----------Schreib/Lese-Kopf auf den richtigen Sektor setzen---------- 00118 00119 if(write == true) set_dma_transfer(2, 512, buffer, true); else set_dma_transfer(2, 512, buffer, false); //----------DMA-Datenübertragung vereinbaren, entweder zum 1: schreiben oder 2: lesen---------- 00120 for(uint32_t i = 0; i < 3; i++) { 00121 if(write == true) fdc_send_command(0x40 | 0x05); else fdc_send_command(0x40 | 0x06); //----------Den Befehl für 1: schreiben oder 2: lesen vom Floppy schicken---------- 00122 fdc_send_data(drive | head << 2); //----------Das Laufwerk und die Headnummer senden---------- 00123 fdc_send_data(cylinder); //----------Sendet die Cylindernummer---------- 00124 fdc_send_data(head); //----------Sendet nochmal die Headnummer---------- 00125 fdc_send_data(sector); //----------Sendet die Sektornummer---------- 00126 fdc_send_data(2); //----------Sektorgröße: 0: 128Byte 1: 256Byte 2: 512Byte .... ---------- 00127 fdc_send_data(18); //----------Letzter Sektor eines Cylinders---------- 00128 fdc_send_data(27); //----------GAP3 Länge, 27 ist Standard für 3,5"---------- 00129 fdc_send_data(0xFF); //----------Datenlänge---------- 00130 while(irq6_fdc != 1 ); //----------Warte auf Beendigung durch IRQ6 und hole die Rückgabewerte---------- 00131 fdc_read_data(); //----------ST0---------- 00132 fdc_read_data(); //----------ST1---------- 00133 fdc_read_data(); //----------ST2---------- 00134 fdc_read_data(); //----------Cylinder---------- 00135 fdc_read_data(); //----------Head---------- 00136 fdc_read_data(); //----------Sektor---------- 00137 fdc_read_data(); //----------Sektorgröße, siehe oben---------- 00138 if(inb(MSR) & 0xC0) { check_fdc_itr(); fdc_stop_motor(drive); return 0;} 00139 sleep(5); 00140 } 00141 00142 return 1; 00143 } 00144 00146 00152 void fdc_seek(uint8_t cylinder, uint8_t head, uint8_t drive) { 00153 if(curr_cylinder == cylinder) return; //----------Wenn das schon der Cylinder ist, muss es nicht zweimal gemacht werden---------- 00154 for(uint32_t i = 0; i < 3; i++) { 00155 fdc_send_command(0xF); //----------Befehl zum Seek senden---------- 00156 fdc_send_data(drive | head << 2); //----------Das Laufwerk und die Headnummer senden---------- 00157 fdc_send_data(cylinder); //----------Sendet die Cylindernummer---------- 00158 sleep(300); 00159 if(irq6_fdc == 1){ if(check_fdc_itr() & 0x16) continue; curr_cylinder = cylinder; return; } //----------Beim IRQ6 ist es geschafft---------- 00160 } 00161 } 00162 00164 00168 uint8_t check_fdc_itr() { 00169 fdc_send_command(0x8); 00170 uint8_t st0 = fdc_read_data(); fdc_read_data(); 00171 return st0; 00172 } 00173 00175 00181 void show_floppys() { 00182 00183 uint32_t floppy_connected = (get_data_cmos(0x14) & 0x1); //----------Ist überhaupt ein Floppy angeschlossen?---------- 00184 00185 if(floppy_connected == 1) //----------Wenn ja, dann...---------- 00186 { 00187 uint32_t num_of_floppys = (get_data_cmos(0x14) >> 6); //----------Hole die Anzahl der angeschlossenen Floppy-Disks---------- 00188 uint32_t floppy_a = (get_data_cmos(0x10) >> 4); //----------Hole den Typ vom Floppy A---------- 00189 char* type_of_a; 00190 switch(floppy_a) { //----------Und schreibe dafür den Text aus---------- 00191 case 0x0: type_of_a = "Laufwerk nicht vorhanden"; break; 00192 case 0x1: type_of_a = "5 1/2 Zoll // 360 Kbyte"; break; 00193 case 0x2: type_of_a = "5 1/2 Zoll // 1,2 Mbyte"; break; 00194 case 0x3: type_of_a = "3 1/2 Zoll // 720 Kbyte"; break; 00195 case 0x4: type_of_a = "3 1/2 Zoll // 1,44 Mbyte"; break; 00196 case 0x5: type_of_a = "3 1/2 Zoll // 2,88 Mbyte"; break; } 00197 00198 kprintf("\n Angeschlossene Diskettenlaufwerke:"); 00199 kprintf("\n\n Floppy A: %s", type_of_a); 00200 00201 //----------Das gleiche für Floppy B---------- 00202 if(num_of_floppys > 1) 00203 { 00204 char* type_of_b; 00205 uint32_t floppy_b = (get_data_cmos(0x10) & 0xF); 00206 switch(floppy_b) { 00207 case 0x0: type_of_b= "Laufwerk nicht vorhanden"; break; 00208 case 0x1: type_of_b = "5 1/2 Zoll // 360 Kbyte"; break; 00209 case 0x2: type_of_b = "5 1/2 Zoll // 1,2 Mbyte"; break; 00210 case 0x3: type_of_b = "3 1/2 Zoll // 720 Kbyte"; break; 00211 case 0x4: type_of_b = "3 1/2 Zoll // 1,44 Mbyte"; break; 00212 case 0x5: type_of_a = "3 1/2 Zoll // 2,88 Mbyte"; break; } 00213 kprintf("\n Floppy B: %s", type_of_a); 00214 } 00215 00216 } else kprintf("\n Keine Diskettenlaufwerke angeschlossen!"); 00217 00218 return; 00219 }