mirror of
https://github.com/stevenhowes/wbios.git
synced 2026-05-26 15:53:34 +01:00
d410ad0acb
Original source https://www.pcengines.ch/file/wbios111s.zip
187 lines
3.8 KiB
ObjectPascal
187 lines
3.8 KiB
ObjectPascal
{$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.
|