Сообщение от
Vladimir_S
Почитай в Радио 7 1988г.
---------- Post added at 16:12 ---------- Previous post was at 15:59 ----------
Чейто сам прочитал что посоветовал - ахинея какая то. А п/п F82A?
Да, там просто ужас. Лучше примеры. Номер первый - листинг из загрузчика Специалиста (контролька, как известно, у всех одинаковая была):
Код:
ROM:C427 ; =============== S U B R O U T I N E =======================================
ROM:C427
ROM:C427 ; Cравнение HL и DE. Портит [A], выставляет флаги.
ROM:C427
ROM:C427 BIOS_HL_DE_Compare: ; CODE XREF: BIOS_Load_Block_Loop+6p
ROM:C427 ; BIOS_Copy_HL2BC+4p ...
ROM:C427 mov a, h
ROM:C428 cmp d
ROM:C429 rnz
ROM:C42A mov a, l
ROM:C42B cmp e
ROM:C42C ret
ROM:C42C ; End of function BIOS_HL_DE_Compare
ROM:CC89 ; =============== S U B R O U T I N E =======================================
ROM:CC89
ROM:CC89 ; Считает контрольную сумму для блока [HL]..[DE] и возвращает ее в [BC].
ROM:CC89
ROM:CC89 Mon_Count_Check_Sum_J: ; CODE XREF: ROM:Mon_Count_Check_Sumj
ROM:CC89 ; Mon_Command+153p ...
ROM:CC89
ROM:CC89 ; FUNCTION CHUNK AT ROM:CCAB SIZE 00000002 BYTES
ROM:CC89
ROM:CC89 lxi b, 0
ROM:CC8C
ROM:CC8C loc_CC8C: ; CODE XREF: Mon_Count_Check_Sum_J+14j
ROM:CC8C mov a, m
ROM:CC8D add c
ROM:CC8E mov c, a
ROM:CC8F push psw
ROM:CC90 call BIOS_HL_DE_Compare ; Cравнение HL и DE. Портит [A], выставляет флаги.
ROM:CC93 jz loc_CCAB
ROM:CC96 pop psw
ROM:CC97 mov a, b
ROM:CC98 adc m
ROM:CC99 mov b, a
ROM:CC9A call sub_CCA0
ROM:CC9D jmp loc_CC8C
ROM:CCA0 sub_CCA0: ; CODE XREF: Mon_Count_Check_Sum_J+11p
ROM:CCA0 call BIOS_HL_DE_Compare ; Cравнение HL и DE. Портит [A], выставляет флаги.
ROM:CCA3 jnz loc_CCA9
ROM:CCA6 inx sp
ROM:CCA7 inx sp
ROM:CCA8 ret
ROM:CCA9 loc_CCA9: ; CODE XREF: sub_CCA0+3j
ROM:CCA9 inx h
ROM:CCAA ret
ROM:CCAB loc_CCAB: ; CODE XREF: Mon_Count_Check_Sum_J+Aj
ROM:CCAB pop psw
ROM:CCAC ret
ROM:CCAC ; END OF FUNCTION CHUNK FOR Mon_Count_Check_Sum_J
Да, это буйство символов сразу и не понять. И да, вы все правильно поняли: вторая проверка на [HL]=[DE] никогда не сработает. Более того, старший байт контрольки не обновляется на последнем байте. Все это особенности реальной контрольки, применяемой в РК86, Специалисте и Орионе и используемой в дамплистах журнала Радио. Чтобы облегчить вам жизнь, я дам вот такой, полностью рабочий и много лет как проверенный алгоритм на паскале:
Код:
// Вычисление контрольки
// AdrB - начальный адрес в буфере данных
// AdrE - конечный адрес в буфере данных
// Buf[] - буфер данных
function CheckSum(AdrB,AdrE:Word):Word;
Var SumH:Byte; // Старший байт контрольки
SumL:Word; // Младший байт контрольки + перенос
Begin
// Обнулим
SumL:=0; SumH:=0;
// Вечный цикл
while true do begin
// Складываем младшую часть контрольки, сохраняем перенос
SumL:=Lo(SumL)+Buf[AdrB];
// Если достигли конца - выходим из цикла
if AdrB=AdrE then Break;
// Складываем старшую часть контрольки и перенос
SumH:=SumH+Buf[AdrB]+Hi(SumL);
// Увеличиваем адрес
Inc(AdrB);
End;
// Возвращаем контрольку
CheckSum:=SumH*256+Lo(SumL);
End;
Теперь, я думаю все будет понятно. Отмечу лишь то, что у Специалиста контролька идет младшим байтом вперед и сразу же за блоком кодов, а у Ориона она идет после синхробайта и старшим вперед (и ЕМНИП проинвертирована - поправьте если что не так).