Search
lxdream.org :: lxdream :: r152:d42a4c5cc709
lxdream 0.9.1
released Jun 29
Download Now
changeset152:d42a4c5cc709
parent151:3d3135644b8e
child153:3d4091e2b136
authornkeynes
dateTue May 23 13:11:45 2006 +0000 (14 years ago)
Clean up the buffer and i/o handling
Implement save/load state
src/gdrom/gdrom.c
src/gdrom/gdrom.h
src/gdrom/ide.c
src/gdrom/ide.h
1.1 --- a/src/gdrom/gdrom.c Tue May 23 13:11:09 2006 +0000
1.2 +++ b/src/gdrom/gdrom.c Tue May 23 13:11:45 2006 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: gdrom.c,v 1.4 2006-05-20 06:24:49 nkeynes Exp $
1.6 + * $Id: gdrom.c,v 1.5 2006-05-23 13:11:45 nkeynes Exp $
1.7 *
1.8 * GD-Rom access functions.
1.9 *
1.10 @@ -24,7 +24,7 @@
1.11 #include "dream.h"
1.12
1.13 static void gdrom_image_destroy( gdrom_disc_t );
1.14 -static uint32_t gdrom_image_read_sectors( gdrom_disc_t, uint32_t, uint32_t, int, char *, uint32_t * );
1.15 +static gdrom_error_t gdrom_image_read_sectors( gdrom_disc_t, uint32_t, uint32_t, int, char *, uint32_t * );
1.16
1.17
1.18 gdrom_disc_t gdrom_disc = NULL;
1.19 @@ -59,28 +59,56 @@
1.20 free( disc );
1.21 }
1.22
1.23 -static uint32_t gdrom_image_read_sectors( gdrom_disc_t disc, uint32_t sector,
1.24 - uint32_t sector_count, int mode, char *buf,
1.25 - uint32_t *length )
1.26 +static gdrom_error_t gdrom_image_read_sectors( gdrom_disc_t disc, uint32_t sector,
1.27 + uint32_t sector_count, int mode, char *buf,
1.28 + uint32_t *length )
1.29 {
1.30 - int i, track = -1, track_offset, read_len;
1.31 + int i, file_offset, read_len;
1.32 + struct gdrom_track *track = NULL;
1.33
1.34 for( i=0; i<disc->track_count; i++ ) {
1.35 if( disc->track[i].lba <= sector &&
1.36 (sector + sector_count) <= (disc->track[i].lba + disc->track[i].sector_count) ) {
1.37 - track = i;
1.38 + track = &disc->track[i];
1.39 break;
1.40 }
1.41 }
1.42 - if( track == -1 )
1.43 + if( track == NULL )
1.44 return PKT_ERR_BADREAD;
1.45 - if( mode == GDROM_GD && disc->track[i].mode != GDROM_GD )
1.46 +
1.47 + file_offset = track->offset + track->sector_size * (sector - track->lba);
1.48 + read_len = track->sector_size * sector_count;
1.49 + fseek( disc->file, file_offset, SEEK_SET );
1.50 +
1.51 + switch( mode ) {
1.52 + case GDROM_GD:
1.53 + if( track->mode != GDROM_GD )
1.54 + return PKT_ERR_BADREADMODE;
1.55 + break;
1.56 + case GDROM_MODE1:
1.57 + switch( track->mode ) {
1.58 + case GDROM_MODE1:
1.59 + case GDROM_MODE2_XA1:
1.60 + fread( buf, track->sector_size, sector_count, disc->file );
1.61 + break;
1.62 + case GDROM_MODE2:
1.63 + read_len = sector_count * 2048;
1.64 + while( sector_count > 0 ) {
1.65 + fread( buf, 2048, 1, disc->file );
1.66 + file_offset += track->sector_size;
1.67 + buf += 2048;
1.68 + fseek( disc->file, file_offset, SEEK_SET );
1.69 + sector_count--;
1.70 + }
1.71 + break;
1.72 + default:
1.73 + return PKT_ERR_BADREADMODE;
1.74 + }
1.75 + break;
1.76 + default:
1.77 return PKT_ERR_BADREADMODE;
1.78 -
1.79 - track_offset = disc->track[track].sector_size * (sector - disc->track[track].lba);
1.80 - read_len = disc->track[track].sector_size * sector_count;
1.81 - fseek( disc->file, disc->track[track].offset + track_offset, SEEK_SET );
1.82 - fread( buf, disc->track[track].sector_size, sector_count, disc->file );
1.83 + }
1.84 +
1.85 *length = read_len;
1.86 return PKT_ERR_OK;
1.87 }
1.88 @@ -125,20 +153,36 @@
1.89 return PKT_ERR_OK;
1.90 }
1.91
1.92 -gdrom_error_t gdrom_get_info( char *buf )
1.93 +gdrom_error_t gdrom_get_info( char *buf, int session )
1.94 {
1.95 if( gdrom_disc == NULL )
1.96 return PKT_ERR_NODISC;
1.97 struct gdrom_track *last_track = &gdrom_disc->track[gdrom_disc->track_count-1];
1.98 unsigned int end_of_disc = last_track->lba + last_track->sector_count;
1.99 -
1.100 - buf[0] = 0x01; /* Unknown. First session? */
1.101 + int i;
1.102 + buf[0] = 0x01; /* Disc status? */
1.103 buf[1] = 0;
1.104 - buf[2] = last_track->session+1; /* last session */
1.105 - buf[3] = (end_of_disc >> 16) & 0xFF;
1.106 - buf[4] = (end_of_disc >> 8) & 0xFF;
1.107 - buf[5] = end_of_disc & 0xFF;
1.108 - return PKT_ERR_OK;
1.109 +
1.110 + if( session == 0 ) {
1.111 + buf[2] = last_track->session+1; /* last session */
1.112 + buf[3] = (end_of_disc >> 16) & 0xFF;
1.113 + buf[4] = (end_of_disc >> 8) & 0xFF;
1.114 + buf[5] = end_of_disc & 0xFF;
1.115 + return PKT_ERR_OK;
1.116 + } else {
1.117 + session--;
1.118 + for( i=0; i<gdrom_disc->track_count; i++ ) {
1.119 + if( gdrom_disc->track[i].session == session ) {
1.120 + buf[2] = i+1; /* first track of session */
1.121 + buf[3] = (gdrom_disc->track[i].lba >> 16) & 0xFF;
1.122 + buf[4] = (gdrom_disc->track[i].lba >> 8) & 0xFF;
1.123 + buf[5] = gdrom_disc->track[i].lba & 0xFF;
1.124 + return PKT_ERR_OK;
1.125 + }
1.126 + }
1.127 + return PKT_ERR_BADFIELD; /* No such session */
1.128 + }
1.129 +
1.130 }
1.131
1.132 void gdrom_mount_disc( gdrom_disc_t disc )
2.1 --- a/src/gdrom/gdrom.h Tue May 23 13:11:09 2006 +0000
2.2 +++ b/src/gdrom/gdrom.h Tue May 23 13:11:45 2006 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: gdrom.h,v 1.5 2006-05-20 06:24:49 nkeynes Exp $
2.6 + * $Id: gdrom.h,v 1.6 2006-05-23 13:11:45 nkeynes Exp $
2.7 *
2.8 * This file defines the structures and functions used by the GD-Rom
2.9 * disc driver. (ie, the modules that supply a CD image to be used by the
2.10 @@ -77,7 +77,7 @@
2.11 gchar mcn[14]; /* Media catalogue number */
2.12 const gchar *filename; /* Image filename */
2.13 FILE *file; /* Stream, for image files */
2.14 - uint32_t (*read_sectors)( struct gdrom_disc *disc,
2.15 + gdrom_error_t (*read_sectors)( struct gdrom_disc *disc,
2.16 uint32_t lba, uint32_t sector_count,
2.17 int mode, char *buf, uint32_t *length );
2.18 void (*close)( struct gdrom_disc *disc );
2.19 @@ -102,10 +102,10 @@
2.20 gdrom_error_t gdrom_get_toc( char *buf );
2.21
2.22 /**
2.23 - * Retrieve the short (6-byte) disc info, and write it into the buffer.
2.24 + * Retrieve the short (6-byte) session info, and write it into the buffer.
2.25 * @return 0 on success, error code on failure.
2.26 */
2.27 -gdrom_error_t gdrom_get_info( char *buf );
2.28 +gdrom_error_t gdrom_get_info( char *buf, int session );
2.29
2.30 /**
2.31 * Shortcut to open and mount an image file
3.1 --- a/src/gdrom/ide.c Tue May 23 13:11:09 2006 +0000
3.2 +++ b/src/gdrom/ide.c Tue May 23 13:11:45 2006 +0000
3.3 @@ -1,8 +1,12 @@
3.4 /**
3.5 - * $Id: ide.c,v 1.13 2006-05-20 06:24:49 nkeynes Exp $
3.6 + * $Id: ide.c,v 1.14 2006-05-23 13:11:45 nkeynes Exp $
3.7 *
3.8 * IDE interface implementation
3.9 *
3.10 + *
3.11 + * Note: All references to read/write are from the host's point of view.
3.12 + *
3.13 + * See: INF-8020
3.14 * Copyright (c) 2005 Nathan Keynes.
3.15 *
3.16 * This program is free software; you can redistribute it and/or modify
3.17 @@ -36,16 +40,18 @@
3.18 static int ide_load_state( FILE *f );
3.19 static void ide_raise_interrupt( void );
3.20 static void ide_clear_interrupt( void );
3.21 +static void ide_packet_command( unsigned char *data );
3.22
3.23 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
3.24 NULL, ide_save_state, ide_load_state };
3.25
3.26 struct ide_registers idereg;
3.27 -
3.28 -static unsigned char command_buffer[12];
3.29 unsigned char *data_buffer = NULL;
3.30 uint32_t data_buffer_len = 0;
3.31
3.32 +#define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x16
3.33 +#define READ_BUFFER() *((uint16_t *)(data_buffer + idereg.data_offset))
3.34 +
3.35 /* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */
3.36 unsigned char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
3.37 0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
3.38 @@ -73,38 +79,77 @@
3.39 idereg.status = 0x00;
3.40 idereg.device = 0x00;
3.41 idereg.disc = gdrom_is_mounted() ? (IDE_DISC_CDROM|IDE_DISC_READY) : IDE_DISC_NONE;
3.42 + idereg.state = IDE_STATE_IDLE;
3.43 + memset( idereg.gdrom_sense, '\0', 10 );
3.44 + idereg.data_offset = -1;
3.45 + idereg.data_length = -1;
3.46 }
3.47
3.48 static void ide_save_state( FILE *f )
3.49 {
3.50 -
3.51 -
3.52 + fwrite( &idereg, sizeof(idereg), 1, f );
3.53 + fwrite( &data_buffer_len, sizeof(data_buffer_len), 1, f );
3.54 + fwrite( data_buffer, data_buffer_len, 1, f );
3.55 }
3.56
3.57 static int ide_load_state( FILE *f )
3.58 {
3.59 + uint32_t length;
3.60 + fread( &idereg, sizeof(idereg), 1, f );
3.61 + fread( &length, sizeof(uint32_t), 1, f );
3.62 + if( length > data_buffer_len ) {
3.63 + if( data_buffer != NULL )
3.64 + free( data_buffer );
3.65 + data_buffer = malloc( length );
3.66 + assert( data_buffer != NULL );
3.67 + data_buffer_len = length;
3.68 + }
3.69 + fread( data_buffer, length, 1, f );
3.70 return 0;
3.71 }
3.72
3.73 -static void ide_set_write_buffer( unsigned char *buf, int len )
3.74 +/************************ State transitions *************************/
3.75 +
3.76 +/**
3.77 + * Begin command packet write to the device. This is always 12 bytes of PIO data
3.78 + */
3.79 +static void ide_start_command_packet_write( )
3.80 {
3.81 - idereg.status |= IDE_ST_DATA;
3.82 - idereg.data = buf;
3.83 - idereg.datalen = len;
3.84 - idereg.writeptr = (uint16_t *)buf;
3.85 - idereg.readptr = NULL;
3.86 + idereg.state = IDE_STATE_CMD_WRITE;
3.87 + idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
3.88 + idereg.error = idereg.feature & 0x03; /* Copy values of OVL/DMA */
3.89 + idereg.count = IDE_COUNT_CD;
3.90 + idereg.data_offset = 0;
3.91 + idereg.data_length = 12;
3.92 }
3.93
3.94 -static void ide_set_read_buffer( unsigned char *buf, int len, int blocksize )
3.95 +/**
3.96 + * Begin PIO read from the device. The data is assumed to already be
3.97 + * in the buffer at this point.
3.98 + */
3.99 +static void ide_start_read( int length, int blocksize, gboolean dma )
3.100 {
3.101 - idereg.status |= IDE_ST_DATA;
3.102 - idereg.data = buf;
3.103 - idereg.datalen = len;
3.104 - idereg.readptr = (uint16_t *)buf;
3.105 - idereg.writeptr = NULL;
3.106 - idereg.lba1 = len&0xFF;
3.107 - idereg.lba2 = len>>8;
3.108 - idereg.blocksize = idereg.blockleft = blocksize;
3.109 + idereg.status = IDE_STATUS_DRDY | IDE_STATUS_DRQ;
3.110 + idereg.count = IDE_COUNT_IO;
3.111 + idereg.data_length = length;
3.112 + idereg.data_offset = 0;
3.113 + if( dma ) {
3.114 + idereg.state = IDE_STATE_DMA_READ;
3.115 + idereg.status |= IDE_STATUS_DMRD;
3.116 + } else {
3.117 + idereg.state = IDE_STATE_PIO_READ;
3.118 + idereg.lba1 = length & 0xFF;
3.119 + idereg.lba2 = (length >> 8) & 0xFF;
3.120 + // idereg.lba1 = blocksize & 0xFF;
3.121 + // idereg.lba2 = blocksize >> 8;
3.122 + idereg.block_length = blocksize;
3.123 + idereg.block_left = blocksize;
3.124 + }
3.125 +}
3.126 +
3.127 +static void ide_start_packet_read( int length, int blocksize )
3.128 +{
3.129 + ide_start_read( length, blocksize, idereg.feature & IDE_FEAT_DMA ? TRUE : FALSE );
3.130 }
3.131
3.132 static void ide_raise_interrupt( void )
3.133 @@ -133,38 +178,80 @@
3.134
3.135 uint8_t ide_read_status( void )
3.136 {
3.137 - if( (idereg.status & IDE_ST_BUSY) == 0 )
3.138 + if( (idereg.status & IDE_STATUS_BSY) == 0 )
3.139 ide_clear_interrupt();
3.140 return idereg.status;
3.141 }
3.142
3.143 uint16_t ide_read_data_pio( void ) {
3.144 - if( idereg.readptr == NULL )
3.145 + if( idereg.state == IDE_STATE_PIO_READ ) {
3.146 + uint16_t rv = READ_BUFFER();
3.147 + idereg.data_offset += 2;
3.148 + idereg.block_left -= 2;
3.149 + if( idereg.data_offset >= idereg.data_length ) {
3.150 + idereg.state = IDE_STATE_IDLE;
3.151 + idereg.status &= ~IDE_STATUS_DRQ;
3.152 + idereg.data_offset = -1;
3.153 + ide_raise_interrupt();
3.154 + } else if( idereg.block_left <= 0 ) {
3.155 + idereg.block_left = idereg.block_length;
3.156 + ide_raise_interrupt();
3.157 + }
3.158 + return rv;
3.159 + } else {
3.160 return 0xFFFF;
3.161 - uint16_t rv = *idereg.readptr++;
3.162 - idereg.datalen-=2;
3.163 - idereg.blockleft-=2;
3.164 - if( idereg.datalen <=0 ) {
3.165 - idereg.readptr = NULL;
3.166 - idereg.status &= ~IDE_ST_DATA;
3.167 - ide_raise_interrupt();
3.168 - } else if( idereg.blockleft <= 0 ) {
3.169 - ide_raise_interrupt();
3.170 - idereg.blockleft = idereg.blocksize;
3.171 }
3.172 - return rv;
3.173 }
3.174
3.175 +
3.176 +/**
3.177 + * DMA read request
3.178 + *
3.179 + * This method is called from the ASIC side when a DMA read request is
3.180 + * initiated. If there is a pending DMA transfer already, we copy the
3.181 + * data immediately, otherwise we record the DMA buffer for use when we
3.182 + * get to actually doing the transfer.
3.183 + * @return number of bytes transfered
3.184 + */
3.185 +uint32_t ide_read_data_dma( uint32_t addr, uint32_t length )
3.186 +{
3.187 + if( idereg.state == IDE_STATE_DMA_READ ) {
3.188 + int xferlen = length;
3.189 + int remaining = idereg.data_length - idereg.data_offset;
3.190 + if( xferlen > remaining )
3.191 + xferlen = remaining;
3.192 + mem_copy_to_sh4( addr, data_buffer + idereg.data_offset, xferlen );
3.193 + idereg.data_offset += xferlen;
3.194 + if( idereg.data_offset >= idereg.data_length ) {
3.195 + idereg.data_offset = -1;
3.196 + idereg.state = IDE_STATE_IDLE;
3.197 + idereg.status &= ~IDE_STATUS_DRQ;
3.198 + ide_raise_interrupt();
3.199 + }
3.200 + return xferlen;
3.201 + }
3.202 + return 0;
3.203 +}
3.204 +
3.205 +
3.206 void ide_write_data_pio( uint16_t val ) {
3.207 - if( idereg.writeptr == NULL )
3.208 - return;
3.209 - *idereg.writeptr++ = val;
3.210 - idereg.datalen-=2;
3.211 - if( idereg.datalen <= 0 ) {
3.212 - int len = ((unsigned char *)idereg.writeptr) - idereg.data;
3.213 - idereg.writeptr = NULL;
3.214 - idereg.status &= ~IDE_ST_DATA;
3.215 - ide_write_buffer( idereg.data, len );
3.216 + if( idereg.state == IDE_STATE_CMD_WRITE ) {
3.217 + WRITE_BUFFER(val);
3.218 + idereg.data_offset+=2;
3.219 + if( idereg.data_offset >= idereg.data_length ) {
3.220 + idereg.state = IDE_STATE_BUSY;
3.221 + idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
3.222 + idereg.data_offset = -1;
3.223 + ide_packet_command(data_buffer);
3.224 + }
3.225 + } else if( idereg.state == IDE_STATE_PIO_WRITE ) {
3.226 + WRITE_BUFFER(val);
3.227 + if( idereg.data_offset >= idereg.data_length ) {
3.228 + idereg.state = IDE_STATE_BUSY;
3.229 + idereg.data_offset = -1;
3.230 + idereg.status = (idereg.status & ~IDE_STATUS_DRQ) | IDE_STATUS_BSY;
3.231 + /* ??? - no data writes yet anyway */
3.232 + }
3.233 }
3.234 }
3.235
3.236 @@ -187,8 +274,7 @@
3.237 ide_reset();
3.238 break;
3.239 case IDE_CMD_PACKET:
3.240 - idereg.count = 0x01;
3.241 - ide_set_write_buffer(command_buffer,12);
3.242 + ide_start_command_packet_write();
3.243 break;
3.244 case IDE_CMD_SET_FEATURE:
3.245 switch( idereg.feature ) {
3.246 @@ -219,15 +305,19 @@
3.247 default:
3.248 WARN( "IDE: Unimplemented command: %02X", val );
3.249 }
3.250 - idereg.status = (idereg.status | IDE_ST_READY | IDE_ST_SERV) & (~IDE_ST_ERROR);
3.251 + idereg.status = (idereg.status | IDE_STATUS_DRDY | IDE_STATUS_SERV) & (~IDE_STATUS_CHK);
3.252 }
3.253
3.254 -void ide_set_packet_error( uint16_t error )
3.255 +void ide_set_packet_result( uint16_t result )
3.256 {
3.257 - idereg.gdrom_error = error;
3.258 - idereg.error = (error & 0x0F) << 4;
3.259 - if( error != 0 ) {
3.260 + idereg.gdrom_sense[0] = 0xf0;
3.261 + idereg.gdrom_sense[2] = result & 0xFF;
3.262 + idereg.gdrom_sense[8] = (result >> 8) & 0xFF;
3.263 + idereg.error = (result & 0x0F) << 4;
3.264 + if( result != 0 ) {
3.265 idereg.status = 0x51;
3.266 + } else {
3.267 + idereg.status = idereg.status & ~(IDE_STATUS_BSY|IDE_STATUS_CHK);
3.268 }
3.269 }
3.270
3.271 @@ -250,10 +340,10 @@
3.272 switch( cmd[0] ) {
3.273 case PKT_CMD_TEST_READY:
3.274 if( !gdrom_is_mounted() ) {
3.275 - ide_set_packet_error( PKT_ERR_NODISC );
3.276 + ide_set_packet_result( PKT_ERR_NODISC );
3.277 return;
3.278 }
3.279 - ide_set_packet_error( 0 );
3.280 + ide_set_packet_result( 0 );
3.281 idereg.status = 0x50;
3.282 return;
3.283 break;
3.284 @@ -266,39 +356,38 @@
3.285 length = cmd[4];
3.286 if( lba+length > sizeof(gdrom_ident) )
3.287 length = sizeof(gdrom_ident) - lba;
3.288 - ide_set_read_buffer(gdrom_ident + lba, length, blocksize);
3.289 + memcpy( data_buffer, gdrom_ident + lba, length );
3.290 + ide_start_packet_read( length, blocksize );
3.291 break;
3.292 case PKT_CMD_SENSE:
3.293 - memset( data_buffer, 0, 10 );
3.294 length = cmd[4];
3.295 if( length > 10 )
3.296 length = 10;
3.297 - data_buffer[0] = 0xf0;
3.298 - data_buffer[2] = idereg.gdrom_error & 0xFF;
3.299 - data_buffer[8] = (idereg.gdrom_error >> 8) & 0xFF;
3.300 - ide_set_read_buffer( data_buffer, length , blocksize );
3.301 + memcpy( data_buffer, idereg.gdrom_sense, length );
3.302 + ide_start_packet_read( length, blocksize );
3.303 break;
3.304 case PKT_CMD_READ_TOC:
3.305 - status = gdrom_get_toc( data_buffer );
3.306 - if( status != PKT_ERR_OK ) {
3.307 - ide_set_packet_error( status );
3.308 - return;
3.309 - }
3.310 length = (cmd[3]<<8) | cmd[4];
3.311 if( length > sizeof(struct gdrom_toc) )
3.312 length = sizeof(struct gdrom_toc);
3.313 - ide_set_read_buffer( data_buffer, length, blocksize );
3.314 +
3.315 + status = gdrom_get_toc( data_buffer );
3.316 + if( status != PKT_ERR_OK ) {
3.317 + ide_set_packet_result( status );
3.318 + return;
3.319 + }
3.320 + ide_start_packet_read( length, blocksize );
3.321 break;
3.322 case PKT_CMD_DISC_INFO:
3.323 - status = gdrom_get_info( data_buffer );
3.324 - if( status != PKT_ERR_OK ) {
3.325 - ide_set_packet_error( status );
3.326 - return;
3.327 - }
3.328 length = cmd[4];
3.329 if( length > 6 )
3.330 length = 6;
3.331 - ide_set_read_buffer( data_buffer, length, blocksize );
3.332 + status = gdrom_get_info( data_buffer, cmd[2] );
3.333 + if( status != PKT_ERR_OK ) {
3.334 + ide_set_packet_result( status );
3.335 + return;
3.336 + }
3.337 + ide_start_packet_read( length, blocksize );
3.338 break;
3.339 case PKT_CMD_READ_SECTOR:
3.340 lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
3.341 @@ -317,47 +406,26 @@
3.342 case 0x30: mode = GDROM_RAW; break;
3.343 default:
3.344 ERROR( "Unrecognized read mode '%02X' in GD-Rom read request", cmd[1] );
3.345 - ide_set_packet_error( PKT_ERR_BADFIELD );
3.346 + ide_set_packet_result( PKT_ERR_BADFIELD );
3.347 return;
3.348 }
3.349 -
3.350 - status = gdrom_read_sectors( lba, length, mode, data_buffer, &data_buffer_len );
3.351 + datalen = data_buffer_len;
3.352 + status = gdrom_read_sectors( lba, length, mode, data_buffer, &datalen );
3.353 if( status != 0 ) {
3.354 - ide_set_packet_error( status );
3.355 - data_buffer[6] = (lba >> 8) & 0xFF;
3.356 - data_buffer[7] = lba & 0xFF;
3.357 + ide_set_packet_result( status );
3.358 + idereg.gdrom_sense[5] = (lba >> 16) & 0xFF;
3.359 + idereg.gdrom_sense[6] = (lba >> 8) & 0xFF;
3.360 + idereg.gdrom_sense[7] = lba & 0xFF;
3.361 return;
3.362 }
3.363 - ide_set_read_buffer( data_buffer, datalen, blocksize );
3.364 + ide_start_packet_read( datalen, blocksize );
3.365 break;
3.366 case PKT_CMD_SPIN_UP:
3.367 /* do nothing? */
3.368 break;
3.369 default:
3.370 - ide_set_packet_error( PKT_ERR_BADCMD ); /* Invalid command */
3.371 + ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
3.372 return;
3.373 }
3.374 - ide_set_packet_error( PKT_ERR_OK );
3.375 + ide_set_packet_result( PKT_ERR_OK );
3.376 }
3.377 -
3.378 -void ide_write_buffer( unsigned char *data, int datalen ) {
3.379 - switch( idereg.command ) {
3.380 - case IDE_CMD_PACKET:
3.381 - ide_packet_command( data );
3.382 - break;
3.383 - }
3.384 -}
3.385 -
3.386 -/**
3.387 - * DMA read request
3.388 - *
3.389 - * This method is called from the ASIC side when a DMA read request is
3.390 - * initiated. If there is a pending DMA transfer already, we copy the
3.391 - * data immediately, otherwise we record the DMA buffer for use when we
3.392 - * get to actually doing the transfer.
3.393 - */
3.394 -void ide_dma_read_req( uint32_t addr, uint32_t length )
3.395 -{
3.396 -
3.397 -
3.398 -}
4.1 --- a/src/gdrom/ide.h Tue May 23 13:11:09 2006 +0000
4.2 +++ b/src/gdrom/ide.h Tue May 23 13:11:45 2006 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: ide.h,v 1.7 2006-05-20 06:24:49 nkeynes Exp $
4.6 + * $Id: ide.h,v 1.8 2006-05-23 13:11:45 nkeynes Exp $
4.7 *
4.8 * This file defines the interface and structures of the dreamcast's IDE
4.9 * port. Note that the register definitions are in asic.h, as the registers
4.10 @@ -26,6 +26,7 @@
4.11 #include "dream.h"
4.12
4.13 struct ide_registers {
4.14 + /* IDE interface registers */
4.15 uint8_t status; /* A05F709C + A05F7018 Read-only */
4.16 uint8_t control; /* A05F7018 Write-only 01110 */
4.17 uint8_t error; /* A05F7084 Read-only 10001 */
4.18 @@ -37,33 +38,47 @@
4.19 uint8_t lba2; /* A05F7094 Read/Write 10101 */
4.20 uint8_t device; /* A05F7098 Read/Write 10110 */
4.21 uint8_t command; /* A05F709C Write-only 10111 */
4.22 +
4.23 + /* Internal IDE state */
4.24 uint8_t intrq_pending; /* Flag to indicate if the INTRQ line is active */
4.25 + int state;
4.26
4.27 - /* We don't keep the data register per se, rather the currently pending
4.28 - * data is kept here and read out a byte at a time (in PIO mode) or all at
4.29 - * once (in DMA mode). The IDE routines are responsible for managing this
4.30 - * memory. If dataptr == NULL, there is no data available.
4.31 - */
4.32 - unsigned char *data;
4.33 - uint16_t *readptr, *writeptr;
4.34 - uint16_t gdrom_error; /* Lo-byte = error code, Hi-byte = subcode */
4.35 - int datalen;
4.36 - int blocksize; /* Used to determine the transfer unit size */
4.37 - int blockleft; /* Bytes remaining in the current block */
4.38 + /* Sense response for the last executed packet command */
4.39 + unsigned char gdrom_sense[10];
4.40 +
4.41 +
4.42 + /* offset in the buffer of the next word to read/write, or -1
4.43 + * if inactive.
4.44 + */
4.45 + int data_offset;
4.46 + int data_length;
4.47 +
4.48 + int block_length; /* Used to determine the transfer unit size */
4.49 + int block_left; /* Bytes remaining in the current block */
4.50 };
4.51
4.52 -#define IDE_ST_BUSY 0x80
4.53 -#define IDE_ST_READY 0x40
4.54 -#define IDE_ST_SERV 0x10
4.55 -#define IDE_ST_DATA 0x08
4.56 -#define IDE_ST_ERROR 0x01
4.57 +#define IDE_STATE_IDLE 0
4.58 +#define IDE_STATE_CMD_WRITE 1
4.59 +#define IDE_STATE_PIO_READ 2
4.60 +#define IDE_STATE_PIO_WRITE 3
4.61 +#define IDE_STATE_DMA_READ 4
4.62 +#define IDE_STATE_DMA_WRITE 5
4.63 +#define IDE_STATE_BUSY 6
4.64 +
4.65 +/* Flag bits */
4.66 +#define IDE_STATUS_BSY 0x80 /* Busy */
4.67 +#define IDE_STATUS_DRDY 0x40 /* Device ready */
4.68 +#define IDE_STATUS_DMRD 0x20 /* DMA Request */
4.69 +#define IDE_STATUS_SERV 0x10
4.70 +#define IDE_STATUS_DRQ 0x08
4.71 +#define IDE_STATUS_CHK 0x01 /* Check condition (ie error) */
4.72
4.73 #define IDE_FEAT_DMA 0x01
4.74 #define IDE_FEAT_OVL 0x02
4.75
4.76 -#define IDE_COUNT_CD 0x01
4.77 -#define IDE_COUNT_IO 0x02
4.78 -#define IDE_COUNT_REL 0x04
4.79 +#define IDE_COUNT_CD 0x01 /* Command (1)/Data (0) */
4.80 +#define IDE_COUNT_IO 0x02 /* Input (0)/Output (1) */
4.81 +#define IDE_COUNT_REL 0x04 /* Release device */
4.82
4.83
4.84 #define IDE_CTL_RESET 0x04
4.85 @@ -91,10 +106,13 @@
4.86
4.87
4.88 uint16_t ide_read_data_pio(void);
4.89 +void ide_write_data_pio( uint16_t value );
4.90 +uint32_t ide_read_data_dma( uint32_t addr, uint32_t length );
4.91 uint8_t ide_read_status(void);
4.92 -void ide_write_data_pio( uint16_t value );
4.93 void ide_write_buffer( unsigned char *data, int length );
4.94
4.95 void ide_write_command( uint8_t command );
4.96 void ide_write_control( uint8_t value );
4.97 +
4.98 +void ide_dma_read_req( uint32_t addr, uint32_t length );
4.99 #endif
.