diff options
-rw-r--r-- | src/emu/machine/corvushd.c | 80 | ||||
-rw-r--r-- | src/emu/machine/corvushd.h | 12 |
2 files changed, 79 insertions, 13 deletions
diff --git a/src/emu/machine/corvushd.c b/src/emu/machine/corvushd.c index 7bdc4f51d94..c5204ab7d3a 100644 --- a/src/emu/machine/corvushd.c +++ b/src/emu/machine/corvushd.c @@ -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 = diff --git a/src/emu/machine/corvushd.h b/src/emu/machine/corvushd.h index 0699eb434ae..f1c39a1ab9f 100644 --- a/src/emu/machine/corvushd.h +++ b/src/emu/machine/corvushd.h @@ -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); |