コード例 #1
0
ファイル: ssem_sys.c プロジェクト: BillHeaton/simh
t_stat ssem_dump (FILE *fi)
{
if (sim_fwrite(A, sizeof(int32), 1, fi) != 1 ||
    sim_fwrite(C, sizeof(uint32), 1, fi) != 1 ||
    sim_fwrite(S, sizeof(uint32), MEMSIZE, fi) != MEMSIZE) {
    return SCPE_IOERR;
    }
return SCPE_OK;
}
コード例 #2
0
ファイル: cdc1700_dp.c プロジェクト: agn453/simh
/*
 * Initiate a write operation on a disk.
 */
static enum dpio_status DPDiskIOWrite(UNIT *uptr)
{
  struct dpio_unit *iou = (struct dpio_unit *)uptr->up7;
  uint16 numcy = ((uptr->flags & UNIT_854) != 0) ? DP_854CY : DP_853CY;
  uint32 lba = DPLBA(iou);
  t_bool fill = FALSE;
  int i;

  if (iou->cylinder >= numcy)
    return DPIO_ADDRERR;

  for (i = 0; i < DP_NUMWD; i++) {
    if (!fill) {
      iou->buf[i] = LoadFromMem(iou->CWA);
      iou->CWA++;
      if (iou->CWA == iou->LWA)
        fill = TRUE;
    } else iou->buf[i] = 0;
  }

  /*
   * Report any error in the underlying container infrastructure as an
   * address error.
   */
  if (sim_fseeko(uptr->fileref, lba * DP_NUMBY, SEEK_SET) ||
      (sim_fwrite(iou->buf, sizeof(uint16), DP_NUMWD, uptr->fileref) != DP_NUMWD))
    return DPIO_ADDRERR;

  DPDiskIOIncSector(iou);
  return fill ? DPIO_DONE : DPIO_MORE;
}
コード例 #3
0
ファイル: sim_tape.c プロジェクト: charlesUnixPro/dps8m
t_stat sim_tape_wrrecf (UNIT *uptr, uint8 *buf, t_mtrlnt bc)
{
uint32 f = MT_GET_FMT (uptr);
t_mtrlnt sbc;

MT_CLR_PNU (uptr);
sbc = MTR_L (bc);
if ((uptr->flags & UNIT_ATT) == 0)                      /* not attached? */
    return MTSE_UNATT;
if (sim_tape_wrp (uptr))                                /* write prot? */
    return MTSE_WRP;
if (sbc == 0)                                           /* nothing to do? */
    return MTSE_OK;
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);         /* set pos */
switch (f) {                                            /* case on format */

    case MTUF_F_STD:                                    /* standard */
        sbc = MTR_L ((bc + 1) & ~1);                    /* pad odd length */
    case MTUF_F_E11:                                    /* E11 */
        sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
        sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref);
        sim_fwrite (&bc, sizeof (t_mtrlnt), 1, uptr->fileref);
        if (ferror (uptr->fileref)) {                   /* error? */
            MT_SET_PNU (uptr);
            return sim_tape_ioerr (uptr);
            }
        uptr->pos = uptr->pos + sbc + (2 * sizeof (t_mtrlnt));  /* move tape */
        break;

    case MTUF_F_P7B:                                    /* Pierce 7B */
        buf[0] = buf[0] | P7B_SOR;                      /* mark start of rec */
        sim_fwrite (buf, sizeof (uint8), sbc, uptr->fileref);
        sim_fwrite (buf, sizeof (uint8), 1, uptr->fileref); /* delimit rec */
        if (ferror (uptr->fileref)) {                   /* error? */
            MT_SET_PNU (uptr);
            return sim_tape_ioerr (uptr);
            }
        uptr->pos = uptr->pos + sbc;                    /* move tape */
        break;
        }

return MTSE_OK;
}
コード例 #4
0
ファイル: sim_tape.c プロジェクト: charlesUnixPro/dps8m
t_stat sim_tape_wrdata (UNIT *uptr, uint32 dat)
{
MT_CLR_PNU (uptr);
if ((uptr->flags & UNIT_ATT) == 0)                      /* not attached? */
    return MTSE_UNATT;
if (sim_tape_wrp (uptr))                                /* write prot? */
    return MTSE_WRP;
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);         /* set pos */
sim_fwrite (&dat, sizeof (t_mtrlnt), 1, uptr->fileref);
if (ferror (uptr->fileref)) {                           /* error? */
    MT_SET_PNU (uptr);
    return sim_tape_ioerr (uptr);
    }
