Esempio n. 1
0
void UPD765A::process_cmd(int cmd)
{
	switch(cmd & 0x1f) {
	case 0x02:
		cmd_read_diagnostic();
		break;
	case 0x03:
		cmd_specify();
		break;
	case 0x04:
		cmd_sence_devstat();
		break;
	case 0x05:
	case 0x09:
		cmd_write_data();
		break;
	case 0x06:
	case 0x0c:
		cmd_read_data();
		break;
	case 0x07:
		cmd_recalib();
		break;
	case 0x08:
		cmd_sence_intstat();
		break;
	case 0x0a:
		cmd_read_id();
		break;
	case 0x0d:
		cmd_write_id();
		break;
	case 0x0f:
		cmd_seek();
		break;
	case 0x11:
	case 0x19:
	case 0x1d:
		cmd_scan();
		break;
	default:
		cmd_invalid();
		break;
	}
}
Esempio n. 2
0
static int main_cmd(int argc, char *argv[])
{
	if (argc < 1) {
		return help();
	}

	char *cmd = *argv++; argc--;

	if (contains(cmd, "key")) {
		if (argc < 2) {
			return help();
		}
		uint32_t lockkey = strtoul(argv[0], NULL, 0);
		hdhomerun_device_tuner_lockkey_use_value(hd, lockkey);

		cmd = argv[1];
		argv+=2; argc-=2;
	}

	if (contains(cmd, "get")) {
		if (argc < 1) {
			return help();
		}
		return cmd_get(argv[0]);
	}

	if (contains(cmd, "set")) {
		if (argc < 2) {
			return help();
		}
		return cmd_set(argv[0], argv[1]);
	}

	if (contains(cmd, "scan")) {
		if (argc < 1) {
			return help();
		}
		if (argc < 2) {
			return cmd_scan(argv[0], NULL);
		} else {
			return cmd_scan(argv[0], argv[1]);
		}
	}

	if (contains(cmd, "save")) {
		if (argc < 2) {
			return help();
		}
		return cmd_save(argv[0], argv[1]);
	}

	if (contains(cmd, "upgrade")) {
		if (argc < 1) {
			return help();
		}
		return cmd_upgrade(argv[0]);
	}

	if (contains(cmd, "execute")) {
		return cmd_execute();
	}

	return help();
}
Esempio n. 3
0
void fdc_write_data(byte val)
{
    int idx;

#ifdef DEBUG_FDC
    if (FDC.phase == CMD_PHASE) {
        if (FDC.byte_count) {
            fprintf(pfoDebug, "%02x ", val);
        }
        else {
            fprintf(pfoDebug, "\n%02x: ", val);
        }
    }
#endif

    switch (FDC.phase)
    {
    case CMD_PHASE: // in command phase?
        if (FDC.byte_count) { // receiving command parameters?
            FDC.command[FDC.byte_count++] = val; // copy to buffer
            if (FDC.byte_count == FDC.cmd_length) { // received all command bytes?
                FDC.byte_count = 0; // clear byte counter
                FDC.phase = EXEC_PHASE; // switch to execution phase
                FDC.cmd_handler();
            }
        }
        else { // first command byte received
            if (val & 0x20) { // skip DAM or DDAM?
                FDC.flags |= SKIP_flag; // DAM/DDAM will be skipped
                val &= ~0x20; // reset skip bit in command byte
            }
            else {
                FDC.flags &= ~SKIP_flag; // make sure skip inidicator is off
            }
            for (idx = 0; idx < MAX_CMD_COUNT; idx++) { // loop through all known FDC commands
                if (fdc_cmd_table[idx].cmd == val) { // do we have a match?
                    break;
                }
            }
            if (idx != MAX_CMD_COUNT) { // valid command received
                FDC.cmd_length = fdc_cmd_table[idx].cmd_length; // command length in bytes
                FDC.res_length = fdc_cmd_table[idx].res_length; // result length in bytes
                FDC.cmd_direction = fdc_cmd_table[idx].cmd_direction; // direction is CPU to FDC, or FDC to CPU
                FDC.cmd_handler = fdc_cmd_table[idx].cmd_handler; // pointer to command handler

                FDC.command[FDC.byte_count++] = val; // copy command code to buffer
                if (FDC.byte_count == FDC.cmd_length) { // already received all command bytes?
                    FDC.byte_count = 0; // clear byte counter
                    FDC.phase = EXEC_PHASE; // switch to execution phase
                    FDC.cmd_handler();
                }
            }
            else { // unknown command received
                FDC.result[0] = 0x80; // indicate invalid command
                FDC.res_length = 1;
                FDC.phase = RESULT_PHASE; // switch to result phase
            }
        }
        break;
    case EXEC_PHASE: // in execution phase?
        if (FDC.cmd_direction == CPU_TO_FDC) { // proper direction?
            FDC.timeout = OVERRUN_TIMEOUT;
            if ((FDC.flags & SCAN_flag)) { // processing any of the scan commands?
                if (val != 0xff) { // no comparison on CPU byte = 0xff
                    switch((FDC.command[CMD_CODE] & 0x1f))
                    {
                    case 0x51: // scan equal
                        if (val != *FDC.buffer_ptr) {
                            FDC.result[RES_ST2] &= 0xf7; // reset Scan Equal Hit
                            FDC.flags |= SCANFAILED_flag;
                        }
                        break;
                    case 0x59: // scan low or equal
                        if (val != *FDC.buffer_ptr) {
                            FDC.result[RES_ST2] &= 0xf7; // reset Scan Equal Hit
                        }
                        if (val > *FDC.buffer_ptr) {
                            FDC.flags |= SCANFAILED_flag;
                        }
                        break;
                    case 0x5d: // scan high or equal
                        if (val != *FDC.buffer_ptr) {
                            FDC.result[RES_ST2] &= 0xf7; // reset Scan Equal Hit
                        }
                        if (val < *FDC.buffer_ptr) {
                            FDC.flags |= SCANFAILED_flag;
                        }
                        break;
                    }
                }
                FDC.buffer_ptr++; // advance sector data pointer
            }
            else {
                *FDC.buffer_ptr++ = val; // write byte to sector
            }
            if (FDC.buffer_ptr > FDC.buffer_endptr) {
                FDC.buffer_ptr = active_track->data; // wrap around
            }
            if (--FDC.buffer_count == 0) { // processed all data?
                if ((FDC.flags & SCAN_flag)) { // processing any of the scan commands?
                    if ((FDC.flags & SCANFAILED_flag) && (FDC.command[CMD_R] != FDC.command[CMD_EOT])) {
                        FDC.command[CMD_R] += FDC.command[CMD_STP]; // advance to next sector
                        cmd_scan();
                    }
                    else {
                        if ((FDC.flags & SCANFAILED_flag)) {
                            FDC.result[RES_ST2] |= 0x04; // Scan Not Satisfied
                        }

                        LOAD_RESULT_WITH_CHRN

                        FDC.phase = RESULT_PHASE; // switch to result phase
                    }
                }
                else if (FDC.command[CMD_CODE] == 0x4d) { // write ID command?
                    dword sector_size, track_size;
                    byte *pbPtr, *pbDataPtr;

                    if (active_track->sectors != 0) { // track is formatted?
                        free(active_track->data); // dealloc memory for old track data
                    }
                    sector_size = 128 << FDC.command[CMD_C]; // determine number of bytes from N value
                    if (((sector_size + 62 + FDC.command[CMD_R]) * FDC.command[CMD_H]) > CPC.max_tracksize) { // track size exceeds maximum?
                        active_track->sectors = 0; // 'unformat' track
                    }
                    else {
                        int sector;

                        track_size = sector_size * FDC.command[CMD_H];
                        active_track->sectors = FDC.command[CMD_H];
                        active_track->data = (byte *)malloc(track_size); // attempt to allocate the required memory
                        pbDataPtr = active_track->data;
                        pbPtr = pbGPBuffer;
                        for (sector = 0; sector < FDC.command[CMD_H]; sector++) {
                            memcpy(active_track->sector[sector].CHRN, pbPtr, 4); // copy CHRN
                            memset(active_track->sector[sector].flags, 0, 2); // clear ST1 & ST2
                            active_track->sector[sector].data = pbDataPtr; // store pointer to sector data
                            pbDataPtr += sector_size;
                            pbPtr += 4;
                        }
                        memset(active_track->data, FDC.command[CMD_N], track_size); // fill track data with specified byte value
                    }
                    pbPtr = pbGPBuffer + ((FDC.command[CMD_H]-1) * 4); // pointer to the last CHRN passed to writeID
                    memcpy(&FDC.result[RES_C], pbPtr, 4); // copy sector's CHRN to result buffer
                    FDC.result[RES_N] = FDC.command[CMD_C]; // overwrite with the N value from the writeID command

                    active_drive->altered = 1; // indicate that the image has been modified
                    FDC.phase = RESULT_PHASE; // switch to result phase
                }
                else if (FDC.command[CMD_R] != FDC.command[CMD_EOT]) { // haven't reached End of Track?
                    FDC.command[CMD_R]++; // advance to next sector
                    cmd_write();
                }
                else {
                    active_drive->altered = 1; // indicate that the image has been modified

                    FDC.result[RES_ST0] |= 0x40; // AT
                    FDC.result[RES_ST1] |= 0x80; // End of Cylinder

                    LOAD_RESULT_WITH_CHRN

                    FDC.phase = RESULT_PHASE; // switch to result phase
                }
            }
        }
        break;
    }
}
Esempio n. 4
0
void UPD765A::write_io8(uint32 addr, uint32 data)
{
	if(addr & 1) {
		// fdc data
		if((status & (S_RQM | S_DIO)) == S_RQM) {
			status &= ~S_RQM;
			
			switch(phase) {
			case PHASE_IDLE:
#ifdef _FDC_DEBUG_LOG
				switch(data & 0x1f) {
				case 0x02:
					emu->out_debug_log("FDC: CMD=%2x READ DIAGNOSTIC\n", data);
					break;
				case 0x03:
					emu->out_debug_log("FDC: CMD=%2x SPECIFY\n", data);
					break;
				case 0x04:
					emu->out_debug_log("FDC: CMD=%2x SENCE DEVSTAT\n", data);
					break;
				case 0x05:
				case 0x09:
					emu->out_debug_log("FDC: CMD=%2x WRITE DATA\n", data);
					break;
				case 0x06:
				case 0x0c:
					emu->out_debug_log("FDC: CMD=%2x READ DATA\n", data);
					break;
				case 0x07:
					emu->out_debug_log("FDC: CMD=%2x RECALIB\n", data);
					break;
				case 0x08:
					emu->out_debug_log("FDC: CMD=%2x SENCE INTSTAT\n", data);
					break;
				case 0x0a:
					emu->out_debug_log("FDC: CMD=%2x READ ID\n", data);
					break;
				case 0x0d:
					emu->out_debug_log("FDC: CMD=%2x WRITE ID\n", data);
					break;
				case 0x0f:
					emu->out_debug_log("FDC: CMD=%2x SEEK\n", data);
					break;
				case 0x11:
				case 0x19:
				case 0x1d:
					emu->out_debug_log("FDC: CMD=%2x SCAN\n", data);
					break;
				default:
					emu->out_debug_log("FDC: CMD=%2x INVALID\n", data);
					break;
				}
#endif
				command = data;
				process_cmd(command & 0x1f);
				break;
				
			case PHASE_CMD:
#ifdef _FDC_DEBUG_LOG
				emu->out_debug_log("FDC: PARAM=%2x\n", data);
#endif
				*bufptr++ = data;
				if(--count) {
					status |= S_RQM;
				} else {
					process_cmd(command & 0x1f);
				}
				break;
				
			case PHASE_WRITE:
#ifdef _FDC_DEBUG_LOG
				emu->out_debug_log("FDC: WRITE=%2x\n", data);
#endif
				*bufptr++ = data;
				set_drq(false);
				if(--count) {
					REGISTER_DRQ_EVENT();
				} else {
					process_cmd(command & 0x1f);
				}
				fdc[hdu & DRIVE_MASK].access = true;
				break;
				
			case PHASE_SCAN:
				if(data != 0xff) {
					if(((command & 0x1f) == 0x11 && *bufptr != data) ||
					   ((command & 0x1f) == 0x19 && *bufptr >  data) ||
					   ((command & 0x1f) == 0x1d && *bufptr <  data)) {
						result &= ~ST2_SH;
					}
				}
				bufptr++;
				set_drq(false);
				if(--count) {
					REGISTER_DRQ_EVENT();
				} else {
					cmd_scan();
				}
				fdc[hdu & DRIVE_MASK].access = true;
				break;
			}
		}
	}
}