Попытка проверить контрольную сумму параметров привода в соответствии с расширенной спецификацией дисковода версии 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