uptr->pos = uptr->pos + sizeof (t_mtrlnt);              /* move tape */
return MTSE_OK;
}
コード例 #5
0
int32 fdcdata(int32 io, int32 data)
{
	int32 i;

	if (io) {							/* write byte to fdc */
		fdcbyte = data;					/* save for seek */
        if ((i = cur_byt[cur_dsk]) < SECT_SIZE) { /* copy bytes to buffer */
#if DEBUG > 3
			printf("Writing byte %d of %02X\n\r", cur_byt[cur_dsk], data);
#endif
        	cur_byt[cur_dsk]++;			/* step counter */
			dskbuf[i] = data;			/* byte into buffer */
			if (cur_byt[cur_dsk] == SECT_SIZE) {
				cur_flg[cur_dsk] &= ~(BUSY | DRQ);
				if (dptr) {				/* if initiated by FDC write command */
					sim_fwrite(dskbuf, 256, 1, dptr -> fileref); /* write it */
					dptr = NULL;
				}
#if DEBUG > 0
				printf("Sector write complete\n\r");
#endif
			}
		}
		return 0;
	} else {							/* read byte from fdc */
        if ((i = cur_byt[cur_dsk]) < SECT_SIZE) { /* copy bytes from buffer */
#if DEBUG > 1
			printf("Reading byte %d\n\r", cur_byt[cur_dsk]);
#endif
        	cur_byt[cur_dsk]++;			/* step counter */
			if (cur_byt[cur_dsk] == SECT_SIZE) { /* done? */
				cur_flg[cur_dsk] &= ~(BUSY | DRQ); /* clear flags */
#if DEBUG > 0
				printf("Sector read complete\n\r");
#endif
			}
       		return (dskbuf[i] & 0xFF);
		} else
			return 0;
	}
}
コード例 #6
0
ファイル: sigma_lp.c プロジェクト: charlesUnixPro/simh
uint32 lp_print (UNIT *uptr)
{
uint32 i, bp, c;
uint32 max = (lp_model == LP_7440)? BUF_LNT4: BUF_LNT5;
uint32 st;

if (lp_pass == 0) {                                     /* pass 1? clr buf */
    for (i = 0; i < BUF_LNT4; i++) lp_buf[i] = ' ';
    }
for (bp = 0, st = 0; (bp < max) && !st; bp++) {          /* fill buffer */
    st = chan_RdMemB (lp_dib.dva, &c);                  /* get char */
    if (CHS_IFERR (st))                                 /* channel error? */
        return st;                                      /* caller handles */
    if ((lp_model == LP_7440) ||                        /* 7440 or */
        ((bp & 1) == lp_pass))                          /* correct pass? */
        lp_buf[bp] = lp_to_ascii[c & 0x3F];
    }
if ((lp_model == LP_7440) || lp_pass) {                 /* ready to print? */
    lp_pass = 0;
    for (i = BUF_LNT4; (i > 0) && (lp_buf[i - 1] == ' '); i--) ; /* trim */
    if (i)                                              /* write line */
        sim_fwrite (lp_buf, 1, i, uptr->fileref);
    fputc (lp_inh? '\r': '\n', uptr->fileref);          /* cr or nl */
    uptr->pos = ftell (uptr->fileref);                  /* update position */
    if (ferror (uptr->fileref)) {                       /* error? */
        sim_perror ("Line printer I/O error");
        clearerr (uptr->fileref);
        chan_set_chf (lp_dib.dva, CHF_XMDE);
        return SCPE_IOERR;
        }
    if ((lp_model == LP_7440) &&                        /* 7440? */
        ((bp != BUF_LNT4) || (st != CHS_ZBC)) &&        /* check lnt err */
        chan_set_chf (lp_dib.dva, CHF_LNTE))
        return CHS_INACTV;                              /* stop if asked */
    }
else lp_pass = 1;                                       /* 7450 pass 2 */
lp_cmd = LPS_END;                                       /* end state */
return 0;
}
コード例 #7
0
ファイル: dc-4.c プロジェクト: alexchenfeng/UNIXV6
int32 fdcdata(int32 io, int32 data)
{
    int32 val;

    if (io) {                           /* write byte to fdc */
        fdcbyte = data;                 /* save for seek */
        if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes to buffer */
            if (dsk_dev.dctrl & DEBUG_write)
                printf("\nfdcdata: Writing byte %d of %02X", dsk_unit[cur_dsk].pos, data);
            *(uint8 *)(dsk_unit[cur_dsk].filebuf + dsk_unit[cur_dsk].pos) = data; /* byte into buffer */
            dsk_unit[cur_dsk].pos++;    /* step counter */
            if (dsk_unit[cur_dsk].pos == SECSIZ) {
                dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ);
                if (wrt_flag) {         /* if initiated by FDC write command */
                    sim_fwrite(dsk_unit[cur_dsk].filebuf, SECSIZ, 1, dsk_unit[cur_dsk].fileref); /* write it */
                    wrt_flag = 0;       /* clear write flag */
                }
                if (dsk_dev.dctrl & DEBUG_write)
                    printf("\nfdcdata: Sector write complete");
            }
        }
        return 0;
    } else {                            /* read byte from fdc */
    if (dsk_unit[cur_dsk].pos < SECSIZ) { /* copy bytes from buffer */
        if (dsk_dev.dctrl & DEBUG_read)
            printf("\nfdcdata: Reading byte %d u3=%02X", dsk_unit[cur_dsk].pos, dsk_unit[cur_dsk].u3);
        val = *(uint8 *)(dsk_unit[cur_dsk].filebuf + dsk_unit[cur_dsk].pos) & 0xFF;
        dsk_unit[cur_dsk].pos++;        /* step counter */
        if (dsk_unit[cur_dsk].pos == SECSIZ) { /* done? */
            dsk_unit[cur_dsk].u3 &= ~(BUSY | DRQ); /* clear flags */
            if (dsk_dev.dctrl & DEBUG_write)
                printf("\nfdcdata: Sector read complete");
        }
        return val;
    } else
        return 0;
    }
}
コード例 #8
0
ファイル: altairz80_dsk.c プロジェクト: BillHeaton/simh
/* precondition: current_disk < NUM_OF_DSK */
static void writebuf(void) {
    int32 i, rtn;
    UNIT *uptr;
    i = current_byte[current_disk];         /* null-fill rest of sector if any */
    while (i < DSK_SECTSIZE)
        dskbuf[i++] = 0;
    uptr = dsk_dev.units + current_disk;
    if (((uptr -> flags) & UNIT_DSK_WLK) == 0) { /* write enabled */
        sim_debug(WRITE_MSG, &dsk_dev,
                  "DSK%i: " ADDRESS_FORMAT " OUT 0x0a (WRITE) D%d T%d S%d\n",
                  current_disk, PCX, current_disk,
                  current_track[current_disk], current_sector[current_disk]);
        if (dskseek(uptr)) {
            sim_debug(VERBOSE_MSG, &dsk_dev,
                      "DSK%i: " ADDRESS_FORMAT " fseek failed D%d T%d S%d\n",
                      current_disk, PCX, current_disk,
                      current_track[current_disk], current_sector[current_disk]);
        }
        rtn = sim_fwrite(dskbuf, 1, DSK_SECTSIZE, uptr -> fileref);
        if (rtn != DSK_SECTSIZE) {
            sim_debug(VERBOSE_MSG, &dsk_dev,
                      "DSK%i: " ADDRESS_FORMAT " sim_fwrite failed T%d S%d Return=%d\n",
                      current_disk, PCX, current_track[current_disk],
                      current_sector[current_disk], rtn);
        }
    }
    else if ( (dsk_dev.dctrl & VERBOSE_MSG) && (warnLock[current_disk] < warnLevelDSK) ) {
        /* write locked - print warning message if required */
        warnLock[current_disk]++;
        sim_debug(VERBOSE_MSG, &dsk_dev,
                  "DSK%i: " ADDRESS_FORMAT " Attempt to write to locked DSK%d - ignored.\n",
                  current_disk, PCX, current_disk);
    }
    current_flag[current_disk]  &= 0xfe;    /* ENWD off */
    current_byte[current_disk]  = 0xff;
    dirty                       = FALSE;
}
コード例 #9
0
ファイル: s100_disk3.c プロジェクト: rekrevs/simh
static uint8 DISK3_Write(const uint32 Addr, uint8 cData)
{
    uint32 next_link;
    uint8 result = DISK3_STATUS_COMPLETE;
    uint8 i;
    uint8 cmd;

    DISK3_DRIVE_INFO *pDrive;

    for(i = 0; i < DISK3_IOPB_LEN; i++) {
        disk3_info->iopb[i] = GetByteDMA(disk3_info->link_addr + i);
    }

    cmd = disk3_info->iopb[DISK3_IOPB_CMD];
    disk3_info->sel_drive = disk3_info->iopb[DISK3_IOPB_DRIVE] & 0x03;

    disk3_info->dma_addr = disk3_info->iopb[0x0A];
    disk3_info->dma_addr |= disk3_info->iopb[0x0B] << 8;
    disk3_info->dma_addr |= disk3_info->iopb[0x0C] << 16;

    next_link  = disk3_info->iopb[DISK3_IOPB_LINK+0];
    next_link |= disk3_info->iopb[DISK3_IOPB_LINK+1] << 8;
    next_link |= disk3_info->iopb[DISK3_IOPB_LINK+2] << 16;

    sim_debug(VERBOSE_MSG, &disk3_dev, "DISK3[%d]: LINK=0x%05x, NEXT=0x%05x, CMD=%x, %s DMA@0x%05x\n",
              disk3_info->sel_drive,
              disk3_info->link_addr,
              next_link,
              disk3_info->iopb[DISK3_IOPB_CMD] & DISK3_CMD_MASK,
              (disk3_info->iopb[DISK3_IOPB_CMD] & DISK3_REQUEST_IRQ) ? "IRQ" : "POLL",
              disk3_info->dma_addr);

    pDrive = &disk3_info->drive[disk3_info->sel_drive];

    if(pDrive->ready) {

        /* Perform command */
        switch(cmd & DISK3_CMD_MASK) {
            case DISK3_CODE_NOOP:
                sim_debug(VERBOSE_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " NOOP\n", disk3_info->sel_drive, PCX);
                break;
            case DISK3_CODE_VERSION:
                break;
            case DISK3_CODE_GLOBAL:
                sim_debug(CMD_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " GLOBAL\n", disk3_info->sel_drive, PCX);

                disk3_info->mode = disk3_info->iopb[DISK3_IOPB_ARG1];
                disk3_info->retries = disk3_info->iopb[DISK3_IOPB_ARG2];
                disk3_info->ndrives = disk3_info->iopb[DISK3_IOPB_ARG3];

                sim_debug(SPECIFY_MSG, &disk3_dev, "        Mode: 0x%02x\n", disk3_info->mode);
                sim_debug(SPECIFY_MSG, &disk3_dev, "   # Retries: 0x%02x\n", disk3_info->retries);
                sim_debug(SPECIFY_MSG, &disk3_dev, "    # Drives: 0x%02x\n", disk3_info->ndrives);

                if(disk3_info->mode == DISK3_MODE_ABS) {
                    sim_debug(ERROR_MSG, &disk3_dev, "DISK3: Absolute addressing not supported.\n");
                }

                break;
            case DISK3_CODE_SPECIFY:
                {
                    uint8 specify_data[22];
                    sim_debug(CMD_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                              " SPECIFY\n", disk3_info->sel_drive, PCX);

                    for(i = 0; i < 22; i++) {
                        specify_data[i] = GetByteDMA(disk3_info->dma_addr + i);
                    }

                    pDrive->sectsize = specify_data[4] | (specify_data[5] << 8);
                    pDrive->nsectors = specify_data[6] | (specify_data[7] << 8);
                    pDrive->nheads = specify_data[8] | (specify_data[9] << 8);
                    pDrive->ntracks = specify_data[10] | (specify_data[11] << 8);
                    pDrive->res_tracks = specify_data[18] | (specify_data[19] << 8);

                    sim_debug(SPECIFY_MSG, &disk3_dev, "    Sectsize: %d\n", pDrive->sectsize);
                    sim_debug(SPECIFY_MSG, &disk3_dev, "     Sectors: %d\n", pDrive->nsectors);
                    sim_debug(SPECIFY_MSG, &disk3_dev, "       Heads: %d\n", pDrive->nheads);
                    sim_debug(SPECIFY_MSG, &disk3_dev, "      Tracks: %d\n", pDrive->ntracks);
                    sim_debug(SPECIFY_MSG, &disk3_dev, "    Reserved: %d\n", pDrive->res_tracks);
                    break;
                }
            case DISK3_CODE_HOME:
                pDrive->track = 0;
                sim_debug(SEEK_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " HOME\n", disk3_info->sel_drive, PCX);
                break;
            case DISK3_CODE_SEEK:
                pDrive->track = disk3_info->iopb[DISK3_IOPB_ARG1];
                pDrive->track |= (disk3_info->iopb[DISK3_IOPB_ARG2] << 8);

                if(pDrive->track > pDrive->ntracks) {
                    sim_debug(ERROR_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                              " SEEK ERROR %d not found\n", disk3_info->sel_drive, PCX, pDrive->track);
                    pDrive->track = pDrive->ntracks - 1;
                    result = DISK3_STATUS_TIMEOUT;
                } else {
                    sim_debug(SEEK_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                              " SEEK %d\n", disk3_info->sel_drive, PCX, pDrive->track);
                }
                break;
            case DISK3_CODE_READ_HDR:
            {
                sim_debug(CMD_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " READ HEADER: %d\n", pDrive->track, PCX, pDrive->track >> 8);
                PutByteDMA(disk3_info->dma_addr + 0, pDrive->track & 0xFF);
                PutByteDMA(disk3_info->dma_addr + 1, (pDrive->track >> 8) & 0xFF);
                PutByteDMA(disk3_info->dma_addr + 2, 0);
                PutByteDMA(disk3_info->dma_addr + 3, 1);

                break;
            }
            case DISK3_CODE_READWRITE:
            {
                uint32 track_len;
                uint32 xfr_len;
                uint32 file_offset;
                uint32 xfr_count = 0;
                uint8 *dataBuffer;
                size_t rtn;

                if(disk3_info->mode == DISK3_MODE_ABS) {
                    sim_debug(ERROR_MSG, &disk3_dev, "DISK3: Absolute addressing not supported.\n");
                    break;
                }

                pDrive->cur_sect = disk3_info->iopb[DISK3_IOPB_ARG2] | (disk3_info->iopb[DISK3_IOPB_ARG3] << 8);
                pDrive->cur_track = disk3_info->iopb[DISK3_IOPB_ARG4] | (disk3_info->iopb[DISK3_IOPB_ARG5] << 8);
                pDrive->xfr_nsects = disk3_info->iopb[DISK3_IOPB_ARG6] | (disk3_info->iopb[DISK3_IOPB_ARG7] << 8);

                track_len = pDrive->nsectors * pDrive->sectsize;

                file_offset = (pDrive->cur_track * track_len); /* Calculate offset based on current track */
                file_offset += pDrive->cur_sect * pDrive->sectsize;

                xfr_len = pDrive->xfr_nsects * pDrive->sectsize;

                dataBuffer = malloc(xfr_len);

                sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET);

                if(disk3_info->iopb[DISK3_IOPB_ARG1] == 1) { /* Read */
                    rtn = sim_fread(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref);

                    sim_debug(RD_DATA_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                              "  READ @0x%05x T:%04d/S:%04d/#:%d %s\n",
                              disk3_info->sel_drive,
                              PCX,
                              disk3_info->dma_addr,
                              pDrive->cur_track,
                              pDrive->cur_sect,
                              pDrive->xfr_nsects,
                              rtn == (size_t)xfr_len ? "OK" : "NOK" );


                    /* Perform DMA Transfer */
                    for(xfr_count = 0;xfr_count < xfr_len; xfr_count++) {
                        PutByteDMA(disk3_info->dma_addr + xfr_count, dataBuffer[xfr_count]);
                    }
                } else { /* Write */
                    sim_debug(WR_DATA_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                              " WRITE @0x%05x T:%04d/S:%04d/#:%d\n", disk3_info->sel_drive, PCX, disk3_info->dma_addr, pDrive->cur_track, pDrive->cur_sect, pDrive->xfr_nsects );

                    /* Perform DMA Transfer */
                    for(xfr_count = 0;xfr_count < xfr_len; xfr_count++) {
                        dataBuffer[xfr_count] = GetByteDMA(disk3_info->dma_addr + xfr_count);
                    }

                    sim_fwrite(dataBuffer, 1, xfr_len, (pDrive->uptr)->fileref);
                }

                free(dataBuffer);
                /* Update Track/Sector in IOPB */
                pDrive->cur_sect += pDrive->xfr_nsects;
                if(pDrive->cur_sect >= pDrive->nsectors) {
                    pDrive->cur_sect = pDrive->cur_sect % pDrive->nsectors;
                    pDrive->cur_track++;
                }
                disk3_info->iopb[DISK3_IOPB_ARG2] = pDrive->cur_sect & 0xFF;
                disk3_info->iopb[DISK3_IOPB_ARG3] = (pDrive->cur_sect >> 8) & 0xFF;
                disk3_info->iopb[DISK3_IOPB_ARG4] = pDrive->cur_track & 0xFF;
                disk3_info->iopb[DISK3_IOPB_ARG5] = (pDrive->cur_track >> 8) & 0xFF;
                disk3_info->iopb[DISK3_IOPB_ARG6] = 0;
                disk3_info->iopb[DISK3_IOPB_ARG7] = 0;

                /* Update the DATA field in the IOPB */
                disk3_info->dma_addr += xfr_len;
                disk3_info->iopb[DISK3_IOPB_DATA+0] = disk3_info->dma_addr & 0xFF;
                disk3_info->iopb[DISK3_IOPB_DATA+1] = (disk3_info->dma_addr >> 8) & 0xFF;
                disk3_info->iopb[DISK3_IOPB_DATA+2] = (disk3_info->dma_addr >> 16) & 0xFF;

                break;
                }
            case DISK3_CODE_FORMAT:
            {
                uint32 data_len;
                uint32 file_offset;
                uint8 *fmtBuffer;

                data_len = pDrive->nsectors * pDrive->sectsize;

                sim_debug(WR_DATA_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " FORMAT T:%d/H:%d/Fill=0x%02x/Len=%d\n",
                          disk3_info->sel_drive,
                          PCX,
                          pDrive->track,
                          disk3_info->iopb[DISK3_IOPB_ARG3],
                          disk3_info->iopb[DISK3_IOPB_ARG2],
                          data_len);

                file_offset = (pDrive->track * (pDrive->nheads) * data_len); /* Calculate offset based on current track */
                file_offset += (disk3_info->iopb[DISK3_IOPB_ARG3] * data_len);

                fmtBuffer = malloc(data_len);
                memset(fmtBuffer, disk3_info->iopb[DISK3_IOPB_ARG2], data_len);

                sim_fseek((pDrive->uptr)->fileref, file_offset, SEEK_SET);
                sim_fwrite(fmtBuffer, 1, data_len, (pDrive->uptr)->fileref);

                free(fmtBuffer);

                break;
            }
            case DISK3_CODE_SET_MAP:
                break;
            case DISK3_CODE_RELOCATE:
            case DISK3_CODE_FORMAT_BAD:
            case DISK3_CODE_STATUS:
            case DISK3_CODE_SELECT:
            case DISK3_CODE_EXAMINE:
            case DISK3_CODE_MODIFY:
            default:
                sim_debug(ERROR_MSG, &disk3_dev, "DISK3[%d]: " ADDRESS_FORMAT
                          " CMD=%x Unsupported\n",
                          disk3_info->sel_drive,
                          PCX,
                          cmd & DISK3_CMD_MASK);
                break;
        }
    } else { /* Drive not ready */
コード例 #10
0
ファイル: s100_mdsad.c プロジェクト: ProtoSD/simh
static uint8 MDSAD_Read(const uint32 Addr)
{
    uint8 cData;
    uint8 ds;
    MDSAD_DRIVE_INFO *pDrive;
    int32 rtn;

    cData = 0x00;

    pDrive = &mdsad_info->drive[mdsad_info->orders.ds];

    switch( (Addr & 0x300) >> 8 ) {
        case MDSAD_READ_ROM:
            cData = mdsad_rom[Addr & 0xFF];
            break;
        case MDSAD_WRITE_DATA:
        {
            if(mdsad_info->datacount == 0) {
                sim_debug(WR_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                          " WRITE Start:  Drive: %d, Track=%d, Head=%d, Sector=%d\n",
                          PCX, mdsad_info->orders.ds, pDrive->track,
                          mdsad_info->orders.ss, pDrive->sector);

                sec_offset = calculate_mdsad_sec_offset(pDrive->track,
                    mdsad_info->orders.ss,
                    pDrive->sector);

            }

            DBG_PRINT(("MDSAD: " ADDRESS_FORMAT
                " WRITE-DATA[offset:%06x+%03x]=%02x" NLP,
                PCX, sec_offset, mdsad_info->datacount, Addr & 0xFF));
            mdsad_info->datacount++;
            if(mdsad_info->datacount < MDSAD_RAW_LEN)
                sdata.raw[mdsad_info->datacount] = Addr & 0xFF;

            if(mdsad_info->datacount == (MDSAD_RAW_LEN - 1)) {
                sim_debug(WR_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                          " Write Complete\n", PCX);

                if ((pDrive->uptr == NULL) || (pDrive->uptr->fileref == NULL)) {
                    sim_debug(WR_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " Drive: %d not attached - write ignored.\n", PCX, mdsad_info->orders.ds);
                    return 0x00;
                }
                if(mdsad_dev.dctrl & WR_DATA_DETAIL_MSG)
                    showdata(FALSE);
                switch((pDrive->uptr)->u3)
                {
                    case IMAGE_TYPE_DSK:
                        if(pDrive->uptr->fileref == NULL) {
                            printf(".fileref is NULL!" NLP);
                        } else {
                            sim_fseek((pDrive->uptr)->fileref, sec_offset, SEEK_SET);
                            sim_fwrite(sdata.u.data, 1, MDSAD_SECTOR_LEN,
                                (pDrive->uptr)->fileref);
                        }
                        break;
                    case IMAGE_TYPE_CPT:
                        printf("%s: CPT Format not supported" NLP, __FUNCTION__);
                        break;
                    default:
                        printf("%s: Unknown image Format" NLP, __FUNCTION__);
                        break;
                }
            }
            break;
        }
        case MDSAD_CTLR_ORDERS:
            mdsad_info->orders.dd = (Addr & 0x80) >> 7;
            mdsad_info->orders.ss = (Addr & 0x40) >> 6;
            mdsad_info->orders.dp = (Addr & 0x20) >> 5;
            mdsad_info->orders.st = (Addr & 0x10) >> 4;
            mdsad_info->orders.ds = (Addr & 0x0F);

            ds = mdsad_info->orders.ds;
            switch(mdsad_info->orders.ds) {
                case 0:
                case 1:
                    mdsad_info->orders.ds = 0;
                    break;
                case 2:
                    mdsad_info->orders.ds = 1;
                    break;
                case 4:
                    mdsad_info->orders.ds = 2;
                    break;
                case 8:
                    mdsad_info->orders.ds = 3;
                    break;
            }

            if(mdsad_info->orders.ds != (mdsad_info->orders.ds & 0x03)) {
                sim_debug(ERROR_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                          " Controller Orders update drive %x\n", PCX, mdsad_info->orders.ds);
                mdsad_info->orders.ds &= 0x03;
            }
            sim_debug(ORDERS_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                      " Controller Orders: Drive=%x[%x], DD=%d, SS=%d, DP=%d, ST=%d\n",
                      PCX, mdsad_info->orders.ds, ds, mdsad_info->orders.dd,
                      mdsad_info->orders.ss, mdsad_info->orders.dp, mdsad_info->orders.st);

            /* use latest selected drive */
            pDrive = &mdsad_info->drive[mdsad_info->orders.ds];

            if(mdsad_info->orders.st == 1) {
                if(mdsad_info->orders.dp == 0) {
                    sim_debug(SEEK_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " Step out: Track=%d%s\n", PCX, pDrive->track,
                              pDrive->track == 0 ? "[Warn: already at 0]" : "");
                    if(pDrive->track > 0) /* anything to do? */
                        pDrive->track--;
                } else {
                    sim_debug(SEEK_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " Step  in: Track=%d%s\n", PCX, pDrive->track,
                              pDrive->track == (MDSAD_TRACKS - 1) ? "[Warn: already at highest track]" : "");
                    if(pDrive->track < (MDSAD_TRACKS - 1)) /* anything to do? */
                        pDrive->track++;
                }
            }
            /* always update t0 */
            mdsad_info->b_status.t0 = (pDrive->track == 0);
            break;
        case MDSAD_CTLR_COMMAND:
/*          sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT " DM=%x\n", PCX, (Addr & 0xF0) >> 4); */
            switch(Addr & 0x0F) {
                case MDSAD_CMD_MOTORS_ON:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Motors On\n", PCX);
                    mdsad_info->com_status.mo = 1;      /* Turn motors on */
                    break;

                case MDSAD_CMD_NOP:
                    pDrive->sector_wait_count++;
                    switch(pDrive->sector_wait_count) {
                        case 10:
                        {
                            mdsad_info->com_status.sf = 1;
                            mdsad_info->a_status.wi = 0;
                            mdsad_info->a_status.re = 0;
                            mdsad_info->a_status.bd = 0;
                            pDrive->sector_wait_count = 0;
                            pDrive->sector++;
                            if(pDrive->sector >= MDSAD_SECTORS_PER_TRACK) {
                                pDrive->sector = 0;
                                mdsad_info->com_status.ix = 1;
                            } else {
                                mdsad_info->com_status.ix = 0;
                            }
                            break;
                        }
                        case 2:
                            mdsad_info->a_status.wi = 1;
                            break;
                        case 3:
                            mdsad_info->a_status.re = 1;
                            mdsad_info->a_status.bd = 1;
                            break;
                        default:
                            break;
                    }
                    break;
                case MDSAD_CMD_RESET_SF:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Reset Sector Flag\n", PCX);
                    mdsad_info->com_status.sf = 0;
                    mdsad_info->datacount = 0;
                    break;
                case MDSAD_CMD_INTR_DIS:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Disarm Interrupt\n", PCX);
                    mdsad_info->int_enable = 0;
                    break;
                case MDSAD_CMD_INTR_ARM:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Arm Interrupt\n", PCX);
                    mdsad_info->int_enable = 1;
                    break;
                case MDSAD_CMD_SET_BODY:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Set Body (Diagnostic)\n", PCX);
                    break;
                case MDSAD_CMD_BEGIN_WR:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Begin Write\n", PCX);
                    break;
                case MDSAD_CMD_RESET:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " CMD=Reset Controller\n", PCX);
                    mdsad_info->com_status.mo = 0;  /* Turn motors off */
                    break;
                default:
                    sim_debug(CMD_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " Unsupported CMD=0x%x\n", PCX, Addr & 0x0F);
                    break;
            }

            /* Always Double-Density for now... */
            mdsad_info->com_status.dd = 1;

            cData  = (mdsad_info->com_status.sf & 1) << 7;
            cData |= (mdsad_info->com_status.ix & 1) << 6;
            cData |= (mdsad_info->com_status.dd & 1) << 5;
            cData |= (mdsad_info->com_status.mo & 1) << 4;

            mdsad_info->c_status.sc = pDrive->sector;

            switch( (Addr & 0xF0) >> 4) {
                case MDSAD_A_STATUS:    /* A-STATUS */
                    cData |= (mdsad_info->a_status.wi & 1) << 3;
                    cData |= (mdsad_info->a_status.re & 1) << 2;
                    cData |= (mdsad_info->a_status.sp & 1) << 1;
                    cData |= (mdsad_info->a_status.bd & 1);
                    sim_debug(STATUS_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " A-Status = <%s %s %s %s %s %s %s %s>\n",
                              PCX,
                              cData & MDSAD_A_SF ? "SF" : "  ",
                              cData & MDSAD_A_IX ? "IX" : "  ",
                              cData & MDSAD_A_DD ? "DD" : "  ",
                              cData & MDSAD_A_MO ? "MO" : "  ",
                              cData & MDSAD_A_WI ? "WI" : "  ",
                              cData & MDSAD_A_RE ? "RE" : "  ",
                              cData & MDSAD_A_SP ? "SP" : "  ",
                              cData & MDSAD_A_BD ? "BD" : "  ");
                    break;
                case MDSAD_B_STATUS:    /* B-STATUS */
                    cData |= (mdsad_info->b_status.wr & 1) << 3;
                    cData |= (mdsad_info->b_status.sp & 1) << 2;
                    cData |= (mdsad_info->b_status.wp & 1) << 1;
                    cData |= (mdsad_info->b_status.t0 & 1);
                    sim_debug(STATUS_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " B-Status = <%s %s %s %s %s %s %s %s>\n",
                              PCX,
                              cData & MDSAD_B_SF ? "SF" : "  ",
                              cData & MDSAD_B_IX ? "IX" : "  ",
                              cData & MDSAD_B_DD ? "DD" : "  ",
                              cData & MDSAD_B_MO ? "MO" : "  ",
                              cData & MDSAD_B_WR ? "WR" : "  ",
                              cData & MDSAD_B_SP ? "SP" : "  ",
                              cData & MDSAD_B_WP ? "WP" : "  ",
                              cData & MDSAD_B_T0 ? "T0" : "  ");
                    break;
                case MDSAD_C_STATUS:    /* C-STATUS */
                    cData |= (mdsad_info->c_status.sc & 0xF);
                    sim_debug(STATUS_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                              " C-Status = <%s %s %s %s %i>\n",
                              PCX,
                              cData & MDSAD_C_SF ? "SF" : "  ",
                              cData & MDSAD_C_IX ? "IX" : "  ",
                              cData & MDSAD_C_DD ? "DD" : "  ",
                              cData & MDSAD_C_MO ? "MO" : "  ",
                              cData & MDSAD_C_SC);
                    break;
                case MDSAD_READ_DATA:   /* READ DATA */
                {
                    if(mdsad_info->datacount == 0) {
                        sim_debug(RD_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                                  " READ Start:  Drive: %d, Track=%d, Head=%d, Sector=%d\n",
                                  PCX,
                                  mdsad_info->orders.ds,
                                  pDrive->track,
                                  mdsad_info->orders.ss,
                                  pDrive->sector);

                            checksum = 0;

                            sec_offset = calculate_mdsad_sec_offset(pDrive->track,
                                mdsad_info->orders.ss,
                                pDrive->sector);

                            if ((pDrive->uptr == NULL) ||
                                    (pDrive->uptr->fileref == NULL)) {
                                sim_debug(RD_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                                          " Drive: %d not attached - read ignored.\n",
                                          PCX, mdsad_info->orders.ds);
                                return 0xe5;
                            }

                            switch((pDrive->uptr)->u3)
                            {
                                case IMAGE_TYPE_DSK:
                                    if(pDrive->uptr->fileref == NULL) {
                                        printf(".fileref is NULL!" NLP);
                                    } else {
                                        sim_fseek((pDrive->uptr)->fileref,
                                            sec_offset, SEEK_SET);
                                        rtn = sim_fread(&sdata.u.data[0], 1, MDSAD_SECTOR_LEN,
                                            (pDrive->uptr)->fileref);
                                        if (rtn != MDSAD_SECTOR_LEN) {
                                            sim_debug(ERROR_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                                                      " READ: sim_fread error.\n", PCX);
                                        }
                                    }
                                    break;
                                case IMAGE_TYPE_CPT:
                                    printf("%s: CPT Format not supported"
                                        NLP, __FUNCTION__);
                                    break;
                                default:
                                    printf("%s: Unknown image Format"
                                        NLP, __FUNCTION__);
                                    break;
                            }
                            if(mdsad_dev.dctrl & RD_DATA_DETAIL_MSG)
                                showdata(TRUE);
                    }

                    if(mdsad_info->datacount < MDSAD_SECTOR_LEN) {
                        cData = sdata.u.data[mdsad_info->datacount];

                        /* Exclusive OR */
                        checksum ^= cData;
                        /* Rotate Left Circular */
                        checksum = ((checksum << 1) | ((checksum & 0x80) != 0)) & 0xff;

                        DBG_PRINT(("MDSAD: " ADDRESS_FORMAT
                            " READ-DATA[offset:%06x+%03x]=%02x" NLP,
                            PCX, sec_offset, mdsad_info->datacount, cData));
                    } else { /* checksum */
                        cData = checksum;
                        sim_debug(RD_DATA_MSG, &mdsad_dev, "MDSAD: " ADDRESS_FORMAT
                                  " READ-DATA: Checksum is: 0x%02x\n",
                                  PCX, cData);
                    }

                    mdsad_info->datacount++;
                    break;
                }
                default:
                    DBG_PRINT(("MDSAD: " ADDRESS_FORMAT
                        " Invalid DM=%x" NLP, PCX, Addr & 0xF));
                    break;
            }

            break;
    }
    return (cData);
}
コード例 #11
0
ファイル: sim_imd.c プロジェクト: j-hoppe/BlinkenBone
/* Format an entire track.  The new track to be formatted must be after any existing tracks on
 * the disk.
 *
 * This routine should be enhanced to re-format an existing track to the same format (this
 * does not involve changing the disk image size.)
 *
 * Any existing data on the disk image will be destroyed when Track 0, Head 0 is formatted.
 * At that time, the IMD file is truncated.  So for the trackWrite to be used to sucessfully
 * format a disk image, then format program must format tracks starting with Cyl 0, Head 0,
 * and proceed sequentially through all tracks/heads on the disk.
 *
 * Format programs that are known to work include:
 * Cromemco CDOS "INIT.COM"
 * ADC Super-Six (CP/M-80) "FMT8.COM"
 * 86-DOS "INIT.COM"
 *
 */
