


=====================================================
[color=#0000FF]Итак, первый[/color].
[color=#0000FF]The Bootblock checksum algorithm follows :[/color]
* in 68000 assembler :
[code]
lea bootbuffer,a0
move.l a0,a1
clr.l 4(a1) ;clear the checksum
move.w #(BOOTBLOCKSIZE/4)-1,d1 ;for floppy disks = 1024
;for hd = (DosEnvVec->Bootblocks * BSIZE)
moveq #0,d0
lpchk: add.l (a0)+,d0 ;accumulation
bcc.s jump ;if carry set, add 1 to checksum
add.l #1,d0
jump: dbf d1,lpchk ;next long word
not.l d0
move.l d0,4(a1) ;new checksum
[/code]
* in C (version 1):
[code]#include<limits.h>
#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))
unsigned long newsum,d;
unsigned char buf[BOOTBLOCKSIZE]; /* contains bootblock */
/* for floppy disks = 1024, */
/* for hard disks = (DosEnvVec->Bootblocks * BSIZE) */
int i;
memset(buf+4,0,4); /* clear old checksum */
newsum=0L;
for(i=0; i<BOOTBLOCKSIZE/4; i++) {
d=Long(buf+i*4);
if ( (ULONG_MAX-newsum) < d ) /* overflow */
newsum++;
newsum+=d;
}
newsum=~newsum; /* not */[/code]
* version 2 (From Ralph Babel's 'Install2.c', sent by Hans-Joachim)
[code]unsigned long checksum, precsum;
checksum = 0;
for(i=0; i<BOOTBLOCKSIZE/sizeof(unsigned long); i++) {
precsum = checksum;
if ( (checksum+=Long(buf+i*4)) < precsum) /* better 68000 to C translation of 'bcc' */
++checksum;
}
checksum = ~checksum;[/code]
=========================================================
[color=#0000FF]Второй. [/color]
[color=#0000FF]4.2.3 How to compute the checksum ? [/color]
[code]#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))
unsigned long newsum;
unsigned char buf[BSIZE]; /* contains rootblock */
int i;
memset(buf+20,0,4); /* clear old checksum */
newsum=0L;
for(i=0; i<(BSIZE/4); i++)
newsum+=Long(buf+i*4);
newsum=-newsum; /* negation */
This checksum algorithm works for most block types except for Bootblock.
The bitmap table ('bm_pages[]') stores one or several pointers to Bitmap blocks. The first pointer is at index 0.[/code]
=======================