mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
(MESS) corvushd: Prep mode now supports multiple drives. [Mike Naberezny]
This allows the Corvus diagnostics program to format any drive. Previously, the drive id sent in the command to enter prep mode was ignored and drive 1 would always be formatted instead.
This commit is contained in:
parent
113fe7f12c
commit
422026f786
@ -74,6 +74,7 @@ corvus_hdc_t::corvus_hdc_t(const machine_config &mconfig, const char *tag, devic
|
||||
device_t(mconfig, CORVUS_HDC, "Corvus Flat Cable HDC", tag, owner, clock, "corvus_hdc", __FILE__),
|
||||
m_status(0),
|
||||
m_prep_mode(false),
|
||||
m_prep_drv(0),
|
||||
m_sectors_per_track(0),
|
||||
m_tracks_per_cylinder(0),
|
||||
m_cylinders_per_drive(0),
|
||||
@ -761,7 +762,58 @@ UINT8 corvus_hdc_t::corvus_read_boot_block(UINT8 block) {
|
||||
|
||||
|
||||
//
|
||||
// Corvus_Read_Firmware_Block
|
||||
// corvus_enter_prep_mode
|
||||
//
|
||||
// Enter prep mode. In prep mode, only prep mode commands may be executed.
|
||||
//
|
||||
// The "prep block" is 512 bytes of Z80 machine code that the host sends to
|
||||
// the controller. The controller will jump to this code after receiving it,
|
||||
// and it is what actually implements prep mode commands. This HLE ignores
|
||||
// the prep block from the host.
|
||||
//
|
||||
// Pass:
|
||||
// drv: Corvus drive id (1..15) to be prepped
|
||||
// prep_block: 512 bytes of Z80 machine code, contents ignored
|
||||
//
|
||||
// Returns:
|
||||
// Status of command
|
||||
//
|
||||
UINT8 corvus_hdc_t::corvus_enter_prep_mode(UINT8 drv, UINT8 *prep_block) {
|
||||
// check if drive is valid
|
||||
if (!corvus_hdc_file(drv)) {
|
||||
logerror("corvus_enter_prep_mode: Failure returned by corvus_hdc_file(%d)\n", drv);
|
||||
return STAT_FATAL_ERR | STAT_DRIVE_NOT_ONLINE;
|
||||
}
|
||||
|
||||
LOG(("corvus_enter_prep_mode: Prep mode entered for drive %d, prep block follows:\n", drv));
|
||||
LOG_BUFFER(prep_block, 512);
|
||||
|
||||
m_prep_mode = true;
|
||||
m_prep_drv = drv;
|
||||
return STAT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// corvus_exit_prep_mode (Prep Mode Only)
|
||||
//
|
||||
// Exit from prep mode and return to normal command mode.
|
||||
//
|
||||
// Returns:
|
||||
// Status of command (always success)
|
||||
//
|
||||
UINT8 corvus_hdc_t::corvus_exit_prep_mode() {
|
||||
LOG(("corvus_exit_prep_mode: Prep mode exited\n"));
|
||||
m_prep_mode = false;
|
||||
m_prep_drv = 0;
|
||||
return STAT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Corvus_Read_Firmware_Block (Prep Mode Only)
|
||||
//
|
||||
// Reads firmware information from the first cylinder of the drive
|
||||
//
|
||||
@ -781,14 +833,14 @@ UINT8 corvus_hdc_t::corvus_read_firmware_block(UINT8 head, UINT8 sector) {
|
||||
LOG(("corvus_read_firmware_block: Reading firmware head: 0x%2.2x, sector: 0x%2.2x, relative_sector: 0x%2.2x\n",
|
||||
head, sector, relative_sector));
|
||||
|
||||
status = corvus_read_sector(1, relative_sector, m_buffer.read_512_response.data, 512); // TODO: Which drive should Prep Mode talk to ???
|
||||
status = corvus_read_sector(m_prep_drv, relative_sector, m_buffer.read_512_response.data, 512);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Corvus_Write_Firmware_Block
|
||||
// Corvus_Write_Firmware_Block (Prep Mode Only)
|
||||
//
|
||||
// Writes firmware information to the first cylinder of the drive
|
||||
//
|
||||
@ -809,14 +861,14 @@ UINT8 corvus_hdc_t::corvus_write_firmware_block(UINT8 head, UINT8 sector, UINT8
|
||||
LOG(("corvus_write_firmware_block: Writing firmware head: 0x%2.2x, sector: 0x%2.2x, relative_sector: 0x%2.2x\n",
|
||||
head, sector, relative_sector));
|
||||
|
||||
status = corvus_write_sector(1, relative_sector, buffer, 512); // TODO: Which drive should Prep Mode talk to ???
|
||||
status = corvus_write_sector(m_prep_drv, relative_sector, buffer, 512);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Corvus_Format_Drive
|
||||
// Corvus_Format_Drive (Prep Mode Only)
|
||||
//
|
||||
// Write the pattern provided across the entire disk
|
||||
//
|
||||
@ -833,7 +885,7 @@ UINT8 corvus_hdc_t::corvus_format_drive(UINT8 *pattern, UINT16 len) {
|
||||
UINT8 tbuffer[512];
|
||||
|
||||
// Set up m_tracks_per_cylinder and m_sectors_per_track
|
||||
corvus_hdc_file(1);
|
||||
corvus_hdc_file(m_prep_drv);
|
||||
|
||||
max_sector = m_sectors_per_track * m_tracks_per_cylinder * m_cylinders_per_drive;
|
||||
|
||||
@ -849,7 +901,7 @@ UINT8 corvus_hdc_t::corvus_format_drive(UINT8 *pattern, UINT16 len) {
|
||||
LOG_BUFFER(pattern, 512);
|
||||
|
||||
for(sector = 0; sector <= max_sector; sector++) {
|
||||
status = corvus_write_sector(1, sector, pattern, 512);
|
||||
status = corvus_write_sector(m_prep_drv, sector, pattern, 512);
|
||||
if(status != STAT_SUCCESS) {
|
||||
logerror("corvus_format_drive: Error while formatting drive in corvus_write_sector--sector: 0x%5.5x, status: 0x%x2.2x\n",
|
||||
sector, status);
|
||||
@ -995,8 +1047,9 @@ void corvus_hdc_t::corvus_process_command_packet(bool invalid_command_flag) {
|
||||
corvus_get_drive_parameters(m_buffer.get_drive_parameters_command.drive);
|
||||
break;
|
||||
case PREP_MODE_SELECT:
|
||||
m_prep_mode = true;
|
||||
m_buffer.single_byte_response.status = STAT_SUCCESS;
|
||||
m_buffer.single_byte_response.status =
|
||||
corvus_enter_prep_mode(m_buffer.prep_mode_command.drive,
|
||||
m_buffer.prep_mode_command.prep_block);
|
||||
break;
|
||||
default:
|
||||
m_xmit_bytes = 1; // Return a fatal status
|
||||
@ -1007,12 +1060,13 @@ void corvus_hdc_t::corvus_process_command_packet(bool invalid_command_flag) {
|
||||
} else { // In Prep mode
|
||||
switch(m_buffer.command.code) {
|
||||
case PREP_MODE_SELECT:
|
||||
m_prep_mode = true;
|
||||
m_buffer.single_byte_response.status = STAT_SUCCESS;
|
||||
m_buffer.single_byte_response.status =
|
||||
corvus_enter_prep_mode(m_buffer.prep_mode_command.drive,
|
||||
m_buffer.prep_mode_command.prep_block);
|
||||
break;
|
||||
case PREP_RESET_DRIVE:
|
||||
m_prep_mode = false;
|
||||
m_buffer.single_byte_response.status = STAT_SUCCESS;
|
||||
m_buffer.single_byte_response.status =
|
||||
corvus_exit_prep_mode();
|
||||
break;
|
||||
case PREP_READ_FIRMWARE:
|
||||
m_buffer.drive_param_response.status =
|
||||
|
@ -206,7 +206,9 @@ private:
|
||||
};
|
||||
|
||||
UINT8 m_status; // Controller status byte (DIRECTION + BUSY/READY)
|
||||
// Prep mode
|
||||
bool m_prep_mode; // Whether the controller is in Prep Mode or not
|
||||
UINT8 m_prep_drv; // If in prep mode, Corvus drive id (1..15) being prepped
|
||||
// Physical drive info
|
||||
UINT8 m_sectors_per_track; // Number of sectors per track for this drive
|
||||
UINT8 m_tracks_per_cylinder;// Number of tracks per cylinder (heads)
|
||||
@ -400,6 +402,14 @@ private:
|
||||
UINT8 boot_block; // Which boot block to read (0-7)
|
||||
} old_boot_command;
|
||||
//
|
||||
// Put drive into prep mode command (0x11)
|
||||
//
|
||||
struct {
|
||||
UINT8 code; // Command code
|
||||
UINT8 drive; // Drive number (starts at 1)
|
||||
UINT8 prep_block[512]; // Z80 machine code payload
|
||||
} prep_mode_command;
|
||||
//
|
||||
// Read Firmware command (Prep Mode 0x32)
|
||||
//
|
||||
struct {
|
||||
@ -499,6 +509,8 @@ private:
|
||||
UINT8 corvus_init_semaphore_table();
|
||||
UINT8 corvus_get_drive_parameters(UINT8 drv);
|
||||
UINT8 corvus_read_boot_block(UINT8 block);
|
||||
UINT8 corvus_enter_prep_mode(UINT8 drv, UINT8 *prep_block);
|
||||
UINT8 corvus_exit_prep_mode();
|
||||
UINT8 corvus_read_firmware_block(UINT8 head, UINT8 sector);
|
||||
UINT8 corvus_write_firmware_block(UINT8 head, UINT8 sector, UINT8 *buffer);
|
||||
UINT8 corvus_format_drive(UINT8 *pattern, UINT16 len);
|
||||
|
Loading…
Reference in New Issue
Block a user