TwlToolsRED/build/tools/A9Ovl_Chk/main.~pas

324 lines
12 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

unit main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, FileCtrl, ComCtrls, ShellCtrls, ExtCtrls;
type
TForm1 = class(TForm)
ListBox_log: TListBox;
Button1: TButton;
DriveBox: TDriveComboBox;
DirListBox: TDirectoryListBox;
StatusBar: TStatusBar;
StaticText3: TStaticText;
RG_select: TRadioGroup;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure DriveBoxChange(Sender: TObject);
procedure DirListBoxChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private 宣言 }
function CheckSrlHeader:integer;
public
{ Public 宣言 }
end;
TRom_Fat = record
top:Longword; // file region start
bottom:Longword; // end;
end;
TRomh = record //ROMヘッダ(nitro_romheader.hより)
title: array[1..12] of Char;
game_code: array[1..4] of Char;
//0x10
maker_code: array[1..2] of Byte;
machine_code: Byte;
rom_type: Byte;
rom_size: Byte;
resv_A: array[1..8] of Byte; //Reserve(All 0)
region: Byte;
// b0 = china,b1 = koria
rom_version: Byte;
comp_boot_area: Byte;//b7 =A9,b6=A7
//
// 0x020 for Static modules (Section:B)
//ARM9
A9_main_rom_offset: Longword; // ROM offset
A9_main_entry_address: Longword; // Entry point
A9_main_ram_address: Longword; // RAM address
A9_main_size: Longword; // Module size
//ARM7
A7_main_rom_offset: Longword; // ROM offset
A7_main_entry_address: Longword; // Entry point
A7_main_ram_address: Longword; // RAM address
A7_main_size: Longword; // Module size
//0x40
dumy2:array[1..8] of Byte;//ツールで使用しない部分
//
// 0x048 for File Allocation Table[FAT] (Section:E)
//
fat_offset: Longword; // ROM offset
fat_size:Longword; // Table size
//
// 0x050 for Overlay Tables[OVT] (Section:D)
//
// ARM9
main_ovt_offset: Longword; // ROM offset
main_ovt_size:Longword; // Table size
end;
var
Form1: TForm1;
LogDir,SrlDir: String;//ディレクトリパス
ng_all: longword;//総NGエントリ数
implementation
function TForm1.CheckSrlHeader: integer;
var
Rec: TSearchRec;
sf,s,ss: String;
i,n,Count,err_files,ng_entry: integer;
fsrl: file;
flog:TextFile;
romh: TRomh;
noc_size,noc_sectors,size,sectors,nums,max_sectors,total_sectors: integer;
fat: TRom_Fat;
top,btm,all_sectors: Longword;
ng_flg:boolean;
begin
{$I-}
//ログファイル作成
ListBox_log.Items.Add('Create Log file');
s := ExtractFilePath(Application.Exename)+'log.txt';
AssignFile (flog,s);
Rewrite(flog);
if IOResult <> 0 then begin
Count := -1;
ListBox_log.Items.Add('faild')
end else begin
Count := 0;
err_files := 0;
ng_all := 0;
//指定ディレクトリからファイルを取り出す
// ** 内容で判別しないので違うファイル置かないよう注意 **
if FindFirst(SrlDir + '*.*', faAnyFile, Rec) = 0 then
try
repeat
//フォルダやカレントディレクトリや親ディレクトリは対象外
if not((Rec.Attr and faDirectory > 0)) and
(Rec.Name <> '.') and (Rec.Name <> '..') and (Rec.name<>'log.txt')then
begin
//ListBox_log.Items.Add('**********************************');
Writeln(flog,'**********************************');
sf := 'file: '+Rec.Name;
//ListBox_log.Items.Add(sf);
Writeln(flog,sf);
AssignFile (fsrl,SrlDir+Rec.Name);
FileMode := fmOpenRead;//リード専用指定
Reset(fsrl,1);//ファイル開く
if IOResult = 0 then begin
BlockRead(fsrl,romh,SizeOf(TRomh),n);//ヘッダリード
if SizeOf(TRomh) <> n then
s := ' header read error'
else begin
//SetLength(s,12);
s := '[ ( )]';
for i:=1 to 12 do begin
if romh.title[i] = char(0) then break;
s[i+1] := romh.title[i];
end;
s[15] := romh.game_code[4];//idの文字目(仕向地)
//ListBox_log.Items.Add(s); //title
Writeln(flog,s);
s := 'game_code = ';
for i:=1 to 4 do s[12+i] := romh.game_code[i];
//ListBox_log.Items.Add(s); //game code
//ListBox_log.Items.Add('version = '+inttostr(romh.rom_version));
//ListBox_log.Items.Add(' ');
Writeln(flog,s);
Writeln(flog,'version = '+inttostr(romh.rom_version));
Writeln(flog);//改行
//オーバレイチェック
if romh.main_ovt_size >31 then begin
//DHT_OVERLAY_MAX (512*1024)
ng_entry := 0;
total_sectors := 0;
all_sectors := 0;
nums := romh.main_ovt_size div 32;//Ovl count
noc_size :=0;//範囲外トータルsize
noc_sectors := 0;// 同セクタ
for i := 0 to nums-1 do begin
top := 0;btm := 0;
seek( fsrl,romh.fat_offset+sizeof(TRom_Fat)*i);
BlockRead( fsrl,fat,sizeof(fat),n);//top,bottom取得
if n <> sizeof(fat) then begin
s := 'file error';
break;
end;
ng_flg:=false;
ss := '(A9 Overlay'+inttostr(i);
//max_sectors = (DHT_OVERLAY_MAX/512 - total_sectors) / (nums-i);
if (total_sectors < 1024)then max_sectors := (1024 - total_sectors) div (nums-i)
else max_sectors := 0;
btm := fat.bottom and $fffffe00; //512単位
if (fat.bottom and $1ff)<>0 then inc(btm,512);//上方向に丸める
if max_sectors = 0 then begin//最大達したら丸ごと検証外
top := fat.top;
sectors := (btm-top) shr 9;//div 512
if (top and $1ff)<>0 then inc(sectors);
ss := ss+' の全部)';
ng_flg:=true;
end else begin
ss := ss+' の一部)';
top := fat.top and $fffffe00; //512単位
size := fat.top and $01ff;
if size<>0 then begin
inc(top,512);////上方向に丸める
//先頭の未検証部分 .. 不要?
s := 'offset'+inttostr(i)+' = 0x'+ inttohex(fat.top,8)
+' ; 0x'+ inttohex(fat.top,8)
+'-0x' + inttohex(top-1,8)+ss;
//ListBox_log.Items.Add(s);
Writeln(flog,s);
s := 'length'+ inttostr(i) + ' = 0x' + inttohex(size,4)
+ ' ; '+ inttostr(size)+' bytes';
//ListBox_log.Items.Add(s);
Writeln(flog,s);
inc(noc_size,512);
inc(noc_sectors);
inc(all_sectors);
ng_flg:=true;
end;
size := btm - top;
sectors := size shr 9;//div 512
inc(all_sectors,sectors);
if sectors > max_sectors then begin //最大割当サイズ超
sectors := sectors - max_sectors;//残りセクタ数
inc(top,max_sectors*512);//残り先頭
inc(total_sectors,max_sectors);
ng_flg:=true;
end else begin //超過なし
inc(total_sectors,sectors);
sectors := 0;
end;
end;
if sectors > 0 then begin//残りあり
size := sectors shl 9;
s := 'offset'+inttostr(i)+' = 0x'+ inttohex(top,8)
+' ; 0x'+ inttohex(top,8)
+'-0x' + inttohex(btm-1,8)+ss;
//ListBox_log.Items.Add(s);
Writeln(flog,s);
s := 'length'+ inttostr(i) + ' = 0x' + inttohex(size,4)
+ ' ; '+ inttostr(size)+' bytes';
//ListBox_log.Items.Add(s);
Writeln(flog,s);
inc(noc_size,size);
inc(noc_sectors,sectors);
end;
if ng_flg then inc(ng_entry);
end;
if i = nums then begin //中断なし
//ListBox_log.Items.Add(' ');
//ListBox_log.Items.Add('total sectors = '+inttostr(all_sectors));
//ListBox_log.Items.Add('no check sectors = '+inttostr(noc_sectors));
//ListBox_log.Items.Add('no check size = '+inttostr(noc_size));
Writeln(flog); //改行
Writeln(flog,'total sectors = '+inttostr(all_sectors));
Writeln(flog,'check sectors = '+inttostr(total_sectors));
Writeln(flog,'no check sectors = '+inttostr(noc_sectors));
Writeln(flog,'no check size = '+inttostr(noc_size));
if noc_size <> 0 then s:= 'NG'
else s:= 'OK';
end;
end else s := 'no OVL';
end;
end else s := ' Open Error';
CloseFile(fsrl);
Writeln(flog,s);//結果
if (s='OK') or (s='NG') then begin
if s = 'NG' then begin
s := 'done, '+ inttostr(ng_entry) + ' enties NG';
inc(ng_all,ng_entry);
end else s := 'done, OK';
Inc(Count);
end else inc(err_files);
ss := sf + ' : ' + s;
ListBox_log.Items.Add(ss);
end;
until (FindNext(Rec) <> 0);
finally
FindClose(Rec);
end;
Writeln(flog,'********************************');
Writeln(flog,'check files = '+ inttostr(Count));
Writeln(flog,'error files = '+ inttostr(err_files));
CloseFile(flog);
end;
{$I+}
Result :=Count;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
FileCount :integer;
s :string;
begin
ListBox_log.Clear;
//指定ディレクトリのsrlファイルをチェック
FileCount := CheckSrlHeader;
if FileCount>=0 then begin
ListBox_log.Items.Add(' ------------------------------ ');
s := ' '+inttostr(FileCount)+' files done, '
+ inttostr(ng_all)+' entries NG';
ListBox_log.Items.Add(s);
end;
end;
procedure TForm1.DriveBoxChange(Sender: TObject);
begin
DirListBox.Drive := DriveBox.Drive;
end;
procedure TForm1.DirListBoxChange(Sender: TObject);
begin
if RG_select.ItemIndex = 0 then begin
SrlDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
StatusBar.SimpleText := '[srl dir] ' + DirListBox.Directory;
end else begin
LogDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
StatusBar1.SimpleText := '[log dir] ' + DirListBox.Directory;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
SrlDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
StatusBar.SimpleText := '[srl dir] ' + DirListBox.Directory;
LogDir := IncludeTrailingPathDelimiter(DirListBox.Directory);
StatusBar1.SimpleText := '[log dir] ' + DirListBox.Directory;
end;
end.