Search
lxdream.org :: lxdream/src/gdrom/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 39:3c35cb97b2ff
prev35:21a4be098304
next47:da09bcb7ce69
author nkeynes
date Mon Dec 26 10:47:34 2005 +0000 (14 years ago)
permissions -rw-r--r--
last change Log feature on calls to SET_FEATURE
view annotate diff log raw
     1 /**
     2  * $Id: ide.c,v 1.6 2005-12-26 10:47:34 nkeynes Exp $
     3  *
     4  * IDE interface implementation
     5  *
     6  * Copyright (c) 2005 Nathan Keynes.
     7  *
     8  * This program is free software; you can redistribute it and/or modify
     9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16  * GNU General Public License for more details.
    17  */
    19 #define MODULE ide_module
    21 #include <stdlib.h>
    22 #include "dream.h"
    23 #include "gdrom/ide.h"
    25 #define MAX_WRITE_BUF 4096;
    27 void ide_init( void );
    28 void ide_init( void );
    30 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
    31 				       NULL, NULL, NULL };
    33 struct ide_registers idereg;
    35 static char command_buffer[12];
    37 /* "\0\0\0\0\xb4\x19\0\0\x08SE      REV 6.42990316" */
    38 char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
    39                        0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
    40                        0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
    41                        0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
    44 void set_write_buffer( char *buf, int len )
    45 {
    46     idereg.status |= IDE_ST_DATA;
    47     idereg.data = buf;
    48     idereg.datalen = len;
    49     idereg.writeptr = (uint16_t *)buf;
    50     idereg.readptr = NULL;
    51 }
    53 void set_read_buffer( char *buf, int len )
    54 {
    55     idereg.status |= IDE_ST_DATA;
    56     idereg.data = buf;
    57     idereg.datalen = len;
    58     idereg.readptr = (uint16_t *)buf;
    59     idereg.writeptr = NULL;
    60     idereg.lba1 = len&0xFF;
    61     idereg.lba2 = len>>8;
    62 }
    64 void ide_clear_interrupt( void )
    65 {
    66     /* TODO */
    67 }
    69 void ide_init( void )
    70 {
    72 }
    74 void ide_reset( void )
    75 {
    76     ide_clear_interrupt();
    77     idereg.error = 0x01;
    78     idereg.count = 0x01;
    79     idereg.lba0 = 0x21;
    80     idereg.lba1 = 0x14;
    81     idereg.lba2 = 0xeb;
    82     idereg.feature = 0; /* Indeterminate really */
    83     idereg.status = 0x00;
    84     idereg.device = 0x00;
    85     idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
    86 }
    88 uint16_t ide_read_data_pio( void ) {
    89     if( idereg.readptr == NULL )
    90         return 0xFFFF;
    91     uint16_t rv = *idereg.readptr++;
    92     idereg.datalen-=2;
    93     if( idereg.datalen <=0 ) {
    94         idereg.readptr = NULL;
    95         idereg.status &= ~IDE_ST_DATA;
    96     }
    97     return rv;
    98 }
   100 void ide_write_data_pio( uint16_t val ) {
   101     if( idereg.writeptr == NULL )
   102         return;
   103     *idereg.writeptr++ = val;
   104     idereg.datalen-=2;
   105     if( idereg.datalen <= 0 ) {
   106         idereg.writeptr = NULL;
   107         idereg.status &= ~IDE_ST_DATA;
   108         ide_write_buffer( idereg.data );
   109     }
   110 }
   112 void ide_write_control( uint8_t val ) {
   113     /* TODO: In theory we can cause a soft-reset here, but the DC doesn't
   114      * appear to support it.
   115      */
   116 }
   118 void ide_write_command( uint8_t val ) {
   119     idereg.command = val;
   120     switch( val ) {
   121     case IDE_CMD_RESET_DEVICE:
   122 	ide_reset();
   123 	break;
   124     case IDE_CMD_PACKET:
   125 	set_write_buffer(command_buffer,12);
   126 	break;
   127     case IDE_CMD_SET_FEATURE:
   128 	switch( idereg.feature ) {
   129 	default:
   130 	    WARN( "IDE: unimplemented feature: %02X", idereg.feature );
   131 	}
   132 	break;
   133     default:
   134 	WARN( "IDE: Unimplemented command: %02X", val );
   135     }
   136     idereg.status |= IDE_ST_READY | IDE_ST_SERV;
   137 }
   139 void ide_write_buffer( char *data ) {
   140     uint16_t length;
   141     switch( idereg.command ) {
   142         case IDE_CMD_PACKET:
   143             /* Okay we have the packet in the command buffer */
   144             WARN( "ATAPI: Received Packet command: %02X", data[0] );
   146             switch( command_buffer[0] ) {
   147                 case PKT_CMD_IDENTIFY:
   148                     /* NB: Bios sets data[4] = 0x08, no idea what this is for;
   149                      * different values here appear to have no effect.
   150                      */
   151                     length = *((uint16_t*)(data+2));
   152                     if( length > sizeof(gdrom_ident) )
   153                         length = sizeof(gdrom_ident);
   154                     set_read_buffer(gdrom_ident, length);
   155                     break;
   156             }
   157             break;
   158     }
   159 }
.