static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)

{

    fdrive_t *cur_drv;

    uint8_t kh, kt, ks;

    int did_seek;



    fdctrl->cur_drv = fdctrl->fifo[1] & 1;

    cur_drv = get_cur_drv(fdctrl);

    kt = fdctrl->fifo[2];

    kh = fdctrl->fifo[3];

    ks = fdctrl->fifo[4];

    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",

                   fdctrl->cur_drv, kh, kt, ks,

                   _fd_sector(kh, kt, ks, cur_drv->last_sect));

    did_seek = 0;

    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {

    case 2:

        /* sect too big */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 3:

        /* track too big */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 4:

        /* No seek enabled */

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 1:

        did_seek = 1;

        break;

    default:

        break;

    }

    /* Set the FIFO state */

    fdctrl->data_dir = direction;

    fdctrl->data_pos = 0;

    FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); /* FIFO ready for data */

    if (fdctrl->fifo[0] & 0x80)

        fdctrl->data_state |= FD_STATE_MULTI;

    else

        fdctrl->data_state &= ~FD_STATE_MULTI;

    if (did_seek)

        fdctrl->data_state |= FD_STATE_SEEK;

    else

        fdctrl->data_state &= ~FD_STATE_SEEK;

    if (fdctrl->fifo[5] == 00) {

        fdctrl->data_len = fdctrl->fifo[8];

    } else {

	int tmp;

        fdctrl->data_len = 128 << fdctrl->fifo[5];

        tmp = (cur_drv->last_sect - ks + 1);

        if (fdctrl->fifo[0] & 0x80)

            tmp += cur_drv->last_sect;

	fdctrl->data_len *= tmp;

    }

    fdctrl->eot = fdctrl->fifo[6];

    if (fdctrl->dma_en) {

        int dma_mode;

        /* DMA transfer are enabled. Check if DMA channel is well programmed */

        dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);

        dma_mode = (dma_mode >> 2) & 3;

        FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",

		       dma_mode, direction,

                       (128 << fdctrl->fifo[5]) *

		       (cur_drv->last_sect - ks + 1), fdctrl->data_len);

        if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||

              direction == FD_DIR_SCANH) && dma_mode == 0) ||

            (direction == FD_DIR_WRITE && dma_mode == 2) ||

            (direction == FD_DIR_READ && dma_mode == 1)) {

            /* No access is allowed until DMA transfer has completed */

            fdctrl->state |= FD_CTRL_BUSY;

            /* Now, we just have to wait for the DMA controller to

             * recall us...

             */

            DMA_hold_DREQ(fdctrl->dma_chann);

            DMA_schedule(fdctrl->dma_chann);

            return;

        } else {

	    FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);

        }

    }

    FLOPPY_DPRINTF("start non-DMA transfer\n");

    /* IO based transfer: calculate len */

    fdctrl_raise_irq(fdctrl, 0x00);



    return;

}

static void fdctrl_start_transfer (fdctrl_t *fdctrl, int direction)

