2 * ide.c 31 Mar 2004 - IDE Interface implementation
4 * Copyright (c) 2004 Nathan Keynes. Distribution and modification permitted
5 * under the terms of the GNU General Public License version 2 or later.
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 )
25 idereg.status |= IDE_ST_DATA;
28 idereg.writeptr = (uint16_t *)buf;
29 idereg.readptr = NULL;
32 void set_read_buffer( char *buf, int len )
34 idereg.status |= IDE_ST_DATA;
37 idereg.readptr = (uint16_t *)buf;
38 idereg.writeptr = NULL;
39 idereg.lba1 = len&0xFF;
43 void ide_clear_interrupt( void )
48 void ide_reset( void )
50 ide_clear_interrupt();
56 idereg.feature = 0; /* Indeterminate really */
59 idereg.disc = IDE_DISC_GDROM | IDE_DISC_READY;
62 uint16_t ide_read_data_pio( void ) {
63 if( idereg.readptr == NULL )
65 uint16_t rv = *idereg.readptr++;
67 if( idereg.datalen <=0 ) {
68 idereg.readptr = NULL;
69 idereg.status &= ~IDE_ST_DATA;
74 void ide_write_data_pio( uint16_t val ) {
75 if( idereg.writeptr == NULL )
77 *idereg.writeptr++ = val;
79 if( idereg.datalen <= 0 ) {
80 idereg.writeptr = NULL;
81 idereg.status &= ~IDE_ST_DATA;
82 ide_write_buffer( idereg.data );
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.
92 void ide_write_command( uint8_t val ) {
95 case IDE_CMD_RESET_DEVICE:
99 set_write_buffer(command_buffer,12);
102 WARN( "IDE: Unimplemented command: %02X", val );
104 idereg.status |= IDE_ST_READY | IDE_ST_SERV;
107 void ide_write_buffer( char *data ) {
109 switch( idereg.command ) {
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.
119 length = *((uint16_t*)(data+2));
120 if( length > sizeof(gdrom_ident) )
121 length = sizeof(gdrom_ident);
122 set_read_buffer(gdrom_ident, length);
.