예제 #1
0
static void scsiDeviceStartStopUnit(SCSIDEVICE* scsi)
{
    FileProperties* disk = &propGetGlobalProperties()->media.disks[scsi->diskId];

    switch (scsi->cdb[4]) {
    case 2:
        // Eject
        if (diskPresent(scsi->diskId)) {
            disk->fileName[0] = 0;
            disk->fileNameInZip[0] = 0;
            updateExtendedDiskName(scsi->diskId, disk->fileName, disk->fileNameInZip);
            boardChangeDiskette(scsi->diskId, NULL, NULL);
            SCSILOG1("hdd %d eject\n", scsi->scsiId);
        }
        break;
    case 3:
        // Insert
        if (!diskPresent(scsi->diskId)) {
            *disk = scsi->disk;
            updateExtendedDiskName(scsi->diskId, disk->fileName, disk->fileNameInZip);
            boardChangeDiskette(scsi->diskId, disk->fileName, disk->fileNameInZip);
            SCSILOG1("hdd %d insert\n", scsi->scsiId);
        }
        break;
    }
    scsi->motor = scsi->cdb[4] & 1;
    SCSILOG2("hdd %d motor: %d\n", scsi->scsiId, scsi->motor);
}
예제 #2
0
// Check the initiator in the call origin.
int scsiDeviceSelection(SCSIDEVICE* scsi)
{
    scsi->lun = 0;
    if (scsi->mode & MODE_REMOVABLE) {
        if (!scsi->enabled &&
           (scsi->mode & MODE_NOVAXIS) && scsi->deviceType != SDT_CDROM) {
            scsi->enabled = diskPresent(scsi->diskId) ? 1 : 0;
        }
        return scsi->enabled;
    }
    return scsi->enabled && diskPresent(scsi->diskId);
}
예제 #3
0
void harddiskIdeWriteRegister(HarddiskIde* hd, UInt8 reg, UInt8 value)
{
    if (!diskPresent(hd->diskId)) {
        return;
    }
    switch (reg) {
    case 1:
        hd->featureReg = value;
        break;
    case 2:
        hd->sectorCountReg = value;
        break;
    case 3:
        hd->sectorNumReg = value;
        break;
    case 4:
        hd->cylinderLowReg = value;
        break;
    case 5:
        hd->cylinderHighReg = value;
        break;
    case 6:
        hd->devHeadReg = value;
        break;
    case 7:
        executeCommand(hd, value);
        break;
    }
}
예제 #4
0
UInt8 harddiskIdeReadRegister(HarddiskIde* hd, UInt8 reg)
{
    if (!diskPresent(hd->diskId)) {
        return 0x7f;
    }

    switch (reg) {
    case 1:
        return hd->errorReg;
    case 2: 
        return hd->sectorCountReg;
    case 3: 
        return hd->sectorNumReg;
    case 4: 
        return hd->cylinderLowReg;
    case 5: 
        return hd->cylinderHighReg;
    case 6: 
        return hd->devHeadReg;
    case 7: 
        return hd->statusReg;
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 15:
        return 0x7f;
    }

    return 0x7f;
}
예제 #5
0
파일: WD2793.c 프로젝트: imclab/CocoaMSX
static void commandType3(WD2793* wd)
{
	wd->regStatus  &= ~(ST_LOST_DATA | ST_RECORD_NOT_FOUND | ST_RECORD_TYPE);
	wd->regStatus  |= ST_BUSY;
    wd->headLoaded  = 1;
	wd->dataRequest = 0;
	wd->dataReady  = 0;

	if (!diskPresent(wd->drive)) {
	    wd->intRequest = 1;
	    wd->regStatus &= ~ST_BUSY;
        return;
	} 

	switch (wd->regCommand >> 4) {
	case CMD_READ_ADDRESS:
	case CMD_READ_TRACK:
	    wd->intRequest = 1;
	    wd->regStatus &= ~ST_BUSY;

	case CMD_WRITE_TRACK:
	    wd->dataRequest = 1;
		break;
	}
}
예제 #6
0
파일: WD2793.c 프로젝트: imclab/CocoaMSX
static void commandType2(WD2793* wd)
{
	wd->regStatus  &= ~(ST_LOST_DATA   | ST_RECORD_NOT_FOUND | ST_RECORD_TYPE | ST_WRITE_PROTECTED);
	wd->regStatus  |= ST_BUSY;
    wd->headLoaded  = 1;
	wd->dataRequest = 0;

	if (!diskPresent(wd->drive)) {
	    wd->intRequest  = 1;
	    wd->regStatus &= ~ST_BUSY;
        return;
	} 

    switch (wd->regCommand >> 4) {
	case CMD_READ_SECTOR:
	case CMD_READ_SECTORS:
		wd2793ReadSector(wd);
		break;

	case CMD_WRITE_SECTOR:
	case CMD_WRITE_SECTORS:
		wd->sectorOffset  = 0;
		wd->dataRequest   = 1;
        wd->dataAvailable = diskGetSectorSize(wd->drive, wd->diskSide, wd->diskTrack, wd->diskDensity);
		break;
	}
}
예제 #7
0
void checkDeviceFlags(struct AFSBase *afsbase) {
struct Volume *volume;
struct IOHandle *ioh;

	volume = (struct Volume *)afsbase->device_list.lh_Head;
	while (volume->ln.ln_Succ != NULL)
	{
		ioh = &volume->ioh;
		if ((ioh->ioflags & IOHF_MEDIA_CHANGE) && (!volume->inhibitcounter))
		{
			D(bug("[afs 0x%08lX] Media change signalled\n", volume));
			if (diskPresent(afsbase, ioh))
			{
			    if (!volume->inhibitcounter)
			    {
				D(bug("[afs 0x%08lX] Media inserted\n", volume));
				newMedium(afsbase, volume);
			    }
			    ioh->ioflags |= IOHF_DISK_IN;
			}
			else
			{
			    if (!volume->inhibitcounter)
			    {
				flush(afsbase, volume);
				remDosVolume(afsbase, volume);
			    }
			    ioh->ioflags &= ~IOHF_DISK_IN;
			}
			ioh->ioflags &= ~IOHF_MEDIA_CHANGE;
		}
		volume = (struct Volume *)volume->ln.ln_Succ;
	}
}
예제 #8
0
static int scsiDeviceGetReady(SCSIDEVICE* scsi)
{
    if (diskPresent(scsi->diskId)) {
        return 1;
    }
    scsi->keycode = SENSE_MEDIUM_NOT_PRESENT;
    return 0;
}
예제 #9
0
파일: WD2793.c 프로젝트: imclab/CocoaMSX
UInt8 wd2793PeekStatusReg(WD2793* wd)
{
    UInt8 regStatus;

    sync(wd);

    regStatus = wd->regStatus;

	if (((wd->regCommand & 0x80) == 0) || ((wd->regCommand & 0xf0) == 0xd0)) {
		regStatus &= ~(ST_INDEX | ST_TRACK00 | ST_HEAD_LOADED | ST_WRITE_PROTECTED);
    	if (diskEnabled(wd->drive)) {
            if (diskPresent(wd->drive)) {
                if ((UInt64)160 * boardSystemTime() / boardFrequency() & 0x1e) {
			        regStatus |= ST_INDEX;
		        }
            }
		    if (wd->diskTrack == 0) {
			    regStatus |=  ST_TRACK00;
		    }
            if (wd->headLoaded) {
    		    regStatus |=  ST_HEAD_LOADED;
            }
        }
        else {
    		regStatus |= ST_WRITE_PROTECTED;
        }
	} 
    else {
		if (wd2793PeekDataRequest(wd)) {
			regStatus |=  ST_DATA_REQUEST;
		} 
        else {
			regStatus &= ~ST_DATA_REQUEST;
		}
	}

	if (diskPresent(wd->drive)) {
		regStatus &= ~ST_NOT_READY;
	} 
    else {
		regStatus |=  ST_NOT_READY;
	}

	return regStatus;
}
예제 #10
0
UInt16 harddiskIdePeek(HarddiskIde* hd)
{
    UInt16 value;

    if (!hd->transferRead || !diskPresent(hd->diskId)) {
        return 0x7f7f;
    }

    value  = hd->sectorData[hd->sectorDataOffset];
    value |= hd->sectorData[hd->sectorDataOffset + 1] << 8;

    return value;
}
예제 #11
0
UInt16 harddiskIdeRead(HarddiskIde* hd)
{
    UInt16 value;

    if (!hd->transferRead || !diskPresent(hd->diskId)) {
        return 0x7f7f;
    }

    value  = hd->sectorData[hd->sectorDataOffset++];
    value |= hd->sectorData[hd->sectorDataOffset++] << 8;
    if (--hd->transferCount == 0) {
        hd->transferRead = 0;
        hd->statusReg &= ~STATUS_DRQ;
    }
    return value;
}
예제 #12
0
static int scsiDeviceDiskChanged(SCSIDEVICE* scsi)
{
    FileProperties* pDisk;
    int changed = diskChanged(scsi->diskId);

    if (changed) {
        scsi->motor = 1;
        pDisk = &propGetGlobalProperties()->media.disks[scsi->diskId];

        if (scsi->changeCheck2) {
            scsi->changeCheck2 = 0;
            if (scsi->inserted &&
               (strcmp(scsi->disk.fileName, pDisk->fileName) == 0) &&
               (strcmp(scsi->disk.fileNameInZip, pDisk->fileNameInZip) == 0)) {
                SCSILOG("Disk change invalidity\n\n");
                return 0;
            }
        }
        scsi->changed  = 1;
        scsi->disk = *pDisk;
        scsi->inserted = 1;

        SCSILOG1("hdd %d: disk change\n", scsi->scsiId);
        SCSILOG1("filename: %s\n", scsi->disk.fileName);
        SCSILOG1("     zip: %s\n", scsi->disk.fileNameInZip);
    } else {
        if (scsi->inserted & !diskPresent(scsi->diskId)) {
            scsi->inserted = 0;
            scsi->motor    = 0;
            scsi->changed  = 1;
            changed        = 1;
        }
    }

    if (changed && (scsi->mode & MODE_UNITATTENTION)) {
        scsi->reset = 1;
    }
    return changed;
}
예제 #13
0
void harddiskIdeWrite(HarddiskIde* hd, UInt16 value)
{
    if (!hd->transferWrite || !diskPresent(hd->diskId)) {
        return;
    }

    hd->sectorData[hd->sectorDataOffset++] = value & 0xff;
    hd->sectorData[hd->sectorDataOffset++] = value >> 8;
    hd->transferCount--;
    if ((hd->transferCount & 255) == 0) {
        if (!diskWriteSector(hd->diskId, hd->sectorData, hd->transferSectorNumber + 1, 0, 0, 0)) {
            setError(hd, 0x44);
            hd->transferWrite = 0;
            return;
        }
        hd->transferSectorNumber++;
        hd->sectorDataOffset = 0;
    }
    if (hd->transferCount == 0) {
        hd->transferWrite = 0;
        hd->statusReg &= ~STATUS_DRQ;
    }
}
예제 #14
0
struct IOHandle *openBlockDevice(struct AFSBase *afsbase, struct IOHandle *ioh)
{

	ioh->mp = CreateMsgPort();
	if (ioh->mp != NULL)
	{
		ioh->ioreq = openDevice(afsbase, ioh->mp, ioh->blockdevice, ioh->unit, ioh->flags);
		if (ioh->ioreq != NULL)
		{
			ioh->cmdread = CMD_READ;
			ioh->cmdwrite = CMD_WRITE;
			ioh->cmdseek = TD_SEEK;
			ioh->cmdformat = TD_FORMAT;
			ioh->afsbase = afsbase;
			if (diskPresent(afsbase, ioh))
				ioh->ioflags |= IOHF_DISK_IN;
			checkAddChangeInt(afsbase, ioh);
			return ioh;
		}
		DeleteMsgPort(ioh->mp);
	}
	return NULL;
}