2 * $Id: ide.c,v 1.7 2005-12-27 12:41:33 nkeynes Exp $
4 * IDE interface implementation
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
19 #define MODULE ide_module
23 #include "gdrom/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,
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 )
46 idereg.status |= IDE_ST_DATA;
49 idereg.writeptr = (uint16_t *)buf;
50 idereg.readptr = NULL;
53 void set_read_buffer( char *buf, int len )
55 idereg.status |= IDE_ST_DATA;
58 idereg.readptr = (uint16_t *)buf;
59 idereg.writeptr = NULL;
60 idereg.lba1 = len&0xFF;
64 void ide_clear_interrupt( void )
74 void ide_reset( void )
76 ide_clear_interrupt();
82 idereg.feature = 0; /* Indeterminate really */
85 idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
88 uint16_t ide_read_data_pio( void ) {
89 if( idereg.readptr == NULL )
91 uint16_t rv = *idereg.readptr++;
93 if( idereg.datalen <=0 ) {
94 idereg.readptr = NULL;
95 idereg.status &= ~IDE_ST_DATA;
100 void ide_write_data_pio( uint16_t val ) {
101 if( idereg.writeptr == NULL )
103 *idereg.writeptr++ = val;
105 if( idereg.datalen <= 0 ) {
106 idereg.writeptr = NULL;
107 idereg.status &= ~IDE_ST_DATA;
108 ide_write_buffer( idereg.data );
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.
118 void ide_write_command( uint8_t val ) {
119 idereg.command = val;
121 case IDE_CMD_RESET_DEVICE:
125 set_write_buffer(command_buffer,12);
127 case IDE_CMD_SET_FEATURE:
128 switch( idereg.feature ) {
129 case IDE_FEAT_SET_TRANSFER_MODE:
130 switch( idereg.count & 0xF8 ) {
132 INFO( "Set PIO default mode: %d", idereg.count&0x07 );
134 case IDE_XFER_PIO_FLOW:
135 INFO( "Set PIO Flow-control mode: %d", idereg.count&0x07 );
137 case IDE_XFER_MULTI_DMA:
138 INFO( "Set Multiword DMA mode: %d", idereg.count&0x07 );
140 case IDE_XFER_ULTRA_DMA:
141 INFO( "Set Ultra DMA mode: %d", idereg.count&0x07 );
144 INFO( "Setting unknown transfer mode: %02X", idereg.count );
149 WARN( "IDE: unimplemented feature: %02X", idereg.feature );
153 WARN( "IDE: Unimplemented command: %02X", val );
155 idereg.status |= IDE_ST_READY | IDE_ST_SERV;
158 void ide_write_buffer( char *data ) {
160 switch( idereg.command ) {
162 /* Okay we have the packet in the command buffer */
163 WARN( "ATAPI: Received Packet command: %02X", data[0] );
165 switch( command_buffer[0] ) {
166 case PKT_CMD_IDENTIFY:
167 /* NB: Bios sets data[4] = 0x08, no idea what this is for;
168 * different values here appear to have no effect.
170 length = *((uint16_t*)(data+2));
171 if( length > sizeof(gdrom_ident) )
172 length = sizeof(gdrom_ident);
173 set_read_buffer(gdrom_ident, length);
.