Subversion Repositories freemyipod

Rev

Rev 898 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
770 user890104 1
//
2
//
898 user890104 3
//    Copyright 2013 user890104
770 user890104 4
//
5
//
6
//    This file is part of emCORE.
7
//
8
//    emCORE is free software: you can redistribute it and/or
9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
13
//    emCORE 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.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
20
//
21
//
22
 
23
#include "global.h"
24
 
25
#include "emcore.h"
26
#include "util.h"
27
#include "usb.h"
28
 
898 user890104 29
int32_t emcore_send(const void *data, uint32_t length) {
30
    return usb_control_transfer(0x41, (void *)data, length);
770 user890104 31
}
32
 
898 user890104 33
int32_t emcore_receive(void *data, uint32_t length) {
34
    return usb_control_transfer(0xc1, data, length);
770 user890104 35
}
36
 
898 user890104 37
int32_t emcore_monitor_command(const void *out, void *in,
38
    uint32_t send_length, uint32_t receive_length) {
39
    int32_t res;
770 user890104 40
    uint32_t status;
41
 
42
#ifdef DEBUG_USB_PACKETS
43
    fprintf(stderr, "--------------------------------------------\n");
44
    fprintf(stderr, "Sending %d bytes...\n", send_length);
45
 
46
    dump_packet(out, send_length);
47
 
48
#endif
898 user890104 49
    res = emcore_send(out, send_length);
770 user890104 50
 
898 user890104 51
    if (res != LIBUSB_SUCCESS) {
770 user890104 52
        return res;
53
    }
54
 
898 user890104 55
    if (in && receive_length) {
770 user890104 56
#ifdef DEBUG_USB_PACKETS
57
        fprintf(stderr, "Receiving %d bytes...\n", receive_length);
58
 
59
#endif
898 user890104 60
        res = emcore_receive(in, receive_length);
770 user890104 61
 
898 user890104 62
        if (res != LIBUSB_SUCCESS) {
770 user890104 63
            return res;
64
        }
65
 
66
#ifdef DEBUG_USB_PACKETS
67
        dump_packet(in, receive_length);
68
 
69
#endif
898 user890104 70
        status = *((int32_t *)(in));
770 user890104 71
    }
898 user890104 72
    else {
770 user890104 73
        status = EMCORE_SUCCESS;
74
    }
75
 
76
#ifdef DEBUG_USB_PACKETS
77
    fprintf(stderr, "--------------------------------------------\n");
78
 
79
#endif
898 user890104 80
    switch (status) {
770 user890104 81
        case 0:
82
            return EMCORE_ERROR_INVALID;
83
        break;
84
        case 1:
85
            return EMCORE_SUCCESS;
86
        break;
87
        case 2:
88
            return EMCORE_ERROR_NOT_SUPPORTED;
89
        break;
90
        case 3:
91
            return EMCORE_ERROR_BUSY;
92
        break;
93
        default:
94
            return EMCORE_ERROR_INVALID;
95
        break;
96
    }
97
}
98
 
898 user890104 99
int32_t emcore_get_version(struct emcore_dev_info *dev_info) {
100
    int32_t res;
770 user890104 101
    uint32_t out[4] = { 1, 0, 0, 0 }, in[4];
102
 
103
    res = emcore_monitor_command(out, in, 16, 16);
104
 
898 user890104 105
    if (res != EMCORE_SUCCESS) {
770 user890104 106
        return res;
107
    }
108
 
109
    memcpy(dev_info, &in[1], sizeof(*dev_info));
110
 
111
    return EMCORE_SUCCESS;
112
}
113
 
898 user890104 114
int32_t emcore_get_malloc_pool_bounds(struct emcore_malloc_pool_bounds *bounds) {
115
    int32_t res;
770 user890104 116
    uint32_t out[4] = { 1, 1, 0, 0 }, in[4];
117
 
118
    res = emcore_monitor_command(out, in, 16, 16);
119
 
898 user890104 120
    if (res != EMCORE_SUCCESS) {
770 user890104 121
        return res;
122
    }
123
 
898 user890104 124
    memcpy(bounds, &in[1], sizeof(*bounds));
770 user890104 125
 
126
    return EMCORE_SUCCESS;
127
}
128
 
898 user890104 129
int32_t emcore_reset(uint8_t graceful) {
130
    int32_t res;
131
    uint32_t out[4] = { 2, 0xdeadbeef, 0, 0 };
770 user890104 132
 
133
    out[1] = graceful;
134
 
898 user890104 135
    res = emcore_monitor_command(out, NULL, 16, 0);
770 user890104 136
 
898 user890104 137
    if (res != EMCORE_SUCCESS) {
770 user890104 138
        return res;
139
    }
140
 
141
    return EMCORE_SUCCESS;
142
}
143
 
