static void fdctrl_write_data (fdctrl_t *fdctrl, uint32_t value) { fdrive_t *cur_drv; int pos; /* Reset mode */ if (!(fdctrl->dor & FD_DOR_nRESET)) { FLOPPY_DPRINTF("Floppy controller in RESET state !\n"); return; } if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) { FLOPPY_ERROR("controller not ready for writing\n"); return; } fdctrl->dsr &= ~FD_DSR_PWRDOWN; /* Is it write command time ? */ if (fdctrl->msr & FD_MSR_NONDMA) { /* FIFO data write */ fdctrl->fifo[fdctrl->data_pos++] = value; if (fdctrl->data_pos % FD_SECTOR_LEN == (FD_SECTOR_LEN - 1) || fdctrl->data_pos == fdctrl->data_len) { cur_drv = get_cur_drv(fdctrl); if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { FLOPPY_ERROR("writing sector %d\n", fd_sector(cur_drv)); return; } if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { FLOPPY_DPRINTF("error seeking to next sector %d\n", fd_sector(cur_drv)); return; } } /* Switch from transfer mode to status mode * then from status mode to command mode */ if (fdctrl->data_pos == fdctrl->data_len) fdctrl_stop_transfer(fdctrl, FD_SR0_SEEK, 0x00, 0x00); return; } if (fdctrl->data_pos == 0) { /* Command */ pos = command_to_handler[value & 0xff]; FLOPPY_DPRINTF("%s command\n", handlers[pos].name); fdctrl->data_len = handlers[pos].parameters + 1; } FLOPPY_DPRINTF("%s: %02x\n", __func__, value); fdctrl->fifo[fdctrl->data_pos++] = value; if (fdctrl->data_pos == fdctrl->data_len) { /* We now have all parameters * and will be able to treat the command */ if (fdctrl->data_state & FD_STATE_FORMAT) { fdctrl_format_sector(fdctrl); return; } pos = command_to_handler[fdctrl->fifo[0] & 0xff]; FLOPPY_DPRINTF("treat %s command\n", handlers[pos].name); (*handlers[pos].handler)(fdctrl, handlers[pos].direction); } }