Участник:Dim568/Silmarils IO DOS

Материал из Old-Games.RU Wiki
Перейти к навигации Перейти к поиску

Header

Base

0 1 2 3 4 5
H0 H1 H2

Extend

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
H3 H4 H5 H6 H7 ?? H9


Logic

Base

/* blancpc.io обрабатывается отдельно от основной логики */
ReadBaseHeader();
int8_t control = (H1 >> 8) & 0xFE8; //старшие 7 бит
if( H2 != 0 ){
  if( control < 0){
    if( control == 0xA0 ){
      /* базовый кейс, часть данных пишется в сегмент кода o_0 */
    }else{  
      /* Нужно найти файлы подходящие под этот кейс */
    }
  }else{
    /* кейс похож на несжатые данные, но под него попадают только monstre.io и telep.io в первой Ishar */
  }
}else{
  /* Кейс похож на хранение системной информации, явный пример main.io */
  ReadExtendedPart();
  if( control < 0){
    if( control == 0xA0 ){
    }else{
    }
  }else{
  }
}


H2 равен 0

Дочитываются дополнительные 16 байт заголовка

uint16_t VAL01 = ((H3/4)+1)*16;
VAL1 += 0; // Нужно проверить, при запуске равен нулю, но бывает ли иным?
uint16_t VAL02 = (H4*6)+VAL01;
uint16_t VAL03 = ES_REG_VAL; // Портит всю малину, нужно понять можно ли без значения регистра
VAL03 += (H7/16)+1
uint16_t VAL04 = VAL03 + (((H9+3)*0x26)/16)+1; // Значение используется в алгоритме когда H2 равен 1, нужно проследить дальше
uint16_t VAL05 = ((H6&0x0F)<<12);
uint16_t VAL06 = H5/16;
VAL05 += VAL06;
uint16_t VAL07 = VAL04 + VAL05;

Заметки на полях

Первая базовая механика

Старшие биты базового слова копируются в младшие биты слова приемника.

Оригинальная реализация
void SilmarilsIORotate(uint16_t* recipient, uint16_t* base, uint8_t count){
  uint32_t  tmp = 0;
  // Input check
  if( recipient == NULL || base == NULL)
    return;
  // Do work
  while(count > 0){
    tmp = (*base)&0x8000;
    (*base)      <<= 1;
    (*recipient) <<= 1;
    if(tmp)
      (*recipient) |= 1;
    count -= 1;
  }
}


Оптимальная реализация для X32
void SilmarilsIORotate(uint16_t* recipient, uint16_t* base, uint8_t count){
  uint32_t  blob = 0;
  // Input check
  if( recipient == NULL || base == NULL)
    return;
  // Make blob
  blob = (uint32_t)((*recipient) << 16) | (uint32_t)*base;
  // Do work
  while(count > 0){
    blob <<= 1;
    count -= 1;
  }
  // Write result
  *recipient = (blob&0xFFFF0000) >> 16;
  *base      = (blob&0x0000FFFF);
}