Beispiel #1
0
// ----------------------------------------------------------------------- //
//
//	ROUTINE:	CTronPlayerObj::Load
//
//	PURPOSE:	Load the object
//
// ----------------------------------------------------------------------- //
void CTronPlayerObj::Load(ILTMessage_Read *pMsg, uint32 dwLoadFlags)
{
	for(int i=0;i<NUM_RATINGS;i++)
	{
		LOAD_BYTE(m_iPerformanceRatings[i]);
	}
	LOAD_BYTE(m_byPSets);
	LOAD_BYTE(m_byOldPSets);
	LOAD_BYTE(m_nArmorPercentage);
	LOAD_WORD(m_nBuildPoints);
	LOAD_WORD(m_nOldBuildPoints);

	CPlayerObj::Load(pMsg, dwLoadFlags);
}
Beispiel #2
0
dword TFDSize(byte *pTFD)
{
  TRACEENTER();

  word                  NrBlocks = 0;
  dword                 i;
  byte                  *p = pTFD;

  if(!pTFD)
  {
    TRACEEXIT();
    return 0;
  }

  if(LOAD_WORD(p) != 8)
  {
    //Invalid header
    TRACEEXIT();
    return 0;
  }

  if(CRC16 (0, p + 4, 6) != LOAD_WORD(p + 2))
  {
    //Invalid header CRC
    TRACEEXIT();
    return 0;
  }

  if(LOAD_WORD(p + 6) != 1)
  {
    //Invalid file version
    TRACEEXIT();
    return 0;
  }

  NrBlocks = LOAD_WORD(p + 8);
  p += 10;
  for(i = 0; i < NrBlocks; i++)
    p += LOAD_WORD(p) + 2;

  TRACEEXIT();
  return p - pTFD;
}
dword UncompressedFirmwareSize (byte *pSrc)
{
  word                  compSize = 0, uncompSize = 0;
  dword                 outSize = 0;

  compSize   = LOAD_WORD(pSrc + 2);
  uncompSize = LOAD_WORD(pSrc + 0);

  while (uncompSize != 0xfefe)
  {
    if (uncompSize > 0x8000) return 0;
    pSrc += (6 + compSize);
    outSize += uncompSize;

    compSize   = LOAD_WORD(pSrc + 2);
    uncompSize = LOAD_WORD(pSrc + 0);
  }

  return outSize;
}
//Every block has the following header:
// 0 - compressed size includeing header (word)
// 2 - CRC-16 (word)
// 4 - block type
// 6 - uncompressed size (word)
// 8 .. (compressed size + 5) - compressed data (byte array)
dword UncompressTFD (byte *pSrc, byte *pDest, void *pPercentFinishedCallback)
{
  word                  compSize = 0, uncompSize = 0, NrBlocks = 0;
  dword                 outSize = 0, i;

  //PercentFinishedCallback is called for every block. PercentFinished contains a number between 0 and 100
  void (*PercentFinishedCallback) (dword PercentFinished) = pPercentFinishedCallback;

  if (LOAD_WORD(pSrc) != 8) return 0;                              //Invalid header?
  if (CRC16 (0, pSrc + 4, 6) != LOAD_WORD(pSrc + 2)) return 0;     //Invalid header CRC?
  if (LOAD_WORD(pSrc + 6) != 1) return 0;                          //Invalid file version?

  NrBlocks = LOAD_WORD(pSrc + 8);

  pSrc += 10;

  for (i = 0; i < NrBlocks; i++)
  {
    if (PercentFinishedCallback) PercentFinishedCallback (i * 100 / NrBlocks);

    compSize   = LOAD_WORD(pSrc) - 6;
    uncompSize = LOAD_WORD(pSrc + 6);

    if (uncompSize > 0x7ffa) return 0;

    pSrc += 8;

    if(compSize == uncompSize)
    {
      // not compressed data, copy it directly
      if (pDest) memcpy(pDest, pSrc, uncompSize);
    }
    else
    {
      // compressed data, uncompress it
      if (!UncompressBlock (pSrc, compSize, pDest, uncompSize)) return 0;
    }

    if (pDest) pDest += uncompSize;
    pSrc += compSize;
    outSize += uncompSize;
  }
  if (PercentFinishedCallback) PercentFinishedCallback (100);

  return outSize;
}
// UncompressFirmware() is a function wrapper that decodes data blocks
// encoded with AR002 algorithm until the uncompressed size field
// is set to 0xfefe. This is normaly used for the Loader or the Firmware
// inside of the flash memory.
// The expected block structure is as follows:
// 0 - uncompressed size (word)
// 2 - compressed size (incl CRC-16) (word)
// 4 - CRC-16 (word)
// 6 .. (compressed size + 5) - compressed data (byte array)
dword UncompressFirmware(byte *pSrc, byte *pDest, void *pPercentFinishedCallback)
{
  TRACEENTER();

  word                  compSize = 0, uncompSize = 0;
  dword                 outSize = 0, NrBlocks = 0, CurrentBlock = 0;
  byte                  *OrigpSrc;

  if(!pSrc || !pDest)
  {
    TRACEEXIT();
    return 0;
  }

  //PercentFinishedCallback is called for every block. PercentFinished contains a number between 0 and 100
  void (*PercentFinishedCallback) (dword PercentFinished) = pPercentFinishedCallback;

  OrigpSrc   = pSrc;
  uncompSize = LOAD_WORD(pSrc + 0);
  compSize   = LOAD_WORD(pSrc + 2);

  //Count the number of blocks
  while(uncompSize != 0xfefe)
  {
    NrBlocks++;

    if(uncompSize > 0x8000)
    {
      //Uncompressed data block size too large
      TRACEEXIT();

      return 0;
    }

    pSrc += 4;
    pSrc += compSize;

    uncompSize = LOAD_WORD(pSrc + 0);
    compSize   = LOAD_WORD(pSrc + 2);
  }

  pSrc = OrigpSrc;
  uncompSize = LOAD_WORD(pSrc + 0);
  compSize   = LOAD_WORD(pSrc + 2);

  while(uncompSize != 0xfefe)
  {
    if(PercentFinishedCallback) PercentFinishedCallback(CurrentBlock * 100 / NrBlocks);
    CurrentBlock++;

    if(uncompSize > 0x8000)
    {
      //Uncompressed data block size too large
      TRACEEXIT();

      return 0;
    }

    pSrc += 6;

    if(compSize == uncompSize)
    {
      // data not compressed, copy it directly
      if(pDest) memcpy(pDest, pSrc, uncompSize);
    }
    else
    {
      // compressed data, uncompress it
      if(!UncompressBlock(pSrc, compSize, pDest, uncompSize))
      {
        //Uncompress has failed
        TRACEEXIT();
        return 0;
      }
    }

    if(pDest) pDest += uncompSize;
    pSrc += compSize;
    outSize += uncompSize;

    uncompSize = LOAD_WORD(pSrc + 0);
    compSize   = LOAD_WORD(pSrc + 2);
  }
  if(PercentFinishedCallback) PercentFinishedCallback(100);

  TRACEEXIT();
  return outSize;
}
Beispiel #6
0
/* This function disassembles the opcode at the PC and outputs it in *output */
static void disassemble(char *output, uint8_t *buffer, options_t *options, uint16_t *pc) {
    char opcode_repr[256], hex_dump[256];
    int opcode_idx;
    int len = 0;
    int entry = 0;
    int found = 0;
    uint8_t byte_operand;
    uint16_t word_operand = 0;
    uint16_t current_addr = *pc;
    uint8_t opcode = buffer[current_addr];
    const char *mnemonic;

    opcode_repr[0] = '\0';
    hex_dump[0] = '\0';

    // Linear search for opcode
    for (opcode_idx = 0; opcode_idx < NUMBER_OPCODES; opcode_idx++) {
        if (opcode == g_opcode_table[opcode_idx].number) {
            /* Found the opcode, record its table index */
            found = 1;
            entry = opcode_idx;
        }
    }

    // For opcode not found, terminate early
    if (!found) {
        sprintf(opcode_repr, ".byte $%02X", opcode);
        if (options->hex_output) {
            sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
            sprintf(output, "%-16s%-16s; INVALID OPCODE !!!\n", hex_dump, opcode_repr);
        } else {
            sprintf(hex_dump, "$%04X", current_addr);
            sprintf(output, "%-8s%-16s; INVALID OPCODE !!!\n", hex_dump, opcode_repr);
        }
        return;
    }

    // Opcode found in table: disassemble properly according to addressing mode
    mnemonic = g_opcode_table[entry].mnemonic;

    // Set hex dump to default single address format. Will be overwritten
    // by more complex output in case of hex dump mode enabled
    sprintf(hex_dump, "$%04X", current_addr);

    switch (g_opcode_table[entry].addressing) {
        case IMMED:
            /* Get immediate value operand */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s #$%02X", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case ABSOL:
            /* Get absolute address operand */
            word_operand = LOAD_WORD(buffer, *pc);
            *pc += 2;

            sprintf(opcode_repr, "%s $%02X%02X", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
            }

            break;
        case ZEROP:
            /* Get zero page address */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s $%02X", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case IMPLI:
            sprintf(opcode_repr, "%s", mnemonic);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
            }

            break;
        case INDIA:
            /* Get indirection address */
            word_operand = LOAD_WORD(buffer, *pc);
            *pc += 2;

            sprintf(opcode_repr, "%s ($%02X%02X)", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
            }

            break;
        case ABSIX:
            /* Get base address */
            word_operand = LOAD_WORD(buffer, *pc);
            *pc += 2;

            sprintf(opcode_repr, "%s $%02X%02X,X", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
            }

            break;
        case ABSIY:
            /* Get baser address */
            word_operand = LOAD_WORD(buffer, *pc);
            *pc += 2;

            sprintf(opcode_repr, "%s $%02X%02X,Y", mnemonic, HIGH_PART(word_operand), LOW_PART(word_operand));
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X%02X:", current_addr, opcode, LOW_PART(word_operand), HIGH_PART(word_operand));
            }

            break;
        case ZEPIX:
            /* Get zero-page base address */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s $%02X,X", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case ZEPIY:
            /* Get zero-page base address */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s $%02X,Y", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case INDIN:
            /* Get zero-page base address */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s ($%02X,X)", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case ININD:
            /* Get zero-page base address */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            sprintf(opcode_repr, "%s ($%02X),Y", mnemonic, byte_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case RELAT:
            /* Get relative modifier */
            byte_operand = buffer[*pc + 1];
            *pc += 1;

            // Compute displacement from first byte after full instruction.
            word_operand = current_addr + 2;
            if (byte_operand > 0x7Fu) {
                word_operand -= ((~byte_operand & 0x7Fu) + 1);
            } else {
                word_operand += byte_operand & 0x7Fu;
            }

            sprintf(opcode_repr, "%s $%04X", mnemonic, word_operand);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X %02X:", current_addr, opcode, byte_operand);
            }

            break;
        case ACCUM:
            sprintf(opcode_repr, "%s A", mnemonic);
            if (options->hex_output) {
                sprintf(hex_dump, "$%04X> %02X:", current_addr, opcode);
            }

            break;
        default:
            // Will not happen since each entry in opcode_table has address mode set
            break;
    }

    // Emit disassembly line content, prior to annotation comments
    len = sprintf(output, DUMP_FORMAT, hex_dump, opcode_repr);
    output += len;

    /* Add cycle count if necessary */
    if (options->cycle_counting) {
        output = append_cycle(output, entry, *pc + 1, word_operand);
    }

    /* Add NES port info if necessary */
    switch (g_opcode_table[entry].addressing) {
        case ABSOL:
        case ABSIX:
        case ABSIY:
            if (options->nes_mode) {
                append_nes(output, word_operand);
            }
            break;
        default:
            /* Other addressing modes: not enough info to add NES register annotation */
            break;
    }
}