{

    fdrive_t *cur_drv;

    uint8_t kh, kt, ks;

    int did_seek;



    fdctrl->cur_drv = fdctrl->fifo[1] & 1;

    cur_drv = get_cur_drv(fdctrl);

    kt = fdctrl->fifo[2];

    kh = fdctrl->fifo[3];

    ks = fdctrl->fifo[4];

    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",

                   fdctrl->cur_drv, kh, kt, ks,

                   _fd_sector(kh, kt, ks, cur_drv->last_sect));

    did_seek = 0;

    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & 0x40)) {

    case 2:

        

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 3:

        

        fdctrl_stop_transfer(fdctrl, 0x40, 0x80, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 4:

        

        fdctrl_stop_transfer(fdctrl, 0x40, 0x00, 0x00);

        fdctrl->fifo[3] = kt;

        fdctrl->fifo[4] = kh;

        fdctrl->fifo[5] = ks;

        return;

    case 1:

        did_seek = 1;

        break;

    default:

        break;

    }

    

    fdctrl->data_dir = direction;

    fdctrl->data_pos = 0;

    FD_SET_STATE(fdctrl->data_state, FD_STATE_DATA); 

    if (fdctrl->fifo[0] & 0x80)

        fdctrl->data_state |= FD_STATE_MULTI;

    else

        fdctrl->data_state &= ~FD_STATE_MULTI;

    if (did_seek)

        fdctrl->data_state |= FD_STATE_SEEK;

    else

        fdctrl->data_state &= ~FD_STATE_SEEK;

    if (fdctrl->fifo[5] == 00) {

        fdctrl->data_len = fdctrl->fifo[8];

    } else {

	int tmp;

        fdctrl->data_len = 128 << fdctrl->fifo[5];

        tmp = (cur_drv->last_sect - ks + 1);

        if (fdctrl->fifo[0] & 0x80)

            tmp += cur_drv->last_sect;

	fdctrl->data_len *= tmp;

    }

    fdctrl->eot = fdctrl->fifo[6];

    if (fdctrl->dma_en) {

        int dma_mode;

        

        dma_mode = DMA_get_channel_mode(fdctrl->dma_chann);

        dma_mode = (dma_mode >> 2) & 3;

        FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",

		       dma_mode, direction,

                       (128 << fdctrl->fifo[5]) *

		       (cur_drv->last_sect - ks + 1), fdctrl->data_len);

        if (((direction == FD_DIR_SCANE || direction == FD_DIR_SCANL ||

              direction == FD_DIR_SCANH) && dma_mode == 0) ||

            (direction == FD_DIR_WRITE && dma_mode == 2) ||

            (direction == FD_DIR_READ && dma_mode == 1)) {

            

            fdctrl->state |= FD_CTRL_BUSY;

            





            DMA_hold_DREQ(fdctrl->dma_chann);

            DMA_schedule(fdctrl->dma_chann);

            return;

        } else {

	    FLOPPY_ERROR("dma_mode=%d direction=%d\n", dma_mode, direction);

        }

    }

    FLOPPY_DPRINTF("start non-DMA transfer\n");

    

    fdctrl_raise_irq(fdctrl, 0x00);



    return;

}

        fdctrl->data_len = 128 << fdctrl->fifo[5];
static void FUNC_0 (fdctrl_t *VAR_0, int VAR_1)

{

    fdrive_t *cur_drv;

    uint8_t kh, kt, ks;

    int VAR_2;



    VAR_0->cur_drv = VAR_0->fifo[1] & 1;

    cur_drv = get_cur_drv(VAR_0);

    kt = VAR_0->fifo[2];

    kh = VAR_0->fifo[3];

    ks = VAR_0->fifo[4];

    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",

                   VAR_0->cur_drv, kh, kt, ks,

                   _fd_sector(kh, kt, ks, cur_drv->last_sect));

    VAR_2 = 0;

    switch (fd_seek(cur_drv, kh, kt, ks, VAR_0->config & 0x40)) {

    case 2:

        

        fdctrl_stop_transfer(VAR_0, 0x40, 0x00, 0x00);

        VAR_0->fifo[3] = kt;

        VAR_0->fifo[4] = kh;

        VAR_0->fifo[5] = ks;

        return;

    case 3:

        

        fdctrl_stop_transfer(VAR_0, 0x40, 0x80, 0x00);

        VAR_0->fifo[3] = kt;

        VAR_0->fifo[4] = kh;

        VAR_0->fifo[5] = ks;

        return;

    case 4:

        

        fdctrl_stop_transfer(VAR_0, 0x40, 0x00, 0x00);

        VAR_0->fifo[3] = kt;

        VAR_0->fifo[4] = kh;

        VAR_0->fifo[5] = ks;

        return;

    case 1:

        VAR_2 = 1;

        break;

    default:

        break;

    }

    

    VAR_0->data_dir = VAR_1;

    VAR_0->data_pos = 0;

    FD_SET_STATE(VAR_0->data_state, FD_STATE_DATA); 

    if (VAR_0->fifo[0] & 0x80)

        VAR_0->data_state |= FD_STATE_MULTI;

    else

        VAR_0->data_state &= ~FD_STATE_MULTI;

    if (VAR_2)

        VAR_0->data_state |= FD_STATE_SEEK;

    else

        VAR_0->data_state &= ~FD_STATE_SEEK;

    if (VAR_0->fifo[5] == 00) {

        VAR_0->data_len = VAR_0->fifo[8];

    } else {

	int VAR_3;

        VAR_0->data_len = 128 << VAR_0->fifo[5];

        VAR_3 = (cur_drv->last_sect - ks + 1);

        if (VAR_0->fifo[0] & 0x80)

            VAR_3 += cur_drv->last_sect;

	VAR_0->data_len *= VAR_3;

    }

    VAR_0->eot = VAR_0->fifo[6];

    if (VAR_0->dma_en) {

        int VAR_4;

        

        VAR_4 = DMA_get_channel_mode(VAR_0->dma_chann);

        VAR_4 = (VAR_4 >> 2) & 3;

        FLOPPY_DPRINTF("VAR_4=%d VAR_1=%d (%d - %d)\n",

		       VAR_4, VAR_1,

                       (128 << VAR_0->fifo[5]) *

		       (cur_drv->last_sect - ks + 1), VAR_0->data_len);

        if (((VAR_1 == FD_DIR_SCANE || VAR_1 == FD_DIR_SCANL ||

              VAR_1 == FD_DIR_SCANH) && VAR_4 == 0) ||

            (VAR_1 == FD_DIR_WRITE && VAR_4 == 2) ||

            (VAR_1 == FD_DIR_READ && VAR_4 == 1)) {

            

            VAR_0->state |= FD_CTRL_BUSY;

            





            DMA_hold_DREQ(VAR_0->dma_chann);

            DMA_schedule(VAR_0->dma_chann);

            return;

        } else {

	    FLOPPY_ERROR("VAR_4=%d VAR_1=%d\n", VAR_4, VAR_1);

        }

    }

    FLOPPY_DPRINTF("start non-DMA transfer\n");

    

    fdctrl_raise_irq(VAR_0, 0x00);



    return;

}

