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