898 user890104 144
int32_t emcore_poweroff(uint8_t graceful) {
145
    int32_t res;
146
    uint32_t out[4] = { 3, 0xdeadbeef, 0, 0 };
770 user890104 147
 
148
    out[1] = graceful;
149
 
898 user890104 150
    res = emcore_monitor_command(out, NULL, 16, 0);
770 user890104 151
 
898 user890104 152
    if (res != EMCORE_SUCCESS) {
770 user890104 153
        return res;
154
    }
155
 
156
    return EMCORE_SUCCESS;
157
}
158
 
898 user890104 159
int32_t emcore_read(void *data, uint32_t addr, uint32_t size) {
160
    int32_t res;
161
    uint32_t readsize, out[4] = { 4, 0xdeadbeef, 0xdeadbeef, 0 };
162
    void *in;
163
 
164
    in = malloc(EMCORE_HEADER_SIZE + 0x0F00);
165
 
166
    while (size) {
167
        readsize = MIN(size, 0x0F00);
168
 
169
        out[1] = addr;
170
        out[2] = readsize;
171
 
172
        res = emcore_monitor_command(out, in, 16, readsize + EMCORE_HEADER_SIZE);
173
 
174
        if (res != EMCORE_SUCCESS) {
175
            free(in);
176
            return res;
177
        }
178
 
179
        memcpy(data, in + EMCORE_HEADER_SIZE, readsize);
180
 
181
        data += readsize;
182
        addr += readsize;
183
        size -= readsize;
770 user890104 184
    }
185
 
786 user890104 186
    free(in);
898 user890104 187
 
770 user890104 188
    return EMCORE_SUCCESS;
189
}
190
 
898 user890104 191
int32_t emcore_write(const void *data, uint32_t addr, uint32_t size) {
192
    int32_t res;
193
    uint32_t writesize, in[4], *out;
194
 
195
    out = calloc(sizeof(char), EMCORE_HEADER_SIZE + 0x0F00);
770 user890104 196
 
197
    *(out) = 5;
898 user890104 198
 
199
    while (size) {
200
        writesize = MIN(size, 0x0F00);
201
 
202
        memcpy(out + 4, data, writesize);
770 user890104 203
 
898 user890104 204
        *(out + 1) = addr;
205
        *(out + 2) = writesize;
206
 
207
        res = emcore_monitor_command(out, in, writesize + EMCORE_HEADER_SIZE, 16);
770 user890104 208
 
898 user890104 209
        if (res != EMCORE_SUCCESS) {
210
            free(out);
211
            return res;
212
        }
213
 
214
        data += writesize;
215
        addr += writesize;
216
        size -= writesize;
770 user890104 217
    }
898 user890104 218
 
219
    free(out);
770 user890104 220
 
221
    return EMCORE_SUCCESS;
222
}
223
 
898 user890104 224
int32_t emcore_readi2c(void *data, uint8_t bus, uint8_t slave, uint8_t addr, uint8_t size) {
225
    int32_t res;
226
    uint32_t data_length, out[4] = { 8, 0xdeadbeef, 0, 0 };
227
    void *in;
770 user890104 228
 
898 user890104 229
    if (!size) {
230
        return EMCORE_SUCCESS;
770 user890104 231
    }
232
 
233
    out[1] = bus | (slave << 8) | (addr << 16) | (size << 24);
234
 
898 user890104 235
    data_length = EMCORE_HEADER_SIZE + size;
770 user890104 236
    in = malloc(data_length);
237
 
238
    res = emcore_monitor_command(out, in, 16, data_length);
239
 
898 user890104 240
    if (res != EMCORE_SUCCESS) {
786 user890104 241
        free(in);
242
 
770 user890104 243
        return res;
244
    }
245
 
898 user890104 246
    memcpy(data, in + EMCORE_HEADER_SIZE, size);
770 user890104 247
 
786 user890104 248
    free(in);
249
 
770 user890104 250
    return EMCORE_SUCCESS;
251
}
252
 
898 user890104 253
int32_t emcore_writei2c(const void *data, uint8_t bus, uint8_t slave, uint8_t addr, uint8_t size) {
254
    int32_t res;
770 user890104 255
    uint32_t data_length, in[4], *out;
256
 
898 user890104 257
    if (!size) {
258
        return EMCORE_SUCCESS;
259
    }
260
 
261
    if (size > 48) {
770 user890104 262
        return EMCORE_ERROR_OVERFLOW;
263
    }
898 user890104 264
 
265
    data_length = size + EMCORE_HEADER_SIZE;
770 user890104 266
    out = calloc(data_length, 1);
267
 
898 user890104 268
    *(out) = 9;
269
    out[1] = bus | (slave << 8) | (addr << 16) | (size << 24);
770 user890104 270
 
898 user890104 271
    memcpy(out + 4, data, size);
770 user890104 272
 
273
    res = emcore_monitor_command(out, in, data_length, 16);
274
 
898 user890104 275
    if (res != EMCORE_SUCCESS) {
770 user890104 276
        return res;
277
    }
278
 
279
    return EMCORE_SUCCESS;
280
}
281
 
