Search
lxdream.org :: lxdream/src/gdrom/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 31:495e480360d7
prev23:1ec3acd0594d
next35:21a4be098304
author nkeynes
date Sun Dec 25 08:24:11 2005 +0000 (15 years ago)
permissions -rw-r--r--
last change Finish adding header blocks to all files
view annotate diff log raw
     1 /**
     2  * $Id: ide.c,v 1.4 2005-12-25 08:24:11 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  */
    18 #include <stdlib.h>
    19 #include "modules.h"
    20 #include "ide.h"
    22 #define MAX_WRITE_BUF 4096;
    24 void ide_init( void );
    25 void ide_init( void );
    27 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
    28 				       NULL, NULL, NULL };
    30 struct ide_registers idereg;
    32 static char command_buffer[12];
    34 /* "\0\0\0\0\xb4\x19\0\0\x08SE      REV 6.42990316" */
    35 char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
    36                        0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
    37                        0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
    38                        0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
    41 void set_write_buffer( char *buf, int len )
    42 {
    43     idereg.status |= IDE_ST_DATA;
    44     idereg.data = buf;
    45     idereg.datalen = len;
    46     idereg.writeptr = (uint16_t *)buf;
    47     idereg.readptr = NULL;
    48 }
    50 void set_read_buffer( char *buf, int len )
    51 {
    52     idereg.status |= IDE_ST_DATA;
    53     idereg.data = buf;
    54     idereg.datalen = len;
    55     idereg.readptr = (uint16_t *)buf;
    56     idereg.writeptr = NULL;
    57     idereg.lba1 = len&0xFF;
    58     idereg.lba2 = len>>8;
    59 }
    61 void ide_clear_interrupt( void )
    62 {
    63     /* TODO */
    64 }
    66 void ide_init( void )
    67 {
    69 }
    71 void ide_reset( void )
    72 {
    73     ide_clear_interrupt();
    74     idereg.error = 0x01;
    75     idereg.count = 0x01;
    76     idereg.lba0 = 0x21;
    77     idereg.lba1 = 0x14;
    78     idereg.lba2 = 0xeb;
    79     idereg.feature = 0; /* Indeterminate really */
    80     idereg.status = 0x00;
    81     idereg.device = 0x00;
    82     idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
    83 }
    85 uint16_t ide_read_data_pio( void ) {
    86     if( idereg.readptr == NULL )
    87         return 0xFFFF;
    88     uint16_t rv = *idereg.readptr++;
    89     idereg.datalen-=2;
    90     if( idereg.datalen <=0 ) {
    91         idereg.readptr = NULL;
    92         idereg.status &= ~IDE_ST_DATA;
    93     }
    94     return rv;
    95 }
    97 void ide_write_data_pio( uint16_t val ) {
    98     if( idereg.writeptr == NULL )
    99         return;
   100     *idereg.writeptr++ = val;
   101     idereg.datalen-=2;
   102     if( idereg.datalen <= 0 ) {
   103         idereg.writeptr = NULL;
   104         idereg.status &= ~IDE_ST_DATA;
   105         ide_write_buffer( idereg.data );
   106     }
   107 }
   109 void ide_write_control( uint8_t val ) {
   110     /* TODO: In theory we can cause a soft-reset here, but the DC doesn't
   111      * appear to support it.
   112      */
   113 }
   115 void ide_write_command( uint8_t val ) {
   116     idereg.command = val;
   117     switch( val ) {
   118         case IDE_CMD_RESET_DEVICE:
   119             ide_reset();
   120             break;
   121         case IDE_CMD_PACKET:
   122             set_write_buffer(command_buffer,12);
   123             break;
   124         default:
   125             WARN( "IDE: Unimplemented command: %02X", val );
   126     }
   127     idereg.status |= IDE_ST_READY | IDE_ST_SERV;
   128 }
   130 void ide_write_buffer( char *data ) {
   131     uint16_t length;
   132     switch( idereg.command ) {
   133         case IDE_CMD_PACKET:
   134             /* Okay we have the packet in the command buffer */
   135             WARN( "ATAPI: Received Packet command: %02X", data[0] );
   137             switch( command_buffer[0] ) {
   138                 case PKT_CMD_IDENTIFY:
   139                     /* NB: Bios sets data[4] = 0x08, no idea what this is for;
   140                      * different values here appear to have no effect.
   141                      */
   142                     length = *((uint16_t*)(data+2));
   143                     if( length > sizeof(gdrom_ident) )
   144                         length = sizeof(gdrom_ident);
   145                     set_read_buffer(gdrom_ident, length);
   146                     break;
   147             }
   148             break;
   149     }
   150 }
.