Search
lxdream.org :: lxdream/src/gdrom/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 35:21a4be098304
prev31:495e480360d7
next39:3c35cb97b2ff
author nkeynes
date Mon Dec 26 06:38:13 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Remove RTE log line (not needed anymore)
view annotate diff log raw
     1 /**
     2  * $Id: ide.c,v 1.5 2005-12-26 03:54:55 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 "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         default:
   128             WARN( "IDE: Unimplemented command: %02X", val );
   129     }
   130     idereg.status |= IDE_ST_READY | IDE_ST_SERV;
   131 }
   133 void ide_write_buffer( char *data ) {
   134     uint16_t length;
   135     switch( idereg.command ) {
   136         case IDE_CMD_PACKET:
   137             /* Okay we have the packet in the command buffer */
   138             WARN( "ATAPI: Received Packet command: %02X", data[0] );
   140             switch( command_buffer[0] ) {
   141                 case PKT_CMD_IDENTIFY:
   142                     /* NB: Bios sets data[4] = 0x08, no idea what this is for;
   143                      * different values here appear to have no effect.
   144                      */
   145                     length = *((uint16_t*)(data+2));
   146                     if( length > sizeof(gdrom_ident) )
   147                         length = sizeof(gdrom_ident);
   148                     set_read_buffer(gdrom_ident, length);
   149                     break;
   150             }
   151             break;
   152     }
   153 }
.