Контрольная сумма в спецификации BIOS EDD 3.0 - PullRequest
0 голосов
/ 07 сентября 2018

Попытка проверить контрольную сумму параметров привода в соответствии с расширенной спецификацией дисковода версии 3.0 . Но это всегда неправильно в моих расчетах. Считывание параметров привода с функцией INT 13H 48H в порядке, проверено на виртуальной коробке и реальной машине. Документы говорят на странице 9 (конец таблицы 3):

65 - Байт - Контрольная сумма для информации о пути к устройству включает 0BEDDh подпись. 2-е дополнение суммы зачета 30-64. Сумма смещение 30-65 равно 0.

Итак, я получил дамп под моей виртуальной машиной с FreeDos 1.2 и написал для нее простой тест. Вот код и вывод. Что там не так?

void calc_checksum(uint8_t dump[], int dump_size)
{
  uint8_t sum, checksum, cs_from_dump;
  uint16_t real_size;
  int i, data_start, data_end, dump_end;

  // first byte index for checksum as in EDD spec
  data_start = 30; 
  // sizeof drive parameters struct is in first word
  real_size = ((uint16_t*)dump)[0];
  // index of checksum
  dump_end = real_size - 1;
  // index of last data byte
  data_end =  dump_end - 1;
  // read checksum from dump
  cs_from_dump = dump[dump_end];

  puts("dump:");
  print_hex(dump, real_size);
  printf("Calculating checksum for data from %d to %d\n", data_start, data_end);
  printf("Must be %02X\n", cs_from_dump);

  puts("first attempt");
  sum = 0; checksum = 0;
  for (i = data_start; i <= data_end; i++)
    sum += dump[i]; 
  checksum = ~sum + 1;
  printf("sum = %02X\n", sum);
  printf("checksum = %02X\n", checksum);

  puts("second attempt");
  sum = 0; checksum = 0;
  for (i = data_start; i <= data_end; i++)
    sum = (uint8_t)(sum + *(dump + i));
  checksum = (uint8_t)(0x100 - sum);
  printf("sum = %02X\n", sum);
  printf("checksum = %02X\n", checksum);
}

void test_checksum()
{
  uint8_t dump[] = 
  {
    0x42, 0x00, 0x02, 0x00, 0xFF, 0x3F, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x56, 0x03, 0xC0, 0x9F, 0xDD, 0xBE, 
    0x24, 0x00, 0x00, 0x00, 0x49, 0x53, 0x41, 0x00, 0x41, 0x54, 0x41, 0x20, 0x20, 0x20, 0x20, 0x20, 
    0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0xEE, 0xDD 
  };

  calc_checksum(dump, sizeof dump);
}

Выход:

dump:
42 00 02 00 FF 3F 00 00 10 00 00 00 3F 00 00 00 
00 00 40 01 00 00 00 00 00 02 56 03 C0 9F DD BE 
24 00 00 00 49 53 41 00 41 54 41 20 20 20 20 20 
F0 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
EE DD 

Calculating checksum for data from 30 to 64
Must be DD
first attempt
sum = F1
checksum = 0F
second attempt
sum = F1
checksum = 0F
...