fork from va009039/USBLocalFileSystem

Dependencies:   USBDevice

Dependents:   11u35_usbLocalFilesystem

Fork of USBLocalFileSystem by Norimasa Okamoto

src/RamDisk.cpp

Committer:
k4zuki
Date:
2016-03-04
Revision:
11:c396747794c6
Parent:
2:97c314eae8b8

File content as of revision 11:c396747794c6:

#include "RamDisk.h"

#if (DEBUG2 > 3)
#define RAMDISK_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");} while(0);
#else
#define RAMDISK_DBG(...)
#endif

RamDisk::RamDisk(int sectors):_sectors(sectors)
{
    format();
}

/* virtual */ uint32_t RamDisk::storage_sectors()
{
    report_sectors_count++;
    return _sectors;
}

/* virtual */ uint32_t RamDisk::storage_size()
{
    report_size_count++;
    return _sectors * 512;
}

/* virtual */ int RamDisk::storage_read(uint8_t * data, uint32_t block)
{
    RAMDISK_DBG("R block=%d", block);
    report_read_count++;
    memset(data, 0x00, 512);
    if (_sector_image.count(block) > 0) {
        uint8_t* buf = _sector_image[block];
        int size = buf[0]|(buf[1]<<8);
        size &= 0x7fff; // remove ROM area bit
        memcpy(data, buf + 2, size);
    }
    return 0;
}

static int block_size(const uint8_t* data)
{
    for(int i = 512-1; i >= 0; i--) {
        if (data[i] != 0x00) {
            return i+1;
        }
    }
    return 0;
}

/* virtual */ int RamDisk::storage_write(const uint8_t * data, uint32_t block)
{
    report_write_count++;
    int size = block_size(data);
    if (_sector_image.count(block) > 0) {
        uint8_t* buf = _sector_image[block];
        if (!(buf[1] & 0x80)) { // ROM area
            free(buf);
        }
        buf = (uint8_t*)malloc(size + 2);
        if (buf == NULL) {
            RAMDISK_DBG("DISK FULL");
            exit(1);
            return 1;
        }
        _sector_image[block] = buf;
        buf[0] = size;
        buf[1] = size>>8;
        memcpy(buf + 2, data, size);
        RAMDISK_DBG("W block=%d size=%d", (int)block, size);
    } else if (size > 0) {
        uint8_t* buf = (uint8_t*)malloc(size + 2);
        if (buf == NULL) {
            RAMDISK_DBG("DISK FULL");
            exit(1);
            return 1;
        }
        _sector_image[block] = (uint8_t*)buf;
        buf[0] = size;
        buf[1] = size>>8;
        
        memcpy(buf + 2, data, size);
        RAMDISK_DBG("W block=%d size=%d NEW %d", (int)block, size, _sector_image.size());
    } else {
        RAMDISK_DBG("W block=%d BLANK", (int)block);
    }
    return 0;
}

void RamDisk::dump(int mode)
{
    printf("static const uint8_t block_image[] = { // %d blocks\n", _sector_image.size());
    for(int i = 0; i < _sector_image.size(); i++) {
        int block = _sector_image.getKey(i);
        uint8_t* buf = _sector_image[block];
        int size = buf[0]|(buf[1]<<8);
        size &= 0x7fff;
        printf("0x%02x,0x%02x,0x%02x|0x80, // block=%d, size=%d, ROM area\n", 
                                block, buf[0], buf[1], block, size);
        if (mode == 1) {
            for(int j = 0; j < size; j++) {
                printf("0x%02x,", buf[j+2]);
                if ((j % 16) == 15 || j == size-1) {
                    printf("\n");
                }
            }
        }
    }
    printf("0xff};\n");
}