static void FUNC_0 (fdctrl_t *VAR_0, int VAR_1)
{ fdrive_t *cur_drv; uint8_t kh, kt, ks; int VAR_2; VAR_0->cur_drv = VAR_0->fifo[1] & 1; cur_drv = get_cur_drv(VAR_0); kt = VAR_0->fifo[2]; kh = VAR_0->fifo[3]; ks = VAR_0->fifo[4]; FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
VAR_0->cur_drv, kh, kt, ks,
_fd_sector(kh, kt, ks, cur_drv->last_sect)); VAR_2 = 0; switch (fd_seek(cur_drv, kh, kt, ks, VAR_0->config & 0x40)) { case 2:
fdctrl_stop_transfer(VAR_0, 0x40, 0x00, 0x00); VAR_0->fifo[3] = kt; VAR_0->fifo[4] = kh; VAR_0->fifo[5] = ks; return; case 3:
fdctrl_stop_transfer(VAR_0, 0x40, 0x80, 0x00); VAR_0->fifo[3] = kt; VAR_0->fifo[4] = kh; VAR_0->fifo[5] = ks; return; case 4:
fdctrl_stop_transfer(VAR_0, 0x40, 0x00, 0x00); VAR_0->fifo[3] = kt; VAR_0->fifo[4] = kh; VAR_0->fifo[5] = ks; return; case 1:
VAR_2 = 1; break; default:
break; } VAR_0->data_dir = VAR_1; VAR_0->data_pos = 0; FD_SET_STATE(VAR_0->data_state, FD_STATE_DATA); if (VAR_0->fifo[0] & 0x80)
VAR_0->data_state |= FD_STATE_MULTI; else
VAR_0->data_state &= ~FD_STATE_MULTI; if (VAR_2)
VAR_0->data_state |= FD_STATE_SEEK; else
VAR_0->data_state &= ~FD_STATE_SEEK; if (VAR_0->fifo[5] == 00) { VAR_0->data_len = VAR_0->fifo[8]; } else { int VAR_3; VAR_0->data_len = 128 << VAR_0->fifo[5]; VAR_3 = (cur_drv->last_sect - ks + 1); if (VAR_0->fifo[0] & 0x80)
VAR_3 += cur_drv->last_sect; VAR_0->data_len *= VAR_3; } VAR_0->eot = VAR_0->fifo[6]; if (VAR_0->dma_en) { int VAR_4; VAR_4 = DMA_get_channel_mode(VAR_0->dma_chann); VAR_4 = (VAR_4 >> 2) & 3; FLOPPY_DPRINTF("VAR_4=%d VAR_1=%d (%d - %d)\n",
VAR_4, VAR_1,
(128 << VAR_0->fifo[5]) *
(cur_drv->last_sect - ks + 1), VAR_0->data_len); if (((VAR_1 == FD_DIR_SCANE || VAR_1 == FD_DIR_SCANL ||
VAR_1 == FD_DIR_SCANH) && VAR_4 == 0) ||
(VAR_1 == FD_DIR_WRITE && VAR_4 == 2) ||
(VAR_1 == FD_DIR_READ && VAR_4 == 1)) { VAR_0->state |= FD_CTRL_BUSY; DMA_hold_DREQ(VAR_0->dma_chann); DMA_schedule(VAR_0->dma_chann); return; } else { FLOPPY_ERROR("VAR_4=%d VAR_1=%d\n", VAR_4, VAR_1); } } FLOPPY_DPRINTF("start non-DMA transfer\n"); fdctrl_raise_irq(VAR_0, 0x00); return; }