diff options
Diffstat (limited to 'firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c')
-rw-r--r-- | firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c index 0c4dd4bfbe..1732c5d2c4 100644 --- a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c +++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "panic.h" | 28 | #include "panic.h" |
29 | #include "ata-target.h" | 29 | #include "ata-target.h" |
30 | #include "dm320.h" | 30 | #include "dm320.h" |
31 | #include "ata.h" | ||
32 | #include "string.h" | ||
31 | 33 | ||
32 | void sleep_ms(int ms) | 34 | void sleep_ms(int ms) |
33 | { | 35 | { |
@@ -109,3 +111,106 @@ void GIO2(void) | |||
109 | IO_INTC_IRQ1 = INTR_IRQ1_EXT2; /* Mask GIO2 interrupt */ | 111 | IO_INTC_IRQ1 = INTR_IRQ1_EXT2; /* Mask GIO2 interrupt */ |
110 | return; | 112 | return; |
111 | } | 113 | } |
114 | |||
115 | /* | ||
116 | --------------------------------------------------------------------------- | ||
117 | Creative File Systems parsing code | ||
118 | --------------------------------------------------------------------------- | ||
119 | */ | ||
120 | |||
121 | struct main_header | ||
122 | { | ||
123 | char mblk[4]; | ||
124 | unsigned char sector_size[4]; | ||
125 | unsigned char disk_size[8]; | ||
126 | struct partition_header | ||
127 | { | ||
128 | unsigned char end[4]; | ||
129 | unsigned char start[4]; | ||
130 | char name[8]; | ||
131 | } partitions[31]; | ||
132 | }; | ||
133 | |||
134 | struct minifs_file | ||
135 | { | ||
136 | char name[0x10]; | ||
137 | unsigned char unk[4]; | ||
138 | unsigned char size[4]; | ||
139 | unsigned char chain1[4]; | ||
140 | unsigned char chain2[4]; | ||
141 | }; | ||
142 | |||
143 | struct minifs_chain | ||
144 | { | ||
145 | unsigned char unknown[4]; | ||
146 | unsigned char chain[2*0x27FE]; | ||
147 | unsigned char unknown2[4]; | ||
148 | unsigned char length[4]; | ||
149 | }; | ||
150 | |||
151 | |||
152 | #define DIR_BITMAP_START 0x0143 | ||
153 | #define DIR_START 0x0144 | ||
154 | #define DATASPACE_BITMAP_START 0x0145 | ||
155 | #define DATASPACE_START 0x0146 | ||
156 | |||
157 | #define CLUSTER_CHAIN_SIZE 0x5008 | ||
158 | #define CLUSTER_CHAIN_HEAD 0x0000 | ||
159 | #define CLUSTER_CHAIN_BITMAP 0x0001 | ||
160 | #define CLUSTER_CHAIN_CHAIN 0x0002 | ||
161 | |||
162 | |||
163 | static unsigned short le2int16(unsigned char* buf) | ||
164 | { | ||
165 | return (buf[1] << 8) | buf[0]; | ||
166 | } | ||
167 | |||
168 | static unsigned int le2int32(unsigned char* buf) | ||
169 | { | ||
170 | return (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; | ||
171 | } | ||
172 | |||
173 | int load_minifs_file(char* filename, unsigned char* location) | ||
174 | { | ||
175 | struct main_header *hdr; | ||
176 | static struct minifs_file files[128]; | ||
177 | struct minifs_chain *chain; | ||
178 | unsigned int i; | ||
179 | int found = -1; | ||
180 | unsigned char sector[512]; | ||
181 | static unsigned char chain_data[42*512]; /* stack overflow if not static */ | ||
182 | |||
183 | /* Reading MBLK */ | ||
184 | ata_read_sectors(0, 1, §or); | ||
185 | hdr = (struct main_header*)§or; | ||
186 | |||
187 | /* Reading directory listing */ | ||
188 | #define CLUSTER2SECTOR(x) ( (le2int32(hdr->partitions[0].start) + (x)*8) ) | ||
189 | ata_read_sectors(CLUSTER2SECTOR(DIR_START), 8, &files); | ||
190 | |||
191 | for(i=0; i<127; i++) | ||
192 | { | ||
193 | if(strcmp(files[i].name, filename) == 0) | ||
194 | found = i; | ||
195 | } | ||
196 | |||
197 | if(found == -1) | ||
198 | return -1; | ||
199 | |||
200 | #define GET_CHAIN(x) ( CLUSTER2SECTOR(CLUSTER_CHAIN_CHAIN)*512 + (x)*CLUSTER_CHAIN_SIZE ) | ||
201 | #define FILE2SECTOR(x) ( CLUSTER2SECTOR(DATASPACE_START + (x)) ) | ||
202 | |||
203 | /* Reading chain list */ | ||
204 | ata_read_sectors(GET_CHAIN(le2int32(files[found].chain1))/512, 41, &chain_data[0]); | ||
205 | |||
206 | chain = (struct minifs_chain*)&chain_data[GET_CHAIN(le2int32(files[found].chain1))%512]; | ||
207 | |||
208 | /* Copying data */ | ||
209 | for(i=0; i<le2int32(chain->length); i++) | ||
210 | { | ||
211 | ata_read_sectors(FILE2SECTOR(le2int16(&chain->chain[i*2])), 8, location); | ||
212 | location += 0x1000; | ||
213 | } | ||
214 | |||
215 | return le2int32(files[found].size); | ||
216 | } | ||