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