diff options
Diffstat (limited to 'src/devices/machine/wd33c9x.cpp')
-rw-r--r-- | src/devices/machine/wd33c9x.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/devices/machine/wd33c9x.cpp b/src/devices/machine/wd33c9x.cpp index a8aec27d45d..9e20893b9d3 100644 --- a/src/devices/machine/wd33c9x.cpp +++ b/src/devices/machine/wd33c9x.cpp @@ -807,6 +807,38 @@ void wd33c9x_base_device::start_command() step(false); break; + case COMMAND_CC_TRANSLATE_ADDRESS: + LOGMASKED(LOG_COMMANDS, "Translate Address Command\n"); + { + uint8_t total_sectors = m_regs[CDB_1]; + uint8_t total_heads = m_regs[CDB_2]; + uint16_t total_cylinders = m_regs[CDB_3] << 8 | m_regs[CDB_4]; + uint32_t lba = (m_regs[CDB_5] << 24) | (m_regs[CDB_6] << 16) | (m_regs[CDB_7] << 8) | (m_regs[CDB_8] << 0); + + LOGMASKED(LOG_COMMANDS, "total_sectors=%02x, total_heads=%02x, total_cylinders=%04x, lba=%08x\n", total_sectors, total_heads, total_cylinders, lba); + + uint16_t cylinder = lba / (total_sectors * total_heads); + uint8_t head = (lba - (cylinder * total_sectors * total_heads)) / total_sectors; + uint8_t sector = (lba - (cylinder * total_sectors * total_heads)) % total_sectors; + + LOGMASKED(LOG_COMMANDS, "-> cylinder=%04x, head=%02x, sector=%02x\n", cylinder, head, sector); + + m_regs[CDB_9] = sector; + m_regs[CDB_10] = head; + m_regs[CDB_11] = cylinder >> 8; + m_regs[CDB_12] = cylinder >> 0; + + m_regs[AUXILIARY_STATUS] &= ~(AUXILIARY_STATUS_CIP | AUXILIARY_STATUS_BSY); + + if (cylinder >= total_cylinders) + irq_fifo_push(SCSI_STATUS_LOGICAL_ADDRESS_TOO_LARGE); + else + irq_fifo_push(SCSI_STATUS_TRANSLATE_SUCCESS); + + update_irq(); + } + break; + case COMMAND_CC_TRANSFER_INFO: LOGMASKED(LOG_COMMANDS, "Transfer Info Command\n"); if (m_mode != MODE_I) { |