filename | src/gdrom/ide.c |
changeset | 2:42349f6ea216 |
next | 15: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 }
.