Example #1
0
uint32_t crc32_calculate(const uint8_t *data, size_t length)
{
   size_t i;
   uint32_t checksum = ~0;
   for (i = 0; i < length; i++)
      checksum = crc32_adjust(checksum, data[i]);
   return ~checksum;
}
Example #2
0
void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
  mode = cartridge_mode;
  region = Region::NTSC;
  ram_size = 0;
  spc7110_data_rom_offset = 0x100000;
  st_A_ram_size = 0;
  st_B_ram_size = 0;
  supergameboy_version = SuperGameBoyVersion::Version1;
  supergameboy_ram_size = 0;
  supergameboy_rtc_size = 0;

  has_bsx_slot   = false;
  has_superfx    = false;
  has_sa1        = false;
  has_necdsp     = false;
  has_srtc       = false;
  has_sdd1       = false;
  has_spc7110    = false;
  has_spc7110rtc = false;
  has_cx4        = false;
  has_obc1       = false;
  has_st0018     = false;
  has_msu1       = false;
  has_serial     = false;

  parse_xml(xml_list);
//print(xml_list[0], "\n\n");

  if(ram_size > 0) {
    memory::cartram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
  }

  if(has_srtc || has_spc7110rtc) {
    memory::cartrtc.map(allocate<uint8_t>(20, 0xff), 20);
  }

  if(mode == Mode::Bsx) {
    memory::bsxram.map (allocate<uint8_t>( 32 * 1024, 0xff),  32 * 1024);
    memory::bsxpram.map(allocate<uint8_t>(512 * 1024, 0xff), 512 * 1024);
  }

  if(mode == Mode::SufamiTurbo) {
    if(st_A_ram_size) memory::stAram.map(allocate<uint8_t>(st_A_ram_size, 0xff), st_A_ram_size);
    if(st_B_ram_size) memory::stBram.map(allocate<uint8_t>(st_B_ram_size, 0xff), st_B_ram_size);
  }

  if(mode == Mode::SuperGameBoy) {
    if(memory::gbrom.data()) {
      if(supergameboy_ram_size) memory::gbram.map(allocate<uint8_t>(supergameboy_ram_size, 0xff), supergameboy_ram_size);
      if(supergameboy_rtc_size) memory::gbrtc.map(allocate<uint8_t>(supergameboy_rtc_size, 0x00), supergameboy_rtc_size);
    }
  }

  memory::cartrom.write_protect(true);
  memory::cartram.write_protect(false);
  memory::cartrtc.write_protect(false);
  memory::bsxflash.write_protect(true);
  memory::bsxram.write_protect(false);
  memory::bsxpram.write_protect(false);
  memory::stArom.write_protect(true);
  memory::stAram.write_protect(false);
  memory::stBrom.write_protect(true);
  memory::stBram.write_protect(false);
  memory::gbrom.write_protect(true);
  memory::gbram.write_protect(false);
  memory::gbrtc.write_protect(false);

  unsigned checksum = ~0;                                           foreach(n, memory::cartrom ) checksum = crc32_adjust(checksum, n);
  if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0) foreach(n, memory::bsxflash) checksum = crc32_adjust(checksum, n);
  if(memory::stArom.size()   != 0 && memory::stArom.size()   != ~0) foreach(n, memory::stArom  ) checksum = crc32_adjust(checksum, n);
  if(memory::stBrom.size()   != 0 && memory::stBrom.size()   != ~0) foreach(n, memory::stBrom  ) checksum = crc32_adjust(checksum, n);
  if(memory::gbrom.size()    != 0 && memory::gbrom.size()    != ~0) foreach(n, memory::gbrom   ) checksum = crc32_adjust(checksum, n);
  crc32 = ~checksum;

  sha256_ctx sha;
  uint8_t shahash[32];
  sha256_init(&sha);
  sha256_chunk(&sha, memory::cartrom.data(), memory::cartrom.size());
  sha256_final(&sha);
  sha256_hash(&sha, shahash);

  string hash;
  foreach(n, shahash) hash << hex<2>(n);
  sha256 = hash;

  bus.load_cart();
  system.serialize_init();
  loaded = true;
}
Example #3
0
void Cartridge::load(Mode cartridge_mode) {
  mode = cartridge_mode;
  read_header(memory::cartrom.data(), memory::cartrom.size());

  if(ram_size > 0) {
    memory::cartram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
  }

  if(has_srtc || has_spc7110rtc) {
    memory::cartrtc.map(allocate<uint8_t>(20, 0xff), 20);
  }

  if(mode == ModeBsx) {
    memory::bsxram.map (allocate<uint8_t>( 32 * 1024, 0xff),  32 * 1024);
    memory::bsxpram.map(allocate<uint8_t>(512 * 1024, 0xff), 512 * 1024);
  }

  if(mode == ModeSufamiTurbo) {
    if(memory::stArom.data()) memory::stAram.map(allocate<uint8_t>(128 * 1024, 0xff), 128 * 1024);
    if(memory::stBrom.data()) memory::stBram.map(allocate<uint8_t>(128 * 1024, 0xff), 128 * 1024);
  }

  if(mode == ModeSuperGameBoy) {
    if(memory::gbrom.data()) {
      unsigned ram_size = gameboy_ram_size();
      unsigned rtc_size = gameboy_rtc_size();

      if(ram_size) memory::gbram.map(allocate<uint8_t>(ram_size, 0xff), ram_size);
      if(rtc_size) memory::gbrtc.map(allocate<uint8_t>(rtc_size, 0x00), rtc_size);
    }
  }

  memory::cartrom.write_protect(true);
  memory::cartram.write_protect(false);
  memory::cartrtc.write_protect(false);
  memory::bsxflash.write_protect(true);
  memory::bsxram.write_protect(false);
  memory::bsxpram.write_protect(false);
  memory::stArom.write_protect(true);
  memory::stAram.write_protect(false);
  memory::stBrom.write_protect(true);
  memory::stBram.write_protect(false);
  memory::gbrom.write_protect(true);
  memory::gbram.write_protect(false);
  memory::gbrtc.write_protect(false);

  unsigned checksum = ~0;
  for(unsigned n = 0; n < memory::cartrom.size(); n++) checksum = crc32_adjust(checksum, memory::cartrom[n]);
  if(memory::bsxflash.size() != 0 && memory::bsxflash.size() != ~0)
  for(unsigned n = 0; n < memory::bsxflash.size(); n++) checksum = crc32_adjust(checksum, memory::bsxflash[n]);
  if(memory::stArom.size() != 0 && memory::stArom.size() != ~0)
  for(unsigned n = 0; n < memory::stArom.size(); n++) checksum = crc32_adjust(checksum, memory::stArom[n]);
  if(memory::stBrom.size() != 0 && memory::stBrom.size() != ~0)
  for(unsigned n = 0; n < memory::stBrom.size(); n++) checksum = crc32_adjust(checksum, memory::stBrom[n]);
  if(memory::gbrom.size() != 0 && memory::gbrom.size() != ~0)
  for(unsigned n = 0; n < memory::gbrom.size(); n++) checksum = crc32_adjust(checksum, memory::gbrom[n]);
  crc32 = ~checksum;

#if 0
  fprintf(stdout, "crc32  = %.8x\n", (unsigned)crc32);

  sha256_ctx sha;
  uint8_t shahash[32];
  sha256_init(&sha);
  sha256_chunk(&sha, memory::cartrom.data(), memory::cartrom.size());
  sha256_final(&sha);
  sha256_hash(&sha, shahash);

  fprintf(stdout, "sha256 = ");
  for(unsigned i = 0; i < 32; i++) fprintf(stdout, "%.2x", shahash[i]);
  fprintf(stdout, "\n");
#endif

  bus.load_cart();
  system.serialize_init();
  loaded = true;
}
Example #4
0
bool bpslinear::create(const string &filename, const string &metadata) {
  file modifyFile;
  if(modifyFile.open(filename, file::mode::write) == false) return false;

  uint32_t modifyChecksum = ~0;
  unsigned targetRelativeOffset = 0, outputOffset = 0;

  auto write = [&](uint8_t data) {
    modifyFile.write(data);
    modifyChecksum = crc32_adjust(modifyChecksum, data);
  };

  auto encode = [&](uint64_t data) {
    while(true) {
      uint64_t x = data & 0x7f;
      data >>= 7;
      if(data == 0) {
        write(0x80 | x);
        break;
      }
      write(x);
      data--;
    }
  };

  unsigned targetReadLength = 0;

  auto targetReadFlush = [&]() {
    if(targetReadLength) {
      encode(TargetRead | ((targetReadLength - 1) << 2));
      unsigned offset = outputOffset - targetReadLength;
      while(targetReadLength) write(targetData[offset++]), targetReadLength--;
    }
  };

  write('B');
  write('P');
  write('S');
  write('1');

  encode(sourceSize);
  encode(targetSize);

  unsigned markupSize = metadata.length();
  encode(markupSize);
  for(unsigned n = 0; n < markupSize; n++) write(metadata[n]);

  while(outputOffset < targetSize) {
    unsigned sourceLength = 0;
    for(unsigned n = 0; outputOffset + n < min(sourceSize, targetSize); n++) {
      if(sourceData[outputOffset + n] != targetData[outputOffset + n]) break;
      sourceLength++;
    }

    unsigned rleLength = 0;
    for(unsigned n = 1; outputOffset + n < targetSize; n++) {
      if(targetData[outputOffset] != targetData[outputOffset + n]) break;
      rleLength++;
    }

    if(rleLength >= 4) {
      //write byte to repeat
      targetReadLength++;
      outputOffset++;
      targetReadFlush();

      //copy starting from repetition byte
      encode(TargetCopy | ((rleLength - 1) << 2));
      unsigned relativeOffset = (outputOffset - 1) - targetRelativeOffset;
      encode(relativeOffset << 1);
      outputOffset += rleLength;
      targetRelativeOffset = outputOffset - 1;
    } else if(sourceLength >= 4) {
      targetReadFlush();
      encode(SourceRead | ((sourceLength - 1) << 2));
      outputOffset += sourceLength;
    } else {
      targetReadLength += Granularity;
      outputOffset += Granularity;
    }
  }

  targetReadFlush();

  uint32_t sourceChecksum = crc32_calculate(sourceData, sourceSize);
  for(unsigned n = 0; n < 32; n += 8) write(sourceChecksum >> n);
  uint32_t targetChecksum = crc32_calculate(targetData, targetSize);
  for(unsigned n = 0; n < 32; n += 8) write(targetChecksum >> n);
  uint32_t outputChecksum = ~modifyChecksum;
  for(unsigned n = 0; n < 32; n += 8) write(outputChecksum >> n);

  modifyFile.close();
  return true;
}
Example #5
0
File: delta.hpp Project: ARM9/bass
bool bpsdelta::create(const string& filename, const string& metadata) {
  file modifyFile;
  if(modifyFile.open(filename, file::mode::write) == false) return false;

  uint32_t sourceChecksum = ~0, modifyChecksum = ~0;
  unsigned sourceRelativeOffset = 0, targetRelativeOffset = 0, outputOffset = 0;

  auto write = [&](uint8_t data) {
    modifyFile.write(data);
    modifyChecksum = crc32_adjust(modifyChecksum, data);
  };

  auto encode = [&](uint64_t data) {
    while(true) {
      uint64_t x = data & 0x7f;
      data >>= 7;
      if(data == 0) {
        write(0x80 | x);
        break;
      }
      write(x);
      data--;
    }
  };

  write('B');
  write('P');
  write('S');
  write('1');

  encode(sourceSize);
  encode(targetSize);

  unsigned markupSize = metadata.length();
  encode(markupSize);
  for(unsigned n = 0; n < markupSize; n++) write(metadata[n]);

  Node* sourceTree[65536];
  Node* targetTree[65536];
  for(unsigned n = 0; n < 65536; n++) sourceTree[n] = nullptr, targetTree[n] = nullptr;

  //source tree creation
  for(unsigned offset = 0; offset < sourceSize; offset++) {
    uint16_t symbol = sourceData[offset + 0];
    sourceChecksum = crc32_adjust(sourceChecksum, symbol);
    if(offset < sourceSize - 1) symbol |= sourceData[offset + 1] << 8;
    Node *node = new Node;
    node->offset = offset;
    node->next = sourceTree[symbol];
    sourceTree[symbol] = node;
  }

  unsigned targetReadLength = 0;

  auto targetReadFlush = [&]() {
    if(targetReadLength) {
      encode(TargetRead | ((targetReadLength - 1) << 2));
      unsigned offset = outputOffset - targetReadLength;
      while(targetReadLength) write(targetData[offset++]), targetReadLength--;
    }
  };

  while(outputOffset < targetSize) {
    unsigned maxLength = 0, maxOffset = 0, mode = TargetRead;

    uint16_t symbol = targetData[outputOffset + 0];
    if(outputOffset < targetSize - 1) symbol |= targetData[outputOffset + 1] << 8;

    { //source read
      unsigned length = 0, offset = outputOffset;
      while(offset < sourceSize && offset < targetSize && sourceData[offset] == targetData[offset]) {
        length++;
        offset++;
      }
      if(length > maxLength) maxLength = length, mode = SourceRead;
    }

    { //source copy
      Node* node = sourceTree[symbol];
      while(node) {
        unsigned length = 0, x = node->offset, y = outputOffset;
        while(x < sourceSize && y < targetSize && sourceData[x++] == targetData[y++]) length++;
        if(length > maxLength) maxLength = length, maxOffset = node->offset, mode = SourceCopy;
        node = node->next;
      }
    }

    { //target copy
      Node* node = targetTree[symbol];
      while(node) {
        unsigned length = 0, x = node->offset, y = outputOffset;
        while(y < targetSize && targetData[x++] == targetData[y++]) length++;
        if(length > maxLength) maxLength = length, maxOffset = node->offset, mode = TargetCopy;
        node = node->next;
      }

      //target tree append
      node = new Node;
      node->offset = outputOffset;
      node->next = targetTree[symbol];
      targetTree[symbol] = node;
    }

    { //target read
      if(maxLength < 4) {
        maxLength = min((unsigned)Granularity, targetSize - outputOffset);
        mode = TargetRead;
      }
    }

    if(mode != TargetRead) targetReadFlush();

    switch(mode) {
    case SourceRead:
      encode(SourceRead | ((maxLength - 1) << 2));
      break;
    case TargetRead:
      //delay write to group sequential TargetRead commands into one
      targetReadLength += maxLength;
      break;
    case SourceCopy:
    case TargetCopy:
      encode(mode | ((maxLength - 1) << 2));
      signed relativeOffset;
      if(mode == SourceCopy) {
        relativeOffset = maxOffset - sourceRelativeOffset;
        sourceRelativeOffset = maxOffset + maxLength;
      } else {
        relativeOffset = maxOffset - targetRelativeOffset;
        targetRelativeOffset = maxOffset + maxLength;
      }
      encode((relativeOffset < 0) | (abs(relativeOffset) << 1));
      break;
    }

    outputOffset += maxLength;
  }

  targetReadFlush();

  sourceChecksum = ~sourceChecksum;
  for(unsigned n = 0; n < 32; n += 8) write(sourceChecksum >> n);
  uint32_t targetChecksum = crc32_calculate(targetData, targetSize);
  for(unsigned n = 0; n < 32; n += 8) write(targetChecksum >> n);
  uint32_t outputChecksum = ~modifyChecksum;
  for(unsigned n = 0; n < 32; n += 8) write(outputChecksum >> n);

  modifyFile.close();
  return true;
}
Example #6
0
 void write(uint8_t data) {
   fp.write(data);
   checksum = crc32_adjust(checksum, data);
 }