Search
lxdream.org :: lxdream/src/gdrom/ide.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/gdrom/ide.c
changeset 2:42349f6ea216
next15:5194dd0fdb60
author nkeynes
date Thu Dec 08 13:38:00 2005 +0000 (18 years ago)
permissions -rw-r--r--
last change Generalise the core debug window to allow multiple instances.
Add cpu description structure to define different cpus for use by the
debug window, in preparation for ARM implementation
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 "ide.h"
    10 #define MAX_WRITE_BUF 4096;
    12 struct ide_registers idereg;
    14 static char command_buffer[12];
    16 /* "\0\0\0\0\xb4\x19\0\0\x08SE      REV 6.42990316" */
    17 char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
    18                        0x00, 0x08, 0x53, 0x45, 0x20, 0x20, 0x20, 0x20,
    19                        0x20, 0x20, 0x52, 0x65, 0x76, 0x20, 0x36, 0x2e,
    20                        0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
    23 void set_write_buffer( char *buf, int len )
    24 {
    25     idereg.status |= IDE_ST_DATA;
    26     idereg.data = buf;
    27     idereg.datalen = len;
    28     idereg.writeptr = (uint16_t *)buf;
    29     idereg.readptr = NULL;
    30 }
    32 void set_read_buffer( char *buf, int len )
    33 {
    34     idereg.status |= IDE_ST_DATA;
    35     idereg.data = buf;
    36     idereg.datalen = len;
    37     idereg.readptr = (uint16_t *)buf;
    38     idereg.writeptr = NULL;
    39     idereg.lba1 = len&0xFF;
    40     idereg.lba2 = len>>8;
    41 }
    43 void ide_clear_interrupt( void )
    44 {
    45     /* TODO */
    46 }
    48 void ide_reset( void )
    49 {
    50     ide_clear_interrupt();
    51     idereg.error = 0x01;
    52     idereg.count = 0x01;
    53     idereg.lba0 = 0x21;
    54     idereg.lba1 = 0x14;
    55     idereg.lba2 = 0xeb;
    56     idereg.feature = 0; /* Indeterminate really */
    57     idereg.status = 0x00;
    58     idereg.device = 0x00;
    59     idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
    60 }
    62 uint16_t ide_read_data_pio( void ) {
    63     if( idereg.readptr == NULL )
    64         return 0xFFFF;
    65     uint16_t rv = *idereg.readptr++;
    66     idereg.datalen-=2;
    67     if( idereg.datalen <=0 ) {
    68         idereg.readptr = NULL;
    69         idereg.status &= ~IDE_ST_DATA;
    70     }
    71     return rv;
    72 }
    74 void ide_write_data_pio( uint16_t val ) {
    75     if( idereg.writeptr == NULL )
    76         return;
    77     *idereg.writeptr++ = val;
    78     idereg.datalen-=2;
    79     if( idereg.datalen <= 0 ) {
    80         idereg.writeptr = NULL;
    81         idereg.status &= ~IDE_ST_DATA;
    82         ide_write_buffer( idereg.data );
    83     }
    84 }
    86 void ide_write_control( uint8_t val ) {
    87     /* TODO: In theory we can cause a soft-reset here, but the DC doesn't
    88      * appear to support it.
    89      */
    90 }
    92 void ide_write_command( uint8_t val ) {
    93     idereg.command = val;
    94     switch( val ) {
    95         case IDE_CMD_RESET_DEVICE:
    96             ide_reset();
    97             break;
    98         case IDE_CMD_PACKET:
    99             set_write_buffer(command_buffer,12);
   100             break;
   101         default:
   102             WARN( "IDE: Unimplemented command: %02X", val );
   103     }
   104     idereg.status |= IDE_ST_READY | IDE_ST_SERV;
   105 }
   107 void ide_write_buffer( char *data ) {
   108     uint16_t length;
   109     switch( idereg.command ) {
   110         case IDE_CMD_PACKET:
   111             /* Okay we have the packet in the command buffer */
   112             WARN( "ATAPI: Received Packet command: %02X", data[0] );
   114             switch( command_buffer[0] ) {
   115                 case PKT_CMD_IDENTIFY:
   116                     /* NB: Bios sets data[4] = 0x08, no idea what this is for;
   117                      * different values here appear to have no effect.
   118                      */
   119                     length = *((uint16_t*)(data+2));
   120                     if( length > sizeof(gdrom_ident) )
   121                         length = sizeof(gdrom_ident);
   122                     set_read_buffer(gdrom_ident, length);
   123                     break;
   124             }
   125             break;
   126     }
   127 }
.