898 user890104 282
int32_t emcore_file_open(uint32_t *handle, const char *path, uint32_t flags) {
283
    int32_t res;
770 user890104 284
    uint32_t str_length, data_length, in[4], *out;
898 user890104 285
    int32_t flags_emcore = 0;
770 user890104 286
 
287
    *handle = 0;
288
 
782 user890104 289
    /*
290
    #define O_RDONLY 0
291
    #define O_WRONLY 1
292
    #define O_RDWR   2
293
    #define O_CREAT  4
294
    #define O_APPEND 8
295
    #define O_TRUNC  0x10
296
    */
297
 
298
    if (flags & O_WRONLY) {
299
        flags_emcore |= 0x01;
300
    }
301
 
302
    if (flags & O_RDWR) {
303
        flags_emcore |= 0x02;
304
    }
305
 
306
    if (flags & O_CREAT) {
307
        flags_emcore |= 0x04;
308
    }
309
 
310
    if (flags & O_APPEND) {
311
        flags_emcore |= 0x08;
312
    }
313
 
314
    if (flags & O_TRUNC) {
315
        flags_emcore |= 0x10;
316
    }
317
 
898 user890104 318
    str_length = strlen(path) + 1;
782 user890104 319
 
898 user890104 320
    if (str_length > 48) {
321
        uint32_t buf = 0;
322
 
323
        res = emcore_malloc(&buf, str_length);
324
 
325
        if (res != EMCORE_SUCCESS) {
326
            return res;
327
        }
328
 
329
        res = emcore_write(path, buf, str_length);
330
 
331
        if (res != EMCORE_SUCCESS) {
332
            return res;
333
        }
334
 
335
        out = calloc(sizeof(char), EMCORE_HEADER_SIZE);
770 user890104 336
 
898 user890104 337
        *(out) = 30;
338
        *(out + 1) = flags_emcore;
339
        *(out + 3) = buf;
340
 
341
        res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
342
    }
343
    else {
344
        data_length = EMCORE_HEADER_SIZE + str_length;
345
 
346
        out = calloc(sizeof(char), data_length);
770 user890104 347
 
898 user890104 348
        *(out) = 30;
349
        *(out + 1) = flags_emcore;
350
 
351
        strncpy(((char *)(out + 4)), path, str_length - 1);
352
 
353
        res = emcore_monitor_command(out, in, data_length, 16);
354
    }
355
 
356
    if (res != EMCORE_SUCCESS) {
770 user890104 357
        return res;
358
    }
359
 
898 user890104 360
    if (in[1] > 0x80000000) {
770 user890104 361
        return EMCORE_ERROR_IO;
362
    }
363
 
364
    *handle = in[1];
365
 
366
    return EMCORE_SUCCESS;
367
}
368
 
898 user890104 369
int32_t emcore_file_size(uint32_t *size, uint32_t handle) {
370
    int32_t res;
770 user890104 371
    uint32_t out[4] = { 31, 0xdeadbeef, 0, 0 }, in[4];
372
 
373
    out[1] = handle;
374
 
375
    res = emcore_monitor_command(out, in, 16, 16);
376
 
898 user890104 377
    if (res != EMCORE_SUCCESS) {
770 user890104 378
        return res;
379
    }
380
 
898 user890104 381
    if (in[1] > 0x80000000) {
770 user890104 382
        return EMCORE_ERROR_IO;
383
    }
384
 
385
    *size = in[1];
386
 
387
    return EMCORE_SUCCESS;
388
}
389
 
