static int fd_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
- blkno_t block;
- uint16_t dptr;
+ uint16_t nb = udata.u_nblock;
int tries;
uint8_t err = 0;
uint8_t *driveptr = &fd_tab[minor & 1];
irqflags_t irq;
- uint8_t nblock;
-
- if(rawflag == 0) {
- dptr = (uint16_t)udata.u_buf->bf_data;
- block = udata.u_buf->bf_blk;
- nblock = 2;
- } else if (rawflag == 1) {
- if (((uint16_t)udata.u_offset|udata.u_count) & BLKMASK)
- goto bad2;
- dptr = (uint16_t)udata.u_base;
- block = udata.u_offset >> 9;
- nblock = udata.u_count >> 8;
- }
- else
+
+ if(rawflag == 1 && d_blkoff(9))
+ return -1;
+ udata.u_nblock *= 2;
+
+ if (rawflag == 2)
goto bad2;
irq = di();
// kprintf("Issue command: drive %d block %d\n", minor, block);
fd_cmd[0] = rawflag;
fd_cmd[1] = is_read ? FD_READ : FD_WRITE;
- fd_cmd[2] = block / 16; /* 2 sectors per block */
- fd_cmd[3] = ((block & 15) << 1); /* 0 - 1 base is corrected in asm */
+ fd_cmd[2] = udata.u_block / 16; /* 2 sectors per block */
+ fd_cmd[3] = ((udata.u_block & 15) << 1); /* 0 - 1 base is corrected in asm */
fd_cmd[4] = is_read ? OPDIR_READ: OPDIR_WRITE;
- fd_data = dptr;
+ fd_data = (uint16_t)udata.u_dptr;
- while (nblock--) {
+ while (udata.u_nblock--) {
for (tries = 0; tries < 4 ; tries++) {
// kprintf("Sector: %d Track %d\n", cmd[2]+1, cmd[1]);
err = fd_operation(driveptr);
fd_cmd[2]++;
}
}
- return 1;
+ return nb << BLKSHIFT;
bad:
kprintf("fd%d: error %x\n", minor, err);
bad2:
/*
* Memotech Silicon Disk Driver
*
- * FIXME: would be sensible to add swap support to this driver
+ * FIXME: would be sensible to add swap support to this driver for boxes with
+ * < 512K RAM.
+ *
+ * FIXME: Check presence of device by probing ?
*/
#include <kernel.h>
static int sil_transfer(uint8_t minor, bool is_read, uint8_t rawflag)
{
- blkno_t block;
- int block_xfer;
- uint16_t dptr;
- int dlen;
int ct = 0;
- int map;
+ int map = 0;
+ uint8_t unit = 0x50 + 4 * minor;
- if(rawflag) {
- dlen = udata.u_count;
- dptr = (uint16_t)udata.u_base;
- if (((uint16_t)dptr | dlen) & BLKMASK) {
- udata.u_error = EIO;
+ if(rawflag == 1) {
+ if (d_blkoff(BLKSHIFT))
return -1;
- }
- block = udata.u_offset >> 9;
- block_xfer = dlen >> 9;
map = udata.u_page;
- } else { /* rawflag == 0 */
- dlen = 512;
- dptr = (uint16_t)udata.u_buf->bf_data;
- block = udata.u_buf->bf_blk;
- block_xfer = 1;
- map = 0;
}
-
- while (ct < block_xfer) {
- sil_memcpy(is_read, map, dptr, block, 0x50 + 4 * minor);
- block++;
+ if (rawflag == 2)
+ return -1;
+
+ while (ct < udata.u_nblock) {
+ sil_memcpy(is_read, map, (uint16_t)udata.u_dptr, udata.u_block, unit);
+ udata.u_dptr += BLKSIZE;
+ udata.u_block++;
ct++;
}
- return ct;
+ return ct << BLKSHIFT;
}
int sil_open(uint8_t minor, uint16_t flag)