Search
lxdream.org :: lxdream/src/gdrom/ide.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 493:c8183f888b14
prev430:467519b050f4
next561:533f6b478071
author nkeynes
date Tue Nov 06 08:35:33 2007 +0000 (12 years ago)
permissions -rw-r--r--
last change Implement mode select command
file annotate diff log raw
1.1 --- a/src/gdrom/ide.c Mon Oct 08 12:09:06 2007 +0000
1.2 +++ b/src/gdrom/ide.c Tue Nov 06 08:35:33 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: ide.c,v 1.26 2007-10-08 12:06:01 nkeynes Exp $
1.6 + * $Id: ide.c,v 1.27 2007-11-06 08:35:33 nkeynes Exp $
1.7 *
1.8 * IDE interface implementation
1.9 *
1.10 @@ -56,12 +56,12 @@
1.11 #define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x16
1.12 #define READ_BUFFER() *((uint16_t *)(data_buffer + idereg.data_offset))
1.13
1.14 -/* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */
1.15 -unsigned char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
1.16 - 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
1.17 - 0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
1.18 - 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
1.19 -
1.20 +/* 10 bytes followed by "SE REV 6.42990316" */
1.21 +unsigned char default_gdrom_mode[GDROM_MODE_LENGTH] =
1.22 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00, 0x00, 0x08,
1.23 + 0x53, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1.24 + 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e, 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
1.25 +
1.26 unsigned char gdrom_71[] = { 0x3E, 0x0F, 0x90, 0xBE, 0x1D, 0xD9, 0x89, 0x04, 0x28, 0x3A, 0x8E, 0x26, 0x5C, 0x95, 0x10, 0x5A,
1.27 0x0A, 0x99, 0xEE, 0xFB, 0x69, 0xCE, 0xD9, 0x63, 0x00, 0xF5, 0x0A, 0xBC, 0x2C, 0x0D, 0xF8, 0xE2,
1.28 0x05, 0x02, 0x00, 0x7C, 0x03, 0x00, 0x3D, 0x08, 0xD8, 0x8D, 0x08, 0x7A, 0x6D, 0x00, 0x35, 0x06,
1.29 @@ -148,11 +148,12 @@
1.30 idereg.device = 0x00;
1.31 idereg.state = IDE_STATE_IDLE;
1.32 memset( idereg.gdrom_sense, '\0', 10 );
1.33 + memcpy( idereg.gdrom_mode, default_gdrom_mode, GDROM_MODE_LENGTH );
1.34 idereg.data_offset = -1;
1.35 idereg.data_length = -1;
1.36 idereg.last_read_track = 1;
1.37 - idereg.read_lba = 150;
1.38 - idereg.read_mode = 0x28;
1.39 + idereg.current_lba = 150;
1.40 + idereg.current_mode = 0x28;
1.41 idereg.sectors_left = 0;
1.42 idereg.was_reset = TRUE;
1.43 }
1.44 @@ -209,7 +210,7 @@
1.45 }
1.46
1.47 /**
1.48 - * Begin PIO read from the device. The data is assumed to already be
1.49 + * Begin PIO/DMA read from the device. The data is assumed to already be
1.50 * in the buffer at this point.
1.51 */
1.52 static void ide_start_read( int length, gboolean dma )
1.53 @@ -229,6 +230,23 @@
1.54 }
1.55 }
1.56
1.57 +static void ide_start_write( int length, gboolean dma )
1.58 +{
1.59 + idereg.count = 0;
1.60 + idereg.data_length = length;
1.61 + idereg.data_offset = 0;
1.62 + if( dma ) {
1.63 + idereg.state = IDE_STATE_DMA_WRITE;
1.64 + idereg.status = 0xD0;
1.65 + } else {
1.66 + idereg.state = IDE_STATE_PIO_WRITE;
1.67 + idereg.status = 0x58;
1.68 + idereg.lba1 = length & 0xFF;
1.69 + idereg.lba2 = length >> 8;
1.70 + ide_raise_interrupt( );
1.71 + }
1.72 +}
1.73 +
1.74 static void ide_start_packet_read( int length, int sector_count )
1.75 {
1.76 idereg.sectors_left = sector_count;
1.77 @@ -236,6 +254,13 @@
1.78 ide_start_read( length, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
1.79 }
1.80
1.81 +static void ide_start_packet_write( int length, int sector_count )
1.82 +{
1.83 + idereg.sectors_left = sector_count;
1.84 + ide_set_packet_result( PKT_ERR_OK );
1.85 + ide_start_write( length, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
1.86 +}
1.87 +
1.88 static void ide_raise_interrupt( void )
1.89 {
1.90 if( idereg.intrq_pending == 0 ) {
1.91 @@ -341,11 +366,14 @@
1.92 }
1.93 } else if( idereg.state == IDE_STATE_PIO_WRITE ) {
1.94 WRITE_BUFFER(val);
1.95 + idereg.data_offset +=2;
1.96 if( idereg.data_offset >= idereg.data_length ) {
1.97 - idereg.state = IDE_STATE_BUSY;
1.98 + idereg.state = IDE_STATE_IDLE;
1.99 + idereg.status &= ~IDE_STATUS_DRQ;
1.100 idereg.data_offset = -1;
1.101 - idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
1.102 - /* ??? - no data writes yet anyway */
1.103 + idereg.count = 3; /* complete */
1.104 + ide_raise_interrupt();
1.105 + ide_write_buffer( data_buffer, idereg.data_length );
1.106 }
1.107 }
1.108 }
1.109 @@ -432,16 +460,16 @@
1.110 uint32_t sector_size;
1.111 REQUIRE_DISC();
1.112 gdrom_error_t status =
1.113 - gdrom_disc->read_sector( gdrom_disc, idereg.read_lba, idereg.read_mode,
1.114 + gdrom_disc->read_sector( gdrom_disc, idereg.current_lba, idereg.current_mode,
1.115 data_buffer, &sector_size );
1.116 if( status != PKT_ERR_OK ) {
1.117 ide_set_packet_result( status );
1.118 - idereg.gdrom_sense[5] = (idereg.read_lba >> 16) & 0xFF;
1.119 - idereg.gdrom_sense[6] = (idereg.read_lba >> 8) & 0xFF;
1.120 - idereg.gdrom_sense[7] = idereg.read_lba & 0xFF;
1.121 + idereg.gdrom_sense[5] = (idereg.current_lba >> 16) & 0xFF;
1.122 + idereg.gdrom_sense[6] = (idereg.current_lba >> 8) & 0xFF;
1.123 + idereg.gdrom_sense[7] = idereg.current_lba & 0xFF;
1.124 WARN( " => Read CD returned sense key %02X, %02X", status & 0xFF, status >> 8 );
1.125 } else {
1.126 - idereg.read_lba++;
1.127 + idereg.current_lba++;
1.128 idereg.sectors_left--;
1.129 ide_start_read( sector_size, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
1.130 }
1.131 @@ -475,18 +503,30 @@
1.132 ide_raise_interrupt();
1.133 idereg.status = 0x50;
1.134 break;
1.135 - case PKT_CMD_IDENTIFY:
1.136 + case PKT_CMD_MODE_SENSE:
1.137 lba = cmd[2];
1.138 - if( lba >= sizeof(gdrom_ident) ) {
1.139 + if( lba >= GDROM_MODE_LENGTH ) {
1.140 ide_set_error(PKT_ERR_BADFIELD);
1.141 } else {
1.142 length = cmd[4];
1.143 - if( lba+length > sizeof(gdrom_ident) )
1.144 - length = sizeof(gdrom_ident) - lba;
1.145 - memcpy( data_buffer, gdrom_ident + lba, length );
1.146 + if( lba+length > GDROM_MODE_LENGTH )
1.147 + length = GDROM_MODE_LENGTH - lba;
1.148 + memcpy( data_buffer, idereg.gdrom_mode + lba, length );
1.149 ide_start_packet_read( length, 0 );
1.150 }
1.151 break;
1.152 + case PKT_CMD_MODE_SELECT:
1.153 + lba = cmd[2];
1.154 + if( lba >= GDROM_MODE_LENGTH ) {
1.155 + ide_set_error(PKT_ERR_BADFIELD);
1.156 + } else {
1.157 + length = cmd[4];
1.158 + if( lba+length > GDROM_MODE_LENGTH )
1.159 + length = GDROM_MODE_LENGTH - lba;
1.160 + idereg.current_lba = lba;
1.161 + ide_start_packet_write( length, 0 );
1.162 + }
1.163 + break;
1.164 case PKT_CMD_SENSE:
1.165 length = cmd[4];
1.166 if( length > 10 )
1.167 @@ -527,9 +567,9 @@
1.168 break;
1.169 case PKT_CMD_READ_SECTOR:
1.170 REQUIRE_DISC();
1.171 - idereg.read_lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
1.172 + idereg.current_lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
1.173 idereg.sectors_left = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */
1.174 - idereg.read_mode = cmd[1];
1.175 + idereg.current_mode = cmd[1];
1.176 ide_read_next_sector();
1.177 break;
1.178 case PKT_CMD_SPIN_UP:
1.179 @@ -553,7 +593,7 @@
1.180 if( length > 14 ) {
1.181 length = 14;
1.182 }
1.183 - gdrom_disc->read_position( gdrom_disc, idereg.read_lba, data_buffer );
1.184 + gdrom_disc->read_position( gdrom_disc, idereg.current_lba, data_buffer );
1.185 data_buffer[0] = 0x00;
1.186 data_buffer[1] = 0x15; /* audio status ? */
1.187 data_buffer[2] = 0x00;
1.188 @@ -575,4 +615,21 @@
1.189 ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
1.190 return;
1.191 }
1.192 + idereg.last_packet_command = cmd[0];
1.193 }
1.194 +
1.195 +void ide_write_buffer( unsigned char *data, uint32_t length )
1.196 +{
1.197 + switch( idereg.last_packet_command ) {
1.198 + case PKT_CMD_MODE_SELECT:
1.199 + if( idereg.current_lba < 10 ) {
1.200 + if( idereg.current_lba + length > 10 ) {
1.201 + length = 10 - idereg.current_lba;
1.202 + }
1.203 + memcpy( idereg.gdrom_mode + idereg.current_lba, data, length );
1.204 + }
1.205 + break;
1.206 + default:
1.207 + WARN( "Don't know what to do with received data buffer for command %02X", idereg.last_packet_command );
1.208 + }
1.209 +}
.