summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/emu/machine/corvushd.c80
-rw-r--r--src/emu/machine/corvushd.h12
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);