898 user890104 390
int32_t emcore_file_read(uint32_t *nread, uint32_t handle, uint32_t addr, uint32_t size) {
391
    int32_t res;
770 user890104 392
    uint32_t out[4] = { 32, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
393
 
394
    out[1] = handle;
395
    out[2] = addr;
396
    out[3] = size;
397
 
398
    res = emcore_monitor_command(out, in, 16, 16);
399
 
898 user890104 400
    if (res != EMCORE_SUCCESS) {
770 user890104 401
        return res;
402
    }
403
 
898 user890104 404
    if (in[1] > 0x80000000) {
770 user890104 405
        return EMCORE_ERROR_IO;
406
    }
407
 
408
    *nread = in[1];
409
 
410
    return EMCORE_SUCCESS;
411
}
412
 
898 user890104 413
int32_t emcore_file_write(uint32_t *nwrite, uint32_t handle, uint32_t addr, uint32_t size) {
414
    int32_t res;
770 user890104 415
    uint32_t out[4] = { 33, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
416
 
417
    out[1] = handle;
418
    out[2] = addr;
419
    out[3] = size;
420
 
421
    res = emcore_monitor_command(out, in, 16, 16);
422
 
898 user890104 423
    if (res != EMCORE_SUCCESS) {
770 user890104 424
        return res;
425
    }
426
 
898 user890104 427
    if (in[1] > 0x80000000) {
770 user890104 428
        return EMCORE_ERROR_IO;
429
    }
430
 
784 user890104 431
    *nwrite = in[1];
432
 
770 user890104 433
    return EMCORE_SUCCESS;
434
}
435
 
898 user890104 436
int32_t emcore_file_seek(uint32_t handle, uint32_t offset, uint32_t whence) {
437
    int32_t res;
770 user890104 438
    uint32_t out[4] = { 34, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }, in[4];
439
 
440
    out[1] = handle;
441
    out[2] = offset;
442
    out[3] = whence;
443
 
444
    res = emcore_monitor_command(out, in, 16, 16);
445
 
898 user890104 446
    if (res != EMCORE_SUCCESS) {
770 user890104 447
        return res;
448
    }
449
 
898 user890104 450
    if (in[1] > 0x80000000) {
770 user890104 451
        return EMCORE_ERROR_IO;
452
    }
453
 
454
    return EMCORE_SUCCESS;
455
}
456
 
898 user890104 457
int32_t emcore_file_truncate(uint32_t handle, uint32_t length) {
458
    int32_t res;
770 user890104 459
    uint32_t out[4] = { 35, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
460
 
461
    out[1] = handle;
462
    out[2] = length;
463
 
464
    res = emcore_monitor_command(out, in, 16, 16);
465
 
898 user890104 466
    if (res != EMCORE_SUCCESS) {
770 user890104 467
        return res;
468
    }
469
 
898 user890104 470
    if (in[1] > 0x80000000) {
770 user890104 471
        return EMCORE_ERROR_IO;
472
    }
473
 
474
    return EMCORE_SUCCESS;
475
}
476
 
898 user890104 477
int32_t emcore_file_sync(uint32_t handle) {
478
    int32_t res;
770 user890104 479
    uint32_t out[4] = { 36, 0xdeadbeef, 0, 0 }, in[4];
480
 
481
    out[1] = handle;
482
 
483
    res = emcore_monitor_command(out, in, 16, 16);
484
 
898 user890104 485
    if (res != EMCORE_SUCCESS) {
770 user890104 486
        return res;
487
    }
488
 
898 user890104 489
    if (in[1] > 0x80000000) {
770 user890104 490
        return EMCORE_ERROR_IO;
491
    }
492
 
493
    return EMCORE_SUCCESS;
494
}
495
 
898 user890104 496
int32_t emcore_file_close(uint32_t handle) {
497
    int32_t res;
770 user890104 498
    uint32_t out[4] = { 37, 0xdeadbeef, 0, 0 }, in[4];
499
 
500
    out[1] = handle;
501
 
502
    res = emcore_monitor_command(out, in, 16, 16);
503
 
898 user890104 504
    if (res != EMCORE_SUCCESS) {
770 user890104 505
        return res;
506
    }
507
 
898 user890104 508
    if (in[1] > 0x80000000) {
770 user890104 509
        return EMCORE_ERROR_IO;
510
    }
511
 
512
    return EMCORE_SUCCESS;
513
}
514
 
898 user890104 515
int32_t emcore_file_close_all(uint32_t *count) {
516
    int32_t res;
770 user890104 517
    uint32_t out[4] = { 38, 0, 0, 0 }, in[4];
518
 
519
    res = emcore_monitor_command(out, in, 16, 16);
520
 
898 user890104 521
    if (res != EMCORE_SUCCESS) {
770 user890104 522
        return res;
523
    }
524
 
898 user890104 525
    if (in[1] > 0x80000000) {
770 user890104 526
        return EMCORE_ERROR_IO;
527
    }
528
 
529
    *count = in[1];
530
 
531
    return EMCORE_SUCCESS;
532
}
533
 
898 user890104 534
int32_t emcore_file_kill_all(uint32_t volume) {
535
    int32_t res;
770 user890104 536
    uint32_t out[4] = { 39, 0xdeadbeef, 0, 0 }, in[4];
537
 
538
    out[1] = volume;
539
 
540
    res = emcore_monitor_command(out, in, 16, 16);
541
 
898 user890104 542
    if (res != EMCORE_SUCCESS) {
770 user890104 543
        return res;
544
    }
545
 
898 user890104 546
    if (in[1] > 0x80000000) {
770 user890104 547
        return EMCORE_ERROR_IO;
548
    }
549
 
550
    return EMCORE_SUCCESS;
551
}
552
 
898 user890104 553
int32_t emcore_file_unlink(const char *path) {
554
    int32_t res;
770 user890104 555
    uint32_t str_length, data_length, in[4], *out;
556
 
898 user890104 557
    str_length = strlen(path) + 1;
770 user890104 558
 
898 user890104 559
    if (str_length > 48) {
560
        uint32_t buf;
561
 
562
        res = emcore_malloc(&buf, str_length);
563
 
564
        if (res != EMCORE_SUCCESS) {
565
            return res;
566
        }
567
 
568
        res = emcore_write(path, buf, str_length);
569
 
570
        if (res != EMCORE_SUCCESS) {
571
            return res;
572
        }
573
 
574
        out = calloc(sizeof(char), EMCORE_HEADER_SIZE);
575
 
576
        *(out) = 40;
577
        *(out + 3) = buf;
578
 
579
        res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
770 user890104 580
    }
898 user890104 581
    else {
582
        data_length = EMCORE_HEADER_SIZE + str_length;
583
 
584
        out = calloc(sizeof(char), data_length);
770 user890104 585
 
898 user890104 586
        *(out) = 40;
587
 
588
        strncpy(((char *)(out + 4)), path, str_length - 1);
589
 
590
        res = emcore_monitor_command(out, in, data_length, 16);
591
    }
770 user890104 592
 
898 user890104 593
    if (res != EMCORE_SUCCESS) {
770 user890104 594
        return res;
595
    }
596
 
898 user890104 597
    if (in[1] > 0x80000000) {
770 user890104 598
        return EMCORE_ERROR_IO;
599
    }
600
 
601
    return EMCORE_SUCCESS;
602
}
603
 
898 user890104 604
int32_t emcore_file_rename(const char *path, const char *newpath) {
605
    // TODO: currently, calling file_rename crashes the emCORE kernel
606
    return EMCORE_ERROR_NOT_IMPLEMENTED;
770 user890104 607
 
898 user890104 608
    int32_t res;
609
    uint32_t in[4], out[4] = { 41, 0, 0xdeadbeef, 0xdeadbeef }, buf;
610
    void *data;
611
    size_t obytes, nbytes;
612
 
613
    obytes = strlen(path) + 1;
614
    nbytes = strlen(newpath) + 1;
615
 
616
    res = emcore_malloc(&buf, obytes + nbytes);
617
 
618
    if (res != EMCORE_SUCCESS) {
619
        return res;
770 user890104 620
    }
621
 
898 user890104 622
    data = calloc(sizeof(char), obytes + nbytes);
770 user890104 623
 
898 user890104 624
    strcpy(data, path);
625
    strcpy(data + obytes, newpath);
626
 
627
    res = emcore_write(data, buf, obytes + nbytes);
628
 
629
    free(data);
630
 
631
    if (res != EMCORE_SUCCESS) {
632
        return res;
770 user890104 633
    }
634
 
898 user890104 635
    out[2] = buf;
636
    out[3] = buf + obytes;
637
 
638
    res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
770 user890104 639
 
898 user890104 640
    if (res != EMCORE_SUCCESS) {
641
        return res;
642
    }
770 user890104 643
 
898 user890104 644
    res = emcore_free(buf);
770 user890104 645
 
898 user890104 646
    if (res != EMCORE_SUCCESS) {
770 user890104 647
        return res;
648
    }
649
 
898 user890104 650
    if (in[1] > 0x80000000) {
770 user890104 651
        return EMCORE_ERROR_IO;
652
    }
653
 
654
    return EMCORE_SUCCESS;
655
}
656
 
898 user890104 657
int32_t emcore_dir_open(uint32_t *handle, const char *name) {
658
    int32_t res;
659
    uint32_t str_length, data_length, in[4], *out;
660
 
661
    str_length = strlen(name) + 1;
662
 
663
    if (str_length > 48) {
664
        uint32_t buf = 0;
665
 
666
        res = emcore_malloc(&buf, str_length);
667
 
668
        if (res != EMCORE_SUCCESS) {
669
            return res;
670
        }
671
 
672
        res = emcore_write(name, buf, str_length);
673
 
674
        if (res != EMCORE_SUCCESS) {
675
            return res;
676
        }
677
 
678
        out = calloc(sizeof(char), EMCORE_HEADER_SIZE);
770 user890104 679
 
898 user890104 680
        *(out) = 42;
681
        *(out + 3) = buf;
682
 
683
        res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
684
    }
685
    else {
686
        data_length = EMCORE_HEADER_SIZE + str_length;
687
 
688
        out = calloc(sizeof(char), data_length);
770 user890104 689
 
898 user890104 690
        *(out) = 42;
691
 
692
        strncpy(((char *)(out + 4)), name, str_length - 1);
693
 
694
        res = emcore_monitor_command(out, in, data_length, 16);
695
    }
770 user890104 696
 
898 user890104 697
    if (res != EMCORE_SUCCESS) {
770 user890104 698
        return res;
699
    }
898 user890104 700
 
701
    if (in[1] > 0x80000000) {
702
        return EMCORE_ERROR_IO;
703
    }
704
 
770 user890104 705
    *handle = in[1];
706
 
707
    return EMCORE_SUCCESS;
708
}
709
 
898 user890104 710
int32_t emcore_dir_read(struct emcore_dir_entry *entry, uint32_t handle) {
711
    int32_t res;
770 user890104 712
    uint32_t maxpath, ptr, dirent_size, emcore_errno_value, filename_buf_len,
713
        out[4] = { 43, 0xdeadbeef, 0, 0 }, in[4];
714
    void *buf;
715
 
716
    memset(entry, 0, sizeof(*entry));
717
 
718
    out[1] = handle;
719
 
720
    res = emcore_monitor_command(out, in, 16, 16);
721
 
898 user890104 722
    if (res != EMCORE_SUCCESS) {
770 user890104 723
        return res;
724
    }
725
 
726
    ptr = in[3];
727
 
898 user890104 728
    if (!ptr) {
770 user890104 729
        res = emcore_errno(&emcore_errno_value);
730
 
898 user890104 731
        if (res != EMCORE_SUCCESS) {
770 user890104 732
            return res;
733
        }
782 user890104 734
 
898 user890104 735
        if (emcore_errno_value != EMCORE_SUCCESS && emcore_errno_value != 2) {
770 user890104 736
            return EMCORE_ERROR_IO;
737
        }
738
 
739
        return EMCORE_ERROR_NO_MORE_ENTRIES;
740
    }
741
 
898 user890104 742
    if (in[1] != 1) { // version
770 user890104 743
        return EMCORE_ERROR_NOT_IMPLEMENTED;
744
    }
745
 
746
    maxpath = in[2];
747
 
748
    dirent_size = maxpath + 16;
749
 
750
    buf = malloc(dirent_size);
751
 
752
    res = emcore_read(buf, ptr, dirent_size);
753
 
898 user890104 754
    if (res != EMCORE_SUCCESS) {
755
        free(buf);
770 user890104 756
        return res;
757
    }
758
 
898 user890104 759
    filename_buf_len = strlen((char *)buf) + 1;
770 user890104 760
 
761
    entry->name = malloc(filename_buf_len);
762
    strncpy(entry->name, buf, filename_buf_len);
763
    memcpy(&entry->attributes, buf + maxpath, 16);
898 user890104 764
 
765
    free(buf);
770 user890104 766
 
767
#ifdef DEBUG_DIR_ENTRIES
768
    fprintf(stderr, "Read directory entry: %s\n", entry->name);
769
    fprintf(stderr, "Attributes: 0x%08x\n", entry->attributes);
770
    fprintf(stderr, "Size: %d\n", entry->size);
771
    fprintf(stderr, "Start cluster: %d\n", entry->startcluster);
772
    fprintf(stderr, "Last written date: 0x%04x\n", entry->wrtdate);
773
    fprintf(stderr, "Last written time: 0x%04x\n", entry->wrttime);
898 user890104 774
    fprintf(stderr, "Last written TS: %d\n",
775
        fat_time_to_unix_ts(entry->wrttime, entry->wrtdate));
770 user890104 776
#endif
777
    return EMCORE_SUCCESS;
778
}
779
 
898 user890104 780
int32_t emcore_dir_close(uint32_t handle) {
781
    int32_t res;
770 user890104 782
    uint32_t out[4] = { 44, 0xdeadbeef, 0, 0 }, in[4];
783
 
784
    out[1] = handle;
785
 
786
    res = emcore_monitor_command(out, in, 16, 16);
787
 
898 user890104 788
    if (res != EMCORE_SUCCESS) {
770 user890104 789
        return res;
790
    }
791
 
898 user890104 792
    if (in[1] > 0x80000000) {
770 user890104 793
        return EMCORE_ERROR_IO;
794
    }
795
 
796
    return EMCORE_SUCCESS;
797
}
798
 
898 user890104 799
int32_t emcore_dir_close_all(uint32_t *count) {
800
    int32_t res;
770 user890104 801
    uint32_t out[4] = { 45, 0, 0, 0 }, in[4];
802
 
803
    res = emcore_monitor_command(out, in, 16, 16);
804
 
898 user890104 805
    if (res != EMCORE_SUCCESS) {
770 user890104 806
        return res;
807
    }
808
 
898 user890104 809
    if (in[1] > 0x80000000) {
770 user890104 810
        return EMCORE_ERROR_IO;
811
    }
812
 
813
    *count = in[1];
814
 
815
    return EMCORE_SUCCESS;
816
}
817
 
898 user890104 818
int32_t emcore_dir_create(const char *name) {
819
    int32_t res;
782 user890104 820
    uint32_t str_length, data_length, in[4], *out;
821
 
898 user890104 822
    str_length = strlen(name) + 1;
782 user890104 823
 
898 user890104 824
    if (str_length > 48) {
825
        uint32_t buf = 0;
826
 
827
        res = emcore_malloc(&buf, str_length);
828
 
829
        if (res != EMCORE_SUCCESS) {
830
            return res;
831
        }
832
 
833
        res = emcore_write(name, buf, str_length);
834
 
835
        if (res != EMCORE_SUCCESS) {
836
            return res;
837
        }
838
 
839
        out = calloc(sizeof(char), EMCORE_HEADER_SIZE);
840
 
841
        *(out) = 47;
842
        *(out + 3) = buf;
843
 
844
        res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
782 user890104 845
    }
898 user890104 846
    else {
847
        data_length = EMCORE_HEADER_SIZE + str_length;
848
 
849
        out = calloc(sizeof(char), data_length);
782 user890104 850
 
898 user890104 851
        *(out) = 47;
852
 
853
        strncpy(((char *)(out + 4)), name, str_length - 1);
854
 
855
        res = emcore_monitor_command(out, in, data_length, 16);
856
    }
782 user890104 857
 
898 user890104 858
    if (res != EMCORE_SUCCESS) {
782 user890104 859
        return res;
860
    }
861
 
898 user890104 862
    if (in[1] > 0x80000000) {
782 user890104 863
        return EMCORE_ERROR_IO;
864
    }
865
 
866
    return EMCORE_SUCCESS;
867
}
868
 
898 user890104 869
int32_t emcore_dir_remove(const char *name) {
870
    int32_t res;
782 user890104 871
    uint32_t str_length, data_length, in[4], *out;
872
 
898 user890104 873
    str_length = strlen(name) + 1;
782 user890104 874
 
898 user890104 875
    if (str_length > 48) {
876
        uint32_t buf = 0;
877
 
878
        res = emcore_malloc(&buf, str_length);
879
 
880
        if (res != EMCORE_SUCCESS) {
881
            return res;
882
        }
883
 
884
        res = emcore_write(name, buf, str_length);
885
 
886
        if (res != EMCORE_SUCCESS) {
887
            return res;
888
        }
889
 
890
        out = calloc(sizeof(char), EMCORE_HEADER_SIZE);
891
 
892
        *(out) = 48;
893
        *(out + 3) = buf;
894
 
895
        res = emcore_monitor_command(out, in, EMCORE_HEADER_SIZE, 16);
782 user890104 896
    }
898 user890104 897
    else {
898
        data_length = EMCORE_HEADER_SIZE + str_length;
899
 
900
        out = calloc(sizeof(char), data_length);
782 user890104 901
 
898 user890104 902
        *(out) = 48;
903
 
904
        strncpy(((char *)(out + 4)), name, str_length - 1);
905
 
906
        res = emcore_monitor_command(out, in, data_length, 16);
907
    }
782 user890104 908
 
898 user890104 909
    if (res != EMCORE_SUCCESS) {
782 user890104 910
        return res;
911
    }
912
 
898 user890104 913
    if (in[1] > 0x80000000) {
782 user890104 914
        return EMCORE_ERROR_IO;
915
    }
916
 
917
    return EMCORE_SUCCESS;
918
}
919
 
898 user890104 920
int32_t emcore_errno(uint32_t *emcore_errno_value) {
921
    int32_t res;
770 user890104 922
    uint32_t out[4] = { 49, 0, 0, 0 }, in[4];
923
 
924
    res = emcore_monitor_command(out, in, 16, 16);
925
 
898 user890104 926
    if (res != EMCORE_SUCCESS) {
770 user890104 927
        return res;
928
    }
929
 
930
    *emcore_errno_value = in[1];
931
 
932
    return EMCORE_SUCCESS;
933
}
934
 
898 user890104 935
int32_t emcore_malloc(uint32_t *ptr, uint32_t size) {
936
    int32_t res;
770 user890104 937
    uint32_t out[4] = { 52, 0xdeadbeef, 0, 0 }, in[4];
938
 
939
    out[1] = size;
940
 
941
    res = emcore_monitor_command(out, in, 16, 16);
942
 
898 user890104 943
    if (res != EMCORE_SUCCESS) {
770 user890104 944
        return res;
945
    }
946
 
947
    *ptr = in[1];
948
 
949
    return EMCORE_SUCCESS;
950
}
951
 
898 user890104 952
int32_t emcore_memalign(uint32_t *ptr, uint32_t align, uint32_t size) {
953
    int32_t res;
770 user890104 954
    uint32_t out[4] = { 53, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
955
 
956
    out[1] = align;
957
    out[2] = size;
958
 
959
    res = emcore_monitor_command(out, in, 16, 16);
960
 
898 user890104 961
    if (res != EMCORE_SUCCESS) {
770 user890104 962
        return res;
963
    }
964
 
965
    *ptr = in[1];
966
 
967
    return EMCORE_SUCCESS;
968
}
969
 
898 user890104 970
int32_t emcore_realloc(uint32_t *new_ptr, uint32_t ptr, uint32_t size) {
971
    int32_t res;
770 user890104 972
    uint32_t out[4] = { 54, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
973
 
974
    out[1] = ptr;
975
    out[2] = size;
976
 
977
    res = emcore_monitor_command(out, in, 16, 16);
978
 
898 user890104 979
    if (res != EMCORE_SUCCESS) {
770 user890104 980
        return res;
981
    }
982
 
983
    *new_ptr = in[1];
984
 
985
    return EMCORE_SUCCESS;
986
}
987
 
898 user890104 988
int32_t emcore_reownalloc(uint32_t ptr, uint32_t owner) {
770 user890104 989
    uint32_t out[4] = { 55, 0xdeadbeef, 0xdeadbeef, 0 }, in[4];
990
 
991
    out[1] = ptr;
992
    out[2] = owner;
993
 
994
    return emcore_monitor_command(out, in, 16, 16);
995
}
996
 
898 user890104 997
int32_t emcore_free(uint32_t ptr) {
770 user890104 998
    uint32_t out[4] = { 56, 0xdeadbeef, 0, 0 }, in[4];
999
 
1000
    out[1] = ptr;
1001
 
1002
    return emcore_monitor_command(out, in, 16, 16);
1003
}
1004
 
898 user890104 1005
int32_t emcore_free_all(void) {
770 user890104 1006
    uint32_t out[4] = { 57, 0, 0, 0 }, in[4];
1007
 
1008
    return emcore_monitor_command(out, in, 16, 16);
1009
}
1010
 
898 user890104 1011
int32_t emcore_ls(uint32_t handle) {
1012
    uint32_t res = 0;
770 user890104 1013
    struct emcore_dir_entry entry;
1014
 
898 user890104 1015
    while (1) {
770 user890104 1016
        res = emcore_dir_read(&entry, handle);
1017
 
898 user890104 1018
        if (res == EMCORE_ERROR_NO_MORE_ENTRIES) {
770 user890104 1019
            res = EMCORE_SUCCESS;
1020
            break;
1021
        }
1022
 
898 user890104 1023
        if (res != EMCORE_SUCCESS) {
770 user890104 1024
            return res;
1025
        }
1026
 
1027
#ifdef DEBUG_DIR_ENTRIES
1028
        fprintf(stderr, "Read directory entry:\n");
1029
        fprintf(stderr, "Name: %s\n", entry.name);
1030
        fprintf(stderr, "Attributes: 0x%08x\n", entry.attributes);
1031
        fprintf(stderr, "Size: %d\n", entry.size);
1032
        fprintf(stderr, "Start cluster: %d\n", entry.startcluster);
1033
        fprintf(stderr, "Last written date: 0x%04x\n", entry.wrtdate);
1034
        fprintf(stderr, "Last written time: 0x%04x\n", entry.wrttime);
898 user890104 1035
        fprintf(stderr, "Last written TS: %d\n",
1036
            fat_time_to_unix_ts(entry.wrttime, entry.wrtdate));
770 user890104 1037
#endif
898 user890104 1038
        if (entry.attributes & 0x10) {
770 user890104 1039
            printf("     [DIR]");
1040
        }
898 user890104 1041
        else {
770 user890104 1042
            printf("%10d", entry.size);
1043
        }
1044
 
1045
        printf(" %s\n", entry.name);
1046
    }
1047
 
1048
    return res;
1049
}