From 2c7f83e006c3fee8d26e940eee801a4be9443e50 Mon Sep 17 00:00:00 2001 From: neoraider Date: Mon, 18 Apr 2005 15:18:02 +0000 Subject: Verzeichnisstruktur ver?ndert --- driver/floppy.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 driver/floppy.c (limited to 'driver/floppy.c') diff --git a/driver/floppy.c b/driver/floppy.c new file mode 100644 index 0000000..6b5d2d9 --- /dev/null +++ b/driver/floppy.c @@ -0,0 +1,214 @@ +/* floppy.c - floppy disk driver */ + +#include +#include +#include +#include + + +unsigned char floppy_flags = 0; +unsigned char floppy_num_drives = 0; +unsigned char floppy_drive_type; +unsigned char floppy_state = FLOPPY_STATE_IDLE; +unsigned char floppy_waiting = 0; +unsigned char floppy_requests = 0; +unsigned char ST0, ST1, ST2, ST3; + +struct floppy_request request; + + +static inline void send_floppy_byte(unsigned char byte) { + unsigned char status; + do IN_PORT_PP(PORT_FLOPPY_STATUS, status); while((status & 0xC0) != 0x80); + OUT_PORT(byte, PORT_FLOPPY_COMMAND_DATA); +} + +static inline unsigned char recv_floppy_byte() { + unsigned char status; + do IN_PORT_PP(PORT_FLOPPY_STATUS, status); while((status & 0xD0) != 0xD0); + IN_PORT_PP(PORT_FLOPPY_COMMAND_DATA, status); + return status; +} + +static inline void recalibrate(unsigned char drive) { + floppy_state = FLOPPY_STATE_RECALIBRATE; + floppy_waiting = 1; + send_floppy_byte(0x07); + send_floppy_byte(drive); +} + +void test() { + read_floppy_sectors(0, 0, 0, 1, 1); +} + +void init_floppy() { + unsigned short info; + unsigned char i; + + + //Kill motor + OUT_PORT(0x0C, PORT_FLOPPY_DOR); + + //List drives + asm( + "mov $0x28,%%ax\n" + "mov %%ax,%%fs\n" + "mov %%fs:0x0410,%0" + : "=a" (info) + ); + + if(info & 1) { + floppy_num_drives = ((info >> 6) & 3) + 1; + if(floppy_num_drives > 2) floppy_num_drives = 2; + if(floppy_num_drives == 1) print("1 floppy drive found\r\n"); + else print("2 floppy drives found\r\n"); + } + else { + print(" No floppy drives found...\r\n"); + return; + } + + + OUT_PORT(0x10, 0x70); + IN_PORT(0x71, floppy_drive_type); + + if((floppy_drive_type >> 4) & 0x0F) { + print(" fd0: "); + if(((floppy_drive_type >> 4) & 0x0F) > 5) print("unknown"); + else print(floppy_drive_types[(floppy_drive_type >> 4) & 0x0F]); + print("\r\n"); + } + + if(floppy_drive_type & 0x0F) { + print(" fd1: "); + if((floppy_drive_type & 0x0F) > 5) print("unknown"); + else print(floppy_drive_types[floppy_drive_type & 0x0F]); + print("\r\n"); + } + + // configure + + /*OUT_PORT(0x13, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0x1F, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0, PORT_FLOPPY_COMMAND_DATA); + + // specify + + OUT_PORT(0x03, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0xCF, PORT_FLOPPY_COMMAND_DATA); + OUT_PORT(0x06, PORT_FLOPPY_COMMAND_DATA);*/ +} + +int read_floppy_sectors(unsigned char drive, unsigned char cylinder, unsigned char head, unsigned char sector, unsigned char sector_count) { + unsigned char i; + + // test parameters + if(drive != 0 && drive != 1) return 1; + else if((drive == 0) && (((floppy_drive_type >> 4) & 0x0F) != 4)) return 2; + else if((drive == 1) && ((floppy_drive_type & 0x0F) != 4)) return 2; + + if(!sector_count) return 3; + + if(floppy_state == FLOPPY_STATE_IDLE) { + + //Activate drive motor + OUT_PORT((1 << (4 + drive)) | 0x0C, PORT_FLOPPY_DOR); + + print("TEST\n"); + + sleep(5000); + + print("TEST\n"); + + //Recalibrate + //recalibrate(drive); + } + + return 0; +} + +void floppy_proc() { + unsigned char i; + + /*IN_PORT(PORT_FLOPPY_STATUS, i); + print_hex_byte(i);*/ + //dma_clear_ff(); + //IN_PORT(0x04, i); + //print_hex_byte(i); + //IN_PORT(0x04, i); + //print_hex_byte(i); + /*IN_PORT(0x81, i); + print_hex_byte(i);*/ + //IN_PORT(0x05, i); + //print_hex_byte(i); + /*IN_PORT(0x05, i); + print_hex_byte(i);*/ + + if(floppy_waiting) return; + + if(floppy_state == FLOPPY_STATE_RECALIBRATE) { + floppy_state = FLOPPY_STATE_READ; + floppy_waiting = 1; + + dma_disable(2); + dma_clear_ff(); + dma_set_mode(2, DMA_MODE_SINGLE | DMA_MODE_READ | DMA_MODE_INC_ADDR); + dma_set_base_addr(2, (void*)0x200000); + dma_set_word_count(2, 0xFFFF); + dma_enable(2); + + send_floppy_byte(0xE6); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x02); + send_floppy_byte(0x02); + send_floppy_byte(0x01); + send_floppy_byte(0x1B); + send_floppy_byte(0xFF); + } +} + +void floppy_IRQ() { + //floppy_waiting = 0; + switch(floppy_state) { + case FLOPPY_STATE_RECALIBRATE: + print("Recalibrate FDC interrupt\n"); + //IN_PORT(PORT_FLOPPY_STATUS, i); + //print_hex_byte(i); + //floppy_state = FLOPPY_STATE_READ; + //floppy_waiting = 0; + send_floppy_byte(0x08); + //print_hex_byte(recv_floppy_byte()); + //print_hex_byte(recv_floppy_byte()); + ST0 = recv_floppy_byte(); + ST1 = recv_floppy_byte(); + + /*dma_disable(2); + dma_clear_ff(); + dma_set_mode(2, DMA_MODE_SINGLE | DMA_MODE_READ | DMA_MODE_INC_ADDR); + dma_set_base_addr(2, (void*)0x100000); + dma_set_word_count(2, 512); + dma_enable(2); + + send_floppy_byte(0xE6); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x00); + send_floppy_byte(0x01); + send_floppy_byte(0x02); + send_floppy_byte(0x01); + send_floppy_byte(0x1B); + send_floppy_byte(0xFF);*/ + + break; + case FLOPPY_STATE_READ: + print("Read FDC interrupt\n"); + floppy_state = FLOPPY_STATE_IDLE; + print_hex_long(*(unsigned long*)0x1FFB00); + break; + default: + print("Unexpected FDC interrupt!\n"); + } +} -- cgit v1.2.3