t_stat trackWrite(DISK_INFO *myDisk,
               uint32 Cyl,
               uint32 Head,
               uint32 numSectors,
               uint32 sectorLen,
               uint8 *sectorMap,
               uint8 mode,
               uint8 fillbyte,
               uint32 *flags)
{
    FILE *fileref;
    IMD_HEADER track_header;
    uint8 *sectorData;
    unsigned long i;
    unsigned long dataLen;

    *flags = 0;

    /* Check parameters */
    if(myDisk == NULL) {
        *flags |= IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    if(myDisk->flags & FD_FLAG_WRITELOCK) {
        sim_printf("Disk write-protected, cannot format tracks.\n");
        *flags |= IMD_DISK_IO_ERROR_WPROT;
        return(SCPE_IOERR);
    }

    fileref = myDisk->file;

    sim_debug(myDisk->debugmask, myDisk->device, "Formatting C:%d/H:%d/N:%d, len=%d, Fill=0x%02x\n", Cyl, Head, numSectors, sectorLen, fillbyte);

    /* Truncate the IMD file when formatting Cyl 0, Head 0 */
    if((Cyl == 0) && (Head == 0))
    {
        /* Skip over IMD comment field. */
        commentParse(myDisk, NULL, 0);

        /* Truncate the IMD file after the comment field. */
        if (sim_set_fsize(fileref, (t_addr)ftell (fileref)) == -1) {
            sim_printf("Disk truncation failed.\n");
            *flags |= IMD_DISK_IO_ERROR_GENERAL;
            return(SCPE_IOERR);
        }
        /* Flush and re-parse the IMD file. */
        fflush(fileref);
        diskParse(myDisk, 0);
    }

    /* Check to make sure the Cyl / Head is not already formatted. */
    if(sectSeek(myDisk, Cyl, Head) == 0) {
        sim_printf("SIM_IMD: ERROR: Not Formatting C:%d/H:%d, track already exists.\n", Cyl, Head);
        *flags |= IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    track_header.mode = mode;
    track_header.cyl = Cyl;
    track_header.head = Head;
    track_header.nsects = numSectors;
    track_header.sectsize = sectorLen;

    /* Forward to end of the file, write track header and sector map. */
    sim_fseek(myDisk->file, 0, SEEK_END);
    sim_fwrite(&track_header, 1, sizeof(IMD_HEADER), fileref);
    sim_fwrite(sectorMap, 1, numSectors, fileref);

    /* Compute data length, and fill a sector buffer with the
     * sector record type as the first byte, and fill the sector
     * data with the fillbyte.
     */
    dataLen = sectorLen + 1;
    sectorData = (uint8 *)malloc(dataLen);
    memset(sectorData, fillbyte, dataLen);
    sectorData[0] = SECT_RECORD_NORM;

    /* For each sector on the track, write the record type and sector data. */
    for(i=0;i<numSectors;i++) {
        sim_fwrite(sectorData, 1, dataLen, fileref);
    }

    /* Flush the file, and free the sector buffer. */
    fflush(fileref);
    free(sectorData);

    /* Now that the disk track/sector layout has been modified, re-parse the disk image. */
    diskParse(myDisk, 0);

    return(SCPE_OK);
}
コード例 #12
0
ファイル: sim_imd.c プロジェクト: j-hoppe/BlinkenBone
/* Write a sector to an IMD image. */
t_stat sectWrite(DISK_INFO *myDisk,
              uint32 Cyl,
              uint32 Head,
              uint32 Sector,
              uint8 *buf,
              uint32 buflen,
              uint32 *flags,
              uint32 *writelen)
{
    uint32 sectorFileOffset;
    uint8 sectRecordType;
    uint8 start_sect;
    *writelen = 0;

    sim_debug(myDisk->debugmask, myDisk->device, "Writing C:%d/H:%d/S:%d, len=%d\n", Cyl, Head, Sector, buflen);

    /* Check parameters */
    if(myDisk == NULL) {
        *flags = IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    if(sectSeek(myDisk, Cyl, Head) != 0) {
        *flags = IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    if(Sector > myDisk->track[Cyl][Head].nsects) {
        sim_debug(myDisk->debugmask, myDisk->device, "%s: invalid sector\n", __FUNCTION__);
        *flags = IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    if(myDisk->flags & FD_FLAG_WRITELOCK) {
        sim_printf("Disk write-protected because the image contains compressed sectors. Use IMDU to uncompress.\n");
        *flags = IMD_DISK_IO_ERROR_WPROT;
        return(SCPE_IOERR);
    }

    if(buflen < myDisk->track[Cyl][Head].sectsize) {
        sim_printf("%s: user buffer too short [buflen %i < sectsize %i]\n",
                   __FUNCTION__, buflen, myDisk->track[Cyl][Head].sectsize);
        *flags = IMD_DISK_IO_ERROR_GENERAL;
        return(SCPE_IOERR);
    }

    start_sect = myDisk->track[Cyl][Head].start_sector;

    sectorFileOffset = myDisk->track[Cyl][Head].sectorOffsetMap[Sector-start_sect];

    sim_fseek(myDisk->file, sectorFileOffset-1, SEEK_SET);

    if (*flags & IMD_DISK_IO_ERROR_GENERAL) {
        sectRecordType = SECT_RECORD_UNAVAILABLE;
    } else if (*flags & IMD_DISK_IO_ERROR_CRC) {
        if (*flags & IMD_DISK_IO_DELETED_ADDR_MARK)
            sectRecordType = SECT_RECORD_NORM_DAM_ERR;
        else
            sectRecordType = SECT_RECORD_NORM_ERR;
    } else {
        if (*flags & IMD_DISK_IO_DELETED_ADDR_MARK)
            sectRecordType = SECT_RECORD_NORM_DAM;
        else
        sectRecordType = SECT_RECORD_NORM;
    }

    fputc(sectRecordType, myDisk->file);
    sim_fwrite(buf, 1, myDisk->track[Cyl][Head].sectsize, myDisk->file);
    *writelen = myDisk->track[Cyl][Head].sectsize;

    return(SCPE_OK);
}
コード例 #13
0
ファイル: mfdc.c プロジェクト: ProtoSD/simh
static uint8 MFDC_Write(const uint32 Addr, uint8 cData)
{
    unsigned int sec_offset;
    uint32 flags = 0;
    uint32 writelen;
    MFDC_DRIVE_INFO *pDrive;

    pDrive = &mfdc_info->drive[mfdc_info->sel_drive];

    switch(Addr & 0x3) {
        case 0:
        case 1:
            MFDC_Command(cData);
            break;
        case 2:
        case 3:
/*          DBG_PRINT(("MFDC: " ADDRESS_FORMAT " WR Data" NLP, PCX)); */
            if(mfdc_info->wr_latch == 0) {
                printf("MFDC: " ADDRESS_FORMAT " Error, attempt to write data when write latch is not set." NLP, PCX);
            } else {
#ifdef USE_VGI
                sec_offset = (pDrive->track * MFDC_SECTOR_LEN * 16) + \
                             (pDrive->sector * MFDC_SECTOR_LEN);

                sdata.raw[mfdc_info->datacount] = cData;
#else
                int data_index = mfdc_info->datacount - 13;

                sec_offset = (pDrive->track * 4096) + \
                             (pDrive->sector * 256);

                if((data_index >= 0) && (data_index < 256)) {
                    DBG_PRINT(("writing data [%03d]=%02x" NLP, data_index, cData));

                    sdata.u.data[data_index] = cData;

                }

#endif /* USE_VGI */

                mfdc_info->datacount ++;

                if(mfdc_info->datacount == 270) {
                    sim_debug(WR_DATA_MSG, &mfdc_dev, "MFDC: " ADDRESS_FORMAT " WR Data T:%d S:[%d]\n", PCX, pDrive->track, pDrive->sector);

                    if (!(pDrive->uptr->flags & UNIT_ATT)) {
                        if (pDrive->uptr->flags & UNIT_MFDC_VERBOSE)
                            printf("MFDC: " ADDRESS_FORMAT " MDSK%i not attached." NLP, PCX,
                                mfdc_info->sel_drive);
                        return 0x00;
                    }

                    switch((pDrive->uptr)->u3)
                    {
                        case IMAGE_TYPE_IMD:
                            if(pDrive->imd == NULL) {
                                printf(".imd is NULL!" NLP);
                            }
                            sectWrite(pDrive->imd,
                                pDrive->track,
                                mfdc_info->head,
                                pDrive->sector,
                                sdata.u.data,
                                256,
                                &flags,
                                &writelen);
                            break;
                        case IMAGE_TYPE_DSK:
                            if(pDrive->uptr->fileref == NULL) {
                                printf(".fileref is NULL!" NLP);
                            } else {
                                sim_fseek((pDrive->uptr)->fileref, sec_offset, SEEK_SET);
#ifdef USE_VGI
                                sim_fwrite(sdata.raw, 1, MFDC_SECTOR_LEN, (pDrive->uptr)->fileref);
#else
                                sim_fwrite(sdata.u.data, 1, 256, (pDrive->uptr)->fileref);
#endif /* USE_VGI */
                            }
                            break;
                        case IMAGE_TYPE_CPT:
                            printf("%s: CPT Format not supported" NLP, __FUNCTION__);
                            break;
                        default:
                            printf("%s: Unknown image Format" NLP, __FUNCTION__);
                            break;
                    }
                }
            }
            break;
    }

    cData = 0x00;

    return (cData);
}