/******************************************************************************* * bool floppy_block_write(unsigned int block, void *blockbuff, * unsigned int nosectors) * * This writes the contents of 'blockbuff' onto a floppy disk, starting at 'block' * and going for 'nosectors' * * Parameters: * 1) int block * The starting sector to write to * 2) unsigned char *blockbuff * The buffer to read from when writing * * Date: December 31, 2004 * *****************************************************************************/ bool floppy_block_write(unsigned int block, void *blockbuff, unsigned int nosectors) { return floppy_rw(block, blockbuff, false, nosectors); }
/******************************************************************************* * bool floppy_block_read(unsigned int block, void *blockbuff, * unsigned int nosectors) * * This reads data from a floppy disk starting at 'block' and reads 'nosectors' * number of blocks. * * Parameters: * 1) int block * The starting sector to read * 2) unsigned char *blockbuff * The buffer to be read into * 3) unsigned long nosectors * How many sectors do we want to read in? * * Date: December 31, 2004 * *****************************************************************************/ bool floppy_block_read(unsigned int block, void *blockbuff, unsigned int nosectors) { return floppy_rw(block, blockbuff, true, nosectors); }
/* Write ONE sector */ int floppy_write(int sector, void * buf) { return floppy_rw(sector, buf, FD_WRITE); }
/******************************************************************************* * bool floppy_rw(int block, unsigned char *blockbuff, * unsigned char read, unsigned long nosectors) * * Since the read and write to a floppy disk is not that much different, most of * the code is the same. The only difference is dependent on what the 'read' * variable is set as. * * Parameters: * 1) int block * This is the block that we want to read. * 2) unsigned char *blockbuff * This is the buffer that we want it read into or written out to. The size * of this buffer should be 512 * nosectors, as each sector read in is 512 * bytes * 3) unsigned char read * Are we going to read or write to this block. * 4) unsigned long nosectors * The number of sectors that we want to be read in. * * Return value: * This returns where or not the read/write was successfull. * * Date: December 31, 2004 * *****************************************************************************/ bool floppy_rw(int block, unsigned char *blockbuff, unsigned char read, unsigned long nosectors) { int head; int track; int sector; int tries; int copycount=0; unsigned char *p_track_buffer = (unsigned char*)floppy_dma_address; unsigned char *p_block_buffer = blockbuff; ///convert logical address into physical address floppy_block2hts(block , &head, &track, §or); ///start the floppy motor floppy_motor_start(); if (!read && blockbuff) ///copy data from the data buffer into the track buffer for (copycount=0; copycount<(nosectors*512); copycount++) *(p_track_buffer++) = *(p_block_buffer++); for (tries = 0; tries < 3; tries++) { ///check for disk change if (inportb(FDC_DIR) & 0x80) { floppy_dchange = true; floppy_seek(1); floppy_recalibrate(); floppy_motor_stop(); ERROR_MSG(("FDC: Disk change detected. Trying again.")); return floppy_rw(block, blockbuff, read, nosectors); } ///move head to the right track if (!floppy_seek(track)) { floppy_motor_stop(); ERROR_MSG(("FDC: Seek error")); return false; } ///program data rate (500Kb/s) outportb(FDC_CCR, 0); ///send command if (read) { dma_xfer(2, (unsigned long)floppy_dma_address, nosectors*512, false); floppy_sendbyte(CMD_READ); } else { dma_xfer(2, (unsigned long)floppy_dma_address, nosectors*512, true); floppy_sendbyte(CMD_WRITE); } floppy_sendbyte(head << 2); floppy_sendbyte(track); floppy_sendbyte(head); floppy_sendbyte(sector); floppy_sendbyte(2); floppy_sendbyte(floppy_geometry.spt); if (floppy_geometry.spt == DG144_SPT) floppy_sendbyte(DG144_GAP3RW); else floppy_sendbyte(DG168_GAP3RW); floppy_sendbyte(0xff); ///wait for commmand completion if (!floppy_wait(true)) { ERROR_MSG(("Timed out, trying operation again after reset")); floppy_reset(); return floppy_rw(block, blockbuff, read, nosectors); } ///let's see if the transfer worked if ((floppy_status[0] & 0xC0) == 0) break; ///it didn't work. try again floppy_recalibrate(); } floppy_motor_stop(); if (read && blockbuff) { ///copy data from track buffer into data buffer p_block_buffer = blockbuff; p_track_buffer = (unsigned char *)floppy_dma_address; for (copycount = 0; copycount <(nosectors*512); copycount++) { *p_block_buffer = *p_track_buffer; p_block_buffer++; p_track_buffer++; } } return (tries != 3); }
/* Read ONE sector */ int floppy_read(int sector, void * buf) { return floppy_rw(sector, buf, FD_READ); }