summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/t10sbc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/t10sbc.cpp')
-rw-r--r--src/devices/machine/t10sbc.cpp181
1 files changed, 153 insertions, 28 deletions
diff --git a/src/devices/machine/t10sbc.cpp b/src/devices/machine/t10sbc.cpp
index 036917bbbbe..e0a08688a91 100644
--- a/src/devices/machine/t10sbc.cpp
+++ b/src/devices/machine/t10sbc.cpp
@@ -163,22 +163,119 @@ void t10sbc::ReadData( uint8_t *data, int dataLength )
break;
case T10SPC_CMD_MODE_SENSE_6:
- // special Apple ID page. this is a vendor-specific page,
- // so unless collisions occur there should be no need
- // to change it.
- if ((command[2] & 0x3f) == 0x30)
+ {
+ const uint8_t page = command[2] & 0x3f;
+ const uint8_t subpage = command[3];
+
+ switch (page)
{
- memset(data, 0, 40);
- data[0] = 0x14;
- strcpy((char *)&data[14], "APPLE COMPUTER, INC.");
+ case 0x03:
+ {
+ // Format Parameters
+ if (subpage != 0)
+ {
+ m_device->logerror("T10SBC: Unsupported MODE SENSE subpage for Format Parameters page: %02x\n", subpage);
+ break;
+ }
+
+ const size_t fullSize = sizeof(format_page_t) + 12;
+ if (dataLength < fullSize)
+ {
+ m_device->logerror("T10SBC: Insufficient MODE SENSE buffer room for Format Parameters page: Need %d, given %d\n", fullSize, dataLength);
+ break;
+ }
+
+ m_device->logerror("T10SBC: MODE SENSE (6), Format Parameters page\n");
+ memset(data, 0, (uint8_t)fullSize);
+ data[0] = fullSize;
+ data[3] = 8;
+
+ ReadCapacity(&data[4]);
+
+ format_page_t format;
+ GetFormatPage(&format);
+ memcpy(&data[12], &format, sizeof(format_page_t));
+ break;
+ }
+ case 0x04:
+ {
+ // Rigid Drive Geometry Parameters
+ if (subpage != 0)
+ {
+ m_device->logerror("T10SBC: Unsupported MODE SENSE subpage for Geometry Parameters page: %02x\n", subpage);
+ break;
+ }
+
+ const size_t fullSize = sizeof(geometry_page_t) + 12;
+ if (dataLength < fullSize)
+ {
+ m_device->logerror("T10SBC: Insufficient MODE SENSE buffer room for Geometry Parameters page: Need %d, given %d\n", fullSize, dataLength);
+ break;
+ }
+
+ m_device->logerror("T10SBC: MODE SENSE (6), Geometry Parameters page\n");
+ memset(data, 0, fullSize);
+ data[0] = (uint8_t)fullSize;
+ data[3] = 8;
+
+ ReadCapacity(&data[4]);
+
+ geometry_page_t geometry;
+ GetGeometryPage(&geometry);
+ memcpy(&data[12], &geometry, sizeof(geometry_page_t));
+ break;
+ }
+ case 0x30:
+ // special Apple ID page. this is a vendor-specific page,
+ // so unless collisions occur there should be no need
+ // to change it.
+ memset(data, 0, 40);
+ data[0] = 0x14;
+ strcpy((char *)&data[14], "APPLE COMPUTER, INC.");
+ break;
+ case 0x3f:
+ if (subpage == 0)
+ {
+ const size_t fullSize = sizeof(format_page_t) + sizeof(geometry_page_t) + 12;
+ if (dataLength < fullSize)
+ {
+ m_device->logerror("T10SBC: Insufficient MODE SENSE buffer room for Return All Pages: Need %d, given %d\n", fullSize, dataLength);
+ break;
+ }
+
+ m_device->logerror("T10SBC: MODE SENSE (6), Return All Pages\n");
+ memset(data, 0, (uint8_t)fullSize);
+ data[0] = (uint8_t)fullSize;
+ data[3] = (uint8_t)8;
+
+ ReadCapacity(&data[4]);
+
+ format_page_t format;
+ GetFormatPage(&format);
+ memcpy(&data[12], &format, sizeof(format_page_t));
+
+ geometry_page_t geometry;
+ GetGeometryPage(&geometry);
+ memcpy(&data[12 + sizeof(format_page_t)], &geometry, sizeof(geometry_page_t));
+ }
+ else
+ {
+ m_device->logerror("T10SBC: Unsupported MODE SENSE subpage for Return All Pages: %02x\n", subpage);
+ }
+ break;
+ default:
+ m_device->logerror("T10SBC: Unknown MODE SENSE page: %02x\n", page);
+ break;
}
break;
+ }
case T10SBC_CMD_READ_6:
case T10SBC_CMD_READ_10:
case T10SBC_CMD_READ_12:
if ((m_disk) && (m_blocks))
{
+ m_device->logerror("T10SBC: Reading %d bytes from HD\n", dataLength);
while (dataLength > 0)
{
if (!hard_disk_read(m_disk, m_lba, data))
@@ -194,27 +291,8 @@ void t10sbc::ReadData( uint8_t *data, int dataLength )
break;
case T10SBC_CMD_READ_CAPACITY: // READ CAPACITY
- {
- hard_disk_info *info;
- uint32_t temp;
-
- info = hard_disk_get_info(m_disk);
-
- m_device->logerror("T10SBC: READ CAPACITY\n");
-
- // get # of sectors
- temp = info->cylinders * info->heads * info->sectors;
- temp--;
-
- data[0] = (temp>>24) & 0xff;
- data[1] = (temp>>16) & 0xff;
- data[2] = (temp>>8) & 0xff;
- data[3] = (temp & 0xff);
- data[4] = (info->sectorbytes>>24)&0xff;
- data[5] = (info->sectorbytes>>16)&0xff;
- data[6] = (info->sectorbytes>>8)&0xff;
- data[7] = (info->sectorbytes & 0xff);
- }
+ m_device->logerror("T10SBC: READ CAPACITY\n");
+ ReadCapacity(&data[0]);
break;
default:
@@ -239,6 +317,7 @@ void t10sbc::WriteData( uint8_t *data, int dataLength )
case T10SBC_CMD_WRITE_10:
if ((m_disk) && (m_blocks))
{
+ m_device->logerror("T10SBC: Writing %d bytes to HD\n", dataLength);
while (dataLength > 0)
{
if (!hard_disk_write(m_disk, m_lba, data))
@@ -268,3 +347,49 @@ void t10sbc::SetDevice( void *_disk )
{
m_disk = (hard_disk_file *)_disk;
}
+
+void t10sbc::GetFormatPage( format_page_t *page )
+{
+ hard_disk_info *info = hard_disk_get_info(m_disk);
+
+ memset(page, 0, sizeof(format_page_t));
+ page->m_page_code = 0x03;
+ page->m_page_length = 0x16;
+ page->m_sectors_per_track_msb = (uint8_t)(info->sectors >> 8);
+ page->m_sectors_per_track_lsb = (uint8_t)info->sectors;
+ page->m_bytes_per_sector_msb = (uint8_t)(info->sectorbytes >> 8);
+ page->m_bytes_per_sector_lsb = (uint8_t)info->sectorbytes;
+ page->m_format = 0x80; // SSEC, Soft-Sectored
+}
+
+void t10sbc::GetGeometryPage( geometry_page_t *page )
+{
+ hard_disk_info *info = hard_disk_get_info(m_disk);
+
+ memset(page, 0, sizeof(geometry_page_t));
+ page->m_page_code = 0x04;
+ page->m_page_length = 0x16;
+ page->m_num_cylinders_msb = (uint8_t)(info->cylinders >> 16);
+ page->m_num_cylinders_2nd = (uint8_t)(info->cylinders >> 8);
+ page->m_num_cylinders_lsb = (uint8_t)info->cylinders;
+ page->m_num_heads = (uint8_t)info->heads;
+ page->m_rot_rate_msb = (uint8_t)(3600 >> 8);
+ page->m_rot_rate_lsb = (uint8_t)3600;
+}
+
+void t10sbc::ReadCapacity( uint8_t *data )
+{
+ hard_disk_info *info = hard_disk_get_info(m_disk);
+
+ // get # of sectors
+ uint32_t temp = info->cylinders * info->heads * info->sectors - 1;
+
+ data[0] = (temp>>24) & 0xff;
+ data[1] = (temp>>16) & 0xff;
+ data[2] = (temp>>8) & 0xff;
+ data[3] = (temp & 0xff);
+ data[4] = (info->sectorbytes>>24)&0xff;
+ data[5] = (info->sectorbytes>>16)&0xff;
+ data[6] = (info->sectorbytes>>8)&0xff;
+ data[7] = (info->sectorbytes & 0xff);
+} \ No newline at end of file