コード例 #1
0
ファイル: G64Archive.cpp プロジェクト: DNSGeek/virtualc64
int
G64Archive::getStartOfItem(int n)
{
    if (n < 0 || n >= 84)
        return -1;
    
    int offset = 0x00C + (4 * n);
    return LO_LO_HI_HI(data[offset], data[offset+1], data[offset+2], data[offset+3]);
}
コード例 #2
0
ファイル: T64File.cpp プロジェクト: dirkwhoffmann/virtualc64
void
T64File::seekItem(long offset)
{
    size_t i = 0x48 + (selectedItem * 0x20);

    // Move file pointer the the start of the selected item + offset
    iFp = LO_LO_HI_HI(data[i], data[i+1], data[i+2], data[i+3]) + offset;

    // Invalidate file pointer if it is out of range
    if (iFp > size)
        iFp = -1;
}
コード例 #3
0
ファイル: TAPFile.cpp プロジェクト: dirkwhoffmann/virtualc64
bool
TAPFile::readFromBuffer(const uint8_t *buffer, size_t length)
{
    if (!AnyC64File::readFromBuffer(buffer, length))
        return false;
    
    int l = LO_LO_HI_HI(data[0x10], data[0x11], data[0x12], data[0x13]);
    if (l + 0x14 /* Header */ != size) {
        warn("Size mismatch! Archive should have %d data bytes, found %d\n", l, size - 0x14);
    }
        
    return true;
}
コード例 #4
0
void 
T64Archive::selectItem(int n)
{
	unsigned i;
    
    if (n < getNumberOfItems()) {

        // Compute start address in container
        i = 0x48 + (n * 0x20);
        if ((fp = LO_LO_HI_HI(data[i], data[i+1], data[i+2], data[i+3])) >= size)
            fprintf(stderr, "PANIC! fp is out of bounds!\n");

        // Compute start address in memory
        i = 0x42 + (n * 0x20);
        uint16_t startAddrInMemory = LO_HI(data[i], data[i+1]);
        
        // Compute end address in memory
        i = 0x44 + (n * 0x20);
        uint16_t endAddrInMemory = LO_HI(data[i], data[i+1]);

        if (endAddrInMemory == 0xC3C6) {
            fprintf(stderr, "WARNING: Corrupted archive. Mostly likely created with CONV64!\n");
            // WHAT DO WE DO ABOUT IT?
        }

        // Compute size of item
        uint16_t length = endAddrInMemory - startAddrInMemory;

        // fprintf(stderr, "start = %d end = %d diff = %d\n", startAddrInMemory, endAddrInMemory, length);
        // fprintf(stderr, "fp = %d fp_eof = %d\n", fp, fp_eof);

        // Store largest offset that belongs to the file
        if ((fp_eof = fp + length) > size)
            fprintf(stderr, "PANIC! fp_eof is out of bounds!\n");
        
        // Return if offset values are safe
        if (fp < size && fp_eof <= size)
            return; // success
    }

    fp = fp_eof = -1; // fail
	return;
}
コード例 #5
0
ファイル: Datasette.cpp プロジェクト: DNSGeek/virtualc64
int
Datasette::pulseLength(int *skip)
{
    assert(head < size);

    if (data[head] != 0) {
        // Pulse lengths between 1 * 8 and 255 * 8
        if (skip) *skip = 1;
        return 8 * data[head];
    }
    
    if (type == 0) {
        // Pulse lengths greater than 8 * 255 (TAP V0 files)
        if (skip) *skip = 1;
        return 8 * 256;
    } else {
        // Pulse lengths greater than 8 * 255 (TAP V1 files)
        if (skip) *skip = 4;
        return  LO_LO_HI_HI(data[head+1], data[head+2], data[head+3], 0);
    }
}
コード例 #6
0
ファイル: T64File.cpp プロジェクト: dirkwhoffmann/virtualc64
void
T64File::selectItem(unsigned item)
{
    // Invalidate the file pointer if a non-existing item is requested.
    if (item >= numberOfItems()) {
        iFp = -1;
        return;
    }
    
    // Remember the selection
    selectedItem = item;
    
    // Set file pointer and end of file index
    unsigned i = 0x48 + (item * 0x20);
    iFp = LO_LO_HI_HI(data[i], data[i+1], data[i+2], data[i+3]);
    iEof = iFp + getSizeOfItem();
    
    // Check for inconsistent values. As all inconsistencies should have
    // been ruled out by repair(), the if condition should never hit.
    if (iFp > size || iEof > size) {
        assert(false);
    }
}
コード例 #7
0
ファイル: T64File.cpp プロジェクト: dirkwhoffmann/virtualc64
bool
T64File::repair()
{
    unsigned i, n;
    uint16_t noOfItems = numberOfItems();

    //
    // 1. Repair number of items, if this value is zero
    //
    
    if (noOfItems == 0) {

        while (directoryItemIsPresent(noOfItems))
            noOfItems++;

        uint16_t noOfItemsStatedInHeader = numberOfItems();
        if (noOfItems != noOfItemsStatedInHeader) {
        
            debug(1, "Repairing corrupted T64 archive: Changing number of items from %d to %d.\n",
                  noOfItemsStatedInHeader, noOfItems);
        
            data[0x24] = LO_BYTE(noOfItems);
            data[0x25] = HI_BYTE(noOfItems);
            
        }
        assert(noOfItems == numberOfItems());
    }
    
    for (i = 0; i < noOfItems; i++) {

        //
        // 2. Check relative offset information for each item
        //

        // Compute start address in file
        n = 0x48 + (i * 0x20);
        uint16_t startAddrInContainer = LO_LO_HI_HI(data[n], data[n+1], data[n+2], data[n+3]);

        if (startAddrInContainer >= size) {
            warn("T64 archive is corrupt (offset mismatch). Sorry, can't repair.\n");
            return false;
        }
    
        //
        // 3. Check for file end address mismatches (as created by CONVC64)
        //
        
        // Compute start address in memory
        n = 0x42 + (i * 0x20);
        uint16_t startAddrInMemory = LO_HI(data[n], data[n+1]);
    
        // Compute end address in memory
        n = 0x44 + (i * 0x20);
        uint16_t endAddrInMemory = LO_HI(data[n], data[n+1]);
    
        if (endAddrInMemory == 0xC3C6) {

            // Let's assume that the rest of the file data belongs to this file ...
            uint16_t fixedEndAddrInMemory = startAddrInMemory + (size - startAddrInContainer);

            debug(1, "Repairing corrupted T64 archive: Changing end address of item %d from %04X to %04X.\n",
                  i, endAddrInMemory, fixedEndAddrInMemory);

            data[n] = LO_BYTE(fixedEndAddrInMemory);
            data[n+1] = HI_BYTE(fixedEndAddrInMemory);
        }
    }
    
    return 1; // Archive repaired successfully
}