Search
lxdream.org :: lxdream/src/gdrom/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 15:5194dd0fdb60
prev2:42349f6ea216
next23:1ec3acd0594d
author nkeynes
date Thu Dec 22 13:52:02 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Implement status clearing correctly
view annotate diff log raw
     1 /*
     2  * ide.c    31 Mar 2004  - IDE Interface implementation
     3  *
     4  * Copyright (c) 2004 Nathan Keynes. Distribution and modification permitted
     5  * under the terms of the GNU General Public License version 2 or later. 
     6  */
     7 #include <stdlib.h>
     8 #include "modules.h"
     9 #include "ide.h"
    11 #define MAX_WRITE_BUF 4096;
    13 void ide_init( void );
    14 void ide_init( void );
    16 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
    17 				       NULL, NULL };
    19 struct ide_registers idereg;
    21 static char command_buffer[12];
    23 /* "\0\0\0\0\xb4\x19\0\0\x08SE      REV 6.42990316" */
    24 char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
    25                        0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
    26                        0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
    27                        0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
    30 void set_write_buffer( char *buf, int len )
    31 {
    32     idereg.status |= IDE_ST_DATA;
    33     idereg.data = buf;
    34     idereg.datalen = len;
    35     idereg.writeptr = (uint16_t *)buf;
    36     idereg.readptr = NULL;
    37 }
    39 void set_read_buffer( char *buf, int len )
    40 {
    41     idereg.status |= IDE_ST_DATA;
    42     idereg.data = buf;
    43     idereg.datalen = len;
    44     idereg.readptr = (uint16_t *)buf;
    45     idereg.writeptr = NULL;
    46     idereg.lba1 = len&0xFF;
    47     idereg.lba2 = len>>8;
    48 }
    50 void ide_clear_interrupt( void )
    51 {
    52     /* TODO */
    53 }
    55 void ide_init( void )
    56 {
    58 }
    60 void ide_reset( void )
    61 {
    62     ide_clear_interrupt();
    63     idereg.error = 0x01;
    64     idereg.count = 0x01;
    65     idereg.lba0 = 0x21;
    66     idereg.lba1 = 0x14;
    67     idereg.lba2 = 0xeb;
    68     idereg.feature = 0; /* Indeterminate really */
    69     idereg.status = 0x00;
    70     idereg.device = 0x00;
    71     idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
    72 }
    74 uint16_t ide_read_data_pio( void ) {
    75     if( idereg.readptr == NULL )
    76         return 0xFFFF;
    77     uint16_t rv = *idereg.readptr++;
    78     idereg.datalen-=2;
    79     if( idereg.datalen <=0 ) {
    80         idereg.readptr = NULL;
    81         idereg.status &= ~IDE_ST_DATA;
    82     }
    83     return rv;
    84 }
    86 void ide_write_data_pio( uint16_t val ) {
    87     if( idereg.writeptr == NULL )
    88         return;
    89     *idereg.writeptr++ = val;
    90     idereg.datalen-=2;
    91     if( idereg.datalen <= 0 ) {
    92         idereg.writeptr = NULL;
    93         idereg.status &= ~IDE_ST_DATA;
    94         ide_write_buffer( idereg.data );
    95     }
    96 }
    98 void ide_write_control( uint8_t val ) {
    99     /* TODO: In theory we can cause a soft-reset here, but the DC doesn't
   100      * appear to support it.
   101      */
   102 }
   104 void ide_write_command( uint8_t val ) {
   105     idereg.command = val;
   106     switch( val ) {
   107         case IDE_CMD_RESET_DEVICE:
   108             ide_reset();
   109             break;
   110         case IDE_CMD_PACKET:
   111             set_write_buffer(command_buffer,12);
   112             break;
   113         default:
   114             WARN( "IDE: Unimplemented command: %02X", val );
   115     }
   116     idereg.status |= IDE_ST_READY | IDE_ST_SERV;
   117 }
   119 void ide_write_buffer( char *data ) {
   120     uint16_t length;
   121     switch( idereg.command ) {
   122         case IDE_CMD_PACKET:
   123             /* Okay we have the packet in the command buffer */
   124             WARN( "ATAPI: Received Packet command: %02X", data[0] );
   126             switch( command_buffer[0] ) {
   127                 case PKT_CMD_IDENTIFY:
   128                     /* NB: Bios sets data[4] = 0x08, no idea what this is for;
   129                      * different values here appear to have no effect.
   130                      */
   131                     length = *((uint16_t*)(data+2));
   132                     if( length > sizeof(gdrom_ident) )
   133                         length = sizeof(gdrom_ident);
   134                     set_read_buffer(gdrom_ident, length);
   135                     break;
   136             }
   137             break;
   138     }
   139 }
.