📄 biossum.pas
字号:
{$r-,i-,s-}
{ BIOS checksum utility
(C)2001 Pascal Dornier / PC Engines
This file is licensed pursuant to the COMMON PUBLIC LICENSE Rev. 0.5.
- find _32_ (paragraph aligned), insert checksum byte for 32 bit
PCI BIOS header
- find _DAT (word aligned), insert checksum byte for BIOS read/write
data area
- insert BIOS date
- insert model byte
- insert overall checksum byte
Compile using Borland Pascal 7.0 (older versions likely to work too)
}
uses dos;
const
zero=ord('0');
hx:array[0..15] of char = '0123456789ABCDEF';
type
bios=array[0..$fffe] of byte;
var
b:^bios;
fi:file;
blen:word;
startofs,datofs,pciofs:word;
i:word;
sum:byte;
yy,mm,dd,dw:word;
procedure hexw(i:word);
begin
write(hx[i shr 12],hx[hi(i) and 15],hx[lo(i) shr 4],hx[i and 15]);
end;
begin
if paramcount<>2 then begin
writeln('BIOSSUM usage: BIOSSUM infile outfile');
halt(1);
end;
{ read input file }
new(b);
assign(fi,paramstr(1));
reset(fi,1);
if ioresult<>0 then begin
write('Could not open input file ',paramstr(1));
halt(1);
end;
blockread(fi,b^,sizeof(b^),blen);
close(fi);
if blen<>$fff7 then writeln('Warning: input file length incorrect ?');
{ get start offset }
startofs:=b^[$fff5]+swap(b^[$fff6]); { stored just after the reset vector }
{ find _32_ (paragraph aligned), insert checksum byte for 32 bit
PCI BIOS header }
asm
xor bx,bx { clear offset }
les di,b { pointer to BIOS buffer }
mov di,startofs
db $66 { mov eax,"_32" }
mov ax,$335f
dw $5f32
@l1: db $66 { cmp [di],eax }
cmp [es:di],ax
jz @l2 { :found header }
add di,16 { next paragraph }
jnz @l1 { :keep looking }
jmp @l9 { not found }
@l2: mov bx,di { remember start address }
xor al,al { calculate checksum }
mov cx,10
@l3: add al,[es:di]
inc di
loop @l3
neg al
stosb
@l9: mov pciofs,bx { return offset, 0 if not found }
end;
if pciofs=0 then
writeln('_32_ area not found.')
else begin
write('_32_ area found at '); hexw(pciofs); writeln;
end;
{ find _DAT (word aligned), insert checksum byte for BIOS read/write
data area }
asm
xor bx,bx { clear offset }
les di,b { pointer to BIOS buffer }
mov di,startofs
mov cx,di
neg cx
shr cx,1
mov ax,$445F { _D }
@l1: jcxz @l9 { bail if nothing left }
repnz scasw
jnz @l9 { :not found }
cmp word [es:di],$5441 { AT ? }
jnz @l1 { :keep searching }
lea bx,[di-2] { save offset }
mov cx,[es:di+2] { get byte count }
int 3 {&&&}
add di,4
xor al,al
@l2: add al,[es:di] { calculate checksum }
inc di
loop @l2
neg al { store checksum }
stosb
@l9: mov datofs,bx { return offset, 0 if not found }
end;
if datofs=0 then
writeln('_DAT area not found.')
else begin
write('_DAT area found at '); hexw(datofs); writeln;
end;
{ insert BIOS date }
getdate(yy,mm,dd,dw);
b^[$fff5]:=(mm div 10)+zero;
b^[$fff6]:=(mm mod 10)+zero;
b^[$fff7]:=ord('/');
b^[$fff8]:=(dd div 10)+zero;
b^[$fff9]:=(dd mod 10)+zero;
b^[$fffa]:=ord('/');
b^[$fffb]:=((yy mod 100)div 10)+zero;
b^[$fffc]:=(yy mod 10)+zero;
b^[$fffd]:=$ff;
{ insert AT model byte }
b^[$fffe]:=$fc;
{ calculate overall checksum }
sum:=0;
for i:=startofs to $fffe do
inc(sum,b^[i]);
i:=$ffff;
b^[i]:=-sum;
{ write output file }
assign(fi,paramstr(2));
rewrite(fi,1);
if ioresult<>0 then begin
write('Could not create output file ',paramstr(1));
halt(1);
end;
if startofs=0 then begin
blockwrite(fi,b^[0],$8000); { write 64KB in two pieces }
blockwrite(fi,b^[$8000],$8000);
end else
blockwrite(fi,b^[startofs],$10000-startofs);
if ioresult<>0 then begin
write('Write error !');
halt(1);
end;
close(fi);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -