📄 bddrv.c
字号:
printf("floppy_await_interrupt: timeout\n");
return -1;
}
/* read in command result bytes */
for(temp = 0; temp < 7; temp++)
{
if((inportb(ioadr + FDC_MSR) & 0x10) == 0)
break;
status[temp] = floppy_get_byte(ioadr);
}
/* perform "sense interrupt" */
floppy_send_byte(ioadr, 0x08); /* CMD_SENSEI */
fdev->sr0 = floppy_get_byte(ioadr);
fdev->curr_track = floppy_get_byte(ioadr);
/* */
#if 1
DEBUG(printf("status byte returned by floppy controller: 0x%X\n",
status[0]);)
#else
DEBUG(
printf("status returned by floppy controller:\n");
printf("drive %u, head %u\n", status[0] & 3,
(status[0] >> 2) & 1);
printf("not ready on R/W or SS access to head 1: %u\n",
(status[0] >> 3) & 1);
printf("equipment check: %u\n",
(status[0] >> 4) & 1);
printf("seek complete: %u\n",
(status[0] >> 5) & 1);
printf("last command status: ");
switch(status[0] >> 6)
{
case 0: printf("success\n"); break;
case 1: printf("started OK but abnormal termination\n"); break;
case 2: printf("invalid command issued\n"); break;
case 3: printf("abnormal termination because READY changed state\n"); break;
}
)
#endif
return status[0];
}
/*****************************************************************************
*****************************************************************************/
static int floppy_seek(floppy_t *dev, unsigned char track)
{
unsigned short ioadr;
DEBUG(printf("floppy_seek: seeking track %u\n", track);)
/* already there? */
if(dev->curr_track == track)
return 0;
/* turn on the motor */
floppy_motor_on(dev);
/* send the actual command bytes */
ioadr = dev->blkdev.io.adr[0];
floppy_send_byte(ioadr, 0x0F); /* CMD_SEEK */
floppy_send_byte(ioadr, 0);
floppy_send_byte(ioadr, track);
/* wait until seek finished */
if(floppy_await_interrupt(dev) < 0)
return -1;
/* now let head settle for 15ms
xxx - use interrupt */
msleep(15);
DEBUG(printf("floppy_seek: sr0=0x%X (should be 0x20), curr_track=%u "
"(should be %u)\n", dev->sr0, dev->curr_track, track);)
floppy_motor_off(dev);
/* check that seek worked */
if(dev->sr0 != 0x20 || dev->curr_track != track)
return -1;
return 0;
}
/*****************************************************************************
*****************************************************************************/
static int floppy_recalibrate(floppy_t *fdev)
{
unsigned short ioadr;
DEBUG(printf("floppy_recalibrate:\n");)
ioadr = fdev->blkdev.io.adr[0];
floppy_send_byte(ioadr, 0x07);
floppy_send_byte(ioadr, 0);
return floppy_await_interrupt(fdev) < 0;
}
/*****************************************************************************
*****************************************************************************/
static int floppy_error(request_t *req)
{
floppy_t *fdev;
unsigned short ioadr;
DEBUG(printf("*** floppy_error: ***\n");)
/* increment req->errors */
(req->errors)++;
if(req->errors >= 3)
return -1;
/* */
fdev = (floppy_t *)req->dev;
ioadr = fdev->blkdev.io.adr[0];
/* if disk change, seek track 1 (xxx - one? not zero?) */
if(inportb(ioadr + FDC_DIR) & 0x80)
{
DEBUG(printf("floppy_error: disk change\n");)
if(floppy_seek(fdev, 1) != 0)
{
/* if that fails, we're screwed... */
floppy_motor_off(fdev);
return -1;
}
}
return floppy_recalibrate(fdev);
}
/*****************************************************************************
*****************************************************************************/
static int floppy_rw(request_t *req)
{
unsigned short ioadr, sector, head, num_bytes, num_blks;
unsigned long blk, adr;
blkdev_t *blkdev;
floppy_t *fdev;
int temp;
DEBUG(printf("floppy_rw:\n");)
fdev = (floppy_t *)req->dev;
/* if floppy_t struct had a magic value in it, we could validate it here */
blkdev = &fdev->blkdev;
/* select drive and spin up the disk */
floppy_motor_on(fdev);
ioadr = blkdev->io.adr[0];
do
{
blk = req->blk;
sector = blk % blkdev->sectors + 1;
blk /= blkdev->sectors;
head = blk % blkdev->heads;
blk /= blkdev->heads;
DEBUG(printf("floppy_rw: CHS=%lu:%u:%u\n", blk, head,
sector);)
/* do not cross a track boundary */
num_blks = min(req->num_blks, blkdev->sectors -
req->blk % blkdev->sectors);
num_bytes = num_blks * blkdev->bytes_per_blk;
DEBUG(printf("floppy_rw: transferring %u blocks (%u bytes)\n",
num_blks, num_bytes);)
/* disk change? */
if(inportb(ioadr + FDC_DIR) & 0x80)
goto ERR;
/* seek to correct track */
if(floppy_seek(fdev, blk) != 0)
goto ERR;
/* program data rate (500K/s) */
outportb(ioadr + FDC_CCR, 0);
/* copy data to 64K-aligned conventional memory buffer */
if(req->cmd == BLK_CMD_WRITE)
movedata(_DS, (unsigned)req->buf,
LMEM_SEG, LMEM_OFF,
num_bytes);
#if defined(__TURBOC__)
adr = LMEM_SEG;
adr <<= 4;
adr += LMEM_OFF;
#elif defined(__DJGPP__)
adr = LMEM_OFF;
#endif
if(req->cmd == BLK_CMD_READ)
{
DEBUG(printf("floppy_rw: read\n");)
floppy_send_byte(ioadr, 0xE6);//CMD_READ);
/* xxx - 2 is DMA number. Can't use blkdev->io.dma; it is a mask
Dammit, I forgot to subtract one here to convert length into terminal count.
Made that error with my sound software, too. */
if(dma_read(2, adr, num_bytes - 1) != 0)
{
printf("floppy_rw: error from dma_read()\n");
goto ERR;
}
}
else// if(req->cmd == BLK_CMD_WRITE)
{
DEBUG(printf("floppy_rw: write\n");)
floppy_send_byte(ioadr, 0xC5);//CMD_WRITE);
if(dma_write(2, adr, num_bytes - 1) != 0)
{
printf("floppy_rw: error from dma_write()\n");
goto ERR;
}
}
/* head and drive select */
floppy_send_byte(ioadr, (head << 2) | blkdev->unit);
/* C, H, S, N */
floppy_send_byte(ioadr, blk);
floppy_send_byte(ioadr, head);
floppy_send_byte(ioadr, sector);
floppy_send_byte(ioadr, 2); /* 512 bytes/sector */
/* EOT */
floppy_send_byte(ioadr, blkdev->sectors);
/* gap 3 length for 1.44M or 1.68M floppies */
if(blkdev->sectors == 18)
floppy_send_byte(ioadr, 0x1B);
else //if(blkdev->sectors == 21)
floppy_send_byte(ioadr, 0x1C);
floppy_send_byte(ioadr, 0xFF); /* DTL = unused */
/* wait up to 1 second for IRQ 6 */
temp = floppy_await_interrupt(fdev);
if((temp < 0) || (temp & 0xC0))
{
ERR:
temp = floppy_error(req);
/* if floppy_error() returns non-zero, then we are doomed... */
if(temp != 0)
return temp;
/* ...else try again */
else
continue;
}
/* copy data from 64K-aligned conventional memory buffer */
if(req->cmd == BLK_CMD_READ)
movedata(LMEM_SEG, LMEM_OFF,
_DS, (unsigned)req->buf,
num_bytes);
/* advance pointers */
req->num_blks -= num_blks;
req->blk += num_blks;
req->buf += num_bytes;
} while (req->num_blks != 0);
floppy_motor_off(fdev);
return 0;
}
//////////////////////////////////////////////////////////////////////////////
// MAIN/DEMO ROUTINES
//////////////////////////////////////////////////////////////////////////////
/*****************************************************************************
*****************************************************************************/
static void INTERRUPT irq6(void)
{
_interrupt_occurred |= 0x0040;
outportb(0x20, 0x20);
}
/*****************************************************************************
*****************************************************************************/
static void INTERRUPT irq14(void)
{
_interrupt_occurred |= 0x4000;
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
/*****************************************************************************
*****************************************************************************/
static void INTERRUPT irq15(void)
{
_interrupt_occurred |= 0x8000;
outportb(0xA0, 0x20);
outportb(0x20, 0x20);
}
/*****************************************************************************
*****************************************************************************/
#define _18K 18432
#define FLOPPY 1
#if defined(__TURBOC__)
#define LEN (32768u + 2048)
#elif defined(__DJGPP__)
#define LEN 92160u
#endif
static unsigned char _big_buf[LEN];
int main(void)
{
vector_t vector6, vector14, vector15;
request_t freq, creq;
floppy_t fdev;
unsigned temp, foo;
unsigned char buf[_18K];
memset(&fdev, 0, sizeof(fdev));
fdev.blkdev.io.dma = 0x04;
fdev.blkdev.io.irq = 0x0040;
fdev.blkdev.io.adr[0] = 0x3F0;
/* 8 bytes at 0x3F0
xxx - steer clear of 0x3F6? Win95 says 0x3F2-0x3F5, but we need 0x3F7 too */
fdev.blkdev.io.span[0] = 8;
// fdev.blkdev.unit = ?;
fdev.blkdev.num_blks = 2880;
fdev.blkdev.bytes_per_blk = 512;
fdev.blkdev.sectors = 18; /* xxx - probe this, somehow */
fdev.blkdev.heads = 2;
fdev.blkdev.cyls = 80;
fdev.curr_track = -1;
memset(&creq, 0, sizeof(creq));
creq.cmd = BLK_CMD_READ;
creq.dev = _drives + 1;
memset(&freq, 0, sizeof(freq));
freq.dev = &fdev;
/* */
SAVE_VECT(14, vector6);
SAVE_VECT(118, vector14);
SAVE_VECT(119, vector15);
SET_VECT(14, irq6);
SET_VECT(118, irq14);
SET_VECT(119, irq15);
/* */
ide_probe();
/* */
#if 0
/******
check if CD-ROM drive can rip audio
look for "CD-DA commands: YES"
xxx - not sure about this
******/
(void)atapi_mode_sense(_drives + 1);
#elif 0
/******
this is both incomplete and untested, so don't use it
1 block of CD-DA data = 2352 bytes = 1/75 sec of audio
******/
creq.buf = buf;
creq.num_blks = 1;
(void)atapi_rip_audio(&creq);
#elif 0
/******
read from CD-ROM
******/
creq.buf = buf;
creq.num_blks = 9;
creq.blk = 16;
(void)atapi_read_sectors(&creq);
dump(buf, 128);
#elif 0
/******
read from floppy
******/
foo = fdev.blkdev.sectors * /* =18 */
fdev.blkdev.heads; /* =2 */
freq.cmd = BLK_CMD_READ;
freq.buf = buf;
freq.num_blks = foo;
freq.blk = 0;
(void)floppy_rw(&freq);
dump(buf, 128);
#elif 0
/******
copy data from CD-ROM to disk file
******/
creq.buf = _big_buf;
creq.num_blks = LEN / 2048;
creq.blk = 0;
if(atapi_read_sectors(&creq) != 0)
{
printf("atapi_read_sectors failed\n");
goto ERR;
}
RESTORE_VECT(14, vector6);
RESTORE_VECT(118, vector14);
RESTORE_VECT(119, vector15);
{
FILE *out;
out = fopen("data.bin", "wb");
if(out == NULL)
exit(0);
fwrite(_big_buf, 1, LEN, out);
fclose(out);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -