示例#1
0
文件: omti8621.c 项目: clobber/UME
static void format_track(omti8621_state *state, const UINT8 * cdb) {
	UINT8 lun = get_lun(cdb);
	UINT32 disk_addr = get_disk_address(state, cdb);
	UINT32 disk_track = get_disk_track(state, cdb);

	if (state->diskaddr_ecc_error == disk_addr) {
		// reset previous ECC error
		state->diskaddr_ecc_error = 0;
	}

	if (state->diskaddr_format_bad_track == disk_track) {
		// reset previous bad track formatting
		state->diskaddr_format_bad_track = 0;
	}

	if (state->alternate_track_address[0] == disk_track) {
		// reset source of alternate track address
		state->alternate_track_address[0] = 0;
	}

	if (state->alternate_track_address[1] == disk_track) {
		// reset alternate track address
		state->alternate_track_address[1] = 0;
	}

	if (check_disk_address(state, cdb) ) {
		if ((cdb[5] & 0x40) == 0) {
			memset(state->sector_buffer, 0x6C, OMTI_DISK_SECTOR_SIZE * state->disk[lun]->sectors);
		}
		write_sectors_to_disk(state, disk_addr, state->disk[lun]->sectors, lun);
	}

}
示例#2
0
void omti8621_device::format_track(const UINT8 * cdb)
{
	UINT8 lun = get_lun(cdb);
	UINT32 disk_addr = get_disk_address(cdb);
	UINT32 disk_track = get_disk_track(cdb);

	if (diskaddr_ecc_error == disk_addr) {
		// reset previous ECC error
		diskaddr_ecc_error = 0;
	}

	if (diskaddr_format_bad_track == disk_track) {
		// reset previous bad track formatting
		diskaddr_format_bad_track = 0;
	}

	if (alternate_track_address[0] == disk_track) {
		// reset source of alternate track address
		alternate_track_address[0] = 0;
	}

	if (alternate_track_address[1] == disk_track) {
		// reset alternate track address
		alternate_track_address[1] = 0;
	}

	if (check_disk_address(cdb) ) {
		if ((cdb[5] & 0x40) == 0) {
			memset(&sector_buffer[0], 0x6C, OMTI_DISK_SECTOR_SIZE * our_disks[lun]->m_sectors);
		}
		write_sectors_to_disk(disk_addr, our_disks[lun]->m_sectors, lun);
	}

}
示例#3
0
UINT8 omti8621_device::check_disk_address(const UINT8 *cdb)
{
	UINT8 sense_code = OMTI_SENSE_CODE_NO_ERROR;
	UINT8 lun = get_lun(cdb);
	UINT16 head = cdb[1] & 0x1f;
	UINT16 sector = cdb[2] & 0x3f;
	UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3);
	UINT8 block_count = cdb[4];
	omti_disk_image_device *disk = our_disks[lun];

	UINT32 disk_track = cylinder * disk->m_heads + head;
	UINT32 disk_addr = (disk_track * disk->m_sectors) + sector;

	if (block_count > OMTI_MAX_BLOCK_COUNT) {
		LOG(("########### check_disk_address: unexpected block count %x", block_count));
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	}

	if (lun > OMTI_MAX_LUN) {
		sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY;
	} else  if (!disk->m_image->exists()) {
		sense_code = OMTI_SENSE_CODE_DRIVE_NOT_READY;
	} else  if (sector >= OMTI_MAX_BLOCK_COUNT) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if (head >= disk->m_heads) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if (cylinder >= disk->m_cylinders) {
		sense_code = OMTI_SENSE_CODE_ILLEGAL_ADDRESS | OMTI_SENSE_CODE_ADDRESS_VALID;
	} else if ( disk_track == diskaddr_format_bad_track && disk_track != 0) {
		sense_code = OMTI_SENSE_CODE_BAD_TRACK;
	} else if (disk_addr == diskaddr_ecc_error && disk_addr != 0) {
		sense_code = OMTI_SENSE_CODE_ECC_ERROR;
	} else if (disk_track == alternate_track_address[1] && disk_track != 0) {
		sense_code = OMTI_SENSE_CODE_ALTERNATE_TRACK;
	}

	if (sense_code == OMTI_SENSE_CODE_NO_ERROR) {
		clear_sense_data();
	} else {
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		set_sense_data(sense_code, cdb);
	}
	return sense_code == OMTI_SENSE_CODE_NO_ERROR;
}
示例#4
0
void omti8621_device::do_command(const UINT8 cdb[], const UINT16 cdb_length)
{
	UINT8 lun = get_lun(cdb);
	omti_disk_image_device *disk = our_disks[lun];
	int command_duration = 0; // ms

	log_command( cdb, cdb_length);

	// default to read status and status is successful completion
	omti_state = OMTI_STATE_STATUS;
	status_port |= OMTI_STATUS_IO | OMTI_STATUS_CD;
	command_status = lun ? OMTI_COMMAND_STATUS_LUN : 0;

	if (mask_port & OMTI_MASK_INTE) {
		set_interrupt(CLEAR_LINE);
	}

	if (!disk->m_image->exists()) {
		command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive
	}

	switch (cdb[0]) {
	case OMTI_CMD_TEST_DRIVE_READY: // 0x00
		if (!disk->m_image->exists())
		{
			set_sense_data(OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb);
		}
		break;

	case OMTI_CMD_RECALIBRATE: // 0x01
		break;

	case OMTI_CMD_REQUEST_SENSE: // 0x03
		set_data_transfer(sense_data, sizeof(sense_data));
		break;

	case OMTI_CMD_READ_VERIFY: // 0x05
		check_disk_address(cdb);
		break;

	case OMTI_CMD_FORMAT_TRACK: // 0x06
		format_track(cdb);
		break;

	case OMTI_CMD_FORMAT_BAD_TRACK: // 0x07
		diskaddr_format_bad_track = get_disk_address(cdb);
		break;

	case OMTI_CMD_READ: // 0x08
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk(get_disk_address(cdb), cdb[4], lun);
			set_data_transfer(&sector_buffer[0],  OMTI_DISK_SECTOR_SIZE*cdb[4]);
		}
		break;

	case OMTI_CMD_WRITE: // 0x0A
		log_data();
		if (check_disk_address(cdb)) {
			write_sectors_to_disk(get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_SEEK: // 0x0B
		check_disk_address(cdb);
		break;

	case OMTI_CMD_READ_SECTOR_BUFFER: // 0x0E
		set_data_transfer(&sector_buffer[0], OMTI_DISK_SECTOR_SIZE*cdb[4]);
		break;

	case OMTI_CMD_WRITE_SECTOR_BUFFER: // 0x0F
		log_data();
		break;

	case OMTI_CMD_COPY: // 0x20
		if (check_disk_address(cdb) && check_disk_address(cdb+4)) {
			// copy sectors
			copy_sectors (get_disk_address(cdb+4), get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37
		set_esdi_defect_list(get_lun(cdb), cdb[1] & 0x1f);
		set_data_transfer(disk->m_esdi_defect_list, sizeof(disk->m_esdi_defect_list));
		break;

#if 0   // this command seems unused by Domain/OS, and it's unclear what the intent of the code is (it makes some versions of GCC quite unhappy)
	case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11
		log_data();
		alternate_track_address[0] = get_disk_track(cdb);
		alternate_track_address[1] = get_disk_track(alternate_track_buffer-1);
		break;
#endif

	case OMTI_CMD_READ_DATA_TO_BUFFER: // 0x1E
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk (get_disk_address(cdb), cdb[4], lun);
			// Domain/OS doesn't expect zero access time
			command_duration += 1; // 1 ms is enough, average time would be 30 ms)
		}
		break;

	case OMTI_CMD_WRITE_DATA_FROM_BUFFER: // 0x1F
		log_data();
		if (check_disk_address(cdb)) {
			write_sectors_to_disk(get_disk_address(cdb), cdb[4], lun);
		}
		break;

	case  OMTI_CMD_RAM_DIAGNOSTICS: // 0xE0
		break;

	case OMTI_CMD_CONTROLLER_INT_DIAGNOSTIC: // 0xE4
		break;

	case OMTI_CMD_READ_LONG: // 0xE5
		if (check_disk_address(cdb)) {
			// read data from controller
			read_sectors_from_disk(get_disk_address(cdb), cdb[4], lun);
			set_data_transfer(&sector_buffer[0], OMTI_DISK_SECTOR_SIZE+6);
		}
		break;

	case OMTI_CMD_WRITE_LONG: // 0xE6
		log_data();
		if (check_disk_address(cdb)) {
			UINT32 diskaddr =  get_disk_address(cdb);
			write_sectors_to_disk(diskaddr, cdb[4], lun);
			// this will spoil the ECC code
			diskaddr_ecc_error = diskaddr;
		}
		break;

	case OMTI_CMD_READ_CONFIGURATION: // 0xEC
		set_configuration_data(get_lun(cdb));
		set_data_transfer(disk->m_config_data, sizeof(disk->m_config_data));
		break;

	case OMTI_CMD_INVALID_COMMAND: // 0xFF
		set_sense_data(OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;

	default:
		LOG(("do_command: UNEXPECTED command %02x",cdb[0]));
		set_sense_data(OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;
	}

	if (mask_port & OMTI_MASK_INTE) {
//      if (omti_state != OMTI_STATE_STATUS) {
//          LOG(("do_command: UNEXPECTED omti_state %02x",omti_state));
//      }
		status_port |= OMTI_STATUS_IREQ;
		if (command_duration == 0)
		{
			set_interrupt(ASSERT_LINE);
		}
		else
		{
			// FIXME: should delay omti_state and status_port as well
			m_timer->adjust(attotime::from_msec(command_duration), 0);
		}
	}
}
示例#5
0
UINT32 omti8621_device::get_disk_address(const UINT8 * cdb) {
	UINT8 lun = get_lun(cdb);
	UINT16 sector = cdb[2] & 0x3f;
	return get_disk_track(cdb) * our_disks[lun]->m_sectors + sector;
}
示例#6
0
UINT32 omti8621_device::get_disk_track(const UINT8 * cdb) {
	UINT8 lun = get_lun(cdb);
	UINT16 head = cdb[1] & 0x1f;
	UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3);
	return cylinder * our_disks[lun]->m_heads + head;
}
示例#7
0
文件: icv196test.c 项目: dcobas/coht
int main(int argc,char *argv[])
{
	int rp, pr, dev;
	char *cp;
	char host[49];
	char tmpb[CMD_BUF_SIZE];

	pname = argv[0];
	printf("%s: Compiled %s %s\n",pname,__DATE__,__TIME__);

	if (argc > 1)
		dev = strtoul(argv[1],&cp,0);

	do_open(dev);
	show_dev(1);

	bzero((void *) host,49);
	gethostname(host,48);

	while (True) {

		sprintf(prompt,"%s:Icv196.%d[%02d]",host,get_lun(),cmdindx+1);
		printf("%s",prompt);

		cmdbuf = &(history[cmdindx][0]);

		bzero((void *) tmpb,CMD_BUF_SIZE);
		if (fgets(tmpb,CMD_BUF_SIZE,stdin) == NULL) break;

		cp = &(tmpb[0]);
		pr = 0;           /* Dont print a history */
		rp = 0;           /* Dont repeat a command */

		while ((*cp == '-')
		||     (*cp == '+')
		||     (*cp == '.')
		||     (*cp == '!')) {

			pr = 1;        /* Print command on */

			if (*cp == '!') {
				cp++;
				cmdindx = strtoul(cp,&cp,0) -1;
				if (cmdindx >= HISTORIES) cmdindx = 0;
				if (cmdindx < 0) cmdindx = HISTORIES -1;
				rp = 1;
				break;
			}

			if (*cp == '-') {
				if (--cmdindx < 0) cmdindx = HISTORIES -1;
				cmdbuf = &(history[cmdindx][0]);
			}

			if (*cp == '+') {
				if (++cmdindx >= HISTORIES) cmdindx = 0;
				cmdbuf = &(history[cmdindx][0]);
			}

			if (*cp == '.') {
				rp = 1;
				break;
			}

			cp++;
		}
		if (pr) {
			printf("{%s}\t ",cmdbuf); fflush(stdout);
			if (!rp) continue;
		}
		if (!rp) strcpy(cmdbuf,tmpb);

		bzero((void *) val_bufs,sizeof(val_bufs));
		GetAtoms(cmdbuf);
		DoCmd(0);

		if ((!rp) && (++cmdindx >= HISTORIES)) cmdindx = 0;
	}
	exit(0);
}
示例#8
0
文件: omti8621.c 项目: clobber/UME
static void do_command(omti8621_state *state,
		const UINT8 cdb[], const UINT16 cdb_length) {

	UINT8 lun = get_lun(cdb);
	disk_data *disk = state->disk[lun];
	int command_duration = 0; // ms

	log_command( state, cdb, cdb_length);

	// default to read status and status is successful completion
	state->omti_state = OMTI_STATE_STATUS;
	state->status_port |= OMTI_STATUS_IO | OMTI_STATUS_CD;
	state->command_status = lun ? OMTI_COMMAND_STATUS_LUN : 0;

	if (state->mask_port & OMTI_MASK_INTE) {
		set_interrupt(state, CLEAR_LINE);
	}

	if (!disk->image->exists()) {
		state->command_status |= OMTI_COMMAND_STATUS_ERROR; // no such drive
	}

	switch (cdb[0]) {
	case OMTI_CMD_TEST_DRIVE_READY: // 0x00
		if (!disk->image->exists())
		{
			set_sense_data(state, OMTI_SENSE_CODE_DRIVE_NOT_READY, cdb);
		}
		break;

	case OMTI_CMD_RECALIBRATE: // 0x01
		break;

	case OMTI_CMD_REQUEST_SENSE: // 0x03
		set_data_transfer(state, state->sense_data, sizeof(state->sense_data));
		break;

	case OMTI_CMD_READ_VERIFY: // 0x05
		check_disk_address(state, cdb);
		break;

	case OMTI_CMD_FORMAT_TRACK: // 0x06
		format_track(state, cdb);
		break;

	case OMTI_CMD_FORMAT_BAD_TRACK: // 0x07
		state->diskaddr_format_bad_track = get_disk_address(state, cdb);
		break;

	case OMTI_CMD_READ: // 0x08
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk(state, get_disk_address(state, cdb), cdb[4], lun);
			set_data_transfer(state, state->sector_buffer,  OMTI_DISK_SECTOR_SIZE*cdb[4]);
		}
		break;

	case OMTI_CMD_WRITE: // 0x0A
		log_data(state);
		if (check_disk_address(state, cdb)) {
			write_sectors_to_disk(state, get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_SEEK: // 0x0B
		check_disk_address(state, cdb);
		break;

	case OMTI_CMD_READ_SECTOR_BUFFER: // 0x0E
		set_data_transfer(state, state->sector_buffer, OMTI_DISK_SECTOR_SIZE*cdb[4]);
		break;

	case OMTI_CMD_WRITE_SECTOR_BUFFER: // 0x0F
		log_data(state);
		break;

	case OMTI_CMD_COPY: // 0x20
		if (check_disk_address(state, cdb) && check_disk_address(state, cdb+4)) {
			// copy sectors
			copy_sectors (state, get_disk_address(state,  cdb+4), get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case OMTI_CMD_READ_ESDI_DEFECT_LIST: // 0x37
		set_esdi_defect_list(state, get_lun(cdb), cdb[1] & 0x1f);
		set_data_transfer(state, disk->esdi_defect_list, sizeof(disk->esdi_defect_list));
		break;

	case OMTI_CMD_ASSIGN_ALTERNATE_TRACK: // 0x11
		log_data(state);
		state->alternate_track_address[0] = get_disk_track(state, cdb);
		state->alternate_track_address[1] = get_disk_track(state, state->alternate_track_buffer-1);;
		break;

	case OMTI_CMD_READ_DATA_TO_BUFFER: // 0x1E
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk (state, get_disk_address(state, cdb), cdb[4], lun);
			// Domain/OS doesn't expect zero access time
			command_duration += 1; // 1 ms is enough, average time would be 30 ms)
		}
		break;

	case OMTI_CMD_WRITE_DATA_FROM_BUFFER: // 0x1F
		log_data(state);
		if (check_disk_address(state, cdb)) {
			write_sectors_to_disk(state, get_disk_address(state, cdb), cdb[4], lun);
		}
		break;

	case  OMTI_CMD_RAM_DIAGNOSTICS: // 0xE0
		break;

	case OMTI_CMD_CONTROLLER_INT_DIAGNOSTIC: // 0xE4
		break;

	case OMTI_CMD_READ_LONG: // 0xE5
		if (check_disk_address(state, cdb)) {
			// read data from controller
			read_sectors_from_disk(state, get_disk_address(state, cdb), cdb[4], lun);
			set_data_transfer(state, state->sector_buffer, OMTI_DISK_SECTOR_SIZE+6);
		}
		break;

	case OMTI_CMD_WRITE_LONG: // 0xE6
		log_data(state);
		if (check_disk_address(state, cdb)) {
			UINT32 diskaddr =  get_disk_address(state, cdb);
			write_sectors_to_disk(state, diskaddr, cdb[4], lun);
			// this will spoil the ECC code
			state->diskaddr_ecc_error = diskaddr;
		}
		break;

	case OMTI_CMD_READ_CONFIGURATION: // 0xEC
		set_configuration_data(state, get_lun(cdb));
		set_data_transfer(state, disk->config_data, sizeof(disk->config_data));
		break;

	case OMTI_CMD_INVALID_COMMAND: // 0xFF
		set_sense_data(state, OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		state->command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;

	default:
		LOG(("do_command: UNEXPECTED command %02x",cdb[0]));
		set_sense_data(state, OMTI_SENSE_CODE_INVALID_COMMAND, cdb);
		state->command_status |= OMTI_COMMAND_STATUS_ERROR;
		break;
	}

	if (state->mask_port & OMTI_MASK_INTE) {
//      if (state->omti_state != OMTI_STATE_STATUS) {
//          LOG(("do_command: UNEXPECTED omti_state %02x",state->omti_state));
//      }
		state->status_port |= OMTI_STATUS_IREQ;
		if (command_duration == 0) {
			set_interrupt(state, ASSERT_LINE);
		} else {
			// FIXME: should delay state->omti_state and state->status_port as well
			state->device->machine().scheduler().timer_set(attotime::from_msec(command_duration), FUNC(set_interrupt_caba), 0, state);
		}
	}
}
示例#9
0
文件: omti8621.c 项目: clobber/UME
static UINT32 get_disk_address(const omti8621_state *state, const UINT8 * cdb) {
	UINT8 lun = get_lun(cdb);
	UINT16 sector = cdb[2] & 0x3f;
	return get_disk_track(state, cdb) * state->disk[lun]->sectors + sector;
}
示例#10
0
文件: omti8621.c 项目: clobber/UME
static UINT32 get_disk_track(const omti8621_state *state, const UINT8 * cdb) {
	UINT8 lun = get_lun(cdb);
	UINT16 head = cdb[1] & 0x1f;
	UINT32 cylinder = cdb[3] + ((cdb[2] & 0xc0) << 2) + ((cdb[1] & 0x80) << 3);
	return cylinder * state->disk[lun]->heads + head;
}