Search
lxdream.org :: lxdream :: r493:c8183f888b14
lxdream 0.9.1
released Jun 29
Download Now
changeset493:c8183f888b14
parent492:84e33e4dda1c
child494:67c133a17400
authornkeynes
dateTue Nov 06 08:35:33 2007 +0000 (12 years ago)
Implement mode select command
src/dreamcast.h
src/gdrom/ide.c
src/gdrom/ide.h
src/gdrom/packet.h
1.1 --- a/src/dreamcast.h Tue Nov 06 08:35:16 2007 +0000
1.2 +++ b/src/dreamcast.h Tue Nov 06 08:35:33 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: dreamcast.h,v 1.21 2007-10-31 09:10:23 nkeynes Exp $
1.6 + * $Id: dreamcast.h,v 1.22 2007-11-06 08:35:33 nkeynes Exp $
1.7 *
1.8 * Public interface for dreamcast.c -
1.9 * Central switchboard for the system. This pulls all the individual modules
1.10 @@ -47,7 +47,7 @@
1.11 gboolean dreamcast_is_running(void);
1.12
1.13 #define DREAMCAST_SAVE_MAGIC "%!-lxDream!Save\0"
1.14 -#define DREAMCAST_SAVE_VERSION 0x00010001
1.15 +#define DREAMCAST_SAVE_VERSION 0x00010002
1.16
1.17 int dreamcast_save_state( const gchar *filename );
1.18 int dreamcast_load_state( const gchar *filename );
2.1 --- a/src/gdrom/ide.c Tue Nov 06 08:35:16 2007 +0000
2.2 +++ b/src/gdrom/ide.c Tue Nov 06 08:35:33 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: ide.c,v 1.26 2007-10-08 12:06:01 nkeynes Exp $
2.6 + * $Id: ide.c,v 1.27 2007-11-06 08:35:33 nkeynes Exp $
2.7 *
2.8 * IDE interface implementation
2.9 *
2.10 @@ -56,12 +56,12 @@
2.11 #define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x16
2.12 #define READ_BUFFER() *((uint16_t *)(data_buffer + idereg.data_offset))
2.13
2.14 -/* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */
2.15 -unsigned char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
2.16 - 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
2.17 - 0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
2.18 - 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
2.19 -
2.20 +/* 10 bytes followed by "SE REV 6.42990316" */
2.21 +unsigned char default_gdrom_mode[GDROM_MODE_LENGTH] =
2.22 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00, 0x00, 0x08,
2.23 + 0x53, 0x45, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2.24 + 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e, 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
2.25 +
2.26 unsigned char gdrom_71[] = { 0x3E, 0x0F, 0x90, 0xBE, 0x1D, 0xD9, 0x89, 0x04, 0x28, 0x3A, 0x8E, 0x26, 0x5C, 0x95, 0x10, 0x5A,
2.27 0x0A, 0x99, 0xEE, 0xFB, 0x69, 0xCE, 0xD9, 0x63, 0x00, 0xF5, 0x0A, 0xBC, 0x2C, 0x0D, 0xF8, 0xE2,
2.28 0x05, 0x02, 0x00, 0x7C, 0x03, 0x00, 0x3D, 0x08, 0xD8, 0x8D, 0x08, 0x7A, 0x6D, 0x00, 0x35, 0x06,
2.29 @@ -148,11 +148,12 @@
2.30 idereg.device = 0x00;
2.31 idereg.state = IDE_STATE_IDLE;
2.32 memset( idereg.gdrom_sense, '\0', 10 );
2.33 + memcpy( idereg.gdrom_mode, default_gdrom_mode, GDROM_MODE_LENGTH );
2.34 idereg.data_offset = -1;
2.35 idereg.data_length = -1;
2.36 idereg.last_read_track = 1;
2.37 - idereg.read_lba = 150;
2.38 - idereg.read_mode = 0x28;
2.39 + idereg.current_lba = 150;
2.40 + idereg.current_mode = 0x28;
2.41 idereg.sectors_left = 0;
2.42 idereg.was_reset = TRUE;
2.43 }
2.44 @@ -209,7 +210,7 @@
2.45 }
2.46
2.47 /**
2.48 - * Begin PIO read from the device. The data is assumed to already be
2.49 + * Begin PIO/DMA read from the device. The data is assumed to already be
2.50 * in the buffer at this point.
2.51 */
2.52 static void ide_start_read( int length, gboolean dma )
2.53 @@ -229,6 +230,23 @@
2.54 }
2.55 }
2.56
2.57 +static void ide_start_write( int length, gboolean dma )
2.58 +{
2.59 + idereg.count = 0;
2.60 + idereg.data_length = length;
2.61 + idereg.data_offset = 0;
2.62 + if( dma ) {
2.63 + idereg.state = IDE_STATE_DMA_WRITE;
2.64 + idereg.status = 0xD0;
2.65 + } else {
2.66 + idereg.state = IDE_STATE_PIO_WRITE;
2.67 + idereg.status = 0x58;
2.68 + idereg.lba1 = length & 0xFF;
2.69 + idereg.lba2 = length >> 8;
2.70 + ide_raise_interrupt( );
2.71 + }
2.72 +}
2.73 +
2.74 static void ide_start_packet_read( int length, int sector_count )
2.75 {
2.76 idereg.sectors_left = sector_count;
2.77 @@ -236,6 +254,13 @@
2.78 ide_start_read( length, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
2.79 }
2.80
2.81 +static void ide_start_packet_write( int length, int sector_count )
2.82 +{
2.83 + idereg.sectors_left = sector_count;
2.84 + ide_set_packet_result( PKT_ERR_OK );
2.85 + ide_start_write( length, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
2.86 +}
2.87 +
2.88 static void ide_raise_interrupt( void )
2.89 {
2.90 if( idereg.intrq_pending == 0 ) {
2.91 @@ -341,11 +366,14 @@
2.92 }
2.93 } else if( idereg.state == IDE_STATE_PIO_WRITE ) {
2.94 WRITE_BUFFER(val);
2.95 + idereg.data_offset +=2;
2.96 if( idereg.data_offset >= idereg.data_length ) {
2.97 - idereg.state = IDE_STATE_BUSY;
2.98 + idereg.state = IDE_STATE_IDLE;
2.99 + idereg.status &= ~IDE_STATUS_DRQ;
2.100 idereg.data_offset = -1;
2.101 - idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
2.102 - /* ??? - no data writes yet anyway */
2.103 + idereg.count = 3; /* complete */
2.104 + ide_raise_interrupt();
2.105 + ide_write_buffer( data_buffer, idereg.data_length );
2.106 }
2.107 }
2.108 }
2.109 @@ -432,16 +460,16 @@
2.110 uint32_t sector_size;
2.111 REQUIRE_DISC();
2.112 gdrom_error_t status =
2.113 - gdrom_disc->read_sector( gdrom_disc, idereg.read_lba, idereg.read_mode,
2.114 + gdrom_disc->read_sector( gdrom_disc, idereg.current_lba, idereg.current_mode,
2.115 data_buffer, &sector_size );
2.116 if( status != PKT_ERR_OK ) {
2.117 ide_set_packet_result( status );
2.118 - idereg.gdrom_sense[5] = (idereg.read_lba >> 16) & 0xFF;
2.119 - idereg.gdrom_sense[6] = (idereg.read_lba >> 8) & 0xFF;
2.120 - idereg.gdrom_sense[7] = idereg.read_lba & 0xFF;
2.121 + idereg.gdrom_sense[5] = (idereg.current_lba >> 16) & 0xFF;
2.122 + idereg.gdrom_sense[6] = (idereg.current_lba >> 8) & 0xFF;
2.123 + idereg.gdrom_sense[7] = idereg.current_lba & 0xFF;
2.124 WARN( " => Read CD returned sense key %02X, %02X", status & 0xFF, status >> 8 );
2.125 } else {
2.126 - idereg.read_lba++;
2.127 + idereg.current_lba++;
2.128 idereg.sectors_left--;
2.129 ide_start_read( sector_size, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );
2.130 }
2.131 @@ -475,18 +503,30 @@
2.132 ide_raise_interrupt();
2.133 idereg.status = 0x50;
2.134 break;
2.135 - case PKT_CMD_IDENTIFY:
2.136 + case PKT_CMD_MODE_SENSE:
2.137 lba = cmd[2];
2.138 - if( lba >= sizeof(gdrom_ident) ) {
2.139 + if( lba >= GDROM_MODE_LENGTH ) {
2.140 ide_set_error(PKT_ERR_BADFIELD);
2.141 } else {
2.142 length = cmd[4];
2.143 - if( lba+length > sizeof(gdrom_ident) )
2.144 - length = sizeof(gdrom_ident) - lba;
2.145 - memcpy( data_buffer, gdrom_ident + lba, length );
2.146 + if( lba+length > GDROM_MODE_LENGTH )
2.147 + length = GDROM_MODE_LENGTH - lba;
2.148 + memcpy( data_buffer, idereg.gdrom_mode + lba, length );
2.149 ide_start_packet_read( length, 0 );
2.150 }
2.151 break;
2.152 + case PKT_CMD_MODE_SELECT:
2.153 + lba = cmd[2];
2.154 + if( lba >= GDROM_MODE_LENGTH ) {
2.155 + ide_set_error(PKT_ERR_BADFIELD);
2.156 + } else {
2.157 + length = cmd[4];
2.158 + if( lba+length > GDROM_MODE_LENGTH )
2.159 + length = GDROM_MODE_LENGTH - lba;
2.160 + idereg.current_lba = lba;
2.161 + ide_start_packet_write( length, 0 );
2.162 + }
2.163 + break;
2.164 case PKT_CMD_SENSE:
2.165 length = cmd[4];
2.166 if( length > 10 )
2.167 @@ -527,9 +567,9 @@
2.168 break;
2.169 case PKT_CMD_READ_SECTOR:
2.170 REQUIRE_DISC();
2.171 - idereg.read_lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
2.172 + idereg.current_lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
2.173 idereg.sectors_left = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */
2.174 - idereg.read_mode = cmd[1];
2.175 + idereg.current_mode = cmd[1];
2.176 ide_read_next_sector();
2.177 break;
2.178 case PKT_CMD_SPIN_UP:
2.179 @@ -553,7 +593,7 @@
2.180 if( length > 14 ) {
2.181 length = 14;
2.182 }
2.183 - gdrom_disc->read_position( gdrom_disc, idereg.read_lba, data_buffer );
2.184 + gdrom_disc->read_position( gdrom_disc, idereg.current_lba, data_buffer );
2.185 data_buffer[0] = 0x00;
2.186 data_buffer[1] = 0x15; /* audio status ? */
2.187 data_buffer[2] = 0x00;
2.188 @@ -575,4 +615,21 @@
2.189 ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
2.190 return;
2.191 }
2.192 + idereg.last_packet_command = cmd[0];
2.193 }
2.194 +
2.195 +void ide_write_buffer( unsigned char *data, uint32_t length )
2.196 +{
2.197 + switch( idereg.last_packet_command ) {
2.198 + case PKT_CMD_MODE_SELECT:
2.199 + if( idereg.current_lba < 10 ) {
2.200 + if( idereg.current_lba + length > 10 ) {
2.201 + length = 10 - idereg.current_lba;
2.202 + }
2.203 + memcpy( idereg.gdrom_mode + idereg.current_lba, data, length );
2.204 + }
2.205 + break;
2.206 + default:
2.207 + WARN( "Don't know what to do with received data buffer for command %02X", idereg.last_packet_command );
2.208 + }
2.209 +}
3.1 --- a/src/gdrom/ide.h Tue Nov 06 08:35:16 2007 +0000
3.2 +++ b/src/gdrom/ide.h Tue Nov 06 08:35:33 2007 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: ide.h,v 1.13 2007-01-31 10:58:42 nkeynes Exp $
3.6 + * $Id: ide.h,v 1.14 2007-11-06 08:35:33 nkeynes Exp $
3.7 *
3.8 * This file defines the interface and structures of the dreamcast's IDE
3.9 * port. Note that the register definitions are in asic.h, as the registers
3.10 @@ -25,6 +25,9 @@
3.11
3.12 #include "dream.h"
3.13
3.14 +#define GDROM_SENSE_LENGTH 10
3.15 +#define GDROM_MODE_LENGTH 32
3.16 +
3.17 struct ide_registers {
3.18 /* IDE interface registers */
3.19 uint8_t status; /* A05F709C + A05F7018 Read-only */
3.20 @@ -43,22 +46,23 @@
3.21 uint8_t intrq_pending; /* Flag to indicate if the INTRQ line is active */
3.22 gboolean interface_enabled;
3.23 gboolean was_reset; /* Flag indicating that the device has just been reset */
3.24 - int state;
3.25 + uint32_t state;
3.26 + uint32_t last_packet_command; /* Identifies the command executing during a r/w cycle */
3.27
3.28 /* Sense response for the last executed packet command */
3.29 - unsigned char gdrom_sense[10];
3.30 -
3.31 + unsigned char gdrom_sense[GDROM_SENSE_LENGTH];
3.32 + unsigned char gdrom_mode[GDROM_MODE_LENGTH];
3.33
3.34 /* offset in the buffer of the next word to read/write, or -1
3.35 * if inactive.
3.36 */
3.37 - int data_offset;
3.38 - int data_length;
3.39 + int32_t data_offset;
3.40 + int32_t data_length;
3.41
3.42 /* Status reporting information */
3.43 uint8_t last_read_track;
3.44 - uint32_t read_lba;
3.45 - uint32_t read_mode;
3.46 + uint32_t current_lba;
3.47 + uint32_t current_mode;
3.48 uint32_t sectors_left; /* sectors left after current read */
3.49 };
3.50
3.51 @@ -116,7 +120,7 @@
3.52 uint32_t ide_read_data_dma( uint32_t addr, uint32_t length );
3.53 uint8_t ide_read_status(void);
3.54 uint8_t ide_get_drive_status(void);
3.55 -void ide_write_buffer( unsigned char *data, int length );
3.56 +void ide_write_buffer( unsigned char *data, uint32_t length );
3.57
3.58 void ide_write_command( uint8_t command );
3.59 void ide_write_control( uint8_t value );
4.1 --- a/src/gdrom/packet.h Tue Nov 06 08:35:16 2007 +0000
4.2 +++ b/src/gdrom/packet.h Tue Nov 06 08:35:33 2007 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: packet.h,v 1.7 2007-01-31 10:58:42 nkeynes Exp $
4.6 + * $Id: packet.h,v 1.8 2007-11-06 08:35:33 nkeynes Exp $
4.7 *
4.8 * This file defines the command codes and any other flags used by the
4.9 * GD-Rom ATAPI packet commands.
4.10 @@ -47,7 +47,8 @@
4.11 */
4.12
4.13 #define PKT_CMD_TEST_READY 0x00
4.14 -#define PKT_CMD_IDENTIFY 0x11
4.15 +#define PKT_CMD_MODE_SENSE 0x11
4.16 +#define PKT_CMD_MODE_SELECT 0x12
4.17 #define PKT_CMD_SENSE 0x13
4.18 #define PKT_CMD_READ_TOC 0x14
4.19 #define PKT_CMD_SESSION_INFO 0x15
.